diff --git a/.gitignore b/.gitignore index 5fd1b00c1fae114f3dc53ba8719f30b232bb0575..ca388691d2bdab58e5d2f409d199747109d45cc8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -node_modules -config.js -bundle.js -bundle.js.map -coverage +node_modules +config.js +bundle.js +bundle.js.map +coverage diff --git a/.prettierrc b/.prettierrc index 2c34d5c92b9b0f488012da0f083455a79544daf9..f7bb3dccc9bfba1bd9d39aa2994d72266007cfdb 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ -{ - "printWidth": 100, - "proseWrap": "always", - "singleQuote": true -} +{ + "printWidth": 100, + "proseWrap": "always", + "singleQuote": true +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 735324c1148876eb93c7e6ebb93cd61593b4cfcf..c2f20c6f3660e5635c42fe37b72d1e4cc3c968f1 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,3 @@ -{ - "recommendations": ["flowtype.flow-for-vscode", "esbenp.prettier-vscode"] -} +{ + "recommendations": ["flowtype.flow-for-vscode", "esbenp.prettier-vscode"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 340945dcd4f3822931f837395291853e6ca597e5..3f8397994c6611bbb5a4f581b2b2e326d972d8e6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ -{ - "javascript.validate.enable": false, - "editor.formatOnSave": true, - "flow.showUncovered": true -} +{ + "javascript.validate.enable": false, + "editor.formatOnSave": true, + "flow.showUncovered": true +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..9fe8a32c7b290e7b0e5268a472bf2f6adc78b4d9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +# Use Debian latest stable from https://hub.docker.com as base image +FROM debian:latest +# Upgrade packages +RUN apt-get update +RUN apt-get -y upgrade +# Install Node.js +RUN apt-get -y install nodejs diff --git a/LICENSE b/LICENSE index 4adab368927c8d4b4bad66a1ee889d40960b52c9..dbbb298589fcd669141ae6d20bcdc780ab5f26b6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2020 ntnu-dcst2002 - -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. +MIT License + +Copyright (c) 2020 ntnu-dcst2002 + +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. diff --git a/README.md b/README.md index 51ec6ef326076ea923858d4c2da6348f907bf0c7..c2d6815b34dec021ab5aa7b06f3ec89d6e53a75b 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,64 @@ -# Client tests example - -## Setup database connections - -You need to create two configuration files that will contain the database connection details. These -files should not be uploaded to your git repository, and they have therefore been added to -`.gitignore`. The connection details may vary, but example content of the two configuration files -are as follows: - -`server/src/config.js`: - -```js -// @flow - -process.env.MYSQL_HOST = 'mysql.stud.ntnu.no'; -process.env.MYSQL_USER = 'username_todo'; -process.env.MYSQL_PASSWORD = 'username_todo'; -process.env.MYSQL_DATABASE = 'username_todo_dev'; -``` - -`server/test/config.js`: - -```js -// @flow - -process.env.MYSQL_HOST = 'mysql.stud.ntnu.no'; -process.env.MYSQL_USER = 'username_todo'; -process.env.MYSQL_PASSWORD = 'username_todo'; -process.env.MYSQL_DATABASE = 'username_todo_test'; -``` - -These environment variables will be used in the `server/src/mysql-pool.js` file. - -## Start server - -Install dependencies and start server: - -```sh -cd server -npm install -npm start -``` - -### Run server tests: - -```sh -npm test -``` - -## Bundle client files to be served through server - -Install dependencies and bundle client files: - -```sh -cd client -npm install -npm start -``` - -### Run client tests: - -```sh -npm test -``` +# Client tests example + +## Setup database connections + +You need to create two configuration files that will contain the database connection details. These +files should not be uploaded to your git repository, and they have therefore been added to +`.gitignore`. The connection details may vary, but example content of the two configuration files +are as follows: + +`server/src/config.js`: + +```js +// @flow + +process.env.MYSQL_HOST = 'mysql.stud.ntnu.no'; +process.env.MYSQL_USER = 'username_todo'; +process.env.MYSQL_PASSWORD = 'username_todo'; +process.env.MYSQL_DATABASE = 'username_todo_dev'; +``` + +`server/test/config.js`: + +```js +// @flow + +process.env.MYSQL_HOST = 'mysql.stud.ntnu.no'; +process.env.MYSQL_USER = 'username_todo'; +process.env.MYSQL_PASSWORD = 'username_todo'; +process.env.MYSQL_DATABASE = 'username_todo_test'; +``` + +These environment variables will be used in the `server/src/mysql-pool.js` file. + +## Start server + +Install dependencies and start server: + +```sh +cd server +npm install +npm start +``` + +### Run server tests: + +```sh +npm test +``` + +## Bundle client files to be served through server + +Install dependencies and bundle client files: + +```sh +cd client +npm install +npm start +``` + +### Run client tests: + +```sh +npm test +``` diff --git a/client/.babelrc b/client/.babelrc index aa0bf73ab3498d8077d9fedb9661ee0f9ad3c449..4300537379e84085b72ddad6a4914c175e8857eb 100644 --- a/client/.babelrc +++ b/client/.babelrc @@ -1,4 +1,4 @@ -{ - "presets": ["@babel/preset-env", "@babel/preset-flow", "@babel/preset-react"], - "plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-optional-chaining", "@babel/plugin-proposal-nullish-coalescing-operator"] -} +{ + "presets": ["@babel/preset-env", "@babel/preset-flow", "@babel/preset-react"], + "plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-optional-chaining", "@babel/plugin-proposal-nullish-coalescing-operator"] +} diff --git a/client/.flowconfig b/client/.flowconfig index 93c28dc58dd2e1778f9eb29d1cc2c13bc1463062..81a71d868054c0faf906eef1fe3dc9d92d965b3e 100644 --- a/client/.flowconfig +++ b/client/.flowconfig @@ -1,2 +1,2 @@ -[options] -types_first=false +[options] +types_first=false diff --git a/client/.npmrc b/client/.npmrc index 43c97e719a5a824700932f72e6e7e6748ce45d01..094e38421d4085d75e1223c8c02d400bd687613c 100644 --- a/client/.npmrc +++ b/client/.npmrc @@ -1 +1 @@ -package-lock=false +package-lock=false diff --git a/client/flow-typed/npm/axios_v0.19.x.js b/client/flow-typed/npm/axios_v0.19.x.js index 65cd2161928036a709803bc99e7bbe089e91bc70..2af576fd753108326a8545646f308d752fb7512d 100644 --- a/client/flow-typed/npm/axios_v0.19.x.js +++ b/client/flow-typed/npm/axios_v0.19.x.js @@ -1,225 +1,225 @@ -// flow-typed signature: fe7f00984c44d69833f19bc39895832f -// flow-typed version: a4cc3d5e98/axios_v0.19.x/flow_>=v0.104.x - -declare module 'axios' { - import type { Agent as HttpAgent } from 'http'; - import type { Agent as HttpsAgent } from 'https'; - - declare type AxiosTransformer<T> = ( - data: T, - headers?: { [key: string]: mixed, ...}, - ) => mixed; - - declare type ProxyConfig = {| - host: string, - port: number, - auth?: {| - username: string, - password: string, - |}, - protocol?: string, - |}; - - declare class Cancel { - constructor(message?: string): Cancel; - message: string; - } - - declare type Canceler = (message?: string) => void; - - declare type CancelTokenSource = {| - token: CancelToken, - cancel: Canceler, - |}; - - declare class CancelToken { - constructor(executor: (cancel: Canceler) => void): void; - static source(): CancelTokenSource; - promise: Promise<Cancel>; - reason?: Cancel; - throwIfRequested(): void; - } - - declare type Method = - | 'get' - | 'GET' - | 'delete' - | 'DELETE' - | 'head' - | 'HEAD' - | 'options' - | 'OPTIONS' - | 'post' - | 'POST' - | 'put' - | 'PUT' - | 'patch' - | 'PATCH'; - - declare type ResponseType = - | 'arraybuffer' - | 'blob' - | 'document' - | 'json' - | 'text' - | 'stream'; - - declare type AxiosAdapter = ( - config: AxiosXHRConfig<mixed> - ) => Promise<AxiosXHR<mixed>>; - - declare type AxiosXHRConfigBase<T, R = T> = { - adapter?: AxiosAdapter, - auth?: {| - username: string, - password: string, - |}, - baseURL?: string, - cancelToken?: CancelToken, - headers?: { [key: string]: mixed, ...}, - httpAgent?: HttpAgent, - httpsAgent?: HttpsAgent, - maxContentLength?: number, - maxRedirects?: number, - socketPath?: string | null, - params?: { [key: string]: mixed, ...}, - paramsSerializer?: (params: { [key: string]: mixed, ...}) => string, - onUploadProgress?: (progressEvent: ProgressEvent) => void, - onDownloadProgress?: (progressEvent: ProgressEvent) => void, - proxy?: ProxyConfig | false, - responseType?: ResponseType, - timeout?: number, - transformRequest?: AxiosTransformer<T> | Array<AxiosTransformer<T>>, - transformResponse?: AxiosTransformer<R> | Array<AxiosTransformer<R>>, - validateStatus?: (status: number) => boolean, - withCredentials?: boolean, - xsrfCookieName?: string, - xsrfHeaderName?: string, - ... - }; - - declare type AxiosXHRConfig<T, R = T> = { - ...$Exact<AxiosXHRConfigBase<T, R>>, - data?: T, - method?: Method, - url: string, - ... - }; - - declare type AxiosXHRConfigShape<T, R = T> = $Shape<AxiosXHRConfig<T, R>>; - - declare type AxiosXHR<T, R = T> = {| - config: AxiosXHRConfig<T, R>, - data: R, - headers: ?{[key: string]: mixed, ...}, - status: number, - statusText: string, - request: http$ClientRequest<> | XMLHttpRequest | mixed, - |}; - - declare type AxiosInterceptorIdent = number; - - declare type AxiosRequestInterceptor<T, R = T> = {| - use( - onFulfilled: ?( - response: AxiosXHRConfig<T, R> - ) => Promise<AxiosXHRConfig<mixed>> | AxiosXHRConfig<mixed>, - onRejected: ?(error: mixed) => mixed - ): AxiosInterceptorIdent, - eject(ident: AxiosInterceptorIdent): void, - |}; - - declare type AxiosResponseInterceptor<T, R = T> = {| - use( - onFulfilled: ?(response: AxiosXHR<T, R>) => mixed, - onRejected: ?(error: mixed) => mixed - ): AxiosInterceptorIdent, - eject(ident: AxiosInterceptorIdent): void, - |}; - - declare type AxiosPromise<T, R = T> = Promise<AxiosXHR<T, R>>; - - declare class Axios { - <T, R>( - config: AxiosXHRConfig<T, R> | string, - config?: AxiosXHRConfigShape<T, R> - ): AxiosPromise<T, R>; - constructor<T, R>(config?: AxiosXHRConfigBase<T, R>): void; - request<T, R>( - config: AxiosXHRConfig<T, R> | string, - config?: AxiosXHRConfigShape<T, R> - ): AxiosPromise<T, R>; - delete<R>( - url: string, - config?: AxiosXHRConfigBase<mixed, R> - ): AxiosPromise<mixed, R>; - get<R>( - url: string, - config?: AxiosXHRConfigBase<mixed, R> - ): AxiosPromise<mixed, R>; - head<R>( - url: string, - config?: AxiosXHRConfigBase<mixed, R> - ): AxiosPromise<mixed, R>; - options<R>( - url: string, - config?: AxiosXHRConfigBase<mixed, R> - ): AxiosPromise<mixed, R>; - post<T, R>( - url: string, - data?: T, - config?: AxiosXHRConfigBase<T, R> - ): AxiosPromise<T, R>; - put<T, R>( - url: string, - data?: T, - config?: AxiosXHRConfigBase<T, R> - ): AxiosPromise<T, R>; - patch<T, R>( - url: string, - data?: T, - config?: AxiosXHRConfigBase<T, R> - ): AxiosPromise<T, R>; - interceptors: {| - request: AxiosRequestInterceptor<mixed>, - response: AxiosResponseInterceptor<mixed>, - |}; - defaults: {| - ...$Exact<AxiosXHRConfigBase<mixed>>, - headers: { [key: string]: mixed, ...}, - |}; - getUri<T, R>(config?: AxiosXHRConfig<T, R>): string; - } - - declare class AxiosError<T, R = T> extends Error { - config: AxiosXHRConfig<T, R>; - request?: http$ClientRequest<> | XMLHttpRequest; - response?: AxiosXHR<T, R>; - code?: string; - isAxiosError: boolean; - } - - declare interface AxiosExport extends Axios { - <T, R>( - config: AxiosXHRConfig<T, R> | string, - config?: AxiosXHRConfigShape<T, R> - ): AxiosPromise<T, R>; - Axios: typeof Axios; - Cancel: typeof Cancel; - CancelToken: typeof CancelToken; - isCancel(value: mixed): boolean; - create(config?: AxiosXHRConfigBase<T, R>): Axios; - all: typeof Promise.all; - spread<T, R>(callback: (...args: T) => R): (array: T) => R; - } - - declare type $AxiosXHRConfigBase<T, R = T> = AxiosXHRConfigBase<T, R>; - - declare type $AxiosXHRConfig<T, R = T> = AxiosXHRConfig<T, R>; - - declare type $AxiosXHR<T, R = T> = AxiosXHR<T, R>; - - declare type $AxiosError<T, R = T> = AxiosError<T, R>; - - declare module.exports: AxiosExport; -} +// flow-typed signature: fe7f00984c44d69833f19bc39895832f +// flow-typed version: a4cc3d5e98/axios_v0.19.x/flow_>=v0.104.x + +declare module 'axios' { + import type { Agent as HttpAgent } from 'http'; + import type { Agent as HttpsAgent } from 'https'; + + declare type AxiosTransformer<T> = ( + data: T, + headers?: { [key: string]: mixed, ...}, + ) => mixed; + + declare type ProxyConfig = {| + host: string, + port: number, + auth?: {| + username: string, + password: string, + |}, + protocol?: string, + |}; + + declare class Cancel { + constructor(message?: string): Cancel; + message: string; + } + + declare type Canceler = (message?: string) => void; + + declare type CancelTokenSource = {| + token: CancelToken, + cancel: Canceler, + |}; + + declare class CancelToken { + constructor(executor: (cancel: Canceler) => void): void; + static source(): CancelTokenSource; + promise: Promise<Cancel>; + reason?: Cancel; + throwIfRequested(): void; + } + + declare type Method = + | 'get' + | 'GET' + | 'delete' + | 'DELETE' + | 'head' + | 'HEAD' + | 'options' + | 'OPTIONS' + | 'post' + | 'POST' + | 'put' + | 'PUT' + | 'patch' + | 'PATCH'; + + declare type ResponseType = + | 'arraybuffer' + | 'blob' + | 'document' + | 'json' + | 'text' + | 'stream'; + + declare type AxiosAdapter = ( + config: AxiosXHRConfig<mixed> + ) => Promise<AxiosXHR<mixed>>; + + declare type AxiosXHRConfigBase<T, R = T> = { + adapter?: AxiosAdapter, + auth?: {| + username: string, + password: string, + |}, + baseURL?: string, + cancelToken?: CancelToken, + headers?: { [key: string]: mixed, ...}, + httpAgent?: HttpAgent, + httpsAgent?: HttpsAgent, + maxContentLength?: number, + maxRedirects?: number, + socketPath?: string | null, + params?: { [key: string]: mixed, ...}, + paramsSerializer?: (params: { [key: string]: mixed, ...}) => string, + onUploadProgress?: (progressEvent: ProgressEvent) => void, + onDownloadProgress?: (progressEvent: ProgressEvent) => void, + proxy?: ProxyConfig | false, + responseType?: ResponseType, + timeout?: number, + transformRequest?: AxiosTransformer<T> | Array<AxiosTransformer<T>>, + transformResponse?: AxiosTransformer<R> | Array<AxiosTransformer<R>>, + validateStatus?: (status: number) => boolean, + withCredentials?: boolean, + xsrfCookieName?: string, + xsrfHeaderName?: string, + ... + }; + + declare type AxiosXHRConfig<T, R = T> = { + ...$Exact<AxiosXHRConfigBase<T, R>>, + data?: T, + method?: Method, + url: string, + ... + }; + + declare type AxiosXHRConfigShape<T, R = T> = $Shape<AxiosXHRConfig<T, R>>; + + declare type AxiosXHR<T, R = T> = {| + config: AxiosXHRConfig<T, R>, + data: R, + headers: ?{[key: string]: mixed, ...}, + status: number, + statusText: string, + request: http$ClientRequest<> | XMLHttpRequest | mixed, + |}; + + declare type AxiosInterceptorIdent = number; + + declare type AxiosRequestInterceptor<T, R = T> = {| + use( + onFulfilled: ?( + response: AxiosXHRConfig<T, R> + ) => Promise<AxiosXHRConfig<mixed>> | AxiosXHRConfig<mixed>, + onRejected: ?(error: mixed) => mixed + ): AxiosInterceptorIdent, + eject(ident: AxiosInterceptorIdent): void, + |}; + + declare type AxiosResponseInterceptor<T, R = T> = {| + use( + onFulfilled: ?(response: AxiosXHR<T, R>) => mixed, + onRejected: ?(error: mixed) => mixed + ): AxiosInterceptorIdent, + eject(ident: AxiosInterceptorIdent): void, + |}; + + declare type AxiosPromise<T, R = T> = Promise<AxiosXHR<T, R>>; + + declare class Axios { + <T, R>( + config: AxiosXHRConfig<T, R> | string, + config?: AxiosXHRConfigShape<T, R> + ): AxiosPromise<T, R>; + constructor<T, R>(config?: AxiosXHRConfigBase<T, R>): void; + request<T, R>( + config: AxiosXHRConfig<T, R> | string, + config?: AxiosXHRConfigShape<T, R> + ): AxiosPromise<T, R>; + delete<R>( + url: string, + config?: AxiosXHRConfigBase<mixed, R> + ): AxiosPromise<mixed, R>; + get<R>( + url: string, + config?: AxiosXHRConfigBase<mixed, R> + ): AxiosPromise<mixed, R>; + head<R>( + url: string, + config?: AxiosXHRConfigBase<mixed, R> + ): AxiosPromise<mixed, R>; + options<R>( + url: string, + config?: AxiosXHRConfigBase<mixed, R> + ): AxiosPromise<mixed, R>; + post<T, R>( + url: string, + data?: T, + config?: AxiosXHRConfigBase<T, R> + ): AxiosPromise<T, R>; + put<T, R>( + url: string, + data?: T, + config?: AxiosXHRConfigBase<T, R> + ): AxiosPromise<T, R>; + patch<T, R>( + url: string, + data?: T, + config?: AxiosXHRConfigBase<T, R> + ): AxiosPromise<T, R>; + interceptors: {| + request: AxiosRequestInterceptor<mixed>, + response: AxiosResponseInterceptor<mixed>, + |}; + defaults: {| + ...$Exact<AxiosXHRConfigBase<mixed>>, + headers: { [key: string]: mixed, ...}, + |}; + getUri<T, R>(config?: AxiosXHRConfig<T, R>): string; + } + + declare class AxiosError<T, R = T> extends Error { + config: AxiosXHRConfig<T, R>; + request?: http$ClientRequest<> | XMLHttpRequest; + response?: AxiosXHR<T, R>; + code?: string; + isAxiosError: boolean; + } + + declare interface AxiosExport extends Axios { + <T, R>( + config: AxiosXHRConfig<T, R> | string, + config?: AxiosXHRConfigShape<T, R> + ): AxiosPromise<T, R>; + Axios: typeof Axios; + Cancel: typeof Cancel; + CancelToken: typeof CancelToken; + isCancel(value: mixed): boolean; + create(config?: AxiosXHRConfigBase<T, R>): Axios; + all: typeof Promise.all; + spread<T, R>(callback: (...args: T) => R): (array: T) => R; + } + + declare type $AxiosXHRConfigBase<T, R = T> = AxiosXHRConfigBase<T, R>; + + declare type $AxiosXHRConfig<T, R = T> = AxiosXHRConfig<T, R>; + + declare type $AxiosXHR<T, R = T> = AxiosXHR<T, R>; + + declare type $AxiosError<T, R = T> = AxiosError<T, R>; + + declare module.exports: AxiosExport; +} diff --git a/client/flow-typed/npm/enzyme_v3.x.x.js b/client/flow-typed/npm/enzyme_v3.x.x.js index 6ed48bcb6f6af14e1d330b43291773ab9a929717..71bad69631d5fbdccc227a011a275ec379627d27 100644 --- a/client/flow-typed/npm/enzyme_v3.x.x.js +++ b/client/flow-typed/npm/enzyme_v3.x.x.js @@ -1,144 +1,144 @@ -// flow-typed signature: 20e2bb4e722c2a79e4e0f178491bf6cc -// flow-typed version: 1f669c8dd2/enzyme_v3.x.x/flow_>=v0.104.x - -declare module "enzyme" { - declare type PredicateFunction<T: Wrapper<*>> = ( - wrapper: T, - index: number - ) => boolean; - declare type UntypedSelector = string | { [key: string]: number|string|boolean, ... }; - declare type EnzymeSelector = UntypedSelector | React$ElementType; - - // CheerioWrapper is a type alias for an actual cheerio instance - // TODO: Reference correct type from cheerio's type declarations - declare type CheerioWrapper = any; - - declare class Wrapper<RootComponent> { - at(index: number): this, - childAt(index: number): this, - children(selector?: UntypedSelector): this, - children<T: React$ElementType>(selector: T): ReactWrapper<T>, - closest(selector: UntypedSelector): this, - closest<T: React$ElementType>(selector: T): ReactWrapper<T>, - contains(nodes: React$Element<any> | $ReadOnlyArray<React$Element<any>>): boolean, - containsAllMatchingElements(nodes: $ReadOnlyArray<React$Element<any>>): boolean, - containsAnyMatchingElements(nodes: $ReadOnlyArray<React$Element<any>>): boolean, - containsMatchingElement(node: React$Element<any>): boolean, - context(key?: string): any, - debug(options?: Object): string, - dive(option?: { context?: Object, ... }): this, - equals(node: React$Element<any>): boolean, - every(selector: EnzymeSelector): boolean, - everyWhere(predicate: PredicateFunction<this>): boolean, - exists(selector?: EnzymeSelector): boolean, - filter(selector: UntypedSelector): this, - filter<T: React$ElementType>(selector: T): ReactWrapper<T>, - filterWhere(predicate: PredicateFunction<this>): this, - find(selector: UntypedSelector): this, - find<T: React$ElementType>(selector: T): ReactWrapper<T>, - findWhere(predicate: PredicateFunction<this>): this, - first(): this, - forEach(fn: (node: this, index: number) => mixed): this, - get<T = any>(index: number): React$Element<T>, - getDOMNode(): HTMLElement | HTMLInputElement, - hasClass(className: string): boolean, - hostNodes(): this, - html(): string, - instance(): React$ElementRef<RootComponent>, - invoke(propName: string): (...args: $ReadOnlyArray<any>) => mixed, - is(selector: EnzymeSelector): boolean, - isEmpty(): boolean, - isEmptyRender(): boolean, - key(): string, - last(): this, - length: number, - map<T>(fn: (node: this, index: number) => T): Array<T>, - matchesElement(node: React$Element<any>): boolean, - name(): string, - not(selector: EnzymeSelector): this, - parent(): this, - parents(selector?: UntypedSelector): this, - parents<T: React$ElementType>(selector: T): ReactWrapper<T>, - prop(key: string): any, - props(): Object, - reduce<T>( - fn: (value: T, node: this, index: number) => T, - initialValue?: T - ): Array<T>, - reduceRight<T>( - fn: (value: T, node: this, index: number) => T, - initialValue?: T - ): Array<T>, - render(): CheerioWrapper, - renderProp(propName: string): (...args: Array<any>) => this, - setContext(context: Object): this, - setProps(props: {...}, callback?: () => void): this, - setState(state: {...}, callback?: () => void): this, - simulate(event: string, ...args: Array<any>): this, - simulateError(error: Error): this, - slice(begin?: number, end?: number): this, - some(selector: EnzymeSelector): boolean, - someWhere(predicate: PredicateFunction<this>): boolean, - state(key?: string): any, - text(): string, - type(): string | Function | null, - unmount(): this, - update(): this, - } - - declare class ReactWrapper<T> extends Wrapper<T> { - constructor(nodes: React$Element<T>, root: any, options?: ?Object): ReactWrapper<T>, - mount(): this, - ref(refName: string): this, - detach(): void - } - - declare class ShallowWrapper<T> extends Wrapper<T> { - constructor( - nodes: React$Element<T>, - root: any, - options?: ?Object - ): ShallowWrapper<T>, - shallow(options?: { context?: Object, ... }): ShallowWrapper<T>, - getElement<T = any>(): React$Element<T>, - getElements<T = any>(): Array<React$Element<T>> - } - - declare function shallow<T>( - node: React$Element<T>, - options?: { - context?: Object, - disableLifecycleMethods?: boolean, - ... - } - ): ShallowWrapper<T>; - - declare function mount<T>( - node: React$Element<T>, - options?: { - context?: Object, - attachTo?: HTMLElement, - childContextTypes?: Object, - ... - } - ): ReactWrapper<T>; - - declare function render( - node: React$Node, - options?: { context?: Object, ... } - ): CheerioWrapper; - - declare module.exports: { - configure(options: { - Adapter?: any, - disableLifecycleMethods?: boolean, - ... - }): void, - render: typeof render, - mount: typeof mount, - shallow: typeof shallow, - ShallowWrapper: typeof ShallowWrapper, - ReactWrapper: typeof ReactWrapper, - ... - }; -} +// flow-typed signature: 20e2bb4e722c2a79e4e0f178491bf6cc +// flow-typed version: 1f669c8dd2/enzyme_v3.x.x/flow_>=v0.104.x + +declare module "enzyme" { + declare type PredicateFunction<T: Wrapper<*>> = ( + wrapper: T, + index: number + ) => boolean; + declare type UntypedSelector = string | { [key: string]: number|string|boolean, ... }; + declare type EnzymeSelector = UntypedSelector | React$ElementType; + + // CheerioWrapper is a type alias for an actual cheerio instance + // TODO: Reference correct type from cheerio's type declarations + declare type CheerioWrapper = any; + + declare class Wrapper<RootComponent> { + at(index: number): this, + childAt(index: number): this, + children(selector?: UntypedSelector): this, + children<T: React$ElementType>(selector: T): ReactWrapper<T>, + closest(selector: UntypedSelector): this, + closest<T: React$ElementType>(selector: T): ReactWrapper<T>, + contains(nodes: React$Element<any> | $ReadOnlyArray<React$Element<any>>): boolean, + containsAllMatchingElements(nodes: $ReadOnlyArray<React$Element<any>>): boolean, + containsAnyMatchingElements(nodes: $ReadOnlyArray<React$Element<any>>): boolean, + containsMatchingElement(node: React$Element<any>): boolean, + context(key?: string): any, + debug(options?: Object): string, + dive(option?: { context?: Object, ... }): this, + equals(node: React$Element<any>): boolean, + every(selector: EnzymeSelector): boolean, + everyWhere(predicate: PredicateFunction<this>): boolean, + exists(selector?: EnzymeSelector): boolean, + filter(selector: UntypedSelector): this, + filter<T: React$ElementType>(selector: T): ReactWrapper<T>, + filterWhere(predicate: PredicateFunction<this>): this, + find(selector: UntypedSelector): this, + find<T: React$ElementType>(selector: T): ReactWrapper<T>, + findWhere(predicate: PredicateFunction<this>): this, + first(): this, + forEach(fn: (node: this, index: number) => mixed): this, + get<T = any>(index: number): React$Element<T>, + getDOMNode(): HTMLElement | HTMLInputElement, + hasClass(className: string): boolean, + hostNodes(): this, + html(): string, + instance(): React$ElementRef<RootComponent>, + invoke(propName: string): (...args: $ReadOnlyArray<any>) => mixed, + is(selector: EnzymeSelector): boolean, + isEmpty(): boolean, + isEmptyRender(): boolean, + key(): string, + last(): this, + length: number, + map<T>(fn: (node: this, index: number) => T): Array<T>, + matchesElement(node: React$Element<any>): boolean, + name(): string, + not(selector: EnzymeSelector): this, + parent(): this, + parents(selector?: UntypedSelector): this, + parents<T: React$ElementType>(selector: T): ReactWrapper<T>, + prop(key: string): any, + props(): Object, + reduce<T>( + fn: (value: T, node: this, index: number) => T, + initialValue?: T + ): Array<T>, + reduceRight<T>( + fn: (value: T, node: this, index: number) => T, + initialValue?: T + ): Array<T>, + render(): CheerioWrapper, + renderProp(propName: string): (...args: Array<any>) => this, + setContext(context: Object): this, + setProps(props: {...}, callback?: () => void): this, + setState(state: {...}, callback?: () => void): this, + simulate(event: string, ...args: Array<any>): this, + simulateError(error: Error): this, + slice(begin?: number, end?: number): this, + some(selector: EnzymeSelector): boolean, + someWhere(predicate: PredicateFunction<this>): boolean, + state(key?: string): any, + text(): string, + type(): string | Function | null, + unmount(): this, + update(): this, + } + + declare class ReactWrapper<T> extends Wrapper<T> { + constructor(nodes: React$Element<T>, root: any, options?: ?Object): ReactWrapper<T>, + mount(): this, + ref(refName: string): this, + detach(): void + } + + declare class ShallowWrapper<T> extends Wrapper<T> { + constructor( + nodes: React$Element<T>, + root: any, + options?: ?Object + ): ShallowWrapper<T>, + shallow(options?: { context?: Object, ... }): ShallowWrapper<T>, + getElement<T = any>(): React$Element<T>, + getElements<T = any>(): Array<React$Element<T>> + } + + declare function shallow<T>( + node: React$Element<T>, + options?: { + context?: Object, + disableLifecycleMethods?: boolean, + ... + } + ): ShallowWrapper<T>; + + declare function mount<T>( + node: React$Element<T>, + options?: { + context?: Object, + attachTo?: HTMLElement, + childContextTypes?: Object, + ... + } + ): ReactWrapper<T>; + + declare function render( + node: React$Node, + options?: { context?: Object, ... } + ): CheerioWrapper; + + declare module.exports: { + configure(options: { + Adapter?: any, + disableLifecycleMethods?: boolean, + ... + }): void, + render: typeof render, + mount: typeof mount, + shallow: typeof shallow, + ShallowWrapper: typeof ShallowWrapper, + ReactWrapper: typeof ReactWrapper, + ... + }; +} diff --git a/client/flow-typed/npm/history_v4.10.x.js b/client/flow-typed/npm/history_v4.10.x.js index e46d4e7ad428e79c39b20d4e789db81ef1b9209d..48c7bbaec3dd4d20f5b4e7e2fad344d9b59a9391 100644 --- a/client/flow-typed/npm/history_v4.10.x.js +++ b/client/flow-typed/npm/history_v4.10.x.js @@ -1,109 +1,109 @@ -// flow-typed signature: 90337b03d736e9bdaa68004c36c4d3ee -// flow-typed version: 51319746df/history_v4.10.x/flow_>=v0.104.x - -declare module 'history' { - declare type Unregister = () => void; - - declare export type Action = 'PUSH' | 'REPLACE' | 'POP'; - - declare export type Location = {| - pathname: string, - search: string, - hash: string, - state: { ... }, - key: string, - |}; - - declare type History<HistoryLocation = Location> = {| - length: number, - location: HistoryLocation, - action: Action, - push: ((path: string, state?: { ... }) => void) & - ((location: $Shape<HistoryLocation>) => void), - replace: ((path: string, state?: { ... }) => void) & - ((location: $Shape<HistoryLocation>) => void), - go(n: number): void, - goBack(): void, - goForward(): void, - listen((location: HistoryLocation, action: Action) => void): Unregister, - block( - prompt: - | string - | boolean - | ((location: HistoryLocation, action: Action) => string | false | void) - ): Unregister, - createHref(location: $Shape<HistoryLocation>): string, - |}; - - declare export type BrowserHistory = History<>; - - declare type BrowserHistoryOpts = {| - basename?: string, - forceRefresh?: boolean, - getUserConfirmation?: ( - message: string, - callback: (willContinue: boolean) => void - ) => void, - keyLength?: number, - |}; - - declare function createBrowserHistory( - opts?: BrowserHistoryOpts - ): BrowserHistory; - - declare export type MemoryHistory = {| - ...History<>, - index: number, - entries: Array<string | Location>, - canGo(n: number): boolean, - |}; - - declare type MemoryHistoryOpts = {| - initialEntries?: Array<string>, - initialIndex?: number, - keyLength?: number, - getUserConfirmation?: ( - message: string, - callback: (willContinue: boolean) => void - ) => void, - |}; - - declare function createMemoryHistory(opts?: MemoryHistoryOpts): MemoryHistory; - - declare export type HashLocation = {| - ...Location, - state: void, - key: void, - |}; - - declare export type HashHistory = History<HashLocation>; - - declare type HashHistoryOpts = {| - basename?: string, - hashType: 'slash' | 'noslash' | 'hashbang', - getUserConfirmation?: ( - message: string, - callback: (willContinue: boolean) => void - ) => void, - |}; - - declare function createHashHistory(opts?: HashHistoryOpts): HashHistory; - - // PathUtils - declare function parsePath(path: string): Location; - - declare function createPath(location: $Shape<Location>): string; - - // LocationUtils - declare function locationsAreEqual( - a: $Shape<Location>, - b: $Shape<Location> - ): boolean; - - declare function createLocation( - path: string | $Shape<Location>, - state?: { ... }, - key?: string, - currentLocation?: Location - ): Location; -} +// flow-typed signature: 90337b03d736e9bdaa68004c36c4d3ee +// flow-typed version: 51319746df/history_v4.10.x/flow_>=v0.104.x + +declare module 'history' { + declare type Unregister = () => void; + + declare export type Action = 'PUSH' | 'REPLACE' | 'POP'; + + declare export type Location = {| + pathname: string, + search: string, + hash: string, + state: { ... }, + key: string, + |}; + + declare type History<HistoryLocation = Location> = {| + length: number, + location: HistoryLocation, + action: Action, + push: ((path: string, state?: { ... }) => void) & + ((location: $Shape<HistoryLocation>) => void), + replace: ((path: string, state?: { ... }) => void) & + ((location: $Shape<HistoryLocation>) => void), + go(n: number): void, + goBack(): void, + goForward(): void, + listen((location: HistoryLocation, action: Action) => void): Unregister, + block( + prompt: + | string + | boolean + | ((location: HistoryLocation, action: Action) => string | false | void) + ): Unregister, + createHref(location: $Shape<HistoryLocation>): string, + |}; + + declare export type BrowserHistory = History<>; + + declare type BrowserHistoryOpts = {| + basename?: string, + forceRefresh?: boolean, + getUserConfirmation?: ( + message: string, + callback: (willContinue: boolean) => void + ) => void, + keyLength?: number, + |}; + + declare function createBrowserHistory( + opts?: BrowserHistoryOpts + ): BrowserHistory; + + declare export type MemoryHistory = {| + ...History<>, + index: number, + entries: Array<string | Location>, + canGo(n: number): boolean, + |}; + + declare type MemoryHistoryOpts = {| + initialEntries?: Array<string>, + initialIndex?: number, + keyLength?: number, + getUserConfirmation?: ( + message: string, + callback: (willContinue: boolean) => void + ) => void, + |}; + + declare function createMemoryHistory(opts?: MemoryHistoryOpts): MemoryHistory; + + declare export type HashLocation = {| + ...Location, + state: void, + key: void, + |}; + + declare export type HashHistory = History<HashLocation>; + + declare type HashHistoryOpts = {| + basename?: string, + hashType: 'slash' | 'noslash' | 'hashbang', + getUserConfirmation?: ( + message: string, + callback: (willContinue: boolean) => void + ) => void, + |}; + + declare function createHashHistory(opts?: HashHistoryOpts): HashHistory; + + // PathUtils + declare function parsePath(path: string): Location; + + declare function createPath(location: $Shape<Location>): string; + + // LocationUtils + declare function locationsAreEqual( + a: $Shape<Location>, + b: $Shape<Location> + ): boolean; + + declare function createLocation( + path: string | $Shape<Location>, + state?: { ... }, + key?: string, + currentLocation?: Location + ): Location; +} diff --git a/client/flow-typed/npm/jest_v26.x.x.js b/client/flow-typed/npm/jest_v26.x.x.js index 587373b2940ab84c19393e44b1be2933abd1a369..f3cdd9bde54812625c5458b3cf4279aec7a8badd 100644 --- a/client/flow-typed/npm/jest_v26.x.x.js +++ b/client/flow-typed/npm/jest_v26.x.x.js @@ -1,1218 +1,1218 @@ -// flow-typed signature: e60c7806ec0ddaf4588f438843ef37bd -// flow-typed version: 7afca48d86/jest_v26.x.x/flow_>=v0.104.x - -type JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = { - (...args: TArguments): TReturn, - /** - * An object for introspecting mock calls - */ - mock: { - /** - * An array that represents all calls that have been made into this mock - * function. Each call is represented by an array of arguments that were - * passed during the call. - */ - calls: Array<TArguments>, - /** - * An array that contains all the object instances that have been - * instantiated from this mock function. - */ - instances: Array<TReturn>, - /** - * An array that contains all the object results that have been - * returned by this mock function call - */ - results: Array<{ - isThrow: boolean, - value: TReturn, - ... - }>, - ... - }, - /** - * Resets all information stored in the mockFn.mock.calls and - * mockFn.mock.instances arrays. Often this is useful when you want to clean - * up a mock's usage data between two assertions. - */ - mockClear(): void, - /** - * Resets all information stored in the mock. This is useful when you want to - * completely restore a mock back to its initial state. - */ - mockReset(): void, - /** - * Removes the mock and restores the initial implementation. This is useful - * when you want to mock functions in certain test cases and restore the - * original implementation in others. Beware that mockFn.mockRestore only - * works when mock was created with jest.spyOn. Thus you have to take care of - * restoration yourself when manually assigning jest.fn(). - */ - mockRestore(): void, - /** - * Accepts a function that should be used as the implementation of the mock. - * The mock itself will still record all calls that go into and instances - * that come from itself -- the only difference is that the implementation - * will also be executed when the mock is called. - */ - mockImplementation( - fn: (...args: TArguments) => TReturn - ): JestMockFn<TArguments, TReturn>, - /** - * Accepts a function that will be used as an implementation of the mock for - * one call to the mocked function. Can be chained so that multiple function - * calls produce different results. - */ - mockImplementationOnce( - fn: (...args: TArguments) => TReturn - ): JestMockFn<TArguments, TReturn>, - /** - * Accepts a string to use in test result output in place of "jest.fn()" to - * indicate which mock function is being referenced. - */ - mockName(name: string): JestMockFn<TArguments, TReturn>, - /** - * Just a simple sugar function for returning `this` - */ - mockReturnThis(): void, - /** - * Accepts a value that will be returned whenever the mock function is called. - */ - mockReturnValue(value: TReturn): JestMockFn<TArguments, TReturn>, - /** - * Sugar for only returning a value once inside your mock - */ - mockReturnValueOnce(value: TReturn): JestMockFn<TArguments, TReturn>, - /** - * Sugar for jest.fn().mockImplementation(() => Promise.resolve(value)) - */ - mockResolvedValue(value: TReturn): JestMockFn<TArguments, Promise<TReturn>>, - /** - * Sugar for jest.fn().mockImplementationOnce(() => Promise.resolve(value)) - */ - mockResolvedValueOnce( - value: TReturn - ): JestMockFn<TArguments, Promise<TReturn>>, - /** - * Sugar for jest.fn().mockImplementation(() => Promise.reject(value)) - */ - mockRejectedValue(value: TReturn): JestMockFn<TArguments, Promise<any>>, - /** - * Sugar for jest.fn().mockImplementationOnce(() => Promise.reject(value)) - */ - mockRejectedValueOnce(value: TReturn): JestMockFn<TArguments, Promise<any>>, - ... -}; - -type JestAsymmetricEqualityType = { - /** - * A custom Jasmine equality tester - */ - asymmetricMatch(value: mixed): boolean, - ... -}; - -type JestCallsType = { - allArgs(): mixed, - all(): mixed, - any(): boolean, - count(): number, - first(): mixed, - mostRecent(): mixed, - reset(): void, - ... -}; - -type JestClockType = { - install(): void, - mockDate(date: Date): void, - tick(milliseconds?: number): void, - uninstall(): void, - ... -}; - -type JestMatcherResult = { - message?: string | (() => string), - pass: boolean, - ... -}; - -type JestMatcher = ( - received: any, - ...actual: Array<any> -) => JestMatcherResult | Promise<JestMatcherResult>; - -type JestPromiseType = { - /** - * Use rejects to unwrap the reason of a rejected promise so any other - * matcher can be chained. If the promise is fulfilled the assertion fails. - */ - rejects: JestExpectType, - /** - * Use resolves to unwrap the value of a fulfilled promise so any other - * matcher can be chained. If the promise is rejected the assertion fails. - */ - resolves: JestExpectType, - ... -}; - -/** - * Jest allows functions and classes to be used as test names in test() and - * describe() - */ -type JestTestName = string | Function; - -/** - * Plugin: jest-styled-components - */ - -type JestStyledComponentsMatcherValue = - | string - | JestAsymmetricEqualityType - | RegExp - | typeof undefined; - -type JestStyledComponentsMatcherOptions = { - media?: string, - modifier?: string, - supports?: string, - ... -}; - -type JestStyledComponentsMatchersType = { - toHaveStyleRule( - property: string, - value: JestStyledComponentsMatcherValue, - options?: JestStyledComponentsMatcherOptions - ): void, - ... -}; - -/** - * Plugin: jest-enzyme - */ -type EnzymeMatchersType = { - // 5.x - toBeEmpty(): void, - toBePresent(): void, - // 6.x - toBeChecked(): void, - toBeDisabled(): void, - toBeEmptyRender(): void, - toContainMatchingElement(selector: string): void, - toContainMatchingElements(n: number, selector: string): void, - toContainExactlyOneMatchingElement(selector: string): void, - toContainReact(element: React$Element<any>): void, - toExist(): void, - toHaveClassName(className: string): void, - toHaveHTML(html: string): void, - toHaveProp: ((propKey: string, propValue?: any) => void) & - ((props: { ... }) => void), - toHaveRef(refName: string): void, - toHaveState: ((stateKey: string, stateValue?: any) => void) & - ((state: { ... }) => void), - toHaveStyle: ((styleKey: string, styleValue?: any) => void) & - ((style: { ... }) => void), - toHaveTagName(tagName: string): void, - toHaveText(text: string): void, - toHaveValue(value: any): void, - toIncludeText(text: string): void, - toMatchElement( - element: React$Element<any>, - options?: {| ignoreProps?: boolean, verbose?: boolean |} - ): void, - toMatchSelector(selector: string): void, - // 7.x - toHaveDisplayName(name: string): void, - ... -}; - -// DOM testing library extensions (jest-dom) -// https://github.com/testing-library/jest-dom -type DomTestingLibraryType = { - /** - * @deprecated - */ - toBeInTheDOM(container?: HTMLElement): void, - - // 4.x - toBeInTheDocument(): void, - toBeVisible(): void, - toBeEmpty(): void, - toBeDisabled(): void, - toBeEnabled(): void, - toBeInvalid(): void, - toBeRequired(): void, - toBeValid(): void, - toContainElement(element: HTMLElement | null): void, - toContainHTML(htmlText: string): void, - toHaveAttribute(attr: string, value?: any): void, - toHaveClass(...classNames: string[]): void, - toHaveFocus(): void, - toHaveFormValues(expectedValues: { [name: string]: any, ... }): void, - toHaveStyle(css: string | { [name: string]: any, ... }): void, - toHaveTextContent( - text: string | RegExp, - options?: {| normalizeWhitespace: boolean |} - ): void, - toHaveValue(value?: string | string[] | number): void, - - // 5.x - toHaveDisplayValue(value: string | string[]): void, - toBeChecked(): void, - ... -}; - -// Jest JQuery Matchers: https://github.com/unindented/custom-jquery-matchers -type JestJQueryMatchersType = { - toExist(): void, - toHaveLength(len: number): void, - toHaveId(id: string): void, - toHaveClass(className: string): void, - toHaveTag(tag: string): void, - toHaveAttr(key: string, val?: any): void, - toHaveProp(key: string, val?: any): void, - toHaveText(text: string | RegExp): void, - toHaveData(key: string, val?: any): void, - toHaveValue(val: any): void, - toHaveCss(css: { [key: string]: any, ... }): void, - toBeChecked(): void, - toBeDisabled(): void, - toBeEmpty(): void, - toBeHidden(): void, - toBeSelected(): void, - toBeVisible(): void, - toBeFocused(): void, - toBeInDom(): void, - toBeMatchedBy(sel: string): void, - toHaveDescendant(sel: string): void, - toHaveDescendantWithText(sel: string, text: string | RegExp): void, - ... -}; - -// Jest Extended Matchers: https://github.com/jest-community/jest-extended -type JestExtendedMatchersType = { - /** - * Note: Currently unimplemented - * Passing assertion - * - * @param {String} message - */ - // pass(message: string): void; - - /** - * Note: Currently unimplemented - * Failing assertion - * - * @param {String} message - */ - // fail(message: string): void; - - /** - * Use .toBeEmpty when checking if a String '', Array [] or Object {} is empty. - */ - toBeEmpty(): void, - /** - * Use .toBeOneOf when checking if a value is a member of a given Array. - * @param {Array.<*>} members - */ - toBeOneOf(members: any[]): void, - /** - * Use `.toBeNil` when checking a value is `null` or `undefined`. - */ - toBeNil(): void, - /** - * Use `.toSatisfy` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean`. - * @param {Function} predicate - */ - toSatisfy(predicate: (n: any) => boolean): void, - /** - * Use `.toBeArray` when checking if a value is an `Array`. - */ - toBeArray(): void, - /** - * Use `.toBeArrayOfSize` when checking if a value is an `Array` of size x. - * @param {Number} x - */ - toBeArrayOfSize(x: number): void, - /** - * Use `.toIncludeAllMembers` when checking if an `Array` contains all of the same members of a given set. - * @param {Array.<*>} members - */ - toIncludeAllMembers(members: any[]): void, - /** - * Use `.toIncludeAnyMembers` when checking if an `Array` contains any of the members of a given set. - * @param {Array.<*>} members - */ - toIncludeAnyMembers(members: any[]): void, - /** - * Use `.toSatisfyAll` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean` for all values in an array. - * @param {Function} predicate - */ - toSatisfyAll(predicate: (n: any) => boolean): void, - /** - * Use `.toBeBoolean` when checking if a value is a `Boolean`. - */ - toBeBoolean(): void, - /** - * Use `.toBeTrue` when checking a value is equal (===) to `true`. - */ - toBeTrue(): void, - /** - * Use `.toBeFalse` when checking a value is equal (===) to `false`. - */ - toBeFalse(): void, - /** - * Use .toBeDate when checking if a value is a Date. - */ - toBeDate(): void, - /** - * Use `.toBeFunction` when checking if a value is a `Function`. - */ - toBeFunction(): void, - /** - * Use `.toHaveBeenCalledBefore` when checking if a `Mock` was called before another `Mock`. - * - * Note: Required Jest version >22 - * Note: Your mock functions will have to be asynchronous to cause the timestamps inside of Jest to occur in a differentJS event loop, otherwise the mock timestamps will all be the same - * - * @param {Mock} mock - */ - toHaveBeenCalledBefore(mock: JestMockFn<any, any>): void, - /** - * Use `.toBeNumber` when checking if a value is a `Number`. - */ - toBeNumber(): void, - /** - * Use `.toBeNaN` when checking a value is `NaN`. - */ - toBeNaN(): void, - /** - * Use `.toBeFinite` when checking if a value is a `Number`, not `NaN` or `Infinity`. - */ - toBeFinite(): void, - /** - * Use `.toBePositive` when checking if a value is a positive `Number`. - */ - toBePositive(): void, - /** - * Use `.toBeNegative` when checking if a value is a negative `Number`. - */ - toBeNegative(): void, - /** - * Use `.toBeEven` when checking if a value is an even `Number`. - */ - toBeEven(): void, - /** - * Use `.toBeOdd` when checking if a value is an odd `Number`. - */ - toBeOdd(): void, - /** - * Use `.toBeWithin` when checking if a number is in between the given bounds of: start (inclusive) and end (exclusive). - * - * @param {Number} start - * @param {Number} end - */ - toBeWithin(start: number, end: number): void, - /** - * Use `.toBeObject` when checking if a value is an `Object`. - */ - toBeObject(): void, - /** - * Use `.toContainKey` when checking if an object contains the provided key. - * - * @param {String} key - */ - toContainKey(key: string): void, - /** - * Use `.toContainKeys` when checking if an object has all of the provided keys. - * - * @param {Array.<String>} keys - */ - toContainKeys(keys: string[]): void, - /** - * Use `.toContainAllKeys` when checking if an object only contains all of the provided keys. - * - * @param {Array.<String>} keys - */ - toContainAllKeys(keys: string[]): void, - /** - * Use `.toContainAnyKeys` when checking if an object contains at least one of the provided keys. - * - * @param {Array.<String>} keys - */ - toContainAnyKeys(keys: string[]): void, - /** - * Use `.toContainValue` when checking if an object contains the provided value. - * - * @param {*} value - */ - toContainValue(value: any): void, - /** - * Use `.toContainValues` when checking if an object contains all of the provided values. - * - * @param {Array.<*>} values - */ - toContainValues(values: any[]): void, - /** - * Use `.toContainAllValues` when checking if an object only contains all of the provided values. - * - * @param {Array.<*>} values - */ - toContainAllValues(values: any[]): void, - /** - * Use `.toContainAnyValues` when checking if an object contains at least one of the provided values. - * - * @param {Array.<*>} values - */ - toContainAnyValues(values: any[]): void, - /** - * Use `.toContainEntry` when checking if an object contains the provided entry. - * - * @param {Array.<String, String>} entry - */ - toContainEntry(entry: [string, string]): void, - /** - * Use `.toContainEntries` when checking if an object contains all of the provided entries. - * - * @param {Array.<Array.<String, String>>} entries - */ - toContainEntries(entries: [string, string][]): void, - /** - * Use `.toContainAllEntries` when checking if an object only contains all of the provided entries. - * - * @param {Array.<Array.<String, String>>} entries - */ - toContainAllEntries(entries: [string, string][]): void, - /** - * Use `.toContainAnyEntries` when checking if an object contains at least one of the provided entries. - * - * @param {Array.<Array.<String, String>>} entries - */ - toContainAnyEntries(entries: [string, string][]): void, - /** - * Use `.toBeExtensible` when checking if an object is extensible. - */ - toBeExtensible(): void, - /** - * Use `.toBeFrozen` when checking if an object is frozen. - */ - toBeFrozen(): void, - /** - * Use `.toBeSealed` when checking if an object is sealed. - */ - toBeSealed(): void, - /** - * Use `.toBeString` when checking if a value is a `String`. - */ - toBeString(): void, - /** - * Use `.toEqualCaseInsensitive` when checking if a string is equal (===) to another ignoring the casing of both strings. - * - * @param {String} string - */ - toEqualCaseInsensitive(string: string): void, - /** - * Use `.toStartWith` when checking if a `String` starts with a given `String` prefix. - * - * @param {String} prefix - */ - toStartWith(prefix: string): void, - /** - * Use `.toEndWith` when checking if a `String` ends with a given `String` suffix. - * - * @param {String} suffix - */ - toEndWith(suffix: string): void, - /** - * Use `.toInclude` when checking if a `String` includes the given `String` substring. - * - * @param {String} substring - */ - toInclude(substring: string): void, - /** - * Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times. - * - * @param {String} substring - * @param {Number} times - */ - toIncludeRepeated(substring: string, times: number): void, - /** - * Use `.toIncludeMultiple` when checking if a `String` includes all of the given substrings. - * - * @param {Array.<String>} substring - */ - toIncludeMultiple(substring: string[]): void, - ... -}; - -// Diffing snapshot utility for Jest (snapshot-diff) -// https://github.com/jest-community/snapshot-diff -type SnapshotDiffType = { - /** - * Compare the difference between the actual in the `expect()` - * vs the object inside `valueB` with some extra options. - */ - toMatchDiffSnapshot( - valueB: any, - options?: {| - expand?: boolean, - colors?: boolean, - contextLines?: number, - stablePatchmarks?: boolean, - aAnnotation?: string, - bAnnotation?: string, - |}, - testName?: string - ): void, - ... -}; - -interface JestExpectType { - not: JestExpectType & - EnzymeMatchersType & - DomTestingLibraryType & - JestJQueryMatchersType & - JestStyledComponentsMatchersType & - JestExtendedMatchersType & - SnapshotDiffType; - /** - * If you have a mock function, you can use .lastCalledWith to test what - * arguments it was last called with. - */ - lastCalledWith(...args: Array<any>): void; - /** - * toBe just checks that a value is what you expect. It uses === to check - * strict equality. - */ - toBe(value: any): void; - /** - * Use .toBeCalledWith to ensure that a mock function was called with - * specific arguments. - */ - toBeCalledWith(...args: Array<any>): void; - /** - * Using exact equality with floating point numbers is a bad idea. Rounding - * means that intuitive things fail. - */ - toBeCloseTo(num: number, delta: any): void; - /** - * Use .toBeDefined to check that a variable is not undefined. - */ - toBeDefined(): void; - /** - * Use .toBeFalsy when you don't care what a value is, you just want to - * ensure a value is false in a boolean context. - */ - toBeFalsy(): void; - /** - * To compare floating point numbers, you can use toBeGreaterThan. - */ - toBeGreaterThan(number: number): void; - /** - * To compare floating point numbers, you can use toBeGreaterThanOrEqual. - */ - toBeGreaterThanOrEqual(number: number): void; - /** - * To compare floating point numbers, you can use toBeLessThan. - */ - toBeLessThan(number: number): void; - /** - * To compare floating point numbers, you can use toBeLessThanOrEqual. - */ - toBeLessThanOrEqual(number: number): void; - /** - * Use .toBeInstanceOf(Class) to check that an object is an instance of a - * class. - */ - toBeInstanceOf(cls: Class<*>): void; - /** - * .toBeNull() is the same as .toBe(null) but the error messages are a bit - * nicer. - */ - toBeNull(): void; - /** - * Use .toBeTruthy when you don't care what a value is, you just want to - * ensure a value is true in a boolean context. - */ - toBeTruthy(): void; - /** - * Use .toBeUndefined to check that a variable is undefined. - */ - toBeUndefined(): void; - /** - * Use .toContain when you want to check that an item is in a list. For - * testing the items in the list, this uses ===, a strict equality check. - */ - toContain(item: any): void; - /** - * Use .toContainEqual when you want to check that an item is in a list. For - * testing the items in the list, this matcher recursively checks the - * equality of all fields, rather than checking for object identity. - */ - toContainEqual(item: any): void; - /** - * Use .toEqual when you want to check that two objects have the same value. - * This matcher recursively checks the equality of all fields, rather than - * checking for object identity. - */ - toEqual(value: any): void; - /** - * Use .toHaveBeenCalled to ensure that a mock function got called. - */ - toHaveBeenCalled(): void; - toBeCalled(): void; - /** - * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact - * number of times. - */ - toHaveBeenCalledTimes(number: number): void; - toBeCalledTimes(number: number): void; - /** - * - */ - toHaveBeenNthCalledWith(nthCall: number, ...args: Array<any>): void; - nthCalledWith(nthCall: number, ...args: Array<any>): void; - /** - * - */ - toHaveReturned(): void; - toReturn(): void; - /** - * - */ - toHaveReturnedTimes(number: number): void; - toReturnTimes(number: number): void; - /** - * - */ - toHaveReturnedWith(value: any): void; - toReturnWith(value: any): void; - /** - * - */ - toHaveLastReturnedWith(value: any): void; - lastReturnedWith(value: any): void; - /** - * - */ - toHaveNthReturnedWith(nthCall: number, value: any): void; - nthReturnedWith(nthCall: number, value: any): void; - /** - * Use .toHaveBeenCalledWith to ensure that a mock function was called with - * specific arguments. - */ - toHaveBeenCalledWith(...args: Array<any>): void; - toBeCalledWith(...args: Array<any>): void; - /** - * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called - * with specific arguments. - */ - toHaveBeenLastCalledWith(...args: Array<any>): void; - lastCalledWith(...args: Array<any>): void; - /** - * Check that an object has a .length property and it is set to a certain - * numeric value. - */ - toHaveLength(number: number): void; - /** - * - */ - toHaveProperty(propPath: string | $ReadOnlyArray<string>, value?: any): void; - /** - * Use .toMatch to check that a string matches a regular expression or string. - */ - toMatch(regexpOrString: RegExp | string): void; - /** - * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. - */ - toMatchObject(object: Object | Array<Object>): void; - /** - * Use .toStrictEqual to check that a javascript object matches a subset of the properties of an object. - */ - toStrictEqual(value: any): void; - /** - * This ensures that an Object matches the most recent snapshot. - */ - toMatchSnapshot(propertyMatchers?: any, name?: string): void; - /** - * This ensures that an Object matches the most recent snapshot. - */ - toMatchSnapshot(name: string): void; - - toMatchInlineSnapshot(snapshot?: string): void; - toMatchInlineSnapshot(propertyMatchers?: any, snapshot?: string): void; - /** - * Use .toThrow to test that a function throws when it is called. - * If you want to test that a specific error gets thrown, you can provide an - * argument to toThrow. The argument can be a string for the error message, - * a class for the error, or a regex that should match the error. - * - * Alias: .toThrowError - */ - toThrow(message?: string | Error | Class<Error> | RegExp): void; - toThrowError(message?: string | Error | Class<Error> | RegExp): void; - /** - * Use .toThrowErrorMatchingSnapshot to test that a function throws a error - * matching the most recent snapshot when it is called. - */ - toThrowErrorMatchingSnapshot(): void; - toThrowErrorMatchingInlineSnapshot(snapshot?: string): void; -} - -type JestObjectType = { - /** - * Disables automatic mocking in the module loader. - * - * After this method is called, all `require()`s will return the real - * versions of each module (rather than a mocked version). - */ - disableAutomock(): JestObjectType, - /** - * An un-hoisted version of disableAutomock - */ - autoMockOff(): JestObjectType, - /** - * Enables automatic mocking in the module loader. - */ - enableAutomock(): JestObjectType, - /** - * An un-hoisted version of enableAutomock - */ - autoMockOn(): JestObjectType, - /** - * Clears the mock.calls and mock.instances properties of all mocks. - * Equivalent to calling .mockClear() on every mocked function. - */ - clearAllMocks(): JestObjectType, - /** - * Resets the state of all mocks. Equivalent to calling .mockReset() on every - * mocked function. - */ - resetAllMocks(): JestObjectType, - /** - * Restores all mocks back to their original value. - */ - restoreAllMocks(): JestObjectType, - /** - * Removes any pending timers from the timer system. - */ - clearAllTimers(): void, - /** - * Returns the number of fake timers still left to run. - */ - getTimerCount(): number, - /** - * The same as `mock` but not moved to the top of the expectation by - * babel-jest. - */ - doMock(moduleName: string, moduleFactory?: any): JestObjectType, - /** - * The same as `unmock` but not moved to the top of the expectation by - * babel-jest. - */ - dontMock(moduleName: string): JestObjectType, - /** - * Returns a new, unused mock function. Optionally takes a mock - * implementation. - */ - fn<TArguments: $ReadOnlyArray<*>, TReturn>( - implementation?: (...args: TArguments) => TReturn - ): JestMockFn<TArguments, TReturn>, - /** - * Determines if the given function is a mocked function. - */ - isMockFunction(fn: Function): boolean, - /** - * Given the name of a module, use the automatic mocking system to generate a - * mocked version of the module for you. - */ - genMockFromModule(moduleName: string): any, - /** - * Mocks a module with an auto-mocked version when it is being required. - * - * The second argument can be used to specify an explicit module factory that - * is being run instead of using Jest's automocking feature. - * - * The third argument can be used to create virtual mocks -- mocks of modules - * that don't exist anywhere in the system. - */ - mock( - moduleName: string, - moduleFactory?: any, - options?: Object - ): JestObjectType, - /** - * Returns the actual module instead of a mock, bypassing all checks on - * whether the module should receive a mock implementation or not. - */ - requireActual<T>(m: $Flow$ModuleRef<T> | string): T, - /** - * Returns a mock module instead of the actual module, bypassing all checks - * on whether the module should be required normally or not. - */ - requireMock(moduleName: string): any, - /** - * Resets the module registry - the cache of all required modules. This is - * useful to isolate modules where local state might conflict between tests. - */ - resetModules(): JestObjectType, - /** - * Creates a sandbox registry for the modules that are loaded inside the - * callback function. This is useful to isolate specific modules for every - * test so that local module state doesn't conflict between tests. - */ - isolateModules(fn: () => void): JestObjectType, - /** - * Exhausts the micro-task queue (usually interfaced in node via - * process.nextTick). - */ - runAllTicks(): void, - /** - * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), - * setInterval(), and setImmediate()). - */ - runAllTimers(): void, - /** - * Exhausts all tasks queued by setImmediate(). - */ - runAllImmediates(): void, - /** - * Executes only the macro task queue (i.e. all tasks queued by setTimeout() - * or setInterval() and setImmediate()). - */ - advanceTimersByTime(msToRun: number): void, - /** - * Executes only the macro task queue (i.e. all tasks queued by setTimeout() - * or setInterval() and setImmediate()). - * - * Renamed to `advanceTimersByTime`. - */ - runTimersToTime(msToRun: number): void, - /** - * Executes only the macro-tasks that are currently pending (i.e., only the - * tasks that have been queued by setTimeout() or setInterval() up to this - * point) - */ - runOnlyPendingTimers(): void, - /** - * Explicitly supplies the mock object that the module system should return - * for the specified module. Note: It is recommended to use jest.mock() - * instead. - */ - setMock(moduleName: string, moduleExports: any): JestObjectType, - /** - * Indicates that the module system should never return a mocked version of - * the specified module from require() (e.g. that it should always return the - * real module). - */ - unmock(moduleName: string): JestObjectType, - /** - * Instructs Jest to use fake versions of the standard timer functions - * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, - * setImmediate and clearImmediate). - */ - useFakeTimers(mode?: 'modern' | 'legacy'): JestObjectType, - /** - * Instructs Jest to use the real versions of the standard timer functions. - */ - useRealTimers(): JestObjectType, - /** - * Creates a mock function similar to jest.fn but also tracks calls to - * object[methodName]. - */ - spyOn( - object: Object, - methodName: string, - accessType?: 'get' | 'set' - ): JestMockFn<any, any>, - /** - * Set the default timeout interval for tests and before/after hooks in milliseconds. - * Note: The default timeout interval is 5 seconds if this method is not called. - */ - setTimeout(timeout: number): JestObjectType, - ... -}; - -type JestSpyType = { calls: JestCallsType, ... }; - -type JestDoneFn = {| - (error?: Error): void, - fail: (error: Error) => void, -|}; - -/** Runs this function after every test inside this context */ -declare function afterEach( - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; -/** Runs this function before every test inside this context */ -declare function beforeEach( - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; -/** Runs this function after all tests have finished inside this context */ -declare function afterAll( - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; -/** Runs this function before any tests have started inside this context */ -declare function beforeAll( - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; - -/** A context for grouping tests together */ -declare var describe: { - /** - * Creates a block that groups together several related tests in one "test suite" - */ - (name: JestTestName, fn: () => void): void, - /** - * Only run this describe block - */ - only(name: JestTestName, fn: () => void): void, - /** - * Skip running this describe block - */ - skip(name: JestTestName, fn: () => void): void, - /** - * each runs this test against array of argument arrays per each run - * - * @param {table} table of Test - */ - each( - ...table: Array<Array<mixed> | mixed> | [Array<string>, string] - ): ( - name: JestTestName, - fn?: (...args: Array<any>) => ?Promise<mixed>, - timeout?: number - ) => void, - ... -}; - -/** An individual test unit */ -declare var it: { - /** - * An individual test unit - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - ( - name: JestTestName, - fn?: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number - ): void, - /** - * Only run this test - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - only: {| - ( - name: JestTestName, - fn?: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number - ): void, - each( - ...table: Array<Array<mixed> | mixed> | [Array<string>, string] - ): ( - name: JestTestName, - fn?: (...args: Array<any>) => ?Promise<mixed>, - timeout?: number - ) => void, - |}, - /** - * Skip running this test - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - skip( - name: JestTestName, - fn?: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number - ): void, - /** - * Highlight planned tests in the summary output - * - * @param {String} Name of Test to do - */ - todo(name: string): void, - /** - * Run the test concurrently - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - concurrent( - name: JestTestName, - fn?: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number - ): void, - /** - * each runs this test against array of argument arrays per each run - * - * @param {table} table of Test - */ - each( - ...table: Array<Array<mixed> | mixed> | [Array<string>, string] - ): ( - name: JestTestName, - fn?: (...args: Array<any>) => ?Promise<mixed>, - timeout?: number - ) => void, - ... -}; - -declare function fit( - name: JestTestName, - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; -/** An individual test unit */ -declare var test: typeof it; -/** A disabled group of tests */ -declare var xdescribe: typeof describe; -/** A focused group of tests */ -declare var fdescribe: typeof describe; -/** A disabled individual test */ -declare var xit: typeof it; -/** A disabled individual test */ -declare var xtest: typeof it; - -type JestPrettyFormatColors = { - comment: { - close: string, - open: string, - ... - }, - content: { - close: string, - open: string, - ... - }, - prop: { - close: string, - open: string, - ... - }, - tag: { - close: string, - open: string, - ... - }, - value: { - close: string, - open: string, - ... - }, - ... -}; - -type JestPrettyFormatIndent = (string) => string; -type JestPrettyFormatRefs = Array<any>; -type JestPrettyFormatPrint = (any) => string; -type JestPrettyFormatStringOrNull = string | null; - -type JestPrettyFormatOptions = {| - callToJSON: boolean, - edgeSpacing: string, - escapeRegex: boolean, - highlight: boolean, - indent: number, - maxDepth: number, - min: boolean, - plugins: JestPrettyFormatPlugins, - printFunctionName: boolean, - spacing: string, - theme: {| - comment: string, - content: string, - prop: string, - tag: string, - value: string, - |}, -|}; - -type JestPrettyFormatPlugin = { - print: ( - val: any, - serialize: JestPrettyFormatPrint, - indent: JestPrettyFormatIndent, - opts: JestPrettyFormatOptions, - colors: JestPrettyFormatColors - ) => string, - test: (any) => boolean, - ... -}; - -type JestPrettyFormatPlugins = Array<JestPrettyFormatPlugin>; - -/** The expect function is used every time you want to test a value */ -declare var expect: { - /** The object that you want to make assertions against */ - ( - value: any - ): JestExpectType & - JestPromiseType & - EnzymeMatchersType & - DomTestingLibraryType & - JestJQueryMatchersType & - JestStyledComponentsMatchersType & - JestExtendedMatchersType & - SnapshotDiffType, - /** Add additional Jasmine matchers to Jest's roster */ - extend(matchers: { [name: string]: JestMatcher, ... }): void, - /** Add a module that formats application-specific data structures. */ - addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void, - assertions(expectedAssertions: number): void, - hasAssertions(): void, - any(value: mixed): JestAsymmetricEqualityType, - anything(): any, - arrayContaining(value: Array<mixed>): Array<mixed>, - objectContaining(value: Object): Object, - /** Matches any received string that contains the exact expected string. */ - stringContaining(value: string): string, - stringMatching(value: string | RegExp): string, - not: { - arrayContaining: (value: $ReadOnlyArray<mixed>) => Array<mixed>, - objectContaining: (value: { ... }) => Object, - stringContaining: (value: string) => string, - stringMatching: (value: string | RegExp) => string, - ... - }, - ... -}; - -// TODO handle return type -// http://jasmine.github.io/2.4/introduction.html#section-Spies -declare function spyOn(value: mixed, method: string): Object; - -/** Holds all functions related to manipulating test runner */ -declare var jest: JestObjectType; - -/** - * The global Jasmine object, this is generally not exposed as the public API, - * using features inside here could break in later versions of Jest. - */ -declare var jasmine: { - DEFAULT_TIMEOUT_INTERVAL: number, - any(value: mixed): JestAsymmetricEqualityType, - anything(): any, - arrayContaining(value: Array<mixed>): Array<mixed>, - clock(): JestClockType, - createSpy(name: string): JestSpyType, - createSpyObj( - baseName: string, - methodNames: Array<string> - ): { [methodName: string]: JestSpyType, ... }, - objectContaining(value: Object): Object, - stringMatching(value: string): string, - ... -}; +// flow-typed signature: e60c7806ec0ddaf4588f438843ef37bd +// flow-typed version: 7afca48d86/jest_v26.x.x/flow_>=v0.104.x + +type JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = { + (...args: TArguments): TReturn, + /** + * An object for introspecting mock calls + */ + mock: { + /** + * An array that represents all calls that have been made into this mock + * function. Each call is represented by an array of arguments that were + * passed during the call. + */ + calls: Array<TArguments>, + /** + * An array that contains all the object instances that have been + * instantiated from this mock function. + */ + instances: Array<TReturn>, + /** + * An array that contains all the object results that have been + * returned by this mock function call + */ + results: Array<{ + isThrow: boolean, + value: TReturn, + ... + }>, + ... + }, + /** + * Resets all information stored in the mockFn.mock.calls and + * mockFn.mock.instances arrays. Often this is useful when you want to clean + * up a mock's usage data between two assertions. + */ + mockClear(): void, + /** + * Resets all information stored in the mock. This is useful when you want to + * completely restore a mock back to its initial state. + */ + mockReset(): void, + /** + * Removes the mock and restores the initial implementation. This is useful + * when you want to mock functions in certain test cases and restore the + * original implementation in others. Beware that mockFn.mockRestore only + * works when mock was created with jest.spyOn. Thus you have to take care of + * restoration yourself when manually assigning jest.fn(). + */ + mockRestore(): void, + /** + * Accepts a function that should be used as the implementation of the mock. + * The mock itself will still record all calls that go into and instances + * that come from itself -- the only difference is that the implementation + * will also be executed when the mock is called. + */ + mockImplementation( + fn: (...args: TArguments) => TReturn + ): JestMockFn<TArguments, TReturn>, + /** + * Accepts a function that will be used as an implementation of the mock for + * one call to the mocked function. Can be chained so that multiple function + * calls produce different results. + */ + mockImplementationOnce( + fn: (...args: TArguments) => TReturn + ): JestMockFn<TArguments, TReturn>, + /** + * Accepts a string to use in test result output in place of "jest.fn()" to + * indicate which mock function is being referenced. + */ + mockName(name: string): JestMockFn<TArguments, TReturn>, + /** + * Just a simple sugar function for returning `this` + */ + mockReturnThis(): void, + /** + * Accepts a value that will be returned whenever the mock function is called. + */ + mockReturnValue(value: TReturn): JestMockFn<TArguments, TReturn>, + /** + * Sugar for only returning a value once inside your mock + */ + mockReturnValueOnce(value: TReturn): JestMockFn<TArguments, TReturn>, + /** + * Sugar for jest.fn().mockImplementation(() => Promise.resolve(value)) + */ + mockResolvedValue(value: TReturn): JestMockFn<TArguments, Promise<TReturn>>, + /** + * Sugar for jest.fn().mockImplementationOnce(() => Promise.resolve(value)) + */ + mockResolvedValueOnce( + value: TReturn + ): JestMockFn<TArguments, Promise<TReturn>>, + /** + * Sugar for jest.fn().mockImplementation(() => Promise.reject(value)) + */ + mockRejectedValue(value: TReturn): JestMockFn<TArguments, Promise<any>>, + /** + * Sugar for jest.fn().mockImplementationOnce(() => Promise.reject(value)) + */ + mockRejectedValueOnce(value: TReturn): JestMockFn<TArguments, Promise<any>>, + ... +}; + +type JestAsymmetricEqualityType = { + /** + * A custom Jasmine equality tester + */ + asymmetricMatch(value: mixed): boolean, + ... +}; + +type JestCallsType = { + allArgs(): mixed, + all(): mixed, + any(): boolean, + count(): number, + first(): mixed, + mostRecent(): mixed, + reset(): void, + ... +}; + +type JestClockType = { + install(): void, + mockDate(date: Date): void, + tick(milliseconds?: number): void, + uninstall(): void, + ... +}; + +type JestMatcherResult = { + message?: string | (() => string), + pass: boolean, + ... +}; + +type JestMatcher = ( + received: any, + ...actual: Array<any> +) => JestMatcherResult | Promise<JestMatcherResult>; + +type JestPromiseType = { + /** + * Use rejects to unwrap the reason of a rejected promise so any other + * matcher can be chained. If the promise is fulfilled the assertion fails. + */ + rejects: JestExpectType, + /** + * Use resolves to unwrap the value of a fulfilled promise so any other + * matcher can be chained. If the promise is rejected the assertion fails. + */ + resolves: JestExpectType, + ... +}; + +/** + * Jest allows functions and classes to be used as test names in test() and + * describe() + */ +type JestTestName = string | Function; + +/** + * Plugin: jest-styled-components + */ + +type JestStyledComponentsMatcherValue = + | string + | JestAsymmetricEqualityType + | RegExp + | typeof undefined; + +type JestStyledComponentsMatcherOptions = { + media?: string, + modifier?: string, + supports?: string, + ... +}; + +type JestStyledComponentsMatchersType = { + toHaveStyleRule( + property: string, + value: JestStyledComponentsMatcherValue, + options?: JestStyledComponentsMatcherOptions + ): void, + ... +}; + +/** + * Plugin: jest-enzyme + */ +type EnzymeMatchersType = { + // 5.x + toBeEmpty(): void, + toBePresent(): void, + // 6.x + toBeChecked(): void, + toBeDisabled(): void, + toBeEmptyRender(): void, + toContainMatchingElement(selector: string): void, + toContainMatchingElements(n: number, selector: string): void, + toContainExactlyOneMatchingElement(selector: string): void, + toContainReact(element: React$Element<any>): void, + toExist(): void, + toHaveClassName(className: string): void, + toHaveHTML(html: string): void, + toHaveProp: ((propKey: string, propValue?: any) => void) & + ((props: { ... }) => void), + toHaveRef(refName: string): void, + toHaveState: ((stateKey: string, stateValue?: any) => void) & + ((state: { ... }) => void), + toHaveStyle: ((styleKey: string, styleValue?: any) => void) & + ((style: { ... }) => void), + toHaveTagName(tagName: string): void, + toHaveText(text: string): void, + toHaveValue(value: any): void, + toIncludeText(text: string): void, + toMatchElement( + element: React$Element<any>, + options?: {| ignoreProps?: boolean, verbose?: boolean |} + ): void, + toMatchSelector(selector: string): void, + // 7.x + toHaveDisplayName(name: string): void, + ... +}; + +// DOM testing library extensions (jest-dom) +// https://github.com/testing-library/jest-dom +type DomTestingLibraryType = { + /** + * @deprecated + */ + toBeInTheDOM(container?: HTMLElement): void, + + // 4.x + toBeInTheDocument(): void, + toBeVisible(): void, + toBeEmpty(): void, + toBeDisabled(): void, + toBeEnabled(): void, + toBeInvalid(): void, + toBeRequired(): void, + toBeValid(): void, + toContainElement(element: HTMLElement | null): void, + toContainHTML(htmlText: string): void, + toHaveAttribute(attr: string, value?: any): void, + toHaveClass(...classNames: string[]): void, + toHaveFocus(): void, + toHaveFormValues(expectedValues: { [name: string]: any, ... }): void, + toHaveStyle(css: string | { [name: string]: any, ... }): void, + toHaveTextContent( + text: string | RegExp, + options?: {| normalizeWhitespace: boolean |} + ): void, + toHaveValue(value?: string | string[] | number): void, + + // 5.x + toHaveDisplayValue(value: string | string[]): void, + toBeChecked(): void, + ... +}; + +// Jest JQuery Matchers: https://github.com/unindented/custom-jquery-matchers +type JestJQueryMatchersType = { + toExist(): void, + toHaveLength(len: number): void, + toHaveId(id: string): void, + toHaveClass(className: string): void, + toHaveTag(tag: string): void, + toHaveAttr(key: string, val?: any): void, + toHaveProp(key: string, val?: any): void, + toHaveText(text: string | RegExp): void, + toHaveData(key: string, val?: any): void, + toHaveValue(val: any): void, + toHaveCss(css: { [key: string]: any, ... }): void, + toBeChecked(): void, + toBeDisabled(): void, + toBeEmpty(): void, + toBeHidden(): void, + toBeSelected(): void, + toBeVisible(): void, + toBeFocused(): void, + toBeInDom(): void, + toBeMatchedBy(sel: string): void, + toHaveDescendant(sel: string): void, + toHaveDescendantWithText(sel: string, text: string | RegExp): void, + ... +}; + +// Jest Extended Matchers: https://github.com/jest-community/jest-extended +type JestExtendedMatchersType = { + /** + * Note: Currently unimplemented + * Passing assertion + * + * @param {String} message + */ + // pass(message: string): void; + + /** + * Note: Currently unimplemented + * Failing assertion + * + * @param {String} message + */ + // fail(message: string): void; + + /** + * Use .toBeEmpty when checking if a String '', Array [] or Object {} is empty. + */ + toBeEmpty(): void, + /** + * Use .toBeOneOf when checking if a value is a member of a given Array. + * @param {Array.<*>} members + */ + toBeOneOf(members: any[]): void, + /** + * Use `.toBeNil` when checking a value is `null` or `undefined`. + */ + toBeNil(): void, + /** + * Use `.toSatisfy` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean`. + * @param {Function} predicate + */ + toSatisfy(predicate: (n: any) => boolean): void, + /** + * Use `.toBeArray` when checking if a value is an `Array`. + */ + toBeArray(): void, + /** + * Use `.toBeArrayOfSize` when checking if a value is an `Array` of size x. + * @param {Number} x + */ + toBeArrayOfSize(x: number): void, + /** + * Use `.toIncludeAllMembers` when checking if an `Array` contains all of the same members of a given set. + * @param {Array.<*>} members + */ + toIncludeAllMembers(members: any[]): void, + /** + * Use `.toIncludeAnyMembers` when checking if an `Array` contains any of the members of a given set. + * @param {Array.<*>} members + */ + toIncludeAnyMembers(members: any[]): void, + /** + * Use `.toSatisfyAll` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean` for all values in an array. + * @param {Function} predicate + */ + toSatisfyAll(predicate: (n: any) => boolean): void, + /** + * Use `.toBeBoolean` when checking if a value is a `Boolean`. + */ + toBeBoolean(): void, + /** + * Use `.toBeTrue` when checking a value is equal (===) to `true`. + */ + toBeTrue(): void, + /** + * Use `.toBeFalse` when checking a value is equal (===) to `false`. + */ + toBeFalse(): void, + /** + * Use .toBeDate when checking if a value is a Date. + */ + toBeDate(): void, + /** + * Use `.toBeFunction` when checking if a value is a `Function`. + */ + toBeFunction(): void, + /** + * Use `.toHaveBeenCalledBefore` when checking if a `Mock` was called before another `Mock`. + * + * Note: Required Jest version >22 + * Note: Your mock functions will have to be asynchronous to cause the timestamps inside of Jest to occur in a differentJS event loop, otherwise the mock timestamps will all be the same + * + * @param {Mock} mock + */ + toHaveBeenCalledBefore(mock: JestMockFn<any, any>): void, + /** + * Use `.toBeNumber` when checking if a value is a `Number`. + */ + toBeNumber(): void, + /** + * Use `.toBeNaN` when checking a value is `NaN`. + */ + toBeNaN(): void, + /** + * Use `.toBeFinite` when checking if a value is a `Number`, not `NaN` or `Infinity`. + */ + toBeFinite(): void, + /** + * Use `.toBePositive` when checking if a value is a positive `Number`. + */ + toBePositive(): void, + /** + * Use `.toBeNegative` when checking if a value is a negative `Number`. + */ + toBeNegative(): void, + /** + * Use `.toBeEven` when checking if a value is an even `Number`. + */ + toBeEven(): void, + /** + * Use `.toBeOdd` when checking if a value is an odd `Number`. + */ + toBeOdd(): void, + /** + * Use `.toBeWithin` when checking if a number is in between the given bounds of: start (inclusive) and end (exclusive). + * + * @param {Number} start + * @param {Number} end + */ + toBeWithin(start: number, end: number): void, + /** + * Use `.toBeObject` when checking if a value is an `Object`. + */ + toBeObject(): void, + /** + * Use `.toContainKey` when checking if an object contains the provided key. + * + * @param {String} key + */ + toContainKey(key: string): void, + /** + * Use `.toContainKeys` when checking if an object has all of the provided keys. + * + * @param {Array.<String>} keys + */ + toContainKeys(keys: string[]): void, + /** + * Use `.toContainAllKeys` when checking if an object only contains all of the provided keys. + * + * @param {Array.<String>} keys + */ + toContainAllKeys(keys: string[]): void, + /** + * Use `.toContainAnyKeys` when checking if an object contains at least one of the provided keys. + * + * @param {Array.<String>} keys + */ + toContainAnyKeys(keys: string[]): void, + /** + * Use `.toContainValue` when checking if an object contains the provided value. + * + * @param {*} value + */ + toContainValue(value: any): void, + /** + * Use `.toContainValues` when checking if an object contains all of the provided values. + * + * @param {Array.<*>} values + */ + toContainValues(values: any[]): void, + /** + * Use `.toContainAllValues` when checking if an object only contains all of the provided values. + * + * @param {Array.<*>} values + */ + toContainAllValues(values: any[]): void, + /** + * Use `.toContainAnyValues` when checking if an object contains at least one of the provided values. + * + * @param {Array.<*>} values + */ + toContainAnyValues(values: any[]): void, + /** + * Use `.toContainEntry` when checking if an object contains the provided entry. + * + * @param {Array.<String, String>} entry + */ + toContainEntry(entry: [string, string]): void, + /** + * Use `.toContainEntries` when checking if an object contains all of the provided entries. + * + * @param {Array.<Array.<String, String>>} entries + */ + toContainEntries(entries: [string, string][]): void, + /** + * Use `.toContainAllEntries` when checking if an object only contains all of the provided entries. + * + * @param {Array.<Array.<String, String>>} entries + */ + toContainAllEntries(entries: [string, string][]): void, + /** + * Use `.toContainAnyEntries` when checking if an object contains at least one of the provided entries. + * + * @param {Array.<Array.<String, String>>} entries + */ + toContainAnyEntries(entries: [string, string][]): void, + /** + * Use `.toBeExtensible` when checking if an object is extensible. + */ + toBeExtensible(): void, + /** + * Use `.toBeFrozen` when checking if an object is frozen. + */ + toBeFrozen(): void, + /** + * Use `.toBeSealed` when checking if an object is sealed. + */ + toBeSealed(): void, + /** + * Use `.toBeString` when checking if a value is a `String`. + */ + toBeString(): void, + /** + * Use `.toEqualCaseInsensitive` when checking if a string is equal (===) to another ignoring the casing of both strings. + * + * @param {String} string + */ + toEqualCaseInsensitive(string: string): void, + /** + * Use `.toStartWith` when checking if a `String` starts with a given `String` prefix. + * + * @param {String} prefix + */ + toStartWith(prefix: string): void, + /** + * Use `.toEndWith` when checking if a `String` ends with a given `String` suffix. + * + * @param {String} suffix + */ + toEndWith(suffix: string): void, + /** + * Use `.toInclude` when checking if a `String` includes the given `String` substring. + * + * @param {String} substring + */ + toInclude(substring: string): void, + /** + * Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times. + * + * @param {String} substring + * @param {Number} times + */ + toIncludeRepeated(substring: string, times: number): void, + /** + * Use `.toIncludeMultiple` when checking if a `String` includes all of the given substrings. + * + * @param {Array.<String>} substring + */ + toIncludeMultiple(substring: string[]): void, + ... +}; + +// Diffing snapshot utility for Jest (snapshot-diff) +// https://github.com/jest-community/snapshot-diff +type SnapshotDiffType = { + /** + * Compare the difference between the actual in the `expect()` + * vs the object inside `valueB` with some extra options. + */ + toMatchDiffSnapshot( + valueB: any, + options?: {| + expand?: boolean, + colors?: boolean, + contextLines?: number, + stablePatchmarks?: boolean, + aAnnotation?: string, + bAnnotation?: string, + |}, + testName?: string + ): void, + ... +}; + +interface JestExpectType { + not: JestExpectType & + EnzymeMatchersType & + DomTestingLibraryType & + JestJQueryMatchersType & + JestStyledComponentsMatchersType & + JestExtendedMatchersType & + SnapshotDiffType; + /** + * If you have a mock function, you can use .lastCalledWith to test what + * arguments it was last called with. + */ + lastCalledWith(...args: Array<any>): void; + /** + * toBe just checks that a value is what you expect. It uses === to check + * strict equality. + */ + toBe(value: any): void; + /** + * Use .toBeCalledWith to ensure that a mock function was called with + * specific arguments. + */ + toBeCalledWith(...args: Array<any>): void; + /** + * Using exact equality with floating point numbers is a bad idea. Rounding + * means that intuitive things fail. + */ + toBeCloseTo(num: number, delta: any): void; + /** + * Use .toBeDefined to check that a variable is not undefined. + */ + toBeDefined(): void; + /** + * Use .toBeFalsy when you don't care what a value is, you just want to + * ensure a value is false in a boolean context. + */ + toBeFalsy(): void; + /** + * To compare floating point numbers, you can use toBeGreaterThan. + */ + toBeGreaterThan(number: number): void; + /** + * To compare floating point numbers, you can use toBeGreaterThanOrEqual. + */ + toBeGreaterThanOrEqual(number: number): void; + /** + * To compare floating point numbers, you can use toBeLessThan. + */ + toBeLessThan(number: number): void; + /** + * To compare floating point numbers, you can use toBeLessThanOrEqual. + */ + toBeLessThanOrEqual(number: number): void; + /** + * Use .toBeInstanceOf(Class) to check that an object is an instance of a + * class. + */ + toBeInstanceOf(cls: Class<*>): void; + /** + * .toBeNull() is the same as .toBe(null) but the error messages are a bit + * nicer. + */ + toBeNull(): void; + /** + * Use .toBeTruthy when you don't care what a value is, you just want to + * ensure a value is true in a boolean context. + */ + toBeTruthy(): void; + /** + * Use .toBeUndefined to check that a variable is undefined. + */ + toBeUndefined(): void; + /** + * Use .toContain when you want to check that an item is in a list. For + * testing the items in the list, this uses ===, a strict equality check. + */ + toContain(item: any): void; + /** + * Use .toContainEqual when you want to check that an item is in a list. For + * testing the items in the list, this matcher recursively checks the + * equality of all fields, rather than checking for object identity. + */ + toContainEqual(item: any): void; + /** + * Use .toEqual when you want to check that two objects have the same value. + * This matcher recursively checks the equality of all fields, rather than + * checking for object identity. + */ + toEqual(value: any): void; + /** + * Use .toHaveBeenCalled to ensure that a mock function got called. + */ + toHaveBeenCalled(): void; + toBeCalled(): void; + /** + * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact + * number of times. + */ + toHaveBeenCalledTimes(number: number): void; + toBeCalledTimes(number: number): void; + /** + * + */ + toHaveBeenNthCalledWith(nthCall: number, ...args: Array<any>): void; + nthCalledWith(nthCall: number, ...args: Array<any>): void; + /** + * + */ + toHaveReturned(): void; + toReturn(): void; + /** + * + */ + toHaveReturnedTimes(number: number): void; + toReturnTimes(number: number): void; + /** + * + */ + toHaveReturnedWith(value: any): void; + toReturnWith(value: any): void; + /** + * + */ + toHaveLastReturnedWith(value: any): void; + lastReturnedWith(value: any): void; + /** + * + */ + toHaveNthReturnedWith(nthCall: number, value: any): void; + nthReturnedWith(nthCall: number, value: any): void; + /** + * Use .toHaveBeenCalledWith to ensure that a mock function was called with + * specific arguments. + */ + toHaveBeenCalledWith(...args: Array<any>): void; + toBeCalledWith(...args: Array<any>): void; + /** + * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called + * with specific arguments. + */ + toHaveBeenLastCalledWith(...args: Array<any>): void; + lastCalledWith(...args: Array<any>): void; + /** + * Check that an object has a .length property and it is set to a certain + * numeric value. + */ + toHaveLength(number: number): void; + /** + * + */ + toHaveProperty(propPath: string | $ReadOnlyArray<string>, value?: any): void; + /** + * Use .toMatch to check that a string matches a regular expression or string. + */ + toMatch(regexpOrString: RegExp | string): void; + /** + * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. + */ + toMatchObject(object: Object | Array<Object>): void; + /** + * Use .toStrictEqual to check that a javascript object matches a subset of the properties of an object. + */ + toStrictEqual(value: any): void; + /** + * This ensures that an Object matches the most recent snapshot. + */ + toMatchSnapshot(propertyMatchers?: any, name?: string): void; + /** + * This ensures that an Object matches the most recent snapshot. + */ + toMatchSnapshot(name: string): void; + + toMatchInlineSnapshot(snapshot?: string): void; + toMatchInlineSnapshot(propertyMatchers?: any, snapshot?: string): void; + /** + * Use .toThrow to test that a function throws when it is called. + * If you want to test that a specific error gets thrown, you can provide an + * argument to toThrow. The argument can be a string for the error message, + * a class for the error, or a regex that should match the error. + * + * Alias: .toThrowError + */ + toThrow(message?: string | Error | Class<Error> | RegExp): void; + toThrowError(message?: string | Error | Class<Error> | RegExp): void; + /** + * Use .toThrowErrorMatchingSnapshot to test that a function throws a error + * matching the most recent snapshot when it is called. + */ + toThrowErrorMatchingSnapshot(): void; + toThrowErrorMatchingInlineSnapshot(snapshot?: string): void; +} + +type JestObjectType = { + /** + * Disables automatic mocking in the module loader. + * + * After this method is called, all `require()`s will return the real + * versions of each module (rather than a mocked version). + */ + disableAutomock(): JestObjectType, + /** + * An un-hoisted version of disableAutomock + */ + autoMockOff(): JestObjectType, + /** + * Enables automatic mocking in the module loader. + */ + enableAutomock(): JestObjectType, + /** + * An un-hoisted version of enableAutomock + */ + autoMockOn(): JestObjectType, + /** + * Clears the mock.calls and mock.instances properties of all mocks. + * Equivalent to calling .mockClear() on every mocked function. + */ + clearAllMocks(): JestObjectType, + /** + * Resets the state of all mocks. Equivalent to calling .mockReset() on every + * mocked function. + */ + resetAllMocks(): JestObjectType, + /** + * Restores all mocks back to their original value. + */ + restoreAllMocks(): JestObjectType, + /** + * Removes any pending timers from the timer system. + */ + clearAllTimers(): void, + /** + * Returns the number of fake timers still left to run. + */ + getTimerCount(): number, + /** + * The same as `mock` but not moved to the top of the expectation by + * babel-jest. + */ + doMock(moduleName: string, moduleFactory?: any): JestObjectType, + /** + * The same as `unmock` but not moved to the top of the expectation by + * babel-jest. + */ + dontMock(moduleName: string): JestObjectType, + /** + * Returns a new, unused mock function. Optionally takes a mock + * implementation. + */ + fn<TArguments: $ReadOnlyArray<*>, TReturn>( + implementation?: (...args: TArguments) => TReturn + ): JestMockFn<TArguments, TReturn>, + /** + * Determines if the given function is a mocked function. + */ + isMockFunction(fn: Function): boolean, + /** + * Given the name of a module, use the automatic mocking system to generate a + * mocked version of the module for you. + */ + genMockFromModule(moduleName: string): any, + /** + * Mocks a module with an auto-mocked version when it is being required. + * + * The second argument can be used to specify an explicit module factory that + * is being run instead of using Jest's automocking feature. + * + * The third argument can be used to create virtual mocks -- mocks of modules + * that don't exist anywhere in the system. + */ + mock( + moduleName: string, + moduleFactory?: any, + options?: Object + ): JestObjectType, + /** + * Returns the actual module instead of a mock, bypassing all checks on + * whether the module should receive a mock implementation or not. + */ + requireActual<T>(m: $Flow$ModuleRef<T> | string): T, + /** + * Returns a mock module instead of the actual module, bypassing all checks + * on whether the module should be required normally or not. + */ + requireMock(moduleName: string): any, + /** + * Resets the module registry - the cache of all required modules. This is + * useful to isolate modules where local state might conflict between tests. + */ + resetModules(): JestObjectType, + /** + * Creates a sandbox registry for the modules that are loaded inside the + * callback function. This is useful to isolate specific modules for every + * test so that local module state doesn't conflict between tests. + */ + isolateModules(fn: () => void): JestObjectType, + /** + * Exhausts the micro-task queue (usually interfaced in node via + * process.nextTick). + */ + runAllTicks(): void, + /** + * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), + * setInterval(), and setImmediate()). + */ + runAllTimers(): void, + /** + * Exhausts all tasks queued by setImmediate(). + */ + runAllImmediates(): void, + /** + * Executes only the macro task queue (i.e. all tasks queued by setTimeout() + * or setInterval() and setImmediate()). + */ + advanceTimersByTime(msToRun: number): void, + /** + * Executes only the macro task queue (i.e. all tasks queued by setTimeout() + * or setInterval() and setImmediate()). + * + * Renamed to `advanceTimersByTime`. + */ + runTimersToTime(msToRun: number): void, + /** + * Executes only the macro-tasks that are currently pending (i.e., only the + * tasks that have been queued by setTimeout() or setInterval() up to this + * point) + */ + runOnlyPendingTimers(): void, + /** + * Explicitly supplies the mock object that the module system should return + * for the specified module. Note: It is recommended to use jest.mock() + * instead. + */ + setMock(moduleName: string, moduleExports: any): JestObjectType, + /** + * Indicates that the module system should never return a mocked version of + * the specified module from require() (e.g. that it should always return the + * real module). + */ + unmock(moduleName: string): JestObjectType, + /** + * Instructs Jest to use fake versions of the standard timer functions + * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, + * setImmediate and clearImmediate). + */ + useFakeTimers(mode?: 'modern' | 'legacy'): JestObjectType, + /** + * Instructs Jest to use the real versions of the standard timer functions. + */ + useRealTimers(): JestObjectType, + /** + * Creates a mock function similar to jest.fn but also tracks calls to + * object[methodName]. + */ + spyOn( + object: Object, + methodName: string, + accessType?: 'get' | 'set' + ): JestMockFn<any, any>, + /** + * Set the default timeout interval for tests and before/after hooks in milliseconds. + * Note: The default timeout interval is 5 seconds if this method is not called. + */ + setTimeout(timeout: number): JestObjectType, + ... +}; + +type JestSpyType = { calls: JestCallsType, ... }; + +type JestDoneFn = {| + (error?: Error): void, + fail: (error: Error) => void, +|}; + +/** Runs this function after every test inside this context */ +declare function afterEach( + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; +/** Runs this function before every test inside this context */ +declare function beforeEach( + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; +/** Runs this function after all tests have finished inside this context */ +declare function afterAll( + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; +/** Runs this function before any tests have started inside this context */ +declare function beforeAll( + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; + +/** A context for grouping tests together */ +declare var describe: { + /** + * Creates a block that groups together several related tests in one "test suite" + */ + (name: JestTestName, fn: () => void): void, + /** + * Only run this describe block + */ + only(name: JestTestName, fn: () => void): void, + /** + * Skip running this describe block + */ + skip(name: JestTestName, fn: () => void): void, + /** + * each runs this test against array of argument arrays per each run + * + * @param {table} table of Test + */ + each( + ...table: Array<Array<mixed> | mixed> | [Array<string>, string] + ): ( + name: JestTestName, + fn?: (...args: Array<any>) => ?Promise<mixed>, + timeout?: number + ) => void, + ... +}; + +/** An individual test unit */ +declare var it: { + /** + * An individual test unit + * + * @param {JestTestName} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + ( + name: JestTestName, + fn?: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number + ): void, + /** + * Only run this test + * + * @param {JestTestName} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + only: {| + ( + name: JestTestName, + fn?: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number + ): void, + each( + ...table: Array<Array<mixed> | mixed> | [Array<string>, string] + ): ( + name: JestTestName, + fn?: (...args: Array<any>) => ?Promise<mixed>, + timeout?: number + ) => void, + |}, + /** + * Skip running this test + * + * @param {JestTestName} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + skip( + name: JestTestName, + fn?: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number + ): void, + /** + * Highlight planned tests in the summary output + * + * @param {String} Name of Test to do + */ + todo(name: string): void, + /** + * Run the test concurrently + * + * @param {JestTestName} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + concurrent( + name: JestTestName, + fn?: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number + ): void, + /** + * each runs this test against array of argument arrays per each run + * + * @param {table} table of Test + */ + each( + ...table: Array<Array<mixed> | mixed> | [Array<string>, string] + ): ( + name: JestTestName, + fn?: (...args: Array<any>) => ?Promise<mixed>, + timeout?: number + ) => void, + ... +}; + +declare function fit( + name: JestTestName, + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; +/** An individual test unit */ +declare var test: typeof it; +/** A disabled group of tests */ +declare var xdescribe: typeof describe; +/** A focused group of tests */ +declare var fdescribe: typeof describe; +/** A disabled individual test */ +declare var xit: typeof it; +/** A disabled individual test */ +declare var xtest: typeof it; + +type JestPrettyFormatColors = { + comment: { + close: string, + open: string, + ... + }, + content: { + close: string, + open: string, + ... + }, + prop: { + close: string, + open: string, + ... + }, + tag: { + close: string, + open: string, + ... + }, + value: { + close: string, + open: string, + ... + }, + ... +}; + +type JestPrettyFormatIndent = (string) => string; +type JestPrettyFormatRefs = Array<any>; +type JestPrettyFormatPrint = (any) => string; +type JestPrettyFormatStringOrNull = string | null; + +type JestPrettyFormatOptions = {| + callToJSON: boolean, + edgeSpacing: string, + escapeRegex: boolean, + highlight: boolean, + indent: number, + maxDepth: number, + min: boolean, + plugins: JestPrettyFormatPlugins, + printFunctionName: boolean, + spacing: string, + theme: {| + comment: string, + content: string, + prop: string, + tag: string, + value: string, + |}, +|}; + +type JestPrettyFormatPlugin = { + print: ( + val: any, + serialize: JestPrettyFormatPrint, + indent: JestPrettyFormatIndent, + opts: JestPrettyFormatOptions, + colors: JestPrettyFormatColors + ) => string, + test: (any) => boolean, + ... +}; + +type JestPrettyFormatPlugins = Array<JestPrettyFormatPlugin>; + +/** The expect function is used every time you want to test a value */ +declare var expect: { + /** The object that you want to make assertions against */ + ( + value: any + ): JestExpectType & + JestPromiseType & + EnzymeMatchersType & + DomTestingLibraryType & + JestJQueryMatchersType & + JestStyledComponentsMatchersType & + JestExtendedMatchersType & + SnapshotDiffType, + /** Add additional Jasmine matchers to Jest's roster */ + extend(matchers: { [name: string]: JestMatcher, ... }): void, + /** Add a module that formats application-specific data structures. */ + addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void, + assertions(expectedAssertions: number): void, + hasAssertions(): void, + any(value: mixed): JestAsymmetricEqualityType, + anything(): any, + arrayContaining(value: Array<mixed>): Array<mixed>, + objectContaining(value: Object): Object, + /** Matches any received string that contains the exact expected string. */ + stringContaining(value: string): string, + stringMatching(value: string | RegExp): string, + not: { + arrayContaining: (value: $ReadOnlyArray<mixed>) => Array<mixed>, + objectContaining: (value: { ... }) => Object, + stringContaining: (value: string) => string, + stringMatching: (value: string | RegExp) => string, + ... + }, + ... +}; + +// TODO handle return type +// http://jasmine.github.io/2.4/introduction.html#section-Spies +declare function spyOn(value: mixed, method: string): Object; + +/** Holds all functions related to manipulating test runner */ +declare var jest: JestObjectType; + +/** + * The global Jasmine object, this is generally not exposed as the public API, + * using features inside here could break in later versions of Jest. + */ +declare var jasmine: { + DEFAULT_TIMEOUT_INTERVAL: number, + any(value: mixed): JestAsymmetricEqualityType, + anything(): any, + arrayContaining(value: Array<mixed>): Array<mixed>, + clock(): JestClockType, + createSpy(name: string): JestSpyType, + createSpyObj( + baseName: string, + methodNames: Array<string> + ): { [methodName: string]: JestSpyType, ... }, + objectContaining(value: Object): Object, + stringMatching(value: string): string, + ... +}; diff --git a/client/flow-typed/npm/react-dom_v16.x.x.js b/client/flow-typed/npm/react-dom_v16.x.x.js index 889928b99690c4c10226361659cc07dac9169ba6..f9fef8e40bcec2f4f0c6846b04bb6a869883b12c 100644 --- a/client/flow-typed/npm/react-dom_v16.x.x.js +++ b/client/flow-typed/npm/react-dom_v16.x.x.js @@ -1,110 +1,110 @@ -// flow-typed signature: a333d1cdbb5a4103d0be63a412070e22 -// flow-typed version: b2693c1879/react-dom_v16.x.x/flow_>=v0.117.x - -declare module 'react-dom' { - declare function findDOMNode( - componentOrElement: Element | ?React$Component<any, any>, - ): null | Element | Text; - - declare function render<ElementType: React$ElementType>( - element: React$Element<ElementType>, - container: Element, - callback?: () => void, - ): React$ElementRef<ElementType>; - - declare function hydrate<ElementType: React$ElementType>( - element: React$Element<ElementType>, - container: Element, - callback?: () => void, - ): React$ElementRef<ElementType>; - - declare function createPortal( - node: React$Node, - container: Element, - ): React$Portal; - - declare function unmountComponentAtNode(container: any): boolean; - declare var version: string; - - declare function unstable_batchedUpdates<A, B, C, D, E>( - callback: (a: A, b: B, c: C, d: D, e: E) => mixed, - a: A, - b: B, - c: C, - d: D, - e: E, - ): void; - declare function unstable_renderSubtreeIntoContainer< - ElementType: React$ElementType, - >( - parentComponent: React$Component<any, any>, - nextElement: React$Element<ElementType>, - container: any, - callback?: () => void, - ): React$ElementRef<ElementType>; -} - -declare module 'react-dom/server' { - declare function renderToString(element: React$Node): string; - declare function renderToStaticMarkup(element: React$Node): string; - declare function renderToNodeStream(element: React$Node): stream$Readable; - declare function renderToStaticNodeStream( - element: React$Node, - ): stream$Readable; - declare var version: string; -} - -type Thenable = { then(resolve: () => mixed, reject?: () => mixed): mixed, ... }; - -declare module 'react-dom/test-utils' { - declare var Simulate: { [eventName: string]: (element: Element, eventData?: Object) => void, ... }; - declare function renderIntoDocument( - instance: React$Element<any>, - ): React$Component<any, any>; - declare function mockComponent( - componentClass: React$ElementType, - mockTagName?: string, - ): Object; - declare function isElement(element: React$Element<any>): boolean; - declare function isElementOfType( - element: React$Element<any>, - componentClass: React$ElementType, - ): boolean; - declare function isDOMComponent(instance: any): boolean; - declare function isCompositeComponent( - instance: React$Component<any, any>, - ): boolean; - declare function isCompositeComponentWithType( - instance: React$Component<any, any>, - componentClass: React$ElementType, - ): boolean; - declare function findAllInRenderedTree( - tree: React$Component<any, any>, - test: (child: React$Component<any, any>) => boolean, - ): Array<React$Component<any, any>>; - declare function scryRenderedDOMComponentsWithClass( - tree: React$Component<any, any>, - className: string, - ): Array<Element>; - declare function findRenderedDOMComponentWithClass( - tree: React$Component<any, any>, - className: string, - ): ?Element; - declare function scryRenderedDOMComponentsWithTag( - tree: React$Component<any, any>, - tagName: string, - ): Array<Element>; - declare function findRenderedDOMComponentWithTag( - tree: React$Component<any, any>, - tagName: string, - ): ?Element; - declare function scryRenderedComponentsWithType( - tree: React$Component<any, any>, - componentClass: React$ElementType, - ): Array<React$Component<any, any>>; - declare function findRenderedComponentWithType( - tree: React$Component<any, any>, - componentClass: React$ElementType, - ): ?React$Component<any, any>; - declare function act(callback: () => void | Thenable): Thenable; -} +// flow-typed signature: a333d1cdbb5a4103d0be63a412070e22 +// flow-typed version: b2693c1879/react-dom_v16.x.x/flow_>=v0.117.x + +declare module 'react-dom' { + declare function findDOMNode( + componentOrElement: Element | ?React$Component<any, any>, + ): null | Element | Text; + + declare function render<ElementType: React$ElementType>( + element: React$Element<ElementType>, + container: Element, + callback?: () => void, + ): React$ElementRef<ElementType>; + + declare function hydrate<ElementType: React$ElementType>( + element: React$Element<ElementType>, + container: Element, + callback?: () => void, + ): React$ElementRef<ElementType>; + + declare function createPortal( + node: React$Node, + container: Element, + ): React$Portal; + + declare function unmountComponentAtNode(container: any): boolean; + declare var version: string; + + declare function unstable_batchedUpdates<A, B, C, D, E>( + callback: (a: A, b: B, c: C, d: D, e: E) => mixed, + a: A, + b: B, + c: C, + d: D, + e: E, + ): void; + declare function unstable_renderSubtreeIntoContainer< + ElementType: React$ElementType, + >( + parentComponent: React$Component<any, any>, + nextElement: React$Element<ElementType>, + container: any, + callback?: () => void, + ): React$ElementRef<ElementType>; +} + +declare module 'react-dom/server' { + declare function renderToString(element: React$Node): string; + declare function renderToStaticMarkup(element: React$Node): string; + declare function renderToNodeStream(element: React$Node): stream$Readable; + declare function renderToStaticNodeStream( + element: React$Node, + ): stream$Readable; + declare var version: string; +} + +type Thenable = { then(resolve: () => mixed, reject?: () => mixed): mixed, ... }; + +declare module 'react-dom/test-utils' { + declare var Simulate: { [eventName: string]: (element: Element, eventData?: Object) => void, ... }; + declare function renderIntoDocument( + instance: React$Element<any>, + ): React$Component<any, any>; + declare function mockComponent( + componentClass: React$ElementType, + mockTagName?: string, + ): Object; + declare function isElement(element: React$Element<any>): boolean; + declare function isElementOfType( + element: React$Element<any>, + componentClass: React$ElementType, + ): boolean; + declare function isDOMComponent(instance: any): boolean; + declare function isCompositeComponent( + instance: React$Component<any, any>, + ): boolean; + declare function isCompositeComponentWithType( + instance: React$Component<any, any>, + componentClass: React$ElementType, + ): boolean; + declare function findAllInRenderedTree( + tree: React$Component<any, any>, + test: (child: React$Component<any, any>) => boolean, + ): Array<React$Component<any, any>>; + declare function scryRenderedDOMComponentsWithClass( + tree: React$Component<any, any>, + className: string, + ): Array<Element>; + declare function findRenderedDOMComponentWithClass( + tree: React$Component<any, any>, + className: string, + ): ?Element; + declare function scryRenderedDOMComponentsWithTag( + tree: React$Component<any, any>, + tagName: string, + ): Array<Element>; + declare function findRenderedDOMComponentWithTag( + tree: React$Component<any, any>, + tagName: string, + ): ?Element; + declare function scryRenderedComponentsWithType( + tree: React$Component<any, any>, + componentClass: React$ElementType, + ): Array<React$Component<any, any>>; + declare function findRenderedComponentWithType( + tree: React$Component<any, any>, + componentClass: React$ElementType, + ): ?React$Component<any, any>; + declare function act(callback: () => void | Thenable): Thenable; +} diff --git a/client/flow-typed/npm/react-router-dom_v5.x.x.js b/client/flow-typed/npm/react-router-dom_v5.x.x.js index 68e6c5a726fd6de231ff0b76d7892a6ac614d383..7254b5f9e80d40e53e381346ce6145b1435ffad9 100644 --- a/client/flow-typed/npm/react-router-dom_v5.x.x.js +++ b/client/flow-typed/npm/react-router-dom_v5.x.x.js @@ -1,181 +1,181 @@ -// flow-typed signature: 33bc320ebb5343629e228a9caa367310 -// flow-typed version: c4f47bdda4/react-router-dom_v5.x.x/flow_>=v0.104.x - -declare module "react-router-dom" { - declare export var BrowserRouter: React$ComponentType<{| - basename?: string, - forceRefresh?: boolean, - getUserConfirmation?: GetUserConfirmation, - keyLength?: number, - children?: React$Node - |}> - - declare export var HashRouter: React$ComponentType<{| - basename?: string, - getUserConfirmation?: GetUserConfirmation, - hashType?: "slash" | "noslash" | "hashbang", - children?: React$Node - |}> - - declare export var Link: React$ComponentType<{ - +className?: string, - +to: string | LocationShape, - +replace?: boolean, - +children?: React$Node, - ... - }> - - declare export var NavLink: React$ComponentType<{ - +to: string | LocationShape, - +activeClassName?: string, - +className?: string, - +activeStyle?: { +[string]: mixed, ... }, - +style?: { +[string]: mixed, ... }, - +isActive?: (match: Match, location: Location) => boolean, - +children?: React$Node, - +exact?: boolean, - +strict?: boolean, - ... - }> - - // NOTE: Below are duplicated from react-router. If updating these, please - // update the react-router and react-router-native types as well. - declare export type Location = { - pathname: string, - search: string, - hash: string, - ... - }; - - declare export type LocationShape = { - pathname?: string, - search?: string, - hash?: string, - ... - }; - - declare export type HistoryAction = "PUSH" | "REPLACE" | "POP"; - - declare export type RouterHistory = { - length: number, - location: Location, - action: HistoryAction, - listen( - callback: (location: Location, action: HistoryAction) => void - ): () => void, - push(path: string | LocationShape, state?: any): void, - replace(path: string | LocationShape, state?: any): void, - go(n: number): void, - goBack(): void, - goForward(): void, - canGo?: (n: number) => boolean, - block( - callback: string | (location: Location, action: HistoryAction) => ?string - ): () => void, - ... - }; - - declare export type Match = { - params: { [key: string]: ?string, ... }, - isExact: boolean, - path: string, - url: string, - ... - }; - - declare export type ContextRouter = {| - history: RouterHistory, - location: Location, - match: Match, - staticContext?: StaticRouterContext - |}; - - declare type ContextRouterVoid = { - history: RouterHistory | void, - location: Location | void, - match: Match | void, - staticContext?: StaticRouterContext | void, - ... - }; - - declare export type GetUserConfirmation = ( - message: string, - callback: (confirmed: boolean) => void - ) => void; - - declare export type StaticRouterContext = { url?: string, ... }; - - declare export var StaticRouter: React$ComponentType<{| - basename?: string, - location?: string | Location, - context: StaticRouterContext, - children?: React$Node - |}> - - declare export var MemoryRouter: React$ComponentType<{| - initialEntries?: Array<LocationShape | string>, - initialIndex?: number, - getUserConfirmation?: GetUserConfirmation, - keyLength?: number, - children?: React$Node - |}> - - declare export var Router: React$ComponentType<{| - history: RouterHistory, - children?: React$Node - |}> - - declare export var Prompt: React$ComponentType<{| - message: string | ((location: Location) => string | boolean), - when?: boolean - |}> - - declare export var Redirect: React$ComponentType<{| - to: string | LocationShape, - push?: boolean, - from?: string, - exact?: boolean, - strict?: boolean - |}> - - declare export var Route: React$ComponentType<{| - component?: React$ComponentType<*>, - render?: (router: ContextRouter) => React$Node, - children?: React$ComponentType<ContextRouter> | React$Node, - path?: string | Array<string>, - exact?: boolean, - strict?: boolean, - location?: LocationShape, - sensitive?: boolean - |}> - - declare export var Switch: React$ComponentType<{| - children?: React$Node, - location?: Location - |}> - - declare export function withRouter<Props: {...}, Component: React$ComponentType<Props>>( - WrappedComponent: Component - ): React$ComponentType<$Diff<React$ElementConfig<Component>, ContextRouterVoid>>; - - declare type MatchPathOptions = { - path?: string | string[], - exact?: boolean, - sensitive?: boolean, - strict?: boolean, - ... - }; - - declare export function matchPath( - pathname: string, - options?: MatchPathOptions | string | string[], - parent?: Match - ): null | Match; - - declare export function useHistory(): $PropertyType<ContextRouter, 'history'>; - declare export function useLocation(): $PropertyType<ContextRouter, 'location'>; - declare export function useParams(): $PropertyType<$PropertyType<ContextRouter, 'match'>, 'params'>; - declare export function useRouteMatch(path?: MatchPathOptions | string | string[]): $PropertyType<ContextRouter, 'match'>; - - declare export function generatePath(pattern?: string, params?: { +[string]: mixed, ... }): string; -} +// flow-typed signature: 33bc320ebb5343629e228a9caa367310 +// flow-typed version: c4f47bdda4/react-router-dom_v5.x.x/flow_>=v0.104.x + +declare module "react-router-dom" { + declare export var BrowserRouter: React$ComponentType<{| + basename?: string, + forceRefresh?: boolean, + getUserConfirmation?: GetUserConfirmation, + keyLength?: number, + children?: React$Node + |}> + + declare export var HashRouter: React$ComponentType<{| + basename?: string, + getUserConfirmation?: GetUserConfirmation, + hashType?: "slash" | "noslash" | "hashbang", + children?: React$Node + |}> + + declare export var Link: React$ComponentType<{ + +className?: string, + +to: string | LocationShape, + +replace?: boolean, + +children?: React$Node, + ... + }> + + declare export var NavLink: React$ComponentType<{ + +to: string | LocationShape, + +activeClassName?: string, + +className?: string, + +activeStyle?: { +[string]: mixed, ... }, + +style?: { +[string]: mixed, ... }, + +isActive?: (match: Match, location: Location) => boolean, + +children?: React$Node, + +exact?: boolean, + +strict?: boolean, + ... + }> + + // NOTE: Below are duplicated from react-router. If updating these, please + // update the react-router and react-router-native types as well. + declare export type Location = { + pathname: string, + search: string, + hash: string, + ... + }; + + declare export type LocationShape = { + pathname?: string, + search?: string, + hash?: string, + ... + }; + + declare export type HistoryAction = "PUSH" | "REPLACE" | "POP"; + + declare export type RouterHistory = { + length: number, + location: Location, + action: HistoryAction, + listen( + callback: (location: Location, action: HistoryAction) => void + ): () => void, + push(path: string | LocationShape, state?: any): void, + replace(path: string | LocationShape, state?: any): void, + go(n: number): void, + goBack(): void, + goForward(): void, + canGo?: (n: number) => boolean, + block( + callback: string | (location: Location, action: HistoryAction) => ?string + ): () => void, + ... + }; + + declare export type Match = { + params: { [key: string]: ?string, ... }, + isExact: boolean, + path: string, + url: string, + ... + }; + + declare export type ContextRouter = {| + history: RouterHistory, + location: Location, + match: Match, + staticContext?: StaticRouterContext + |}; + + declare type ContextRouterVoid = { + history: RouterHistory | void, + location: Location | void, + match: Match | void, + staticContext?: StaticRouterContext | void, + ... + }; + + declare export type GetUserConfirmation = ( + message: string, + callback: (confirmed: boolean) => void + ) => void; + + declare export type StaticRouterContext = { url?: string, ... }; + + declare export var StaticRouter: React$ComponentType<{| + basename?: string, + location?: string | Location, + context: StaticRouterContext, + children?: React$Node + |}> + + declare export var MemoryRouter: React$ComponentType<{| + initialEntries?: Array<LocationShape | string>, + initialIndex?: number, + getUserConfirmation?: GetUserConfirmation, + keyLength?: number, + children?: React$Node + |}> + + declare export var Router: React$ComponentType<{| + history: RouterHistory, + children?: React$Node + |}> + + declare export var Prompt: React$ComponentType<{| + message: string | ((location: Location) => string | boolean), + when?: boolean + |}> + + declare export var Redirect: React$ComponentType<{| + to: string | LocationShape, + push?: boolean, + from?: string, + exact?: boolean, + strict?: boolean + |}> + + declare export var Route: React$ComponentType<{| + component?: React$ComponentType<*>, + render?: (router: ContextRouter) => React$Node, + children?: React$ComponentType<ContextRouter> | React$Node, + path?: string | Array<string>, + exact?: boolean, + strict?: boolean, + location?: LocationShape, + sensitive?: boolean + |}> + + declare export var Switch: React$ComponentType<{| + children?: React$Node, + location?: Location + |}> + + declare export function withRouter<Props: {...}, Component: React$ComponentType<Props>>( + WrappedComponent: Component + ): React$ComponentType<$Diff<React$ElementConfig<Component>, ContextRouterVoid>>; + + declare type MatchPathOptions = { + path?: string | string[], + exact?: boolean, + sensitive?: boolean, + strict?: boolean, + ... + }; + + declare export function matchPath( + pathname: string, + options?: MatchPathOptions | string | string[], + parent?: Match + ): null | Match; + + declare export function useHistory(): $PropertyType<ContextRouter, 'history'>; + declare export function useLocation(): $PropertyType<ContextRouter, 'location'>; + declare export function useParams(): $PropertyType<$PropertyType<ContextRouter, 'match'>, 'params'>; + declare export function useRouteMatch(path?: MatchPathOptions | string | string[]): $PropertyType<ContextRouter, 'match'>; + + declare export function generatePath(pattern?: string, params?: { +[string]: mixed, ... }): string; +} diff --git a/client/package.json b/client/package.json index 5676d8d75906e8e2ca425dfa2867050c3596df5f..d6f01db28b3097059ffd08f81ca5ff78779a8072 100644 --- a/client/package.json +++ b/client/package.json @@ -1,43 +1,43 @@ -{ - "name": "todo-client", - "version": "1.0.0", - "description": "A simple Todo web client", - "license": "MIT", - "scripts": { - "start": "webpack --mode development --watch", - "test": "jest --setupFiles ./test/setup" - }, - "jest": { - "snapshotSerializers": [ - "enzyme-to-json/serializer" - ], - "collectCoverage": true - }, - "browserslist": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ], - "dependencies": { - "axios": "^0.20.0", - "react-router-dom": "^5.2.0", - "react-simplified": "^2.0.1" - }, - "devDependencies": { - "@babel/core": "^7.11.6", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/preset-env": "^7.11.5", - "@babel/preset-flow": "^7.10.4", - "@babel/preset-react": "^7.10.4", - "babel-jest": "^26.3.0", - "babel-loader": "^8.1.0", - "enzyme": "^3.11.0", - "enzyme-adapter-react-16": "^1.15.4", - "enzyme-to-json": "^3.5.0", - "flow-bin": "^0.134.0", - "jest": "^26.4.2", - "prettier": "^2.1.1", - "webpack": "^4.44.1", - "webpack-cli": "^3.3.12" - } -} +{ + "name": "todo-client", + "version": "1.0.0", + "description": "A simple Todo web client", + "license": "MIT", + "scripts": { + "start": "webpack --mode development --watch", + "test": "jest --setupFiles ./test/setup" + }, + "jest": { + "snapshotSerializers": [ + "enzyme-to-json/serializer" + ], + "collectCoverage": true + }, + "browserslist": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ], + "dependencies": { + "axios": "^0.20.0", + "react-router-dom": "^5.2.0", + "react-simplified": "^2.0.1" + }, + "devDependencies": { + "@babel/core": "^7.11.6", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/preset-env": "^7.11.5", + "@babel/preset-flow": "^7.10.4", + "@babel/preset-react": "^7.10.4", + "babel-jest": "^26.3.0", + "babel-loader": "^8.1.0", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.4", + "enzyme-to-json": "^3.5.0", + "flow-bin": "^0.134.0", + "jest": "^26.4.2", + "prettier": "^2.1.1", + "webpack": "^4.44.1", + "webpack-cli": "^3.3.12" + } +} diff --git a/client/public/bootstrap.min.css b/client/public/bootstrap.min.css index 92e3fe871295c44f8fa58ddc7ac242463f13e6bd..9beb5410477fd6fd10820f26fa95f388a4c60e65 100644 --- a/client/public/bootstrap.min.css +++ b/client/public/bootstrap.min.css @@ -1,7 +1,7 @@ -/*! - * Bootstrap v4.3.1 (https://getbootstrap.com/) - * Copyright 2011-2019 The Bootstrap Authors - * Copyright 2011-2019 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #dee2e6;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*! + * Bootstrap v4.3.1 (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #dee2e6;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} /*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/client/public/index.html b/client/public/index.html index 1b41e2c010ec9669bfcfec300bed226e46d919ab..8da0bfcb6efe2e5a7294afbdf97ac691f6eb3b62 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -1,13 +1,13 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="UTF-8" /> - <title>Todo web application example</title> - <link rel="stylesheet" href="bootstrap.min.css" /> - </head> - <body> - <div id="root"></div> - <!-- Embed React application bundled by webpack and babel --> - <script src="bundle.js"></script> - </body> -</html> +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8" /> + <title>Todo web application example</title> + <link rel="stylesheet" href="bootstrap.min.css" /> + </head> + <body> + <div id="root"></div> + <!-- Embed React application bundled by webpack and babel --> + <script src="bundle.js"></script> + </body> +</html> diff --git a/client/src/index.js b/client/src/index.js index 5c33ce11d58dccb3f96af5b25cfc0bd7b1cfbf41..a5067e3fc935a8426e2150523481729f270ff1f2 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -1,41 +1,77 @@ -// @flow - -import ReactDOM from 'react-dom'; -import * as React from 'react'; -import { Component } from 'react-simplified'; -import { HashRouter, Route } from 'react-router-dom'; -import { NavBar, Card, Alert } from './widgets'; -import { TaskList, TaskDetails, TaskEdit, TaskNew } from './task-components'; - -class Menu extends Component { - render() { - return ( - <NavBar brand="Todo App"> - <NavBar.Link to="/tasks">Tasks</NavBar.Link> - </NavBar> - ); - } -} - -class Home extends Component { - render() { - return <Card title="Welcome">This is Todo App</Card>; - } -} - -const root = document.getElementById('root'); -if (root) - ReactDOM.render( - <HashRouter> - <div> - <Alert /> - <Menu /> - <Route exact path="/" component={Home} /> - <Route exact path="/tasks" component={TaskList} /> - <Route exact path="/tasks/:id(\d+)" component={TaskDetails} /> {/* id must be number */} - <Route exact path="/tasks/:id(\d+)/edit" component={TaskEdit} /> {/* id must be number */} - <Route exact path="/tasks/new" component={TaskNew} /> - </div> - </HashRouter>, - root - ); +// @flow + +import ReactDOM from 'react-dom'; +import * as React from 'react'; +import { Component } from 'react-simplified'; +import { Alert, Card, Row, Column, Form, Button } from './widgets'; +import appService from './task-service'; + +class App extends Component { + code: string = ''; + stOutput: string = ''; + stError: string = ''; + stExit: number = 0; + + render() { + return ( + <> + <Card> + App.js + <Row> + <Column> + <Form.Textarea + type="text" + value={this.code} + onChange={(event) => (this.code = event.currentTarget.value)} + rows={10} + /> + </Column> + </Row> + <Button.Success + onClick={() => + appService.send(this.code).then((response) => { + (this.stOutput = response.data[0]), + (this.stError = response.data[1]), + (this.stExit = response.data[2]); + console.log(this.stExit); + }) + } + > + Run + </Button.Success> + </Card> + <Card> + Standard Output: + <Form.Label>{this.stOutput}</Form.Label> + </Card> + <Card> + Standard Error: + <Form.Label>{this.stError}</Form.Label> + </Card> + <Card> + Standard Exit Status: + <Form.Label>{this.stExit}</Form.Label> + </Card> + </> + ); + } + + mounted() {} + + // func() { + // appService.send(this.code).then((response) => { + // (this.stOutput = response.data[0]), + // (this.stError = response.data[1]), + // (this.stExit = response.data[2]); + // }); + // } +} + +const root = document.getElementById('root'); +if (root) + ReactDOM.render( + <> + <App /> + </>, + root + ); diff --git a/client/src/task-components.js b/client/src/task-components.js index 6a92ddeaa58a3c0590ef43fbdb2cdd722f4cd056..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/client/src/task-components.js +++ b/client/src/task-components.js @@ -1,188 +0,0 @@ -// @flow - -import * as React from 'react'; -import { Component } from 'react-simplified'; -import { Alert, Card, Row, Column, Form, Button, NavBar } from './widgets'; -import { NavLink } from 'react-router-dom'; -import taskService, { type Task } from './task-service'; -import { createHashHistory } from 'history'; - -const history = createHashHistory(); // Use history.push(...) to programmatically change path, for instance after successfully saving a student - -/** - * Renders task list. - */ -export class TaskList extends Component { - tasks: Task[] = []; - - render() { - return ( - <> - <Card title="Tasks"> - {this.tasks.map((task) => ( - <Row key={task.id}> - <Column> - <NavLink to={'/tasks/' + task.id}>{task.title}</NavLink> - </Column> - </Row> - ))} - </Card> - <Button.Success onClick={() => history.push('/tasks/new')}>New task</Button.Success> - </> - ); - } - - mounted() { - taskService - .getAll() - .then((tasks) => (this.tasks = tasks)) - .catch((error: Error) => Alert.danger('Error getting tasks: ' + error.message)); - } -} - -/** - * Renders a specific task. - */ -export class TaskDetails extends Component<{ match: { params: { id: number } } }> { - task: Task = { id: 0, title: '', done: false }; - - render() { - return ( - <> - <Card title="Task"> - <Row> - <Column width={2}>Title:</Column> - <Column>{this.task.title}</Column> - </Row> - <Row> - <Column width={2}>Description:</Column> - </Row> - <Row> - <Column width={2}>Done:</Column> - <Column> - <Form.Checkbox checked={this.task.done} onChange={() => {}} disabled /> - </Column> - </Row> - </Card> - <Button.Success - onClick={() => history.push('/tasks/' + this.props.match.params.id + '/edit')} - > - Edit - </Button.Success> - </> - ); - } - - mounted() { - taskService - .get(this.props.match.params.id) - .then((task) => (this.task = task)) - .catch((error: Error) => Alert.danger('Error getting task: ' + error.message)); - } -} - -/** - * Renders form to edit a specific task. - */ -export class TaskEdit extends Component<{ match: { params: { id: number } } }> { - task: Task = { id: 0, title: '', done: false }; - - render() { - return ( - <> - <Card title="Edit task"> - <Row> - <Column width={2}> - <Form.Label>Title:</Form.Label> - </Column> - <Column> - <Form.Input - type="text" - value={this.task.title} - onChange={(event) => (this.task.title = event.currentTarget.value)} - /> - </Column> - </Row> - <Row> - <Column width={2}> - <Form.Label>Description:</Form.Label> - </Column> - <Column> - <Form.Textarea value="" onChange={() => {}} rows={10} disabled /> - </Column> - </Row> - <Row> - <Column width={2}>Done:</Column> - <Column> - <Form.Checkbox - checked={this.task.done} - onChange={(event) => (this.task.done = event.currentTarget.checked)} - /> - </Column> - </Row> - </Card> - <Row> - <Column> - <Button.Success onClick={() => Alert.info('Not yet implemented')}>Save</Button.Success> - </Column> - <Column right> - <Button.Danger onClick={() => Alert.info('Not yet implemented')}>Delete</Button.Danger> - </Column> - </Row> - </> - ); - } - - mounted() { - taskService - .get(this.props.match.params.id) - .then((task) => (this.task = task)) - .catch((error: Error) => Alert.danger('Error getting task: ' + error.message)); - } -} - -/** - * Renders form to create new task. - */ -export class TaskNew extends Component { - title = ''; - - render() { - return ( - <> - <Card title="New task"> - <Row> - <Column width={2}> - <Form.Label>Title:</Form.Label> - </Column> - <Column> - <Form.Input - type="text" - value={this.title} - onChange={(event) => (this.title = event.currentTarget.value)} - /> - </Column> - </Row> - <Row> - <Column width={2}> - <Form.Label>Description:</Form.Label> - </Column> - <Column> - <Form.Textarea value="" onChange={() => {}} rows={10} disabled /> - </Column> - </Row> - </Card> - <Button.Success - onClick={() => { - taskService - .create(this.title) - .then((id) => history.push('/tasks/' + id)) - .catch((error: Error) => Alert.danger('Error creating task: ' + error.message)); - }} - > - Create - </Button.Success> - </> - ); - } -} diff --git a/client/src/task-service.js b/client/src/task-service.js index e804f4cdfef15642c9627efb29acd7774d7e0fe3..d45821e6faf4cf770deedd6d75b7e63a9c94cdf2 100644 --- a/client/src/task-service.js +++ b/client/src/task-service.js @@ -1,40 +1,16 @@ -// @flow -import axios from 'axios'; - -axios.defaults.baseURL = 'http://localhost:3000/api/v2'; - -export type Task = { - id: number, - title: string, - done: boolean, -}; - -class TaskService { - /** - * Get task with given id. - */ - get(id: number) { - return axios.get<Task>('/tasks/' + id).then((response) => response.data); - } - - /** - * Get all tasks. - */ - getAll() { - return axios.get<Task[]>('/tasks').then((response) => response.data); - } - - /** - * Create new task having the given title. - * - * Resolves the newly created task id. - */ - create(title: string) { - return axios - .post<{}, { id: number }>('/tasks', { title: title }) - .then((response) => response.data.id); - } -} - -const taskService = new TaskService(); -export default taskService; +// @flow +import axios from 'axios'; + +axios.defaults.baseURL = 'http://localhost:3000/api/v2'; + +class AppService { + send(code: string) { + return axios.post<{}, { code: string }>('/', { code: code }); + /* .then((response) => { + response.data; + });*/ + } +} + +const appService = new AppService(); +export default appService; diff --git a/client/src/widgets.js b/client/src/widgets.js index 19417347e32533b5df7fefed0f1fe119b616f6b3..d6abeed0c1fcdf00b98d9bfb7b6f9cdca2ad1acd 100644 --- a/client/src/widgets.js +++ b/client/src/widgets.js @@ -1,315 +1,315 @@ -// @flow - -import * as React from 'react'; -import { Component } from 'react-simplified'; -import { NavLink } from 'react-router-dom'; - -/** - * Renders alert messages using Bootstrap classes. - */ -export class Alert extends Component { - alerts: { id: number, text: React.Node, type: string }[] = []; - nextId = 0; - - render() { - return ( - <> - {this.alerts.map((alert, i) => ( - <div key={alert.id} className={'alert alert-' + alert.type} role="alert"> - {alert.text} - <button type="button" className="close" onClick={() => this.alerts.splice(i, 1)}> - × - </button> - </div> - ))} - </> - ); - } - - /** - * Show success alert. - */ - static success(text: React.Node) { - // To avoid 'Cannot update during an existing state transition' errors, run after current event through setTimeout - setTimeout(() => { - const instance = Alert.instance(); // Get rendered Alert component instance - instance?.alerts.push({ id: instance.nextId++, text: text, type: 'success' }); - }); - } - - /** - * Show info alert. - */ - static info(text: React.Node) { - // To avoid 'Cannot update during an existing state transition' errors, run after current event through setTimeout - setTimeout(() => { - const instance = Alert.instance(); // Get rendered Alert component instance - instance?.alerts.push({ id: instance.nextId++, text: text, type: 'info' }); - }); - } - - /** - * Show warning alert. - */ - static warning(text: React.Node) { - // To avoid 'Cannot update during an existing state transition' errors, run after current event through setTimeout - setTimeout(() => { - const instance = Alert.instance(); // Get rendered Alert component instance - instance?.alerts.push({ id: instance.nextId++, text: text, type: 'warning' }); - }); - } - - /** - * Show danger alert. - */ - static danger(text: React.Node) { - // To avoid 'Cannot update during an existing state transition' errors, run after current event through setTimeout - setTimeout(() => { - const instance = Alert.instance(); // Get rendered Alert component instance - instance?.alerts.push({ id: instance.nextId++, text: text, type: 'danger' }); - }); - } -} - -/** - * Renders an information card using Bootstrap classes. - */ -export class Card extends Component<{ title?: React.Node, children?: React.Node }> { - render() { - return ( - <div className="card"> - <div className="card-body"> - <h5 className="card-title">{this.props.title}</h5> - <div className="card-text">{this.props.children}</div> - </div> - </div> - ); - } -} - -/** - * Renders a row using Bootstrap classes. - */ -export class Row extends Component<{ children?: React.Node }> { - render() { - return <div className="row">{this.props.children}</div>; - } -} - -/** - * Renders a column with specified width using Bootstrap classes. - */ -export class Column extends Component<{ width?: number, right?: boolean, children?: React.Node }> { - render() { - return ( - <div - className={ - 'col' + - (this.props.width ? '-' + this.props.width : '') + - (this.props.right ? ' text-right' : '') - } - > - {this.props.children} - </div> - ); - } -} - -/** - * Renders a success button using Bootstrap styles. - */ -class ButtonSuccess extends Component<{ - onClick: () => mixed, - small?: boolean, - children?: React.Node, -}> { - render() { - return ( - <button - type="button" - className={'btn btn-success' + (this.props.small ? ' btn-sm py-0' : '')} - onClick={this.props.onClick} - > - {this.props.children} - </button> - ); - } -} - -/** - * Renders a danger button using Bootstrap styles. - */ -class ButtonDanger extends Component<{ - onClick: () => mixed, - small?: boolean, - children?: React.Node, -}> { - render() { - return ( - <button - type="button" - className={'btn btn-danger' + (this.props.small ? ' btn-sm py-0' : '')} - onClick={this.props.onClick} - > - {this.props.children} - </button> - ); - } -} - -/** - * Renders a light button using Bootstrap styles. - */ -class ButtonLight extends Component<{ - onClick: () => mixed, - small?: boolean, - children?: React.Node, -}> { - render() { - return ( - <button - type="button" - className={'btn btn-light' + (this.props.small ? ' btn-sm py-0' : '')} - onClick={this.props.onClick} - > - {this.props.children} - </button> - ); - } -} - -/** - * Renders a button using Bootstrap styles. - */ -export class Button { - static Success = ButtonSuccess; - static Danger = ButtonDanger; - static Light = ButtonLight; -} - -/** - * Renders a NavBar link using Bootstrap styles. - */ -class NavBarLink extends Component<{ to: string, children?: React.Node }> { - render() { - return ( - <NavLink className="nav-link" activeClassName="active" to={this.props.to}> - {this.props.children} - </NavLink> - ); - } -} - -/** - * Renders a NavBar using Bootstrap classes. - */ -export class NavBar extends Component<{ brand?: React.Node, children?: React.Node }> { - static Link = NavBarLink; - - render() { - return ( - <nav className="navbar navbar-expand-sm bg-light navbar-light"> - { - <NavLink className="navbar-brand" activeClassName="active" exact to="/"> - {this.props.brand} - </NavLink> - } - <ul className="navbar-nav">{this.props.children}</ul> - </nav> - ); - } -} - -/** - * Renders a form label using Bootstrap styles. - */ -class FormLabel extends Component<{ children?: React.Node }> { - render() { - return <label className="col-form-label">{this.props.children}</label>; - } -} - -/** - * Renders a form input using Bootstrap styles. - */ -class FormInput extends Component<{ - type: string, - value: React.Node, - onChange: (SyntheticEvent<HTMLInputElement>) => mixed, -}> { - render() { - // ...rest will contain extra passed attributes such as disabled, required, width, height, pattern - // For further information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax - const { type, value, onChange, ...rest } = this.props; - return ( - <input - {...rest} - className="form-control" - type={this.props.type} - value={this.props.value} - onChange={this.props.onChange} - /> - ); - } -} - -/** - * Renders a form textarea using Bootstrap styles. - */ -class FormTextarea extends React.Component<{ - value: React.Node, - onChange: (SyntheticEvent<HTMLTextAreaElement>) => mixed, -}> { - render() { - // ...rest will contain extra passed attributes such as disabled, required, rows, cols - // For further information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax - const { value, onChange, ...rest } = this.props; - return <textarea {...rest} className="form-control" value={value} onChange={onChange} />; - } -} - -/** - * Renders a form checkbox using Bootstrap styles. - */ -class FormCheckbox extends Component<{ - checked: React.Node, - onChange: (SyntheticEvent<HTMLInputElement>) => mixed, -}> { - render() { - // ...rest will contain extra passed attributes such as disabled, required, width, height, pattern - // For further information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax - const { checked, onChange, ...rest } = this.props; - return <input {...rest} type="checkbox" checked={checked} onChange={onChange} />; - } -} - -/** - * Renders a form select using Bootstrap styles. - */ -class FormSelect extends Component<{ - value: React.Node, - onChange: (SyntheticEvent<HTMLSelectElement>) => mixed, - children?: React.Node, -}> { - render() { - // ...rest will contain extra passed attributes such as disabled, required, size. - // For further information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax - const { value, onChange, children, ...rest } = this.props; - return ( - <select {...rest} className="custom-select" value={value} onChange={onChange}> - {children} - </select> - ); - } -} - -/** - * Renders form components using Bootstrap styles. - */ -export class Form { - static Label = FormLabel; - static Input = FormInput; - static Textarea = FormTextarea; - static Checkbox = FormCheckbox; - static Select = FormSelect; -} +// @flow + +import * as React from 'react'; +import { Component } from 'react-simplified'; +import { NavLink } from 'react-router-dom'; + +/** + * Renders alert messages using Bootstrap classes. + */ +export class Alert extends Component { + alerts: { id: number, text: React.Node, type: string }[] = []; + nextId = 0; + + render() { + return ( + <> + {this.alerts.map((alert, i) => ( + <div key={alert.id} className={'alert alert-' + alert.type} role="alert"> + {alert.text} + <button type="button" className="close" onClick={() => this.alerts.splice(i, 1)}> + × + </button> + </div> + ))} + </> + ); + } + + /** + * Show success alert. + */ + static success(text: React.Node) { + // To avoid 'Cannot update during an existing state transition' errors, run after current event through setTimeout + setTimeout(() => { + const instance = Alert.instance(); // Get rendered Alert component instance + instance?.alerts.push({ id: instance.nextId++, text: text, type: 'success' }); + }); + } + + /** + * Show info alert. + */ + static info(text: React.Node) { + // To avoid 'Cannot update during an existing state transition' errors, run after current event through setTimeout + setTimeout(() => { + const instance = Alert.instance(); // Get rendered Alert component instance + instance?.alerts.push({ id: instance.nextId++, text: text, type: 'info' }); + }); + } + + /** + * Show warning alert. + */ + static warning(text: React.Node) { + // To avoid 'Cannot update during an existing state transition' errors, run after current event through setTimeout + setTimeout(() => { + const instance = Alert.instance(); // Get rendered Alert component instance + instance?.alerts.push({ id: instance.nextId++, text: text, type: 'warning' }); + }); + } + + /** + * Show danger alert. + */ + static danger(text: React.Node) { + // To avoid 'Cannot update during an existing state transition' errors, run after current event through setTimeout + setTimeout(() => { + const instance = Alert.instance(); // Get rendered Alert component instance + instance?.alerts.push({ id: instance.nextId++, text: text, type: 'danger' }); + }); + } +} + +/** + * Renders an information card using Bootstrap classes. + */ +export class Card extends Component<{ title?: React.Node, children?: React.Node }> { + render() { + return ( + <div className="card"> + <div className="card-body"> + <h5 className="card-title">{this.props.title}</h5> + <div className="card-text">{this.props.children}</div> + </div> + </div> + ); + } +} + +/** + * Renders a row using Bootstrap classes. + */ +export class Row extends Component<{ children?: React.Node }> { + render() { + return <div className="row">{this.props.children}</div>; + } +} + +/** + * Renders a column with specified width using Bootstrap classes. + */ +export class Column extends Component<{ width?: number, right?: boolean, children?: React.Node }> { + render() { + return ( + <div + className={ + 'col' + + (this.props.width ? '-' + this.props.width : '') + + (this.props.right ? ' text-right' : '') + } + > + {this.props.children} + </div> + ); + } +} + +/** + * Renders a success button using Bootstrap styles. + */ +class ButtonSuccess extends Component<{ + onClick: () => mixed, + small?: boolean, + children?: React.Node, +}> { + render() { + return ( + <button + type="button" + className={'btn btn-success' + (this.props.small ? ' btn-sm py-0' : '')} + onClick={this.props.onClick} + > + {this.props.children} + </button> + ); + } +} + +/** + * Renders a danger button using Bootstrap styles. + */ +class ButtonDanger extends Component<{ + onClick: () => mixed, + small?: boolean, + children?: React.Node, +}> { + render() { + return ( + <button + type="button" + className={'btn btn-danger' + (this.props.small ? ' btn-sm py-0' : '')} + onClick={this.props.onClick} + > + {this.props.children} + </button> + ); + } +} + +/** + * Renders a light button using Bootstrap styles. + */ +class ButtonLight extends Component<{ + onClick: () => mixed, + small?: boolean, + children?: React.Node, +}> { + render() { + return ( + <button + type="button" + className={'btn btn-light' + (this.props.small ? ' btn-sm py-0' : '')} + onClick={this.props.onClick} + > + {this.props.children} + </button> + ); + } +} + +/** + * Renders a button using Bootstrap styles. + */ +export class Button { + static Success = ButtonSuccess; + static Danger = ButtonDanger; + static Light = ButtonLight; +} + +/** + * Renders a NavBar link using Bootstrap styles. + */ +class NavBarLink extends Component<{ to: string, children?: React.Node }> { + render() { + return ( + <NavLink className="nav-link" activeClassName="active" to={this.props.to}> + {this.props.children} + </NavLink> + ); + } +} + +/** + * Renders a NavBar using Bootstrap classes. + */ +export class NavBar extends Component<{ brand?: React.Node, children?: React.Node }> { + static Link = NavBarLink; + + render() { + return ( + <nav className="navbar navbar-expand-sm bg-light navbar-light"> + { + <NavLink className="navbar-brand" activeClassName="active" exact to="/"> + {this.props.brand} + </NavLink> + } + <ul className="navbar-nav">{this.props.children}</ul> + </nav> + ); + } +} + +/** + * Renders a form label using Bootstrap styles. + */ +class FormLabel extends Component<{ children?: React.Node }> { + render() { + return <label className="col-form-label">{this.props.children}</label>; + } +} + +/** + * Renders a form input using Bootstrap styles. + */ +class FormInput extends Component<{ + type: string, + value: React.Node, + onChange: (SyntheticEvent<HTMLInputElement>) => mixed, +}> { + render() { + // ...rest will contain extra passed attributes such as disabled, required, width, height, pattern + // For further information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax + const { type, value, onChange, ...rest } = this.props; + return ( + <input + {...rest} + className="form-control" + type={this.props.type} + value={this.props.value} + onChange={this.props.onChange} + /> + ); + } +} + +/** + * Renders a form textarea using Bootstrap styles. + */ +class FormTextarea extends React.Component<{ + value: React.Node, + onChange: (SyntheticEvent<HTMLTextAreaElement>) => mixed, +}> { + render() { + // ...rest will contain extra passed attributes such as disabled, required, rows, cols + // For further information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax + const { value, onChange, ...rest } = this.props; + return <textarea {...rest} className="form-control" value={value} onChange={onChange} />; + } +} + +/** + * Renders a form checkbox using Bootstrap styles. + */ +class FormCheckbox extends Component<{ + checked: React.Node, + onChange: (SyntheticEvent<HTMLInputElement>) => mixed, +}> { + render() { + // ...rest will contain extra passed attributes such as disabled, required, width, height, pattern + // For further information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax + const { checked, onChange, ...rest } = this.props; + return <input {...rest} type="checkbox" checked={checked} onChange={onChange} />; + } +} + +/** + * Renders a form select using Bootstrap styles. + */ +class FormSelect extends Component<{ + value: React.Node, + onChange: (SyntheticEvent<HTMLSelectElement>) => mixed, + children?: React.Node, +}> { + render() { + // ...rest will contain extra passed attributes such as disabled, required, size. + // For further information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax + const { value, onChange, children, ...rest } = this.props; + return ( + <select {...rest} className="custom-select" value={value} onChange={onChange}> + {children} + </select> + ); + } +} + +/** + * Renders form components using Bootstrap styles. + */ +export class Form { + static Label = FormLabel; + static Input = FormInput; + static Textarea = FormTextarea; + static Checkbox = FormCheckbox; + static Select = FormSelect; +} diff --git a/client/test/alert-widget.test.js b/client/test/alert-widget.test.js index 56f2e79c159b90ffe4286900cc5ee8500b3bec4e..b5b0936c128e64a6bee78d6caa5ecdeebed1df84 100644 --- a/client/test/alert-widget.test.js +++ b/client/test/alert-widget.test.js @@ -1,59 +1,59 @@ -// @flow - -import * as React from 'react'; -import { Alert } from '../src/widgets.js'; -import { shallow } from 'enzyme'; - -describe('Alert tests', () => { - test('No alerts initially', () => { - const wrapper = shallow(<Alert />); - - expect(wrapper.matchesElement(<></>)).toEqual(true); - }); - - test('Show alert message', (done) => { - const wrapper = shallow(<Alert />); - - Alert.danger('test'); - - // Wait for events to complete - setTimeout(() => { - expect( - wrapper.matchesElement( - <> - <div> - test<button>×</button> - </div> - </> - ) - ).toEqual(true); - - done(); - }); - }); - - test('Close alert message', (done) => { - const wrapper = shallow(<Alert />); - - Alert.danger('test'); - - // Wait for events to complete - setTimeout(() => { - expect( - wrapper.matchesElement( - <> - <div> - test<button>×</button> - </div> - </> - ) - ).toEqual(true); - - wrapper.find('button.close').simulate('click'); - - expect(wrapper.matchesElement(<></>)).toEqual(true); - - done(); - }); - }); -}); +// @flow + +import * as React from 'react'; +import { Alert } from '../src/widgets.js'; +import { shallow } from 'enzyme'; + +describe('Alert tests', () => { + test('No alerts initially', () => { + const wrapper = shallow(<Alert />); + + expect(wrapper.matchesElement(<></>)).toEqual(true); + }); + + test('Show alert message', (done) => { + const wrapper = shallow(<Alert />); + + Alert.danger('test'); + + // Wait for events to complete + setTimeout(() => { + expect( + wrapper.matchesElement( + <> + <div> + test<button>×</button> + </div> + </> + ) + ).toEqual(true); + + done(); + }); + }); + + test('Close alert message', (done) => { + const wrapper = shallow(<Alert />); + + Alert.danger('test'); + + // Wait for events to complete + setTimeout(() => { + expect( + wrapper.matchesElement( + <> + <div> + test<button>×</button> + </div> + </> + ) + ).toEqual(true); + + wrapper.find('button.close').simulate('click'); + + expect(wrapper.matchesElement(<></>)).toEqual(true); + + done(); + }); + }); +}); diff --git a/client/test/setup.js b/client/test/setup.js index fe4a5062f6115889b8399f4bfd7362eca6191b60..d4e2cdc4f9bb18f33e700f6788e70add4d5dd6c9 100644 --- a/client/test/setup.js +++ b/client/test/setup.js @@ -1,6 +1,6 @@ -// @flow - -import { configure } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; - -configure({ adapter: new Adapter() }); +// @flow + +import { configure } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +configure({ adapter: new Adapter() }); diff --git a/client/test/task-components.test.js b/client/test/task-components.test.js index 798d2dade5acf8241d127e365ecf5c2054b5d369..4d54ae881d392a36207d697818ab29249e8d1304 100644 --- a/client/test/task-components.test.js +++ b/client/test/task-components.test.js @@ -1,58 +1,58 @@ -// @flow - -import * as React from 'react'; -import { TaskList, TaskNew } from '../src/task-components'; -import { type Task } from '../src/task-service'; -import { shallow } from 'enzyme'; -import { Form, Button, Column } from '../src/widgets'; -import { NavLink } from 'react-router-dom'; - -jest.mock('../src/task-service', () => { - class TaskService { - getAll() { - return Promise.resolve([ - { id: 1, title: 'Les leksjon', done: false }, - { id: 2, title: 'Møt opp på forelesning', done: false }, - { id: 3, title: 'Gjør øving', done: false }, - ]); - } - - create(title: string) { - return Promise.resolve(4); // Same as: return new Promise((resolve) => resolve(4)); - } - } - return new TaskService(); -}); - -describe('Task component tests', () => { - test('TaskList draws correctly', (done) => { - const wrapper = shallow(<TaskList />); - - // Wait for events to complete - setTimeout(() => { - expect( - wrapper.containsAllMatchingElements([ - <NavLink to="/tasks/1">Les leksjon</NavLink>, - <NavLink to="/tasks/2">Møt opp på forelesning</NavLink>, - <NavLink to="/tasks/3">Gjør øving</NavLink>, - ]) - ).toEqual(true); - done(); - }); - }); - - test('TaskNew correctly sets location on create', (done) => { - const wrapper = shallow(<TaskNew />); - - wrapper.find(Form.Input).simulate('change', { currentTarget: { value: 'Kaffepause' } }); - // $FlowExpectedError - expect(wrapper.containsMatchingElement(<Form.Input value="Kaffepause" />)).toEqual(true); - - wrapper.find(Button.Success).simulate('click'); - // Wait for events to complete - setTimeout(() => { - expect(location.hash).toEqual('#/tasks/4'); - done(); - }); - }); -}); +// @flow + +import * as React from 'react'; +import { TaskList, TaskNew } from '../src/task-components'; +import { type Task } from '../src/task-service'; +import { shallow } from 'enzyme'; +import { Form, Button, Column } from '../src/widgets'; +import { NavLink } from 'react-router-dom'; + +jest.mock('../src/task-service', () => { + class TaskService { + getAll() { + return Promise.resolve([ + { id: 1, title: 'Les leksjon', done: false }, + { id: 2, title: 'Møt opp på forelesning', done: false }, + { id: 3, title: 'Gjør øving', done: false }, + ]); + } + + create(title: string) { + return Promise.resolve(4); // Same as: return new Promise((resolve) => resolve(4)); + } + } + return new TaskService(); +}); + +describe('Task component tests', () => { + test('TaskList draws correctly', (done) => { + const wrapper = shallow(<TaskList />); + + // Wait for events to complete + setTimeout(() => { + expect( + wrapper.containsAllMatchingElements([ + <NavLink to="/tasks/1">Les leksjon</NavLink>, + <NavLink to="/tasks/2">Møt opp på forelesning</NavLink>, + <NavLink to="/tasks/3">Gjør øving</NavLink>, + ]) + ).toEqual(true); + done(); + }); + }); + + test('TaskNew correctly sets location on create', (done) => { + const wrapper = shallow(<TaskNew />); + + wrapper.find(Form.Input).simulate('change', { currentTarget: { value: 'Kaffepause' } }); + // $FlowExpectedError + expect(wrapper.containsMatchingElement(<Form.Input value="Kaffepause" />)).toEqual(true); + + wrapper.find(Button.Success).simulate('click'); + // Wait for events to complete + setTimeout(() => { + expect(location.hash).toEqual('#/tasks/4'); + done(); + }); + }); +}); diff --git a/client/webpack.config.js b/client/webpack.config.js index 3599f0d541d7687a236d73f36fa4334e081f776e..6d943d7304cb2cb5b313c8e566022018fcf31023 100644 --- a/client/webpack.config.js +++ b/client/webpack.config.js @@ -1,31 +1,31 @@ -// @flow - -/** - * Configuration file for webpack. - * - * Webpack bundles several JavaScript files into a single file - * for easier script embedding in an index.html file. - */ - -const path = require('path'); - -module.exports = { - entry: './src/index.js', // Initial file to bundle - output: { - // Output file: ./public/bundle.js - path: path.resolve(__dirname, 'public'), - filename: 'bundle.js', - }, - // Makes original source code available to the browser for easier identification of error causes. - devtool: 'source-map', - module: { - rules: [ - { - // Use babel to parse .js files in the src folder - test: /\.js$/, - include: path.resolve(__dirname, 'src'), - use: ['babel-loader'], - }, - ], - }, -}; +// @flow + +/** + * Configuration file for webpack. + * + * Webpack bundles several JavaScript files into a single file + * for easier script embedding in an index.html file. + */ + +const path = require('path'); + +module.exports = { + entry: './src/index.js', // Initial file to bundle + output: { + // Output file: ./public/bundle.js + path: path.resolve(__dirname, 'public'), + filename: 'bundle.js', + }, + // Makes original source code available to the browser for easier identification of error causes. + devtool: 'source-map', + module: { + rules: [ + { + // Use babel to parse .js files in the src folder + test: /\.js$/, + include: path.resolve(__dirname, 'src'), + use: ['babel-loader'], + }, + ], + }, +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..48e341a0954d5f8c2accf3a6731be28e5bb9c0de --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3 @@ +{ + "lockfileVersion": 1 +} diff --git a/server/.babelrc b/server/.babelrc index 04921bcd51d2745b0ef8a2087bd693367dad71d2..3ef5facaac7338bd5217c35355d48c44e1feebcd 100644 --- a/server/.babelrc +++ b/server/.babelrc @@ -1,4 +1,4 @@ -{ - "presets": ["@babel/preset-env", "@babel/preset-flow"], - "plugins": ["@babel/plugin-proposal-class-properties"] -} +{ + "presets": ["@babel/preset-env", "@babel/preset-flow"], + "plugins": ["@babel/plugin-proposal-class-properties"] +} diff --git a/server/.flowconfig b/server/.flowconfig index 93c28dc58dd2e1778f9eb29d1cc2c13bc1463062..81a71d868054c0faf906eef1fe3dc9d92d965b3e 100644 --- a/server/.flowconfig +++ b/server/.flowconfig @@ -1,2 +1,2 @@ -[options] -types_first=false +[options] +types_first=false diff --git a/server/.npmrc b/server/.npmrc index 43c97e719a5a824700932f72e6e7e6748ce45d01..094e38421d4085d75e1223c8c02d400bd687613c 100644 --- a/server/.npmrc +++ b/server/.npmrc @@ -1 +1 @@ -package-lock=false +package-lock=false diff --git a/server/flow-typed/npm/axios_v0.19.x.js b/server/flow-typed/npm/axios_v0.19.x.js index 65cd2161928036a709803bc99e7bbe089e91bc70..2af576fd753108326a8545646f308d752fb7512d 100644 --- a/server/flow-typed/npm/axios_v0.19.x.js +++ b/server/flow-typed/npm/axios_v0.19.x.js @@ -1,225 +1,225 @@ -// flow-typed signature: fe7f00984c44d69833f19bc39895832f -// flow-typed version: a4cc3d5e98/axios_v0.19.x/flow_>=v0.104.x - -declare module 'axios' { - import type { Agent as HttpAgent } from 'http'; - import type { Agent as HttpsAgent } from 'https'; - - declare type AxiosTransformer<T> = ( - data: T, - headers?: { [key: string]: mixed, ...}, - ) => mixed; - - declare type ProxyConfig = {| - host: string, - port: number, - auth?: {| - username: string, - password: string, - |}, - protocol?: string, - |}; - - declare class Cancel { - constructor(message?: string): Cancel; - message: string; - } - - declare type Canceler = (message?: string) => void; - - declare type CancelTokenSource = {| - token: CancelToken, - cancel: Canceler, - |}; - - declare class CancelToken { - constructor(executor: (cancel: Canceler) => void): void; - static source(): CancelTokenSource; - promise: Promise<Cancel>; - reason?: Cancel; - throwIfRequested(): void; - } - - declare type Method = - | 'get' - | 'GET' - | 'delete' - | 'DELETE' - | 'head' - | 'HEAD' - | 'options' - | 'OPTIONS' - | 'post' - | 'POST' - | 'put' - | 'PUT' - | 'patch' - | 'PATCH'; - - declare type ResponseType = - | 'arraybuffer' - | 'blob' - | 'document' - | 'json' - | 'text' - | 'stream'; - - declare type AxiosAdapter = ( - config: AxiosXHRConfig<mixed> - ) => Promise<AxiosXHR<mixed>>; - - declare type AxiosXHRConfigBase<T, R = T> = { - adapter?: AxiosAdapter, - auth?: {| - username: string, - password: string, - |}, - baseURL?: string, - cancelToken?: CancelToken, - headers?: { [key: string]: mixed, ...}, - httpAgent?: HttpAgent, - httpsAgent?: HttpsAgent, - maxContentLength?: number, - maxRedirects?: number, - socketPath?: string | null, - params?: { [key: string]: mixed, ...}, - paramsSerializer?: (params: { [key: string]: mixed, ...}) => string, - onUploadProgress?: (progressEvent: ProgressEvent) => void, - onDownloadProgress?: (progressEvent: ProgressEvent) => void, - proxy?: ProxyConfig | false, - responseType?: ResponseType, - timeout?: number, - transformRequest?: AxiosTransformer<T> | Array<AxiosTransformer<T>>, - transformResponse?: AxiosTransformer<R> | Array<AxiosTransformer<R>>, - validateStatus?: (status: number) => boolean, - withCredentials?: boolean, - xsrfCookieName?: string, - xsrfHeaderName?: string, - ... - }; - - declare type AxiosXHRConfig<T, R = T> = { - ...$Exact<AxiosXHRConfigBase<T, R>>, - data?: T, - method?: Method, - url: string, - ... - }; - - declare type AxiosXHRConfigShape<T, R = T> = $Shape<AxiosXHRConfig<T, R>>; - - declare type AxiosXHR<T, R = T> = {| - config: AxiosXHRConfig<T, R>, - data: R, - headers: ?{[key: string]: mixed, ...}, - status: number, - statusText: string, - request: http$ClientRequest<> | XMLHttpRequest | mixed, - |}; - - declare type AxiosInterceptorIdent = number; - - declare type AxiosRequestInterceptor<T, R = T> = {| - use( - onFulfilled: ?( - response: AxiosXHRConfig<T, R> - ) => Promise<AxiosXHRConfig<mixed>> | AxiosXHRConfig<mixed>, - onRejected: ?(error: mixed) => mixed - ): AxiosInterceptorIdent, - eject(ident: AxiosInterceptorIdent): void, - |}; - - declare type AxiosResponseInterceptor<T, R = T> = {| - use( - onFulfilled: ?(response: AxiosXHR<T, R>) => mixed, - onRejected: ?(error: mixed) => mixed - ): AxiosInterceptorIdent, - eject(ident: AxiosInterceptorIdent): void, - |}; - - declare type AxiosPromise<T, R = T> = Promise<AxiosXHR<T, R>>; - - declare class Axios { - <T, R>( - config: AxiosXHRConfig<T, R> | string, - config?: AxiosXHRConfigShape<T, R> - ): AxiosPromise<T, R>; - constructor<T, R>(config?: AxiosXHRConfigBase<T, R>): void; - request<T, R>( - config: AxiosXHRConfig<T, R> | string, - config?: AxiosXHRConfigShape<T, R> - ): AxiosPromise<T, R>; - delete<R>( - url: string, - config?: AxiosXHRConfigBase<mixed, R> - ): AxiosPromise<mixed, R>; - get<R>( - url: string, - config?: AxiosXHRConfigBase<mixed, R> - ): AxiosPromise<mixed, R>; - head<R>( - url: string, - config?: AxiosXHRConfigBase<mixed, R> - ): AxiosPromise<mixed, R>; - options<R>( - url: string, - config?: AxiosXHRConfigBase<mixed, R> - ): AxiosPromise<mixed, R>; - post<T, R>( - url: string, - data?: T, - config?: AxiosXHRConfigBase<T, R> - ): AxiosPromise<T, R>; - put<T, R>( - url: string, - data?: T, - config?: AxiosXHRConfigBase<T, R> - ): AxiosPromise<T, R>; - patch<T, R>( - url: string, - data?: T, - config?: AxiosXHRConfigBase<T, R> - ): AxiosPromise<T, R>; - interceptors: {| - request: AxiosRequestInterceptor<mixed>, - response: AxiosResponseInterceptor<mixed>, - |}; - defaults: {| - ...$Exact<AxiosXHRConfigBase<mixed>>, - headers: { [key: string]: mixed, ...}, - |}; - getUri<T, R>(config?: AxiosXHRConfig<T, R>): string; - } - - declare class AxiosError<T, R = T> extends Error { - config: AxiosXHRConfig<T, R>; - request?: http$ClientRequest<> | XMLHttpRequest; - response?: AxiosXHR<T, R>; - code?: string; - isAxiosError: boolean; - } - - declare interface AxiosExport extends Axios { - <T, R>( - config: AxiosXHRConfig<T, R> | string, - config?: AxiosXHRConfigShape<T, R> - ): AxiosPromise<T, R>; - Axios: typeof Axios; - Cancel: typeof Cancel; - CancelToken: typeof CancelToken; - isCancel(value: mixed): boolean; - create(config?: AxiosXHRConfigBase<T, R>): Axios; - all: typeof Promise.all; - spread<T, R>(callback: (...args: T) => R): (array: T) => R; - } - - declare type $AxiosXHRConfigBase<T, R = T> = AxiosXHRConfigBase<T, R>; - - declare type $AxiosXHRConfig<T, R = T> = AxiosXHRConfig<T, R>; - - declare type $AxiosXHR<T, R = T> = AxiosXHR<T, R>; - - declare type $AxiosError<T, R = T> = AxiosError<T, R>; - - declare module.exports: AxiosExport; -} +// flow-typed signature: fe7f00984c44d69833f19bc39895832f +// flow-typed version: a4cc3d5e98/axios_v0.19.x/flow_>=v0.104.x + +declare module 'axios' { + import type { Agent as HttpAgent } from 'http'; + import type { Agent as HttpsAgent } from 'https'; + + declare type AxiosTransformer<T> = ( + data: T, + headers?: { [key: string]: mixed, ...}, + ) => mixed; + + declare type ProxyConfig = {| + host: string, + port: number, + auth?: {| + username: string, + password: string, + |}, + protocol?: string, + |}; + + declare class Cancel { + constructor(message?: string): Cancel; + message: string; + } + + declare type Canceler = (message?: string) => void; + + declare type CancelTokenSource = {| + token: CancelToken, + cancel: Canceler, + |}; + + declare class CancelToken { + constructor(executor: (cancel: Canceler) => void): void; + static source(): CancelTokenSource; + promise: Promise<Cancel>; + reason?: Cancel; + throwIfRequested(): void; + } + + declare type Method = + | 'get' + | 'GET' + | 'delete' + | 'DELETE' + | 'head' + | 'HEAD' + | 'options' + | 'OPTIONS' + | 'post' + | 'POST' + | 'put' + | 'PUT' + | 'patch' + | 'PATCH'; + + declare type ResponseType = + | 'arraybuffer' + | 'blob' + | 'document' + | 'json' + | 'text' + | 'stream'; + + declare type AxiosAdapter = ( + config: AxiosXHRConfig<mixed> + ) => Promise<AxiosXHR<mixed>>; + + declare type AxiosXHRConfigBase<T, R = T> = { + adapter?: AxiosAdapter, + auth?: {| + username: string, + password: string, + |}, + baseURL?: string, + cancelToken?: CancelToken, + headers?: { [key: string]: mixed, ...}, + httpAgent?: HttpAgent, + httpsAgent?: HttpsAgent, + maxContentLength?: number, + maxRedirects?: number, + socketPath?: string | null, + params?: { [key: string]: mixed, ...}, + paramsSerializer?: (params: { [key: string]: mixed, ...}) => string, + onUploadProgress?: (progressEvent: ProgressEvent) => void, + onDownloadProgress?: (progressEvent: ProgressEvent) => void, + proxy?: ProxyConfig | false, + responseType?: ResponseType, + timeout?: number, + transformRequest?: AxiosTransformer<T> | Array<AxiosTransformer<T>>, + transformResponse?: AxiosTransformer<R> | Array<AxiosTransformer<R>>, + validateStatus?: (status: number) => boolean, + withCredentials?: boolean, + xsrfCookieName?: string, + xsrfHeaderName?: string, + ... + }; + + declare type AxiosXHRConfig<T, R = T> = { + ...$Exact<AxiosXHRConfigBase<T, R>>, + data?: T, + method?: Method, + url: string, + ... + }; + + declare type AxiosXHRConfigShape<T, R = T> = $Shape<AxiosXHRConfig<T, R>>; + + declare type AxiosXHR<T, R = T> = {| + config: AxiosXHRConfig<T, R>, + data: R, + headers: ?{[key: string]: mixed, ...}, + status: number, + statusText: string, + request: http$ClientRequest<> | XMLHttpRequest | mixed, + |}; + + declare type AxiosInterceptorIdent = number; + + declare type AxiosRequestInterceptor<T, R = T> = {| + use( + onFulfilled: ?( + response: AxiosXHRConfig<T, R> + ) => Promise<AxiosXHRConfig<mixed>> | AxiosXHRConfig<mixed>, + onRejected: ?(error: mixed) => mixed + ): AxiosInterceptorIdent, + eject(ident: AxiosInterceptorIdent): void, + |}; + + declare type AxiosResponseInterceptor<T, R = T> = {| + use( + onFulfilled: ?(response: AxiosXHR<T, R>) => mixed, + onRejected: ?(error: mixed) => mixed + ): AxiosInterceptorIdent, + eject(ident: AxiosInterceptorIdent): void, + |}; + + declare type AxiosPromise<T, R = T> = Promise<AxiosXHR<T, R>>; + + declare class Axios { + <T, R>( + config: AxiosXHRConfig<T, R> | string, + config?: AxiosXHRConfigShape<T, R> + ): AxiosPromise<T, R>; + constructor<T, R>(config?: AxiosXHRConfigBase<T, R>): void; + request<T, R>( + config: AxiosXHRConfig<T, R> | string, + config?: AxiosXHRConfigShape<T, R> + ): AxiosPromise<T, R>; + delete<R>( + url: string, + config?: AxiosXHRConfigBase<mixed, R> + ): AxiosPromise<mixed, R>; + get<R>( + url: string, + config?: AxiosXHRConfigBase<mixed, R> + ): AxiosPromise<mixed, R>; + head<R>( + url: string, + config?: AxiosXHRConfigBase<mixed, R> + ): AxiosPromise<mixed, R>; + options<R>( + url: string, + config?: AxiosXHRConfigBase<mixed, R> + ): AxiosPromise<mixed, R>; + post<T, R>( + url: string, + data?: T, + config?: AxiosXHRConfigBase<T, R> + ): AxiosPromise<T, R>; + put<T, R>( + url: string, + data?: T, + config?: AxiosXHRConfigBase<T, R> + ): AxiosPromise<T, R>; + patch<T, R>( + url: string, + data?: T, + config?: AxiosXHRConfigBase<T, R> + ): AxiosPromise<T, R>; + interceptors: {| + request: AxiosRequestInterceptor<mixed>, + response: AxiosResponseInterceptor<mixed>, + |}; + defaults: {| + ...$Exact<AxiosXHRConfigBase<mixed>>, + headers: { [key: string]: mixed, ...}, + |}; + getUri<T, R>(config?: AxiosXHRConfig<T, R>): string; + } + + declare class AxiosError<T, R = T> extends Error { + config: AxiosXHRConfig<T, R>; + request?: http$ClientRequest<> | XMLHttpRequest; + response?: AxiosXHR<T, R>; + code?: string; + isAxiosError: boolean; + } + + declare interface AxiosExport extends Axios { + <T, R>( + config: AxiosXHRConfig<T, R> | string, + config?: AxiosXHRConfigShape<T, R> + ): AxiosPromise<T, R>; + Axios: typeof Axios; + Cancel: typeof Cancel; + CancelToken: typeof CancelToken; + isCancel(value: mixed): boolean; + create(config?: AxiosXHRConfigBase<T, R>): Axios; + all: typeof Promise.all; + spread<T, R>(callback: (...args: T) => R): (array: T) => R; + } + + declare type $AxiosXHRConfigBase<T, R = T> = AxiosXHRConfigBase<T, R>; + + declare type $AxiosXHRConfig<T, R = T> = AxiosXHRConfig<T, R>; + + declare type $AxiosXHR<T, R = T> = AxiosXHR<T, R>; + + declare type $AxiosError<T, R = T> = AxiosError<T, R>; + + declare module.exports: AxiosExport; +} diff --git a/server/flow-typed/npm/express_v4.17.x.js b/server/flow-typed/npm/express_v4.17.x.js index 716649b34b136d872cd359c52dd62bca01d872cf..34ba2427d1c2d7ed60cce5d234db117c1caf58c6 100644 --- a/server/flow-typed/npm/express_v4.17.x.js +++ b/server/flow-typed/npm/express_v4.17.x.js @@ -1,353 +1,353 @@ -// flow-typed signature: 7e46c8fddb9d601f9b5b405919c74216 -// flow-typed version: 72a1136f77/express_v4.17.x/flow_>=v0.104.x - -declare type express$RouterOptions = { - caseSensitive?: boolean, - mergeParams?: boolean, - strict?: boolean, - ... -}; - -declare class express$RequestResponseBase { - app: express$Application<any, any>; - get(field: string): string | void; -} - -declare type express$RequestParams = { [param: string]: string, ... }; - -/* - NOTE: Use caution when extending `express$Request` or `express$Response`. When - a request first hits the server, its `req` and `res` will not have any - additional properties, even if you explicitly type them with your custom - subclass. Subsequent middleware may assign these properties, but you must be - cognizant of this ordering. One way to handle this is marking all properties - as optional to force refinement every time a property is accessed. Therefore, - we advise that you always mark properties as _optional_ in `express$Request` - and `express$Response` subclasses. - - You may decide not to do this, in which case the typings will be unsound and - the behavior will be similar to how arrays work in Flow. See here for more - information: https://flow.org/en/docs/types/arrays/#toc-array-access-is-unsafe - - See #3578 and #3337 for additional discussion. If you have ideas on how to - improve these typings, please share them in #3578 or open a new issue. - - **BAD** - declare class test_express$CustomRequest extends express$Request { - foo: string; - } - - **GOOD** - declare class test_express$CustomRequest extends express$Request { - foo: string | void; - } -*/ -declare class express$Request extends http$IncomingMessage mixins express$RequestResponseBase { - baseUrl: string; - body: mixed; - cookies: { [cookie: string]: string, ... }; - connection: net$Socket; - fresh: boolean; - hostname: string; - ip: string; - ips: Array<string>; - method: string; - originalUrl: string; - params: express$RequestParams; - path: string; - protocol: "https" | "http"; - query: { [name: string]: string | Array<string>, ... }; - route: string; - secure: boolean; - signedCookies: { [signedCookie: string]: string, ... }; - stale: boolean; - subdomains: Array<string>; - xhr: boolean; - accepts(types: string): string | false; - accepts(types: Array<string>): string | false; - acceptsCharsets(...charsets: Array<string>): string | false; - acceptsEncodings(...encoding: Array<string>): string | false; - acceptsLanguages(...lang: Array<string>): string | false; - header(field: string): string | void; - is(type: string): string | false; - param(name: string, defaultValue?: string): string | void; -} - -declare type express$CookieOptions = { - domain?: string, - encode?: (value: string) => string, - expires?: Date, - httpOnly?: boolean, - maxAge?: number, - path?: string, - secure?: boolean, - signed?: boolean, - ... -}; - -declare type express$Path = string | RegExp; - -declare type express$RenderCallback = ( - err: Error | null, - html?: string -) => mixed; - -declare type express$SendFileOptions = { - maxAge?: number, - root?: string, - lastModified?: boolean, - headers?: { [name: string]: string, ... }, - dotfiles?: "allow" | "deny" | "ignore", - ... -}; - -declare class express$Response extends http$ServerResponse mixins express$RequestResponseBase { - headersSent: boolean; - locals: { [name: string]: mixed, ... }; - append(field: string, value?: string): this; - attachment(filename?: string): this; - cookie(name: string, value: string, options?: express$CookieOptions): this; - clearCookie(name: string, options?: express$CookieOptions): this; - download( - path: string, - filename?: string, - callback?: (err?: ?Error) => void - ): this; - format(typesObject: { [type: string]: Function, ... }): this; - json(body?: mixed): this; - jsonp(body?: mixed): this; - links(links: { [name: string]: string, ... }): this; - location(path: string): this; - redirect(url: string, ...args: Array<void>): this; - redirect(status: number, url: string, ...args: Array<void>): this; - render( - view: string, - locals?: { [name: string]: mixed, ... }, - callback?: express$RenderCallback - ): this; - send(body?: mixed): this; - sendFile( - path: string, - options?: express$SendFileOptions, - callback?: (err?: ?Error) => mixed - ): this; - sendStatus(statusCode: number): this; - header(field: string, value?: string): this; - header(headers: { [name: string]: string, ... }): this; - set(field: string, value?: string | string[]): this; - set(headers: { [name: string]: string, ... }): this; - status(statusCode: number): this; - type(type: string): this; - vary(field: string): this; - req: express$Request; -} - -declare type express$NextFunction = (err?: ?Error | "route") => mixed; -declare type express$Middleware< - Req: express$Request = express$Request, - Res: express$Response = express$Response, -> = - ((req: Req, res: Res, next: express$NextFunction) => mixed) | - ((error: Error, req: Req, res: Res, next: express$NextFunction) => mixed); - -declare interface express$RouteMethodType< - T, - Req: express$Request = express$Request, - Res: express$Response = express$Response, -> { - (middleware: express$Middleware<Req, Res>): T; - (...middleware: Array<express$Middleware<Req, Res>>): T; - ( - path: express$Path | $ReadOnlyArray<express$Path>, - ...middleware: Array<express$Middleware<Req, Res>> - ): T; -} - -declare class express$Route< - Req: express$Request = express$Request, - Res: express$Response = express$Response, -> { - all: express$RouteMethodType<this, Req, Res>; - get: express$RouteMethodType<this, Req, Res>; - post: express$RouteMethodType<this, Req, Res>; - put: express$RouteMethodType<this, Req, Res>; - head: express$RouteMethodType<this, Req, Res>; - delete: express$RouteMethodType<this, Req, Res>; - options: express$RouteMethodType<this, Req, Res>; - trace: express$RouteMethodType<this, Req, Res>; - copy: express$RouteMethodType<this, Req, Res>; - lock: express$RouteMethodType<this, Req, Res>; - mkcol: express$RouteMethodType<this, Req, Res>; - move: express$RouteMethodType<this, Req, Res>; - purge: express$RouteMethodType<this, Req, Res>; - propfind: express$RouteMethodType<this, Req, Res>; - proppatch: express$RouteMethodType<this, Req, Res>; - unlock: express$RouteMethodType<this, Req, Res>; - report: express$RouteMethodType<this, Req, Res>; - mkactivity: express$RouteMethodType<this, Req, Res>; - checkout: express$RouteMethodType<this, Req, Res>; - merge: express$RouteMethodType<this, Req, Res>; - - // @TODO Missing 'm-search' but get flow illegal name error. - - notify: express$RouteMethodType<this, Req, Res>; - subscribe: express$RouteMethodType<this, Req, Res>; - unsubscribe: express$RouteMethodType<this, Req, Res>; - patch: express$RouteMethodType<this, Req, Res>; - search: express$RouteMethodType<this, Req, Res>; - connect: express$RouteMethodType<this, Req, Res>; -} - -declare type express$RouterUseable<Req: express$Request, Res: express$Response> = - | express$Middleware<Req, Res> - | express$Router<Req, Res> - | $ReadOnlyArray<express$Middleware<Req, Res> | express$Router<Req, Res>>; - -declare class express$Router< - Req: express$Request = express$Request, - Res: express$Response = express$Response, -> extends express$Route<Req, Res> { - constructor(options?: express$RouterOptions): void; - route(path: string): express$Route<Req, Res>; - static <Req2: express$Request, Res2: express$Response>( - options?: express$RouterOptions, - ): express$Router<Req2, Res2>; - use(express$RouterUseable<Req, Res>, ...express$RouterUseable<Req, Res>[]): this; - use(express$Path, express$RouterUseable<Req, Res>, ...express$RouterUseable<Req, Res>[]): this; - handle( - req: http$IncomingMessage<>, - res: http$ServerResponse, - next: express$NextFunction - ): void; - param( - param: string, - callback: ( - req: Req, - res: Res, - next: express$NextFunction, - value: string, - paramName: string, - ) => mixed - ): void; - ( - req: http$IncomingMessage<>, - res: http$ServerResponse, - next?: ?express$NextFunction - ): void; -} - -/* -With flow-bin ^0.59, express app.listen() is deemed to return any and fails flow type coverage. -Which is ironic because https://github.com/facebook/flow/blob/master/Changelog.md#misc-2 (release notes for 0.59) -says "Improves typings for Node.js HTTP server listen() function." See that? IMPROVES! -To work around this issue, we changed Server to ?Server here, so that our invocations of express.listen() will -not be deemed to lack type coverage. -*/ - -declare class express$Application< - Req: express$Request = express$Request, - Res: express$Response = express$Response, -> extends express$Router<Req, Res> mixins events$EventEmitter { - constructor(): void; - locals: { [name: string]: mixed, ... }; - mountpath: string; - listen( - port: number, - hostname?: string, - backlog?: number, - callback?: (err?: ?Error) => mixed - ): ?http$Server; - listen( - port: number, - hostname?: string, - callback?: (err?: ?Error) => mixed - ): ?http$Server; - listen(port: number, callback?: (err?: ?Error) => mixed): ?http$Server; - listen(path: string, callback?: (err?: ?Error) => mixed): ?http$Server; - listen(handle: Object, callback?: (err?: ?Error) => mixed): ?http$Server; - disable(name: string): void; - disabled(name: string): boolean; - enable(name: string): this; - enabled(name: string): boolean; - engine(name: string, callback: Function): void; - /** - * Mixed will not be taken as a value option. Issue around using the GET http method name and the get for settings. - */ - // get(name: string): mixed; - set(name: string, value: mixed): mixed; - render( - name: string, - optionsOrFunction: { [name: string]: mixed, ... }, - callback: express$RenderCallback - ): void; - handle( - req: http$IncomingMessage<>, - res: http$ServerResponse, - next?: ?express$NextFunction - ): void; - // callable signature is not inherited - ( - req: http$IncomingMessage<>, - res: http$ServerResponse, - next?: ?express$NextFunction - ): void; -} - -declare type JsonOptions = { - inflate?: boolean, - limit?: string | number, - reviver?: (key: string, value: mixed) => mixed, - strict?: boolean, - type?: string | Array<string> | ((req: express$Request) => boolean), - verify?: ( - req: express$Request, - res: express$Response, - buf: Buffer, - encoding: string - ) => mixed, - ... -}; - -declare type express$UrlEncodedOptions = { - extended?: boolean, - inflate?: boolean, - limit?: string | number, - parameterLimit?: number, - type?: string | Array<string> | ((req: express$Request) => boolean), - verify?: ( - req: express$Request, - res: express$Response, - buf: Buffer, - encoding: string - ) => mixed, - ... -} - -declare module "express" { - declare export type RouterOptions = express$RouterOptions; - declare export type CookieOptions = express$CookieOptions; - declare export type Middleware< - Req: express$Request = express$Request, - Res: express$Response = express$Response, - > = express$Middleware<Req, Res>; - declare export type NextFunction = express$NextFunction; - declare export type RequestParams = express$RequestParams; - declare export type $Response = express$Response; - declare export type $Request = express$Request; - declare export type $Application< - Req: express$Request = express$Request, - Res: express$Response = express$Response, - > = express$Application<Req, Res>; - - declare module.exports: { - // If you try to call like a function, it will use this signature - <Req: express$Request, Res: express$Response>(): express$Application<Req, Res>, - json: (opts: ?JsonOptions) => express$Middleware<>, - // `static` property on the function - static: <Req: express$Request, Res: express$Response>(root: string, options?: Object) => express$Middleware<Req, Res>, - // `Router` property on the function - Router: typeof express$Router, - urlencoded: (opts: ?express$UrlEncodedOptions) => express$Middleware<>, - ... - }; -} +// flow-typed signature: 7e46c8fddb9d601f9b5b405919c74216 +// flow-typed version: 72a1136f77/express_v4.17.x/flow_>=v0.104.x + +declare type express$RouterOptions = { + caseSensitive?: boolean, + mergeParams?: boolean, + strict?: boolean, + ... +}; + +declare class express$RequestResponseBase { + app: express$Application<any, any>; + get(field: string): string | void; +} + +declare type express$RequestParams = { [param: string]: string, ... }; + +/* + NOTE: Use caution when extending `express$Request` or `express$Response`. When + a request first hits the server, its `req` and `res` will not have any + additional properties, even if you explicitly type them with your custom + subclass. Subsequent middleware may assign these properties, but you must be + cognizant of this ordering. One way to handle this is marking all properties + as optional to force refinement every time a property is accessed. Therefore, + we advise that you always mark properties as _optional_ in `express$Request` + and `express$Response` subclasses. + + You may decide not to do this, in which case the typings will be unsound and + the behavior will be similar to how arrays work in Flow. See here for more + information: https://flow.org/en/docs/types/arrays/#toc-array-access-is-unsafe + + See #3578 and #3337 for additional discussion. If you have ideas on how to + improve these typings, please share them in #3578 or open a new issue. + + **BAD** + declare class test_express$CustomRequest extends express$Request { + foo: string; + } + + **GOOD** + declare class test_express$CustomRequest extends express$Request { + foo: string | void; + } +*/ +declare class express$Request extends http$IncomingMessage mixins express$RequestResponseBase { + baseUrl: string; + body: mixed; + cookies: { [cookie: string]: string, ... }; + connection: net$Socket; + fresh: boolean; + hostname: string; + ip: string; + ips: Array<string>; + method: string; + originalUrl: string; + params: express$RequestParams; + path: string; + protocol: "https" | "http"; + query: { [name: string]: string | Array<string>, ... }; + route: string; + secure: boolean; + signedCookies: { [signedCookie: string]: string, ... }; + stale: boolean; + subdomains: Array<string>; + xhr: boolean; + accepts(types: string): string | false; + accepts(types: Array<string>): string | false; + acceptsCharsets(...charsets: Array<string>): string | false; + acceptsEncodings(...encoding: Array<string>): string | false; + acceptsLanguages(...lang: Array<string>): string | false; + header(field: string): string | void; + is(type: string): string | false; + param(name: string, defaultValue?: string): string | void; +} + +declare type express$CookieOptions = { + domain?: string, + encode?: (value: string) => string, + expires?: Date, + httpOnly?: boolean, + maxAge?: number, + path?: string, + secure?: boolean, + signed?: boolean, + ... +}; + +declare type express$Path = string | RegExp; + +declare type express$RenderCallback = ( + err: Error | null, + html?: string +) => mixed; + +declare type express$SendFileOptions = { + maxAge?: number, + root?: string, + lastModified?: boolean, + headers?: { [name: string]: string, ... }, + dotfiles?: "allow" | "deny" | "ignore", + ... +}; + +declare class express$Response extends http$ServerResponse mixins express$RequestResponseBase { + headersSent: boolean; + locals: { [name: string]: mixed, ... }; + append(field: string, value?: string): this; + attachment(filename?: string): this; + cookie(name: string, value: string, options?: express$CookieOptions): this; + clearCookie(name: string, options?: express$CookieOptions): this; + download( + path: string, + filename?: string, + callback?: (err?: ?Error) => void + ): this; + format(typesObject: { [type: string]: Function, ... }): this; + json(body?: mixed): this; + jsonp(body?: mixed): this; + links(links: { [name: string]: string, ... }): this; + location(path: string): this; + redirect(url: string, ...args: Array<void>): this; + redirect(status: number, url: string, ...args: Array<void>): this; + render( + view: string, + locals?: { [name: string]: mixed, ... }, + callback?: express$RenderCallback + ): this; + send(body?: mixed): this; + sendFile( + path: string, + options?: express$SendFileOptions, + callback?: (err?: ?Error) => mixed + ): this; + sendStatus(statusCode: number): this; + header(field: string, value?: string): this; + header(headers: { [name: string]: string, ... }): this; + set(field: string, value?: string | string[]): this; + set(headers: { [name: string]: string, ... }): this; + status(statusCode: number): this; + type(type: string): this; + vary(field: string): this; + req: express$Request; +} + +declare type express$NextFunction = (err?: ?Error | "route") => mixed; +declare type express$Middleware< + Req: express$Request = express$Request, + Res: express$Response = express$Response, +> = + ((req: Req, res: Res, next: express$NextFunction) => mixed) | + ((error: Error, req: Req, res: Res, next: express$NextFunction) => mixed); + +declare interface express$RouteMethodType< + T, + Req: express$Request = express$Request, + Res: express$Response = express$Response, +> { + (middleware: express$Middleware<Req, Res>): T; + (...middleware: Array<express$Middleware<Req, Res>>): T; + ( + path: express$Path | $ReadOnlyArray<express$Path>, + ...middleware: Array<express$Middleware<Req, Res>> + ): T; +} + +declare class express$Route< + Req: express$Request = express$Request, + Res: express$Response = express$Response, +> { + all: express$RouteMethodType<this, Req, Res>; + get: express$RouteMethodType<this, Req, Res>; + post: express$RouteMethodType<this, Req, Res>; + put: express$RouteMethodType<this, Req, Res>; + head: express$RouteMethodType<this, Req, Res>; + delete: express$RouteMethodType<this, Req, Res>; + options: express$RouteMethodType<this, Req, Res>; + trace: express$RouteMethodType<this, Req, Res>; + copy: express$RouteMethodType<this, Req, Res>; + lock: express$RouteMethodType<this, Req, Res>; + mkcol: express$RouteMethodType<this, Req, Res>; + move: express$RouteMethodType<this, Req, Res>; + purge: express$RouteMethodType<this, Req, Res>; + propfind: express$RouteMethodType<this, Req, Res>; + proppatch: express$RouteMethodType<this, Req, Res>; + unlock: express$RouteMethodType<this, Req, Res>; + report: express$RouteMethodType<this, Req, Res>; + mkactivity: express$RouteMethodType<this, Req, Res>; + checkout: express$RouteMethodType<this, Req, Res>; + merge: express$RouteMethodType<this, Req, Res>; + + // @TODO Missing 'm-search' but get flow illegal name error. + + notify: express$RouteMethodType<this, Req, Res>; + subscribe: express$RouteMethodType<this, Req, Res>; + unsubscribe: express$RouteMethodType<this, Req, Res>; + patch: express$RouteMethodType<this, Req, Res>; + search: express$RouteMethodType<this, Req, Res>; + connect: express$RouteMethodType<this, Req, Res>; +} + +declare type express$RouterUseable<Req: express$Request, Res: express$Response> = + | express$Middleware<Req, Res> + | express$Router<Req, Res> + | $ReadOnlyArray<express$Middleware<Req, Res> | express$Router<Req, Res>>; + +declare class express$Router< + Req: express$Request = express$Request, + Res: express$Response = express$Response, +> extends express$Route<Req, Res> { + constructor(options?: express$RouterOptions): void; + route(path: string): express$Route<Req, Res>; + static <Req2: express$Request, Res2: express$Response>( + options?: express$RouterOptions, + ): express$Router<Req2, Res2>; + use(express$RouterUseable<Req, Res>, ...express$RouterUseable<Req, Res>[]): this; + use(express$Path, express$RouterUseable<Req, Res>, ...express$RouterUseable<Req, Res>[]): this; + handle( + req: http$IncomingMessage<>, + res: http$ServerResponse, + next: express$NextFunction + ): void; + param( + param: string, + callback: ( + req: Req, + res: Res, + next: express$NextFunction, + value: string, + paramName: string, + ) => mixed + ): void; + ( + req: http$IncomingMessage<>, + res: http$ServerResponse, + next?: ?express$NextFunction + ): void; +} + +/* +With flow-bin ^0.59, express app.listen() is deemed to return any and fails flow type coverage. +Which is ironic because https://github.com/facebook/flow/blob/master/Changelog.md#misc-2 (release notes for 0.59) +says "Improves typings for Node.js HTTP server listen() function." See that? IMPROVES! +To work around this issue, we changed Server to ?Server here, so that our invocations of express.listen() will +not be deemed to lack type coverage. +*/ + +declare class express$Application< + Req: express$Request = express$Request, + Res: express$Response = express$Response, +> extends express$Router<Req, Res> mixins events$EventEmitter { + constructor(): void; + locals: { [name: string]: mixed, ... }; + mountpath: string; + listen( + port: number, + hostname?: string, + backlog?: number, + callback?: (err?: ?Error) => mixed + ): ?http$Server; + listen( + port: number, + hostname?: string, + callback?: (err?: ?Error) => mixed + ): ?http$Server; + listen(port: number, callback?: (err?: ?Error) => mixed): ?http$Server; + listen(path: string, callback?: (err?: ?Error) => mixed): ?http$Server; + listen(handle: Object, callback?: (err?: ?Error) => mixed): ?http$Server; + disable(name: string): void; + disabled(name: string): boolean; + enable(name: string): this; + enabled(name: string): boolean; + engine(name: string, callback: Function): void; + /** + * Mixed will not be taken as a value option. Issue around using the GET http method name and the get for settings. + */ + // get(name: string): mixed; + set(name: string, value: mixed): mixed; + render( + name: string, + optionsOrFunction: { [name: string]: mixed, ... }, + callback: express$RenderCallback + ): void; + handle( + req: http$IncomingMessage<>, + res: http$ServerResponse, + next?: ?express$NextFunction + ): void; + // callable signature is not inherited + ( + req: http$IncomingMessage<>, + res: http$ServerResponse, + next?: ?express$NextFunction + ): void; +} + +declare type JsonOptions = { + inflate?: boolean, + limit?: string | number, + reviver?: (key: string, value: mixed) => mixed, + strict?: boolean, + type?: string | Array<string> | ((req: express$Request) => boolean), + verify?: ( + req: express$Request, + res: express$Response, + buf: Buffer, + encoding: string + ) => mixed, + ... +}; + +declare type express$UrlEncodedOptions = { + extended?: boolean, + inflate?: boolean, + limit?: string | number, + parameterLimit?: number, + type?: string | Array<string> | ((req: express$Request) => boolean), + verify?: ( + req: express$Request, + res: express$Response, + buf: Buffer, + encoding: string + ) => mixed, + ... +} + +declare module "express" { + declare export type RouterOptions = express$RouterOptions; + declare export type CookieOptions = express$CookieOptions; + declare export type Middleware< + Req: express$Request = express$Request, + Res: express$Response = express$Response, + > = express$Middleware<Req, Res>; + declare export type NextFunction = express$NextFunction; + declare export type RequestParams = express$RequestParams; + declare export type $Response = express$Response; + declare export type $Request = express$Request; + declare export type $Application< + Req: express$Request = express$Request, + Res: express$Response = express$Response, + > = express$Application<Req, Res>; + + declare module.exports: { + // If you try to call like a function, it will use this signature + <Req: express$Request, Res: express$Response>(): express$Application<Req, Res>, + json: (opts: ?JsonOptions) => express$Middleware<>, + // `static` property on the function + static: <Req: express$Request, Res: express$Response>(root: string, options?: Object) => express$Middleware<Req, Res>, + // `Router` property on the function + Router: typeof express$Router, + urlencoded: (opts: ?express$UrlEncodedOptions) => express$Middleware<>, + ... + }; +} diff --git a/server/flow-typed/npm/jest_v26.x.x.js b/server/flow-typed/npm/jest_v26.x.x.js index 587373b2940ab84c19393e44b1be2933abd1a369..f3cdd9bde54812625c5458b3cf4279aec7a8badd 100644 --- a/server/flow-typed/npm/jest_v26.x.x.js +++ b/server/flow-typed/npm/jest_v26.x.x.js @@ -1,1218 +1,1218 @@ -// flow-typed signature: e60c7806ec0ddaf4588f438843ef37bd -// flow-typed version: 7afca48d86/jest_v26.x.x/flow_>=v0.104.x - -type JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = { - (...args: TArguments): TReturn, - /** - * An object for introspecting mock calls - */ - mock: { - /** - * An array that represents all calls that have been made into this mock - * function. Each call is represented by an array of arguments that were - * passed during the call. - */ - calls: Array<TArguments>, - /** - * An array that contains all the object instances that have been - * instantiated from this mock function. - */ - instances: Array<TReturn>, - /** - * An array that contains all the object results that have been - * returned by this mock function call - */ - results: Array<{ - isThrow: boolean, - value: TReturn, - ... - }>, - ... - }, - /** - * Resets all information stored in the mockFn.mock.calls and - * mockFn.mock.instances arrays. Often this is useful when you want to clean - * up a mock's usage data between two assertions. - */ - mockClear(): void, - /** - * Resets all information stored in the mock. This is useful when you want to - * completely restore a mock back to its initial state. - */ - mockReset(): void, - /** - * Removes the mock and restores the initial implementation. This is useful - * when you want to mock functions in certain test cases and restore the - * original implementation in others. Beware that mockFn.mockRestore only - * works when mock was created with jest.spyOn. Thus you have to take care of - * restoration yourself when manually assigning jest.fn(). - */ - mockRestore(): void, - /** - * Accepts a function that should be used as the implementation of the mock. - * The mock itself will still record all calls that go into and instances - * that come from itself -- the only difference is that the implementation - * will also be executed when the mock is called. - */ - mockImplementation( - fn: (...args: TArguments) => TReturn - ): JestMockFn<TArguments, TReturn>, - /** - * Accepts a function that will be used as an implementation of the mock for - * one call to the mocked function. Can be chained so that multiple function - * calls produce different results. - */ - mockImplementationOnce( - fn: (...args: TArguments) => TReturn - ): JestMockFn<TArguments, TReturn>, - /** - * Accepts a string to use in test result output in place of "jest.fn()" to - * indicate which mock function is being referenced. - */ - mockName(name: string): JestMockFn<TArguments, TReturn>, - /** - * Just a simple sugar function for returning `this` - */ - mockReturnThis(): void, - /** - * Accepts a value that will be returned whenever the mock function is called. - */ - mockReturnValue(value: TReturn): JestMockFn<TArguments, TReturn>, - /** - * Sugar for only returning a value once inside your mock - */ - mockReturnValueOnce(value: TReturn): JestMockFn<TArguments, TReturn>, - /** - * Sugar for jest.fn().mockImplementation(() => Promise.resolve(value)) - */ - mockResolvedValue(value: TReturn): JestMockFn<TArguments, Promise<TReturn>>, - /** - * Sugar for jest.fn().mockImplementationOnce(() => Promise.resolve(value)) - */ - mockResolvedValueOnce( - value: TReturn - ): JestMockFn<TArguments, Promise<TReturn>>, - /** - * Sugar for jest.fn().mockImplementation(() => Promise.reject(value)) - */ - mockRejectedValue(value: TReturn): JestMockFn<TArguments, Promise<any>>, - /** - * Sugar for jest.fn().mockImplementationOnce(() => Promise.reject(value)) - */ - mockRejectedValueOnce(value: TReturn): JestMockFn<TArguments, Promise<any>>, - ... -}; - -type JestAsymmetricEqualityType = { - /** - * A custom Jasmine equality tester - */ - asymmetricMatch(value: mixed): boolean, - ... -}; - -type JestCallsType = { - allArgs(): mixed, - all(): mixed, - any(): boolean, - count(): number, - first(): mixed, - mostRecent(): mixed, - reset(): void, - ... -}; - -type JestClockType = { - install(): void, - mockDate(date: Date): void, - tick(milliseconds?: number): void, - uninstall(): void, - ... -}; - -type JestMatcherResult = { - message?: string | (() => string), - pass: boolean, - ... -}; - -type JestMatcher = ( - received: any, - ...actual: Array<any> -) => JestMatcherResult | Promise<JestMatcherResult>; - -type JestPromiseType = { - /** - * Use rejects to unwrap the reason of a rejected promise so any other - * matcher can be chained. If the promise is fulfilled the assertion fails. - */ - rejects: JestExpectType, - /** - * Use resolves to unwrap the value of a fulfilled promise so any other - * matcher can be chained. If the promise is rejected the assertion fails. - */ - resolves: JestExpectType, - ... -}; - -/** - * Jest allows functions and classes to be used as test names in test() and - * describe() - */ -type JestTestName = string | Function; - -/** - * Plugin: jest-styled-components - */ - -type JestStyledComponentsMatcherValue = - | string - | JestAsymmetricEqualityType - | RegExp - | typeof undefined; - -type JestStyledComponentsMatcherOptions = { - media?: string, - modifier?: string, - supports?: string, - ... -}; - -type JestStyledComponentsMatchersType = { - toHaveStyleRule( - property: string, - value: JestStyledComponentsMatcherValue, - options?: JestStyledComponentsMatcherOptions - ): void, - ... -}; - -/** - * Plugin: jest-enzyme - */ -type EnzymeMatchersType = { - // 5.x - toBeEmpty(): void, - toBePresent(): void, - // 6.x - toBeChecked(): void, - toBeDisabled(): void, - toBeEmptyRender(): void, - toContainMatchingElement(selector: string): void, - toContainMatchingElements(n: number, selector: string): void, - toContainExactlyOneMatchingElement(selector: string): void, - toContainReact(element: React$Element<any>): void, - toExist(): void, - toHaveClassName(className: string): void, - toHaveHTML(html: string): void, - toHaveProp: ((propKey: string, propValue?: any) => void) & - ((props: { ... }) => void), - toHaveRef(refName: string): void, - toHaveState: ((stateKey: string, stateValue?: any) => void) & - ((state: { ... }) => void), - toHaveStyle: ((styleKey: string, styleValue?: any) => void) & - ((style: { ... }) => void), - toHaveTagName(tagName: string): void, - toHaveText(text: string): void, - toHaveValue(value: any): void, - toIncludeText(text: string): void, - toMatchElement( - element: React$Element<any>, - options?: {| ignoreProps?: boolean, verbose?: boolean |} - ): void, - toMatchSelector(selector: string): void, - // 7.x - toHaveDisplayName(name: string): void, - ... -}; - -// DOM testing library extensions (jest-dom) -// https://github.com/testing-library/jest-dom -type DomTestingLibraryType = { - /** - * @deprecated - */ - toBeInTheDOM(container?: HTMLElement): void, - - // 4.x - toBeInTheDocument(): void, - toBeVisible(): void, - toBeEmpty(): void, - toBeDisabled(): void, - toBeEnabled(): void, - toBeInvalid(): void, - toBeRequired(): void, - toBeValid(): void, - toContainElement(element: HTMLElement | null): void, - toContainHTML(htmlText: string): void, - toHaveAttribute(attr: string, value?: any): void, - toHaveClass(...classNames: string[]): void, - toHaveFocus(): void, - toHaveFormValues(expectedValues: { [name: string]: any, ... }): void, - toHaveStyle(css: string | { [name: string]: any, ... }): void, - toHaveTextContent( - text: string | RegExp, - options?: {| normalizeWhitespace: boolean |} - ): void, - toHaveValue(value?: string | string[] | number): void, - - // 5.x - toHaveDisplayValue(value: string | string[]): void, - toBeChecked(): void, - ... -}; - -// Jest JQuery Matchers: https://github.com/unindented/custom-jquery-matchers -type JestJQueryMatchersType = { - toExist(): void, - toHaveLength(len: number): void, - toHaveId(id: string): void, - toHaveClass(className: string): void, - toHaveTag(tag: string): void, - toHaveAttr(key: string, val?: any): void, - toHaveProp(key: string, val?: any): void, - toHaveText(text: string | RegExp): void, - toHaveData(key: string, val?: any): void, - toHaveValue(val: any): void, - toHaveCss(css: { [key: string]: any, ... }): void, - toBeChecked(): void, - toBeDisabled(): void, - toBeEmpty(): void, - toBeHidden(): void, - toBeSelected(): void, - toBeVisible(): void, - toBeFocused(): void, - toBeInDom(): void, - toBeMatchedBy(sel: string): void, - toHaveDescendant(sel: string): void, - toHaveDescendantWithText(sel: string, text: string | RegExp): void, - ... -}; - -// Jest Extended Matchers: https://github.com/jest-community/jest-extended -type JestExtendedMatchersType = { - /** - * Note: Currently unimplemented - * Passing assertion - * - * @param {String} message - */ - // pass(message: string): void; - - /** - * Note: Currently unimplemented - * Failing assertion - * - * @param {String} message - */ - // fail(message: string): void; - - /** - * Use .toBeEmpty when checking if a String '', Array [] or Object {} is empty. - */ - toBeEmpty(): void, - /** - * Use .toBeOneOf when checking if a value is a member of a given Array. - * @param {Array.<*>} members - */ - toBeOneOf(members: any[]): void, - /** - * Use `.toBeNil` when checking a value is `null` or `undefined`. - */ - toBeNil(): void, - /** - * Use `.toSatisfy` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean`. - * @param {Function} predicate - */ - toSatisfy(predicate: (n: any) => boolean): void, - /** - * Use `.toBeArray` when checking if a value is an `Array`. - */ - toBeArray(): void, - /** - * Use `.toBeArrayOfSize` when checking if a value is an `Array` of size x. - * @param {Number} x - */ - toBeArrayOfSize(x: number): void, - /** - * Use `.toIncludeAllMembers` when checking if an `Array` contains all of the same members of a given set. - * @param {Array.<*>} members - */ - toIncludeAllMembers(members: any[]): void, - /** - * Use `.toIncludeAnyMembers` when checking if an `Array` contains any of the members of a given set. - * @param {Array.<*>} members - */ - toIncludeAnyMembers(members: any[]): void, - /** - * Use `.toSatisfyAll` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean` for all values in an array. - * @param {Function} predicate - */ - toSatisfyAll(predicate: (n: any) => boolean): void, - /** - * Use `.toBeBoolean` when checking if a value is a `Boolean`. - */ - toBeBoolean(): void, - /** - * Use `.toBeTrue` when checking a value is equal (===) to `true`. - */ - toBeTrue(): void, - /** - * Use `.toBeFalse` when checking a value is equal (===) to `false`. - */ - toBeFalse(): void, - /** - * Use .toBeDate when checking if a value is a Date. - */ - toBeDate(): void, - /** - * Use `.toBeFunction` when checking if a value is a `Function`. - */ - toBeFunction(): void, - /** - * Use `.toHaveBeenCalledBefore` when checking if a `Mock` was called before another `Mock`. - * - * Note: Required Jest version >22 - * Note: Your mock functions will have to be asynchronous to cause the timestamps inside of Jest to occur in a differentJS event loop, otherwise the mock timestamps will all be the same - * - * @param {Mock} mock - */ - toHaveBeenCalledBefore(mock: JestMockFn<any, any>): void, - /** - * Use `.toBeNumber` when checking if a value is a `Number`. - */ - toBeNumber(): void, - /** - * Use `.toBeNaN` when checking a value is `NaN`. - */ - toBeNaN(): void, - /** - * Use `.toBeFinite` when checking if a value is a `Number`, not `NaN` or `Infinity`. - */ - toBeFinite(): void, - /** - * Use `.toBePositive` when checking if a value is a positive `Number`. - */ - toBePositive(): void, - /** - * Use `.toBeNegative` when checking if a value is a negative `Number`. - */ - toBeNegative(): void, - /** - * Use `.toBeEven` when checking if a value is an even `Number`. - */ - toBeEven(): void, - /** - * Use `.toBeOdd` when checking if a value is an odd `Number`. - */ - toBeOdd(): void, - /** - * Use `.toBeWithin` when checking if a number is in between the given bounds of: start (inclusive) and end (exclusive). - * - * @param {Number} start - * @param {Number} end - */ - toBeWithin(start: number, end: number): void, - /** - * Use `.toBeObject` when checking if a value is an `Object`. - */ - toBeObject(): void, - /** - * Use `.toContainKey` when checking if an object contains the provided key. - * - * @param {String} key - */ - toContainKey(key: string): void, - /** - * Use `.toContainKeys` when checking if an object has all of the provided keys. - * - * @param {Array.<String>} keys - */ - toContainKeys(keys: string[]): void, - /** - * Use `.toContainAllKeys` when checking if an object only contains all of the provided keys. - * - * @param {Array.<String>} keys - */ - toContainAllKeys(keys: string[]): void, - /** - * Use `.toContainAnyKeys` when checking if an object contains at least one of the provided keys. - * - * @param {Array.<String>} keys - */ - toContainAnyKeys(keys: string[]): void, - /** - * Use `.toContainValue` when checking if an object contains the provided value. - * - * @param {*} value - */ - toContainValue(value: any): void, - /** - * Use `.toContainValues` when checking if an object contains all of the provided values. - * - * @param {Array.<*>} values - */ - toContainValues(values: any[]): void, - /** - * Use `.toContainAllValues` when checking if an object only contains all of the provided values. - * - * @param {Array.<*>} values - */ - toContainAllValues(values: any[]): void, - /** - * Use `.toContainAnyValues` when checking if an object contains at least one of the provided values. - * - * @param {Array.<*>} values - */ - toContainAnyValues(values: any[]): void, - /** - * Use `.toContainEntry` when checking if an object contains the provided entry. - * - * @param {Array.<String, String>} entry - */ - toContainEntry(entry: [string, string]): void, - /** - * Use `.toContainEntries` when checking if an object contains all of the provided entries. - * - * @param {Array.<Array.<String, String>>} entries - */ - toContainEntries(entries: [string, string][]): void, - /** - * Use `.toContainAllEntries` when checking if an object only contains all of the provided entries. - * - * @param {Array.<Array.<String, String>>} entries - */ - toContainAllEntries(entries: [string, string][]): void, - /** - * Use `.toContainAnyEntries` when checking if an object contains at least one of the provided entries. - * - * @param {Array.<Array.<String, String>>} entries - */ - toContainAnyEntries(entries: [string, string][]): void, - /** - * Use `.toBeExtensible` when checking if an object is extensible. - */ - toBeExtensible(): void, - /** - * Use `.toBeFrozen` when checking if an object is frozen. - */ - toBeFrozen(): void, - /** - * Use `.toBeSealed` when checking if an object is sealed. - */ - toBeSealed(): void, - /** - * Use `.toBeString` when checking if a value is a `String`. - */ - toBeString(): void, - /** - * Use `.toEqualCaseInsensitive` when checking if a string is equal (===) to another ignoring the casing of both strings. - * - * @param {String} string - */ - toEqualCaseInsensitive(string: string): void, - /** - * Use `.toStartWith` when checking if a `String` starts with a given `String` prefix. - * - * @param {String} prefix - */ - toStartWith(prefix: string): void, - /** - * Use `.toEndWith` when checking if a `String` ends with a given `String` suffix. - * - * @param {String} suffix - */ - toEndWith(suffix: string): void, - /** - * Use `.toInclude` when checking if a `String` includes the given `String` substring. - * - * @param {String} substring - */ - toInclude(substring: string): void, - /** - * Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times. - * - * @param {String} substring - * @param {Number} times - */ - toIncludeRepeated(substring: string, times: number): void, - /** - * Use `.toIncludeMultiple` when checking if a `String` includes all of the given substrings. - * - * @param {Array.<String>} substring - */ - toIncludeMultiple(substring: string[]): void, - ... -}; - -// Diffing snapshot utility for Jest (snapshot-diff) -// https://github.com/jest-community/snapshot-diff -type SnapshotDiffType = { - /** - * Compare the difference between the actual in the `expect()` - * vs the object inside `valueB` with some extra options. - */ - toMatchDiffSnapshot( - valueB: any, - options?: {| - expand?: boolean, - colors?: boolean, - contextLines?: number, - stablePatchmarks?: boolean, - aAnnotation?: string, - bAnnotation?: string, - |}, - testName?: string - ): void, - ... -}; - -interface JestExpectType { - not: JestExpectType & - EnzymeMatchersType & - DomTestingLibraryType & - JestJQueryMatchersType & - JestStyledComponentsMatchersType & - JestExtendedMatchersType & - SnapshotDiffType; - /** - * If you have a mock function, you can use .lastCalledWith to test what - * arguments it was last called with. - */ - lastCalledWith(...args: Array<any>): void; - /** - * toBe just checks that a value is what you expect. It uses === to check - * strict equality. - */ - toBe(value: any): void; - /** - * Use .toBeCalledWith to ensure that a mock function was called with - * specific arguments. - */ - toBeCalledWith(...args: Array<any>): void; - /** - * Using exact equality with floating point numbers is a bad idea. Rounding - * means that intuitive things fail. - */ - toBeCloseTo(num: number, delta: any): void; - /** - * Use .toBeDefined to check that a variable is not undefined. - */ - toBeDefined(): void; - /** - * Use .toBeFalsy when you don't care what a value is, you just want to - * ensure a value is false in a boolean context. - */ - toBeFalsy(): void; - /** - * To compare floating point numbers, you can use toBeGreaterThan. - */ - toBeGreaterThan(number: number): void; - /** - * To compare floating point numbers, you can use toBeGreaterThanOrEqual. - */ - toBeGreaterThanOrEqual(number: number): void; - /** - * To compare floating point numbers, you can use toBeLessThan. - */ - toBeLessThan(number: number): void; - /** - * To compare floating point numbers, you can use toBeLessThanOrEqual. - */ - toBeLessThanOrEqual(number: number): void; - /** - * Use .toBeInstanceOf(Class) to check that an object is an instance of a - * class. - */ - toBeInstanceOf(cls: Class<*>): void; - /** - * .toBeNull() is the same as .toBe(null) but the error messages are a bit - * nicer. - */ - toBeNull(): void; - /** - * Use .toBeTruthy when you don't care what a value is, you just want to - * ensure a value is true in a boolean context. - */ - toBeTruthy(): void; - /** - * Use .toBeUndefined to check that a variable is undefined. - */ - toBeUndefined(): void; - /** - * Use .toContain when you want to check that an item is in a list. For - * testing the items in the list, this uses ===, a strict equality check. - */ - toContain(item: any): void; - /** - * Use .toContainEqual when you want to check that an item is in a list. For - * testing the items in the list, this matcher recursively checks the - * equality of all fields, rather than checking for object identity. - */ - toContainEqual(item: any): void; - /** - * Use .toEqual when you want to check that two objects have the same value. - * This matcher recursively checks the equality of all fields, rather than - * checking for object identity. - */ - toEqual(value: any): void; - /** - * Use .toHaveBeenCalled to ensure that a mock function got called. - */ - toHaveBeenCalled(): void; - toBeCalled(): void; - /** - * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact - * number of times. - */ - toHaveBeenCalledTimes(number: number): void; - toBeCalledTimes(number: number): void; - /** - * - */ - toHaveBeenNthCalledWith(nthCall: number, ...args: Array<any>): void; - nthCalledWith(nthCall: number, ...args: Array<any>): void; - /** - * - */ - toHaveReturned(): void; - toReturn(): void; - /** - * - */ - toHaveReturnedTimes(number: number): void; - toReturnTimes(number: number): void; - /** - * - */ - toHaveReturnedWith(value: any): void; - toReturnWith(value: any): void; - /** - * - */ - toHaveLastReturnedWith(value: any): void; - lastReturnedWith(value: any): void; - /** - * - */ - toHaveNthReturnedWith(nthCall: number, value: any): void; - nthReturnedWith(nthCall: number, value: any): void; - /** - * Use .toHaveBeenCalledWith to ensure that a mock function was called with - * specific arguments. - */ - toHaveBeenCalledWith(...args: Array<any>): void; - toBeCalledWith(...args: Array<any>): void; - /** - * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called - * with specific arguments. - */ - toHaveBeenLastCalledWith(...args: Array<any>): void; - lastCalledWith(...args: Array<any>): void; - /** - * Check that an object has a .length property and it is set to a certain - * numeric value. - */ - toHaveLength(number: number): void; - /** - * - */ - toHaveProperty(propPath: string | $ReadOnlyArray<string>, value?: any): void; - /** - * Use .toMatch to check that a string matches a regular expression or string. - */ - toMatch(regexpOrString: RegExp | string): void; - /** - * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. - */ - toMatchObject(object: Object | Array<Object>): void; - /** - * Use .toStrictEqual to check that a javascript object matches a subset of the properties of an object. - */ - toStrictEqual(value: any): void; - /** - * This ensures that an Object matches the most recent snapshot. - */ - toMatchSnapshot(propertyMatchers?: any, name?: string): void; - /** - * This ensures that an Object matches the most recent snapshot. - */ - toMatchSnapshot(name: string): void; - - toMatchInlineSnapshot(snapshot?: string): void; - toMatchInlineSnapshot(propertyMatchers?: any, snapshot?: string): void; - /** - * Use .toThrow to test that a function throws when it is called. - * If you want to test that a specific error gets thrown, you can provide an - * argument to toThrow. The argument can be a string for the error message, - * a class for the error, or a regex that should match the error. - * - * Alias: .toThrowError - */ - toThrow(message?: string | Error | Class<Error> | RegExp): void; - toThrowError(message?: string | Error | Class<Error> | RegExp): void; - /** - * Use .toThrowErrorMatchingSnapshot to test that a function throws a error - * matching the most recent snapshot when it is called. - */ - toThrowErrorMatchingSnapshot(): void; - toThrowErrorMatchingInlineSnapshot(snapshot?: string): void; -} - -type JestObjectType = { - /** - * Disables automatic mocking in the module loader. - * - * After this method is called, all `require()`s will return the real - * versions of each module (rather than a mocked version). - */ - disableAutomock(): JestObjectType, - /** - * An un-hoisted version of disableAutomock - */ - autoMockOff(): JestObjectType, - /** - * Enables automatic mocking in the module loader. - */ - enableAutomock(): JestObjectType, - /** - * An un-hoisted version of enableAutomock - */ - autoMockOn(): JestObjectType, - /** - * Clears the mock.calls and mock.instances properties of all mocks. - * Equivalent to calling .mockClear() on every mocked function. - */ - clearAllMocks(): JestObjectType, - /** - * Resets the state of all mocks. Equivalent to calling .mockReset() on every - * mocked function. - */ - resetAllMocks(): JestObjectType, - /** - * Restores all mocks back to their original value. - */ - restoreAllMocks(): JestObjectType, - /** - * Removes any pending timers from the timer system. - */ - clearAllTimers(): void, - /** - * Returns the number of fake timers still left to run. - */ - getTimerCount(): number, - /** - * The same as `mock` but not moved to the top of the expectation by - * babel-jest. - */ - doMock(moduleName: string, moduleFactory?: any): JestObjectType, - /** - * The same as `unmock` but not moved to the top of the expectation by - * babel-jest. - */ - dontMock(moduleName: string): JestObjectType, - /** - * Returns a new, unused mock function. Optionally takes a mock - * implementation. - */ - fn<TArguments: $ReadOnlyArray<*>, TReturn>( - implementation?: (...args: TArguments) => TReturn - ): JestMockFn<TArguments, TReturn>, - /** - * Determines if the given function is a mocked function. - */ - isMockFunction(fn: Function): boolean, - /** - * Given the name of a module, use the automatic mocking system to generate a - * mocked version of the module for you. - */ - genMockFromModule(moduleName: string): any, - /** - * Mocks a module with an auto-mocked version when it is being required. - * - * The second argument can be used to specify an explicit module factory that - * is being run instead of using Jest's automocking feature. - * - * The third argument can be used to create virtual mocks -- mocks of modules - * that don't exist anywhere in the system. - */ - mock( - moduleName: string, - moduleFactory?: any, - options?: Object - ): JestObjectType, - /** - * Returns the actual module instead of a mock, bypassing all checks on - * whether the module should receive a mock implementation or not. - */ - requireActual<T>(m: $Flow$ModuleRef<T> | string): T, - /** - * Returns a mock module instead of the actual module, bypassing all checks - * on whether the module should be required normally or not. - */ - requireMock(moduleName: string): any, - /** - * Resets the module registry - the cache of all required modules. This is - * useful to isolate modules where local state might conflict between tests. - */ - resetModules(): JestObjectType, - /** - * Creates a sandbox registry for the modules that are loaded inside the - * callback function. This is useful to isolate specific modules for every - * test so that local module state doesn't conflict between tests. - */ - isolateModules(fn: () => void): JestObjectType, - /** - * Exhausts the micro-task queue (usually interfaced in node via - * process.nextTick). - */ - runAllTicks(): void, - /** - * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), - * setInterval(), and setImmediate()). - */ - runAllTimers(): void, - /** - * Exhausts all tasks queued by setImmediate(). - */ - runAllImmediates(): void, - /** - * Executes only the macro task queue (i.e. all tasks queued by setTimeout() - * or setInterval() and setImmediate()). - */ - advanceTimersByTime(msToRun: number): void, - /** - * Executes only the macro task queue (i.e. all tasks queued by setTimeout() - * or setInterval() and setImmediate()). - * - * Renamed to `advanceTimersByTime`. - */ - runTimersToTime(msToRun: number): void, - /** - * Executes only the macro-tasks that are currently pending (i.e., only the - * tasks that have been queued by setTimeout() or setInterval() up to this - * point) - */ - runOnlyPendingTimers(): void, - /** - * Explicitly supplies the mock object that the module system should return - * for the specified module. Note: It is recommended to use jest.mock() - * instead. - */ - setMock(moduleName: string, moduleExports: any): JestObjectType, - /** - * Indicates that the module system should never return a mocked version of - * the specified module from require() (e.g. that it should always return the - * real module). - */ - unmock(moduleName: string): JestObjectType, - /** - * Instructs Jest to use fake versions of the standard timer functions - * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, - * setImmediate and clearImmediate). - */ - useFakeTimers(mode?: 'modern' | 'legacy'): JestObjectType, - /** - * Instructs Jest to use the real versions of the standard timer functions. - */ - useRealTimers(): JestObjectType, - /** - * Creates a mock function similar to jest.fn but also tracks calls to - * object[methodName]. - */ - spyOn( - object: Object, - methodName: string, - accessType?: 'get' | 'set' - ): JestMockFn<any, any>, - /** - * Set the default timeout interval for tests and before/after hooks in milliseconds. - * Note: The default timeout interval is 5 seconds if this method is not called. - */ - setTimeout(timeout: number): JestObjectType, - ... -}; - -type JestSpyType = { calls: JestCallsType, ... }; - -type JestDoneFn = {| - (error?: Error): void, - fail: (error: Error) => void, -|}; - -/** Runs this function after every test inside this context */ -declare function afterEach( - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; -/** Runs this function before every test inside this context */ -declare function beforeEach( - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; -/** Runs this function after all tests have finished inside this context */ -declare function afterAll( - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; -/** Runs this function before any tests have started inside this context */ -declare function beforeAll( - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; - -/** A context for grouping tests together */ -declare var describe: { - /** - * Creates a block that groups together several related tests in one "test suite" - */ - (name: JestTestName, fn: () => void): void, - /** - * Only run this describe block - */ - only(name: JestTestName, fn: () => void): void, - /** - * Skip running this describe block - */ - skip(name: JestTestName, fn: () => void): void, - /** - * each runs this test against array of argument arrays per each run - * - * @param {table} table of Test - */ - each( - ...table: Array<Array<mixed> | mixed> | [Array<string>, string] - ): ( - name: JestTestName, - fn?: (...args: Array<any>) => ?Promise<mixed>, - timeout?: number - ) => void, - ... -}; - -/** An individual test unit */ -declare var it: { - /** - * An individual test unit - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - ( - name: JestTestName, - fn?: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number - ): void, - /** - * Only run this test - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - only: {| - ( - name: JestTestName, - fn?: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number - ): void, - each( - ...table: Array<Array<mixed> | mixed> | [Array<string>, string] - ): ( - name: JestTestName, - fn?: (...args: Array<any>) => ?Promise<mixed>, - timeout?: number - ) => void, - |}, - /** - * Skip running this test - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - skip( - name: JestTestName, - fn?: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number - ): void, - /** - * Highlight planned tests in the summary output - * - * @param {String} Name of Test to do - */ - todo(name: string): void, - /** - * Run the test concurrently - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - concurrent( - name: JestTestName, - fn?: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number - ): void, - /** - * each runs this test against array of argument arrays per each run - * - * @param {table} table of Test - */ - each( - ...table: Array<Array<mixed> | mixed> | [Array<string>, string] - ): ( - name: JestTestName, - fn?: (...args: Array<any>) => ?Promise<mixed>, - timeout?: number - ) => void, - ... -}; - -declare function fit( - name: JestTestName, - fn: (done: JestDoneFn) => ?Promise<mixed>, - timeout?: number -): void; -/** An individual test unit */ -declare var test: typeof it; -/** A disabled group of tests */ -declare var xdescribe: typeof describe; -/** A focused group of tests */ -declare var fdescribe: typeof describe; -/** A disabled individual test */ -declare var xit: typeof it; -/** A disabled individual test */ -declare var xtest: typeof it; - -type JestPrettyFormatColors = { - comment: { - close: string, - open: string, - ... - }, - content: { - close: string, - open: string, - ... - }, - prop: { - close: string, - open: string, - ... - }, - tag: { - close: string, - open: string, - ... - }, - value: { - close: string, - open: string, - ... - }, - ... -}; - -type JestPrettyFormatIndent = (string) => string; -type JestPrettyFormatRefs = Array<any>; -type JestPrettyFormatPrint = (any) => string; -type JestPrettyFormatStringOrNull = string | null; - -type JestPrettyFormatOptions = {| - callToJSON: boolean, - edgeSpacing: string, - escapeRegex: boolean, - highlight: boolean, - indent: number, - maxDepth: number, - min: boolean, - plugins: JestPrettyFormatPlugins, - printFunctionName: boolean, - spacing: string, - theme: {| - comment: string, - content: string, - prop: string, - tag: string, - value: string, - |}, -|}; - -type JestPrettyFormatPlugin = { - print: ( - val: any, - serialize: JestPrettyFormatPrint, - indent: JestPrettyFormatIndent, - opts: JestPrettyFormatOptions, - colors: JestPrettyFormatColors - ) => string, - test: (any) => boolean, - ... -}; - -type JestPrettyFormatPlugins = Array<JestPrettyFormatPlugin>; - -/** The expect function is used every time you want to test a value */ -declare var expect: { - /** The object that you want to make assertions against */ - ( - value: any - ): JestExpectType & - JestPromiseType & - EnzymeMatchersType & - DomTestingLibraryType & - JestJQueryMatchersType & - JestStyledComponentsMatchersType & - JestExtendedMatchersType & - SnapshotDiffType, - /** Add additional Jasmine matchers to Jest's roster */ - extend(matchers: { [name: string]: JestMatcher, ... }): void, - /** Add a module that formats application-specific data structures. */ - addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void, - assertions(expectedAssertions: number): void, - hasAssertions(): void, - any(value: mixed): JestAsymmetricEqualityType, - anything(): any, - arrayContaining(value: Array<mixed>): Array<mixed>, - objectContaining(value: Object): Object, - /** Matches any received string that contains the exact expected string. */ - stringContaining(value: string): string, - stringMatching(value: string | RegExp): string, - not: { - arrayContaining: (value: $ReadOnlyArray<mixed>) => Array<mixed>, - objectContaining: (value: { ... }) => Object, - stringContaining: (value: string) => string, - stringMatching: (value: string | RegExp) => string, - ... - }, - ... -}; - -// TODO handle return type -// http://jasmine.github.io/2.4/introduction.html#section-Spies -declare function spyOn(value: mixed, method: string): Object; - -/** Holds all functions related to manipulating test runner */ -declare var jest: JestObjectType; - -/** - * The global Jasmine object, this is generally not exposed as the public API, - * using features inside here could break in later versions of Jest. - */ -declare var jasmine: { - DEFAULT_TIMEOUT_INTERVAL: number, - any(value: mixed): JestAsymmetricEqualityType, - anything(): any, - arrayContaining(value: Array<mixed>): Array<mixed>, - clock(): JestClockType, - createSpy(name: string): JestSpyType, - createSpyObj( - baseName: string, - methodNames: Array<string> - ): { [methodName: string]: JestSpyType, ... }, - objectContaining(value: Object): Object, - stringMatching(value: string): string, - ... -}; +// flow-typed signature: e60c7806ec0ddaf4588f438843ef37bd +// flow-typed version: 7afca48d86/jest_v26.x.x/flow_>=v0.104.x + +type JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = { + (...args: TArguments): TReturn, + /** + * An object for introspecting mock calls + */ + mock: { + /** + * An array that represents all calls that have been made into this mock + * function. Each call is represented by an array of arguments that were + * passed during the call. + */ + calls: Array<TArguments>, + /** + * An array that contains all the object instances that have been + * instantiated from this mock function. + */ + instances: Array<TReturn>, + /** + * An array that contains all the object results that have been + * returned by this mock function call + */ + results: Array<{ + isThrow: boolean, + value: TReturn, + ... + }>, + ... + }, + /** + * Resets all information stored in the mockFn.mock.calls and + * mockFn.mock.instances arrays. Often this is useful when you want to clean + * up a mock's usage data between two assertions. + */ + mockClear(): void, + /** + * Resets all information stored in the mock. This is useful when you want to + * completely restore a mock back to its initial state. + */ + mockReset(): void, + /** + * Removes the mock and restores the initial implementation. This is useful + * when you want to mock functions in certain test cases and restore the + * original implementation in others. Beware that mockFn.mockRestore only + * works when mock was created with jest.spyOn. Thus you have to take care of + * restoration yourself when manually assigning jest.fn(). + */ + mockRestore(): void, + /** + * Accepts a function that should be used as the implementation of the mock. + * The mock itself will still record all calls that go into and instances + * that come from itself -- the only difference is that the implementation + * will also be executed when the mock is called. + */ + mockImplementation( + fn: (...args: TArguments) => TReturn + ): JestMockFn<TArguments, TReturn>, + /** + * Accepts a function that will be used as an implementation of the mock for + * one call to the mocked function. Can be chained so that multiple function + * calls produce different results. + */ + mockImplementationOnce( + fn: (...args: TArguments) => TReturn + ): JestMockFn<TArguments, TReturn>, + /** + * Accepts a string to use in test result output in place of "jest.fn()" to + * indicate which mock function is being referenced. + */ + mockName(name: string): JestMockFn<TArguments, TReturn>, + /** + * Just a simple sugar function for returning `this` + */ + mockReturnThis(): void, + /** + * Accepts a value that will be returned whenever the mock function is called. + */ + mockReturnValue(value: TReturn): JestMockFn<TArguments, TReturn>, + /** + * Sugar for only returning a value once inside your mock + */ + mockReturnValueOnce(value: TReturn): JestMockFn<TArguments, TReturn>, + /** + * Sugar for jest.fn().mockImplementation(() => Promise.resolve(value)) + */ + mockResolvedValue(value: TReturn): JestMockFn<TArguments, Promise<TReturn>>, + /** + * Sugar for jest.fn().mockImplementationOnce(() => Promise.resolve(value)) + */ + mockResolvedValueOnce( + value: TReturn + ): JestMockFn<TArguments, Promise<TReturn>>, + /** + * Sugar for jest.fn().mockImplementation(() => Promise.reject(value)) + */ + mockRejectedValue(value: TReturn): JestMockFn<TArguments, Promise<any>>, + /** + * Sugar for jest.fn().mockImplementationOnce(() => Promise.reject(value)) + */ + mockRejectedValueOnce(value: TReturn): JestMockFn<TArguments, Promise<any>>, + ... +}; + +type JestAsymmetricEqualityType = { + /** + * A custom Jasmine equality tester + */ + asymmetricMatch(value: mixed): boolean, + ... +}; + +type JestCallsType = { + allArgs(): mixed, + all(): mixed, + any(): boolean, + count(): number, + first(): mixed, + mostRecent(): mixed, + reset(): void, + ... +}; + +type JestClockType = { + install(): void, + mockDate(date: Date): void, + tick(milliseconds?: number): void, + uninstall(): void, + ... +}; + +type JestMatcherResult = { + message?: string | (() => string), + pass: boolean, + ... +}; + +type JestMatcher = ( + received: any, + ...actual: Array<any> +) => JestMatcherResult | Promise<JestMatcherResult>; + +type JestPromiseType = { + /** + * Use rejects to unwrap the reason of a rejected promise so any other + * matcher can be chained. If the promise is fulfilled the assertion fails. + */ + rejects: JestExpectType, + /** + * Use resolves to unwrap the value of a fulfilled promise so any other + * matcher can be chained. If the promise is rejected the assertion fails. + */ + resolves: JestExpectType, + ... +}; + +/** + * Jest allows functions and classes to be used as test names in test() and + * describe() + */ +type JestTestName = string | Function; + +/** + * Plugin: jest-styled-components + */ + +type JestStyledComponentsMatcherValue = + | string + | JestAsymmetricEqualityType + | RegExp + | typeof undefined; + +type JestStyledComponentsMatcherOptions = { + media?: string, + modifier?: string, + supports?: string, + ... +}; + +type JestStyledComponentsMatchersType = { + toHaveStyleRule( + property: string, + value: JestStyledComponentsMatcherValue, + options?: JestStyledComponentsMatcherOptions + ): void, + ... +}; + +/** + * Plugin: jest-enzyme + */ +type EnzymeMatchersType = { + // 5.x + toBeEmpty(): void, + toBePresent(): void, + // 6.x + toBeChecked(): void, + toBeDisabled(): void, + toBeEmptyRender(): void, + toContainMatchingElement(selector: string): void, + toContainMatchingElements(n: number, selector: string): void, + toContainExactlyOneMatchingElement(selector: string): void, + toContainReact(element: React$Element<any>): void, + toExist(): void, + toHaveClassName(className: string): void, + toHaveHTML(html: string): void, + toHaveProp: ((propKey: string, propValue?: any) => void) & + ((props: { ... }) => void), + toHaveRef(refName: string): void, + toHaveState: ((stateKey: string, stateValue?: any) => void) & + ((state: { ... }) => void), + toHaveStyle: ((styleKey: string, styleValue?: any) => void) & + ((style: { ... }) => void), + toHaveTagName(tagName: string): void, + toHaveText(text: string): void, + toHaveValue(value: any): void, + toIncludeText(text: string): void, + toMatchElement( + element: React$Element<any>, + options?: {| ignoreProps?: boolean, verbose?: boolean |} + ): void, + toMatchSelector(selector: string): void, + // 7.x + toHaveDisplayName(name: string): void, + ... +}; + +// DOM testing library extensions (jest-dom) +// https://github.com/testing-library/jest-dom +type DomTestingLibraryType = { + /** + * @deprecated + */ + toBeInTheDOM(container?: HTMLElement): void, + + // 4.x + toBeInTheDocument(): void, + toBeVisible(): void, + toBeEmpty(): void, + toBeDisabled(): void, + toBeEnabled(): void, + toBeInvalid(): void, + toBeRequired(): void, + toBeValid(): void, + toContainElement(element: HTMLElement | null): void, + toContainHTML(htmlText: string): void, + toHaveAttribute(attr: string, value?: any): void, + toHaveClass(...classNames: string[]): void, + toHaveFocus(): void, + toHaveFormValues(expectedValues: { [name: string]: any, ... }): void, + toHaveStyle(css: string | { [name: string]: any, ... }): void, + toHaveTextContent( + text: string | RegExp, + options?: {| normalizeWhitespace: boolean |} + ): void, + toHaveValue(value?: string | string[] | number): void, + + // 5.x + toHaveDisplayValue(value: string | string[]): void, + toBeChecked(): void, + ... +}; + +// Jest JQuery Matchers: https://github.com/unindented/custom-jquery-matchers +type JestJQueryMatchersType = { + toExist(): void, + toHaveLength(len: number): void, + toHaveId(id: string): void, + toHaveClass(className: string): void, + toHaveTag(tag: string): void, + toHaveAttr(key: string, val?: any): void, + toHaveProp(key: string, val?: any): void, + toHaveText(text: string | RegExp): void, + toHaveData(key: string, val?: any): void, + toHaveValue(val: any): void, + toHaveCss(css: { [key: string]: any, ... }): void, + toBeChecked(): void, + toBeDisabled(): void, + toBeEmpty(): void, + toBeHidden(): void, + toBeSelected(): void, + toBeVisible(): void, + toBeFocused(): void, + toBeInDom(): void, + toBeMatchedBy(sel: string): void, + toHaveDescendant(sel: string): void, + toHaveDescendantWithText(sel: string, text: string | RegExp): void, + ... +}; + +// Jest Extended Matchers: https://github.com/jest-community/jest-extended +type JestExtendedMatchersType = { + /** + * Note: Currently unimplemented + * Passing assertion + * + * @param {String} message + */ + // pass(message: string): void; + + /** + * Note: Currently unimplemented + * Failing assertion + * + * @param {String} message + */ + // fail(message: string): void; + + /** + * Use .toBeEmpty when checking if a String '', Array [] or Object {} is empty. + */ + toBeEmpty(): void, + /** + * Use .toBeOneOf when checking if a value is a member of a given Array. + * @param {Array.<*>} members + */ + toBeOneOf(members: any[]): void, + /** + * Use `.toBeNil` when checking a value is `null` or `undefined`. + */ + toBeNil(): void, + /** + * Use `.toSatisfy` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean`. + * @param {Function} predicate + */ + toSatisfy(predicate: (n: any) => boolean): void, + /** + * Use `.toBeArray` when checking if a value is an `Array`. + */ + toBeArray(): void, + /** + * Use `.toBeArrayOfSize` when checking if a value is an `Array` of size x. + * @param {Number} x + */ + toBeArrayOfSize(x: number): void, + /** + * Use `.toIncludeAllMembers` when checking if an `Array` contains all of the same members of a given set. + * @param {Array.<*>} members + */ + toIncludeAllMembers(members: any[]): void, + /** + * Use `.toIncludeAnyMembers` when checking if an `Array` contains any of the members of a given set. + * @param {Array.<*>} members + */ + toIncludeAnyMembers(members: any[]): void, + /** + * Use `.toSatisfyAll` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean` for all values in an array. + * @param {Function} predicate + */ + toSatisfyAll(predicate: (n: any) => boolean): void, + /** + * Use `.toBeBoolean` when checking if a value is a `Boolean`. + */ + toBeBoolean(): void, + /** + * Use `.toBeTrue` when checking a value is equal (===) to `true`. + */ + toBeTrue(): void, + /** + * Use `.toBeFalse` when checking a value is equal (===) to `false`. + */ + toBeFalse(): void, + /** + * Use .toBeDate when checking if a value is a Date. + */ + toBeDate(): void, + /** + * Use `.toBeFunction` when checking if a value is a `Function`. + */ + toBeFunction(): void, + /** + * Use `.toHaveBeenCalledBefore` when checking if a `Mock` was called before another `Mock`. + * + * Note: Required Jest version >22 + * Note: Your mock functions will have to be asynchronous to cause the timestamps inside of Jest to occur in a differentJS event loop, otherwise the mock timestamps will all be the same + * + * @param {Mock} mock + */ + toHaveBeenCalledBefore(mock: JestMockFn<any, any>): void, + /** + * Use `.toBeNumber` when checking if a value is a `Number`. + */ + toBeNumber(): void, + /** + * Use `.toBeNaN` when checking a value is `NaN`. + */ + toBeNaN(): void, + /** + * Use `.toBeFinite` when checking if a value is a `Number`, not `NaN` or `Infinity`. + */ + toBeFinite(): void, + /** + * Use `.toBePositive` when checking if a value is a positive `Number`. + */ + toBePositive(): void, + /** + * Use `.toBeNegative` when checking if a value is a negative `Number`. + */ + toBeNegative(): void, + /** + * Use `.toBeEven` when checking if a value is an even `Number`. + */ + toBeEven(): void, + /** + * Use `.toBeOdd` when checking if a value is an odd `Number`. + */ + toBeOdd(): void, + /** + * Use `.toBeWithin` when checking if a number is in between the given bounds of: start (inclusive) and end (exclusive). + * + * @param {Number} start + * @param {Number} end + */ + toBeWithin(start: number, end: number): void, + /** + * Use `.toBeObject` when checking if a value is an `Object`. + */ + toBeObject(): void, + /** + * Use `.toContainKey` when checking if an object contains the provided key. + * + * @param {String} key + */ + toContainKey(key: string): void, + /** + * Use `.toContainKeys` when checking if an object has all of the provided keys. + * + * @param {Array.<String>} keys + */ + toContainKeys(keys: string[]): void, + /** + * Use `.toContainAllKeys` when checking if an object only contains all of the provided keys. + * + * @param {Array.<String>} keys + */ + toContainAllKeys(keys: string[]): void, + /** + * Use `.toContainAnyKeys` when checking if an object contains at least one of the provided keys. + * + * @param {Array.<String>} keys + */ + toContainAnyKeys(keys: string[]): void, + /** + * Use `.toContainValue` when checking if an object contains the provided value. + * + * @param {*} value + */ + toContainValue(value: any): void, + /** + * Use `.toContainValues` when checking if an object contains all of the provided values. + * + * @param {Array.<*>} values + */ + toContainValues(values: any[]): void, + /** + * Use `.toContainAllValues` when checking if an object only contains all of the provided values. + * + * @param {Array.<*>} values + */ + toContainAllValues(values: any[]): void, + /** + * Use `.toContainAnyValues` when checking if an object contains at least one of the provided values. + * + * @param {Array.<*>} values + */ + toContainAnyValues(values: any[]): void, + /** + * Use `.toContainEntry` when checking if an object contains the provided entry. + * + * @param {Array.<String, String>} entry + */ + toContainEntry(entry: [string, string]): void, + /** + * Use `.toContainEntries` when checking if an object contains all of the provided entries. + * + * @param {Array.<Array.<String, String>>} entries + */ + toContainEntries(entries: [string, string][]): void, + /** + * Use `.toContainAllEntries` when checking if an object only contains all of the provided entries. + * + * @param {Array.<Array.<String, String>>} entries + */ + toContainAllEntries(entries: [string, string][]): void, + /** + * Use `.toContainAnyEntries` when checking if an object contains at least one of the provided entries. + * + * @param {Array.<Array.<String, String>>} entries + */ + toContainAnyEntries(entries: [string, string][]): void, + /** + * Use `.toBeExtensible` when checking if an object is extensible. + */ + toBeExtensible(): void, + /** + * Use `.toBeFrozen` when checking if an object is frozen. + */ + toBeFrozen(): void, + /** + * Use `.toBeSealed` when checking if an object is sealed. + */ + toBeSealed(): void, + /** + * Use `.toBeString` when checking if a value is a `String`. + */ + toBeString(): void, + /** + * Use `.toEqualCaseInsensitive` when checking if a string is equal (===) to another ignoring the casing of both strings. + * + * @param {String} string + */ + toEqualCaseInsensitive(string: string): void, + /** + * Use `.toStartWith` when checking if a `String` starts with a given `String` prefix. + * + * @param {String} prefix + */ + toStartWith(prefix: string): void, + /** + * Use `.toEndWith` when checking if a `String` ends with a given `String` suffix. + * + * @param {String} suffix + */ + toEndWith(suffix: string): void, + /** + * Use `.toInclude` when checking if a `String` includes the given `String` substring. + * + * @param {String} substring + */ + toInclude(substring: string): void, + /** + * Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times. + * + * @param {String} substring + * @param {Number} times + */ + toIncludeRepeated(substring: string, times: number): void, + /** + * Use `.toIncludeMultiple` when checking if a `String` includes all of the given substrings. + * + * @param {Array.<String>} substring + */ + toIncludeMultiple(substring: string[]): void, + ... +}; + +// Diffing snapshot utility for Jest (snapshot-diff) +// https://github.com/jest-community/snapshot-diff +type SnapshotDiffType = { + /** + * Compare the difference between the actual in the `expect()` + * vs the object inside `valueB` with some extra options. + */ + toMatchDiffSnapshot( + valueB: any, + options?: {| + expand?: boolean, + colors?: boolean, + contextLines?: number, + stablePatchmarks?: boolean, + aAnnotation?: string, + bAnnotation?: string, + |}, + testName?: string + ): void, + ... +}; + +interface JestExpectType { + not: JestExpectType & + EnzymeMatchersType & + DomTestingLibraryType & + JestJQueryMatchersType & + JestStyledComponentsMatchersType & + JestExtendedMatchersType & + SnapshotDiffType; + /** + * If you have a mock function, you can use .lastCalledWith to test what + * arguments it was last called with. + */ + lastCalledWith(...args: Array<any>): void; + /** + * toBe just checks that a value is what you expect. It uses === to check + * strict equality. + */ + toBe(value: any): void; + /** + * Use .toBeCalledWith to ensure that a mock function was called with + * specific arguments. + */ + toBeCalledWith(...args: Array<any>): void; + /** + * Using exact equality with floating point numbers is a bad idea. Rounding + * means that intuitive things fail. + */ + toBeCloseTo(num: number, delta: any): void; + /** + * Use .toBeDefined to check that a variable is not undefined. + */ + toBeDefined(): void; + /** + * Use .toBeFalsy when you don't care what a value is, you just want to + * ensure a value is false in a boolean context. + */ + toBeFalsy(): void; + /** + * To compare floating point numbers, you can use toBeGreaterThan. + */ + toBeGreaterThan(number: number): void; + /** + * To compare floating point numbers, you can use toBeGreaterThanOrEqual. + */ + toBeGreaterThanOrEqual(number: number): void; + /** + * To compare floating point numbers, you can use toBeLessThan. + */ + toBeLessThan(number: number): void; + /** + * To compare floating point numbers, you can use toBeLessThanOrEqual. + */ + toBeLessThanOrEqual(number: number): void; + /** + * Use .toBeInstanceOf(Class) to check that an object is an instance of a + * class. + */ + toBeInstanceOf(cls: Class<*>): void; + /** + * .toBeNull() is the same as .toBe(null) but the error messages are a bit + * nicer. + */ + toBeNull(): void; + /** + * Use .toBeTruthy when you don't care what a value is, you just want to + * ensure a value is true in a boolean context. + */ + toBeTruthy(): void; + /** + * Use .toBeUndefined to check that a variable is undefined. + */ + toBeUndefined(): void; + /** + * Use .toContain when you want to check that an item is in a list. For + * testing the items in the list, this uses ===, a strict equality check. + */ + toContain(item: any): void; + /** + * Use .toContainEqual when you want to check that an item is in a list. For + * testing the items in the list, this matcher recursively checks the + * equality of all fields, rather than checking for object identity. + */ + toContainEqual(item: any): void; + /** + * Use .toEqual when you want to check that two objects have the same value. + * This matcher recursively checks the equality of all fields, rather than + * checking for object identity. + */ + toEqual(value: any): void; + /** + * Use .toHaveBeenCalled to ensure that a mock function got called. + */ + toHaveBeenCalled(): void; + toBeCalled(): void; + /** + * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact + * number of times. + */ + toHaveBeenCalledTimes(number: number): void; + toBeCalledTimes(number: number): void; + /** + * + */ + toHaveBeenNthCalledWith(nthCall: number, ...args: Array<any>): void; + nthCalledWith(nthCall: number, ...args: Array<any>): void; + /** + * + */ + toHaveReturned(): void; + toReturn(): void; + /** + * + */ + toHaveReturnedTimes(number: number): void; + toReturnTimes(number: number): void; + /** + * + */ + toHaveReturnedWith(value: any): void; + toReturnWith(value: any): void; + /** + * + */ + toHaveLastReturnedWith(value: any): void; + lastReturnedWith(value: any): void; + /** + * + */ + toHaveNthReturnedWith(nthCall: number, value: any): void; + nthReturnedWith(nthCall: number, value: any): void; + /** + * Use .toHaveBeenCalledWith to ensure that a mock function was called with + * specific arguments. + */ + toHaveBeenCalledWith(...args: Array<any>): void; + toBeCalledWith(...args: Array<any>): void; + /** + * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called + * with specific arguments. + */ + toHaveBeenLastCalledWith(...args: Array<any>): void; + lastCalledWith(...args: Array<any>): void; + /** + * Check that an object has a .length property and it is set to a certain + * numeric value. + */ + toHaveLength(number: number): void; + /** + * + */ + toHaveProperty(propPath: string | $ReadOnlyArray<string>, value?: any): void; + /** + * Use .toMatch to check that a string matches a regular expression or string. + */ + toMatch(regexpOrString: RegExp | string): void; + /** + * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. + */ + toMatchObject(object: Object | Array<Object>): void; + /** + * Use .toStrictEqual to check that a javascript object matches a subset of the properties of an object. + */ + toStrictEqual(value: any): void; + /** + * This ensures that an Object matches the most recent snapshot. + */ + toMatchSnapshot(propertyMatchers?: any, name?: string): void; + /** + * This ensures that an Object matches the most recent snapshot. + */ + toMatchSnapshot(name: string): void; + + toMatchInlineSnapshot(snapshot?: string): void; + toMatchInlineSnapshot(propertyMatchers?: any, snapshot?: string): void; + /** + * Use .toThrow to test that a function throws when it is called. + * If you want to test that a specific error gets thrown, you can provide an + * argument to toThrow. The argument can be a string for the error message, + * a class for the error, or a regex that should match the error. + * + * Alias: .toThrowError + */ + toThrow(message?: string | Error | Class<Error> | RegExp): void; + toThrowError(message?: string | Error | Class<Error> | RegExp): void; + /** + * Use .toThrowErrorMatchingSnapshot to test that a function throws a error + * matching the most recent snapshot when it is called. + */ + toThrowErrorMatchingSnapshot(): void; + toThrowErrorMatchingInlineSnapshot(snapshot?: string): void; +} + +type JestObjectType = { + /** + * Disables automatic mocking in the module loader. + * + * After this method is called, all `require()`s will return the real + * versions of each module (rather than a mocked version). + */ + disableAutomock(): JestObjectType, + /** + * An un-hoisted version of disableAutomock + */ + autoMockOff(): JestObjectType, + /** + * Enables automatic mocking in the module loader. + */ + enableAutomock(): JestObjectType, + /** + * An un-hoisted version of enableAutomock + */ + autoMockOn(): JestObjectType, + /** + * Clears the mock.calls and mock.instances properties of all mocks. + * Equivalent to calling .mockClear() on every mocked function. + */ + clearAllMocks(): JestObjectType, + /** + * Resets the state of all mocks. Equivalent to calling .mockReset() on every + * mocked function. + */ + resetAllMocks(): JestObjectType, + /** + * Restores all mocks back to their original value. + */ + restoreAllMocks(): JestObjectType, + /** + * Removes any pending timers from the timer system. + */ + clearAllTimers(): void, + /** + * Returns the number of fake timers still left to run. + */ + getTimerCount(): number, + /** + * The same as `mock` but not moved to the top of the expectation by + * babel-jest. + */ + doMock(moduleName: string, moduleFactory?: any): JestObjectType, + /** + * The same as `unmock` but not moved to the top of the expectation by + * babel-jest. + */ + dontMock(moduleName: string): JestObjectType, + /** + * Returns a new, unused mock function. Optionally takes a mock + * implementation. + */ + fn<TArguments: $ReadOnlyArray<*>, TReturn>( + implementation?: (...args: TArguments) => TReturn + ): JestMockFn<TArguments, TReturn>, + /** + * Determines if the given function is a mocked function. + */ + isMockFunction(fn: Function): boolean, + /** + * Given the name of a module, use the automatic mocking system to generate a + * mocked version of the module for you. + */ + genMockFromModule(moduleName: string): any, + /** + * Mocks a module with an auto-mocked version when it is being required. + * + * The second argument can be used to specify an explicit module factory that + * is being run instead of using Jest's automocking feature. + * + * The third argument can be used to create virtual mocks -- mocks of modules + * that don't exist anywhere in the system. + */ + mock( + moduleName: string, + moduleFactory?: any, + options?: Object + ): JestObjectType, + /** + * Returns the actual module instead of a mock, bypassing all checks on + * whether the module should receive a mock implementation or not. + */ + requireActual<T>(m: $Flow$ModuleRef<T> | string): T, + /** + * Returns a mock module instead of the actual module, bypassing all checks + * on whether the module should be required normally or not. + */ + requireMock(moduleName: string): any, + /** + * Resets the module registry - the cache of all required modules. This is + * useful to isolate modules where local state might conflict between tests. + */ + resetModules(): JestObjectType, + /** + * Creates a sandbox registry for the modules that are loaded inside the + * callback function. This is useful to isolate specific modules for every + * test so that local module state doesn't conflict between tests. + */ + isolateModules(fn: () => void): JestObjectType, + /** + * Exhausts the micro-task queue (usually interfaced in node via + * process.nextTick). + */ + runAllTicks(): void, + /** + * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), + * setInterval(), and setImmediate()). + */ + runAllTimers(): void, + /** + * Exhausts all tasks queued by setImmediate(). + */ + runAllImmediates(): void, + /** + * Executes only the macro task queue (i.e. all tasks queued by setTimeout() + * or setInterval() and setImmediate()). + */ + advanceTimersByTime(msToRun: number): void, + /** + * Executes only the macro task queue (i.e. all tasks queued by setTimeout() + * or setInterval() and setImmediate()). + * + * Renamed to `advanceTimersByTime`. + */ + runTimersToTime(msToRun: number): void, + /** + * Executes only the macro-tasks that are currently pending (i.e., only the + * tasks that have been queued by setTimeout() or setInterval() up to this + * point) + */ + runOnlyPendingTimers(): void, + /** + * Explicitly supplies the mock object that the module system should return + * for the specified module. Note: It is recommended to use jest.mock() + * instead. + */ + setMock(moduleName: string, moduleExports: any): JestObjectType, + /** + * Indicates that the module system should never return a mocked version of + * the specified module from require() (e.g. that it should always return the + * real module). + */ + unmock(moduleName: string): JestObjectType, + /** + * Instructs Jest to use fake versions of the standard timer functions + * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, + * setImmediate and clearImmediate). + */ + useFakeTimers(mode?: 'modern' | 'legacy'): JestObjectType, + /** + * Instructs Jest to use the real versions of the standard timer functions. + */ + useRealTimers(): JestObjectType, + /** + * Creates a mock function similar to jest.fn but also tracks calls to + * object[methodName]. + */ + spyOn( + object: Object, + methodName: string, + accessType?: 'get' | 'set' + ): JestMockFn<any, any>, + /** + * Set the default timeout interval for tests and before/after hooks in milliseconds. + * Note: The default timeout interval is 5 seconds if this method is not called. + */ + setTimeout(timeout: number): JestObjectType, + ... +}; + +type JestSpyType = { calls: JestCallsType, ... }; + +type JestDoneFn = {| + (error?: Error): void, + fail: (error: Error) => void, +|}; + +/** Runs this function after every test inside this context */ +declare function afterEach( + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; +/** Runs this function before every test inside this context */ +declare function beforeEach( + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; +/** Runs this function after all tests have finished inside this context */ +declare function afterAll( + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; +/** Runs this function before any tests have started inside this context */ +declare function beforeAll( + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; + +/** A context for grouping tests together */ +declare var describe: { + /** + * Creates a block that groups together several related tests in one "test suite" + */ + (name: JestTestName, fn: () => void): void, + /** + * Only run this describe block + */ + only(name: JestTestName, fn: () => void): void, + /** + * Skip running this describe block + */ + skip(name: JestTestName, fn: () => void): void, + /** + * each runs this test against array of argument arrays per each run + * + * @param {table} table of Test + */ + each( + ...table: Array<Array<mixed> | mixed> | [Array<string>, string] + ): ( + name: JestTestName, + fn?: (...args: Array<any>) => ?Promise<mixed>, + timeout?: number + ) => void, + ... +}; + +/** An individual test unit */ +declare var it: { + /** + * An individual test unit + * + * @param {JestTestName} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + ( + name: JestTestName, + fn?: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number + ): void, + /** + * Only run this test + * + * @param {JestTestName} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + only: {| + ( + name: JestTestName, + fn?: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number + ): void, + each( + ...table: Array<Array<mixed> | mixed> | [Array<string>, string] + ): ( + name: JestTestName, + fn?: (...args: Array<any>) => ?Promise<mixed>, + timeout?: number + ) => void, + |}, + /** + * Skip running this test + * + * @param {JestTestName} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + skip( + name: JestTestName, + fn?: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number + ): void, + /** + * Highlight planned tests in the summary output + * + * @param {String} Name of Test to do + */ + todo(name: string): void, + /** + * Run the test concurrently + * + * @param {JestTestName} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + concurrent( + name: JestTestName, + fn?: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number + ): void, + /** + * each runs this test against array of argument arrays per each run + * + * @param {table} table of Test + */ + each( + ...table: Array<Array<mixed> | mixed> | [Array<string>, string] + ): ( + name: JestTestName, + fn?: (...args: Array<any>) => ?Promise<mixed>, + timeout?: number + ) => void, + ... +}; + +declare function fit( + name: JestTestName, + fn: (done: JestDoneFn) => ?Promise<mixed>, + timeout?: number +): void; +/** An individual test unit */ +declare var test: typeof it; +/** A disabled group of tests */ +declare var xdescribe: typeof describe; +/** A focused group of tests */ +declare var fdescribe: typeof describe; +/** A disabled individual test */ +declare var xit: typeof it; +/** A disabled individual test */ +declare var xtest: typeof it; + +type JestPrettyFormatColors = { + comment: { + close: string, + open: string, + ... + }, + content: { + close: string, + open: string, + ... + }, + prop: { + close: string, + open: string, + ... + }, + tag: { + close: string, + open: string, + ... + }, + value: { + close: string, + open: string, + ... + }, + ... +}; + +type JestPrettyFormatIndent = (string) => string; +type JestPrettyFormatRefs = Array<any>; +type JestPrettyFormatPrint = (any) => string; +type JestPrettyFormatStringOrNull = string | null; + +type JestPrettyFormatOptions = {| + callToJSON: boolean, + edgeSpacing: string, + escapeRegex: boolean, + highlight: boolean, + indent: number, + maxDepth: number, + min: boolean, + plugins: JestPrettyFormatPlugins, + printFunctionName: boolean, + spacing: string, + theme: {| + comment: string, + content: string, + prop: string, + tag: string, + value: string, + |}, +|}; + +type JestPrettyFormatPlugin = { + print: ( + val: any, + serialize: JestPrettyFormatPrint, + indent: JestPrettyFormatIndent, + opts: JestPrettyFormatOptions, + colors: JestPrettyFormatColors + ) => string, + test: (any) => boolean, + ... +}; + +type JestPrettyFormatPlugins = Array<JestPrettyFormatPlugin>; + +/** The expect function is used every time you want to test a value */ +declare var expect: { + /** The object that you want to make assertions against */ + ( + value: any + ): JestExpectType & + JestPromiseType & + EnzymeMatchersType & + DomTestingLibraryType & + JestJQueryMatchersType & + JestStyledComponentsMatchersType & + JestExtendedMatchersType & + SnapshotDiffType, + /** Add additional Jasmine matchers to Jest's roster */ + extend(matchers: { [name: string]: JestMatcher, ... }): void, + /** Add a module that formats application-specific data structures. */ + addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void, + assertions(expectedAssertions: number): void, + hasAssertions(): void, + any(value: mixed): JestAsymmetricEqualityType, + anything(): any, + arrayContaining(value: Array<mixed>): Array<mixed>, + objectContaining(value: Object): Object, + /** Matches any received string that contains the exact expected string. */ + stringContaining(value: string): string, + stringMatching(value: string | RegExp): string, + not: { + arrayContaining: (value: $ReadOnlyArray<mixed>) => Array<mixed>, + objectContaining: (value: { ... }) => Object, + stringContaining: (value: string) => string, + stringMatching: (value: string | RegExp) => string, + ... + }, + ... +}; + +// TODO handle return type +// http://jasmine.github.io/2.4/introduction.html#section-Spies +declare function spyOn(value: mixed, method: string): Object; + +/** Holds all functions related to manipulating test runner */ +declare var jest: JestObjectType; + +/** + * The global Jasmine object, this is generally not exposed as the public API, + * using features inside here could break in later versions of Jest. + */ +declare var jasmine: { + DEFAULT_TIMEOUT_INTERVAL: number, + any(value: mixed): JestAsymmetricEqualityType, + anything(): any, + arrayContaining(value: Array<mixed>): Array<mixed>, + clock(): JestClockType, + createSpy(name: string): JestSpyType, + createSpyObj( + baseName: string, + methodNames: Array<string> + ): { [methodName: string]: JestSpyType, ... }, + objectContaining(value: Object): Object, + stringMatching(value: string): string, + ... +}; diff --git a/server/flow-typed/npm/mysql_v2.x.x.js b/server/flow-typed/npm/mysql_v2.x.x.js index cbf5651b059b5c005a9b78eac8aaa80e1988f80c..e0bdc82ef4e762c8e59d6cba786ac131bf492615 100644 --- a/server/flow-typed/npm/mysql_v2.x.x.js +++ b/server/flow-typed/npm/mysql_v2.x.x.js @@ -1,197 +1,197 @@ -// flow-typed signature: c88436aba2c98d85d79c75fd283c917f -// flow-typed version: c3e3979308/mysql_v2.x.x/flow_>=v0.104.x - -// TODO: Events on event emitters -// TODO: Ssl structure type in ConnectionOptions -// TODO: PoolNamespace internal structure -// TODO: Packets internal structure - -declare module "mysql" { - declare type TypeCastField = { - db: string, - table: string, - name: string, - type: string, - length: number, - string: () => string, - buffer: () => Buffer - } - - declare type ConnectionOptions = { - host?: string, - port?: number, - localAddress?: string, - socketPath?: string, - user: string, - password: string, - database?: string, - charset?: string, - timezone?: string, - connectTimeout?: number, - stringifyObjects?: boolean, - insecureAuth?: boolean, - typeCast?: boolean | ((field: TypeCastField, next: () => mixed) => any), - queryFormat?: (query: string, values: ?mixed, timezone: string) => string, - supportBigNumbers?: boolean, - bigNumberStrings?: boolean, - dateStrings?: boolean | Array<string>, - // Array form contains ids of packets for logging - debug?: boolean | Array<string>, - trace?: boolean, - multipleStatements?: boolean, - flags?: string, - ssl?: string | {...}, - ... - }; - - declare type QueryOptions = { - sql: string, - typeCast?: boolean | ((field: TypeCastField, next: () => mixed) => any), - // string form is a separator used to produce column names - nestTables?: boolean | string, - values?: Array<mixed>, - timeout?: number, - ... - } | string; - - declare type QueryResults = Array<Object> & { - insertId?: string | number, - affectedRows?: number, - changedRows?: number, - ... - }; - - declare type QueryField = { - name: string, - type: string, - length: number, - table: string, - db: string, - ... - }; - - declare class Query extends events$EventEmitter { - // readableStreamOptions declared in Flow /lib/node.js - stream(options?: readableStreamOptions): stream$Readable; - } - - declare class Connection extends events$EventEmitter { - threadId: number; - connect(callback?: (error: ?Error) => *): void; - - release(): void; - destroy(): void; - - end(callback?: (error: ?Error) => *): void; - - query( - sql: QueryOptions, - values?: Array<mixed> | {...}, - callback?: QueryCallback - ): Query; - query(sql: QueryOptions, callback?: QueryCallback): Query; - - changeUser( - options: { - user?: string, - password?: string, - charset?: string, - database?: string, - ... - }, - callback: (error: ?Error) => * - ): void; - - beginTransaction(options: QueryOptions, callback: QueryCallback): void; - beginTransaction(callback: QueryCallback): void; - commit(options: QueryOptions, callback: QueryCallback): void; - commit(callback: QueryCallback): void; - rollback(options: QueryOptions, callback: QueryCallback): void; - rollback(callback: QueryCallback): void; - - ping(options: QueryOptions, callback: QueryCallback): void; - ping(callback: QueryCallback): void; - - escapeId(val: mixed, forbidQualified?: boolean): string; - escape(val: mixed, stringifyObjects?: boolean, timeZone?: string): string; - format(sql: string, valus: Array<mixed>): string; - } - - declare class Pool extends events$EventEmitter { - getConnection( - callback: (error: ?Error, connection?: Connection) => * - ): void; - end(callback?: (error: ?Error) => *): void; - query( - sql: QueryOptions, - values?: Array<mixed>, - callback?: QueryCallback - ): Query; - query(sql: QueryOptions, callback?: QueryCallback): Query; - - escapeId(val: mixed, forbidQualified?: boolean): string; - escape(val: mixed, stringifyObjects?: boolean, timeZone?: string): string; - } - - declare type PoolOptions = ConnectionOptions & { - acquireTimeout?: number, - connectionLimit?: number, - waitForConnections?: boolean, - queueLimit?: number, - ... - }; - - declare type PoolClusterSelector = "RR" | "ORDER" | "RANDOM"; - - declare type PoolClusterOptions = { - defaultSelector?: PoolClusterSelector, - canRetry?: boolean, - removeNodeErrorCount?: number, - restoreNodeTimeout?: number, - ... - }; - - declare type QueryCallback = ( - error: ?Error, - results: QueryResults, - fields?: Array<QueryField> - ) => *; - - declare class PoolCluster extends events$EventEmitter { - add(config: PoolOptions | string): void; - add(name: string, config: PoolOptions | string): void; - remove(name: string): void; - - getConnection( - pattern: string | RegExp, - selector: PoolClusterSelector, - callback: (error: ?Error, connection?: Connection) => * - ): void; - getConnection( - pattern: string | RegExp, - callback: (error: ?Error, connection?: Connection) => * - ): void; - getConnection( - callback: (error: ?Error, connection?: Connection) => * - ): void; - - // Truth to be told, of returns not a Pool, but PoolNamespace instance but it is the same for the most part - of(pattern: string | RegExp, selector?: PoolClusterSelector): Pool; - - end(callback?: (error: ?Error) => *): void; - } - - declare function escapeId(val: mixed, forbidQualified?: boolean): string; - declare function escape( - val: mixed, - stringifyObjects?: boolean, - timeZone?: string - ): string; - declare function format(sql: string, valus: Array<mixed>): string; - declare function createConnection( - options: ConnectionOptions | string - ): Connection; - declare function createPool(options: PoolOptions | string): Pool; - declare function createPoolCluster(options?: PoolClusterOptions): PoolCluster; - declare function raw(sql: string): { toSqlString: () => string, ... }; -} +// flow-typed signature: c88436aba2c98d85d79c75fd283c917f +// flow-typed version: c3e3979308/mysql_v2.x.x/flow_>=v0.104.x + +// TODO: Events on event emitters +// TODO: Ssl structure type in ConnectionOptions +// TODO: PoolNamespace internal structure +// TODO: Packets internal structure + +declare module "mysql" { + declare type TypeCastField = { + db: string, + table: string, + name: string, + type: string, + length: number, + string: () => string, + buffer: () => Buffer + } + + declare type ConnectionOptions = { + host?: string, + port?: number, + localAddress?: string, + socketPath?: string, + user: string, + password: string, + database?: string, + charset?: string, + timezone?: string, + connectTimeout?: number, + stringifyObjects?: boolean, + insecureAuth?: boolean, + typeCast?: boolean | ((field: TypeCastField, next: () => mixed) => any), + queryFormat?: (query: string, values: ?mixed, timezone: string) => string, + supportBigNumbers?: boolean, + bigNumberStrings?: boolean, + dateStrings?: boolean | Array<string>, + // Array form contains ids of packets for logging + debug?: boolean | Array<string>, + trace?: boolean, + multipleStatements?: boolean, + flags?: string, + ssl?: string | {...}, + ... + }; + + declare type QueryOptions = { + sql: string, + typeCast?: boolean | ((field: TypeCastField, next: () => mixed) => any), + // string form is a separator used to produce column names + nestTables?: boolean | string, + values?: Array<mixed>, + timeout?: number, + ... + } | string; + + declare type QueryResults = Array<Object> & { + insertId?: string | number, + affectedRows?: number, + changedRows?: number, + ... + }; + + declare type QueryField = { + name: string, + type: string, + length: number, + table: string, + db: string, + ... + }; + + declare class Query extends events$EventEmitter { + // readableStreamOptions declared in Flow /lib/node.js + stream(options?: readableStreamOptions): stream$Readable; + } + + declare class Connection extends events$EventEmitter { + threadId: number; + connect(callback?: (error: ?Error) => *): void; + + release(): void; + destroy(): void; + + end(callback?: (error: ?Error) => *): void; + + query( + sql: QueryOptions, + values?: Array<mixed> | {...}, + callback?: QueryCallback + ): Query; + query(sql: QueryOptions, callback?: QueryCallback): Query; + + changeUser( + options: { + user?: string, + password?: string, + charset?: string, + database?: string, + ... + }, + callback: (error: ?Error) => * + ): void; + + beginTransaction(options: QueryOptions, callback: QueryCallback): void; + beginTransaction(callback: QueryCallback): void; + commit(options: QueryOptions, callback: QueryCallback): void; + commit(callback: QueryCallback): void; + rollback(options: QueryOptions, callback: QueryCallback): void; + rollback(callback: QueryCallback): void; + + ping(options: QueryOptions, callback: QueryCallback): void; + ping(callback: QueryCallback): void; + + escapeId(val: mixed, forbidQualified?: boolean): string; + escape(val: mixed, stringifyObjects?: boolean, timeZone?: string): string; + format(sql: string, valus: Array<mixed>): string; + } + + declare class Pool extends events$EventEmitter { + getConnection( + callback: (error: ?Error, connection?: Connection) => * + ): void; + end(callback?: (error: ?Error) => *): void; + query( + sql: QueryOptions, + values?: Array<mixed>, + callback?: QueryCallback + ): Query; + query(sql: QueryOptions, callback?: QueryCallback): Query; + + escapeId(val: mixed, forbidQualified?: boolean): string; + escape(val: mixed, stringifyObjects?: boolean, timeZone?: string): string; + } + + declare type PoolOptions = ConnectionOptions & { + acquireTimeout?: number, + connectionLimit?: number, + waitForConnections?: boolean, + queueLimit?: number, + ... + }; + + declare type PoolClusterSelector = "RR" | "ORDER" | "RANDOM"; + + declare type PoolClusterOptions = { + defaultSelector?: PoolClusterSelector, + canRetry?: boolean, + removeNodeErrorCount?: number, + restoreNodeTimeout?: number, + ... + }; + + declare type QueryCallback = ( + error: ?Error, + results: QueryResults, + fields?: Array<QueryField> + ) => *; + + declare class PoolCluster extends events$EventEmitter { + add(config: PoolOptions | string): void; + add(name: string, config: PoolOptions | string): void; + remove(name: string): void; + + getConnection( + pattern: string | RegExp, + selector: PoolClusterSelector, + callback: (error: ?Error, connection?: Connection) => * + ): void; + getConnection( + pattern: string | RegExp, + callback: (error: ?Error, connection?: Connection) => * + ): void; + getConnection( + callback: (error: ?Error, connection?: Connection) => * + ): void; + + // Truth to be told, of returns not a Pool, but PoolNamespace instance but it is the same for the most part + of(pattern: string | RegExp, selector?: PoolClusterSelector): Pool; + + end(callback?: (error: ?Error) => *): void; + } + + declare function escapeId(val: mixed, forbidQualified?: boolean): string; + declare function escape( + val: mixed, + stringifyObjects?: boolean, + timeZone?: string + ): string; + declare function format(sql: string, valus: Array<mixed>): string; + declare function createConnection( + options: ConnectionOptions | string + ): Connection; + declare function createPool(options: PoolOptions | string): Pool; + declare function createPoolCluster(options?: PoolClusterOptions): PoolCluster; + declare function raw(sql: string): { toSqlString: () => string, ... }; +} diff --git a/server/flow-typed/npm/reload_vx.x.x.js b/server/flow-typed/npm/reload_vx.x.x.js index e8faaede33472e11559cb78652f322bea25d47c3..44a6aab1abc1aa6a84fef206d74cbb70c9b8940b 100644 --- a/server/flow-typed/npm/reload_vx.x.x.js +++ b/server/flow-typed/npm/reload_vx.x.x.js @@ -1,5 +1,5 @@ -declare module 'reload' { - declare module.exports: { - (app: express$Application): Promise<{ reload(): void }>, - }; -} +declare module 'reload' { + declare module.exports: { + (app: express$Application): Promise<{ reload(): void }>, + }; +} diff --git a/server/flow-typed/npm/ws_v7.x.x.js b/server/flow-typed/npm/ws_v7.x.x.js index a5cafd7a2ee5d92ce0450e28dd4c85f9da2100e9..ee109bbc0dc182af9c37ee0bd98b67fa4ad1f4b3 100644 --- a/server/flow-typed/npm/ws_v7.x.x.js +++ b/server/flow-typed/npm/ws_v7.x.x.js @@ -1,363 +1,363 @@ -// flow-typed signature: cf710812f8fe053ca189786d3fa45067 -// flow-typed version: be32675b14/ws_v7.x.x/flow_>=v0.104.x - -declare type ws$PerMessageDeflateOptions = {| - serverNoContextTakeover?: boolean, - clientNoContextTakeover?: boolean, - serverMaxWindowBits?: boolean | number, - clientMaxWindowBits?: boolean | number, - zlibDeflateOptions?: zlib$options, - zlibInflateOptions?: zlib$options, - threshold?: number, - concurrencyLimit?: number, - isServer?: boolean, - maxPayload?: number, -|}; - -declare class ws$WebSocketServer extends events$EventEmitter { - /** - * Create a `WebSocketServer` instance. - */ - constructor( - options: {| - backlog?: number, - clientTracking?: boolean, - handleProtocols?: () => mixed, - host?: string, - maxPayload?: number, - noServer?: boolean, - path?: string, - perMessageDeflate?: boolean | ws$PerMessageDeflateOptions, - port: number, - server?: http$Server | https$Server, - verifyClient?: () => mixed, - |}, - callback?: () => mixed - ): this; - constructor( - options: {| - backlog?: number, - clientTracking?: boolean, - handleProtocols?: () => mixed, - host?: string, - maxPayload?: number, - noServer?: boolean, - path?: string, - perMessageDeflate?: boolean | ws$PerMessageDeflateOptions, - port?: number, - server: http$Server | https$Server, - verifyClient?: () => mixed, - |}, - callback?: () => mixed - ): this; - constructor( - options: {| - backlog?: number, - clientTracking?: boolean, - handleProtocols?: () => mixed, - host?: string, - maxPayload?: number, - noServer: boolean, - path?: string, - perMessageDeflate?: boolean | ws$PerMessageDeflateOptions, - port?: number, - server?: http$Server | https$Server, - verifyClient?: () => mixed, - |}, - callback?: () => mixed - ): this; - - /** - * Emitted when the server closes. - */ - on(event: 'close', () => mixed): this; - - /** - * Emitted when the handshake is complete. - */ - on( - event: 'connection', - (socket: ws$WebSocket, request: http$IncomingMessage<>) => mixed - ): this; - - /** - * Emitted when an error occurs on the underlying server. - */ - on(event: 'error', (error: Error) => mixed): this; - - /** - * Emitted before the response headers are written to the socket as part of - * the handshake. - */ - on( - event: 'headers', - (headers: Array<string>, request: http$IncomingMessage<>) => mixed - ): this; - - /** - * Emitted when the underlying server has been bound. - */ - on(event: 'listening', () => mixed): this; - - /** - * Returns the bound address, the address family name, and port of the server - * as reported by the operating system if listening on an IP socket. - * If the server is listening on a pipe or UNIX domain socket, the name is - * returned as a string. - */ - address(): - | null - | string - | {| port?: number, family?: string, address?: string |}; - - /** - * A set that stores all connected clients. Please note that this property is - * only added when the `clientTracking` is truthy. - */ - clients: Set<ws$WebSocket>; - - /** - * Close the server. - */ - close(callback?: () => mixed): void; - - /** - * Handle a HTTP Upgrade request. - */ - handleUpgrade( - request: http$IncomingMessage<>, - socket: net$Socket, - head: Buffer, - callback: (?ws$WebSocket) => mixed - ): void; - - /** - * See if a given request should be handled by this server instance. - */ - shouldHandle(request: http$IncomingMessage<>): boolean; -} - -declare type ws$WebSocketOptions = { - followRedirects?: boolean, - handshakeTimeout?: number, - maxRedirects?: number, - perMessageDeflate?: boolean | ws$PerMessageDeflateOptions, - protocolVersion?: number, - origin?: string, - maxPayload?: number, - ...requestOptions, - agent?: boolean | http$Agent<> | http$Agent<tls$TLSSocket>, - createConnection?: - | ((options: net$connectOptions, callback?: () => mixed) => net$Socket) - | ((options: tls$connectOptions, callback?: () => mixed) => tls$TLSSocket), - ... -}; - -declare type ws$CloseListener = (code: number, reason: string) => mixed; -declare type ws$ErrorListener = (error: Error) => mixed; -declare type ws$MessageListener = ( - data: string | Buffer | ArrayBuffer | Array<Buffer> -) => mixed; -declare type ws$OpenListener = () => mixed; -declare type ws$PingListener = (Buffer) => mixed; -declare type ws$PongListener = (Buffer) => mixed; -declare type ws$UnexpectedResponseListener = ( - request: http$ClientRequest<>, - response: http$IncomingMessage<> -) => mixed; -declare type ws$UpgradeListener = (response: http$IncomingMessage<>) => mixed; - -declare class ws$WebSocket extends events$EventEmitter { - static Server: typeof ws$WebSocketServer; - - static createWebSocketStream: ( - WebSocket: ws$WebSocket, - options?: duplexStreamOptions - ) => stream$Duplex; - - static CONNECTING: number; - static OPEN: number; - static CLOSING: number; - static CLOSED: number; - - /** - * Create a `WebSocket` instance. - */ - constructor( - address: string | URL, - protocols?: string | Array<string>, - options?: ws$WebSocketOptions - ): this; - constructor(address: string | URL, options: ws$WebSocketOptions): this; - - /* - * Emitted when the connection is closed. - */ - on('close', ws$CloseListener): this; - - /* - * Emitted when an error occurs. - */ - on('error', ws$ErrorListener): this; - - /* - * Emitted when a message is received from the server. - */ - on('message', ws$MessageListener): this; - - /* - * Emitted when the connection is established. - */ - on('open', ws$OpenListener): this; - - /* - * Emitted when a ping is received from the server. - */ - on('ping', ws$PingListener): this; - - /* - * Emitted when a pong is received from the server. - */ - on('pong', ws$PongListener): this; - - /* - * Emitted when the server response is not the expected one, - * for example a 401 response. - */ - on('unexpected-response', ws$UnexpectedResponseListener): this; - - /* - * Emitted when response headers are received from the server as part of the - * handshake. - */ - on('upgrade', ws$UpgradeListener): this; - - /** - * Register an event listener emulating the `EventTarget` interface. - */ - addEventListener( - type: 'close', - listener: ws$CloseListener, - options?: {| once?: boolean |} - ): this; - addEventListener( - type: 'error', - listener: ws$ErrorListener, - options?: {| once?: boolean |} - ): this; - addEventListener( - type: 'message', - listener: ws$MessageListener, - options?: {| once?: boolean |} - ): this; - addEventListener( - type: 'open', - listener: ws$OpenListener, - options?: {| once?: boolean |} - ): this; - addEventListener( - type: 'ping', - listener: ws$PingListener, - options?: {| once?: boolean |} - ): this; - addEventListener( - type: 'pong', - listener: ws$PongListener, - options?: {| once?: boolean |} - ): this; - addEventListener( - type: 'unexpected-response', - ws$UnexpectedResponseListener, - options?: {| once?: boolean |} - ): this; - addEventListener( - type: 'upgrade', - listener: ws$UpgradeListener, - options?: {| once?: boolean |} - ): this; - - /** - * A string indicating the type of binary data being transmitted by the - * connection. - */ - binaryType: string; - - /** - * The number of bytes of data that have been queued using calls to send() - * but not yet transmitted to the network. - */ - bufferedAmount: number; - - /** - * Initiate a closing handshake. - */ - close(code?: number, reason?: string): void; - - /** - * The negotiated extensions. - */ - extensions: string; - - /** - * Send a ping. - */ - ping(data?: any, mask?: boolean, callback?: () => mixed): void; - ping(data: any, callback: () => mixed): void; - ping(callback: () => mixed): void; - - /** - * Send a pong. - */ - pong(data?: any, mask?: boolean, callback?: () => mixed): void; - pong(data: any, callback: () => mixed): void; - pong(callback: () => mixed): void; - - /** - * The subprotocol selected by the server. - */ - protocol: string; - - /** - * The current state of the connection. - */ - readyState: number; - - /** - * Removes an event listener emulating the `EventTarget` interface. - */ - removeEventListener(type: 'close', listener: ws$CloseListener): this; - removeEventListener(type: 'error', listener: ws$ErrorListener): this; - removeEventListener(type: 'message', listener: ws$MessageListener): this; - removeEventListener(type: 'open', listener: ws$OpenListener): this; - removeEventListener(type: 'ping', listener: ws$PingListener): this; - removeEventListener(type: 'pong', listener: ws$PongListener): this; - removeEventListener( - type: 'unexpected-response', - ws$UnexpectedResponseListener - ): this; - removeEventListener(type: 'upgrade', listener: ws$UpgradeListener): this; - - /** - * Send a data message. - */ - send( - data?: any, - options?: {| - compress?: boolean, - binary?: boolean, - mask?: boolean, - fin?: boolean, - |}, - callback?: () => mixed - ): void; - send(data: any, callback: () => mixed): void; - - /** - * Forcibly close the connection. - */ - terminate(): void; -} - -declare module 'ws' { - declare module.exports: typeof ws$WebSocket; -} +// flow-typed signature: cf710812f8fe053ca189786d3fa45067 +// flow-typed version: be32675b14/ws_v7.x.x/flow_>=v0.104.x + +declare type ws$PerMessageDeflateOptions = {| + serverNoContextTakeover?: boolean, + clientNoContextTakeover?: boolean, + serverMaxWindowBits?: boolean | number, + clientMaxWindowBits?: boolean | number, + zlibDeflateOptions?: zlib$options, + zlibInflateOptions?: zlib$options, + threshold?: number, + concurrencyLimit?: number, + isServer?: boolean, + maxPayload?: number, +|}; + +declare class ws$WebSocketServer extends events$EventEmitter { + /** + * Create a `WebSocketServer` instance. + */ + constructor( + options: {| + backlog?: number, + clientTracking?: boolean, + handleProtocols?: () => mixed, + host?: string, + maxPayload?: number, + noServer?: boolean, + path?: string, + perMessageDeflate?: boolean | ws$PerMessageDeflateOptions, + port: number, + server?: http$Server | https$Server, + verifyClient?: () => mixed, + |}, + callback?: () => mixed + ): this; + constructor( + options: {| + backlog?: number, + clientTracking?: boolean, + handleProtocols?: () => mixed, + host?: string, + maxPayload?: number, + noServer?: boolean, + path?: string, + perMessageDeflate?: boolean | ws$PerMessageDeflateOptions, + port?: number, + server: http$Server | https$Server, + verifyClient?: () => mixed, + |}, + callback?: () => mixed + ): this; + constructor( + options: {| + backlog?: number, + clientTracking?: boolean, + handleProtocols?: () => mixed, + host?: string, + maxPayload?: number, + noServer: boolean, + path?: string, + perMessageDeflate?: boolean | ws$PerMessageDeflateOptions, + port?: number, + server?: http$Server | https$Server, + verifyClient?: () => mixed, + |}, + callback?: () => mixed + ): this; + + /** + * Emitted when the server closes. + */ + on(event: 'close', () => mixed): this; + + /** + * Emitted when the handshake is complete. + */ + on( + event: 'connection', + (socket: ws$WebSocket, request: http$IncomingMessage<>) => mixed + ): this; + + /** + * Emitted when an error occurs on the underlying server. + */ + on(event: 'error', (error: Error) => mixed): this; + + /** + * Emitted before the response headers are written to the socket as part of + * the handshake. + */ + on( + event: 'headers', + (headers: Array<string>, request: http$IncomingMessage<>) => mixed + ): this; + + /** + * Emitted when the underlying server has been bound. + */ + on(event: 'listening', () => mixed): this; + + /** + * Returns the bound address, the address family name, and port of the server + * as reported by the operating system if listening on an IP socket. + * If the server is listening on a pipe or UNIX domain socket, the name is + * returned as a string. + */ + address(): + | null + | string + | {| port?: number, family?: string, address?: string |}; + + /** + * A set that stores all connected clients. Please note that this property is + * only added when the `clientTracking` is truthy. + */ + clients: Set<ws$WebSocket>; + + /** + * Close the server. + */ + close(callback?: () => mixed): void; + + /** + * Handle a HTTP Upgrade request. + */ + handleUpgrade( + request: http$IncomingMessage<>, + socket: net$Socket, + head: Buffer, + callback: (?ws$WebSocket) => mixed + ): void; + + /** + * See if a given request should be handled by this server instance. + */ + shouldHandle(request: http$IncomingMessage<>): boolean; +} + +declare type ws$WebSocketOptions = { + followRedirects?: boolean, + handshakeTimeout?: number, + maxRedirects?: number, + perMessageDeflate?: boolean | ws$PerMessageDeflateOptions, + protocolVersion?: number, + origin?: string, + maxPayload?: number, + ...requestOptions, + agent?: boolean | http$Agent<> | http$Agent<tls$TLSSocket>, + createConnection?: + | ((options: net$connectOptions, callback?: () => mixed) => net$Socket) + | ((options: tls$connectOptions, callback?: () => mixed) => tls$TLSSocket), + ... +}; + +declare type ws$CloseListener = (code: number, reason: string) => mixed; +declare type ws$ErrorListener = (error: Error) => mixed; +declare type ws$MessageListener = ( + data: string | Buffer | ArrayBuffer | Array<Buffer> +) => mixed; +declare type ws$OpenListener = () => mixed; +declare type ws$PingListener = (Buffer) => mixed; +declare type ws$PongListener = (Buffer) => mixed; +declare type ws$UnexpectedResponseListener = ( + request: http$ClientRequest<>, + response: http$IncomingMessage<> +) => mixed; +declare type ws$UpgradeListener = (response: http$IncomingMessage<>) => mixed; + +declare class ws$WebSocket extends events$EventEmitter { + static Server: typeof ws$WebSocketServer; + + static createWebSocketStream: ( + WebSocket: ws$WebSocket, + options?: duplexStreamOptions + ) => stream$Duplex; + + static CONNECTING: number; + static OPEN: number; + static CLOSING: number; + static CLOSED: number; + + /** + * Create a `WebSocket` instance. + */ + constructor( + address: string | URL, + protocols?: string | Array<string>, + options?: ws$WebSocketOptions + ): this; + constructor(address: string | URL, options: ws$WebSocketOptions): this; + + /* + * Emitted when the connection is closed. + */ + on('close', ws$CloseListener): this; + + /* + * Emitted when an error occurs. + */ + on('error', ws$ErrorListener): this; + + /* + * Emitted when a message is received from the server. + */ + on('message', ws$MessageListener): this; + + /* + * Emitted when the connection is established. + */ + on('open', ws$OpenListener): this; + + /* + * Emitted when a ping is received from the server. + */ + on('ping', ws$PingListener): this; + + /* + * Emitted when a pong is received from the server. + */ + on('pong', ws$PongListener): this; + + /* + * Emitted when the server response is not the expected one, + * for example a 401 response. + */ + on('unexpected-response', ws$UnexpectedResponseListener): this; + + /* + * Emitted when response headers are received from the server as part of the + * handshake. + */ + on('upgrade', ws$UpgradeListener): this; + + /** + * Register an event listener emulating the `EventTarget` interface. + */ + addEventListener( + type: 'close', + listener: ws$CloseListener, + options?: {| once?: boolean |} + ): this; + addEventListener( + type: 'error', + listener: ws$ErrorListener, + options?: {| once?: boolean |} + ): this; + addEventListener( + type: 'message', + listener: ws$MessageListener, + options?: {| once?: boolean |} + ): this; + addEventListener( + type: 'open', + listener: ws$OpenListener, + options?: {| once?: boolean |} + ): this; + addEventListener( + type: 'ping', + listener: ws$PingListener, + options?: {| once?: boolean |} + ): this; + addEventListener( + type: 'pong', + listener: ws$PongListener, + options?: {| once?: boolean |} + ): this; + addEventListener( + type: 'unexpected-response', + ws$UnexpectedResponseListener, + options?: {| once?: boolean |} + ): this; + addEventListener( + type: 'upgrade', + listener: ws$UpgradeListener, + options?: {| once?: boolean |} + ): this; + + /** + * A string indicating the type of binary data being transmitted by the + * connection. + */ + binaryType: string; + + /** + * The number of bytes of data that have been queued using calls to send() + * but not yet transmitted to the network. + */ + bufferedAmount: number; + + /** + * Initiate a closing handshake. + */ + close(code?: number, reason?: string): void; + + /** + * The negotiated extensions. + */ + extensions: string; + + /** + * Send a ping. + */ + ping(data?: any, mask?: boolean, callback?: () => mixed): void; + ping(data: any, callback: () => mixed): void; + ping(callback: () => mixed): void; + + /** + * Send a pong. + */ + pong(data?: any, mask?: boolean, callback?: () => mixed): void; + pong(data: any, callback: () => mixed): void; + pong(callback: () => mixed): void; + + /** + * The subprotocol selected by the server. + */ + protocol: string; + + /** + * The current state of the connection. + */ + readyState: number; + + /** + * Removes an event listener emulating the `EventTarget` interface. + */ + removeEventListener(type: 'close', listener: ws$CloseListener): this; + removeEventListener(type: 'error', listener: ws$ErrorListener): this; + removeEventListener(type: 'message', listener: ws$MessageListener): this; + removeEventListener(type: 'open', listener: ws$OpenListener): this; + removeEventListener(type: 'ping', listener: ws$PingListener): this; + removeEventListener(type: 'pong', listener: ws$PongListener): this; + removeEventListener( + type: 'unexpected-response', + ws$UnexpectedResponseListener + ): this; + removeEventListener(type: 'upgrade', listener: ws$UpgradeListener): this; + + /** + * Send a data message. + */ + send( + data?: any, + options?: {| + compress?: boolean, + binary?: boolean, + mask?: boolean, + fin?: boolean, + |}, + callback?: () => mixed + ): void; + send(data: any, callback: () => mixed): void; + + /** + * Forcibly close the connection. + */ + terminate(): void; +} + +declare module 'ws' { + declare module.exports: typeof ws$WebSocket; +} diff --git a/server/package.json b/server/package.json index f0d570ba040c7bc0d9a5c3abdc799abf60f17a5c..ed5f413787a5bda82c43d3ff3f7e76ab296ca0e1 100644 --- a/server/package.json +++ b/server/package.json @@ -1,34 +1,34 @@ -{ - "name": "todo-server", - "version": "1.0.0", - "description": "A simple Todo REST server", - "license": "MIT", - "scripts": { - "start": "nodemon src/server.js --exec \"babel-node --require ./src/config\"", - "test": "jest --setupFiles ./test/config" - }, - "browserslist": [ - "maintained node versions" - ], - "jest": { - "testEnvironment": "node", - "collectCoverage": true - }, - "dependencies": { - "axios": "^0.20.0", - "express": "^4.17.1", - "mysql": "^2.18.1" - }, - "devDependencies": { - "@babel/core": "^7.11.6", - "@babel/node": "^7.10.5", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/preset-env": "^7.11.5", - "@babel/preset-flow": "^7.10.4", - "babel-jest": "^26.3.0", - "flow-bin": "^0.134.0", - "jest": "^26.4.2", - "nodemon": "^2.0.4", - "prettier": "^2.1.1" - } -} +{ + "name": "todo-server", + "version": "1.0.0", + "description": "A simple Todo REST server", + "license": "MIT", + "scripts": { + "start": "nodemon src/server.js --exec \"babel-node --require ./src/config\"", + "test": "jest --setupFiles ./test/config" + }, + "browserslist": [ + "maintained node versions" + ], + "jest": { + "testEnvironment": "node", + "collectCoverage": true + }, + "dependencies": { + "axios": "^0.20.0", + "express": "^4.17.1", + "mysql": "^2.18.1" + }, + "devDependencies": { + "@babel/core": "^7.11.6", + "@babel/node": "^7.10.5", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/preset-env": "^7.11.5", + "@babel/preset-flow": "^7.10.4", + "babel-jest": "^26.3.0", + "flow-bin": "^0.134.0", + "jest": "^26.4.2", + "nodemon": "^2.0.4", + "prettier": "^2.1.1" + } +} diff --git a/server/src/app.js b/server/src/app.js index 560fd7a927c769cac10bc381ab2e1b38d756dd6f..23527cb24a7f1c06c14e1c3e523fa3f28f49863d 100644 --- a/server/src/app.js +++ b/server/src/app.js @@ -1,16 +1,16 @@ -// @flow - -import express from 'express'; -import taskRouter from './task-router'; - -/** - * Express application. - */ -const app: express$Application<> = express(); - -app.use(express.json()); - -// Since API is not compatible with v1, API version is increased to v2 -app.use('/api/v2', taskRouter); - -export default app; +// @flow + +import express from 'express'; +import taskRouter from './task-router'; + +/** + * Express application. + */ +const app: express$Application<> = express(); + +app.use(express.json()); + +// Since API is not compatible with v1, API version is increased to v2 +app.use('/api/v2', taskRouter); + +export default app; diff --git a/server/src/mysql-pool.js b/server/src/mysql-pool.js index 0c51a948a059f8f2317862bde0333bcf191bd235..d99804dd245515abfc092a98572548c7b9442884 100644 --- a/server/src/mysql-pool.js +++ b/server/src/mysql-pool.js @@ -1,24 +1,24 @@ -// @flow - -import mysql from 'mysql'; - -/** - * MySQL connection pool with options specified in the following environment variables: - * - `MYSQL_HOST` - * - `MYSQL_USER` - * - `MYSQL_PASSWORD` - * - `MYSQL_DATABASE` - */ -const pool = mysql.createPool({ - host: process.env.MYSQL_HOST, - user: process.env.MYSQL_USER ?? '', // Use empty string if MYSQL_USER is not set - password: process.env.MYSQL_PASSWORD ?? '', // Use empty string if MYSQL_PASSWORD is not set - database: process.env.MYSQL_DATABASE, - // Reduce load on NTNU MySQL server - connectionLimit: 1, - // Convert MySQL boolean values to JavaScript boolean values - typeCast: (field, next) => - field.type == 'TINY' && field.length == 1 ? field.string() == '1' : next(), -}); - -export default pool; +// @flow + +import mysql from 'mysql'; + +/** + * MySQL connection pool with options specified in the following environment variables: + * - `MYSQL_HOST` + * - `MYSQL_USER` + * - `MYSQL_PASSWORD` + * - `MYSQL_DATABASE` + */ +const pool = mysql.createPool({ + host: process.env.MYSQL_HOST, + user: process.env.MYSQL_USER ?? '', // Use empty string if MYSQL_USER is not set + password: process.env.MYSQL_PASSWORD ?? '', // Use empty string if MYSQL_PASSWORD is not set + database: process.env.MYSQL_DATABASE, + // Reduce load on NTNU MySQL server + connectionLimit: 1, + // Convert MySQL boolean values to JavaScript boolean values + typeCast: (field, next) => + field.type == 'TINY' && field.length == 1 ? field.string() == '1' : next(), +}); + +export default pool; diff --git a/server/src/server.js b/server/src/server.js index 94593cfe49e0ff03d946662d5aebefdb163f324f..5cb0406d350fc7d60401a662f560285711805e04 100644 --- a/server/src/server.js +++ b/server/src/server.js @@ -1,17 +1,17 @@ -// @flow - -/** - * Web server entry point used in `npm start`. - */ - -import app from './app'; -import express from 'express'; -import path from 'path'; - -// Serve client files -app.use(express.static(path.join(__dirname, '/../../client/public'))); - -const port = 3000; -app.listen(port, () => { - console.info(`Server running on port ${port}`); -}); +// @flow + +/** + * Web server entry point used in `npm start`. + */ + +import app from './app'; +import express from 'express'; +import path from 'path'; + +// Serve client files +app.use(express.static(path.join(__dirname, '/../../client/public'))); + +const port = 3000; +app.listen(port, () => { + console.info(`Server running on port ${port}`); +}); diff --git a/server/src/task-router.js b/server/src/task-router.js index 09068ffeb16718c1bb63489e25dd8f113308ddf3..4cd8fa4e8bf357f3e221f8c08591847d6f96797c 100644 --- a/server/src/task-router.js +++ b/server/src/task-router.js @@ -1,44 +1,35 @@ -// @flow -import express from 'express'; -import taskService, { type Task } from './task-service'; - -/** - * Express router containing task methods. - */ -const router: express$Router<> = express.Router(); - -router.get('/tasks', (request, response) => { - taskService - .getAll() - .then((rows) => response.send(rows)) - .catch((error: Error) => response.status(500).send(error)); -}); - -router.get('/tasks/:id', (request, response) => { - const id = Number(request.params.id); - taskService - .get(id) - .then((task) => (task ? response.send(task) : response.status(404).send('Task not found'))) - .catch((error: Error) => response.status(500).send(error)); -}); - -// Example request body: { title: "Ny oppgave" } -// Example response body: { id: 4 } -router.post('/tasks', (request, response) => { - const data = request.body; - if (data && typeof data.title == 'string' && data.title.length != 0) - taskService - .create(data.title) - .then((id) => response.send({ id: id })) - .catch((error: Error) => response.status(500).send(error)); - else response.status(400).send('Missing task title'); -}); - -router.delete('/tasks/:id', (request, response) => { - taskService - .delete(Number(request.params.id)) - .then((result) => response.send()) - .catch((error: Error) => response.status(500).send(error)); -}); - -export default router; +// @flow +import express from 'express'; +import appService from './task-service'; +const { spawn } = require('child_process'); + +/** + * Express router containing task methods. + */ +const router: express$Router<> = express.Router(); + +router.post('/', (request, response) => { + //console.log('hei2'); + let stOut: string = ''; + let stErr: string = ''; + let stExit: number = 0; + let nice: string = request.body.code; + // console.log(nice); + const docker = spawn('docker', ['run', '--rm', 'node-image', 'node', '-e', nice]); + console.log(docker); + docker.stdout.on('data', (data) => { + stOut += data; + }); + + docker.stderr.on('data', (data) => { + stErr += data; + }); + + docker.on('close', (code) => { + stExit += code; + console.log([String(stOut), stErr, stExit]); + response.send([stOut, stErr, stExit]); + }); +}); + +export default router; diff --git a/server/src/task-service.js b/server/src/task-service.js index fed34944b7632c2f6a42f54dd7d4af681b58f9d4..127dfb297c389c753f5524f4499f1dc088a6c9ca 100644 --- a/server/src/task-service.js +++ b/server/src/task-service.js @@ -1,70 +1,70 @@ -// @flow - -import pool from './mysql-pool'; - -export type Task = { - id: number, - title: string, - done: boolean, -}; - -class TaskService { - /** - * Get task with given id. - */ - get(id: number) { - return new Promise<?Task>((resolve, reject) => { - pool.query('SELECT * FROM Tasks WHERE id = ?', [id], (error, results: Task[]) => { - if (error) return reject(error); - - resolve(results[0]); - }); - }); - } - - /** - * Get all tasks. - */ - getAll() { - return new Promise<Task[]>((resolve, reject) => { - pool.query('SELECT * FROM Tasks', (error, results) => { - if (error) return reject(error); - - resolve(results); - }); - }); - } - - /** - * Create new task having the given title. - * - * Resolves the newly created task id. - */ - create(title: string) { - return new Promise<number>((resolve, reject) => { - pool.query('INSERT INTO Tasks SET title=?', [title], (error, results) => { - if (error) return reject(error); - if (!results.insertId) return reject(new Error('No row inserted')); - - resolve(Number(results.insertId)); - }); - }); - } - - /** - * Delete task with given id. - */ - delete(id: number) { - return new Promise<void>((resolve, reject) => { - pool.query('DELETE FROM Tasks WHERE id = ?', [id], (error, results) => { - if (error) return reject(error); - if (!results.affectedRows) reject(new Error('No row deleted')); - - resolve(); - }); - }); - } -} - -const taskService = new TaskService(); -export default taskService; +// @flow + +import pool from './mysql-pool'; + +export type Task = { + id: number, + title: string, + done: boolean, +}; + +class TaskService { + /** + * Get task with given id. + */ + get(id: number) { + return new Promise<?Task>((resolve, reject) => { + pool.query('SELECT * FROM Tasks WHERE id = ?', [id], (error, results: Task[]) => { + if (error) return reject(error); + + resolve(results[0]); + }); + }); + } + + /** + * Get all tasks. + */ + getAll() { + return new Promise<Task[]>((resolve, reject) => { + pool.query('SELECT * FROM Tasks', (error, results) => { + if (error) return reject(error); + + resolve(results); + }); + }); + } + + /** + * Create new task having the given title. + * + * Resolves the newly created task id. + */ + create(title: string) { + return new Promise<number>((resolve, reject) => { + pool.query('INSERT INTO Tasks SET title=?', [title], (error, results) => { + if (error) return reject(error); + if (!results.insertId) return reject(new Error('No row inserted')); + + resolve(Number(results.insertId)); + }); + }); + } + + /** + * Delete task with given id. + */ + delete(id: number) { + return new Promise<void>((resolve, reject) => { + pool.query('DELETE FROM Tasks WHERE id = ?', [id], (error, results) => { + if (error) return reject(error); + if (!results.affectedRows) reject(new Error('No row deleted')); + + resolve(); + }); + }); + } +} + +const taskService = new TaskService(); +export default taskService; diff --git a/server/test/task-router.test.js b/server/test/task-router.test.js index 06cd95f92be481fc1154675dc161e0c17f684c6a..c74177393d62fe1372f0c935f43e3f4cbae12641 100644 --- a/server/test/task-router.test.js +++ b/server/test/task-router.test.js @@ -1,112 +1,112 @@ -// @flow - -import axios from 'axios'; -import pool from '../src/mysql-pool'; -import app from '../src/app'; -import taskService, { type Task } from '../src/task-service'; - -const testTasks: Task[] = [ - { id: 1, title: 'Les leksjon', done: false }, - { id: 2, title: 'Møt opp på forelesning', done: false }, - { id: 3, title: 'Gjør øving', done: false }, -]; - -// Since API is not compatible with v1, API version is increased to v2 -axios.defaults.baseURL = 'http://localhost:3001/api/v2'; - -let webServer; -beforeAll((done) => { - // Use separate port for testing - webServer = app.listen(3001, () => done()); -}); - -beforeEach((done) => { - // Delete all tasks, and reset id auto-increment start value - pool.query('TRUNCATE TABLE Tasks', (error) => { - if (error) return done.fail(error); - - // Create testTasks sequentially in order to set correct id, and call done() when finished - taskService - .create(testTasks[0].title) - .then(() => taskService.create(testTasks[1].title)) // Create testTask[1] after testTask[0] has been created - .then(() => taskService.create(testTasks[2].title)) // Create testTask[2] after testTask[1] has been created - .then(() => done()); // Call done() after testTask[2] has been created - - // Note that the above expression can be written as: - // const promise1 = taskService.create(testTasks[0].title); - // const promise2 = promise1.then(() => taskService.create(testTasks[1].title)); - // const promise3 = promise2.then(() => taskService.create(testTasks[2].title)); - // promise3.then(() => done()); - - // Can also be written as: - // let lastPromise = taskService.create(testTasks[0].title); - // lastPromise = lastPromise.then(() => taskService.create(testTasks[1].title)); - // lastPromise = lastPromise.then(() => taskService.create(testTasks[2].title)); - // lastPromise.then(() => done()); - - // Or without specifying each test task: - // let lastPromise = new Promise((resolve) => resolve()); - // for (const task of testTasks) lastPromise = lastPromise.then(() => taskService.create(task.title)); - // lastPromise.then(() => done()); - - // Or more compactly: - // testTasks - // .reduce((prev, cur) => prev.then(() => taskService.create(cur.title)), Promise.resolve()) - // .then(() => done()); - }); -}); - -// Stop web server and close connection to MySQL server -afterAll((done) => { - if (!webServer) return done.fail(new Error()); - webServer.close(() => pool.end(() => done())); -}); - -describe('Fetch tasks (GET)', () => { - test('Fetch all tasks (200 OK)', (done) => { - axios.get<Task[]>('/tasks').then((response) => { - expect(response.status).toEqual(200); - expect(response.data).toEqual(testTasks); - done(); - }); - }); - - test('Fetch task (200 OK)', (done) => { - axios.get<Task>('/tasks/1').then((response) => { - expect(response.status).toEqual(200); - expect(response.data).toEqual(testTasks[0]); - done(); - }); - }); - - test('Fetch task (404 Not Found)', (done) => { - axios - .get<Task>('/tasks/4') - .then((response) => done.fail(new Error())) - .catch((error: Error) => { - expect(error.message).toEqual('Request failed with status code 404'); - done(); - }); - }); -}); - -describe('Create new task (POST)', () => { - test('Create new task (200 OK)', (done) => { - axios - .post<{}, number>('/tasks', { title: 'Ny oppgave' }) - .then((response) => { - expect(response.status).toEqual(200); - expect(response.data).toEqual({ id: 4 }); - done(); - }); - }); -}); - -describe('Delete task (DELETE)', () => { - test('Delete task (200 OK)', (done) => { - axios.delete('/tasks/2').then((response) => { - expect(response.status).toEqual(200); - done(); - }); - }); -}); +// @flow + +import axios from 'axios'; +import pool from '../src/mysql-pool'; +import app from '../src/app'; +import taskService, { type Task } from '../src/task-service'; + +const testTasks: Task[] = [ + { id: 1, title: 'Les leksjon', done: false }, + { id: 2, title: 'Møt opp på forelesning', done: false }, + { id: 3, title: 'Gjør øving', done: false }, +]; + +// Since API is not compatible with v1, API version is increased to v2 +axios.defaults.baseURL = 'http://localhost:3001/api/v2'; + +let webServer; +beforeAll((done) => { + // Use separate port for testing + webServer = app.listen(3001, () => done()); +}); + +beforeEach((done) => { + // Delete all tasks, and reset id auto-increment start value + pool.query('TRUNCATE TABLE Tasks', (error) => { + if (error) return done.fail(error); + + // Create testTasks sequentially in order to set correct id, and call done() when finished + taskService + .create(testTasks[0].title) + .then(() => taskService.create(testTasks[1].title)) // Create testTask[1] after testTask[0] has been created + .then(() => taskService.create(testTasks[2].title)) // Create testTask[2] after testTask[1] has been created + .then(() => done()); // Call done() after testTask[2] has been created + + // Note that the above expression can be written as: + // const promise1 = taskService.create(testTasks[0].title); + // const promise2 = promise1.then(() => taskService.create(testTasks[1].title)); + // const promise3 = promise2.then(() => taskService.create(testTasks[2].title)); + // promise3.then(() => done()); + + // Can also be written as: + // let lastPromise = taskService.create(testTasks[0].title); + // lastPromise = lastPromise.then(() => taskService.create(testTasks[1].title)); + // lastPromise = lastPromise.then(() => taskService.create(testTasks[2].title)); + // lastPromise.then(() => done()); + + // Or without specifying each test task: + // let lastPromise = new Promise((resolve) => resolve()); + // for (const task of testTasks) lastPromise = lastPromise.then(() => taskService.create(task.title)); + // lastPromise.then(() => done()); + + // Or more compactly: + // testTasks + // .reduce((prev, cur) => prev.then(() => taskService.create(cur.title)), Promise.resolve()) + // .then(() => done()); + }); +}); + +// Stop web server and close connection to MySQL server +afterAll((done) => { + if (!webServer) return done.fail(new Error()); + webServer.close(() => pool.end(() => done())); +}); + +describe('Fetch tasks (GET)', () => { + test('Fetch all tasks (200 OK)', (done) => { + axios.get<Task[]>('/tasks').then((response) => { + expect(response.status).toEqual(200); + expect(response.data).toEqual(testTasks); + done(); + }); + }); + + test('Fetch task (200 OK)', (done) => { + axios.get<Task>('/tasks/1').then((response) => { + expect(response.status).toEqual(200); + expect(response.data).toEqual(testTasks[0]); + done(); + }); + }); + + test('Fetch task (404 Not Found)', (done) => { + axios + .get<Task>('/tasks/4') + .then((response) => done.fail(new Error())) + .catch((error: Error) => { + expect(error.message).toEqual('Request failed with status code 404'); + done(); + }); + }); +}); + +describe('Create new task (POST)', () => { + test('Create new task (200 OK)', (done) => { + axios + .post<{}, number>('/tasks', { title: 'Ny oppgave' }) + .then((response) => { + expect(response.status).toEqual(200); + expect(response.data).toEqual({ id: 4 }); + done(); + }); + }); +}); + +describe('Delete task (DELETE)', () => { + test('Delete task (200 OK)', (done) => { + axios.delete('/tasks/2').then((response) => { + expect(response.status).toEqual(200); + done(); + }); + }); +});