From 120c71962308862bcf563c2e67a3d934e11f3d23 Mon Sep 17 00:00:00 2001 From: Alex Mikhalev Date: Mon, 23 Jul 2018 19:20:41 -0600 Subject: [PATCH] Many ui improvements; saving program updates works --- app/components/App.tsx | 11 +- app/components/DeviceView.scss | 35 +- app/components/DeviceView.tsx | 8 +- app/components/DevicesView.tsx | 5 +- app/components/DurationInput.tsx | 57 --- app/components/DurationView.tsx | 74 +++ app/components/ProgramSequenceView.tsx | 101 +++- app/components/ProgramTable.tsx | 8 +- app/components/RunSectionForm.tsx | 38 +- app/components/SectionChooser.tsx | 47 ++ app/components/SectionTable.tsx | 5 +- app/components/index.ts | 3 +- app/images/favicon-16x16.png | Bin 0 -> 955 bytes app/images/favicon-32x32.png | Bin 0 -> 1349 bytes app/images/favicon-96x96.png | Bin 0 -> 3121 bytes app/images/favicon.ico | Bin 0 -> 1150 bytes app/index.html | 2 +- app/pages/ProgramPage.tsx | 214 +++++++-- app/styles/app.scss | 18 +- app/webpack.config.js | 2 + common/sprinklersRpc/Program.ts | 17 +- common/sprinklersRpc/Section.ts | 2 +- package.json | 1 + server/entities/SprinklersDevice.ts | 3 + yarn.lock | 612 ++++++++++++++++++++++++- 25 files changed, 1063 insertions(+), 200 deletions(-) delete mode 100644 app/components/DurationInput.tsx create mode 100644 app/components/DurationView.tsx create mode 100644 app/components/SectionChooser.tsx create mode 100644 app/images/favicon-16x16.png create mode 100644 app/images/favicon-32x32.png create mode 100644 app/images/favicon-96x96.png create mode 100644 app/images/favicon.ico diff --git a/app/components/App.tsx b/app/components/App.tsx index 400256b..d146d23 100644 --- a/app/components/App.tsx +++ b/app/components/App.tsx @@ -17,12 +17,11 @@ function NavContainer() { - - - - - - + + + {/**/} + {/**/} + {/**/} diff --git a/app/components/DeviceView.scss b/app/components/DeviceView.scss index 72cd540..bca82da 100644 --- a/app/components/DeviceView.scss +++ b/app/components/DeviceView.scss @@ -36,4 +36,37 @@ max-height: 14em; height: 14em; overflow-y: scroll; -} \ No newline at end of file +} + +.ui.modal.programEditor > .header > .header.item .inline.fields { + margin-bottom: 0; +} + +.programSequence.editing .item .content { + width: 20em; +} + +.durationInputs { + display: flex; +} + +$durationInput-labelWidth: 2.5em; + +.ui.form .field .ui.input.durationInput { + &.minutes { + margin-right: 1em; + } + &.seconds { + + } + + > input { + flex: 1 1 6em; + width: 100%; + } + + > .label { + flex: 0 0 $durationInput-labelWidth; + text-align: center; + } +} diff --git a/app/components/DeviceView.tsx b/app/components/DeviceView.tsx index 839faf5..633a334 100644 --- a/app/components/DeviceView.tsx +++ b/app/components/DeviceView.tsx @@ -3,8 +3,11 @@ import { observer } from "mobx-react"; import * as React from "react"; import { Grid, Header, Icon, Item, SemanticICONS } from "semantic-ui-react"; +import * as p from "@app/pages"; +import * as rp from "@app/routePaths"; import { AppState, injectState } from "@app/state"; import { ConnectionState as ConState } from "@common/sprinklersRpc"; +import { Route, RouteComponentProps, withRouter } from "react-router"; import { ProgramTable, RunSectionForm, SectionRunnerView, SectionTable } from "."; import "./DeviceView.scss"; @@ -44,7 +47,7 @@ interface DeviceViewProps { appState: AppState; } -class DeviceView extends React.Component { +class DeviceView extends React.Component> { render() { const { uiStore, sprinklersRpc, routerStore } = this.props.appState; const device = sprinklersRpc.getDevice(this.props.deviceId); @@ -61,6 +64,7 @@ class DeviceView extends React.Component { + ); return ( @@ -81,4 +85,4 @@ class DeviceView extends React.Component { } } -export default injectState(observer(DeviceView)); +export default injectState(withRouter(observer(DeviceView))); diff --git a/app/components/DevicesView.tsx b/app/components/DevicesView.tsx index f718103..59baf51 100644 --- a/app/components/DevicesView.tsx +++ b/app/components/DevicesView.tsx @@ -3,8 +3,9 @@ import * as React from "react"; import { Item } from "semantic-ui-react"; import DeviceView from "@app/components/DeviceView"; +import { RouteComponentProps, withRouter } from "react-router"; -class DevicesView extends React.Component<{deviceId: string}> { +class DevicesView extends React.Component<{deviceId: string} & RouteComponentProps> { render() { return ( @@ -14,4 +15,4 @@ class DevicesView extends React.Component<{deviceId: string}> { } } -export default observer(DevicesView); +export default withRouter(observer(DevicesView)); diff --git a/app/components/DurationInput.tsx b/app/components/DurationInput.tsx deleted file mode 100644 index f028144..0000000 --- a/app/components/DurationInput.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import * as classNames from "classnames"; -import * as React from "react"; -import { Input, InputProps } from "semantic-ui-react"; - -import { Duration } from "@common/Duration"; - -export default class DurationInput extends React.Component<{ - duration: Duration, - onDurationChange: (newDuration: Duration) => void, - className?: string, -}> { - render() { - const duration = this.props.duration; - const className = classNames("field", "durationInput", this.props.className); - // const editing = this.props.onDurationChange != null; - return ( -
- -
- - -
-
- ); - } - - private onMinutesChange: InputProps["onChange"] = (e, { value }) => { - if (isNaN(Number(value))) { - return; - } - const newMinutes = parseInt(value, 10); - this.props.onDurationChange(this.props.duration.withMinutes(newMinutes)); - } - - private onSecondsChange: InputProps["onChange"] = (e, { value }) => { - if (isNaN(Number(value))) { - return; - } - const newSeconds = parseInt(value, 10); - this.props.onDurationChange(this.props.duration.withSeconds(newSeconds)); - } -} diff --git a/app/components/DurationView.tsx b/app/components/DurationView.tsx new file mode 100644 index 0000000..6da305d --- /dev/null +++ b/app/components/DurationView.tsx @@ -0,0 +1,74 @@ +import * as classNames from "classnames"; +import * as React from "react"; +import { Form, Input, InputProps } from "semantic-ui-react"; + +import { Duration } from "@common/Duration"; + +export default class DurationView extends React.Component<{ + label?: string, + inline?: boolean, + duration: Duration, + onDurationChange?: (newDuration: Duration) => void, + className?: string, +}> { + render() { + const { duration, label, inline, onDurationChange } = this.props; + const className = classNames("durationInput", this.props.className); + if (onDurationChange) { + return ( + + + {label && } +
+ + +
+
+
+ ); + } else { + return ( + + {label && } {duration.minutes}M {duration.seconds}S + + ); + } + } + + private onMinutesChange: InputProps["onChange"] = (e, { value }) => { + if (!this.props.onDurationChange || isNaN(Number(value))) { + return; + } + const newMinutes = Number(value); + this.props.onDurationChange(this.props.duration.withMinutes(newMinutes)); + } + + private onSecondsChange: InputProps["onChange"] = (e, { value }) => { + if (!this.props.onDurationChange || isNaN(Number(value))) { + return; + } + const newSeconds = Number(value); + this.props.onDurationChange(this.props.duration.withSeconds(newSeconds)); + } + + private onWheel = () => { + // do nothing + } +} diff --git a/app/components/ProgramSequenceView.tsx b/app/components/ProgramSequenceView.tsx index 39ea92d..0f0999c 100644 --- a/app/components/ProgramSequenceView.tsx +++ b/app/components/ProgramSequenceView.tsx @@ -1,19 +1,94 @@ +import classNames = require("classnames"); +import { observer } from "mobx-react"; import * as React from "react"; +import { Form, List } from "semantic-ui-react"; +import { DurationView, SectionChooser } from "@app/components/index"; import { Duration } from "@common/Duration"; -import { ProgramItem, Section} from "@common/sprinklersRpc"; - -export default function ProgramSequenceView({ sequence, sections }: { - sequence: ProgramItem[], sections: Section[], -}) { - const sequenceItems = sequence.map((item, index) => { - const section = sections[item.section]; - const duration = Duration.fromSeconds(item.duration); +import { ProgramItem, Section } from "@common/sprinklersRpc"; + +@observer +class ProgramSequenceItem extends React.Component<{ + sequenceItem: ProgramItem, sections: Section[], onChange?: (newItem: ProgramItem) => void, +}> { + renderContent() { + const { sequenceItem, sections } = this.props; + const editing = this.props.onChange != null; + const section = sections[sequenceItem.section]; + const duration = Duration.fromSeconds(sequenceItem.duration); + + if (editing) { + return ( + + + + + ); + } else { + return ( + + {section.toString()} + for {duration.toString()} + + ); + } + } + + render() { return ( -
  • - "{section.name}" for {duration.toString()} -
  • + + + {this.renderContent()} + ); - }); - return
      {sequenceItems}
    ; + } + + private onSectionChange = (newSection: Section) => { + if (!this.props.onChange) { + return; + } + this.props.onChange(new ProgramItem({ + ...this.props.sequenceItem, section: newSection.id, + })); + } + + private onDurationChange = (newDuration: Duration) => { + if (!this.props.onChange) { + return; + } + this.props.onChange(new ProgramItem({ + ...this.props.sequenceItem, duration: newDuration.toSeconds(), + })); + } +} + +@observer +export default class ProgramSequenceView extends React.Component<{ + sequence: ProgramItem[], sections: Section[], editing?: boolean, +}> { + render() { + const { sequence, sections } = this.props; + const editing = this.props.editing || false; + const className = classNames("programSequence", { editing }); + const sequenceItems = sequence.map((item, index) => { + const onChange = editing ? (newItem: ProgramItem) => this.changeItem(newItem, index) : undefined; + return ; + }); + return {sequenceItems}; + } + + private changeItem = (newItem: ProgramItem, index: number) => { + this.props.sequence[index] = newItem; + } } diff --git a/app/components/ProgramTable.tsx b/app/components/ProgramTable.tsx index 64f9508..79d30eb 100644 --- a/app/components/ProgramTable.tsx +++ b/app/components/ProgramTable.tsx @@ -6,7 +6,7 @@ import { Button, ButtonProps, Table } from "semantic-ui-react"; import { ProgramSequenceView, ScheduleView } from "@app/components"; import * as rp from "@app/routePaths"; -import { Program, Section, SprinklersDevice } from "@common/sprinklersRpc"; +import { Program, SprinklersDevice } from "@common/sprinklersRpc"; @observer class ProgramRows extends React.Component<{ @@ -15,7 +15,7 @@ class ProgramRows extends React.Component<{ expanded: boolean, toggleExpanded: (program: Program) => void, }> { render() { - const { program, device, expanded, routerStore } = this.props; + const { program, device, expanded } = this.props; const { sections } = device; const { name, running, enabled, schedule, sequence } = program; @@ -46,7 +46,7 @@ class ProgramRows extends React.Component<{ ); const detailRow = expanded && ( - +

    Sequence:

    Schedule:

    @@ -82,7 +82,7 @@ export default class ProgramTable extends React.Component<{ } render() { - const { programs, sections } = this.props.device; + const { programs } = this.props.device; const programRows = programs.map(this.renderRows); return ( diff --git a/app/components/RunSectionForm.tsx b/app/components/RunSectionForm.tsx index 380553f..2cefeff 100644 --- a/app/components/RunSectionForm.tsx +++ b/app/components/RunSectionForm.tsx @@ -1,14 +1,13 @@ -import { computed } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; -import { DropdownItemProps, DropdownProps, Form, Header, Segment } from "semantic-ui-react"; +import { Form, Header, Segment } from "semantic-ui-react"; +import { DurationView, SectionChooser } from "@app/components"; import { UiStore } from "@app/state"; import { Duration } from "@common/Duration"; import log from "@common/logger"; import { Section, SprinklersDevice } from "@common/sprinklersRpc"; import { RunSectionResponse } from "@common/sprinklersRpc/deviceRequests"; -import DurationInput from "./DurationInput"; @observer export default class RunSectionForm extends React.Component<{ @@ -16,13 +15,13 @@ export default class RunSectionForm extends React.Component<{ uiStore: UiStore, }, { duration: Duration, - section: number | "", + section: Section | undefined, }> { constructor(props: any, context?: any) { super(props, context); this.state = { duration: new Duration(0, 0), - section: "", + section: undefined, }; } @@ -32,20 +31,18 @@ export default class RunSectionForm extends React.Component<{
    Run Section
    - - - {/*Label must be   to align it properly*/} , v: DropdownProps) => { - this.setState({ section: v.value as number }); + private onSectionChange = (newSection: Section) => { + this.setState({ section: newSection }); } private onDurationChange = (newDuration: Duration) => { @@ -67,11 +64,10 @@ export default class RunSectionForm extends React.Component<{ private run = (e: React.SyntheticEvent) => { e.preventDefault(); - if (typeof this.state.section !== "number") { + const { section, duration } = this.state; + if (!section) { return; } - const section: Section = this.props.device.sections[this.state.section]; - const { duration } = this.state; section.run(duration.toSeconds()) .then(this.onRunSuccess) .catch(this.onRunError); @@ -94,14 +90,6 @@ export default class RunSectionForm extends React.Component<{ } private get isValid(): boolean { - return typeof this.state.section === "number"; - } - - @computed - private get sectionOptions(): DropdownItemProps[] { - return this.props.device.sections.map((s, i) => ({ - text: s ? s.name : null, - value: i, - })); + return this.state.section != null && this.state.duration.toSeconds() > 0; } } diff --git a/app/components/SectionChooser.tsx b/app/components/SectionChooser.tsx new file mode 100644 index 0000000..85fe67d --- /dev/null +++ b/app/components/SectionChooser.tsx @@ -0,0 +1,47 @@ +import { computed } from "mobx"; +import { observer } from "mobx-react"; +import * as React from "react"; +import { DropdownItemProps, DropdownProps, Form } from "semantic-ui-react"; + +import { Section } from "@common/sprinklersRpc"; + +@observer +export default class SectionChooser extends React.Component<{ + label?: string, + inline?: boolean, + sections: Section[], + value?: Section, + onChange?: (section: Section) => void, +}> { + render() { + const { label, inline, sections, value, onChange } = this.props; + let section = (value == null) ? "" : sections.indexOf(value); + section = (section === -1) ? "" : section; + const onSectionChange = (onChange == null) ? undefined : this.onSectionChange; + if (onChange == null) { + return {label || ""} '{value ? value.toString() : ""}'; + } + return ( + + ); + } + + private onSectionChange = (e: React.SyntheticEvent, v: DropdownProps) => { + this.props.onChange!(this.props.sections[v.value as number]); + } + + @computed + private get sectionOptions(): DropdownItemProps[] { + return this.props.sections.map((s, i) => ({ + text: s ? `${s.id}: ${s.name}` : null, + value: i, + })); + } +} diff --git a/app/components/SectionTable.tsx b/app/components/SectionTable.tsx index bc16ee7..9618c8b 100644 --- a/app/components/SectionTable.tsx +++ b/app/components/SectionTable.tsx @@ -15,9 +15,8 @@ export default class SectionTable extends React.Component<{ sections: Section[] } const { name, state } = section; const sectionStateClass = classNames({ - "section--state": true, - "section--state-true": state, - "section--state-false": !state, + "section-state": true, + "running": state, }); const sectionState = state ? ( Irrigating) diff --git a/app/components/index.ts b/app/components/index.ts index fe3f345..151c136 100644 --- a/app/components/index.ts +++ b/app/components/index.ts @@ -1,7 +1,7 @@ export { default as App } from "./App"; export { default as DevicesView } from "./DevicesView"; export { default as DeviceView } from "./DeviceView"; -export { default as DurationInput } from "./DurationInput"; +export { default as DurationView } from "./DurationView"; export { default as MessagesView } from "./MessagesView"; export { default as ProgramTable } from "./ProgramTable"; export { default as RunSectionForm } from "./RunSectionForm"; @@ -11,3 +11,4 @@ export { default as SectionTable } from "./SectionTable"; export { default as NavBar } from "./NavBar"; export { default as MessageTest } from "./MessageTest"; export { default as ProgramSequenceView } from "./ProgramSequenceView"; +export { default as SectionChooser } from "./SectionChooser"; diff --git a/app/images/favicon-16x16.png b/app/images/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..53f317dc251692084ef09bf3f46effb6698c6618 GIT binary patch literal 955 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 X#@=t?JjZYB34p~J8`FwYo>Bh - + Sprinklers3 diff --git a/app/pages/ProgramPage.tsx b/app/pages/ProgramPage.tsx index 4dbfe30..7040ccd 100644 --- a/app/pages/ProgramPage.tsx +++ b/app/pages/ProgramPage.tsx @@ -1,23 +1,95 @@ import { observer } from "mobx-react"; +import { createViewModel, IViewModel } from "mobx-utils"; import * as React from "react"; -import { Button, Menu, Segment} from "semantic-ui-react"; +import { RouteComponentProps } from "react-router"; +import { Button, CheckboxProps, Form, Input, InputOnChangeData, Menu, Modal, Segment } from "semantic-ui-react"; import { ProgramSequenceView, ScheduleView } from "@app/components"; +import * as rp from "@app/routePaths"; import { AppState, injectState } from "@app/state"; +import log from "@common/logger"; import { Program, SprinklersDevice } from "@common/sprinklersRpc"; -import { RouteComponentProps } from "react-router"; -import { Link } from "react-router-dom"; - -@observer -class ProgramDetailView extends React.Component { - -} @observer class ProgramPage extends React.Component<{ appState: AppState, -} & RouteComponentProps<{ deviceId: string, programId: number }>> { - device!: SprinklersDevice; +} & RouteComponentProps<{ deviceId: string, programId: number }>, { + programView: Program & IViewModel | undefined, +}> { + private device!: SprinklersDevice; + private program!: Program; + + constructor(p: any) { + super(p); + this.state = { + programView: undefined, + }; + } + + get isEditing(): boolean { + return this.state.programView != null; + } + + renderName(program: Program) { + const { name } = program; + if (this.isEditing) { + return ( + + + + + + + + ({program.id}) + + + + ); + } else { + return Program {name} ({program.id}); + } + } + + renderActions(program: Program) { + const { running } = program; + const editing = this.isEditing; + let editButtons; + if (editing) { + editButtons = ( + + + + + ); + } else { + editButtons = ( + + ); + } + return ( + + + {editButtons} + + + ); + } render() { const { deviceId, programId } = this.props.match.params; @@ -26,42 +98,102 @@ class ProgramPage extends React.Component<{ if (device.programs.length <= programId || !device.programs[programId]) { return null; } - const program = device.programs[programId]; + this.program = device.programs[programId]; + + const { programView } = this.state; + const program = programView || this.program; + const editing = programView != null; + + const { running, enabled, schedule, sequence } = program; - const programRows = this.renderRows(program, programId); return ( -
    - - Program {program.name} ({program.id}) - - - - - - - - {programRows} - -
    + + {this.renderName(program)} + +
    + + + + + + + + + + + + +
    +
    + {this.renderActions(program)} +
    ); } - private renderRows = (program: Program, i: number): JSX.Element | null => { - const { name, running, enabled, schedule, sequence } = program; - const cancelOrRun = () => running ? program.cancel() : program.run(); - return ( - - Enabled: {enabled ? "Enabled" : "Not enabled"}
    - Running: {running ? "Running" : "Not running"}
    - -

    Sequence:

    -

    Schedule:

    -
    - ); + private cancelOrRun = () => { + if (!this.program) { + return; + } + this.program.running ? this.program.cancel() : this.program.run(); + } + + private startEditing = () => { + let { programView } = this.state; + if (programView) { // stop editing, so save + programView.submit(); + programView = undefined; + } else { // start editing + programView = createViewModel(this.program); + } + this.setState({ programView }); + } + + private save = () => { + let { programView } = this.state; + if (programView) { // stop editing, so save + programView.submit(); + programView = undefined; + } + this.setState({ programView }); + this.program.update() + .then((data) => { + log.info({ data }, "Program updated"); + }, (err) => { + log.error({ err }, "error updating Program"); + }); + } + + private cancelEditing = () => { + let { programView } = this.state; + if (programView) { + programView = undefined; // stop editing + } + this.setState({ programView }); + } + + private close = () => { + const { deviceId } = this.props.match.params; + this.props.history.push({ pathname: rp.device(deviceId) }); + } + + private onNameChange = (e: any, p: InputOnChangeData) => { + const { programView } = this.state; + if (programView) { + programView.name = p.value; + } + } + + private onEnabledChange = (e: any, p: CheckboxProps) => { + const { programView } = this.state; + if (programView) { + programView.enabled = p.checked!; + } } } diff --git a/app/styles/app.scss b/app/styles/app.scss index b6b461a..f5678d5 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -1,5 +1,5 @@ .app { - margin-top: 1em; + padding-top: 1em; } .sectionRunner--pausedState { @@ -51,26 +51,12 @@ display: flex !important; } -.section--state-true { +.section-state.running { color: green; } -.section--state-false { - -} - -.durationInput--minutes, -.durationInput--seconds { - min-width: 6em !important; -} - -.durationInput .ui.labeled.input > .label { - width: 3em; -} - .messages { position: fixed; - /* top: 12px; */ bottom: 1em; left: 1em; right: 1em; diff --git a/app/webpack.config.js b/app/webpack.config.js index 0151d22..724af23 100644 --- a/app/webpack.config.js +++ b/app/webpack.config.js @@ -2,6 +2,7 @@ const path = require("path"); const webpack = require("webpack"); const HtmlWebpackPlugin = require("html-webpack-plugin"); +const FaviconsWebpackPlugin = require("favicons-webpack-plugin"); const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const DashboardPlugin = require("webpack-dashboard/plugin"); @@ -160,6 +161,7 @@ const getConfig = module.exports = (env) => { minifyURLs: true, } : undefined, }), + new FaviconsWebpackPlugin(path.resolve(paths.appDir, "images", "favicon-96x96.png")), // Makes some environment variables available to the JS code, for example: // if (process.env.NODE_ENV === "production") { ... }. See `./env.js`. // It is absolutely essential that NODE_ENV was set to production here. diff --git a/common/sprinklersRpc/Program.ts b/common/sprinklersRpc/Program.ts index a832ece..85c1273 100644 --- a/common/sprinklersRpc/Program.ts +++ b/common/sprinklersRpc/Program.ts @@ -1,16 +1,20 @@ import { observable } from "mobx"; +import { serialize } from "serializr"; + import { Schedule } from "./schedule"; +import * as schema from "./schema"; import { SprinklersDevice } from "./SprinklersDevice"; export class ProgramItem { // the section number - readonly section: number; + readonly section!: number; // duration of the run, in seconds - readonly duration: number; + readonly duration!: number; - constructor(section: number = 0, duration: number = 0) { - this.section = section; - this.duration = duration; + constructor(data?: Partial) { + if (data) { + Object.assign(this, data); + } } } @@ -37,7 +41,8 @@ export class Program { return this.device.cancelProgram({ programId: this.id }); } - update(data: any) { + update() { + const data = serialize(schema.program, this); return this.device.updateProgram({ programId: this.id, data }); } diff --git a/common/sprinklersRpc/Section.ts b/common/sprinklersRpc/Section.ts index 3f8c710..37bc699 100644 --- a/common/sprinklersRpc/Section.ts +++ b/common/sprinklersRpc/Section.ts @@ -23,6 +23,6 @@ export class Section { } toString(): string { - return `Section{id=${this.id}, name="${this.name}", state=${this.state}}`; + return `Section ${this.id}: '${this.name}'`; } } diff --git a/package.json b/package.json index 97b46bf..8ead490 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "classnames": "^2.2.6", "css-loader": "^0.28.11", "dotenv": "^6.0.0", + "favicons-webpack-plugin": "^0.0.9", "file-loader": "^1.1.11", "font-awesome": "^4.7.0", "happypack": "^5.0.0", diff --git a/server/entities/SprinklersDevice.ts b/server/entities/SprinklersDevice.ts index 107b697..176c1a6 100644 --- a/server/entities/SprinklersDevice.ts +++ b/server/entities/SprinklersDevice.ts @@ -7,6 +7,9 @@ export class SprinklersDevice { @PrimaryGeneratedColumn() id!: number; + @Column({ nullable: true, type: "uuid" }) + deviceId: string | null = null; + @Column() name: string = ""; diff --git a/yarn.lock b/yarn.lock index 4ef5eb0..c7fbfb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -342,6 +342,15 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + ajv@^6.1.0: version "6.5.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.1.tgz#88ebc1263c7133937d108b80c5572e64e1d9322d" @@ -509,6 +518,10 @@ arraybuffer.slice@~0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -559,7 +572,7 @@ async@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/async/-/async-1.5.0.tgz#2796642723573859565633fc6274444bee2f8ce3" -async@^1.4.0, async@^1.5.2: +async@^1.4.0, async@^1.5.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -603,7 +616,11 @@ aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" -aws4@^1.2.1: +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.2.1, aws4@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" @@ -686,6 +703,10 @@ big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" +bignumber.js@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" + binary-extensions@^1.0.0: version "1.11.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" @@ -715,6 +736,14 @@ bluebird@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" +bmp-js@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.1.tgz#5ad0147099d13a9f38aa7b99af1d6e78666ed37f" + +bmp-js@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.3.tgz#64113e9c7cf1202b376ed607bf30626ebe57b18a" + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -882,10 +911,29 @@ browserslist@^3.2.8: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + +buffer-alloc@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + buffer-from@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" @@ -990,7 +1038,7 @@ camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" -camelcase@^2.0.0: +camelcase@^2.0.0, camelcase@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" @@ -1072,6 +1120,16 @@ check-types@^7.3.0: version "7.4.0" resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4" +cheerio@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.19.0.tgz#772e7015f2ee29965096d71ea4175b75ab354925" + dependencies: + css-select "~1.0.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "~3.8.1" + lodash "^3.2.0" + chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -1184,7 +1242,7 @@ cliui@^2.1.0: right-align "^0.1.1" wordwrap "0.0.2" -cliui@^3.2.0: +cliui@^3.0.3, cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" dependencies: @@ -1209,7 +1267,11 @@ clone-deep@^2.0.1: kind-of "^6.0.0" shallow-clone "^1.0.0" -clone@^1.0.2: +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + +clone@^1.0.0, clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -1284,11 +1346,15 @@ colormin@^1.0.5: css-color-names "0.0.4" has "^1.0.1" +colors@^1.1.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.1.tgz#4accdb89cf2cabc7f982771925e9468784f32f3d" + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" -combined-stream@^1.0.5, combined-stream@~1.0.5: +combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" dependencies: @@ -1347,7 +1413,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.5.0, concat-stream@^1.6.2: +concat-stream@1.6.2, concat-stream@^1.5.0, concat-stream@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" dependencies: @@ -1557,6 +1623,15 @@ css-select@^1.1.0: domutils "1.5.1" nth-check "~1.0.1" +css-select@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.0.0.tgz#b1121ca51848dd264e2244d058cee254deeb44b0" + dependencies: + boolbase "~1.0.0" + css-what "1.0" + domutils "1.4" + nth-check "~1.0.0" + css-selector-tokenizer@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" @@ -1565,6 +1640,10 @@ css-selector-tokenizer@^0.7.0: fastparse "^1.1.1" regexpu-core "^1.0.0" +css-what@1.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-1.0.0.tgz#d7cc2df45180666f99d2b14462639469e00f736c" + css-what@2.1: version "2.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" @@ -1667,6 +1746,12 @@ debug@^3.1.0, debug@~3.1.0: dependencies: ms "2.0.0" +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1801,7 +1886,7 @@ dom-converter@~0.1: dependencies: utila "~0.3" -dom-serializer@0: +dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" dependencies: @@ -1830,13 +1915,25 @@ domhandler@2.1: dependencies: domelementtype "1" +domhandler@2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" + dependencies: + domelementtype "1" + domutils@1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485" dependencies: domelementtype "1" -domutils@1.5.1: +domutils@1.4: + version "1.4.3" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.4.3.tgz#0865513796c6b306031850e175516baf80b72a6f" + dependencies: + domelementtype "1" + +domutils@1.5, domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" dependencies: @@ -1975,6 +2072,10 @@ enhanced-resolve@^4.0.0: memory-fs "^0.4.0" tapable "^1.0.0" +entities@1.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" + entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" @@ -2025,6 +2126,14 @@ es6-iterator@~2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" +es6-promise@^3.0.2: + version "3.3.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" + +es6-promise@^4.0.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" + es6-symbol@^3.1.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" @@ -2118,6 +2227,10 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exif-parser@^0.1.9: + version "0.1.12" + resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -2214,6 +2327,10 @@ extend@^3.0.0, extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +extend@~3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + external-editor@^2.0.4: version "2.2.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" @@ -2249,6 +2366,15 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extract-zip@^1.6.5: + version "1.6.7" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" + dependencies: + concat-stream "1.6.2" + debug "2.6.9" + mkdirp "0.5.1" + yauzl "2.4.1" + extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -2257,6 +2383,10 @@ extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" @@ -2281,6 +2411,37 @@ fastparse@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" +favicons-webpack-plugin@^0.0.9: + version "0.0.9" + resolved "https://registry.yarnpkg.com/favicons-webpack-plugin/-/favicons-webpack-plugin-0.0.9.tgz#df63e80c556b804e4925ec8e05bee36391573dc9" + dependencies: + favicons "^4.8.3" + loader-utils "^0.2.14" + lodash "^4.11.1" + +favicons@^4.8.3: + version "4.8.6" + resolved "https://registry.yarnpkg.com/favicons/-/favicons-4.8.6.tgz#a2b13800ab3fec2715bc8f27fa841d038d4761e2" + dependencies: + async "^1.5.0" + cheerio "^0.19.0" + clone "^1.0.2" + colors "^1.1.2" + harmony-reflect "^1.4.2" + image-size "^0.4.0" + jimp "^0.2.13" + jsontoxml "0.0.11" + merge-defaults "^0.2.1" + mkdirp "^0.5.1" + node-rest-client "^1.5.1" + require-directory "^2.1.1" + svg2png "~3.0.1" + through2 "^2.0.0" + tinycolor2 "^1.1.2" + to-ico "^1.1.2" + underscore "^1.8.3" + vinyl "^1.1.0" + faye-websocket@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" @@ -2305,6 +2466,12 @@ fbjs@^0.8.16: setimmediate "^1.0.5" ua-parser-js "^0.7.18" +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + dependencies: + pend "~1.2.0" + figlet@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.2.0.tgz#6c46537378fab649146b5a6143dda019b430b410" @@ -2322,6 +2489,10 @@ file-loader@^1.1.11: loader-utils "^1.0.2" schema-utils "^0.4.5" +file-type@^3.1.0, file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -2411,6 +2582,12 @@ font-awesome@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" +for-each@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + dependencies: + is-callable "^1.1.3" + for-in@^0.1.3: version "0.1.8" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" @@ -2463,6 +2640,14 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" +form-data@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + dependencies: + asynckit "^0.4.0" + combined-stream "1.0.6" + mime-types "^2.1.12" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -2492,6 +2677,14 @@ from@~0: version "0.1.7" resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" +fs-extra@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -2568,6 +2761,13 @@ get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" +get-stream@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -2666,7 +2866,7 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" -global@^4.3.0: +global@^4.3.0, global@~4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" dependencies: @@ -2707,7 +2907,7 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2751,6 +2951,10 @@ har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + har-validator@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" @@ -2767,6 +2971,17 @@ har-validator@~4.2.1: ajv "^4.9.1" har-schema "^1.0.5" +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +harmony-reflect@^1.4.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.0.tgz#9c28a77386ec225f7b5d370f9861ba09c4eea58f" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -2846,6 +3061,13 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" +hasha@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-2.2.0.tgz#78d7cbfc1e6d66303fe79837365984517b2f6ee1" + dependencies: + is-stream "^1.0.1" + pinkie-promise "^2.0.0" + hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -2958,6 +3180,16 @@ htmlparser2@~3.3.0: domutils "1.1" readable-stream "1.0" +htmlparser2@~3.8.1: + version "3.8.3" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" + dependencies: + domelementtype "1" + domhandler "2.3" + domutils "1.5" + entities "1.0" + readable-stream "1.1" + http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" @@ -3009,6 +3241,14 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -3051,6 +3291,14 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +image-size@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.4.0.tgz#d4b4e1f61952e4cbc1cea9a6b0c915fecb707510" + +image-size@^0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -3183,6 +3431,10 @@ io-ts@^1.0.2, io-ts@^1.0.5: dependencies: fp-ts "^1.0.0" +ip-regex@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" + ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -3328,6 +3580,10 @@ is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" +is-function@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -3540,6 +3796,35 @@ isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" +jimp@^0.2.13, jimp@^0.2.21: + version "0.2.28" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.28.tgz#dd529a937190f42957a7937d1acc3a7762996ea2" + dependencies: + bignumber.js "^2.1.0" + bmp-js "0.0.3" + es6-promise "^3.0.2" + exif-parser "^0.1.9" + file-type "^3.1.0" + jpeg-js "^0.2.0" + load-bmfont "^1.2.3" + mime "^1.3.4" + mkdirp "0.5.1" + pixelmatch "^4.0.0" + pngjs "^3.0.0" + read-chunk "^1.0.1" + request "^2.65.0" + stream-to-buffer "^0.1.0" + tinycolor2 "^1.1.2" + url-regex "^3.0.0" + +jpeg-js@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.1.2.tgz#135b992c0575c985cfa0f494a3227ed238583ece" + +jpeg-js@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482" + jquery@x.*: version "3.3.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" @@ -3578,6 +3863,10 @@ json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -3604,6 +3893,12 @@ json5@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -3612,6 +3907,10 @@ jsonpointer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" +jsontoxml@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/jsontoxml/-/jsontoxml-0.0.11.tgz#373ab5b2070be3737a5fb3e32fd1b7b81870caa4" + jsonwebtoken@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" @@ -3650,6 +3949,10 @@ jws@^3.1.5: jwa "^1.1.5" safe-buffer "^5.0.1" +kew@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" + keyboard-key@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/keyboard-key/-/keyboard-key-1.0.1.tgz#a946294fe59ad5431c63a3ea269f023e51fac6aa" @@ -3678,6 +3981,12 @@ kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + optionalDependencies: + graceful-fs "^4.1.9" + latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" @@ -3702,6 +4011,18 @@ leven@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/leven/-/leven-1.0.2.tgz#9144b6eebca5f1d0680169f1a6770dcea60b75c3" +load-bmfont@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.3.0.tgz#bb7e7c710de6bcafcb13cb3b8c81e0c0131ecbc9" + dependencies: + buffer-equal "0.0.1" + mime "^1.3.4" + parse-bmfont-ascii "^1.0.3" + parse-bmfont-binary "^1.0.5" + parse-bmfont-xml "^1.1.0" + xhr "^2.0.1" + xtend "^4.0.0" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -3733,7 +4054,7 @@ loader-utils@1.1.0, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1. emojis-list "^2.0.0" json5 "^0.5.0" -loader-utils@^0.2.16, loader-utils@~0.2.2: +loader-utils@^0.2.14, loader-utils@^0.2.16, loader-utils@~0.2.2: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: @@ -3842,10 +4163,18 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10: +lodash@^3.2.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + +lodash@^4.0.0, lodash@^4.11.1, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" +lodash@~2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" + log-symbols@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" @@ -3978,6 +4307,12 @@ meow@^3.3.0, meow@^3.7.0: redent "^1.0.0" trim-newlines "^1.0.0" +merge-defaults@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/merge-defaults/-/merge-defaults-0.2.1.tgz#dd42248eb96bb6a51521724321c72ff9583dde80" + dependencies: + lodash "~2.4.1" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -4047,6 +4382,10 @@ mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" +mime@^1.3.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + mime@^2.0.3, mime@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" @@ -4142,7 +4481,7 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -4225,6 +4564,10 @@ mqtt@^2.18.1: websocket-stream "^5.1.2" xtend "^4.0.1" +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -4393,6 +4736,13 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" +node-rest-client@^1.5.1: + version "1.8.0" + resolved "https://registry.yarnpkg.com/node-rest-client/-/node-rest-client-1.8.0.tgz#8d3c566b817e27394cb7273783a41caefe3e5955" + dependencies: + debug "~2.2.0" + xml2js ">=0.2.4" + node-sass@^4.8.3: version "4.9.0" resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.9.0.tgz#d1b8aa855d98ed684d6848db929a20771cc2ae52" @@ -4519,7 +4869,7 @@ npm-run-path@^2.0.0: gauge "~2.7.3" set-blocking "~2.0.0" -nth-check@~1.0.1: +nth-check@~1.0.0, nth-check@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" dependencies: @@ -4533,7 +4883,7 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -oauth-sign@~0.8.1: +oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -4755,6 +5105,21 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" +parse-bmfont-ascii@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" + +parse-bmfont-binary@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" + +parse-bmfont-xml@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.3.tgz#d6b66a371afd39c5007d9f0eeb262a4f2cce7b7c" + dependencies: + xml-parse-from-string "^1.0.0" + xml2js "^0.4.5" + parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -4764,6 +5129,13 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.0" +parse-headers@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" + dependencies: + for-each "^0.3.2" + trim "0.0.1" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -4781,6 +5153,12 @@ parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" +parse-png@^1.0.0, parse-png@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/parse-png/-/parse-png-1.1.2.tgz#f5c2ad7c7993490986020a284c19aee459711ff2" + dependencies: + pngjs "^3.2.0" + parse5@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" @@ -4881,10 +5259,18 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + pg-connection-string@0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7" @@ -4920,6 +5306,20 @@ pgpass@1.x: dependencies: split "^1.0.0" +phantomjs-prebuilt@^2.1.10: + version "2.1.16" + resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz#efd212a4a3966d3647684ea8ba788549be2aefef" + dependencies: + es6-promise "^4.0.3" + extract-zip "^1.6.5" + fs-extra "^1.0.0" + hasha "^2.2.0" + kew "^0.7.0" + progress "^1.1.8" + request "^2.81.0" + request-progress "^2.0.1" + which "^1.2.10" + pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -4966,12 +5366,26 @@ pino@^4.10.2, pino@^4.17.3: quick-format-unescaped "^1.1.2" split2 "^2.2.0" +pixelmatch@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" + dependencies: + pngjs "^3.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" dependencies: find-up "^2.1.0" +pn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + +pngjs@^3.0.0, pngjs@^3.2.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.3.3.tgz#85173703bde3edac8998757b96e5821d0966a21b" + portfinder@^1.0.9: version "1.0.13" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" @@ -5553,6 +5967,10 @@ process@~0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -5655,7 +6073,7 @@ qs@6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" -qs@6.5.2: +qs@6.5.2, qs@~6.5.1: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -5827,6 +6245,10 @@ react@16.4.1: object-assign "^4.1.1" prop-types "^15.6.0" +read-chunk@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -5871,6 +6293,15 @@ readable-stream@1.0: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@1.1: + version "1.1.13" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -5999,6 +6430,16 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + +request-progress@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-2.0.1.tgz#5d36bb57961c673aa5b788dbc8141fdf23b44e08" + dependencies: + throttleit "^1.0.0" + "request@>=2.9.0 <2.82.0": version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -6026,6 +6467,31 @@ repeating@^2.0.0: tunnel-agent "^0.6.0" uuid "^3.0.0" +request@^2.65.0, request@^2.81.0: + version "2.87.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + request@~2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" @@ -6067,6 +6533,17 @@ requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" +resize-img@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/resize-img/-/resize-img-1.1.2.tgz#fad650faf3ef2c53ea63112bc272d95e9d92550e" + dependencies: + bmp-js "0.0.1" + file-type "^3.8.0" + get-stream "^2.0.0" + jimp "^0.2.21" + jpeg-js "^0.1.1" + parse-png "^1.1.1" + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -6681,6 +7158,16 @@ stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" +stream-to-buffer@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9" + dependencies: + stream-to "~0.2.0" + +stream-to@~0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -6781,6 +7268,14 @@ supports-color@^5.1.0, supports-color@^5.2.0, supports-color@^5.3.0, supports-co dependencies: has-flag "^3.0.0" +svg2png@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/svg2png/-/svg2png-3.0.1.tgz#a2644d68b0231ac00af431aa163714ff17106447" + dependencies: + phantomjs-prebuilt "^2.1.10" + pn "^1.0.0" + yargs "^3.31.0" + svgo@^0.7.0: version "0.7.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" @@ -6843,6 +7338,10 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +throttleit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" + through2-filter@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" @@ -6875,6 +7374,10 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tinycolor2@^1.1.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -6896,6 +7399,16 @@ to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" +to-ico@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/to-ico/-/to-ico-1.1.5.tgz#1d32da5f2c90922edee6b686d610c54527b5a8d5" + dependencies: + arrify "^1.0.1" + buffer-alloc "^1.1.0" + image-size "^0.5.0" + parse-png "^1.0.0" + resize-img "^1.1.0" + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -6928,7 +7441,7 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" -tough-cookie@~2.3.0: +tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" dependencies: @@ -6938,6 +7451,10 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + "true-case-path@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62" @@ -7100,6 +7617,10 @@ undefsafe@^2.0.2: dependencies: debug "^2.2.0" +underscore@^1.8.3: + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" @@ -7215,6 +7736,12 @@ url-parse@^1.1.8, url-parse@~1.4.0: querystringify "^2.0.0" requires-port "^1.0.0" +url-regex@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724" + dependencies: + ip-regex "^1.0.1" + url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -7298,6 +7825,14 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vinyl@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" @@ -7512,7 +8047,7 @@ which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@1, which@^1.2.14, which@^1.2.9: +which@1, which@^1.2.10, which@^1.2.14, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" dependencies: @@ -7534,6 +8069,10 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" +window-size@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" + wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -7592,7 +8131,20 @@ xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" -xml2js@^0.4.17: +xhr@^2.0.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xml-parse-from-string@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" + +xml2js@>=0.2.4, xml2js@^0.4.17, xml2js@^0.4.5: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" dependencies: @@ -7611,7 +8163,7 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" -y18n@^3.2.1: +y18n@^3.2.0, y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" @@ -7704,6 +8256,18 @@ yargs@^11.1.0: y18n "^3.2.1" yargs-parser "^9.0.2" +yargs@^3.31.0: + version "3.32.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" + dependencies: + camelcase "^2.0.1" + cliui "^3.0.3" + decamelize "^1.1.1" + os-locale "^1.4.0" + string-width "^1.0.1" + window-size "^0.1.4" + y18n "^3.2.0" + yargs@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" @@ -7731,6 +8295,12 @@ yargs@~3.10.0: decamelize "^1.0.0" window-size "0.1.0" +yauzl@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" + dependencies: + fd-slicer "~1.0.1" + yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"