From 115fa4fb52988584e2e97ebd483405e25ea1d380 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 10 Sep 2018 17:00:53 +0200 Subject: [PATCH 001/121] added changesets module --- scm-ui/src/changesets/modules/changesets.js | 71 +++++++++++++++++++ .../src/changesets/modules/changesets.test.js | 66 +++++++++++++++++ scm-ui/src/createReduxStore.js | 2 + scm-ui/src/repos/modules/repos.test.js | 2 +- 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 scm-ui/src/changesets/modules/changesets.js create mode 100644 scm-ui/src/changesets/modules/changesets.test.js diff --git a/scm-ui/src/changesets/modules/changesets.js b/scm-ui/src/changesets/modules/changesets.js new file mode 100644 index 0000000000..639a4ff1db --- /dev/null +++ b/scm-ui/src/changesets/modules/changesets.js @@ -0,0 +1,71 @@ +// @flow + +import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; +import { apiClient } from "@scm-manager/ui-components"; + +export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; +export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; +export const FETCH_CHANGESETS_SUCCESS = `${FETCH_CHANGESETS}_${SUCCESS_SUFFIX}`; +export const FETCH_CHANGESETS_FAILURE = `${FETCH_CHANGESETS}_${FAILURE_SUFFIX}`; + +const REPO_URL = "repositories"; + +export function fetchChangesets(namespace: string, name: string) { + return fetchChangesetsByLink(REPO_URL + "/" + namespace + "/" + name + "/changesets"); +} + +export function fetchChangesetsByLink(link: string) { + return function(dispatch: any) { + dispatch(fetchChangesetsPending()); + return apiClient.get(link).then(response => response.json()) + .then(data => { + dispatch(fetchChangesetsSuccess(data)) + }).catch(cause => { + dispatch(fetchChangesetsFailure(link, cause)) + }) + } +} + +export function fetchChangesetsPending(): Action { + return { + type: FETCH_CHANGESETS_PENDING + } +} + +export function fetchChangesetsSuccess(data: any): Action { + return { + type: FETCH_CHANGESETS_SUCCESS, + payload: data + } +} + +function fetchChangesetsFailure(url: string, error: Error): Action { + return { + type: FETCH_CHANGESETS_FAILURE, + payload: { + url, + error + } + } +} + + +export default function reducer(state: any = {}, action: any = {}) { + switch (action.type) { + case FETCH_CHANGESETS_SUCCESS: + + return {byIds: extractChangesetsByIds(action.payload)}; + default: + return state; + } +} + +function extractChangesetsByIds(data: any) { + const changesets = data._embedded.changesets; + const changesetsByIds = {}; + for (let changeset of changesets) { + changesetsByIds[changeset.id] = changeset; + } + + return changesetsByIds; +} diff --git a/scm-ui/src/changesets/modules/changesets.test.js b/scm-ui/src/changesets/modules/changesets.test.js new file mode 100644 index 0000000000..aaeb75451e --- /dev/null +++ b/scm-ui/src/changesets/modules/changesets.test.js @@ -0,0 +1,66 @@ +// @flow + + +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; +import fetchMock from "fetch-mock"; +import { + FETCH_CHANGESETS_PENDING, + FETCH_CHANGESETS_SUCCESS, + fetchChangesets, + fetchChangesetsSuccess +} from "./changesets"; +import reducer from "./changesets"; + +const collection = {}; + +describe("fetching of changesets", () => { + const URL = "/api/rest/v2/repositories/foo/bar/changesets"; + const mockStore = configureMockStore([thunk]); + + afterEach(() => { + fetchMock.reset(); + fetchMock.restore(); + }); + + it("should fetch changesets", () => { + fetchMock.getOnce(URL, "{}"); + + const expectedActions = [ + { type: FETCH_CHANGESETS_PENDING }, + { + type: FETCH_CHANGESETS_SUCCESS, + payload: collection + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchChangesets("foo", "bar")).then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); + }) +}); + +describe("changesets reducer", () => { + const responseBody = { + _embedded: { + changesets: [ + {id: "changeset1", author: { mail: "z@phod.com", name: "zaphod"}}, + {id: "changeset2"}, + {id: "changeset3"}, + ], + _embedded: { + tags: [], + branches: [], + parents: [] + } + } + }; + it("should set state correctly", () => { + const newState = reducer({}, fetchChangesetsSuccess(responseBody)); + expect(newState.byIds["changeset1"]).toBeDefined(); + expect(newState.byIds["changeset1"].author.mail).toEqual("z@phod.com"); + expect(newState.byIds["changeset2"]).toBeDefined(); + expect(newState.byIds["changeset3"]).toBeDefined(); + }) +}); diff --git a/scm-ui/src/createReduxStore.js b/scm-ui/src/createReduxStore.js index 8411326b53..a63a6edcdb 100644 --- a/scm-ui/src/createReduxStore.js +++ b/scm-ui/src/createReduxStore.js @@ -7,6 +7,7 @@ import { routerReducer, routerMiddleware } from "react-router-redux"; import users from "./users/modules/users"; import repos from "./repos/modules/repos"; import repositoryTypes from "./repos/modules/repositoryTypes"; +import changesets from "./changesets/modules/changesets"; import groups from "./groups/modules/groups"; import auth from "./modules/auth"; import pending from "./modules/pending"; @@ -26,6 +27,7 @@ function createReduxStore(history: BrowserHistory) { users, repos, repositoryTypes, + changesets, groups, auth, config diff --git a/scm-ui/src/repos/modules/repos.test.js b/scm-ui/src/repos/modules/repos.test.js index ae85d6cb17..d537f4bdc0 100644 --- a/scm-ui/src/repos/modules/repos.test.js +++ b/scm-ui/src/repos/modules/repos.test.js @@ -405,7 +405,7 @@ describe("repos fetch", () => { }); }); - it("should disapatch failure if server returns status code 500", () => { + it("should dispatch failure if server returns status code 500", () => { fetchMock.postOnce(REPOS_URL, { status: 500 }); From 9e489cfd1da6b9ee7a0c039f0c99ec9887ad498c Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Tue, 11 Sep 2018 17:20:30 +0200 Subject: [PATCH 002/121] Added types, components and logic for changesets --- .../packages/ui-types/src/Changesets.js | 18 +++++ .../packages/ui-types/src/Tags.js | 8 ++ .../packages/ui-types/src/index.js | 4 + scm-ui/public/locales/en/changesets.json | 12 +++ .../src/changesets/components/ChangesetRow.js | 21 ++++++ .../src/changesets/components/Changesets.js | 59 +++++++++++++++ scm-ui/src/changesets/modules/changesets.js | 59 ++++++++++----- .../src/changesets/modules/changesets.test.js | 74 +++++++++++++++---- .../src/repos/components/RepositoryDetails.js | 2 + 9 files changed, 224 insertions(+), 33 deletions(-) create mode 100644 scm-ui-components/packages/ui-types/src/Changesets.js create mode 100644 scm-ui-components/packages/ui-types/src/Tags.js create mode 100644 scm-ui/public/locales/en/changesets.json create mode 100644 scm-ui/src/changesets/components/ChangesetRow.js create mode 100644 scm-ui/src/changesets/components/Changesets.js diff --git a/scm-ui-components/packages/ui-types/src/Changesets.js b/scm-ui-components/packages/ui-types/src/Changesets.js new file mode 100644 index 0000000000..9979cf2d89 --- /dev/null +++ b/scm-ui-components/packages/ui-types/src/Changesets.js @@ -0,0 +1,18 @@ +//@flow +import type { Links } from "./hal"; +import type { Tag } from "./Tags"; +export type Changeset = { + id: string, + date: Date, + author: { + name: string, + mail: string + }, + description: string + _links: Links, + _embedded: { + tags: Tag[] + branches: any, //todo: Add correct type + parents: any //todo: Add correct type + }; +} diff --git a/scm-ui-components/packages/ui-types/src/Tags.js b/scm-ui-components/packages/ui-types/src/Tags.js new file mode 100644 index 0000000000..1e6244124a --- /dev/null +++ b/scm-ui-components/packages/ui-types/src/Tags.js @@ -0,0 +1,8 @@ +//@flow +import type { Links } from "./hal"; + +export type Tag = { + name: string, + revision: string, + _links: Links +} diff --git a/scm-ui-components/packages/ui-types/src/index.js b/scm-ui-components/packages/ui-types/src/index.js index 109fb9bb6a..5e9c14e758 100644 --- a/scm-ui-components/packages/ui-types/src/index.js +++ b/scm-ui-components/packages/ui-types/src/index.js @@ -9,4 +9,8 @@ export type { Group, Member } from "./Group"; export type { Repository, RepositoryCollection, RepositoryGroup } from "./Repositories"; export type { RepositoryType, RepositoryTypeCollection } from "./RepositoryTypes"; +export type { Changeset } from "./Changesets"; + +export type { Tag } from "./Tags" + export type { Config } from "./Config"; diff --git a/scm-ui/public/locales/en/changesets.json b/scm-ui/public/locales/en/changesets.json new file mode 100644 index 0000000000..6628fcf62f --- /dev/null +++ b/scm-ui/public/locales/en/changesets.json @@ -0,0 +1,12 @@ +{ + "changeset": { + "id": "ID", + "description": "Description", + "contact": "Contact", + "date": "Date" + }, + "author": { + "name": "Author", + "mail": "Mail" + } +} diff --git a/scm-ui/src/changesets/components/ChangesetRow.js b/scm-ui/src/changesets/components/ChangesetRow.js new file mode 100644 index 0000000000..afc544492a --- /dev/null +++ b/scm-ui/src/changesets/components/ChangesetRow.js @@ -0,0 +1,21 @@ +import React from "react" +import type { Changeset } from "@scm-manager/ui-types" + +type Props = { + changeset: Changeset +} + +class ChangesetRow extends React.Component { + + // Todo: Add extension point to author field + render() { + const {changeset} = this.props; + return + { changeset.author.name } + { changeset.description } + { changeset.date } + + } +} + +export default ChangesetRow; diff --git a/scm-ui/src/changesets/components/Changesets.js b/scm-ui/src/changesets/components/Changesets.js new file mode 100644 index 0000000000..733461b722 --- /dev/null +++ b/scm-ui/src/changesets/components/Changesets.js @@ -0,0 +1,59 @@ +import React from "react" +import { connect } from "react-redux"; +import ChangesetRow from "./ChangesetRow"; +import type {Changeset} from "@scm-manager/ui-types"; + +import { fetchChangesetsByNamespaceAndName, getChangesetsForNameAndNamespaceFromState } from "../modules/changesets"; +import { translate } from "react-i18next"; + +type Props = { + changesets: Changeset[], + t: string => string +} + +class Changesets extends React.Component { + componentDidMount() { + const {namespace, name} = this.props.repository; + this.props.fetchChangesetsByNamespaceAndName(namespace, name); + } + + render() { + const { t, changesets } = this.props; + if (!changesets) { + return null; + } + return + + + + + + + + + {changesets.map((changeset, index) => { + return ; + })} + +
{t("author.name")}{t("changeset.description")}{t("changeset.date")}
+ } +} + +const mapStateToProps = (state, ownProps) => { + return { + changesets: getChangesetsForNameAndNamespaceFromState(ownProps.repository.namespace, ownProps.repository.name, state) + } +}; + +const mapDispatchToProps = dispatch => { + return { + fetchChangesetsByNamespaceAndName: (namespace: string, name: string) => { + dispatch(fetchChangesetsByNamespaceAndName(namespace, name)) + } + } +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(translate("changesets")(Changesets)); diff --git a/scm-ui/src/changesets/modules/changesets.js b/scm-ui/src/changesets/modules/changesets.js index 639a4ff1db..78715b53cc 100644 --- a/scm-ui/src/changesets/modules/changesets.js +++ b/scm-ui/src/changesets/modules/changesets.js @@ -1,7 +1,7 @@ // @flow import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; -import { apiClient } from "@scm-manager/ui-components"; +import {apiClient} from "@scm-manager/ui-components"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -10,62 +10,85 @@ export const FETCH_CHANGESETS_FAILURE = `${FETCH_CHANGESETS}_${FAILURE_SUFFIX}`; const REPO_URL = "repositories"; -export function fetchChangesets(namespace: string, name: string) { - return fetchChangesetsByLink(REPO_URL + "/" + namespace + "/" + name + "/changesets"); -} -export function fetchChangesetsByLink(link: string) { - return function(dispatch: any) { - dispatch(fetchChangesetsPending()); - return apiClient.get(link).then(response => response.json()) +// actions +export function fetchChangesetsByNamespaceAndName(namespace: string, name: string) { + return function (dispatch: any) { + dispatch(fetchChangesetsPending(namespace, name)); + return apiClient.get(REPO_URL + "/" + namespace + "/" + name + "/changesets").then(response => response.json()) .then(data => { - dispatch(fetchChangesetsSuccess(data)) + dispatch(fetchChangesetsSuccess(data, namespace, name)) }).catch(cause => { dispatch(fetchChangesetsFailure(link, cause)) }) } } -export function fetchChangesetsPending(): Action { +export function fetchChangesetsPending(namespace: string, name: string): Action { return { - type: FETCH_CHANGESETS_PENDING + type: FETCH_CHANGESETS_PENDING, + payload: { + namespace, + name + } } } -export function fetchChangesetsSuccess(data: any): Action { +export function fetchChangesetsSuccess(collection: any, namespace: string, name: string): Action { return { type: FETCH_CHANGESETS_SUCCESS, - payload: data + payload: {collection, namespace, name} } } -function fetchChangesetsFailure(url: string, error: Error): Action { +function fetchChangesetsFailure(namespace: string, name: string, error: Error): Action { return { type: FETCH_CHANGESETS_FAILURE, payload: { - url, + namespace, + name, error } } } - +// reducer export default function reducer(state: any = {}, action: any = {}) { switch (action.type) { case FETCH_CHANGESETS_SUCCESS: + const {namespace, name} = action.payload; + const key = namespace + "/" + name; - return {byIds: extractChangesetsByIds(action.payload)}; + let oldChangesets = {[key]: {}}; + if (state[key] !== undefined) { + oldChangesets[key] = state[key] + } + return {[key]: {byId: extractChangesetsByIds(action.payload.collection, oldChangesets[key].byId)}}; default: return state; } } -function extractChangesetsByIds(data: any) { +function extractChangesetsByIds(data: any, oldChangesetsByIds: any) { const changesets = data._embedded.changesets; const changesetsByIds = {}; + for (let changeset of changesets) { changesetsByIds[changeset.id] = changeset; } + for (let id in oldChangesetsByIds) { + changesetsByIds[id] = oldChangesetsByIds[id]; + } + return changesetsByIds; } + +//selectors +export function getChangesetsForNameAndNamespaceFromState(namespace: string, name: string, state: any) { + const key = namespace + "/" + name; + if (!state.changesets[key]) { + return null; + } + return Object.values(state.changesets[key].byId); +} diff --git a/scm-ui/src/changesets/modules/changesets.test.js b/scm-ui/src/changesets/modules/changesets.test.js index aaeb75451e..7191846ca2 100644 --- a/scm-ui/src/changesets/modules/changesets.test.js +++ b/scm-ui/src/changesets/modules/changesets.test.js @@ -1,14 +1,13 @@ // @flow - import configureMockStore from "redux-mock-store"; import thunk from "redux-thunk"; import fetchMock from "fetch-mock"; import { FETCH_CHANGESETS_PENDING, FETCH_CHANGESETS_SUCCESS, - fetchChangesets, - fetchChangesetsSuccess + fetchChangesetsByNamespaceAndName, + fetchChangesetsSuccess, getChangesetsForNameAndNamespaceFromState } from "./changesets"; import reducer from "./changesets"; @@ -27,15 +26,15 @@ describe("fetching of changesets", () => { fetchMock.getOnce(URL, "{}"); const expectedActions = [ - { type: FETCH_CHANGESETS_PENDING }, + {type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}}, { type: FETCH_CHANGESETS_SUCCESS, - payload: collection + payload: {collection, namespace: "foo", name: "bar"} } ]; const store = mockStore({}); - return store.dispatch(fetchChangesets("foo", "bar")).then(() => { + return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }) @@ -45,9 +44,9 @@ describe("changesets reducer", () => { const responseBody = { _embedded: { changesets: [ - {id: "changeset1", author: { mail: "z@phod.com", name: "zaphod"}}, - {id: "changeset2"}, - {id: "changeset3"}, + {id: "changeset1", author: {mail: "z@phod.com", name: "zaphod"}}, + {id: "changeset2", description: "foo"}, + {id: "changeset3", description: "bar"}, ], _embedded: { tags: [], @@ -56,11 +55,56 @@ describe("changesets reducer", () => { } } }; - it("should set state correctly", () => { - const newState = reducer({}, fetchChangesetsSuccess(responseBody)); - expect(newState.byIds["changeset1"]).toBeDefined(); - expect(newState.byIds["changeset1"].author.mail).toEqual("z@phod.com"); - expect(newState.byIds["changeset2"]).toBeDefined(); - expect(newState.byIds["changeset3"]).toBeDefined(); + + it("should set state to received changesets", () => { + const newState = reducer({}, fetchChangesetsSuccess(responseBody, "foo", "bar")); + expect(newState).toBeDefined(); + expect(newState["foo/bar"].byId["changeset1"].author.mail).toEqual("z@phod.com"); + expect(newState["foo/bar"].byId["changeset2"].description).toEqual("foo"); + expect(newState["foo/bar"].byId["changeset3"].description).toEqual("bar"); + }); + + it("should not delete existing changesets from state", () => { + const responseBody = { + _embedded: { + changesets: [ + {id: "changeset1", author: {mail: "z@phod.com", name: "zaphod"}}, + ], + _embedded: { + tags: [], + branches: [], + parents: [] + } + } + }; + const newState = reducer({ + "foo/bar": { + byId: { + ["changeset2"]: { + id: "changeset2", + author: {mail: "mail@author.com", name: "author"} + } + } + } + }, fetchChangesetsSuccess(responseBody, "foo", "bar")); + expect(newState["foo/bar"].byId["changeset2"]).toBeDefined(); + expect(newState["foo/bar"].byId["changeset1"]).toBeDefined(); + }) +}); + +describe("changeset selectors", () => { + it("should get all changesets for a given namespace and name", () => { + const state = { + changesets: { + ["foo/bar"]: { + byId: { + "id1": {id: "id1"}, + "id2": {id: "id2"} + } + } + } + }; + const result = getChangesetsForNameAndNamespaceFromState("foo", "bar", state); + expect(result).toContainEqual({id: "id1"}) }) }); diff --git a/scm-ui/src/repos/components/RepositoryDetails.js b/scm-ui/src/repos/components/RepositoryDetails.js index 99c88fec94..33edaff541 100644 --- a/scm-ui/src/repos/components/RepositoryDetails.js +++ b/scm-ui/src/repos/components/RepositoryDetails.js @@ -3,6 +3,7 @@ import React from "react"; import type { Repository } from "@scm-manager/ui-types"; import RepositoryDetailTable from "./RepositoryDetailTable"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; +import Changesets from "../../changesets/components/Changesets"; type Props = { repository: Repository @@ -20,6 +21,7 @@ class RepositoryDetails extends React.Component { renderAll={true} props={{ repository }} /> + ); From ee87ada415068627e4205a43f617e9aed0faf796 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Wed, 12 Sep 2018 17:15:16 +0200 Subject: [PATCH 003/121] Added branches module --- scm-ui/src/repos/modules/branches.js | 53 +++++++++++++++++++ scm-ui/src/repos/modules/branches.test.js | 63 +++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 scm-ui/src/repos/modules/branches.js create mode 100644 scm-ui/src/repos/modules/branches.test.js diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js new file mode 100644 index 0000000000..dde5cb379b --- /dev/null +++ b/scm-ui/src/repos/modules/branches.js @@ -0,0 +1,53 @@ +import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; +import {apiClient} from "@scm-manager/ui-components"; + +export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; +export const FETCH_BRANCHES_PENDING = `${FETCH_BRANCHES}_${PENDING_SUFFIX}`; +export const FETCH_BRANCHES_SUCCESS = `${FETCH_BRANCHES}_${SUCCESS_SUFFIX}`; +export const FETCH_BRANCHES_FAILURE = `${FETCH_BRANCHES}_${FAILURE_SUFFIX}`; + +const REPO_URL = "repositories"; + +// Fetching branches +export function fetchBranchesByNamespaceAndName(namespace: string, name: string) { + return function (dispatch: any) { + dispatch(fetchBranchesPending(namespace, name)); + return apiClient.get(REPO_URL + "/" + namespace + "/" + name + "/branches") + .then(response => response.json()) + .then(data => { + dispatch(fetchBranchesSuccess(data, namespace, name)) + }) + .catch(cause => { + dispatch(fetchBranchesFailure(namespace, name, cause)) + }) + } +} + +// Action creators +export function fetchBranchesPending(namespace: string, name: string) { + return { + type: FETCH_BRANCHES_PENDING, + payload: {namespace, name}, + itemId: namespace + "/" + name + } +} + +export function fetchBranchesSuccess(data: string, namespace: string, name: string) { + return { + type: FETCH_BRANCHES_SUCCESS, + payload: {data, namespace, name}, + itemId: namespace + "/" + name + } +} + +export function fetchBranchesFailure(namespace: string, name: string, error: Error) { + return { + type: FETCH_BRANCHES_FAILURE, + payload: {error, namespace, name}, + itemId: namespace + "/" + name + } +} + +// Reducers + +// Selectors diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js new file mode 100644 index 0000000000..67c5950c5a --- /dev/null +++ b/scm-ui/src/repos/modules/branches.test.js @@ -0,0 +1,63 @@ +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; +import fetchMock from "fetch-mock"; +import { + FETCH_BRANCHES_FAILURE, + FETCH_BRANCHES_PENDING, + FETCH_BRANCHES_SUCCESS, + fetchBranchesByNamespaceAndName +} from "./branches"; + +describe("fetch branches", () => { + const URL = "/api/rest/v2/repositories/foo/bar/branches"; + const mockStore = configureMockStore([thunk]); + + afterEach(() => { + fetchMock.reset(); + fetchMock.restore(); + }); + + + it("should fetch branches", () => { + const collection = {}; + + fetchMock.getOnce(URL, "{}"); + + const expectedActions = [ + {type: FETCH_BRANCHES_PENDING, payload: {namespace: "foo", name: "bar"}, + itemId: "foo/bar"}, + { + type: FETCH_BRANCHES_SUCCESS, + payload: {data: collection, namespace: "foo", name: "bar"}, + itemId: "foo/bar" + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchBranchesByNamespaceAndName("foo", "bar")).then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); + }); + + it("should fail fetching branches on HTTP 500", () => { + const collection = {}; + + fetchMock.getOnce(URL, 500); + + const expectedActions = [ + {type: FETCH_BRANCHES_PENDING, payload: {namespace: "foo", name: "bar"}, + itemId: "foo/bar"}, + { + type: FETCH_BRANCHES_FAILURE, + payload: {error: collection, namespace: "foo", name: "bar"}, + itemId: "foo/bar" + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchBranchesByNamespaceAndName("foo", "bar")).then(() => { + expect(store.getActions()[0]).toEqual(expectedActions[0]); + expect(store.getActions()[1].type).toEqual(FETCH_BRANCHES_FAILURE); + }); + }) +}); From 75002ffcff20860cf1d0a5451033d62c921c2752 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Wed, 12 Sep 2018 17:15:58 +0200 Subject: [PATCH 004/121] Added pending/error-logic for changesets Styled the changeset table a bit --- .../src/changesets/components/ChangesetRow.js | 17 ++++-- .../src/changesets/components/Changesets.js | 8 +-- scm-ui/src/changesets/modules/changesets.js | 24 ++++++-- .../src/changesets/modules/changesets.test.js | 61 ++++++++++++++++++- 4 files changed, 91 insertions(+), 19 deletions(-) diff --git a/scm-ui/src/changesets/components/ChangesetRow.js b/scm-ui/src/changesets/components/ChangesetRow.js index afc544492a..d0be206866 100644 --- a/scm-ui/src/changesets/components/ChangesetRow.js +++ b/scm-ui/src/changesets/components/ChangesetRow.js @@ -1,5 +1,6 @@ import React from "react" import type { Changeset } from "@scm-manager/ui-types" +import {ExtensionPoint} from "@scm-manager/ui-extensions"; type Props = { changeset: Changeset @@ -7,13 +8,19 @@ type Props = { class ChangesetRow extends React.Component { - // Todo: Add extension point to author field render() { - const {changeset} = this.props; + const { changeset } = this.props; + // todo: i18n return - { changeset.author.name } - { changeset.description } - { changeset.date } + + +

{changeset.description}

+

Changeset { changeset.id } commited at { changeset.date }

+

{changeset.author.name} <{changeset.author.mail}>

} } diff --git a/scm-ui/src/changesets/components/Changesets.js b/scm-ui/src/changesets/components/Changesets.js index 733461b722..ea0ac7aad1 100644 --- a/scm-ui/src/changesets/components/Changesets.js +++ b/scm-ui/src/changesets/components/Changesets.js @@ -22,13 +22,9 @@ class Changesets extends React.Component { if (!changesets) { return null; } - return + return
- - - - - + Changesets {changesets.map((changeset, index) => { diff --git a/scm-ui/src/changesets/modules/changesets.js b/scm-ui/src/changesets/modules/changesets.js index 78715b53cc..1aaa77f961 100644 --- a/scm-ui/src/changesets/modules/changesets.js +++ b/scm-ui/src/changesets/modules/changesets.js @@ -2,6 +2,8 @@ import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; import {apiClient} from "@scm-manager/ui-components"; +import {isPending} from "../../modules/pending"; +import {getFailure} from "../../modules/failure"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -19,7 +21,7 @@ export function fetchChangesetsByNamespaceAndName(namespace: string, name: strin .then(data => { dispatch(fetchChangesetsSuccess(data, namespace, name)) }).catch(cause => { - dispatch(fetchChangesetsFailure(link, cause)) + dispatch(fetchChangesetsFailure(namespace, name, cause)) }) } } @@ -30,14 +32,16 @@ export function fetchChangesetsPending(namespace: string, name: string): Action payload: { namespace, name - } + }, + itemId: namespace + "/" + name } } export function fetchChangesetsSuccess(collection: any, namespace: string, name: string): Action { return { type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace, name} + payload: {collection, namespace, name}, + itemId: namespace + "/" + name } } @@ -48,7 +52,8 @@ function fetchChangesetsFailure(namespace: string, name: string, error: Error): namespace, name, error - } + }, + itemId: namespace + "/" + name } } @@ -85,10 +90,19 @@ function extractChangesetsByIds(data: any, oldChangesetsByIds: any) { } //selectors -export function getChangesetsForNameAndNamespaceFromState(namespace: string, name: string, state: any) { +export function getChangesetsForNameAndNamespaceFromState(namespace: string, name: string, state: Object) { const key = namespace + "/" + name; if (!state.changesets[key]) { return null; } return Object.values(state.changesets[key].byId); } + +export function isFetchChangesetsPending( state: Object, namespace: string, name: string) { + return isPending(state, FETCH_CHANGESETS, namespace + "/" + name) +} + +export function getFetchChangesetsFailure( state: Object, namespace: string, name: string) { + return getFailure(state, FETCH_CHANGESETS, namespace + "/" + name); +} + diff --git a/scm-ui/src/changesets/modules/changesets.test.js b/scm-ui/src/changesets/modules/changesets.test.js index 7191846ca2..c514978144 100644 --- a/scm-ui/src/changesets/modules/changesets.test.js +++ b/scm-ui/src/changesets/modules/changesets.test.js @@ -4,10 +4,11 @@ import configureMockStore from "redux-mock-store"; import thunk from "redux-thunk"; import fetchMock from "fetch-mock"; import { + FETCH_CHANGESETS, FETCH_CHANGESETS_FAILURE, FETCH_CHANGESETS_PENDING, FETCH_CHANGESETS_SUCCESS, fetchChangesetsByNamespaceAndName, - fetchChangesetsSuccess, getChangesetsForNameAndNamespaceFromState + fetchChangesetsSuccess, getChangesetsForNameAndNamespaceFromState, getFetchChangesetsFailure, isFetchChangesetsPending } from "./changesets"; import reducer from "./changesets"; @@ -26,10 +27,12 @@ describe("fetching of changesets", () => { fetchMock.getOnce(URL, "{}"); const expectedActions = [ - {type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}}, + {type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}, + itemId: "foo/bar"}, { type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace: "foo", name: "bar"} + payload: {collection, namespace: "foo", name: "bar"}, + itemId: "foo/bar" } ]; @@ -37,6 +40,27 @@ describe("fetching of changesets", () => { return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { expect(store.getActions()).toEqual(expectedActions); }); + }); + + it("should fail fetching changesets on error", () => { + fetchMock.getOnce(URL, 500); + + const expectedActions = [ + {type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}, + itemId: "foo/bar"}, + { + type: FETCH_CHANGESETS_SUCCESS, + payload: {collection, namespace: "foo", name: "bar"}, + itemId: "foo/bar" + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { + expect(store.getActions()[0]).toEqual(expectedActions[0]); + expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); + expect(store.getActions()[1].payload).toBeDefined(); + }); }) }); @@ -93,6 +117,8 @@ describe("changesets reducer", () => { }); describe("changeset selectors", () => { + const error = new Error("Something went wrong"); + it("should get all changesets for a given namespace and name", () => { const state = { changesets: { @@ -106,5 +132,34 @@ describe("changeset selectors", () => { }; const result = getChangesetsForNameAndNamespaceFromState("foo", "bar", state); expect(result).toContainEqual({id: "id1"}) + }); + + it("should return true, when fetching changesets is pending", () => { + const state = { + pending: { + [FETCH_CHANGESETS + "/foo/bar"]: true + } + }; + + expect(isFetchChangesetsPending(state, "foo", "bar")).toBeTruthy(); + }); + + it("should return false, when fetching changesets is not pending", () => { + expect(isFetchChangesetsPending({}, "foo", "bar")).toEqual(false); + }); + + it("should return error if fetching changesets failed", () => { + const state = { + failure: { + [FETCH_CHANGESETS + "/foo/bar"]: error + } + }; + + expect(getFetchChangesetsFailure(state, "foo", "bar")).toEqual(error); + }); + + it("should return false if fetching changesets did not fail", () => { + expect(getFetchChangesetsFailure({}, "foo", "bar")).toBeUndefined(); }) + }); From 5687a552b8fc91fb69a8149ee33b580d0df3214e Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Fri, 14 Sep 2018 16:15:13 +0200 Subject: [PATCH 005/121] Added possibility to fetch changesets by branches --- .../src/changesets/components/Changesets.js | 18 +- scm-ui/src/changesets/modules/changesets.js | 58 +++- .../src/changesets/modules/changesets.test.js | 296 +++++++++++------- scm-ui/src/createReduxStore.js | 2 + scm-ui/src/repos/modules/branches.js | 41 +++ scm-ui/src/repos/modules/branches.test.js | 92 +++++- 6 files changed, 359 insertions(+), 148 deletions(-) diff --git a/scm-ui/src/changesets/components/Changesets.js b/scm-ui/src/changesets/components/Changesets.js index ea0ac7aad1..f9feb51829 100644 --- a/scm-ui/src/changesets/components/Changesets.js +++ b/scm-ui/src/changesets/components/Changesets.js @@ -3,8 +3,12 @@ import { connect } from "react-redux"; import ChangesetRow from "./ChangesetRow"; import type {Changeset} from "@scm-manager/ui-types"; -import { fetchChangesetsByNamespaceAndName, getChangesetsForNameAndNamespaceFromState } from "../modules/changesets"; +import { + fetchChangesetsByNamespaceAndName, + getChangesets, +} from "../modules/changesets"; import { translate } from "react-i18next"; +import {fetchBranchesByNamespaceAndName} from "../../repos/modules/branches"; type Props = { changesets: Changeset[], @@ -15,6 +19,7 @@ class Changesets extends React.Component { componentDidMount() { const {namespace, name} = this.props.repository; this.props.fetchChangesetsByNamespaceAndName(namespace, name); + this.props.fetchBranchesByNamespaceAndName(namespace, name); } render() { @@ -24,7 +29,7 @@ class Changesets extends React.Component { } return
{t("author.name")}{t("changeset.description")}{t("changeset.date")}
- Changesets + {changesets.map((changeset, index) => { @@ -36,15 +41,20 @@ class Changesets extends React.Component { } const mapStateToProps = (state, ownProps) => { + const {namespace, name} = ownProps.repository; return { - changesets: getChangesetsForNameAndNamespaceFromState(ownProps.repository.namespace, ownProps.repository.name, state) + changesets: getChangesets(namespace, name, "", state) } }; const mapDispatchToProps = dispatch => { return { fetchChangesetsByNamespaceAndName: (namespace: string, name: string) => { - dispatch(fetchChangesetsByNamespaceAndName(namespace, name)) + dispatch(fetchChangesetsByNamespaceAndName(namespace, name)); + }, + + fetchBranchesByNamespaceAndName: (namespace: string, name: string) => { + dispatch(fetchBranchesByNamespaceAndName(namespace, name)); } } }; diff --git a/scm-ui/src/changesets/modules/changesets.js b/scm-ui/src/changesets/modules/changesets.js index 1aaa77f961..d77a1423aa 100644 --- a/scm-ui/src/changesets/modules/changesets.js +++ b/scm-ui/src/changesets/modules/changesets.js @@ -26,39 +26,61 @@ export function fetchChangesetsByNamespaceAndName(namespace: string, name: strin } } -export function fetchChangesetsPending(namespace: string, name: string): Action { +export function fetchChangesetsByNamespaceNameAndBranch(namespace: string, name: string, branch: string) { + return function (dispatch: any) { + dispatch(fetchChangesetsPending(namespace, name, branch)); + return apiClient.get(REPO_URL + "/" + namespace + "/" + name + "/branches/" + branch + "/changesets").then(response => response.json()) + .then(data => { + dispatch(fetchChangesetsSuccess(data, namespace, name, branch)) + }).catch(cause => { + dispatch(fetchChangesetsFailure(namespace, name, branch, cause)) + }) + } +} + +export function fetchChangesetsPending(namespace: string, name: string, branch?: string): Action { return { type: FETCH_CHANGESETS_PENDING, payload: { namespace, - name + name, + branch }, - itemId: namespace + "/" + name + itemId: createItemId(namespace, name, branch) } } -export function fetchChangesetsSuccess(collection: any, namespace: string, name: string): Action { +export function fetchChangesetsSuccess(collection: any, namespace: string, name: string, branch?: string): Action { return { type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace, name}, - itemId: namespace + "/" + name + payload: {collection, namespace, name, branch}, + itemId: createItemId(namespace, name, branch) } } -function fetchChangesetsFailure(namespace: string, name: string, error: Error): Action { +function fetchChangesetsFailure(namespace: string, name: string, branch?: string, error: Error): Action { return { type: FETCH_CHANGESETS_FAILURE, payload: { namespace, name, + branch, error }, - itemId: namespace + "/" + name + itemId: createItemId(namespace, name, branch) } } +function createItemId(namespace: string, name: string, branch?: string): string { + let itemId = namespace + "/" + name; + if (branch && branch !== "") { + itemId = itemId + "/" + branch; + } + return itemId; +} + // reducer -export default function reducer(state: any = {}, action: any = {}) { +export default function reducer(state: any = {}, action: Action = {type: "UNKNOWN"}): Object { switch (action.type) { case FETCH_CHANGESETS_SUCCESS: const {namespace, name} = action.payload; @@ -90,7 +112,7 @@ function extractChangesetsByIds(data: any, oldChangesetsByIds: any) { } //selectors -export function getChangesetsForNameAndNamespaceFromState(namespace: string, name: string, state: Object) { +export function getChangesetsForNamespaceAndNameFromState(namespace: string, name: string, state: Object) { const key = namespace + "/" + name; if (!state.changesets[key]) { return null; @@ -98,11 +120,19 @@ export function getChangesetsForNameAndNamespaceFromState(namespace: string, nam return Object.values(state.changesets[key].byId); } -export function isFetchChangesetsPending( state: Object, namespace: string, name: string) { - return isPending(state, FETCH_CHANGESETS, namespace + "/" + name) +export function getChangesets(namespace: string, name: string, branch: string, state: Object) { + const key = createItemId(namespace, name, branch); + if (!state.changesets[key]) { + return null; + } + return Object.values(state.changesets[key].byId); } -export function getFetchChangesetsFailure( state: Object, namespace: string, name: string) { - return getFailure(state, FETCH_CHANGESETS, namespace + "/" + name); +export function isFetchChangesetsPending(state: Object, namespace: string, name: string, branch?: string) { + return isPending(state, FETCH_CHANGESETS, createItemId(namespace, name, branch)) +} + +export function getFetchChangesetsFailure(state: Object, namespace: string, name: string, branch?: string) { + return getFailure(state, FETCH_CHANGESETS, createItemId(namespace, name, branch)); } diff --git a/scm-ui/src/changesets/modules/changesets.test.js b/scm-ui/src/changesets/modules/changesets.test.js index c514978144..e206178538 100644 --- a/scm-ui/src/changesets/modules/changesets.test.js +++ b/scm-ui/src/changesets/modules/changesets.test.js @@ -4,95 +4,129 @@ import configureMockStore from "redux-mock-store"; import thunk from "redux-thunk"; import fetchMock from "fetch-mock"; import { - FETCH_CHANGESETS, FETCH_CHANGESETS_FAILURE, + FETCH_CHANGESETS, + FETCH_CHANGESETS_FAILURE, FETCH_CHANGESETS_PENDING, FETCH_CHANGESETS_SUCCESS, fetchChangesetsByNamespaceAndName, - fetchChangesetsSuccess, getChangesetsForNameAndNamespaceFromState, getFetchChangesetsFailure, isFetchChangesetsPending + fetchChangesetsByNamespaceNameAndBranch, + fetchChangesetsSuccess, + getChangesets, + getChangesetsForNamespaceAndNameFromState, + getFetchChangesetsFailure, + isFetchChangesetsPending } from "./changesets"; import reducer from "./changesets"; const collection = {}; -describe("fetching of changesets", () => { - const URL = "/api/rest/v2/repositories/foo/bar/changesets"; - const mockStore = configureMockStore([thunk]); +describe("changesets", () => { + describe("fetching of changesets", () => { + const DEFAULT_BRANCH_URL = "/api/rest/v2/repositories/foo/bar/changesets"; + const SPECIFIC_BRANCH_URL = "/api/rest/v2/repositories/foo/bar/branches/specific/changesets"; + const mockStore = configureMockStore([thunk]); - afterEach(() => { - fetchMock.reset(); - fetchMock.restore(); - }); - - it("should fetch changesets", () => { - fetchMock.getOnce(URL, "{}"); - - const expectedActions = [ - {type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}, - itemId: "foo/bar"}, - { - type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace: "foo", name: "bar"}, - itemId: "foo/bar" - } - ]; - - const store = mockStore({}); - return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { - expect(store.getActions()).toEqual(expectedActions); + afterEach(() => { + fetchMock.reset(); + fetchMock.restore(); }); - }); - it("should fail fetching changesets on error", () => { - fetchMock.getOnce(URL, 500); + it("should fetch changesets for default branch", () => { + fetchMock.getOnce(DEFAULT_BRANCH_URL, "{}"); - const expectedActions = [ - {type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}, - itemId: "foo/bar"}, - { - type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace: "foo", name: "bar"}, - itemId: "foo/bar" - } - ]; + const expectedActions = [ + { + type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}, + itemId: "foo/bar" + }, + { + type: FETCH_CHANGESETS_SUCCESS, + payload: {collection, namespace: "foo", name: "bar"}, + itemId: "foo/bar" + } + ]; - const store = mockStore({}); - return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { - expect(store.getActions()[0]).toEqual(expectedActions[0]); - expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); - expect(store.getActions()[1].payload).toBeDefined(); + const store = mockStore({}); + return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); }); - }) -}); -describe("changesets reducer", () => { - const responseBody = { - _embedded: { - changesets: [ - {id: "changeset1", author: {mail: "z@phod.com", name: "zaphod"}}, - {id: "changeset2", description: "foo"}, - {id: "changeset3", description: "bar"}, - ], - _embedded: { - tags: [], - branches: [], - parents: [] - } - } - }; + it("should fetch changesets for specific branch", () => { + fetchMock.getOnce(SPECIFIC_BRANCH_URL, "{}"); - it("should set state to received changesets", () => { - const newState = reducer({}, fetchChangesetsSuccess(responseBody, "foo", "bar")); - expect(newState).toBeDefined(); - expect(newState["foo/bar"].byId["changeset1"].author.mail).toEqual("z@phod.com"); - expect(newState["foo/bar"].byId["changeset2"].description).toEqual("foo"); - expect(newState["foo/bar"].byId["changeset3"].description).toEqual("bar"); + const expectedActions = [ + { + type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar", branch: "specific"}, + itemId: "foo/bar/specific" + }, + { + type: FETCH_CHANGESETS_SUCCESS, + payload: {collection, namespace: "foo", name: "bar", branch: "specific"}, + itemId: "foo/bar/specific" + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchChangesetsByNamespaceNameAndBranch("foo", "bar", "specific")).then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); + }); + + it("should fail fetching changesets on error", () => { + fetchMock.getOnce(DEFAULT_BRANCH_URL, 500); + + const expectedActions = [ + { + type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}, + itemId: "foo/bar" + }, + { + type: FETCH_CHANGESETS_SUCCESS, + payload: {collection, namespace: "foo", name: "bar"}, + itemId: "foo/bar" + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { + expect(store.getActions()[0]).toEqual(expectedActions[0]); + expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); + expect(store.getActions()[1].payload).toBeDefined(); + }); + }) + + it("should fail fetching changesets for specific branch on error", () => { + fetchMock.getOnce(SPECIFIC_BRANCH_URL, 500); + + const expectedActions = [ + { + type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar", branch: "specific"}, + itemId: "foo/bar/specific" + }, + { + type: FETCH_CHANGESETS_SUCCESS, + payload: {collection, namespace: "foo", name: "bar", branch: "specific"}, + itemId: "foo/bar/specific" + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchChangesetsByNamespaceNameAndBranch("foo", "bar", "specific")).then(() => { + expect(store.getActions()[0]).toEqual(expectedActions[0]); + expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); + expect(store.getActions()[1].payload).toBeDefined(); + }); + }) }); - it("should not delete existing changesets from state", () => { + describe("changesets reducer", () => { const responseBody = { _embedded: { changesets: [ {id: "changeset1", author: {mail: "z@phod.com", name: "zaphod"}}, + {id: "changeset2", description: "foo"}, + {id: "changeset3", description: "bar"}, ], _embedded: { tags: [], @@ -101,65 +135,89 @@ describe("changesets reducer", () => { } } }; - const newState = reducer({ - "foo/bar": { - byId: { - ["changeset2"]: { - id: "changeset2", - author: {mail: "mail@author.com", name: "author"} + + it("should set state to received changesets", () => { + const newState = reducer({}, fetchChangesetsSuccess(responseBody, "foo", "bar")); + expect(newState).toBeDefined(); + expect(newState["foo/bar"].byId["changeset1"].author.mail).toEqual("z@phod.com"); + expect(newState["foo/bar"].byId["changeset2"].description).toEqual("foo"); + expect(newState["foo/bar"].byId["changeset3"].description).toEqual("bar"); + }); + + it("should not delete existing changesets from state", () => { + const responseBody = { + _embedded: { + changesets: [ + {id: "changeset1", author: {mail: "z@phod.com", name: "zaphod"}}, + ], + _embedded: { + tags: [], + branches: [], + parents: [] } } - } - }, fetchChangesetsSuccess(responseBody, "foo", "bar")); - expect(newState["foo/bar"].byId["changeset2"]).toBeDefined(); - expect(newState["foo/bar"].byId["changeset1"]).toBeDefined(); - }) -}); - -describe("changeset selectors", () => { - const error = new Error("Something went wrong"); - - it("should get all changesets for a given namespace and name", () => { - const state = { - changesets: { - ["foo/bar"]: { + }; + const newState = reducer({ + "foo/bar": { byId: { - "id1": {id: "id1"}, - "id2": {id: "id2"} + ["changeset2"]: { + id: "changeset2", + author: {mail: "mail@author.com", name: "author"} + } } } - } - }; - const result = getChangesetsForNameAndNamespaceFromState("foo", "bar", state); - expect(result).toContainEqual({id: "id1"}) + }, fetchChangesetsSuccess(responseBody, "foo", "bar")); + expect(newState["foo/bar"].byId["changeset2"]).toBeDefined(); + expect(newState["foo/bar"].byId["changeset1"]).toBeDefined(); + }) }); - it("should return true, when fetching changesets is pending", () => { - const state = { - pending: { - [FETCH_CHANGESETS + "/foo/bar"]: true - } - }; + describe("changeset selectors", () => { + const error = new Error("Something went wrong"); + + it("should get all changesets for a given namespace and name", () => { + const state = { + changesets: { + ["foo/bar"]: { + byId: { + "id1": {id: "id1"}, + "id2": {id: "id2"} + } + } + } + }; + // const result = getChangesetsForNamespaceAndNameFromState("foo", "bar", state); + const result = getChangesets("foo", "bar", "", state); + expect(result).toContainEqual({id: "id1"}) + }); + + it("should return true, when fetching changesets is pending", () => { + const state = { + pending: { + [FETCH_CHANGESETS + "/foo/bar"]: true + } + }; + + expect(isFetchChangesetsPending(state, "foo", "bar")).toBeTruthy(); + }); + + it("should return false, when fetching changesets is not pending", () => { + expect(isFetchChangesetsPending({}, "foo", "bar")).toEqual(false); + }); + + it("should return error if fetching changesets failed", () => { + const state = { + failure: { + [FETCH_CHANGESETS + "/foo/bar"]: error + } + }; + + expect(getFetchChangesetsFailure(state, "foo", "bar")).toEqual(error); + }); + + it("should return false if fetching changesets did not fail", () => { + expect(getFetchChangesetsFailure({}, "foo", "bar")).toBeUndefined(); + }) - expect(isFetchChangesetsPending(state, "foo", "bar")).toBeTruthy(); }); - - it("should return false, when fetching changesets is not pending", () => { - expect(isFetchChangesetsPending({}, "foo", "bar")).toEqual(false); - }); - - it("should return error if fetching changesets failed", () => { - const state = { - failure: { - [FETCH_CHANGESETS + "/foo/bar"]: error - } - }; - - expect(getFetchChangesetsFailure(state, "foo", "bar")).toEqual(error); - }); - - it("should return false if fetching changesets did not fail", () => { - expect(getFetchChangesetsFailure({}, "foo", "bar")).toBeUndefined(); - }) - }); diff --git a/scm-ui/src/createReduxStore.js b/scm-ui/src/createReduxStore.js index a63a6edcdb..5c4fb20410 100644 --- a/scm-ui/src/createReduxStore.js +++ b/scm-ui/src/createReduxStore.js @@ -15,6 +15,7 @@ import failure from "./modules/failure"; import config from "./config/modules/config"; import type { BrowserHistory } from "history/createBrowserHistory"; +import branches from "./repos/modules/branches"; function createReduxStore(history: BrowserHistory) { const composeEnhancers = @@ -28,6 +29,7 @@ function createReduxStore(history: BrowserHistory) { repos, repositoryTypes, changesets, + branches, groups, auth, config diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index dde5cb379b..4f1624184f 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -50,4 +50,45 @@ export function fetchBranchesFailure(namespace: string, name: string, error: Err // Reducers +export default function reducer(state: Object = {}, action: Action = {type: "UNKNOWN"}): Object { + switch (action.type) { + case FETCH_BRANCHES_SUCCESS: + const key = action.payload.namespace + "/" + action.payload.name; + let oldBranchesByNames = {[key]: {}}; + if (state[key] !== undefined) { + oldBranchesByNames[key] = state[key] + } + return { + [key]: { + byNames: extractBranchesByNames(action.payload.data, oldBranchesByNames[key].byNames) + } + }; + default: + return state; + } + +} + +function extractBranchesByNames(data: any, oldBranchesByNames: any): Branch[] { + const branches = data._embedded.branches; + const branchesByNames = {}; + + for (let branch of branches) { + branchesByNames[branch.name] = branch; + } + + for (let name in oldBranchesByNames) { + branchesByNames[name] = oldBranchesByNames[name] + } + return branchesByNames; +} + // Selectors + +export function getBranchesForNamespaceAndNameFromState(namespace: string, name: string, state: Object) { + const key = namespace + "/" + name; + if (!state.branches[key]) { + return null; + } + return Object.values(state.branches[key].byNames); +} diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index 67c5950c5a..83a6f73b03 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -5,13 +5,25 @@ import { FETCH_BRANCHES_FAILURE, FETCH_BRANCHES_PENDING, FETCH_BRANCHES_SUCCESS, - fetchBranchesByNamespaceAndName + fetchBranchesByNamespaceAndName, getBranchesForNamespaceAndNameFromState } from "./branches"; +import reducer from "./branches"; + + +const namespace = "foo"; +const name = "bar"; +const key = namespace + "/" + name; + +const branch1 = {name: "branch1", revision: "revision1"}; +const branch2 = {name: "branch2", revision: "revision2"}; +const branch3 = {name: "branch3", revision: "revision3"}; + describe("fetch branches", () => { const URL = "/api/rest/v2/repositories/foo/bar/branches"; const mockStore = configureMockStore([thunk]); + afterEach(() => { fetchMock.reset(); fetchMock.restore(); @@ -24,17 +36,19 @@ describe("fetch branches", () => { fetchMock.getOnce(URL, "{}"); const expectedActions = [ - {type: FETCH_BRANCHES_PENDING, payload: {namespace: "foo", name: "bar"}, - itemId: "foo/bar"}, + { + type: FETCH_BRANCHES_PENDING, payload: {namespace, name}, + itemId: key + }, { type: FETCH_BRANCHES_SUCCESS, - payload: {data: collection, namespace: "foo", name: "bar"}, - itemId: "foo/bar" + payload: {data: collection, namespace, name}, + itemId: key } ]; const store = mockStore({}); - return store.dispatch(fetchBranchesByNamespaceAndName("foo", "bar")).then(() => { + return store.dispatch(fetchBranchesByNamespaceAndName(namespace, name)).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); @@ -45,19 +59,75 @@ describe("fetch branches", () => { fetchMock.getOnce(URL, 500); const expectedActions = [ - {type: FETCH_BRANCHES_PENDING, payload: {namespace: "foo", name: "bar"}, - itemId: "foo/bar"}, + { + type: FETCH_BRANCHES_PENDING, payload: {namespace, name}, + itemId: key + }, { type: FETCH_BRANCHES_FAILURE, - payload: {error: collection, namespace: "foo", name: "bar"}, - itemId: "foo/bar" + payload: {error: collection, namespace, name}, + itemId: key } ]; const store = mockStore({}); - return store.dispatch(fetchBranchesByNamespaceAndName("foo", "bar")).then(() => { + return store.dispatch(fetchBranchesByNamespaceAndName(namespace, name)).then(() => { expect(store.getActions()[0]).toEqual(expectedActions[0]); expect(store.getActions()[1].type).toEqual(FETCH_BRANCHES_FAILURE); }); }) }); + +describe("branches reducer", () => { + + const branches = { + _embedded: { + branches: [branch1, branch2] + } + }; + const action = { + type: FETCH_BRANCHES_SUCCESS, + payload: { + namespace, + name, + data: branches + } + }; + + it("should update state according to successful fetch", () => { + const newState = reducer({}, action); + expect(newState).toBeDefined(); + expect(newState[key]).toBeDefined(); + expect(newState[key].byNames["branch1"]).toEqual(branch1); + expect(newState[key].byNames["branch2"]).toEqual(branch2); + }); + + it("should not delete existing branches from state", () => { + const oldState = { + "foo/bar": { byNames: { + "branch3": branch3 + }} + }; + + const newState = reducer(oldState, action); + console.log(newState); + expect(newState[key].byNames["branch1"]).toEqual(branch1); + expect(newState[key].byNames["branch2"]).toEqual(branch2); + expect(newState[key].byNames["branch3"]).toEqual(branch3); + }); +}); + +describe("branch selectors", () => { + it("should get branches for namespace and name", () => { + const state = { + branches: { + [key]: { + byNames: { + "branch1": branch1 + } + } + } + }; + getBranchesForNamespaceAndNameFromState(namespace, name, state); + }) +}); From 2931877c9ff1889861c3dafc0ea2753a892dc42e Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 17 Sep 2018 14:01:51 +0200 Subject: [PATCH 006/121] Added DropDown.js --- scm-ui/src/changesets/components/DropDown.js | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 scm-ui/src/changesets/components/DropDown.js diff --git a/scm-ui/src/changesets/components/DropDown.js b/scm-ui/src/changesets/components/DropDown.js new file mode 100644 index 0000000000..28d3ef28f0 --- /dev/null +++ b/scm-ui/src/changesets/components/DropDown.js @@ -0,0 +1,25 @@ +// @flow + +import React from "react"; + +type Props = { + options: string[], + optionSelected: string => void +} + +class DropDown extends React.Component { + render() { + const {options} = this.props; + return + } + + change = (event) => { + this.props.optionSelected(event.target.value); + } +} + +export default DropDown; From 4cb644f9f8aee2f23e04affb665979b210ef52e8 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 17 Sep 2018 14:03:13 +0200 Subject: [PATCH 007/121] Restructured Changeset Component WIP --- .../changesets/components/ChangesetTable.js | 28 ++++++ .../src/changesets/components/Changesets.js | 65 -------------- .../src/changesets/containers/Changesets.js | 85 +++++++++++++++++++ scm-ui/src/changesets/modules/changesets.js | 8 +- .../src/repos/components/RepositoryDetails.js | 2 - scm-ui/src/repos/containers/RepositoryRoot.js | 35 ++++---- scm-ui/src/repos/modules/branches.js | 8 ++ scm-ui/src/repos/modules/branches.test.js | 25 +++++- 8 files changed, 167 insertions(+), 89 deletions(-) create mode 100644 scm-ui/src/changesets/components/ChangesetTable.js delete mode 100644 scm-ui/src/changesets/components/Changesets.js create mode 100644 scm-ui/src/changesets/containers/Changesets.js diff --git a/scm-ui/src/changesets/components/ChangesetTable.js b/scm-ui/src/changesets/components/ChangesetTable.js new file mode 100644 index 0000000000..29260bdc32 --- /dev/null +++ b/scm-ui/src/changesets/components/ChangesetTable.js @@ -0,0 +1,28 @@ +// @flow +import ChangesetRow from "./ChangesetRow"; +import React from "react"; + +type Props = { + changesets: Changeset[] +} + +class ChangesetTable extends React.Component { + + render() { + const {changesets} = this.props; + return
Changesets
+ + + + + + + {changesets.map((changeset, index) => { + return ; + })} + +
Changesets
+ } +} + +export default ChangesetTable; diff --git a/scm-ui/src/changesets/components/Changesets.js b/scm-ui/src/changesets/components/Changesets.js deleted file mode 100644 index f9feb51829..0000000000 --- a/scm-ui/src/changesets/components/Changesets.js +++ /dev/null @@ -1,65 +0,0 @@ -import React from "react" -import { connect } from "react-redux"; -import ChangesetRow from "./ChangesetRow"; -import type {Changeset} from "@scm-manager/ui-types"; - -import { - fetchChangesetsByNamespaceAndName, - getChangesets, -} from "../modules/changesets"; -import { translate } from "react-i18next"; -import {fetchBranchesByNamespaceAndName} from "../../repos/modules/branches"; - -type Props = { - changesets: Changeset[], - t: string => string -} - -class Changesets extends React.Component { - componentDidMount() { - const {namespace, name} = this.props.repository; - this.props.fetchChangesetsByNamespaceAndName(namespace, name); - this.props.fetchBranchesByNamespaceAndName(namespace, name); - } - - render() { - const { t, changesets } = this.props; - if (!changesets) { - return null; - } - return - - - - - {changesets.map((changeset, index) => { - return ; - })} - -
Changesets
- } -} - -const mapStateToProps = (state, ownProps) => { - const {namespace, name} = ownProps.repository; - return { - changesets: getChangesets(namespace, name, "", state) - } -}; - -const mapDispatchToProps = dispatch => { - return { - fetchChangesetsByNamespaceAndName: (namespace: string, name: string) => { - dispatch(fetchChangesetsByNamespaceAndName(namespace, name)); - }, - - fetchBranchesByNamespaceAndName: (namespace: string, name: string) => { - dispatch(fetchBranchesByNamespaceAndName(namespace, name)); - } - } -}; - -export default connect( - mapStateToProps, - mapDispatchToProps -)(translate("changesets")(Changesets)); diff --git a/scm-ui/src/changesets/containers/Changesets.js b/scm-ui/src/changesets/containers/Changesets.js new file mode 100644 index 0000000000..2cc64f8bb5 --- /dev/null +++ b/scm-ui/src/changesets/containers/Changesets.js @@ -0,0 +1,85 @@ +import React from "react" +import {connect} from "react-redux"; + +import { + fetchChangesetsByNamespaceAndName, fetchChangesetsByNamespaceNameAndBranch, + getChangesets, +} from "../modules/changesets"; +import {translate} from "react-i18next"; +import {fetchBranchesByNamespaceAndName, getBranchNames} from "../../repos/modules/branches"; +import type {Repository} from "@scm-manager/ui-types"; +import ChangesetTable from "../components/ChangesetTable"; +import DropDown from "../components/DropDown"; + +type Props = { + repository: Repository, + branchName: string, + history: History, + fetchChangesetsByNamespaceNameAndBranch: (namespace: string, name: string, branch: string) => void +} + +type State = { + branchName: string +} + +class Changesets extends React.Component { + constructor(props) { + super(props); + this.state = {}; + } + + componentDidMount() { + const {namespace, name} = this.props.repository; + this.props.fetchChangesetsByNamespaceNameAndBranch(namespace, name, this.props.branchName); + this.props.fetchBranchesByNamespaceAndName(namespace, name); + } + + render() { + const {changesets, branchNames} = this.props; + if (changesets === null) { + return null + } + if (branchNames) { + return
+ + +
; + } else { + return + } + + } + + branchChanged = (branchName: string) => { + this.props.history.push("./history/" + branchName) + }; +} + + +const mapStateToProps = (state, ownProps: Props) => { + console.log("mapStateToProps ownProps: ", ownProps); + const {namespace, name} = ownProps.repository; + return { + changesets: getChangesets(namespace, name, ownProps.branchName, state), + branchNames: getBranchNames(namespace, name, state) + } +}; + +const mapDispatchToProps = dispatch => { + return { + fetchChangesetsByNamespaceAndName: (namespace: string, name: string) => { + dispatch(fetchChangesetsByNamespaceAndName(namespace, name)); + }, + fetchChangesetsByNamespaceNameAndBranch: (namespace: string, name: string, branch: string) => { + dispatch(fetchChangesetsByNamespaceNameAndBranch(namespace, name, branch)); + }, + fetchBranchesByNamespaceAndName: (namespace: string, name: string) => { + dispatch(fetchBranchesByNamespaceAndName(namespace, name)); + } + } +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(Changesets); diff --git a/scm-ui/src/changesets/modules/changesets.js b/scm-ui/src/changesets/modules/changesets.js index d77a1423aa..cd35801a2f 100644 --- a/scm-ui/src/changesets/modules/changesets.js +++ b/scm-ui/src/changesets/modules/changesets.js @@ -83,14 +83,13 @@ function createItemId(namespace: string, name: string, branch?: string): string export default function reducer(state: any = {}, action: Action = {type: "UNKNOWN"}): Object { switch (action.type) { case FETCH_CHANGESETS_SUCCESS: - const {namespace, name} = action.payload; - const key = namespace + "/" + name; - + const {namespace, name, branch} = action.payload; + const key = createItemId(namespace, name, branch); let oldChangesets = {[key]: {}}; if (state[key] !== undefined) { oldChangesets[key] = state[key] } - return {[key]: {byId: extractChangesetsByIds(action.payload.collection, oldChangesets[key].byId)}}; + return {...state, [key]: {byId: extractChangesetsByIds(action.payload.collection, oldChangesets[key].byId)}}; default: return state; } @@ -122,6 +121,7 @@ export function getChangesetsForNamespaceAndNameFromState(namespace: string, nam export function getChangesets(namespace: string, name: string, branch: string, state: Object) { const key = createItemId(namespace, name, branch); + console.log("getChangesets for key " + key); if (!state.changesets[key]) { return null; } diff --git a/scm-ui/src/repos/components/RepositoryDetails.js b/scm-ui/src/repos/components/RepositoryDetails.js index 33edaff541..99c88fec94 100644 --- a/scm-ui/src/repos/components/RepositoryDetails.js +++ b/scm-ui/src/repos/components/RepositoryDetails.js @@ -3,7 +3,6 @@ import React from "react"; import type { Repository } from "@scm-manager/ui-types"; import RepositoryDetailTable from "./RepositoryDetailTable"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; -import Changesets from "../../changesets/components/Changesets"; type Props = { repository: Repository @@ -21,7 +20,6 @@ class RepositoryDetails extends React.Component { renderAll={true} props={{ repository }} /> - ); diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index 2816cdb5c5..0f6f6ada20 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -7,9 +7,9 @@ import { getRepository, isFetchRepoPending } from "../modules/repos"; -import { connect } from "react-redux"; -import { Route } from "react-router-dom"; -import type { Repository } from "@scm-manager/ui-types"; +import {connect} from "react-redux"; +import {Route} from "react-router-dom"; +import type {Repository} from "@scm-manager/ui-types"; import { Page, Loading, @@ -18,13 +18,14 @@ import { NavLink, Section } from "@scm-manager/ui-components"; -import { translate } from "react-i18next"; +import {translate} from "react-i18next"; import RepositoryDetails from "../components/RepositoryDetails"; import DeleteNavAction from "../components/DeleteNavAction"; import Edit from "../containers/Edit"; -import type { History } from "history"; +import type {History} from "history"; import EditNavLink from "../components/EditNavLink"; +import Changesets from "../../changesets/containers/Changesets"; type Props = { namespace: string, @@ -45,7 +46,7 @@ type Props = { class RepositoryRoot extends React.Component { componentDidMount() { - const { fetchRepo, namespace, name } = this.props; + const {fetchRepo, namespace, name} = this.props; fetchRepo(namespace, name); } @@ -70,7 +71,7 @@ class RepositoryRoot extends React.Component { }; render() { - const { loading, error, repository, t } = this.props; + const {loading, error, repository, t} = this.props; if (error) { return ( @@ -83,7 +84,7 @@ class RepositoryRoot extends React.Component { } if (!repository || loading) { - return ; + return ; } const url = this.matchedUrl(); @@ -95,22 +96,26 @@ class RepositoryRoot extends React.Component { } + component={() => } /> } + component={() => } + /> + } />
- - + +
- - + +
@@ -121,7 +126,7 @@ class RepositoryRoot extends React.Component { } const mapStateToProps = (state, ownProps) => { - const { namespace, name } = ownProps.match.params; + const {namespace, name} = ownProps.match.params; const repository = getRepository(state, namespace, name); const loading = isFetchRepoPending(state, namespace, name); const error = getFetchRepoFailure(state, namespace, name); diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 4f1624184f..fb1b222aa9 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -92,3 +92,11 @@ export function getBranchesForNamespaceAndNameFromState(namespace: string, name: } return Object.values(state.branches[key].byNames); } + +export function getBranchNames(namespace: string, name: string, state: Object) { + const key = namespace + "/" + name; + if (!state.branches[key]) { + return null; + } + return Object.keys(state.branches[key].byNames); +} diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index 83a6f73b03..d97d9aa7bf 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -5,7 +5,7 @@ import { FETCH_BRANCHES_FAILURE, FETCH_BRANCHES_PENDING, FETCH_BRANCHES_SUCCESS, - fetchBranchesByNamespaceAndName, getBranchesForNamespaceAndNameFromState + fetchBranchesByNamespaceAndName, getBranchesForNamespaceAndNameFromState, getBranchNames } from "./branches"; import reducer from "./branches"; @@ -128,6 +128,25 @@ describe("branch selectors", () => { } } }; - getBranchesForNamespaceAndNameFromState(namespace, name, state); - }) + const branches = getBranchesForNamespaceAndNameFromState(namespace, name, state); + expect(branches.length).toEqual(1); + expect(branches[0]).toEqual(branch1); + }); + + it("should return branches names", () => { + const state = { + branches: { + [key]: { + byNames: { + "branch1": branch1, + "branch2": branch2 + } + } + } + }; + const names = getBranchNames(namespace, name, state); + expect(names.length).toEqual(2); + expect(names).toContain("branch1"); + expect(names).toContain("branch2"); + }); }); From 2be854e3d2bdfb4cff2a68d8f85a6fe50b499c65 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 17 Sep 2018 14:16:43 +0200 Subject: [PATCH 008/121] Don't push /history-prefix to path WIP --- scm-ui/src/changesets/containers/Changesets.js | 2 +- scm-ui/src/repos/containers/RepositoryRoot.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scm-ui/src/changesets/containers/Changesets.js b/scm-ui/src/changesets/containers/Changesets.js index 2cc64f8bb5..a197ae293d 100644 --- a/scm-ui/src/changesets/containers/Changesets.js +++ b/scm-ui/src/changesets/containers/Changesets.js @@ -51,7 +51,7 @@ class Changesets extends React.Component { } branchChanged = (branchName: string) => { - this.props.history.push("./history/" + branchName) + this.props.history.push(branchName) }; } diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index 0f6f6ada20..7c8bae308f 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -106,6 +106,10 @@ class RepositoryRoot extends React.Component { path={`${url}/history`} component={() => } /> + {/* }*/} + {/*/>*/}
From c5da25a1b435122e9b6363e39cac1a228bb5f96d Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 17 Sep 2018 16:31:19 +0200 Subject: [PATCH 009/121] Determine branch for which to show changesets via URL --- scm-ui/src/changesets/components/DropDown.js | 10 ++++--- .../src/changesets/containers/Changesets.js | 29 +++++++++++-------- scm-ui/src/repos/containers/RepositoryRoot.js | 8 ++--- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/scm-ui/src/changesets/components/DropDown.js b/scm-ui/src/changesets/components/DropDown.js index 28d3ef28f0..8d73ea4fa5 100644 --- a/scm-ui/src/changesets/components/DropDown.js +++ b/scm-ui/src/changesets/components/DropDown.js @@ -4,15 +4,17 @@ import React from "react"; type Props = { options: string[], - optionSelected: string => void + optionSelected: string => void, + preselectedOption: string } class DropDown extends React.Component { render() { - const {options} = this.props; - return {options.map(option => { - return + return })} } diff --git a/scm-ui/src/changesets/containers/Changesets.js b/scm-ui/src/changesets/containers/Changesets.js index a197ae293d..48e95dd5d6 100644 --- a/scm-ui/src/changesets/containers/Changesets.js +++ b/scm-ui/src/changesets/containers/Changesets.js @@ -5,11 +5,12 @@ import { fetchChangesetsByNamespaceAndName, fetchChangesetsByNamespaceNameAndBranch, getChangesets, } from "../modules/changesets"; -import {translate} from "react-i18next"; +import type { History } from "history"; import {fetchBranchesByNamespaceAndName, getBranchNames} from "../../repos/modules/branches"; import type {Repository} from "@scm-manager/ui-types"; import ChangesetTable from "../components/ChangesetTable"; import DropDown from "../components/DropDown"; +import {withRouter} from "react-router-dom"; type Props = { repository: Repository, @@ -18,30 +19,34 @@ type Props = { fetchChangesetsByNamespaceNameAndBranch: (namespace: string, name: string, branch: string) => void } -type State = { - branchName: string -} class Changesets extends React.Component { constructor(props) { super(props); - this.state = {}; + this.state = { + }; } componentDidMount() { const {namespace, name} = this.props.repository; - this.props.fetchChangesetsByNamespaceNameAndBranch(namespace, name, this.props.branchName); + const branchName = this.props.match.params.branch; + if (branchName) { + this.props.fetchChangesetsByNamespaceNameAndBranch(namespace, name, branchName); + } else { + this.props.fetchChangesetsByNamespaceAndName(namespace, name); + } this.props.fetchBranchesByNamespaceAndName(namespace, name); } render() { const {changesets, branchNames} = this.props; + const branch = this.props.match.params.branch; if (changesets === null) { return null } if (branchNames) { return
- + this.branchChanged(branch)}/>
; } else { @@ -51,16 +56,16 @@ class Changesets extends React.Component { } branchChanged = (branchName: string) => { - this.props.history.push(branchName) + const { history, repository } = this.props; + history.push(`/repo/${repository.namespace}/${repository.name}/history/${branchName}`); }; } const mapStateToProps = (state, ownProps: Props) => { - console.log("mapStateToProps ownProps: ", ownProps); const {namespace, name} = ownProps.repository; return { - changesets: getChangesets(namespace, name, ownProps.branchName, state), + changesets: getChangesets(namespace, name, ownProps.match.params.branch, state), branchNames: getBranchNames(namespace, name, state) } }; @@ -79,7 +84,7 @@ const mapDispatchToProps = dispatch => { } }; -export default connect( +export default withRouter(connect( mapStateToProps, mapDispatchToProps -)(Changesets); +)(Changesets)); diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index 7c8bae308f..75a938279c 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -103,13 +103,9 @@ class RepositoryRoot extends React.Component { component={() => } /> } + path={`${url}/history/:branch`} + component={() => } /> - {/* }*/} - {/*/>*/}
From 2af345bba0c767d49c62aad2af745332b954f237 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 17 Sep 2018 16:51:09 +0200 Subject: [PATCH 010/121] Added navigational link to repo's history --- scm-ui/public/locales/en/repos.json | 3 ++- scm-ui/src/changesets/components/DropDown.js | 1 + scm-ui/src/changesets/modules/changesets.js | 3 +-- scm-ui/src/repos/containers/RepositoryRoot.js | 7 +++++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/scm-ui/public/locales/en/repos.json b/scm-ui/public/locales/en/repos.json index 7db2623247..678a7a07b4 100644 --- a/scm-ui/public/locales/en/repos.json +++ b/scm-ui/public/locales/en/repos.json @@ -22,7 +22,8 @@ "actions-label": "Actions", "back-label": "Back", "navigation-label": "Navigation", - "information": "Information" + "information": "Information", + "history": "History" }, "create": { "title": "Create Repository", diff --git a/scm-ui/src/changesets/components/DropDown.js b/scm-ui/src/changesets/components/DropDown.js index 8d73ea4fa5..c045df4af4 100644 --- a/scm-ui/src/changesets/components/DropDown.js +++ b/scm-ui/src/changesets/components/DropDown.js @@ -12,6 +12,7 @@ class DropDown extends React.Component { render() { const {options, preselectedOption} = this.props; return - + return
+ +
} change = (event) => { From 732a84bb7cf2d068dc64783063ac56fd5cb10909 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Tue, 18 Sep 2018 15:07:30 +0200 Subject: [PATCH 017/121] Fixed hiding of branch drop down when there are no branches --- .../changesets/components/ChangesetTable.js | 26 ++++++++++--------- .../src/changesets/containers/Changesets.js | 13 +++++----- scm-ui/src/repos/modules/branches.js | 2 +- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/scm-ui/src/changesets/components/ChangesetTable.js b/scm-ui/src/changesets/components/ChangesetTable.js index 29260bdc32..0658e213e3 100644 --- a/scm-ui/src/changesets/components/ChangesetTable.js +++ b/scm-ui/src/changesets/components/ChangesetTable.js @@ -10,18 +10,20 @@ class ChangesetTable extends React.Component { render() { const {changesets} = this.props; - return - - - - - - - {changesets.map((changeset, index) => { - return ; - })} - -
Changesets
+ return
+ + + + + + + + {changesets.map((changeset, index) => { + return ; + })} + +
Changesets
+
} } diff --git a/scm-ui/src/changesets/containers/Changesets.js b/scm-ui/src/changesets/containers/Changesets.js index 64b56fa559..592cc6d9e5 100644 --- a/scm-ui/src/changesets/containers/Changesets.js +++ b/scm-ui/src/changesets/containers/Changesets.js @@ -30,18 +30,19 @@ class Changesets extends React.Component { componentDidMount() { const {namespace, name} = this.props.repository; const branchName = this.props.match.params.branch; + const {fetchChangesetsByNamespaceNameAndBranch, fetchChangesetsByNamespaceAndName, fetchBranchesByNamespaceAndName} = this.props; if (branchName) { - this.props.fetchChangesetsByNamespaceNameAndBranch(namespace, name, branchName); + fetchChangesetsByNamespaceNameAndBranch(namespace, name, branchName); } else { - this.props.fetchChangesetsByNamespaceAndName(namespace, name); + fetchChangesetsByNamespaceAndName(namespace, name); } - this.props.fetchBranchesByNamespaceAndName(namespace, name); + fetchBranchesByNamespaceAndName(namespace, name); } render() { const {changesets, loading, error} = this.props; if (loading || !changesets) { - return + return } return
@@ -54,9 +55,9 @@ class Changesets extends React.Component { const branch = this.props.match.params.branch; const {changesets, branchNames} = this.props; - if (branchNames) { + if (branchNames && branchNames.length > 0) { return
- Branch: this.branchChanged(branch)}/>
; diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index fb1b222aa9..82c8940df4 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -95,7 +95,7 @@ export function getBranchesForNamespaceAndNameFromState(namespace: string, name: export function getBranchNames(namespace: string, name: string, state: Object) { const key = namespace + "/" + name; - if (!state.branches[key]) { + if (!state.branches[key] || !state.branches[key].byNames) { return null; } return Object.keys(state.branches[key].byNames); From a56dab4d8a521f3ac84b40d0f8dd261fbc78580e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 18 Sep 2018 15:19:01 +0200 Subject: [PATCH 018/121] Fix edit link for repositories in list view --- scm-ui/src/repos/components/list/RepositoryEntry.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scm-ui/src/repos/components/list/RepositoryEntry.js b/scm-ui/src/repos/components/list/RepositoryEntry.js index c28bc6b1dd..bc170144aa 100644 --- a/scm-ui/src/repos/components/list/RepositoryEntry.js +++ b/scm-ui/src/repos/components/list/RepositoryEntry.js @@ -67,10 +67,7 @@ class RepositoryEntry extends React.Component { renderModifyLink = (repository: Repository, repositoryLink: string) => { if (repository._links["update"]) { return ( - + ); } return null; From f75ede4bf03f4010025d5fe24e07857cdeb0b229 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Tue, 18 Sep 2018 16:30:37 +0200 Subject: [PATCH 019/121] Restructured changeset module --- scm-ui/src/changesets/modules/changesets.js | 18 ++++------ .../src/changesets/modules/changesets.test.js | 35 ++++++++----------- 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/scm-ui/src/changesets/modules/changesets.js b/scm-ui/src/changesets/modules/changesets.js index 161f03d48f..6423dca515 100644 --- a/scm-ui/src/changesets/modules/changesets.js +++ b/scm-ui/src/changesets/modules/changesets.js @@ -39,21 +39,18 @@ export function fetchChangesetsByNamespaceNameAndBranch(namespace: string, name: } export function fetchChangesetsPending(namespace: string, name: string, branch?: string): Action { + const itemId = createItemId(namespace, name, branch); return { type: FETCH_CHANGESETS_PENDING, - payload: { - namespace, - name, - branch - }, - itemId: createItemId(namespace, name, branch) + payload: itemId, + itemId } } -export function fetchChangesetsSuccess(collection: any, namespace: string, name: string, branch?: string): Action { +export function fetchChangesetsSuccess(changesets: any, namespace: string, name: string, branch?: string): Action { return { type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace, name, branch}, + payload: changesets, itemId: createItemId(namespace, name, branch) } } @@ -83,13 +80,12 @@ function createItemId(namespace: string, name: string, branch?: string): string export default function reducer(state: any = {}, action: Action = {type: "UNKNOWN"}): Object { switch (action.type) { case FETCH_CHANGESETS_SUCCESS: - const {namespace, name, branch} = action.payload; - const key = createItemId(namespace, name, branch); + const key = action.itemId let oldChangesets = {[key]: {}}; if (state[key] !== undefined) { oldChangesets[key] = state[key] } - return {...state, [key]: {byId: extractChangesetsByIds(action.payload.collection, oldChangesets[key].byId)}}; + return {...state, [key]: {byId: extractChangesetsByIds(action.payload, oldChangesets[key].byId)}}; default: return state; } diff --git a/scm-ui/src/changesets/modules/changesets.test.js b/scm-ui/src/changesets/modules/changesets.test.js index fad8d8a6a8..c74eee3975 100644 --- a/scm-ui/src/changesets/modules/changesets.test.js +++ b/scm-ui/src/changesets/modules/changesets.test.js @@ -17,7 +17,7 @@ import { } from "./changesets"; import reducer from "./changesets"; -const collection = {}; +const changesets = {}; describe("changesets", () => { describe("fetching of changesets", () => { @@ -35,12 +35,12 @@ describe("changesets", () => { const expectedActions = [ { - type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}, + type: FETCH_CHANGESETS_PENDING, payload: "foo/bar", itemId: "foo/bar" }, { type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace: "foo", name: "bar"}, + payload: changesets, itemId: "foo/bar" } ]; @@ -52,17 +52,18 @@ describe("changesets", () => { }); it("should fetch changesets for specific branch", () => { + const itemId = "foo/bar/specific"; fetchMock.getOnce(SPECIFIC_BRANCH_URL, "{}"); const expectedActions = [ { - type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar", branch: "specific"}, - itemId: "foo/bar/specific" + type: FETCH_CHANGESETS_PENDING, payload: itemId, + itemId }, { type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace: "foo", name: "bar", branch: "specific"}, - itemId: "foo/bar/specific" + payload: changesets, + itemId } ]; @@ -73,17 +74,13 @@ describe("changesets", () => { }); it("should fail fetching changesets on error", () => { + const itemId = "foo/bar"; fetchMock.getOnce(DEFAULT_BRANCH_URL, 500); const expectedActions = [ { - type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar"}, - itemId: "foo/bar" - }, - { - type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace: "foo", name: "bar"}, - itemId: "foo/bar" + type: FETCH_CHANGESETS_PENDING, payload: itemId, + itemId } ]; @@ -96,17 +93,13 @@ describe("changesets", () => { }) it("should fail fetching changesets for specific branch on error", () => { + const itemId = "foo/bar/specific"; fetchMock.getOnce(SPECIFIC_BRANCH_URL, 500); const expectedActions = [ { - type: FETCH_CHANGESETS_PENDING, payload: {namespace: "foo", name: "bar", branch: "specific"}, - itemId: "foo/bar/specific" - }, - { - type: FETCH_CHANGESETS_SUCCESS, - payload: {collection, namespace: "foo", name: "bar", branch: "specific"}, - itemId: "foo/bar/specific" + type: FETCH_CHANGESETS_PENDING, payload: itemId, + itemId } ]; From 5c376e1c000fe70abf7ee2f9f4c4b55203b0977f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 18 Sep 2018 16:43:55 +0200 Subject: [PATCH 020/121] Fix history link for repositories in list view --- scm-ui/src/repos/components/list/RepositoryEntry.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scm-ui/src/repos/components/list/RepositoryEntry.js b/scm-ui/src/repos/components/list/RepositoryEntry.js index bc170144aa..ef1df0d3d9 100644 --- a/scm-ui/src/repos/components/list/RepositoryEntry.js +++ b/scm-ui/src/repos/components/list/RepositoryEntry.js @@ -1,9 +1,9 @@ //@flow import React from "react"; -import { Link } from "react-router-dom"; +import {Link} from "react-router-dom"; import injectSheet from "react-jss"; -import type { Repository } from "@scm-manager/ui-types"; -import { DateFromNow } from "@scm-manager/ui-components"; +import type {Repository} from "@scm-manager/ui-types"; +import {DateFromNow} from "@scm-manager/ui-components"; import RepositoryEntryLink from "./RepositoryEntryLink"; import classNames from "classnames"; import RepositoryAvatar from "./RepositoryAvatar"; @@ -45,7 +45,7 @@ class RepositoryEntry extends React.Component { return ( ); } From 03bfb92ec72929e2691260984570d95e8251a825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 18 Sep 2018 16:45:22 +0200 Subject: [PATCH 021/121] Change changeset list from table to simple divs --- .../changesets/components/ChangesetAvatar.js | 28 ++++++++ .../src/changesets/components/ChangesetRow.js | 71 ++++++++++++++----- .../changesets/components/ChangesetTable.js | 29 ++++---- 3 files changed, 93 insertions(+), 35 deletions(-) create mode 100644 scm-ui/src/changesets/components/ChangesetAvatar.js diff --git a/scm-ui/src/changesets/components/ChangesetAvatar.js b/scm-ui/src/changesets/components/ChangesetAvatar.js new file mode 100644 index 0000000000..eb461d374d --- /dev/null +++ b/scm-ui/src/changesets/components/ChangesetAvatar.js @@ -0,0 +1,28 @@ +//@flow +import React from "react"; +import {ExtensionPoint} from "@scm-manager/ui-extensions"; +import type {Changeset} from "@scm-manager/ui-types"; +import {Image} from "@scm-manager/ui-components"; + +type Props = { + changeset: Changeset +}; + +class ChangesetAvatar extends React.Component { + render() { + const { changeset } = this.props; + return ( +

+ + Logo + +

+ ); + } +} + +export default ChangesetAvatar; diff --git a/scm-ui/src/changesets/components/ChangesetRow.js b/scm-ui/src/changesets/components/ChangesetRow.js index d0be206866..ac6d4ef143 100644 --- a/scm-ui/src/changesets/components/ChangesetRow.js +++ b/scm-ui/src/changesets/components/ChangesetRow.js @@ -1,28 +1,63 @@ -import React from "react" -import type { Changeset } from "@scm-manager/ui-types" -import {ExtensionPoint} from "@scm-manager/ui-extensions"; +//@flow +import React from "react"; +import type { Changeset } from "@scm-manager/ui-types"; +import classNames from "classnames"; +import { Link } from "react-router-dom"; +import ChangesetAvatar from "./ChangesetAvatar"; +import injectSheet from "react-jss"; + +const styles = { + pointer: { + cursor: "pointer" + }, + changesetGroup: { + marginBottom: "1em" + } +}; type Props = { - changeset: Changeset -} + changeset: Changeset, + classes: any +}; class ChangesetRow extends React.Component { + createLink = (changeset: Changeset) => { + return `/repo/${changeset.description}/changeset/${changeset.id}`; + }; render() { - const { changeset } = this.props; + const { changeset, classes } = this.props; + const changesetLink = this.createLink(changeset); // todo: i18n - return - - -

{changeset.description}

-

Changeset { changeset.id } commited at { changeset.date }

-

{changeset.author.name} <{changeset.author.mail}>

- + return ( +
+ + +
+ ); } } -export default ChangesetRow; +export default injectSheet(styles)(ChangesetRow); diff --git a/scm-ui/src/changesets/components/ChangesetTable.js b/scm-ui/src/changesets/components/ChangesetTable.js index 0658e213e3..26895c0324 100644 --- a/scm-ui/src/changesets/components/ChangesetTable.js +++ b/scm-ui/src/changesets/components/ChangesetTable.js @@ -1,29 +1,24 @@ // @flow import ChangesetRow from "./ChangesetRow"; import React from "react"; +import type {Changeset} from "@scm-manager/ui-types"; type Props = { changesets: Changeset[] -} +}; class ChangesetTable extends React.Component { - render() { - const {changesets} = this.props; - return
- - - - - - - - {changesets.map((changeset, index) => { - return ; - })} - -
Changesets
-
+ const { changesets } = this.props; + const content = changesets.map((changeset, index) => { + return ; + }); + return ( +
+
+ {content} +
+ ); } } From dc59d1a5ce07339eb7f4727e78318ee71df53bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 18 Sep 2018 16:51:31 +0200 Subject: [PATCH 022/121] Move
to correct file --- .../changesets/components/ChangesetTable.js | 7 +- .../src/changesets/containers/Changesets.js | 125 ++++++++++++------ 2 files changed, 83 insertions(+), 49 deletions(-) diff --git a/scm-ui/src/changesets/components/ChangesetTable.js b/scm-ui/src/changesets/components/ChangesetTable.js index 26895c0324..2dd0d1b955 100644 --- a/scm-ui/src/changesets/components/ChangesetTable.js +++ b/scm-ui/src/changesets/components/ChangesetTable.js @@ -13,12 +13,7 @@ class ChangesetTable extends React.Component { const content = changesets.map((changeset, index) => { return ; }); - return ( -
-
- {content} -
- ); + return
{content}
; } } diff --git a/scm-ui/src/changesets/containers/Changesets.js b/scm-ui/src/changesets/containers/Changesets.js index 592cc6d9e5..09410e91c0 100644 --- a/scm-ui/src/changesets/containers/Changesets.js +++ b/scm-ui/src/changesets/containers/Changesets.js @@ -1,25 +1,34 @@ -import React from "react" -import {connect} from "react-redux"; -import {ErrorNotification, Loading} from "@scm-manager/ui-components"; +import React from "react"; +import { connect } from "react-redux"; +import { ErrorNotification, Loading } from "@scm-manager/ui-components"; import { - fetchChangesetsByNamespaceAndName, fetchChangesetsByNamespaceNameAndBranch, - getChangesets, getFetchChangesetsFailure, isFetchChangesetsPending, + fetchChangesetsByNamespaceAndName, + fetchChangesetsByNamespaceNameAndBranch, + getChangesets, + getFetchChangesetsFailure, + isFetchChangesetsPending } from "../modules/changesets"; -import type {History} from "history"; -import {fetchBranchesByNamespaceAndName, getBranchNames} from "../../repos/modules/branches"; -import type {Repository} from "@scm-manager/ui-types"; +import type { History } from "history"; +import { + fetchBranchesByNamespaceAndName, + getBranchNames +} from "../../repos/modules/branches"; +import type { Repository } from "@scm-manager/ui-types"; import ChangesetTable from "../components/ChangesetTable"; import DropDown from "../components/DropDown"; -import {withRouter} from "react-router-dom"; +import { withRouter } from "react-router-dom"; type Props = { repository: Repository, branchName: string, history: History, - fetchChangesetsByNamespaceNameAndBranch: (namespace: string, name: string, branch: string) => void -} - + fetchChangesetsByNamespaceNameAndBranch: ( + namespace: string, + name: string, + branch: string + ) => void +}; class Changesets extends React.Component { constructor(props) { @@ -28,9 +37,13 @@ class Changesets extends React.Component { } componentDidMount() { - const {namespace, name} = this.props.repository; + const { namespace, name } = this.props.repository; const branchName = this.props.match.params.branch; - const {fetchChangesetsByNamespaceNameAndBranch, fetchChangesetsByNamespaceAndName, fetchBranchesByNamespaceAndName} = this.props; + const { + fetchChangesetsByNamespaceNameAndBranch, + fetchChangesetsByNamespaceAndName, + fetchBranchesByNamespaceAndName + } = this.props; if (branchName) { fetchChangesetsByNamespaceNameAndBranch(namespace, name, branchName); } else { @@ -40,48 +53,66 @@ class Changesets extends React.Component { } render() { - const {changesets, loading, error} = this.props; + const { changesets, loading, error } = this.props; if (loading || !changesets) { - return + return ; } - return
- - {this.renderContent()} -
- + return ( +
+ + {this.renderContent()} +
+ ); } renderContent = () => { const branch = this.props.match.params.branch; - const {changesets, branchNames} = this.props; + const { changesets, branchNames } = this.props; if (branchNames && branchNames.length > 0) { - return
- this.branchChanged(branch)}/> - -
; + return ( +
+ + this.branchChanged(branch)} + /> +
+ +
+ ); } - return + return ; }; - branchChanged = (branchName: string) => { - const {history, repository} = this.props; - history.push(`/repo/${repository.namespace}/${repository.name}/history/${branchName}`); + const { history, repository } = this.props; + history.push( + `/repo/${repository.namespace}/${repository.name}/history/${branchName}` + ); }; } - const mapStateToProps = (state, ownProps: Props) => { - const {namespace, name} = ownProps.repository; + const { namespace, name } = ownProps.repository; return { loading: isFetchChangesetsPending(namespace, name, state), - changesets: getChangesets(state, namespace, name, ownProps.match.params.branch), + changesets: getChangesets( + state, + namespace, + name, + ownProps.match.params.branch + ), branchNames: getBranchNames(namespace, name, state), - error: getFetchChangesetsFailure(state, namespace, name, ownProps.match.params.branch) - } + error: getFetchChangesetsFailure( + state, + namespace, + name, + ownProps.match.params.branch + ) + }; }; const mapDispatchToProps = dispatch => { @@ -89,16 +120,24 @@ const mapDispatchToProps = dispatch => { fetchChangesetsByNamespaceAndName: (namespace: string, name: string) => { dispatch(fetchChangesetsByNamespaceAndName(namespace, name)); }, - fetchChangesetsByNamespaceNameAndBranch: (namespace: string, name: string, branch: string) => { - dispatch(fetchChangesetsByNamespaceNameAndBranch(namespace, name, branch)); + fetchChangesetsByNamespaceNameAndBranch: ( + namespace: string, + name: string, + branch: string + ) => { + dispatch( + fetchChangesetsByNamespaceNameAndBranch(namespace, name, branch) + ); }, fetchBranchesByNamespaceAndName: (namespace: string, name: string) => { dispatch(fetchBranchesByNamespaceAndName(namespace, name)); } - } + }; }; -export default withRouter(connect( - mapStateToProps, - mapDispatchToProps -)(Changesets)); +export default withRouter( + connect( + mapStateToProps, + mapDispatchToProps + )(Changesets) +); From b308aa32f228d7e2f13f6c6bca4c48f9074ebe61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 18 Sep 2018 17:10:39 +0200 Subject: [PATCH 023/121] Fix dummy link --- scm-ui/src/changesets/components/ChangesetRow.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scm-ui/src/changesets/components/ChangesetRow.js b/scm-ui/src/changesets/components/ChangesetRow.js index ac6d4ef143..1c72300459 100644 --- a/scm-ui/src/changesets/components/ChangesetRow.js +++ b/scm-ui/src/changesets/components/ChangesetRow.js @@ -1,8 +1,8 @@ //@flow import React from "react"; -import type { Changeset } from "@scm-manager/ui-types"; +import type {Changeset} from "@scm-manager/ui-types"; import classNames from "classnames"; -import { Link } from "react-router-dom"; +import {Link} from "react-router-dom"; import ChangesetAvatar from "./ChangesetAvatar"; import injectSheet from "react-jss"; @@ -22,7 +22,7 @@ type Props = { class ChangesetRow extends React.Component { createLink = (changeset: Changeset) => { - return `/repo/${changeset.description}/changeset/${changeset.id}`; + return `/repo/changeset/${changeset.id}`; }; render() { From 6d0146f26721456914ffd7232f84b000afd401c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 09:49:24 +0200 Subject: [PATCH 024/121] Adapt layout to next.scm-manager.org --- scm-ui/public/locales/en/changesets.json | 3 +- .../src/changesets/components/ChangesetRow.js | 44 +++++++++++-------- .../changesets/components/ChangesetTable.js | 5 ++- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/scm-ui/public/locales/en/changesets.json b/scm-ui/public/locales/en/changesets.json index 6628fcf62f..8c804d8f62 100644 --- a/scm-ui/public/locales/en/changesets.json +++ b/scm-ui/public/locales/en/changesets.json @@ -3,7 +3,8 @@ "id": "ID", "description": "Description", "contact": "Contact", - "date": "Date" + "date": "Date", + "summary": "Changeset {{id}} committed at {{time}}" }, "author": { "name": "Author", diff --git a/scm-ui/src/changesets/components/ChangesetRow.js b/scm-ui/src/changesets/components/ChangesetRow.js index 1c72300459..9892b0eb34 100644 --- a/scm-ui/src/changesets/components/ChangesetRow.js +++ b/scm-ui/src/changesets/components/ChangesetRow.js @@ -2,7 +2,7 @@ import React from "react"; import type {Changeset} from "@scm-manager/ui-types"; import classNames from "classnames"; -import {Link} from "react-router-dom"; +import {translate} from "react-i18next"; import ChangesetAvatar from "./ChangesetAvatar"; import injectSheet from "react-jss"; @@ -17,6 +17,7 @@ const styles = { type Props = { changeset: Changeset, + t: any, classes: any }; @@ -26,38 +27,43 @@ class ChangesetRow extends React.Component { }; render() { - const { changeset, classes } = this.props; + const { changeset, t, classes } = this.props; const changesetLink = this.createLink(changeset); + const authorLine = ( + <> + {changeset.author.name}{" "} + + < + {changeset.author.mail} + > + + + ); // todo: i18n return ( -
-
-

-

- Changeset {changeset.id} commited at {changeset.date} -

-

- {changeset.author.name}{" "} - - < - {changeset.author.mail} - > - -

-

{changeset.description}

+

+ {changeset.description} +
+ {t("changeset.summary", { + id: changeset.id, + time: changeset.date + })}

+

{authorLine}

-
); } } -export default injectSheet(styles)(ChangesetRow); +export default injectSheet(styles)(translate("changesets")(ChangesetRow)); diff --git a/scm-ui/src/changesets/components/ChangesetTable.js b/scm-ui/src/changesets/components/ChangesetTable.js index 2dd0d1b955..88c2b2fc3a 100644 --- a/scm-ui/src/changesets/components/ChangesetTable.js +++ b/scm-ui/src/changesets/components/ChangesetTable.js @@ -1,7 +1,8 @@ // @flow import ChangesetRow from "./ChangesetRow"; import React from "react"; -import type {Changeset} from "@scm-manager/ui-types"; +import type { Changeset } from "@scm-manager/ui-types"; +import classNames from "classnames"; type Props = { changesets: Changeset[] @@ -13,7 +14,7 @@ class ChangesetTable extends React.Component { const content = changesets.map((changeset, index) => { return ; }); - return
{content}
; + return
{content}
; } } From 10b120c86250fd6f88bb1edd380a6e874197a55a Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Wed, 19 Sep 2018 13:49:04 +0200 Subject: [PATCH 025/121] Restructured changeset module --- .../src/changesets/containers/Changesets.js | 70 ++++-- scm-ui/src/changesets/modules/changesets.js | 218 ++++++++++++++---- .../src/changesets/modules/changesets.test.js | 175 ++++++++++---- 3 files changed, 352 insertions(+), 111 deletions(-) diff --git a/scm-ui/src/changesets/containers/Changesets.js b/scm-ui/src/changesets/containers/Changesets.js index 09410e91c0..5f0d6d9486 100644 --- a/scm-ui/src/changesets/containers/Changesets.js +++ b/scm-ui/src/changesets/containers/Changesets.js @@ -1,20 +1,26 @@ +// @flow import React from "react"; import { connect } from "react-redux"; -import { ErrorNotification, Loading } from "@scm-manager/ui-components"; +import { + ErrorNotification, + Loading, + Paginator +} from "@scm-manager/ui-components"; import { - fetchChangesetsByNamespaceAndName, + fetchChangesets, fetchChangesetsByNamespaceNameAndBranch, getChangesets, getFetchChangesetsFailure, - isFetchChangesetsPending + isFetchChangesetsPending, + selectListAsCollection } from "../modules/changesets"; import type { History } from "history"; import { fetchBranchesByNamespaceAndName, getBranchNames } from "../../repos/modules/branches"; -import type { Repository } from "@scm-manager/ui-types"; +import type { PagedCollection, Repository } from "@scm-manager/ui-types"; import ChangesetTable from "../components/ChangesetTable"; import DropDown from "../components/DropDown"; import { withRouter } from "react-router-dom"; @@ -27,7 +33,8 @@ type Props = { namespace: string, name: string, branch: string - ) => void + ) => void, + list: PagedCollection }; class Changesets extends React.Component { @@ -60,12 +67,13 @@ class Changesets extends React.Component { return (
- {this.renderContent()} + {this.renderTable()} + {this.renderPaginator()}
); } - renderContent = () => { + renderTable = () => { const branch = this.props.match.params.branch; const { changesets, branchNames } = this.props; @@ -78,7 +86,6 @@ class Changesets extends React.Component { preselectedOption={branch} optionSelected={branch => this.branchChanged(branch)} /> -
); @@ -87,7 +94,15 @@ class Changesets extends React.Component { return ; }; - branchChanged = (branchName: string) => { + renderPaginator() { + const { list } = this.props; + if (list) { + return ; + } + return null; + } + + branchChanged = (branchName: string): void => { const { history, repository } = this.props; history.push( `/repo/${repository.namespace}/${repository.name}/history/${branchName}` @@ -97,28 +112,35 @@ class Changesets extends React.Component { const mapStateToProps = (state, ownProps: Props) => { const { namespace, name } = ownProps.repository; + const loading = isFetchChangesetsPending(namespace, name, state); + const changesets = getChangesets( + state, + namespace, + name, + ownProps.match.params.branch + ); + const branchNames = getBranchNames(namespace, name, state); + const error = getFetchChangesetsFailure( + state, + namespace, + name, + ownProps.match.params.branch + ); + const list = selectListAsCollection(state); + return { - loading: isFetchChangesetsPending(namespace, name, state), - changesets: getChangesets( - state, - namespace, - name, - ownProps.match.params.branch - ), - branchNames: getBranchNames(namespace, name, state), - error: getFetchChangesetsFailure( - state, - namespace, - name, - ownProps.match.params.branch - ) + loading, + changesets, + branchNames, + error, + list }; }; const mapDispatchToProps = dispatch => { return { fetchChangesetsByNamespaceAndName: (namespace: string, name: string) => { - dispatch(fetchChangesetsByNamespaceAndName(namespace, name)); + dispatch(fetchChangesets(namespace, name)); }, fetchChangesetsByNamespaceNameAndBranch: ( namespace: string, diff --git a/scm-ui/src/changesets/modules/changesets.js b/scm-ui/src/changesets/modules/changesets.js index 6423dca515..b806fff535 100644 --- a/scm-ui/src/changesets/modules/changesets.js +++ b/scm-ui/src/changesets/modules/changesets.js @@ -1,9 +1,15 @@ // @flow -import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; -import {apiClient} from "@scm-manager/ui-components"; -import {isPending} from "../../modules/pending"; -import {getFailure} from "../../modules/failure"; +import { + FAILURE_SUFFIX, + PENDING_SUFFIX, + SUCCESS_SUFFIX +} from "../../modules/types"; +import { apiClient } from "@scm-manager/ui-components"; +import { isPending } from "../../modules/pending"; +import { getFailure } from "../../modules/failure"; +import { combineReducers } from "redux"; +import type { Action, PagedCollection } from "@scm-manager/ui-types"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -11,51 +17,98 @@ export const FETCH_CHANGESETS_SUCCESS = `${FETCH_CHANGESETS}_${SUCCESS_SUFFIX}`; export const FETCH_CHANGESETS_FAILURE = `${FETCH_CHANGESETS}_${FAILURE_SUFFIX}`; const REPO_URL = "repositories"; - - +//TODO: Content type // actions -export function fetchChangesetsByNamespaceAndName(namespace: string, name: string) { - return function (dispatch: any) { - dispatch(fetchChangesetsPending(namespace, name)); - return apiClient.get(REPO_URL + "/" + namespace + "/" + name + "/changesets").then(response => response.json()) - .then(data => { - dispatch(fetchChangesetsSuccess(data, namespace, name)) - }).catch(cause => { - dispatch(fetchChangesetsFailure(namespace, name, cause)) - }) - } -} -export function fetchChangesetsByNamespaceNameAndBranch(namespace: string, name: string, branch: string) { - return function (dispatch: any) { +export function fetchChangesetsWithOptions( + namespace: string, + name: string, + branch?: string, + suffix?: string +) { + let link = REPO_URL + `/${namespace}/${name}`; + if (branch && branch !== "") { + link = link + `/branches/${branch}`; + } + link = link + "/changesets"; + if (suffix) { + link = link + `${suffix}`; + } + return function(dispatch: any) { dispatch(fetchChangesetsPending(namespace, name, branch)); - return apiClient.get(REPO_URL + "/" + namespace + "/" + name + "/branches/" + branch + "/changesets").then(response => response.json()) + return apiClient + .get(link) + .then(response => response.json()) .then(data => { - dispatch(fetchChangesetsSuccess(data, namespace, name, branch)) - }).catch(cause => { - dispatch(fetchChangesetsFailure(namespace, name, branch, cause)) + dispatch(fetchChangesetsSuccess(data, namespace, name, branch)); }) - } + .catch(cause => { + dispatch(fetchChangesetsFailure(namespace, name, cause, branch)); + }); + }; } -export function fetchChangesetsPending(namespace: string, name: string, branch?: string): Action { +export function fetchChangesets(namespace: string, name: string) { + return fetchChangesetsWithOptions(namespace, name); +} + +export function fetchChangesetsByPage( + namespace: string, + name: string, + page: number +) { + return fetchChangesetsWithOptions(namespace, name, "", `?page=${page}`); +} + +export function fetchChangesetsByBranchAndPage( + namespace: string, + name: string, + branch: string, + page: number +) { + return fetchChangesetsWithOptions(namespace, name, branch, `?page=${page}`); +} + +export function fetchChangesetsByNamespaceNameAndBranch( + namespace: string, + name: string, + branch: string +) { + return fetchChangesetsWithOptions(namespace, name, branch); +} + +export function fetchChangesetsPending( + namespace: string, + name: string, + branch?: string +): Action { const itemId = createItemId(namespace, name, branch); return { type: FETCH_CHANGESETS_PENDING, payload: itemId, itemId - } + }; } -export function fetchChangesetsSuccess(changesets: any, namespace: string, name: string, branch?: string): Action { +export function fetchChangesetsSuccess( + changesets: any, + namespace: string, + name: string, + branch?: string +): Action { return { type: FETCH_CHANGESETS_SUCCESS, payload: changesets, itemId: createItemId(namespace, name, branch) - } + }; } -function fetchChangesetsFailure(namespace: string, name: string, branch?: string, error: Error): Action { +function fetchChangesetsFailure( + namespace: string, + name: string, + error: Error, + branch?: string +): Action { return { type: FETCH_CHANGESETS_FAILURE, payload: { @@ -65,10 +118,14 @@ function fetchChangesetsFailure(namespace: string, name: string, branch?: string error }, itemId: createItemId(namespace, name, branch) - } + }; } -function createItemId(namespace: string, name: string, branch?: string): string { +function createItemId( + namespace: string, + name: string, + branch?: string +): string { let itemId = namespace + "/" + name; if (branch && branch !== "") { itemId = itemId + "/" + branch; @@ -77,20 +134,54 @@ function createItemId(namespace: string, name: string, branch?: string): string } // reducer -export default function reducer(state: any = {}, action: Action = {type: "UNKNOWN"}): Object { +function byKeyReducer( + state: any = {}, + action: Action = { type: "UNKNOWN" } +): Object { switch (action.type) { case FETCH_CHANGESETS_SUCCESS: - const key = action.itemId - let oldChangesets = {[key]: {}}; + const key = action.itemId; + let oldChangesets = { [key]: {} }; if (state[key] !== undefined) { - oldChangesets[key] = state[key] + oldChangesets[key] = state[key]; } - return {...state, [key]: {byId: extractChangesetsByIds(action.payload, oldChangesets[key].byId)}}; + return { + ...state, + [key]: { + byId: extractChangesetsByIds(action.payload, oldChangesets[key].byId) + } + }; default: return state; } } +function listReducer( + state: any = {}, + action: Action = { type: "UNKNOWN" } +): Object { + switch (action.type) { + case FETCH_CHANGESETS_SUCCESS: + const changesets = action.payload._embedded.changesets; + const changesetIds = changesets.map(c => c.id); + return { + entries: changesetIds, + entry: { + page: action.payload.page, + pageTotal: action.payload.pageTotal, + _links: action.payload._links + } + }; + default: + return state; + } +} + +export default combineReducers({ + list: listReducer, + byKey: byKeyReducer +}); + function extractChangesetsByIds(data: any, oldChangesetsByIds: any) { const changesets = data._embedded.changesets; const changesetsByIds = {}; @@ -107,19 +198,60 @@ function extractChangesetsByIds(data: any, oldChangesetsByIds: any) { } //selectors -export function getChangesets(state: Object, namespace: string, name: string, branch?: string) { +export function getChangesets( + state: Object, + namespace: string, + name: string, + branch?: string +) { const key = createItemId(namespace, name, branch); - if (!state.changesets[key]) { + if (!state.changesets.byKey[key]) { return null; } - return Object.values(state.changesets[key].byId); + return Object.values(state.changesets.byKey[key].byId); } -export function isFetchChangesetsPending(state: Object, namespace: string, name: string, branch?: string) { - return isPending(state, FETCH_CHANGESETS, createItemId(namespace, name, branch)) +export function isFetchChangesetsPending( + state: Object, + namespace: string, + name: string, + branch?: string +) { + return isPending( + state, + FETCH_CHANGESETS, + createItemId(namespace, name, branch) + ); } -export function getFetchChangesetsFailure(state: Object, namespace: string, name: string, branch?: string) { - return getFailure(state, FETCH_CHANGESETS, createItemId(namespace, name, branch)); +export function getFetchChangesetsFailure( + state: Object, + namespace: string, + name: string, + branch?: string +) { + return getFailure( + state, + FETCH_CHANGESETS, + createItemId(namespace, name, branch) + ); } +const selectList = (state: Object) => { + if (state.changesets && state.changesets.list) { + return state.changesets.list; + } + return {}; +}; + +const selectListEntry = (state: Object): Object => { + const list = selectList(state); + if (list.entry) { + return list.entry; + } + return {}; +}; + +export const selectListAsCollection = (state: Object): PagedCollection => { + return selectListEntry(state); +}; diff --git a/scm-ui/src/changesets/modules/changesets.test.js b/scm-ui/src/changesets/modules/changesets.test.js index c74eee3975..d46dff8ef7 100644 --- a/scm-ui/src/changesets/modules/changesets.test.js +++ b/scm-ui/src/changesets/modules/changesets.test.js @@ -8,8 +8,10 @@ import { FETCH_CHANGESETS_FAILURE, FETCH_CHANGESETS_PENDING, FETCH_CHANGESETS_SUCCESS, - fetchChangesetsByNamespaceAndName, + fetchChangesets, + fetchChangesetsByBranchAndPage, fetchChangesetsByNamespaceNameAndBranch, + fetchChangesetsByPage, fetchChangesetsSuccess, getChangesets, getFetchChangesetsFailure, @@ -22,7 +24,8 @@ const changesets = {}; describe("changesets", () => { describe("fetching of changesets", () => { const DEFAULT_BRANCH_URL = "/api/rest/v2/repositories/foo/bar/changesets"; - const SPECIFIC_BRANCH_URL = "/api/rest/v2/repositories/foo/bar/branches/specific/changesets"; + const SPECIFIC_BRANCH_URL = + "/api/rest/v2/repositories/foo/bar/branches/specific/changesets"; const mockStore = configureMockStore([thunk]); afterEach(() => { @@ -35,7 +38,8 @@ describe("changesets", () => { const expectedActions = [ { - type: FETCH_CHANGESETS_PENDING, payload: "foo/bar", + type: FETCH_CHANGESETS_PENDING, + payload: "foo/bar", itemId: "foo/bar" }, { @@ -46,7 +50,7 @@ describe("changesets", () => { ]; const store = mockStore({}); - return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { + return store.dispatch(fetchChangesets("foo", "bar")).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); @@ -57,7 +61,8 @@ describe("changesets", () => { const expectedActions = [ { - type: FETCH_CHANGESETS_PENDING, payload: itemId, + type: FETCH_CHANGESETS_PENDING, + payload: itemId, itemId }, { @@ -68,9 +73,13 @@ describe("changesets", () => { ]; const store = mockStore({}); - return store.dispatch(fetchChangesetsByNamespaceNameAndBranch("foo", "bar", "specific")).then(() => { - expect(store.getActions()).toEqual(expectedActions); - }); + return store + .dispatch( + fetchChangesetsByNamespaceNameAndBranch("foo", "bar", "specific") + ) + .then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); }); it("should fail fetching changesets on error", () => { @@ -79,18 +88,19 @@ describe("changesets", () => { const expectedActions = [ { - type: FETCH_CHANGESETS_PENDING, payload: itemId, + type: FETCH_CHANGESETS_PENDING, + payload: itemId, itemId } ]; const store = mockStore({}); - return store.dispatch(fetchChangesetsByNamespaceAndName("foo", "bar")).then(() => { + return store.dispatch(fetchChangesets("foo", "bar")).then(() => { expect(store.getActions()[0]).toEqual(expectedActions[0]); expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); expect(store.getActions()[1].payload).toBeDefined(); }); - }) + }); it("should fail fetching changesets for specific branch on error", () => { const itemId = "foo/bar/specific"; @@ -98,27 +108,81 @@ describe("changesets", () => { const expectedActions = [ { - type: FETCH_CHANGESETS_PENDING, payload: itemId, + type: FETCH_CHANGESETS_PENDING, + payload: itemId, itemId } ]; const store = mockStore({}); - return store.dispatch(fetchChangesetsByNamespaceNameAndBranch("foo", "bar", "specific")).then(() => { - expect(store.getActions()[0]).toEqual(expectedActions[0]); - expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); - expect(store.getActions()[1].payload).toBeDefined(); + return store + .dispatch( + fetchChangesetsByNamespaceNameAndBranch("foo", "bar", "specific") + ) + .then(() => { + expect(store.getActions()[0]).toEqual(expectedActions[0]); + expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); + expect(store.getActions()[1].payload).toBeDefined(); + }); + }); + + it("should fetch changesets by page", () => { + fetchMock.getOnce(DEFAULT_BRANCH_URL + "?page=5", "{}"); + + const expectedActions = [ + { + type: FETCH_CHANGESETS_PENDING, + payload: "foo/bar", + itemId: "foo/bar" + }, + { + type: FETCH_CHANGESETS_SUCCESS, + payload: changesets, + itemId: "foo/bar" + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchChangesetsByPage("foo", "bar", 5)).then(() => { + expect(store.getActions()).toEqual(expectedActions); }); - }) + }); + + it("should fetch changesets by branch and page", () => { + fetchMock.getOnce(SPECIFIC_BRANCH_URL + "?page=5", "{}"); + + const expectedActions = [ + { + type: FETCH_CHANGESETS_PENDING, + payload: "foo/bar/specific", + itemId: "foo/bar/specific" + }, + { + type: FETCH_CHANGESETS_SUCCESS, + payload: changesets, + itemId: "foo/bar/specific" + } + ]; + + const store = mockStore({}); + return store + .dispatch(fetchChangesetsByBranchAndPage("foo", "bar", "specific", 5)) + .then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); + }); }); describe("changesets reducer", () => { const responseBody = { + page: 1, + pageTotal: 10, + _links: {}, _embedded: { changesets: [ - {id: "changeset1", author: {mail: "z@phod.com", name: "zaphod"}}, - {id: "changeset2", description: "foo"}, - {id: "changeset3", description: "bar"}, + { id: "changeset1", author: { mail: "z@phod.com", name: "zaphod" } }, + { id: "changeset2", description: "foo" }, + { id: "changeset3", description: "bar" } ], _embedded: { tags: [], @@ -129,18 +193,35 @@ describe("changesets", () => { }; it("should set state to received changesets", () => { - const newState = reducer({}, fetchChangesetsSuccess(responseBody, "foo", "bar")); + const newState = reducer( + {}, + fetchChangesetsSuccess(responseBody, "foo", "bar") + ); expect(newState).toBeDefined(); - expect(newState["foo/bar"].byId["changeset1"].author.mail).toEqual("z@phod.com"); - expect(newState["foo/bar"].byId["changeset2"].description).toEqual("foo"); - expect(newState["foo/bar"].byId["changeset3"].description).toEqual("bar"); + expect(newState.byKey["foo/bar"].byId["changeset1"].author.mail).toEqual( + "z@phod.com" + ); + expect(newState.byKey["foo/bar"].byId["changeset2"].description).toEqual( + "foo" + ); + expect(newState.byKey["foo/bar"].byId["changeset3"].description).toEqual( + "bar" + ); + expect(newState.list).toEqual({ + entry: { + page: 1, + pageTotal: 10, + _links: {} + }, + entries: ["changeset1", "changeset2", "changeset3"] + }); }); it("should not delete existing changesets from state", () => { const responseBody = { _embedded: { changesets: [ - {id: "changeset1", author: {mail: "z@phod.com", name: "zaphod"}}, + { id: "changeset1", author: { mail: "z@phod.com", name: "zaphod" } } ], _embedded: { tags: [], @@ -149,19 +230,24 @@ describe("changesets", () => { } } }; - const newState = reducer({ - "foo/bar": { - byId: { - ["changeset2"]: { - id: "changeset2", - author: {mail: "mail@author.com", name: "author"} + const newState = reducer( + { + byKey: { + "foo/bar": { + byId: { + ["changeset2"]: { + id: "changeset2", + author: { mail: "mail@author.com", name: "author" } + } + } } } - } - }, fetchChangesetsSuccess(responseBody, "foo", "bar")); - expect(newState["foo/bar"].byId["changeset2"]).toBeDefined(); - expect(newState["foo/bar"].byId["changeset1"]).toBeDefined(); - }) + }, + fetchChangesetsSuccess(responseBody, "foo", "bar") + ); + expect(newState.byKey["foo/bar"].byId["changeset2"]).toBeDefined(); + expect(newState.byKey["foo/bar"].byId["changeset1"]).toBeDefined(); + }); }); describe("changeset selectors", () => { @@ -170,16 +256,18 @@ describe("changesets", () => { it("should get all changesets for a given namespace and name", () => { const state = { changesets: { - ["foo/bar"]: { - byId: { - "id1": {id: "id1"}, - "id2": {id: "id2"} + byKey: { + "foo/bar": { + byId: { + id1: { id: "id1" }, + id2: { id: "id2" } + } } } } }; - const result = getChangesets(state, "foo", "bar" ); - expect(result).toContainEqual({id: "id1"}) + const result = getChangesets(state, "foo", "bar"); + expect(result).toContainEqual({ id: "id1" }); }); it("should return true, when fetching changesets is pending", () => { @@ -208,7 +296,6 @@ describe("changesets", () => { it("should return false if fetching changesets did not fail", () => { expect(getFetchChangesetsFailure({}, "foo", "bar")).toBeUndefined(); - }) - + }); }); }); From c853a3eb80875a74c62781a53b49b4e79e6f3033 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Wed, 19 Sep 2018 14:10:50 +0200 Subject: [PATCH 026/121] Moved changeset code to repos --- scm-ui/src/createReduxStore.js | 2 +- .../components/ChangesetAvatar.js | 0 .../components/ChangesetRow.js | 38 +++++++++---------- .../components/ChangesetTable.js | 0 .../components/DropDown.js | 0 .../containers/Changesets.js | 0 scm-ui/src/repos/containers/RepositoryRoot.js | 2 +- .../modules/changesets.js | 0 .../modules/changesets.test.js | 0 9 files changed, 21 insertions(+), 21 deletions(-) rename scm-ui/src/{changesets => repos}/components/ChangesetAvatar.js (100%) rename scm-ui/src/{changesets => repos}/components/ChangesetRow.js (58%) rename scm-ui/src/{changesets => repos}/components/ChangesetTable.js (100%) rename scm-ui/src/{changesets => repos}/components/DropDown.js (100%) rename scm-ui/src/{changesets => repos}/containers/Changesets.js (100%) rename scm-ui/src/{changesets => repos}/modules/changesets.js (100%) rename scm-ui/src/{changesets => repos}/modules/changesets.test.js (100%) diff --git a/scm-ui/src/createReduxStore.js b/scm-ui/src/createReduxStore.js index 5c4fb20410..c35898ddbf 100644 --- a/scm-ui/src/createReduxStore.js +++ b/scm-ui/src/createReduxStore.js @@ -7,7 +7,7 @@ import { routerReducer, routerMiddleware } from "react-router-redux"; import users from "./users/modules/users"; import repos from "./repos/modules/repos"; import repositoryTypes from "./repos/modules/repositoryTypes"; -import changesets from "./changesets/modules/changesets"; +import changesets from "./repos/modules/changesets"; import groups from "./groups/modules/groups"; import auth from "./modules/auth"; import pending from "./modules/pending"; diff --git a/scm-ui/src/changesets/components/ChangesetAvatar.js b/scm-ui/src/repos/components/ChangesetAvatar.js similarity index 100% rename from scm-ui/src/changesets/components/ChangesetAvatar.js rename to scm-ui/src/repos/components/ChangesetAvatar.js diff --git a/scm-ui/src/changesets/components/ChangesetRow.js b/scm-ui/src/repos/components/ChangesetRow.js similarity index 58% rename from scm-ui/src/changesets/components/ChangesetRow.js rename to scm-ui/src/repos/components/ChangesetRow.js index 9892b0eb34..e6a69fef4b 100644 --- a/scm-ui/src/changesets/components/ChangesetRow.js +++ b/scm-ui/src/repos/components/ChangesetRow.js @@ -1,8 +1,8 @@ //@flow import React from "react"; -import type {Changeset} from "@scm-manager/ui-types"; +import type { Changeset } from "@scm-manager/ui-types"; import classNames from "classnames"; -import {translate} from "react-i18next"; +import { translate } from "react-i18next"; import ChangesetAvatar from "./ChangesetAvatar"; import injectSheet from "react-jss"; @@ -44,24 +44,24 @@ class ChangesetRow extends React.Component { ); // todo: i18n return ( -
-
- -
-
-
-

- {changeset.description} -
- {t("changeset.summary", { - id: changeset.id, - time: changeset.date - })} -

-

{authorLine}

-
+
+
+ +
+
+
+

+ {changeset.description} +
+ {t("changeset.summary", { + id: changeset.id, + time: changeset.date + })} +

+

{authorLine}

-
+
+
); } } diff --git a/scm-ui/src/changesets/components/ChangesetTable.js b/scm-ui/src/repos/components/ChangesetTable.js similarity index 100% rename from scm-ui/src/changesets/components/ChangesetTable.js rename to scm-ui/src/repos/components/ChangesetTable.js diff --git a/scm-ui/src/changesets/components/DropDown.js b/scm-ui/src/repos/components/DropDown.js similarity index 100% rename from scm-ui/src/changesets/components/DropDown.js rename to scm-ui/src/repos/components/DropDown.js diff --git a/scm-ui/src/changesets/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js similarity index 100% rename from scm-ui/src/changesets/containers/Changesets.js rename to scm-ui/src/repos/containers/Changesets.js diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index 958626ce62..e1352fba31 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -25,7 +25,7 @@ import Edit from "../containers/Edit"; import type {History} from "history"; import EditNavLink from "../components/EditNavLink"; -import Changesets from "../../changesets/containers/Changesets"; +import Changesets from "./Changesets"; type Props = { namespace: string, diff --git a/scm-ui/src/changesets/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js similarity index 100% rename from scm-ui/src/changesets/modules/changesets.js rename to scm-ui/src/repos/modules/changesets.js diff --git a/scm-ui/src/changesets/modules/changesets.test.js b/scm-ui/src/repos/modules/changesets.test.js similarity index 100% rename from scm-ui/src/changesets/modules/changesets.test.js rename to scm-ui/src/repos/modules/changesets.test.js From 66bba0d9cfdd5dc7e7144a04fef38cfac3e15324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 14:15:15 +0200 Subject: [PATCH 027/121] Add link to changeset id and use date from now --- .../src/changesets/components/ChangesetRow.js | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/scm-ui/src/changesets/components/ChangesetRow.js b/scm-ui/src/changesets/components/ChangesetRow.js index 9892b0eb34..cb8691206a 100644 --- a/scm-ui/src/changesets/components/ChangesetRow.js +++ b/scm-ui/src/changesets/components/ChangesetRow.js @@ -1,10 +1,11 @@ //@flow import React from "react"; -import type {Changeset} from "@scm-manager/ui-types"; +import type { Changeset } from "@scm-manager/ui-types"; import classNames from "classnames"; -import {translate} from "react-i18next"; +import { translate, Interpolate } from "react-i18next"; import ChangesetAvatar from "./ChangesetAvatar"; import injectSheet from "react-jss"; +import { DateFromNow } from "@scm-manager/ui-components"; const styles = { pointer: { @@ -23,12 +24,13 @@ type Props = { class ChangesetRow extends React.Component { createLink = (changeset: Changeset) => { - return `/repo/changeset/${changeset.id}`; + return {changeset.id}; }; render() { const { changeset, t, classes } = this.props; const changesetLink = this.createLink(changeset); + const dateFromNow = ; const authorLine = ( <> {changeset.author.name}{" "} @@ -42,26 +44,26 @@ class ChangesetRow extends React.Component { ); - // todo: i18n return ( -
-
- -
-
-
-

- {changeset.description} -
- {t("changeset.summary", { - id: changeset.id, - time: changeset.date - })} -

-

{authorLine}

-
+
+
+ +
+
+
+

+ {changeset.description} +
+ +

{" "} +

{authorLine}

-
+
+
); } } From ea34f7e6b8ef6c416c1331da4768f89ce8ba429c Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Wed, 19 Sep 2018 14:46:01 +0200 Subject: [PATCH 028/121] Fixed displaying of loading state --- scm-ui/src/repos/containers/Changesets.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 5f0d6d9486..21c8211d90 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -43,6 +43,8 @@ class Changesets extends React.Component { this.state = {}; } + onPageChange = (link: string) => { + }; componentDidMount() { const { namespace, name } = this.props.repository; const branchName = this.props.match.params.branch; @@ -112,7 +114,12 @@ class Changesets extends React.Component { const mapStateToProps = (state, ownProps: Props) => { const { namespace, name } = ownProps.repository; - const loading = isFetchChangesetsPending(namespace, name, state); + const loading = isFetchChangesetsPending( + state, + namespace, + name, + ownProps.match.params.branch + ); const changesets = getChangesets( state, namespace, From 95762c3afa8c0aefe89b8895e34eae77e13f556f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 14:59:00 +0200 Subject: [PATCH 029/121] Fix overflow in media content --- scm-ui/styles/scm.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scm-ui/styles/scm.scss b/scm-ui/styles/scm.scss index 43701de5eb..19c19b607c 100644 --- a/scm-ui/styles/scm.scss +++ b/scm-ui/styles/scm.scss @@ -11,6 +11,10 @@ $blue: #33B2E8; white-space: nowrap; } +.media-content { + overflow: auto; +} + .has-rounded-border { border-radius: 0.25rem; } From 67e140cd247789e2534d6cefb974a7afa9332471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 15:46:47 +0200 Subject: [PATCH 030/121] Do not extend bulmar native css classes --- scm-ui/src/repos/components/ChangesetRow.js | 5 ++++- scm-ui/styles/scm.scss | 4 ---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/scm-ui/src/repos/components/ChangesetRow.js b/scm-ui/src/repos/components/ChangesetRow.js index cb8691206a..cd2e8a228e 100644 --- a/scm-ui/src/repos/components/ChangesetRow.js +++ b/scm-ui/src/repos/components/ChangesetRow.js @@ -13,6 +13,9 @@ const styles = { }, changesetGroup: { marginBottom: "1em" + }, + withOverflow: { + overflow: "auto" } }; @@ -49,7 +52,7 @@ class ChangesetRow extends React.Component {
-
+

{changeset.description} diff --git a/scm-ui/styles/scm.scss b/scm-ui/styles/scm.scss index 19c19b607c..43701de5eb 100644 --- a/scm-ui/styles/scm.scss +++ b/scm-ui/styles/scm.scss @@ -11,10 +11,6 @@ $blue: #33B2E8; white-space: nowrap; } -.media-content { - overflow: auto; -} - .has-rounded-border { border-radius: 0.25rem; } From 231dcbb9cbcc69689d7193750f4f4a4b3fe4f09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 16:05:35 +0200 Subject: [PATCH 031/121] Correct link to changeset --- scm-ui/src/repos/components/ChangesetRow.js | 15 +++++++++++++-- scm-ui/src/repos/components/ChangesetTable.js | 7 ++++--- scm-ui/src/repos/containers/Changesets.js | 4 ++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/scm-ui/src/repos/components/ChangesetRow.js b/scm-ui/src/repos/components/ChangesetRow.js index cd2e8a228e..27830cbb44 100644 --- a/scm-ui/src/repos/components/ChangesetRow.js +++ b/scm-ui/src/repos/components/ChangesetRow.js @@ -1,11 +1,12 @@ //@flow import React from "react"; -import type { Changeset } from "@scm-manager/ui-types"; +import type { Changeset, Repository } from "@scm-manager/ui-types"; import classNames from "classnames"; import { translate, Interpolate } from "react-i18next"; import ChangesetAvatar from "./ChangesetAvatar"; import injectSheet from "react-jss"; import { DateFromNow } from "@scm-manager/ui-components"; +import { Link } from "react-router-dom"; const styles = { pointer: { @@ -20,6 +21,7 @@ const styles = { }; type Props = { + repository: Repository, changeset: Changeset, t: any, classes: any @@ -27,7 +29,16 @@ type Props = { class ChangesetRow extends React.Component { createLink = (changeset: Changeset) => { - return {changeset.id}; + const { repository } = this.props; + return ( + + {changeset.id} + + ); }; render() { diff --git a/scm-ui/src/repos/components/ChangesetTable.js b/scm-ui/src/repos/components/ChangesetTable.js index 88c2b2fc3a..e16ff384c4 100644 --- a/scm-ui/src/repos/components/ChangesetTable.js +++ b/scm-ui/src/repos/components/ChangesetTable.js @@ -1,18 +1,19 @@ // @flow import ChangesetRow from "./ChangesetRow"; import React from "react"; -import type { Changeset } from "@scm-manager/ui-types"; +import type { Changeset, Repository } from "@scm-manager/ui-types"; import classNames from "classnames"; type Props = { + repository: Repository, changesets: Changeset[] }; class ChangesetTable extends React.Component { render() { - const { changesets } = this.props; + const { repository, changesets } = this.props; const content = changesets.map((changeset, index) => { - return ; + return ; }); return

{content}
; } diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 21c8211d90..e0ab5ee560 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -77,7 +77,7 @@ class Changesets extends React.Component { renderTable = () => { const branch = this.props.match.params.branch; - const { changesets, branchNames } = this.props; + const { repository, changesets, branchNames } = this.props; if (branchNames && branchNames.length > 0) { return ( @@ -88,7 +88,7 @@ class Changesets extends React.Component { preselectedOption={branch} optionSelected={branch => this.branchChanged(branch)} /> - +
); } From 0b6feb6503e28c6c002039a0068bd2c7890d3e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 16:19:59 +0200 Subject: [PATCH 032/121] Rename ChangesetTable -> ChangesetList --- .../components/{ChangesetTable.js => ChangesetList.js} | 4 ++-- scm-ui/src/repos/containers/Changesets.js | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) rename scm-ui/src/repos/components/{ChangesetTable.js => ChangesetList.js} (86%) diff --git a/scm-ui/src/repos/components/ChangesetTable.js b/scm-ui/src/repos/components/ChangesetList.js similarity index 86% rename from scm-ui/src/repos/components/ChangesetTable.js rename to scm-ui/src/repos/components/ChangesetList.js index e16ff384c4..b5613b3754 100644 --- a/scm-ui/src/repos/components/ChangesetTable.js +++ b/scm-ui/src/repos/components/ChangesetList.js @@ -9,7 +9,7 @@ type Props = { changesets: Changeset[] }; -class ChangesetTable extends React.Component { +class ChangesetList extends React.Component { render() { const { repository, changesets } = this.props; const content = changesets.map((changeset, index) => { @@ -19,4 +19,4 @@ class ChangesetTable extends React.Component { } } -export default ChangesetTable; +export default ChangesetList; diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index e0ab5ee560..5d151e33dd 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -21,7 +21,7 @@ import { getBranchNames } from "../../repos/modules/branches"; import type { PagedCollection, Repository } from "@scm-manager/ui-types"; -import ChangesetTable from "../components/ChangesetTable"; +import ChangesetList from "../components/ChangesetList"; import DropDown from "../components/DropDown"; import { withRouter } from "react-router-dom"; @@ -43,8 +43,7 @@ class Changesets extends React.Component { this.state = {}; } - onPageChange = (link: string) => { - }; + onPageChange = (link: string) => {}; componentDidMount() { const { namespace, name } = this.props.repository; const branchName = this.props.match.params.branch; @@ -88,12 +87,12 @@ class Changesets extends React.Component { preselectedOption={branch} optionSelected={branch => this.branchChanged(branch)} /> - +
); } - return ; + return ; }; renderPaginator() { From dfdcd197db09fc22e60d801db957f2c1fc677e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 16:21:56 +0200 Subject: [PATCH 033/121] Show only first seven chars of commit id --- scm-ui/src/repos/components/ChangesetRow.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-ui/src/repos/components/ChangesetRow.js b/scm-ui/src/repos/components/ChangesetRow.js index 27830cbb44..a80b8d2b11 100644 --- a/scm-ui/src/repos/components/ChangesetRow.js +++ b/scm-ui/src/repos/components/ChangesetRow.js @@ -36,7 +36,7 @@ class ChangesetRow extends React.Component { changeset.id }`} > - {changeset.id} + {changeset.id.substr(0, 7)} ); }; From d8c5828987bef1cdc843c53b671e36066c0c51eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 16:39:29 +0200 Subject: [PATCH 034/121] Move changeset id renderer to component --- scm-ui/src/repos/components/ChangesetId.js | 25 +++++++++++++++++++++ scm-ui/src/repos/components/ChangesetRow.js | 14 +++--------- 2 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 scm-ui/src/repos/components/ChangesetId.js diff --git a/scm-ui/src/repos/components/ChangesetId.js b/scm-ui/src/repos/components/ChangesetId.js new file mode 100644 index 0000000000..7669cd606e --- /dev/null +++ b/scm-ui/src/repos/components/ChangesetId.js @@ -0,0 +1,25 @@ +//@flow + +import { Link } from "react-router-dom"; +import React from "react"; +import type { Repository, Changeset } from "@scm-manager/ui-types"; + +type Props = { + repository: Repository, + changeset: Changeset +}; + +export default class ChangesetId extends React.Component { + render() { + const { repository, changeset } = this.props; + return ( + + {changeset.id.substr(0, 7)} + + ); + } +} diff --git a/scm-ui/src/repos/components/ChangesetRow.js b/scm-ui/src/repos/components/ChangesetRow.js index a80b8d2b11..40bcfd59ed 100644 --- a/scm-ui/src/repos/components/ChangesetRow.js +++ b/scm-ui/src/repos/components/ChangesetRow.js @@ -4,9 +4,9 @@ import type { Changeset, Repository } from "@scm-manager/ui-types"; import classNames from "classnames"; import { translate, Interpolate } from "react-i18next"; import ChangesetAvatar from "./ChangesetAvatar"; +import ChangesetId from "./ChangesetId"; import injectSheet from "react-jss"; import { DateFromNow } from "@scm-manager/ui-components"; -import { Link } from "react-router-dom"; const styles = { pointer: { @@ -30,19 +30,11 @@ type Props = { class ChangesetRow extends React.Component { createLink = (changeset: Changeset) => { const { repository } = this.props; - return ( - - {changeset.id.substr(0, 7)} - - ); + return ; }; render() { - const { changeset, t, classes } = this.props; + const { changeset, classes } = this.props; const changesetLink = this.createLink(changeset); const dateFromNow = ; const authorLine = ( From d8cf660237fb65077268209795e4e9e2e4ca7533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 16:47:21 +0200 Subject: [PATCH 035/121] Move changeset authro renderer to component --- .../src/repos/components/ChangesetAuthor.js | 27 +++++++++++++++++++ scm-ui/src/repos/components/ChangesetRow.js | 15 ++--------- 2 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 scm-ui/src/repos/components/ChangesetAuthor.js diff --git a/scm-ui/src/repos/components/ChangesetAuthor.js b/scm-ui/src/repos/components/ChangesetAuthor.js new file mode 100644 index 0000000000..d2993daed4 --- /dev/null +++ b/scm-ui/src/repos/components/ChangesetAuthor.js @@ -0,0 +1,27 @@ +//@flow + +import React from "react"; +import type { Changeset } from "@scm-manager/ui-types"; + +type Props = { + changeset: Changeset +}; + +export default class ChangesetAuthor extends React.Component { + render() { + const { changeset } = this.props; + return ( + <> + {changeset.author.name}{" "} + + < + {changeset.author.mail} + > + + + ); + } +} diff --git a/scm-ui/src/repos/components/ChangesetRow.js b/scm-ui/src/repos/components/ChangesetRow.js index 40bcfd59ed..9ec3a7af58 100644 --- a/scm-ui/src/repos/components/ChangesetRow.js +++ b/scm-ui/src/repos/components/ChangesetRow.js @@ -7,6 +7,7 @@ import ChangesetAvatar from "./ChangesetAvatar"; import ChangesetId from "./ChangesetId"; import injectSheet from "react-jss"; import { DateFromNow } from "@scm-manager/ui-components"; +import ChangesetAuthor from "./ChangesetAuthor"; const styles = { pointer: { @@ -37,19 +38,7 @@ class ChangesetRow extends React.Component { const { changeset, classes } = this.props; const changesetLink = this.createLink(changeset); const dateFromNow = ; - const authorLine = ( - <> - {changeset.author.name}{" "} - - < - {changeset.author.mail} - > - - - ); + const authorLine = ; return (
From f1d2a41c0906154db579c31f99887fefec505d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 16:49:53 +0200 Subject: [PATCH 036/121] Fix translation --- scm-ui/public/locales/en/changesets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-ui/public/locales/en/changesets.json b/scm-ui/public/locales/en/changesets.json index 8c804d8f62..b3e996e094 100644 --- a/scm-ui/public/locales/en/changesets.json +++ b/scm-ui/public/locales/en/changesets.json @@ -4,7 +4,7 @@ "description": "Description", "contact": "Contact", "date": "Date", - "summary": "Changeset {{id}} committed at {{time}}" + "summary": "Changeset {{id}} committed {{time}}" }, "author": { "name": "Author", From ba8ce698e12f728a171d4eb149e4fa50d2cb5cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 19 Sep 2018 17:17:00 +0200 Subject: [PATCH 037/121] Fix paging for log command --- .../api/v2/resources/BranchRootResource.java | 7 ++-- .../v2/resources/ChangesetRootResource.java | 8 +++-- .../v2/resources/FileHistoryRootResource.java | 7 ++-- .../v2/resources/PagedLogCommandBuilder.java | 30 ++++++++++++++++ .../resources/ChangesetRootResourceTest.java | 34 ++++++++++++++++--- 5 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/PagedLogCommandBuilder.java diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java index 9763f11def..80b8f7ddc7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java @@ -100,9 +100,10 @@ public class BranchRootResource { try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { Repository repository = repositoryService.getRepository(); RepositoryPermissions.read(repository).check(); - ChangesetPagingResult changesets = repositoryService.getLogCommand() - .setPagingStart(page) - .setPagingLimit(pageSize) + ChangesetPagingResult changesets = new PagedLogCommandBuilder(repositoryService) + .page(page) + .pageSize(pageSize) + .create() .setBranch(branchName) .getChangesets(); if (changesets != null && changesets.getChangesets() != null) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java index 717b8d7198..97a23684a5 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java @@ -12,6 +12,7 @@ import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryNotFoundException; import sonia.scm.repository.RepositoryPermissions; import sonia.scm.repository.RevisionNotFoundException; +import sonia.scm.repository.api.LogCommandBuilder; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.web.VndMediaType; @@ -59,9 +60,10 @@ public class ChangesetRootResource { try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { Repository repository = repositoryService.getRepository(); RepositoryPermissions.read(repository).check(); - ChangesetPagingResult changesets = repositoryService.getLogCommand() - .setPagingStart(page) - .setPagingLimit(pageSize) + ChangesetPagingResult changesets = new PagedLogCommandBuilder(repositoryService) + .page(page) + .pageSize(pageSize) + .create() .getChangesets(); if (changesets != null && changesets.getChangesets() != null) { PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryRootResource.java index 118cc4167a..e38a6f699a 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryRootResource.java @@ -73,9 +73,10 @@ public class FileHistoryRootResource { try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { log.info("Get changesets of the file {} and revision {}", path, revision); Repository repository = repositoryService.getRepository(); - ChangesetPagingResult changesets = repositoryService.getLogCommand() - .setPagingStart(page) - .setPagingLimit(pageSize) + ChangesetPagingResult changesets = new PagedLogCommandBuilder(repositoryService) + .page(page) + .pageSize(pageSize) + .create() .setPath(path) .setStartChangeset(revision) .getChangesets(); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PagedLogCommandBuilder.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PagedLogCommandBuilder.java new file mode 100644 index 0000000000..c2af89e152 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PagedLogCommandBuilder.java @@ -0,0 +1,30 @@ +package sonia.scm.api.v2.resources; + +import sonia.scm.repository.api.LogCommandBuilder; +import sonia.scm.repository.api.RepositoryService; + +class PagedLogCommandBuilder { + private final RepositoryService repositoryService; + private int page; + private int pageSize ; + + PagedLogCommandBuilder(RepositoryService repositoryService) { + this.repositoryService = repositoryService; + } + + PagedLogCommandBuilder page(int page) { + this.page = page; + return this; + } + + PagedLogCommandBuilder pageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + LogCommandBuilder create() { + return repositoryService.getLogCommand() + .setPagingStart(page * pageSize) + .setPagingLimit(pageSize); + } +} diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java index b80b62167b..4e1a0f90f1 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java @@ -109,8 +109,8 @@ public class ChangesetRootResourceTest extends RepositoryTestBase { List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); when(changesetPagingResult.getChangesets()).thenReturn(changesetList); when(changesetPagingResult.getTotal()).thenReturn(1); - when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder); - when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingStart(0)).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingLimit(10)).thenReturn(logCommandBuilder); when(logCommandBuilder.setBranch(anyString())).thenReturn(logCommandBuilder); when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); MockHttpRequest request = MockHttpRequest @@ -126,6 +126,34 @@ public class ChangesetRootResourceTest extends RepositoryTestBase { assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); } + @Test + public void shouldGetSinglePageOfChangeSets() throws Exception { + String id = "revision_123"; + Instant creationDate = Instant.now(); + String authorName = "name"; + String authorEmail = "em@i.l"; + String commit = "my branch commit"; + ChangesetPagingResult changesetPagingResult = mock(ChangesetPagingResult.class); + List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); + when(changesetPagingResult.getChangesets()).thenReturn(changesetList); + when(changesetPagingResult.getTotal()).thenReturn(1); + when(logCommandBuilder.setPagingStart(20)).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingLimit(10)).thenReturn(logCommandBuilder); + when(logCommandBuilder.setBranch(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); + MockHttpRequest request = MockHttpRequest + .get(CHANGESET_URL + "?page=2") + .accept(VndMediaType.CHANGESET_COLLECTION); + MockHttpResponse response = new MockHttpResponse(); + dispatcher.invoke(request, response); + assertEquals(200, response.getStatus()); + log.info("Response :{}", response.getContentAsString()); + assertTrue(response.getContentAsString().contains(String.format("\"id\":\"%s\"", id))); + assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName))); + assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + } + @Test public void shouldGetChangeSet() throws Exception { String id = "revision_123"; @@ -137,8 +165,6 @@ public class ChangesetRootResourceTest extends RepositoryTestBase { List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); when(changesetPagingResult.getChangesets()).thenReturn(changesetList); when(changesetPagingResult.getTotal()).thenReturn(1); - when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder); - when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); when(logCommandBuilder.setEndChangeset(anyString())).thenReturn(logCommandBuilder); when(logCommandBuilder.setStartChangeset(anyString())).thenReturn(logCommandBuilder); when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); From 57a4e42da6220848286278342ee6787a20bcad73 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Wed, 19 Sep 2018 17:18:24 +0200 Subject: [PATCH 038/121] Implemented paging WIP --- scm-ui/src/repos/containers/Changesets.js | 58 +++++++----- scm-ui/src/repos/modules/changesets.js | 93 ++++++++++++------- scm-ui/src/repos/modules/changesets.test.js | 2 +- .../sonia/scm/api/v2/resources/GroupDto.java | 1 - 4 files changed, 96 insertions(+), 58 deletions(-) diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 21c8211d90..50bb0041c2 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -10,10 +10,11 @@ import { import { fetchChangesets, fetchChangesetsByNamespaceNameAndBranch, - getChangesets, getFetchChangesetsFailure, isFetchChangesetsPending, - selectListAsCollection + selectListAsCollection, + fetchChangesetsByLink, + getChangesetsFromState } from "../modules/changesets"; import type { History } from "history"; import { @@ -34,7 +35,9 @@ type Props = { name: string, branch: string ) => void, - list: PagedCollection + list: PagedCollection, + fetchChangesetsByLink: string => void, + page: number }; class Changesets extends React.Component { @@ -44,7 +47,11 @@ class Changesets extends React.Component { } onPageChange = (link: string) => { + const { namespace, name } = this.props.repository; + const branch = this.props.match.params.branch; + this.props.fetchChangesetsByLink(namespace, name, link, branch); }; + componentDidMount() { const { namespace, name } = this.props.repository; const branchName = this.props.match.params.branch; @@ -112,28 +119,27 @@ class Changesets extends React.Component { }; } +const createKey = ( + namespace: string, + name: string, + branch?: string +): string => { + let key = `${namespace}/${name}`; + if (branch) { + key = key + `/${branch}`; + } + return key; +}; + const mapStateToProps = (state, ownProps: Props) => { const { namespace, name } = ownProps.repository; - const loading = isFetchChangesetsPending( - state, - namespace, - name, - ownProps.match.params.branch - ); - const changesets = getChangesets( - state, - namespace, - name, - ownProps.match.params.branch - ); + const { branch } = ownProps.match.params; + const key = createKey(namespace, name, branch); + const loading = isFetchChangesetsPending(state, namespace, name, branch); + const changesets = getChangesetsFromState(state, key); const branchNames = getBranchNames(namespace, name, state); - const error = getFetchChangesetsFailure( - state, - namespace, - name, - ownProps.match.params.branch - ); - const list = selectListAsCollection(state); + const error = getFetchChangesetsFailure(state, namespace, name, branch); + const list = selectListAsCollection(state, key); return { loading, @@ -160,6 +166,14 @@ const mapDispatchToProps = dispatch => { }, fetchBranchesByNamespaceAndName: (namespace: string, name: string) => { dispatch(fetchBranchesByNamespaceAndName(namespace, name)); + }, + fetchChangesetsByLink: ( + namespace: string, + name: string, + link: string, + branch?: string + ) => { + dispatch(fetchChangesetsByLink(namespace, name, link, branch)); } }; }; diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index b806fff535..658821534b 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -9,7 +9,8 @@ import { apiClient } from "@scm-manager/ui-components"; import { isPending } from "../../modules/pending"; import { getFailure } from "../../modules/failure"; import { combineReducers } from "redux"; -import type { Action, PagedCollection } from "@scm-manager/ui-types"; +import type { Action, Changeset, PagedCollection } from "@scm-manager/ui-types"; +import ChangesetAvatar from "../components/ChangesetAvatar"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -20,6 +21,26 @@ const REPO_URL = "repositories"; //TODO: Content type // actions +export function fetchChangesetsByLink( + namespace: string, + name: string, + link: string, + branch?: string +) { + return function(dispatch: any) { + // dispatch(fetchChangesetsPending(namespace, name, branch)); + return apiClient + .get(link) + .then(response => response.json()) + .then(data => { + dispatch(fetchChangesetsSuccess(data, namespace, name, branch)); + }) + .catch(cause => { + dispatch(fetchChangesetsFailure(namespace, name, cause, branch)); + }); + }; +} + export function fetchChangesetsWithOptions( namespace: string, name: string, @@ -140,36 +161,25 @@ function byKeyReducer( ): Object { switch (action.type) { case FETCH_CHANGESETS_SUCCESS: + const changesets = action.payload._embedded.changesets; + const changesetIds = changesets.map(c => c.id); const key = action.itemId; let oldChangesets = { [key]: {} }; if (state[key] !== undefined) { oldChangesets[key] = state[key]; } + const byIds = extractChangesetsByIds(changesets, oldChangesets[key].byId); return { - ...state, [key]: { - byId: extractChangesetsByIds(action.payload, oldChangesets[key].byId) - } - }; - default: - return state; - } -} - -function listReducer( - state: any = {}, - action: Action = { type: "UNKNOWN" } -): Object { - switch (action.type) { - case FETCH_CHANGESETS_SUCCESS: - const changesets = action.payload._embedded.changesets; - const changesetIds = changesets.map(c => c.id); - return { - entries: changesetIds, - entry: { - page: action.payload.page, - pageTotal: action.payload.pageTotal, - _links: action.payload._links + byId: { ...byIds }, + list: { + entries: changesetIds, + entry: { + page: action.payload.page, + pageTotal: action.payload.pageTotal, + _links: action.payload._links + } + } } }; default: @@ -178,12 +188,10 @@ function listReducer( } export default combineReducers({ - list: listReducer, byKey: byKeyReducer }); -function extractChangesetsByIds(data: any, oldChangesetsByIds: any) { - const changesets = data._embedded.changesets; +function extractChangesetsByIds(changesets: any, oldChangesetsByIds: any) { const changesetsByIds = {}; for (let changeset of changesets) { @@ -237,21 +245,38 @@ export function getFetchChangesetsFailure( ); } -const selectList = (state: Object) => { - if (state.changesets && state.changesets.list) { - return state.changesets.list; +const selectList = (state: Object, key: string) => { + if (state.changesets.byKey[key] && state.changesets.byKey[key].list) { + return state.changesets.byKey[key].list; } return {}; }; -const selectListEntry = (state: Object): Object => { - const list = selectList(state); +const selectListEntry = (state: Object, key: string): Object => { + const list = selectList(state, key); if (list.entry) { return list.entry; } return {}; }; -export const selectListAsCollection = (state: Object): PagedCollection => { - return selectListEntry(state); +export const selectListAsCollection = ( + state: Object, + key: string +): PagedCollection => { + return selectListEntry(state, key); }; + +export function getChangesetsFromState(state: Object, key: string) { + const changesetIds = selectList(state, key).entries; + if (!changesetIds) { + return null; + } + const changesetEntries: Changeset[] = []; + + for (let id of changesetIds) { + changesetEntries.push(state.changesets.byKey[key].byId[id]); + } + + return changesetEntries; +} diff --git a/scm-ui/src/repos/modules/changesets.test.js b/scm-ui/src/repos/modules/changesets.test.js index d46dff8ef7..7122ed3772 100644 --- a/scm-ui/src/repos/modules/changesets.test.js +++ b/scm-ui/src/repos/modules/changesets.test.js @@ -207,7 +207,7 @@ describe("changesets", () => { expect(newState.byKey["foo/bar"].byId["changeset3"].description).toEqual( "bar" ); - expect(newState.list).toEqual({ + expect(newState.byKey["foo/bar"].list).toEqual({ entry: { page: 1, pageTotal: 10, diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java index b847412a33..2577b46c4e 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java @@ -22,7 +22,6 @@ public class GroupDto extends HalRepresentation { private Instant lastModified; @Pattern(regexp = "^[A-z0-9\\.\\-_@]|[^ ]([A-z0-9\\.\\-_@ ]*[A-z0-9\\.\\-_@]|[^ ])?$") private String name; - @NotEmpty private String type; private Map properties; private List members; From 8fefe5ff741767fe4c3806bbaf16782e62d30912 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 20 Sep 2018 16:28:41 +0200 Subject: [PATCH 039/121] page numbers for Changesets are now present in the URL --- .../src/repos/components/ChangesetAvatar.js | 6 +- scm-ui/src/repos/containers/Changesets.js | 91 ++++++++++++++----- scm-ui/src/repos/containers/RepositoryRoot.js | 52 +++++++---- scm-ui/src/repos/modules/changesets.js | 13 ++- 4 files changed, 112 insertions(+), 50 deletions(-) diff --git a/scm-ui/src/repos/components/ChangesetAvatar.js b/scm-ui/src/repos/components/ChangesetAvatar.js index eb461d374d..f7d6ab21af 100644 --- a/scm-ui/src/repos/components/ChangesetAvatar.js +++ b/scm-ui/src/repos/components/ChangesetAvatar.js @@ -1,8 +1,8 @@ //@flow import React from "react"; -import {ExtensionPoint} from "@scm-manager/ui-extensions"; -import type {Changeset} from "@scm-manager/ui-types"; -import {Image} from "@scm-manager/ui-components"; +import { ExtensionPoint } from "@scm-manager/ui-extensions"; +import type { Changeset } from "@scm-manager/ui-types"; +import { Image } from "@scm-manager/ui-components"; type Props = { changeset: Changeset diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 48a2f0d476..a3aa093907 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -4,17 +4,18 @@ import { connect } from "react-redux"; import { ErrorNotification, Loading, + Page, Paginator } from "@scm-manager/ui-components"; import { - fetchChangesets, - fetchChangesetsByNamespaceNameAndBranch, getFetchChangesetsFailure, isFetchChangesetsPending, selectListAsCollection, fetchChangesetsByLink, - getChangesetsFromState + getChangesetsFromState, + fetchChangesetsByPage, + fetchChangesetsByBranchAndPage } from "../modules/changesets"; import type { History } from "history"; import { @@ -40,7 +41,7 @@ type Props = { page: number }; -class Changesets extends React.Component { +class Changesets extends React.PureComponent { constructor(props) { super(props); this.state = {}; @@ -56,26 +57,57 @@ class Changesets extends React.Component { const { namespace, name } = this.props.repository; const branchName = this.props.match.params.branch; const { - fetchChangesetsByNamespaceNameAndBranch, - fetchChangesetsByNamespaceAndName, - fetchBranchesByNamespaceAndName + fetchBranchesByNamespaceAndName, + fetchChangesetsByPage, + fetchChangesetsByBranchAndPage } = this.props; if (branchName) { - fetchChangesetsByNamespaceNameAndBranch(namespace, name, branchName); + fetchChangesetsByBranchAndPage( + namespace, + name, + branchName, + this.props.page + ); } else { - fetchChangesetsByNamespaceAndName(namespace, name); + fetchChangesetsByPage(namespace, name, this.props.page); } fetchBranchesByNamespaceAndName(namespace, name); } + componentDidUpdate() { + const { page, list, repository, match } = this.props; + const { namespace, name } = repository; + const branch = match.params.branch; + + if (list && (list.page || list.page === 0)) { + // backend starts paging at 0 + const statePage: number = list.page + 1; + if (page !== statePage) { + if (branch) { + this.props.history.push( + `/repo/${namespace}/${name}/${branch}/history/${statePage}` + ); + } else { + this.props.history.push( + `/repo/${namespace}/${name}/history/${statePage}` + ); + } + } + } + } + render() { const { changesets, loading, error } = this.props; + if (loading || !changesets) { return ; } + + if (error) { + return ; + } return (
- {this.renderTable()} {this.renderPaginator()}
@@ -114,7 +146,7 @@ class Changesets extends React.Component { branchChanged = (branchName: string): void => { const { history, repository } = this.props; history.push( - `/repo/${repository.namespace}/${repository.name}/history/${branchName}` + `/repo/${repository.namespace}/${repository.name}/${branchName}/history` ); }; } @@ -131,6 +163,16 @@ const createKey = ( return key; }; +const getPageFromProps = props => { + let page = props.match.params.page; + if (page) { + page = parseInt(page, 10); + } else { + page = 1; + } + return page; +}; + const mapStateToProps = (state, ownProps: Props) => { const { namespace, name } = ownProps.repository; const { branch } = ownProps.match.params; @@ -140,33 +182,34 @@ const mapStateToProps = (state, ownProps: Props) => { const branchNames = getBranchNames(namespace, name, state); const error = getFetchChangesetsFailure(state, namespace, name, branch); const list = selectListAsCollection(state, key); + const page = getPageFromProps(ownProps); return { loading, changesets, branchNames, error, - list + list, + page }; }; const mapDispatchToProps = dispatch => { return { - fetchChangesetsByNamespaceAndName: (namespace: string, name: string) => { - dispatch(fetchChangesets(namespace, name)); - }, - fetchChangesetsByNamespaceNameAndBranch: ( - namespace: string, - name: string, - branch: string - ) => { - dispatch( - fetchChangesetsByNamespaceNameAndBranch(namespace, name, branch) - ); - }, fetchBranchesByNamespaceAndName: (namespace: string, name: string) => { dispatch(fetchBranchesByNamespaceAndName(namespace, name)); }, + fetchChangesetsByPage: (namespace: string, name: string, page: number) => { + dispatch(fetchChangesetsByPage(namespace, name, page)); + }, + fetchChangesetsByBranchAndPage: ( + namespace: string, + name: string, + branch: string, + page: number + ) => { + dispatch(fetchChangesetsByBranchAndPage(namespace, name, branch, page)); + }, fetchChangesetsByLink: ( namespace: string, name: string, diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index e1352fba31..1cb7521e24 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -7,9 +7,9 @@ import { getRepository, isFetchRepoPending } from "../modules/repos"; -import {connect} from "react-redux"; -import {Route} from "react-router-dom"; -import type {Repository} from "@scm-manager/ui-types"; +import { connect } from "react-redux"; +import { Route } from "react-router-dom"; +import type { Repository } from "@scm-manager/ui-types"; import { Page, Loading, @@ -18,12 +18,12 @@ import { NavLink, Section } from "@scm-manager/ui-components"; -import {translate} from "react-i18next"; +import { translate } from "react-i18next"; import RepositoryDetails from "../components/RepositoryDetails"; import DeleteNavAction from "../components/DeleteNavAction"; import Edit from "../containers/Edit"; -import type {History} from "history"; +import type { History } from "history"; import EditNavLink from "../components/EditNavLink"; import Changesets from "./Changesets"; @@ -46,7 +46,7 @@ type Props = { class RepositoryRoot extends React.Component { componentDidMount() { - const {fetchRepo, namespace, name} = this.props; + const { fetchRepo, namespace, name } = this.props; fetchRepo(namespace, name); } @@ -71,7 +71,7 @@ class RepositoryRoot extends React.Component { }; render() { - const {loading, error, repository, t} = this.props; + const { loading, error, repository, t } = this.props; if (error) { return ( @@ -84,7 +84,7 @@ class RepositoryRoot extends React.Component { } if (!repository || loading) { - return ; + return ; } const url = this.matchedUrl(); @@ -96,33 +96,47 @@ class RepositoryRoot extends React.Component { } + component={() => } /> } + component={() => } /> } + component={() => } /> } + path={`${url}/history/:page`} + component={() => } + /> + } + /> + } />
- - - + + +
- - + +
@@ -133,7 +147,7 @@ class RepositoryRoot extends React.Component { } const mapStateToProps = (state, ownProps) => { - const {namespace, name} = ownProps.match.params; + const { namespace, name } = ownProps.match.params; const repository = getRepository(state, namespace, name); const loading = isFetchRepoPending(state, namespace, name); const error = getFetchRepoFailure(state, namespace, name); diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index 658821534b..0ab85183a8 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -10,7 +10,6 @@ import { isPending } from "../../modules/pending"; import { getFailure } from "../../modules/failure"; import { combineReducers } from "redux"; import type { Action, Changeset, PagedCollection } from "@scm-manager/ui-types"; -import ChangesetAvatar from "../components/ChangesetAvatar"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -28,7 +27,7 @@ export function fetchChangesetsByLink( branch?: string ) { return function(dispatch: any) { - // dispatch(fetchChangesetsPending(namespace, name, branch)); + dispatch(fetchChangesetsPending(namespace, name, branch)); return apiClient .get(link) .then(response => response.json()) @@ -55,6 +54,7 @@ export function fetchChangesetsWithOptions( if (suffix) { link = link + `${suffix}`; } + return function(dispatch: any) { dispatch(fetchChangesetsPending(namespace, name, branch)); return apiClient @@ -78,7 +78,7 @@ export function fetchChangesetsByPage( name: string, page: number ) { - return fetchChangesetsWithOptions(namespace, name, "", `?page=${page}`); + return fetchChangesetsWithOptions(namespace, name, "", `?page=${page - 1}`); } export function fetchChangesetsByBranchAndPage( @@ -87,7 +87,12 @@ export function fetchChangesetsByBranchAndPage( branch: string, page: number ) { - return fetchChangesetsWithOptions(namespace, name, branch, `?page=${page}`); + return fetchChangesetsWithOptions( + namespace, + name, + branch, + `?page=${page - 1}` + ); } export function fetchChangesetsByNamespaceNameAndBranch( From 9f80840c43a65318c45b362465c8efecd9b25b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 26 Sep 2018 13:19:38 +0200 Subject: [PATCH 040/121] Add branch to changeset collections Branch information is added to a changeset collection and therefore removed from single changesets for git repositories. Mercurial repositories now also set the default branch in changesets. --- .../scm/repository/ChangesetPagingResult.java | 51 ++++++++++------ .../scm/repository/GitChangesetConverter.java | 27 +------- .../repository/spi/AbstractGitCommand.java | 22 ++++++- .../scm/repository/spi/GitLogCommand.java | 23 ++++--- .../scm/repository/spi/GitLogCommandTest.java | 5 ++ .../scm/repository/spi/HgLogCommand.java | 6 +- .../spi/javahg/AbstractChangesetCommand.java | 5 +- .../scm/repository/spi/HgLogCommandTest.java | 15 +++++ .../BranchChangesetCollectionToDtoMapper.java | 4 +- .../api/v2/resources/BranchReferenceDto.java | 19 ++++++ .../ChangesetCollectionToDtoMapper.java | 5 +- .../ChangesetCollectionToDtoMapperBase.java | 19 +++++- .../v2/resources/ChangesetRootResource.java | 6 +- .../scm/api/v2/resources/CollectionDto.java | 5 ++ .../FileHistoryCollectionToDtoMapper.java | 2 +- .../ChangesetCollectionToDtoMapperTest.java | 61 +++++++++++++++++++ 16 files changed, 209 insertions(+), 66 deletions(-) create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchReferenceDto.java create mode 100644 scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperTest.java diff --git a/scm-core/src/main/java/sonia/scm/repository/ChangesetPagingResult.java b/scm-core/src/main/java/sonia/scm/repository/ChangesetPagingResult.java index 59a705e36a..ca1018b7aa 100644 --- a/scm-core/src/main/java/sonia/scm/repository/ChangesetPagingResult.java +++ b/scm-core/src/main/java/sonia/scm/repository/ChangesetPagingResult.java @@ -82,6 +82,22 @@ public class ChangesetPagingResult implements Iterable, Serializable { this.total = total; this.changesets = changesets; + this.branchName = null; + } + + /** + * Constructs a new changeset paging result for a specific branch. + * + * + * @param total total number of changesets + * @param changesets current list of fetched changesets + * @param branchName branch name this result was created for + */ + public ChangesetPagingResult(int total, List changesets, String branchName) + { + this.total = total; + this.changesets = changesets; + this.branchName = branchName; } //~--- methods -------------------------------------------------------------- @@ -158,6 +174,7 @@ public class ChangesetPagingResult implements Iterable, Serializable return MoreObjects.toStringHelper(this) .add("changesets", changesets) .add("total", total) + .add("branch", branchName) .toString(); //J+ } @@ -186,37 +203,35 @@ public class ChangesetPagingResult implements Iterable, Serializable return total; } - //~--- set methods ---------------------------------------------------------- - - /** - * Sets the current list of changesets. - * - * - * @param changesets current list of changesets - */ - public void setChangesets(List changesets) + void setChangesets(List changesets) { this.changesets = changesets; } - /** - * Sets the total number of changesets - * - * - * @param total total number of changesets - */ - public void setTotal(int total) + void setTotal(int total) { this.total = total; } + void setBranchName(String branchName) { + this.branchName = branchName; + } + + /** + * Returns the branch name this result was created for. This can either be an explicit branch ("give me all + * changesets for branch xyz") or an implicit one ("give me the changesets for the default"). + */ + public String getBranchName() { + return branchName; + } + //~--- fields --------------------------------------------------------------- - /** current list of changesets */ @XmlElement(name = "changeset") @XmlElementWrapper(name = "changesets") private List changesets; - /** total number of changesets */ private int total; + + private String branchName; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetConverter.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetConverter.java index 6936c51269..2275fbcfd0 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetConverter.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetConverter.java @@ -39,7 +39,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; -import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; @@ -51,8 +50,8 @@ import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; -import java.util.Set; //~--- JDK imports ------------------------------------------------------------ @@ -130,27 +129,9 @@ public class GitChangesetConverter implements Closeable * * @throws IOException */ - public Changeset createChangeset(RevCommit commit) throws IOException + public Changeset createChangeset(RevCommit commit) { - List branches = Lists.newArrayList(); - Set refs = repository.getAllRefsByPeeledObjectId().get(commit.getId()); - - if (Util.isNotEmpty(refs)) - { - - for (Ref ref : refs) - { - String branch = GitUtil.getBranch(ref); - - if (branch != null) - { - branches.add(branch); - } - } - - } - - return createChangeset(commit, branches); + return createChangeset(commit, Collections.emptyList()); } /** @@ -165,7 +146,6 @@ public class GitChangesetConverter implements Closeable * @throws IOException */ public Changeset createChangeset(RevCommit commit, String branch) - throws IOException { return createChangeset(commit, Lists.newArrayList(branch)); } @@ -183,7 +163,6 @@ public class GitChangesetConverter implements Closeable * @throws IOException */ public Changeset createChangeset(RevCommit commit, List branches) - throws IOException { String id = commit.getId().name(); List parentList = null; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java index d098c30b4e..ed2d06e209 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java @@ -34,7 +34,6 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import org.eclipse.jgit.lib.Repository; @@ -97,7 +96,15 @@ public class AbstractGitCommand } return commit; } - + + protected String getBranchNameOrDefault(String requestedBranch) { + if ( Strings.isNullOrEmpty(requestedBranch) ) { + return getDefaultBranchName(); + } else { + return requestedBranch; + } + } + protected ObjectId getBranchOrDefault(Repository gitRepository, String requestedBranch) throws IOException { ObjectId head; if ( Strings.isNullOrEmpty(requestedBranch) ) { @@ -107,7 +114,16 @@ public class AbstractGitCommand } return head; } - + + protected String getDefaultBranchName() { + String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); + if (!Strings.isNullOrEmpty(defaultBranchName)) { + return defaultBranchName; + } else { + return null; + } + } + protected ObjectId getDefaultBranch(Repository gitRepository) throws IOException { ObjectId head; String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java index beb79cb921..9b106e95a2 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -170,8 +170,8 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand GitChangesetConverter converter = null; RevWalk revWalk = null; - try (org.eclipse.jgit.lib.Repository gr = open()) { - if (!gr.getAllRefs().isEmpty()) { + try (org.eclipse.jgit.lib.Repository repository = open()) { + if (!repository.getAllRefs().isEmpty()) { int counter = 0; int start = request.getPagingStart(); @@ -188,18 +188,18 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand ObjectId startId = null; if (!Strings.isNullOrEmpty(request.getStartChangeset())) { - startId = gr.resolve(request.getStartChangeset()); + startId = repository.resolve(request.getStartChangeset()); } ObjectId endId = null; if (!Strings.isNullOrEmpty(request.getEndChangeset())) { - endId = gr.resolve(request.getEndChangeset()); + endId = repository.resolve(request.getEndChangeset()); } - revWalk = new RevWalk(gr); + revWalk = new RevWalk(repository); - converter = new GitChangesetConverter(gr, revWalk); + converter = new GitChangesetConverter(repository, revWalk); if (!Strings.isNullOrEmpty(request.getPath())) { revWalk.setTreeFilter( @@ -207,7 +207,8 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF)); } - ObjectId head = getBranchOrDefault(gr, request.getBranch()); + ObjectId head = getBranchOrDefault(repository, request.getBranch()); + String branch = getBranchNameOrDefault(request.getBranch()); if (head != null) { if (startId != null) { @@ -234,10 +235,14 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand } } - changesets = new ChangesetPagingResult(counter, changesetList); + if (branch != null) { + changesets = new ChangesetPagingResult(counter, changesetList, branch); + } else { + changesets = new ChangesetPagingResult(counter, changesetList); + } } else if (logger.isWarnEnabled()) { logger.warn("the repository {} seems to be empty", - repository.getName()); + this.repository.getName()); changesets = new ChangesetPagingResult(0, Collections.EMPTY_LIST); } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java index d6e6ac98d8..b1420cb885 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java @@ -45,6 +45,7 @@ import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -72,6 +73,8 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1", result.getChangesets().get(1).getId()); assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(2).getId()); assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(3).getId()); + assertNull(result.getBranchName()); + assertTrue(result.getChangesets().stream().allMatch(r -> r.getBranches().isEmpty())); // set default branch and fetch again repository.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "test-branch"); @@ -83,6 +86,8 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4", result.getChangesets().get(0).getId()); assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(1).getId()); assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(2).getId()); + assertEquals("test-branch", result.getBranchName()); + assertTrue(result.getChangesets().stream().allMatch(r -> r.getBranches().isEmpty())); } @Test diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgLogCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgLogCommand.java index 68d6913962..e9de7f7471 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgLogCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgLogCommand.java @@ -132,7 +132,11 @@ public class HgLogCommand extends AbstractCommand implements LogCommand List changesets = on(repository).rev(start + ":" + end).execute(); - result = new ChangesetPagingResult(total, changesets); + if (request.getBranch() == null) { + result = new ChangesetPagingResult(total, changesets); + } else { + result = new ChangesetPagingResult(total, changesets, request.getBranch()); + } } else { diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/javahg/AbstractChangesetCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/javahg/AbstractChangesetCommand.java index 6466eb6d11..89164a8d80 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/javahg/AbstractChangesetCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/javahg/AbstractChangesetCommand.java @@ -216,10 +216,7 @@ public abstract class AbstractChangesetCommand extends AbstractCommand String branch = in.textUpTo('\n'); - if (!BRANCH_DEFAULT.equals(branch)) - { - changeset.getBranches().add(branch); - } + changeset.getBranches().add(branch); String p1 = readId(in, changeset, PROPERTY_PARENT1_REVISION); diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgLogCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgLogCommandTest.java index 99e9fc191a..29fc46ed57 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgLogCommandTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgLogCommandTest.java @@ -88,6 +88,21 @@ public class HgLogCommandTest extends AbstractHgCommandTestBase result.getChangesets().get(2).getId()); } + @Test + public void testGetDefaultBranchInfo() { + LogCommandRequest request = new LogCommandRequest(); + + request.setPath("a.txt"); + + ChangesetPagingResult result = createComamnd().getChangesets(request); + + assertNotNull(result); + assertEquals(1, + result.getChangesets().get(0).getBranches().size()); + assertEquals("default", + result.getChangesets().get(0).getBranches().get(0)); + } + @Test public void testGetAllWithLimit() { LogCommandRequest request = new LogCommandRequest(); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java index afe8ad318b..8842d176fa 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java @@ -12,12 +12,12 @@ public class BranchChangesetCollectionToDtoMapper extends ChangesetCollectionToD @Inject public BranchChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { - super(changesetToChangesetDtoMapper); + super(changesetToChangesetDtoMapper, resourceLinks); this.resourceLinks = resourceLinks; } public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, String branch) { - return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, branch)); + return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, branch), branch); } private String createSelfLink(Repository repository, String branch) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchReferenceDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchReferenceDto.java new file mode 100644 index 0000000000..129d8d8bfa --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchReferenceDto.java @@ -0,0 +1,19 @@ +package sonia.scm.api.v2.resources; + +import de.otto.edison.hal.HalRepresentation; +import de.otto.edison.hal.Links; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@NoArgsConstructor @AllArgsConstructor @Getter @Setter +public class BranchReferenceDto extends HalRepresentation { + private String name; + + @Override + @SuppressWarnings("squid:S1185") // We want to have this method available in this package + protected HalRepresentation add(Links links) { + return super.add(links); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java index 24ee9b0ce1..87f3454e0f 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java @@ -12,10 +12,13 @@ public class ChangesetCollectionToDtoMapper extends ChangesetCollectionToDtoMapp @Inject public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { - super(changesetToChangesetDtoMapper); + super(changesetToChangesetDtoMapper, resourceLinks); this.resourceLinks = resourceLinks; } + public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, String branchName) { + return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository), branchName); + } public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository) { return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository)); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java index e29a0a92b2..a34b7d44d6 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java @@ -1,5 +1,6 @@ package sonia.scm.api.v2.resources; +import de.otto.edison.hal.Links; import sonia.scm.PageResult; import sonia.scm.repository.Changeset; import sonia.scm.repository.Repository; @@ -10,14 +11,28 @@ import java.util.function.Supplier; class ChangesetCollectionToDtoMapperBase extends PagedCollectionToDtoMapper { private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper; + private final ResourceLinks resourceLinks; - ChangesetCollectionToDtoMapperBase(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper) { + ChangesetCollectionToDtoMapperBase(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { super("changesets"); this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper; + this.resourceLinks = resourceLinks; } CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, Supplier selfLinkSupplier) { return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository)); } -} + CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, Supplier selfLinkSupplier, String branchName) { + CollectionDto collectionDto = this.map(pageNumber, pageSize, pageResult, repository, selfLinkSupplier); + collectionDto.withEmbedded("branch", createBranchReferenceDto(repository, branchName)); + return collectionDto; + } + + private BranchReferenceDto createBranchReferenceDto(Repository repository, String branchName) { + BranchReferenceDto branchReferenceDto = new BranchReferenceDto(); + branchReferenceDto.setName(branchName); + branchReferenceDto.add(Links.linkingTo().self(resourceLinks.branch().self(repository.getNamespaceAndName(), branchName)).build()); + return branchReferenceDto; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java index 717b8d7198..396d055963 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java @@ -65,7 +65,11 @@ public class ChangesetRootResource { .getChangesets(); if (changesets != null && changesets.getChangesets() != null) { PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); - return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + if (changesets.getBranchName() != null) { + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository, changesets.getBranchName())).build(); + } else { + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + } } else { return Response.ok().build(); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionDto.java index c10e18267c..b59d697c2e 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionDto.java @@ -15,4 +15,9 @@ class CollectionDto extends HalRepresentation { CollectionDto(Links links, Embedded embedded) { super(links, embedded); } + + @Override + protected HalRepresentation withEmbedded(String rel, HalRepresentation embeddedItem) { + return super.withEmbedded(rel, embeddedItem); + } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java index af7fb2ed83..57e5667c65 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java @@ -13,7 +13,7 @@ public class FileHistoryCollectionToDtoMapper extends ChangesetCollectionToDtoMa @Inject public FileHistoryCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { - super(changesetToChangesetDtoMapper); + super(changesetToChangesetDtoMapper, resourceLinks); this.resourceLinks = resourceLinks; } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperTest.java new file mode 100644 index 0000000000..69695279e6 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperTest.java @@ -0,0 +1,61 @@ +package sonia.scm.api.v2.resources; + +import org.assertj.core.api.Assertions; +import org.junit.Test; +import sonia.scm.PageResult; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.Repository; + +import java.net.URI; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ChangesetCollectionToDtoMapperTest { + + public static final Repository REPOSITORY = new Repository("", "git", "space", "name"); + public static final Changeset CHANGESET = new Changeset(); + private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper = mock(ChangesetToChangesetDtoMapper.class); + + private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, ResourceLinksMock.createMock(URI.create("/"))); + + @Test + public void shouldMapCollectionEntries() { + ChangesetDto expectedChangesetDto = new ChangesetDto(); + when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto); + + CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY); + + assertThat(collectionDto.getEmbedded().hasItem("changesets")).isTrue(); + assertThat(collectionDto.getEmbedded().getItemsBy("changesets")).containsExactly(expectedChangesetDto); + assertThat(collectionDto.getEmbedded().hasItem("branch")).isFalse(); + } + + @Test + public void shouldNotEmbedBranchIfNotSpecified() { + ChangesetDto expectedChangesetDto = new ChangesetDto(); + when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto); + + CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY); + + assertThat(collectionDto.getEmbedded().hasItem("branch")).isFalse(); + } + + @Test + public void shouldEmbedBranchIfSpecified() { + ChangesetDto expectedChangesetDto = new ChangesetDto(); + when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto); + + CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY, "someBranch"); + + assertThat(collectionDto.getEmbedded().hasItem("branch")).isTrue(); + assertThat(collectionDto.getEmbedded().getItemsBy("branch")) + .hasSize(1) + .first().matches(b -> b.getLinks().getLinkBy("self").isPresent()) + .extracting(b -> b.getLinks().getLinkBy("self").get().getHref()).first().isEqualTo("/v2/repositories/space/name/branches/someBranch"); + assertThat(collectionDto.getEmbedded().getItemsBy("branch")) + .first().extracting("name").first().isEqualTo("someBranch"); + } +} From 360bb807b91347b78c02044465e60ced14327436 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 27 Sep 2018 16:29:33 +0200 Subject: [PATCH 041/121] Fixed bug causing multiple requests for changesets Fixed bug related to displaying errors additionally: implemented i18n --- scm-ui/public/locales/en/changesets.json | 13 ---- scm-ui/public/locales/en/repos.json | 14 ++++ .../{ => changesets}/ChangesetAuthor.js | 4 +- .../{ => changesets}/ChangesetAvatar.js | 8 +- .../{ => changesets}/ChangesetId.js | 0 .../{ => changesets}/ChangesetList.js | 2 +- .../{ => changesets}/ChangesetRow.js | 13 ++-- scm-ui/src/repos/containers/Changesets.js | 47 ++++++++---- scm-ui/src/repos/containers/RepositoryRoot.js | 8 +- scm-ui/src/repos/modules/branches.js | 76 +++++++++++++------ scm-ui/src/repos/modules/changesets.js | 4 +- scm-ui/src/repos/modules/changesets.test.js | 4 +- 12 files changed, 122 insertions(+), 71 deletions(-) delete mode 100644 scm-ui/public/locales/en/changesets.json rename scm-ui/src/repos/components/{ => changesets}/ChangesetAuthor.js (95%) rename scm-ui/src/repos/components/{ => changesets}/ChangesetAvatar.js (68%) rename scm-ui/src/repos/components/{ => changesets}/ChangesetId.js (100%) rename scm-ui/src/repos/components/{ => changesets}/ChangesetList.js (83%) rename scm-ui/src/repos/components/{ => changesets}/ChangesetRow.js (80%) diff --git a/scm-ui/public/locales/en/changesets.json b/scm-ui/public/locales/en/changesets.json deleted file mode 100644 index b3e996e094..0000000000 --- a/scm-ui/public/locales/en/changesets.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "changeset": { - "id": "ID", - "description": "Description", - "contact": "Contact", - "date": "Date", - "summary": "Changeset {{id}} committed {{time}}" - }, - "author": { - "name": "Author", - "mail": "Mail" - } -} diff --git a/scm-ui/public/locales/en/repos.json b/scm-ui/public/locales/en/repos.json index 678a7a07b4..67732372a3 100644 --- a/scm-ui/public/locales/en/repos.json +++ b/scm-ui/public/locales/en/repos.json @@ -43,5 +43,19 @@ "submit": "Yes", "cancel": "No" } + }, + "changesets": { + "changeset": { + "id": "ID", + "description": "Description", + "contact": "Contact", + "date": "Date", + "summary": "Changeset {{id}} committed {{time}}" + }, + "author": { + "name": "Author", + "mail": "Mail" + }, + "branchselector-label": "Branch:" } } diff --git a/scm-ui/src/repos/components/ChangesetAuthor.js b/scm-ui/src/repos/components/changesets/ChangesetAuthor.js similarity index 95% rename from scm-ui/src/repos/components/ChangesetAuthor.js rename to scm-ui/src/repos/components/changesets/ChangesetAuthor.js index d2993daed4..d90b6674b7 100644 --- a/scm-ui/src/repos/components/ChangesetAuthor.js +++ b/scm-ui/src/repos/components/changesets/ChangesetAuthor.js @@ -11,7 +11,7 @@ export default class ChangesetAuthor extends React.Component { render() { const { changeset } = this.props; return ( - <> +
{changeset.author.name}{" "} { {changeset.author.mail} > - +
); } } diff --git a/scm-ui/src/repos/components/ChangesetAvatar.js b/scm-ui/src/repos/components/changesets/ChangesetAvatar.js similarity index 68% rename from scm-ui/src/repos/components/ChangesetAvatar.js rename to scm-ui/src/repos/components/changesets/ChangesetAvatar.js index f7d6ab21af..dc12405590 100644 --- a/scm-ui/src/repos/components/ChangesetAvatar.js +++ b/scm-ui/src/repos/components/changesets/ChangesetAvatar.js @@ -1,8 +1,8 @@ //@flow import React from "react"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; -import type { Changeset } from "@scm-manager/ui-types"; -import { Image } from "@scm-manager/ui-components"; +import type { Changeset } from "../../../../../scm-ui-components/packages/ui-types/src/index"; +import { Image } from "../../../../../scm-ui-components/packages/ui-components/src/index"; type Props = { changeset: Changeset @@ -12,7 +12,7 @@ class ChangesetAvatar extends React.Component { render() { const { changeset } = this.props; return ( -

+

{ > Logo -

+
); } } diff --git a/scm-ui/src/repos/components/ChangesetId.js b/scm-ui/src/repos/components/changesets/ChangesetId.js similarity index 100% rename from scm-ui/src/repos/components/ChangesetId.js rename to scm-ui/src/repos/components/changesets/ChangesetId.js diff --git a/scm-ui/src/repos/components/ChangesetList.js b/scm-ui/src/repos/components/changesets/ChangesetList.js similarity index 83% rename from scm-ui/src/repos/components/ChangesetList.js rename to scm-ui/src/repos/components/changesets/ChangesetList.js index b5613b3754..4dd1762e1c 100644 --- a/scm-ui/src/repos/components/ChangesetList.js +++ b/scm-ui/src/repos/components/changesets/ChangesetList.js @@ -1,7 +1,7 @@ // @flow import ChangesetRow from "./ChangesetRow"; import React from "react"; -import type { Changeset, Repository } from "@scm-manager/ui-types"; +import type { Changeset, Repository } from "../../../../../scm-ui-components/packages/ui-types/src/index"; import classNames from "classnames"; type Props = { diff --git a/scm-ui/src/repos/components/ChangesetRow.js b/scm-ui/src/repos/components/changesets/ChangesetRow.js similarity index 80% rename from scm-ui/src/repos/components/ChangesetRow.js rename to scm-ui/src/repos/components/changesets/ChangesetRow.js index 9ec3a7af58..645f3b8129 100644 --- a/scm-ui/src/repos/components/ChangesetRow.js +++ b/scm-ui/src/repos/components/changesets/ChangesetRow.js @@ -1,12 +1,15 @@ //@flow import React from "react"; -import type { Changeset, Repository } from "@scm-manager/ui-types"; +import type { + Changeset, + Repository +} from "../../../../../scm-ui-components/packages/ui-types/src/index"; import classNames from "classnames"; import { translate, Interpolate } from "react-i18next"; import ChangesetAvatar from "./ChangesetAvatar"; import ChangesetId from "./ChangesetId"; import injectSheet from "react-jss"; -import { DateFromNow } from "@scm-manager/ui-components"; +import { DateFromNow } from "../../../../../scm-ui-components/packages/ui-components/src/index"; import ChangesetAuthor from "./ChangesetAuthor"; const styles = { @@ -38,7 +41,7 @@ class ChangesetRow extends React.Component { const { changeset, classes } = this.props; const changesetLink = this.createLink(changeset); const dateFromNow = ; - const authorLine = ; + const authorLine = ; return (
@@ -50,7 +53,7 @@ class ChangesetRow extends React.Component { {changeset.description}
@@ -63,4 +66,4 @@ class ChangesetRow extends React.Component { } } -export default injectSheet(styles)(translate("changesets")(ChangesetRow)); +export default injectSheet(styles)(translate("repos")(ChangesetRow)); diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index a3aa093907..7e22e50055 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -1,10 +1,10 @@ // @flow import React from "react"; import { connect } from "react-redux"; +import { translate } from "react-i18next"; import { ErrorNotification, Loading, - Page, Paginator } from "@scm-manager/ui-components"; @@ -23,7 +23,7 @@ import { getBranchNames } from "../../repos/modules/branches"; import type { PagedCollection, Repository } from "@scm-manager/ui-types"; -import ChangesetList from "../components/ChangesetList"; +import ChangesetList from "../components/changesets/ChangesetList"; import DropDown from "../components/DropDown"; import { withRouter } from "react-router-dom"; @@ -38,7 +38,12 @@ type Props = { ) => void, list: PagedCollection, fetchChangesetsByLink: string => void, - page: number + page: number, + t: string => string +}; + +type State = { + branch: string }; class Changesets extends React.PureComponent { @@ -54,6 +59,10 @@ class Changesets extends React.PureComponent { }; componentDidMount() { + this.updateContent(); + } + + updateContent() { const { namespace, name } = this.props.repository; const branchName = this.props.match.params.branch; const { @@ -74,11 +83,16 @@ class Changesets extends React.PureComponent { fetchBranchesByNamespaceAndName(namespace, name); } - componentDidUpdate() { + componentDidUpdate(prevProps: Props, prevState: State, snapshot: any) { const { page, list, repository, match } = this.props; const { namespace, name } = repository; const branch = match.params.branch; + if (branch !== prevState.branch) { + this.updateContent(); + this.setState({ branch }); + } + if (list && (list.page || list.page === 0)) { // backend starts paging at 0 const statePage: number = list.page + 1; @@ -99,13 +113,14 @@ class Changesets extends React.PureComponent { render() { const { changesets, loading, error } = this.props; + if (error) { + return ; + } + if (loading || !changesets) { return ; } - if (error) { - return ; - } return (
{this.renderTable()} @@ -116,12 +131,14 @@ class Changesets extends React.PureComponent { renderTable = () => { const branch = this.props.match.params.branch; - const { repository, changesets, branchNames } = this.props; + const { repository, changesets, branchNames, t } = this.props; if (branchNames && branchNames.length > 0) { return (
- + { branchChanged = (branchName: string): void => { const { history, repository } = this.props; - history.push( - `/repo/${repository.namespace}/${repository.name}/${branchName}/history` - ); + if (branchName === undefined || branchName === "") { + history.push(`/repo/${repository.namespace}/${repository.name}/history`); + } else { + history.push( + `/repo/${repository.namespace}/${repository.name}/${branchName}/history` + ); + } }; } @@ -225,5 +246,5 @@ export default withRouter( connect( mapStateToProps, mapDispatchToProps - )(Changesets) + )(translate("repos")(Changesets)) ); diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index 1cb7521e24..b274540370 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -105,22 +105,22 @@ class RepositoryRoot extends React.Component { } + render={() => } /> } + render={() => } /> } + render={() => } /> } + render={() => } />
diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 82c8940df4..1bd8d30df5 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -1,5 +1,10 @@ -import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; -import {apiClient} from "@scm-manager/ui-components"; +// @flow +import { + FAILURE_SUFFIX, + PENDING_SUFFIX, + SUCCESS_SUFFIX +} from "../../modules/types"; +import { apiClient } from "@scm-manager/ui-components"; export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; export const FETCH_BRANCHES_PENDING = `${FETCH_BRANCHES}_${PENDING_SUFFIX}`; @@ -9,64 +14,81 @@ export const FETCH_BRANCHES_FAILURE = `${FETCH_BRANCHES}_${FAILURE_SUFFIX}`; const REPO_URL = "repositories"; // Fetching branches -export function fetchBranchesByNamespaceAndName(namespace: string, name: string) { - return function (dispatch: any) { +export function fetchBranchesByNamespaceAndName( + namespace: string, + name: string +) { + return function(dispatch: any) { dispatch(fetchBranchesPending(namespace, name)); - return apiClient.get(REPO_URL + "/" + namespace + "/" + name + "/branches") + return apiClient + .get(REPO_URL + "/" + namespace + "/" + name + "/branches") .then(response => response.json()) .then(data => { - dispatch(fetchBranchesSuccess(data, namespace, name)) + dispatch(fetchBranchesSuccess(data, namespace, name)); }) - .catch(cause => { - dispatch(fetchBranchesFailure(namespace, name, cause)) - }) - } + .catch(error => { + dispatch(fetchBranchesFailure(namespace, name, error)); + }); + }; } // Action creators export function fetchBranchesPending(namespace: string, name: string) { return { type: FETCH_BRANCHES_PENDING, - payload: {namespace, name}, + payload: { namespace, name }, itemId: namespace + "/" + name - } + }; } -export function fetchBranchesSuccess(data: string, namespace: string, name: string) { +export function fetchBranchesSuccess( + data: string, + namespace: string, + name: string +) { return { type: FETCH_BRANCHES_SUCCESS, - payload: {data, namespace, name}, + payload: { data, namespace, name }, itemId: namespace + "/" + name - } + }; } -export function fetchBranchesFailure(namespace: string, name: string, error: Error) { +export function fetchBranchesFailure( + namespace: string, + name: string, + error: Error +) { return { type: FETCH_BRANCHES_FAILURE, - payload: {error, namespace, name}, + payload: { error, namespace, name }, itemId: namespace + "/" + name - } + }; } // Reducers -export default function reducer(state: Object = {}, action: Action = {type: "UNKNOWN"}): Object { +export default function reducer( + state: Object = {}, + action: Action = { type: "UNKNOWN" } +): Object { switch (action.type) { case FETCH_BRANCHES_SUCCESS: const key = action.payload.namespace + "/" + action.payload.name; - let oldBranchesByNames = {[key]: {}}; + let oldBranchesByNames = { [key]: {} }; if (state[key] !== undefined) { - oldBranchesByNames[key] = state[key] + oldBranchesByNames[key] = state[key]; } return { [key]: { - byNames: extractBranchesByNames(action.payload.data, oldBranchesByNames[key].byNames) + byNames: extractBranchesByNames( + action.payload.data, + oldBranchesByNames[key].byNames + ) } }; default: return state; } - } function extractBranchesByNames(data: any, oldBranchesByNames: any): Branch[] { @@ -78,14 +100,18 @@ function extractBranchesByNames(data: any, oldBranchesByNames: any): Branch[] { } for (let name in oldBranchesByNames) { - branchesByNames[name] = oldBranchesByNames[name] + branchesByNames[name] = oldBranchesByNames[name]; } return branchesByNames; } // Selectors -export function getBranchesForNamespaceAndNameFromState(namespace: string, name: string, state: Object) { +export function getBranchesForNamespaceAndNameFromState( + namespace: string, + name: string, + state: Object +) { const key = namespace + "/" + name; if (!state.branches[key]) { return null; diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index 0ab85183a8..bcc323a937 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -140,8 +140,8 @@ function fetchChangesetsFailure( payload: { namespace, name, - branch, - error + error, + branch }, itemId: createItemId(namespace, name, branch) }; diff --git a/scm-ui/src/repos/modules/changesets.test.js b/scm-ui/src/repos/modules/changesets.test.js index 7122ed3772..40f18c2423 100644 --- a/scm-ui/src/repos/modules/changesets.test.js +++ b/scm-ui/src/repos/modules/changesets.test.js @@ -127,7 +127,7 @@ describe("changesets", () => { }); it("should fetch changesets by page", () => { - fetchMock.getOnce(DEFAULT_BRANCH_URL + "?page=5", "{}"); + fetchMock.getOnce(DEFAULT_BRANCH_URL + "?page=4", "{}"); const expectedActions = [ { @@ -149,7 +149,7 @@ describe("changesets", () => { }); it("should fetch changesets by branch and page", () => { - fetchMock.getOnce(SPECIFIC_BRANCH_URL + "?page=5", "{}"); + fetchMock.getOnce(SPECIFIC_BRANCH_URL + "?page=4", "{}"); const expectedActions = [ { From e35ec519cbfafce1ee673c9d7e17856764f31f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 28 Sep 2018 10:14:04 +0200 Subject: [PATCH 042/121] Add method to retrieve branch name from repository --- .../java/sonia/scm/repository/GitUtil.java | 29 +++++++++++++- .../repository/spi/AbstractGitCommand.java | 8 ++-- .../scm/repository/spi/GitLogCommand.java | 2 +- .../scm/repository/spi/GitLogCommandTest.java | 39 ++++++++++++++++--- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 7e145f2dd9..ed698ef00e 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -499,6 +499,33 @@ public final class GitUtil return ref; } + public static String getRepositoryHeadBranchName(org.eclipse.jgit.lib.Repository repo) { + Map refs = repo.getAllRefs(); + Ref lastHeadRef = null; + + for (Map.Entry e : refs.entrySet()) { + String key = e.getKey(); + + if (REF_HEAD.equals(key)) { + if (e.getValue().isSymbolic() && isBranch(e.getValue().getTarget().getName())) { + return getBranch(e.getValue().getTarget()); + } + } else if (key.startsWith(REF_HEAD_PREFIX)) { + if (REF_MASTER.equals(key.substring(REF_HEAD_PREFIX.length()))) { + return REF_MASTER; + } else { + lastHeadRef = e.getValue(); + } + } + } + + if (lastHeadRef == null) { + return null; + } else { + return getBranch(lastHeadRef); + } + } + /** * Method description * @@ -648,7 +675,7 @@ public final class GitUtil return tagName; } - + /** * Method description * diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java index ed2d06e209..db7adce3f8 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java @@ -97,9 +97,9 @@ public class AbstractGitCommand return commit; } - protected String getBranchNameOrDefault(String requestedBranch) { + protected String getBranchNameOrDefault(Repository gitRepository, String requestedBranch) { if ( Strings.isNullOrEmpty(requestedBranch) ) { - return getDefaultBranchName(); + return getDefaultBranchName(gitRepository); } else { return requestedBranch; } @@ -115,12 +115,12 @@ public class AbstractGitCommand return head; } - protected String getDefaultBranchName() { + protected String getDefaultBranchName(Repository gitRepository) { String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); if (!Strings.isNullOrEmpty(defaultBranchName)) { return defaultBranchName; } else { - return null; + return GitUtil.getRepositoryHeadBranchName(gitRepository); } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java index 9b106e95a2..146962fa80 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -208,7 +208,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand } ObjectId head = getBranchOrDefault(repository, request.getBranch()); - String branch = getBranchNameOrDefault(request.getBranch()); + String branch = getBranchNameOrDefault(repository,request.getBranch()); if (head != null) { if (startId != null) { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java index b1420cb885..2709646aba 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java @@ -1,3 +1,4 @@ + /** * Copyright (c) 2010, Sebastian Sdorra * All rights reserved. @@ -33,24 +34,24 @@ package sonia.scm.repository.spi; -//~--- non-JDK imports -------------------------------------------------------- - +import com.google.common.io.Files; import org.junit.Test; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.GitConstants; import sonia.scm.repository.Modifications; +import java.io.File; +import java.io.IOException; + +import static java.nio.charset.Charset.defaultCharset; import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -//~--- JDK imports ------------------------------------------------------------ - /** * Unit tests for {@link GitLogCommand}. * @@ -73,7 +74,7 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1", result.getChangesets().get(1).getId()); assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(2).getId()); assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(3).getId()); - assertNull(result.getBranchName()); + assertEquals("master", result.getBranchName()); assertTrue(result.getChangesets().stream().allMatch(r -> r.getBranches().isEmpty())); // set default branch and fetch again @@ -215,6 +216,32 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", c2.getId()); } + @Test + public void shouldFindDefaultBranchFromHEAD() throws Exception { + setRepositoryHeadReference("ref: refs/heads/test-branch"); + + ChangesetPagingResult changesets = createCommand().getChangesets(new LogCommandRequest()); + + assertEquals("test-branch", changesets.getBranchName()); + } + + @Test + public void shouldFindMasterBranchWhenHEADisNoRef() throws Exception { + setRepositoryHeadReference("592d797cd36432e591416e8b2b98154f4f163411"); + + ChangesetPagingResult changesets = createCommand().getChangesets(new LogCommandRequest()); + + assertEquals("master", changesets.getBranchName()); + } + + private void setRepositoryHeadReference(String s) throws IOException { + Files.write(s, repositoryHeadReferenceFile(), defaultCharset()); + } + + private File repositoryHeadReferenceFile() { + return new File(repositoryDirectory, "HEAD"); + } + private GitLogCommand createCommand() { return new GitLogCommand(createContext(), repository); From 964f2eab2ed2f3cd3749e8114e80fa9e2ff10a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 28 Sep 2018 11:18:36 +0200 Subject: [PATCH 043/121] Remove duplication --- .../java/sonia/scm/repository/GitUtil.java | 95 ++++++------------- 1 file changed, 31 insertions(+), 64 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index ed698ef00e..d317f07445 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -63,8 +63,12 @@ import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.util.Map; +import java.util.Optional; import java.util.concurrent.TimeUnit; +import static java.util.Optional.of; +import static java.util.Optional.ofNullable; + //~--- JDK imports ------------------------------------------------------------ /** @@ -500,76 +504,16 @@ public final class GitUtil } public static String getRepositoryHeadBranchName(org.eclipse.jgit.lib.Repository repo) { - Map refs = repo.getAllRefs(); - Ref lastHeadRef = null; - - for (Map.Entry e : refs.entrySet()) { - String key = e.getKey(); - - if (REF_HEAD.equals(key)) { - if (e.getValue().isSymbolic() && isBranch(e.getValue().getTarget().getName())) { - return getBranch(e.getValue().getTarget()); - } - } else if (key.startsWith(REF_HEAD_PREFIX)) { - if (REF_MASTER.equals(key.substring(REF_HEAD_PREFIX.length()))) { - return REF_MASTER; - } else { - lastHeadRef = e.getValue(); - } - } - } - - if (lastHeadRef == null) { - return null; - } else { - return getBranch(lastHeadRef); - } + return getRepositoryHeadRef(repo).map(GitUtil::getBranch).orElse(null); } - /** - * Method description - * - * - * @param repo - * - * @return - * - * @throws IOException - */ public static ObjectId getRepositoryHead(org.eclipse.jgit.lib.Repository repo) throws IOException { - ObjectId id = null; - String head = null; - Map refs = repo.getAllRefs(); + Optional headRef = getRepositoryHeadRef(repo); - for (Map.Entry e : refs.entrySet()) - { - String key = e.getKey(); - - if (REF_HEAD.equals(key)) - { - head = REF_HEAD; - id = e.getValue().getObjectId(); - - break; - } - else if (key.startsWith(REF_HEAD_PREFIX)) - { - id = e.getValue().getObjectId(); - head = key.substring(REF_HEAD_PREFIX.length()); - - if (REF_MASTER.equals(head)) - { - break; - } - } - } - - if (id == null) - { - id = repo.resolve(Constants.HEAD); - } + String head = headRef.map(GitUtil::getBranch).orElse(null); + ObjectId id = headRef.map(Ref::getObjectId).orElse(repo.resolve(Constants.HEAD)); if (logger.isDebugEnabled()) { @@ -590,6 +534,29 @@ public final class GitUtil return id; } + public static Optional getRepositoryHeadRef(org.eclipse.jgit.lib.Repository repo) { + Map refs = repo.getAllRefs(); + Ref lastHeadRef = null; + + for (Map.Entry e : refs.entrySet()) { + String key = e.getKey(); + + if (REF_HEAD.equals(key)) { + if (e.getValue().isSymbolic() && isBranch(e.getValue().getTarget().getName())) { + return of(e.getValue().getTarget()); + } + } else if (key.startsWith(REF_HEAD_PREFIX)) { + if (REF_MASTER.equals(key.substring(REF_HEAD_PREFIX.length()))) { + return of(e.getValue()); + } else { + lastHeadRef = e.getValue(); + } + } + } + + return ofNullable(lastHeadRef); + } + /** * Method description * From 6819d6a0fe85cc4d55e40484b77d1d391a365fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 28 Sep 2018 13:17:42 +0200 Subject: [PATCH 044/121] Remove unnecessary HEAD resolving --- .../java/sonia/scm/repository/GitUtil.java | 60 +++++++++---------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index d317f07445..64226fb912 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -66,6 +66,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; +import static java.util.Optional.empty; import static java.util.Optional.of; import static java.util.Optional.ofNullable; @@ -507,35 +508,13 @@ public final class GitUtil return getRepositoryHeadRef(repo).map(GitUtil::getBranch).orElse(null); } - public static ObjectId getRepositoryHead(org.eclipse.jgit.lib.Repository repo) - throws IOException - { - Optional headRef = getRepositoryHeadRef(repo); - - String head = headRef.map(GitUtil::getBranch).orElse(null); - ObjectId id = headRef.map(Ref::getObjectId).orElse(repo.resolve(Constants.HEAD)); - - if (logger.isDebugEnabled()) - { - if ((head != null) && (id != null)) - { - logger.debug("use {}:{} as repository head", head, id.name()); - } - else if (id != null) - { - logger.debug("use {} as repository head", id.name()); - } - else - { - logger.warn("could not find repository head"); - } - } - - return id; + public static ObjectId getRepositoryHead(org.eclipse.jgit.lib.Repository repo) { + return getRepositoryHeadRef(repo).map(Ref::getObjectId).orElse(null); } public static Optional getRepositoryHeadRef(org.eclipse.jgit.lib.Repository repo) { Map refs = repo.getAllRefs(); + Optional foundRef = empty(); Ref lastHeadRef = null; for (Map.Entry e : refs.entrySet()) { @@ -543,18 +522,33 @@ public final class GitUtil if (REF_HEAD.equals(key)) { if (e.getValue().isSymbolic() && isBranch(e.getValue().getTarget().getName())) { - return of(e.getValue().getTarget()); - } - } else if (key.startsWith(REF_HEAD_PREFIX)) { - if (REF_MASTER.equals(key.substring(REF_HEAD_PREFIX.length()))) { - return of(e.getValue()); - } else { - lastHeadRef = e.getValue(); + foundRef = of(e.getValue().getTarget()); + break; } + } else if (key.startsWith(REF_HEAD_PREFIX) && REF_MASTER.equals(key.substring(REF_HEAD_PREFIX.length()))) { + foundRef = of(e.getValue()); + break; + } else { + lastHeadRef = e.getValue(); } } - return ofNullable(lastHeadRef); + if (!foundRef.isPresent()) { + foundRef = ofNullable(lastHeadRef); + } + + if (foundRef.isPresent()) { + if (logger.isDebugEnabled()) { + logger.debug("use {}:{} as repository head for directory {}", + foundRef.map(GitUtil::getBranch).orElse(null), + foundRef.map(Ref::getObjectId).orElse(null).name(), + repo.getDirectory()); + } + } else { + logger.warn("could not find repository head in directory {}", repo.getDirectory()); + } + + return foundRef; } /** From 3dd632888b0bc0d3344a602bfd6276ff559ad79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 28 Sep 2018 16:09:09 +0200 Subject: [PATCH 045/121] Fix optional mapping --- .../src/main/java/sonia/scm/repository/GitUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 64226fb912..0f6daff0e0 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -541,7 +541,7 @@ public final class GitUtil if (logger.isDebugEnabled()) { logger.debug("use {}:{} as repository head for directory {}", foundRef.map(GitUtil::getBranch).orElse(null), - foundRef.map(Ref::getObjectId).orElse(null).name(), + foundRef.map(Ref::getObjectId).map(ObjectId::name).orElse(null), repo.getDirectory()); } } else { From 0356af9ced8cf91d6c0d0203f4323f651041695d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 28 Sep 2018 16:19:41 +0200 Subject: [PATCH 046/121] Fix head ref computation --- .../src/main/java/sonia/scm/repository/GitUtil.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 0f6daff0e0..aac0557d7f 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -525,11 +525,13 @@ public final class GitUtil foundRef = of(e.getValue().getTarget()); break; } - } else if (key.startsWith(REF_HEAD_PREFIX) && REF_MASTER.equals(key.substring(REF_HEAD_PREFIX.length()))) { - foundRef = of(e.getValue()); - break; - } else { - lastHeadRef = e.getValue(); + } else if (key.startsWith(REF_HEAD_PREFIX)) { + if (REF_MASTER.equals(key.substring(REF_HEAD_PREFIX.length()))) { + foundRef = of(e.getValue()); + break; + } else { + lastHeadRef = e.getValue(); + } } } From 4b7940ac50b96309150826117431563247c9d30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 2 Oct 2018 13:20:52 +0200 Subject: [PATCH 047/121] Cleanup computation of default branch --- .../java/sonia/scm/repository/GitUtil.java | 57 +++++++++---------- .../repository/spi/AbstractGitCommand.java | 37 +++++------- .../scm/repository/spi/GitLogCommand.java | 9 ++- 3 files changed, 45 insertions(+), 58 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index aac0557d7f..3590809795 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -39,6 +39,8 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +import lombok.AllArgsConstructor; +import lombok.Getter; import org.eclipse.jgit.api.FetchCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; @@ -66,9 +68,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; -import static java.util.Optional.empty; import static java.util.Optional.of; -import static java.util.Optional.ofNullable; //~--- JDK imports ------------------------------------------------------------ @@ -504,40 +504,12 @@ public final class GitUtil return ref; } - public static String getRepositoryHeadBranchName(org.eclipse.jgit.lib.Repository repo) { - return getRepositoryHeadRef(repo).map(GitUtil::getBranch).orElse(null); - } - public static ObjectId getRepositoryHead(org.eclipse.jgit.lib.Repository repo) { return getRepositoryHeadRef(repo).map(Ref::getObjectId).orElse(null); } public static Optional getRepositoryHeadRef(org.eclipse.jgit.lib.Repository repo) { - Map refs = repo.getAllRefs(); - Optional foundRef = empty(); - Ref lastHeadRef = null; - - for (Map.Entry e : refs.entrySet()) { - String key = e.getKey(); - - if (REF_HEAD.equals(key)) { - if (e.getValue().isSymbolic() && isBranch(e.getValue().getTarget().getName())) { - foundRef = of(e.getValue().getTarget()); - break; - } - } else if (key.startsWith(REF_HEAD_PREFIX)) { - if (REF_MASTER.equals(key.substring(REF_HEAD_PREFIX.length()))) { - foundRef = of(e.getValue()); - break; - } else { - lastHeadRef = e.getValue(); - } - } - } - - if (!foundRef.isPresent()) { - foundRef = ofNullable(lastHeadRef); - } + Optional foundRef = findMostAppropriateHead(repo.getAllRefs()); if (foundRef.isPresent()) { if (logger.isDebugEnabled()) { @@ -553,6 +525,29 @@ public final class GitUtil return foundRef; } + private static Optional findMostAppropriateHead(Map refs) { + Ref refHead = refs.get(REF_HEAD); + if (refHead != null && refHead.isSymbolic() && isBranch(refHead.getTarget().getName())) { + return of(refHead); + } + + Ref master = refs.get(REF_HEAD_PREFIX + REF_MASTER); + if (master != null) { + return of(master); + } + + Ref defaultBranch = refs.get(REF_HEAD_PREFIX + "default"); + if (defaultBranch != null) { + return of(defaultBranch); + } + + return refs.entrySet() + .stream() + .filter(e -> e.getKey().startsWith(REF_HEAD_PREFIX)) + .map(Map.Entry::getValue) + .findFirst(); + } + /** * Method description * diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java index db7adce3f8..f12d1920c7 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java @@ -35,11 +35,16 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.base.Strings; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; +import java.util.Optional; + import org.eclipse.jgit.lib.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -97,30 +102,12 @@ public class AbstractGitCommand return commit; } - protected String getBranchNameOrDefault(Repository gitRepository, String requestedBranch) { + protected BranchWithId getBranchOrDefault(Repository gitRepository, String requestedBranch) throws IOException { if ( Strings.isNullOrEmpty(requestedBranch) ) { - return getDefaultBranchName(gitRepository); + Optional repositoryHeadRef = GitUtil.getRepositoryHeadRef(gitRepository); + return repositoryHeadRef.map(r -> new BranchWithId(GitUtil.getBranch(r), r.getObjectId())).orElse(null); } else { - return requestedBranch; - } - } - - protected ObjectId getBranchOrDefault(Repository gitRepository, String requestedBranch) throws IOException { - ObjectId head; - if ( Strings.isNullOrEmpty(requestedBranch) ) { - head = getDefaultBranch(gitRepository); - } else { - head = GitUtil.getBranchId(gitRepository, requestedBranch); - } - return head; - } - - protected String getDefaultBranchName(Repository gitRepository) { - String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); - if (!Strings.isNullOrEmpty(defaultBranchName)) { - return defaultBranchName; - } else { - return GitUtil.getRepositoryHeadBranchName(gitRepository); + return new BranchWithId(requestedBranch, GitUtil.getBranchId(gitRepository, requestedBranch)); } } @@ -143,4 +130,10 @@ public class AbstractGitCommand /** Field description */ protected sonia.scm.repository.Repository repository; + + @Getter @AllArgsConstructor + static class BranchWithId { + private final String name; + private final ObjectId objectId; + } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java index 146962fa80..6d742012ae 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -207,14 +207,13 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF)); } - ObjectId head = getBranchOrDefault(repository, request.getBranch()); - String branch = getBranchNameOrDefault(repository,request.getBranch()); + BranchWithId branch = getBranchOrDefault(repository,request.getBranch()); - if (head != null) { + if (branch != null) { if (startId != null) { revWalk.markStart(revWalk.lookupCommit(startId)); } else { - revWalk.markStart(revWalk.lookupCommit(head)); + revWalk.markStart(revWalk.lookupCommit(branch.getObjectId())); } Iterator iterator = revWalk.iterator(); @@ -236,7 +235,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand } if (branch != null) { - changesets = new ChangesetPagingResult(counter, changesetList, branch); + changesets = new ChangesetPagingResult(counter, changesetList, branch.getName()); } else { changesets = new ChangesetPagingResult(counter, changesetList); } From 5a1f15b8c8ce4cbc0f1aead8b23d255a1fb4afb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 2 Oct 2018 13:41:20 +0200 Subject: [PATCH 048/121] Fix usage of default branch --- .../java/sonia/scm/repository/GitUtil.java | 18 +++++---------- .../repository/spi/AbstractGitCommand.java | 22 +++++++++---------- .../scm/repository/spi/GitLogCommand.java | 5 +++-- .../scm/repository/spi/GitLogCommandTest.java | 2 +- 4 files changed, 21 insertions(+), 26 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 3590809795..803348dc33 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -350,12 +350,11 @@ public final class GitUtil * * @throws IOException */ - public static ObjectId getBranchId(org.eclipse.jgit.lib.Repository repo, + public static Ref getBranchId(org.eclipse.jgit.lib.Repository repo, String branchName) throws IOException { - ObjectId branchId = null; - + Ref ref = null; if (!branchName.startsWith(REF_HEAD)) { branchName = PREFIX_HEADS.concat(branchName); @@ -365,24 +364,19 @@ public final class GitUtil try { - Ref ref = repo.findRef(branchName); + ref = repo.findRef(branchName); - if (ref != null) - { - branchId = ref.getObjectId(); - } - else if (logger.isWarnEnabled()) + if (ref == null) { logger.warn("could not find branch for {}", branchName); } - } catch (IOException ex) { logger.warn("error occured during resolve of branch id", ex); } - return branchId; + return ref; } /** @@ -528,7 +522,7 @@ public final class GitUtil private static Optional findMostAppropriateHead(Map refs) { Ref refHead = refs.get(REF_HEAD); if (refHead != null && refHead.isSymbolic() && isBranch(refHead.getTarget().getName())) { - return of(refHead); + return of(refHead.getTarget()); } Ref master = refs.get(REF_HEAD_PREFIX + REF_MASTER); diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java index f12d1920c7..8e1a48ed1d 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java @@ -102,12 +102,17 @@ public class AbstractGitCommand return commit; } - protected BranchWithId getBranchOrDefault(Repository gitRepository, String requestedBranch) throws IOException { + protected Ref getBranchOrDefault(Repository gitRepository, String requestedBranch) throws IOException { if ( Strings.isNullOrEmpty(requestedBranch) ) { - Optional repositoryHeadRef = GitUtil.getRepositoryHeadRef(gitRepository); - return repositoryHeadRef.map(r -> new BranchWithId(GitUtil.getBranch(r), r.getObjectId())).orElse(null); + String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); + if (!Strings.isNullOrEmpty(defaultBranchName)) { + return GitUtil.getBranchId(gitRepository, defaultBranchName); + } else { + Optional repositoryHeadRef = GitUtil.getRepositoryHeadRef(gitRepository); + return repositoryHeadRef.orElse(null); + } } else { - return new BranchWithId(requestedBranch, GitUtil.getBranchId(gitRepository, requestedBranch)); + return GitUtil.getBranchId(gitRepository, requestedBranch); } } @@ -115,7 +120,8 @@ public class AbstractGitCommand ObjectId head; String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); if (!Strings.isNullOrEmpty(defaultBranchName)) { - head = GitUtil.getBranchId(gitRepository, defaultBranchName); + Ref ref = GitUtil.getBranchId(gitRepository, defaultBranchName); + head = ref == null? null: ref.getObjectId(); } else { logger.trace("no default branch configured, use repository head as default"); head = GitUtil.getRepositoryHead(gitRepository); @@ -130,10 +136,4 @@ public class AbstractGitCommand /** Field description */ protected sonia.scm.repository.Repository repository; - - @Getter @AllArgsConstructor - static class BranchWithId { - private final String name; - private final ObjectId objectId; - } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java index 6d742012ae..4e9261f517 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -39,6 +39,7 @@ import com.google.common.base.Strings; import com.google.common.collect.Lists; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; @@ -207,7 +208,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF)); } - BranchWithId branch = getBranchOrDefault(repository,request.getBranch()); + Ref branch = getBranchOrDefault(repository,request.getBranch()); if (branch != null) { if (startId != null) { @@ -235,7 +236,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand } if (branch != null) { - changesets = new ChangesetPagingResult(counter, changesetList, branch.getName()); + changesets = new ChangesetPagingResult(counter, changesetList, GitUtil.getBranch(branch.getName())); } else { changesets = new ChangesetPagingResult(counter, changesetList); } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java index 2709646aba..78db8ae686 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java @@ -83,11 +83,11 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase result = createCommand().getChangesets(new LogCommandRequest()); assertNotNull(result); + assertEquals("test-branch", result.getBranchName()); assertEquals(3, result.getTotal()); assertEquals("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4", result.getChangesets().get(0).getId()); assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(1).getId()); assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(2).getId()); - assertEquals("test-branch", result.getBranchName()); assertTrue(result.getChangesets().stream().allMatch(r -> r.getBranches().isEmpty())); } From de6b94fa4c220b17e4ed74c74f113768c4f6067f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 2 Oct 2018 13:44:22 +0200 Subject: [PATCH 049/121] Remove code duplication --- .../repository/spi/AbstractGitCommand.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java index 8e1a48ed1d..df21d61eef 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java @@ -102,12 +102,22 @@ public class AbstractGitCommand return commit; } + protected ObjectId getDefaultBranch(Repository gitRepository) throws IOException { + Ref ref = getBranchOrDefault(gitRepository, null); + if (ref == null) { + return null; + } else { + return ref.getObjectId(); + } + } + protected Ref getBranchOrDefault(Repository gitRepository, String requestedBranch) throws IOException { if ( Strings.isNullOrEmpty(requestedBranch) ) { String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); if (!Strings.isNullOrEmpty(defaultBranchName)) { return GitUtil.getBranchId(gitRepository, defaultBranchName); } else { + logger.trace("no default branch configured, use repository head as default"); Optional repositoryHeadRef = GitUtil.getRepositoryHeadRef(gitRepository); return repositoryHeadRef.orElse(null); } @@ -116,19 +126,6 @@ public class AbstractGitCommand } } - protected ObjectId getDefaultBranch(Repository gitRepository) throws IOException { - ObjectId head; - String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); - if (!Strings.isNullOrEmpty(defaultBranchName)) { - Ref ref = GitUtil.getBranchId(gitRepository, defaultBranchName); - head = ref == null? null: ref.getObjectId(); - } else { - logger.trace("no default branch configured, use repository head as default"); - head = GitUtil.getRepositoryHead(gitRepository); - } - return head; - } - //~--- fields --------------------------------------------------------------- /** Field description */ From 562978e6232496e02ad9f1e7ad0195e40f7917ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 4 Oct 2018 15:46:17 +0200 Subject: [PATCH 050/121] Remove scm logo from changesets --- .../components/changesets/ChangesetAvatar.js | 21 +++++++++++-------- .../components/changesets/ChangesetRow.js | 4 +--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/scm-ui/src/repos/components/changesets/ChangesetAvatar.js b/scm-ui/src/repos/components/changesets/ChangesetAvatar.js index dc12405590..0a5afc1778 100644 --- a/scm-ui/src/repos/components/changesets/ChangesetAvatar.js +++ b/scm-ui/src/repos/components/changesets/ChangesetAvatar.js @@ -12,15 +12,18 @@ class ChangesetAvatar extends React.Component { render() { const { changeset } = this.props; return ( -
- - Logo - -
+ + {/* extension should render something like this: */} + {/*
*/} + {/*
*/} + {/* Logo */} + {/*
*/} + {/*
*/} +
); } } diff --git a/scm-ui/src/repos/components/changesets/ChangesetRow.js b/scm-ui/src/repos/components/changesets/ChangesetRow.js index 645f3b8129..fca5c53d9b 100644 --- a/scm-ui/src/repos/components/changesets/ChangesetRow.js +++ b/scm-ui/src/repos/components/changesets/ChangesetRow.js @@ -44,9 +44,7 @@ class ChangesetRow extends React.Component { const authorLine = ; return (
-
- -
+

From e688da4d91c918c5322c78f951284b178aa84d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 4 Oct 2018 15:52:17 +0200 Subject: [PATCH 051/121] Add space between changeset list and paginator --- scm-ui/src/repos/containers/Changesets.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 7e22e50055..0e0ca3f172 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -123,19 +123,19 @@ class Changesets extends React.PureComponent { return (

- {this.renderTable()} + {this.renderList()} {this.renderPaginator()}
); } - renderTable = () => { + renderList = () => { const branch = this.props.match.params.branch; const { repository, changesets, branchNames, t } = this.props; if (branchNames && branchNames.length > 0) { return ( -
+ <> @@ -145,7 +145,7 @@ class Changesets extends React.PureComponent { optionSelected={branch => this.branchChanged(branch)} /> -
+ ); } From 7019073b93243fb7d283c19f9bf875b190344fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 4 Oct 2018 16:00:02 +0200 Subject: [PATCH 052/121] Fix wrong div in p --- scm-ui/src/repos/components/changesets/ChangesetAuthor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm-ui/src/repos/components/changesets/ChangesetAuthor.js b/scm-ui/src/repos/components/changesets/ChangesetAuthor.js index d90b6674b7..d2993daed4 100644 --- a/scm-ui/src/repos/components/changesets/ChangesetAuthor.js +++ b/scm-ui/src/repos/components/changesets/ChangesetAuthor.js @@ -11,7 +11,7 @@ export default class ChangesetAuthor extends React.Component { render() { const { changeset } = this.props; return ( -
+ <> {changeset.author.name}{" "} { {changeset.author.mail} > -
+ ); } } From 8e23a85e7c9650fa38591ead592e812e5e77b9bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 4 Oct 2018 16:09:12 +0200 Subject: [PATCH 053/121] Render branch chosser as own box --- scm-ui/src/repos/containers/Changesets.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 0e0ca3f172..04c4ec1885 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -136,14 +136,16 @@ class Changesets extends React.PureComponent { if (branchNames && branchNames.length > 0) { return ( <> - - this.branchChanged(branch)} - /> +
+ + this.branchChanged(branch)} + /> +
); From 35bbb44aaa3e5bcacc58db181e894785da9d3bf1 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 4 Oct 2018 17:12:38 +0200 Subject: [PATCH 054/121] Started refactoring Changeset listing --- .../components/changesets/ChangesetRow.js | 2 +- scm-ui/src/repos/containers/Changesets.js | 60 ++--- scm-ui/src/repos/modules/branches.js | 62 +++-- scm-ui/src/repos/modules/branches.test.js | 241 ++++++++++-------- scm-ui/src/repos/modules/changesets.js | 121 ++++----- scm-ui/src/repos/modules/changesets.test.js | 75 ++++-- 6 files changed, 289 insertions(+), 272 deletions(-) diff --git a/scm-ui/src/repos/components/changesets/ChangesetRow.js b/scm-ui/src/repos/components/changesets/ChangesetRow.js index 645f3b8129..02a97c8da0 100644 --- a/scm-ui/src/repos/components/changesets/ChangesetRow.js +++ b/scm-ui/src/repos/components/changesets/ChangesetRow.js @@ -58,7 +58,7 @@ class ChangesetRow extends React.Component { time={dateFromNow} />

{" "} -

{authorLine}

+
{authorLine}
diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 7e22e50055..45f72fb5a7 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -15,17 +15,15 @@ import { fetchChangesetsByLink, getChangesetsFromState, fetchChangesetsByPage, - fetchChangesetsByBranchAndPage + fetchChangesetsByBranchAndPage, + fetchChangesets } from "../modules/changesets"; import type { History } from "history"; -import { - fetchBranchesByNamespaceAndName, - getBranchNames -} from "../../repos/modules/branches"; import type { PagedCollection, Repository } from "@scm-manager/ui-types"; import ChangesetList from "../components/changesets/ChangesetList"; import DropDown from "../components/DropDown"; import { withRouter } from "react-router-dom"; +import { fetchBranches, getBranchNames } from "../modules/branches"; type Props = { repository: Repository, @@ -53,9 +51,9 @@ class Changesets extends React.PureComponent { } onPageChange = (link: string) => { - const { namespace, name } = this.props.repository; + const { repository } = this.props; const branch = this.props.match.params.branch; - this.props.fetchChangesetsByLink(namespace, name, link, branch); + this.props.fetchChangesetsByLink(repository, link, branch); }; componentDidMount() { @@ -63,24 +61,20 @@ class Changesets extends React.PureComponent { } updateContent() { - const { namespace, name } = this.props.repository; + const { repository } = this.props; + const branchName = this.props.match.params.branch; const { - fetchBranchesByNamespaceAndName, fetchChangesetsByPage, - fetchChangesetsByBranchAndPage + fetchChangesetsByBranchAndPage, + fetchBranches } = this.props; if (branchName) { - fetchChangesetsByBranchAndPage( - namespace, - name, - branchName, - this.props.page - ); + fetchChangesetsByBranchAndPage(repository, branchName, this.props.page); } else { - fetchChangesetsByPage(namespace, name, this.props.page); + fetchChangesetsByPage(repository, this.props.page); } - fetchBranchesByNamespaceAndName(namespace, name); + fetchBranches(repository); } componentDidUpdate(prevProps: Props, prevState: State, snapshot: any) { @@ -149,7 +143,7 @@ class Changesets extends React.PureComponent { ); } - return ; + return ; }; renderPaginator() { @@ -195,13 +189,14 @@ const getPageFromProps = props => { }; const mapStateToProps = (state, ownProps: Props) => { + const { repository } = ownProps; const { namespace, name } = ownProps.repository; const { branch } = ownProps.match.params; const key = createKey(namespace, name, branch); - const loading = isFetchChangesetsPending(state, namespace, name, branch); + const loading = isFetchChangesetsPending(state, repository, branch); const changesets = getChangesetsFromState(state, key); - const branchNames = getBranchNames(namespace, name, state); - const error = getFetchChangesetsFailure(state, namespace, name, branch); + const branchNames = getBranchNames(state, repository); + const error = getFetchChangesetsFailure(state, repository, branch); const list = selectListAsCollection(state, key); const page = getPageFromProps(ownProps); @@ -217,27 +212,28 @@ const mapStateToProps = (state, ownProps: Props) => { const mapDispatchToProps = dispatch => { return { - fetchBranchesByNamespaceAndName: (namespace: string, name: string) => { - dispatch(fetchBranchesByNamespaceAndName(namespace, name)); + fetchBranches: (repository: Repository) => { + dispatch(fetchBranches(repository)); }, - fetchChangesetsByPage: (namespace: string, name: string, page: number) => { - dispatch(fetchChangesetsByPage(namespace, name, page)); + fetchChangesets: (repository: Repository) => { + dispatch(fetchChangesets(repository)); + }, + fetchChangesetsByPage: (repository, page: number) => { + dispatch(fetchChangesetsByPage(repository, page)); }, fetchChangesetsByBranchAndPage: ( - namespace: string, - name: string, + repository, branch: string, page: number ) => { - dispatch(fetchChangesetsByBranchAndPage(namespace, name, branch, page)); + dispatch(fetchChangesetsByBranchAndPage(repository, branch, page)); }, fetchChangesetsByLink: ( - namespace: string, - name: string, + repository: Repository, link: string, branch?: string ) => { - dispatch(fetchChangesetsByLink(namespace, name, link, branch)); + dispatch(fetchChangesetsByLink(repository, link, branch)); } }; }; diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 1bd8d30df5..9b6a261a85 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -5,62 +5,71 @@ import { SUCCESS_SUFFIX } from "../../modules/types"; import { apiClient } from "@scm-manager/ui-components"; +import type { Repository } from "@scm-manager/ui-types"; export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; export const FETCH_BRANCHES_PENDING = `${FETCH_BRANCHES}_${PENDING_SUFFIX}`; export const FETCH_BRANCHES_SUCCESS = `${FETCH_BRANCHES}_${SUCCESS_SUFFIX}`; export const FETCH_BRANCHES_FAILURE = `${FETCH_BRANCHES}_${FAILURE_SUFFIX}`; -const REPO_URL = "repositories"; - // Fetching branches -export function fetchBranchesByNamespaceAndName( - namespace: string, - name: string -) { + +export function fetchBranches(repository: Repository) { return function(dispatch: any) { - dispatch(fetchBranchesPending(namespace, name)); + dispatch(fetchBranchesPending(repository)); return apiClient - .get(REPO_URL + "/" + namespace + "/" + name + "/branches") + .get(repository._links.branches.href) .then(response => response.json()) .then(data => { - dispatch(fetchBranchesSuccess(data, namespace, name)); + dispatch(fetchBranchesSuccess(data, repository)); }) .catch(error => { - dispatch(fetchBranchesFailure(namespace, name, error)); + dispatch(fetchBranchesFailure(repository, error)); }); }; } +// export function fetchBranchesByNamespaceAndName( +// namespace: string, +// name: string +// ) { +// return function(dispatch: any) { +// dispatch(fetchBranchesPending(namespace, name)); +// return apiClient +// .get(REPO_URL + "/" + namespace + "/" + name + "/branches") +// .then(response => response.json()) +// .then(data => { +// dispatch(fetchBranchesSuccess(data, namespace, name)); +// }) +// .catch(error => { +// dispatch(fetchBranchesFailure(namespace, name, error)); +// }); +// }; +// } // Action creators -export function fetchBranchesPending(namespace: string, name: string) { +export function fetchBranchesPending(repository: Repository) { + const { namespace, name } = repository; return { type: FETCH_BRANCHES_PENDING, - payload: { namespace, name }, + payload: { repository }, itemId: namespace + "/" + name }; } -export function fetchBranchesSuccess( - data: string, - namespace: string, - name: string -) { +export function fetchBranchesSuccess(data: string, repository: Repository) { + const { namespace, name } = repository; return { type: FETCH_BRANCHES_SUCCESS, - payload: { data, namespace, name }, + payload: { data, repository }, itemId: namespace + "/" + name }; } -export function fetchBranchesFailure( - namespace: string, - name: string, - error: Error -) { +export function fetchBranchesFailure(repository: Repository, error: Error) { + const { namespace, name } = repository; return { type: FETCH_BRANCHES_FAILURE, - payload: { error, namespace, name }, + payload: { error, repository }, itemId: namespace + "/" + name }; } @@ -73,7 +82,7 @@ export default function reducer( ): Object { switch (action.type) { case FETCH_BRANCHES_SUCCESS: - const key = action.payload.namespace + "/" + action.payload.name; + const key = action.itemId; let oldBranchesByNames = { [key]: {} }; if (state[key] !== undefined) { oldBranchesByNames[key] = state[key]; @@ -119,7 +128,8 @@ export function getBranchesForNamespaceAndNameFromState( return Object.values(state.branches[key].byNames); } -export function getBranchNames(namespace: string, name: string, state: Object) { +export function getBranchNames(state: Object, repository: Repository) { + const { namespace, name } = repository; const key = namespace + "/" + name; if (!state.branches[key] || !state.branches[key].byNames) { return null; diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index d97d9aa7bf..361032c78a 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -5,148 +5,163 @@ import { FETCH_BRANCHES_FAILURE, FETCH_BRANCHES_PENDING, FETCH_BRANCHES_SUCCESS, - fetchBranchesByNamespaceAndName, getBranchesForNamespaceAndNameFromState, getBranchNames + fetchBranches, + getBranchNames } from "./branches"; import reducer from "./branches"; - const namespace = "foo"; const name = "bar"; const key = namespace + "/" + name; +const repository = { + namespace: "foo", + name: "bar", + _links: { + branches: { + href: "http://scm/api/rest/v2/repositories/foo/bar/branches" + } + } +}; -const branch1 = {name: "branch1", revision: "revision1"}; -const branch2 = {name: "branch2", revision: "revision2"}; -const branch3 = {name: "branch3", revision: "revision3"}; +const branch1 = { name: "branch1", revision: "revision1" }; +const branch2 = { name: "branch2", revision: "revision2" }; +const branch3 = { name: "branch3", revision: "revision3" }; +describe("branches", () => { + describe("fetch branches", () => { + const URL = "http://scm/api/rest/v2/repositories/foo/bar/branches"; + const mockStore = configureMockStore([thunk]); -describe("fetch branches", () => { - const URL = "/api/rest/v2/repositories/foo/bar/branches"; - const mockStore = configureMockStore([thunk]); + afterEach(() => { + fetchMock.reset(); + fetchMock.restore(); + }); + it("should fetch branches", () => { + const collection = {}; - afterEach(() => { - fetchMock.reset(); - fetchMock.restore(); - }); + fetchMock.getOnce(URL, "{}"); + const expectedActions = [ + { + type: FETCH_BRANCHES_PENDING, + payload: { repository }, + itemId: key + }, + { + type: FETCH_BRANCHES_SUCCESS, + payload: { data: collection, repository }, + itemId: key + } + ]; - it("should fetch branches", () => { - const collection = {}; + const store = mockStore({}); + return store.dispatch(fetchBranches(repository)).then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); + }); - fetchMock.getOnce(URL, "{}"); + it("should fail fetching branches on HTTP 500", () => { + const collection = {}; - const expectedActions = [ - { - type: FETCH_BRANCHES_PENDING, payload: {namespace, name}, - itemId: key - }, - { - type: FETCH_BRANCHES_SUCCESS, - payload: {data: collection, namespace, name}, - itemId: key - } - ]; + fetchMock.getOnce(URL, 500); - const store = mockStore({}); - return store.dispatch(fetchBranchesByNamespaceAndName(namespace, name)).then(() => { - expect(store.getActions()).toEqual(expectedActions); + const expectedActions = [ + { + type: FETCH_BRANCHES_PENDING, + payload: { repository }, + itemId: key + }, + { + type: FETCH_BRANCHES_FAILURE, + payload: { error: collection, repository }, + itemId: key + } + ]; + + const store = mockStore({}); + return store.dispatch(fetchBranches(repository)).then(() => { + expect(store.getActions()[0]).toEqual(expectedActions[0]); + expect(store.getActions()[1].type).toEqual(FETCH_BRANCHES_FAILURE); + }); }); }); - it("should fail fetching branches on HTTP 500", () => { - const collection = {}; - - fetchMock.getOnce(URL, 500); - - const expectedActions = [ - { - type: FETCH_BRANCHES_PENDING, payload: {namespace, name}, - itemId: key - }, - { - type: FETCH_BRANCHES_FAILURE, - payload: {error: collection, namespace, name}, - itemId: key + describe("branches reducer", () => { + const branches = { + _embedded: { + branches: [branch1, branch2] } - ]; + }; + const action = { + type: FETCH_BRANCHES_SUCCESS, + payload: { + namespace, + name, + data: branches + } + }; - const store = mockStore({}); - return store.dispatch(fetchBranchesByNamespaceAndName(namespace, name)).then(() => { - expect(store.getActions()[0]).toEqual(expectedActions[0]); - expect(store.getActions()[1].type).toEqual(FETCH_BRANCHES_FAILURE); + it("should update state according to successful fetch", () => { + const newState = reducer({}, action); + expect(newState).toBeDefined(); + expect(newState[key]).toBeDefined(); + expect(newState[key].byNames["branch1"]).toEqual(branch1); + expect(newState[key].byNames["branch2"]).toEqual(branch2); }); - }) -}); -describe("branches reducer", () => { - - const branches = { - _embedded: { - branches: [branch1, branch2] - } - }; - const action = { - type: FETCH_BRANCHES_SUCCESS, - payload: { - namespace, - name, - data: branches - } - }; - - it("should update state according to successful fetch", () => { - const newState = reducer({}, action); - expect(newState).toBeDefined(); - expect(newState[key]).toBeDefined(); - expect(newState[key].byNames["branch1"]).toEqual(branch1); - expect(newState[key].byNames["branch2"]).toEqual(branch2); - }); - - it("should not delete existing branches from state", () => { - const oldState = { - "foo/bar": { byNames: { - "branch3": branch3 - }} - }; - - const newState = reducer(oldState, action); - console.log(newState); - expect(newState[key].byNames["branch1"]).toEqual(branch1); - expect(newState[key].byNames["branch2"]).toEqual(branch2); - expect(newState[key].byNames["branch3"]).toEqual(branch3); - }); -}); - -describe("branch selectors", () => { - it("should get branches for namespace and name", () => { - const state = { - branches: { - [key]: { + it("should not delete existing branches from state", () => { + const oldState = { + "foo/bar": { byNames: { - "branch1": branch1 + branch3: branch3 } } - } - }; - const branches = getBranchesForNamespaceAndNameFromState(namespace, name, state); - expect(branches.length).toEqual(1); - expect(branches[0]).toEqual(branch1); + }; + + const newState = reducer(oldState, action); + console.log(newState); + expect(newState[key].byNames["branch1"]).toEqual(branch1); + expect(newState[key].byNames["branch2"]).toEqual(branch2); + expect(newState[key].byNames["branch3"]).toEqual(branch3); + }); }); - it("should return branches names", () => { - const state = { - branches: { - [key]: { - byNames: { - "branch1": branch1, - "branch2": branch2 + describe("branch selectors", () => { + it("should get branches for namespace and name", () => { + const state = { + branches: { + [key]: { + byNames: { + branch1: branch1 + } } } - } - }; - const names = getBranchNames(namespace, name, state); - expect(names.length).toEqual(2); - expect(names).toContain("branch1"); - expect(names).toContain("branch2"); + }; + const branches = getBranchesForNamespaceAndNameFromState( + namespace, + name, + state + ); + expect(branches.length).toEqual(1); + expect(branches[0]).toEqual(branch1); + }); + + it("should return branches names", () => { + const state = { + branches: { + [key]: { + byNames: { + branch1: branch1, + branch2: branch2 + } + } + } + }; + const names = getBranchNames(state, repository); + expect(names.length).toEqual(2); + expect(names).toContain("branch1"); + expect(names).toContain("branch2"); + }); }); }); diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index bcc323a937..dffc87268d 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -9,7 +9,12 @@ import { apiClient } from "@scm-manager/ui-components"; import { isPending } from "../../modules/pending"; import { getFailure } from "../../modules/failure"; import { combineReducers } from "redux"; -import type { Action, Changeset, PagedCollection } from "@scm-manager/ui-types"; +import type { + Action, + Changeset, + PagedCollection, + Repository +} from "@scm-manager/ui-types"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -21,137 +26,122 @@ const REPO_URL = "repositories"; // actions export function fetchChangesetsByLink( - namespace: string, - name: string, + repository: Repository, link: string, branch?: string ) { return function(dispatch: any) { - dispatch(fetchChangesetsPending(namespace, name, branch)); + dispatch(fetchChangesetsPending(repository, branch)); return apiClient .get(link) .then(response => response.json()) .then(data => { - dispatch(fetchChangesetsSuccess(data, namespace, name, branch)); + dispatch(fetchChangesetsSuccess(data, repository, branch)); }) .catch(cause => { - dispatch(fetchChangesetsFailure(namespace, name, cause, branch)); + dispatch(fetchChangesetsFailure(repository, cause, branch)); }); }; } export function fetchChangesetsWithOptions( - namespace: string, - name: string, + repository: Repository, branch?: string, suffix?: string ) { - let link = REPO_URL + `/${namespace}/${name}`; + let link = repository._links.changesets.href; + if (branch && branch !== "") { - link = link + `/branches/${branch}`; + const halBranch = repository._links.branches.find(b => b.name === branch); + link = halBranch._links.history.href; } - link = link + "/changesets"; + if (suffix) { link = link + `${suffix}`; } - return function(dispatch: any) { - dispatch(fetchChangesetsPending(namespace, name, branch)); + dispatch(fetchChangesetsPending(repository, branch)); return apiClient .get(link) .then(response => response.json()) .then(data => { - dispatch(fetchChangesetsSuccess(data, namespace, name, branch)); + dispatch(fetchChangesetsSuccess(data, repository, branch)); }) .catch(cause => { - dispatch(fetchChangesetsFailure(namespace, name, cause, branch)); + dispatch(fetchChangesetsFailure(repository, cause, branch)); }); }; } -export function fetchChangesets(namespace: string, name: string) { - return fetchChangesetsWithOptions(namespace, name); +export function fetchChangesets(repository: Repository) { + return fetchChangesetsWithOptions(repository); } -export function fetchChangesetsByPage( - namespace: string, - name: string, - page: number -) { - return fetchChangesetsWithOptions(namespace, name, "", `?page=${page - 1}`); +export function fetchChangesetsByPage(repository: Repository, page: number) { + return fetchChangesetsWithOptions(repository, "", `?page=${page - 1}`); } +// TODO: Rewrite code to fetch changesets by branches, adjust tests and let BranchChooser fetch branches export function fetchChangesetsByBranchAndPage( - namespace: string, - name: string, + repository: Repository, branch: string, page: number ) { - return fetchChangesetsWithOptions( - namespace, - name, - branch, - `?page=${page - 1}` - ); + return fetchChangesetsWithOptions(repository, branch, `?page=${page - 1}`); } -export function fetchChangesetsByNamespaceNameAndBranch( - namespace: string, - name: string, +export function fetchChangesetsByBranch( + repository: Repository, branch: string ) { - return fetchChangesetsWithOptions(namespace, name, branch); + return fetchChangesetsWithOptions(repository, branch); } export function fetchChangesetsPending( - namespace: string, - name: string, + repository: Repository, branch?: string ): Action { - const itemId = createItemId(namespace, name, branch); + const itemId = createItemId(repository, branch); + if (!branch) { + branch = ""; + } return { type: FETCH_CHANGESETS_PENDING, - payload: itemId, + payload: { repository, branch }, itemId }; } export function fetchChangesetsSuccess( changesets: any, - namespace: string, - name: string, + repository: Repository, branch?: string ): Action { return { type: FETCH_CHANGESETS_SUCCESS, payload: changesets, - itemId: createItemId(namespace, name, branch) + itemId: createItemId(repository, branch) }; } function fetchChangesetsFailure( - namespace: string, - name: string, + repository: Repository, error: Error, branch?: string ): Action { return { type: FETCH_CHANGESETS_FAILURE, payload: { - namespace, - name, + repository, error, branch }, - itemId: createItemId(namespace, name, branch) + itemId: createItemId(repository, branch) }; } -function createItemId( - namespace: string, - name: string, - branch?: string -): string { +function createItemId(repository: Repository, branch?: string): string { + const { namespace, name } = repository; let itemId = namespace + "/" + name; if (branch && branch !== "") { itemId = itemId + "/" + branch; @@ -211,13 +201,8 @@ function extractChangesetsByIds(changesets: any, oldChangesetsByIds: any) { } //selectors -export function getChangesets( - state: Object, - namespace: string, - name: string, - branch?: string -) { - const key = createItemId(namespace, name, branch); +export function getChangesets(state: Object, repository, branch?: string) { + const key = createItemId(repository, branch); if (!state.changesets.byKey[key]) { return null; } @@ -226,28 +211,18 @@ export function getChangesets( export function isFetchChangesetsPending( state: Object, - namespace: string, - name: string, + repository: Repository, branch?: string ) { - return isPending( - state, - FETCH_CHANGESETS, - createItemId(namespace, name, branch) - ); + return isPending(state, FETCH_CHANGESETS, createItemId(repository, branch)); } export function getFetchChangesetsFailure( state: Object, - namespace: string, - name: string, + repository: Repository, branch?: string ) { - return getFailure( - state, - FETCH_CHANGESETS, - createItemId(namespace, name, branch) - ); + return getFailure(state, FETCH_CHANGESETS, createItemId(repository, branch)); } const selectList = (state: Object, key: string) => { diff --git a/scm-ui/src/repos/modules/changesets.test.js b/scm-ui/src/repos/modules/changesets.test.js index 40f18c2423..0b73db5e9d 100644 --- a/scm-ui/src/repos/modules/changesets.test.js +++ b/scm-ui/src/repos/modules/changesets.test.js @@ -10,7 +10,7 @@ import { FETCH_CHANGESETS_SUCCESS, fetchChangesets, fetchChangesetsByBranchAndPage, - fetchChangesetsByNamespaceNameAndBranch, + fetchChangesetsByBranch, fetchChangesetsByPage, fetchChangesetsSuccess, getChangesets, @@ -19,13 +19,38 @@ import { } from "./changesets"; import reducer from "./changesets"; +const repository = { + namespace: "foo", + name: "bar", + _links: { + self: { + href: "http://scm/api/rest/v2/repositories/foo/bar" + }, + changesets: { + href: "http://scm/api/rest/v2/repositories/foo/bar/changesets" + }, + branches: [ + { + name: "specific", + _links: { + history: { + href: + "http://scm/api/rest/v2/repositories/foo/bar/branches/specific/changesets" + } + } + } + ] + } +}; + const changesets = {}; describe("changesets", () => { describe("fetching of changesets", () => { - const DEFAULT_BRANCH_URL = "/api/rest/v2/repositories/foo/bar/changesets"; + const DEFAULT_BRANCH_URL = + "http://scm/api/rest/v2/repositories/foo/bar/changesets"; const SPECIFIC_BRANCH_URL = - "/api/rest/v2/repositories/foo/bar/branches/specific/changesets"; + "http://scm/api/rest/v2/repositories/foo/bar/branches/specific/changesets"; const mockStore = configureMockStore([thunk]); afterEach(() => { @@ -39,7 +64,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: "foo/bar", + payload: { repository, branch: "" }, itemId: "foo/bar" }, { @@ -50,7 +75,7 @@ describe("changesets", () => { ]; const store = mockStore({}); - return store.dispatch(fetchChangesets("foo", "bar")).then(() => { + return store.dispatch(fetchChangesets(repository)).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); @@ -62,7 +87,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: itemId, + payload: { repository, branch: "specific" }, itemId }, { @@ -74,9 +99,7 @@ describe("changesets", () => { const store = mockStore({}); return store - .dispatch( - fetchChangesetsByNamespaceNameAndBranch("foo", "bar", "specific") - ) + .dispatch(fetchChangesetsByBranch(repository, "specific")) .then(() => { expect(store.getActions()).toEqual(expectedActions); }); @@ -89,13 +112,13 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: itemId, + payload: { repository, branch: "" }, itemId } ]; const store = mockStore({}); - return store.dispatch(fetchChangesets("foo", "bar")).then(() => { + return store.dispatch(fetchChangesets(repository)).then(() => { expect(store.getActions()[0]).toEqual(expectedActions[0]); expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); expect(store.getActions()[1].payload).toBeDefined(); @@ -109,16 +132,14 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: itemId, + payload: { repository, branch: "specific" }, itemId } ]; const store = mockStore({}); return store - .dispatch( - fetchChangesetsByNamespaceNameAndBranch("foo", "bar", "specific") - ) + .dispatch(fetchChangesetsByBranch(repository, "specific")) .then(() => { expect(store.getActions()[0]).toEqual(expectedActions[0]); expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); @@ -132,7 +153,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: "foo/bar", + payload: { repository, branch: "" }, itemId: "foo/bar" }, { @@ -143,7 +164,7 @@ describe("changesets", () => { ]; const store = mockStore({}); - return store.dispatch(fetchChangesetsByPage("foo", "bar", 5)).then(() => { + return store.dispatch(fetchChangesetsByPage(repository, 5)).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); @@ -154,7 +175,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: "foo/bar/specific", + payload: { repository, branch: "specific" }, itemId: "foo/bar/specific" }, { @@ -166,7 +187,7 @@ describe("changesets", () => { const store = mockStore({}); return store - .dispatch(fetchChangesetsByBranchAndPage("foo", "bar", "specific", 5)) + .dispatch(fetchChangesetsByBranchAndPage(repository, "specific", 5)) .then(() => { expect(store.getActions()).toEqual(expectedActions); }); @@ -195,7 +216,7 @@ describe("changesets", () => { it("should set state to received changesets", () => { const newState = reducer( {}, - fetchChangesetsSuccess(responseBody, "foo", "bar") + fetchChangesetsSuccess(responseBody, repository) ); expect(newState).toBeDefined(); expect(newState.byKey["foo/bar"].byId["changeset1"].author.mail).toEqual( @@ -243,7 +264,7 @@ describe("changesets", () => { } } }, - fetchChangesetsSuccess(responseBody, "foo", "bar") + fetchChangesetsSuccess(responseBody, repository) ); expect(newState.byKey["foo/bar"].byId["changeset2"]).toBeDefined(); expect(newState.byKey["foo/bar"].byId["changeset1"]).toBeDefined(); @@ -253,7 +274,7 @@ describe("changesets", () => { describe("changeset selectors", () => { const error = new Error("Something went wrong"); - it("should get all changesets for a given namespace and name", () => { + it("should get all changesets for a given repository", () => { const state = { changesets: { byKey: { @@ -266,7 +287,7 @@ describe("changesets", () => { } } }; - const result = getChangesets(state, "foo", "bar"); + const result = getChangesets(state, repository); expect(result).toContainEqual({ id: "id1" }); }); @@ -277,11 +298,11 @@ describe("changesets", () => { } }; - expect(isFetchChangesetsPending(state, "foo", "bar")).toBeTruthy(); + expect(isFetchChangesetsPending(state, repository)).toBeTruthy(); }); it("should return false, when fetching changesets is not pending", () => { - expect(isFetchChangesetsPending({}, "foo", "bar")).toEqual(false); + expect(isFetchChangesetsPending({}, repository)).toEqual(false); }); it("should return error if fetching changesets failed", () => { @@ -291,11 +312,11 @@ describe("changesets", () => { } }; - expect(getFetchChangesetsFailure(state, "foo", "bar")).toEqual(error); + expect(getFetchChangesetsFailure(state, repository)).toEqual(error); }); it("should return false if fetching changesets did not fail", () => { - expect(getFetchChangesetsFailure({}, "foo", "bar")).toBeUndefined(); + expect(getFetchChangesetsFailure({}, repository)).toBeUndefined(); }); }); }); From 1f0fea37a920ce4d7b379b84b2196c1589327f77 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 4 Oct 2018 19:03:03 +0200 Subject: [PATCH 055/121] Fixed unit test --- scm-ui/src/repos/modules/branches.js | 13 +++++------- scm-ui/src/repos/modules/branches.test.js | 26 ++--------------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 9b6a261a85..b4cddd63a3 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -1,11 +1,7 @@ // @flow -import { - FAILURE_SUFFIX, - PENDING_SUFFIX, - SUCCESS_SUFFIX -} from "../../modules/types"; -import { apiClient } from "@scm-manager/ui-components"; -import type { Repository } from "@scm-manager/ui-types"; +import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; +import {apiClient} from "@scm-manager/ui-components"; +import type {Repository} from "@scm-manager/ui-types"; export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; export const FETCH_BRANCHES_PENDING = `${FETCH_BRANCHES}_${PENDING_SUFFIX}`; @@ -82,7 +78,8 @@ export default function reducer( ): Object { switch (action.type) { case FETCH_BRANCHES_SUCCESS: - const key = action.itemId; + const { namespace, name } = action.payload.repository; + const key = `${namespace}/${name}`; let oldBranchesByNames = { [key]: {} }; if (state[key] !== undefined) { oldBranchesByNames[key] = state[key]; diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index 361032c78a..f82495f736 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -1,14 +1,13 @@ import configureMockStore from "redux-mock-store"; import thunk from "redux-thunk"; import fetchMock from "fetch-mock"; -import { +import reducer, { FETCH_BRANCHES_FAILURE, FETCH_BRANCHES_PENDING, FETCH_BRANCHES_SUCCESS, fetchBranches, getBranchNames } from "./branches"; -import reducer from "./branches"; const namespace = "foo"; const name = "bar"; @@ -96,8 +95,7 @@ describe("branches", () => { const action = { type: FETCH_BRANCHES_SUCCESS, payload: { - namespace, - name, + repository, data: branches } }; @@ -120,7 +118,6 @@ describe("branches", () => { }; const newState = reducer(oldState, action); - console.log(newState); expect(newState[key].byNames["branch1"]).toEqual(branch1); expect(newState[key].byNames["branch2"]).toEqual(branch2); expect(newState[key].byNames["branch3"]).toEqual(branch3); @@ -128,25 +125,6 @@ describe("branches", () => { }); describe("branch selectors", () => { - it("should get branches for namespace and name", () => { - const state = { - branches: { - [key]: { - byNames: { - branch1: branch1 - } - } - } - }; - const branches = getBranchesForNamespaceAndNameFromState( - namespace, - name, - state - ); - expect(branches.length).toEqual(1); - expect(branches[0]).toEqual(branch1); - }); - it("should return branches names", () => { const state = { branches: { From e059762fc4435a1fe3adc6af831a579838c725cb Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 4 Oct 2018 19:08:11 +0200 Subject: [PATCH 056/121] Fixed flow issues --- scm-ui/src/repos/containers/Changesets.js | 36 ++++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 254cfacbe1..d9109bc3b3 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -9,17 +9,21 @@ import { } from "@scm-manager/ui-components"; import { + fetchChangesets, + fetchChangesetsByBranchAndPage, + fetchChangesetsByLink, + fetchChangesetsByPage, + getChangesetsFromState, getFetchChangesetsFailure, isFetchChangesetsPending, - selectListAsCollection, - fetchChangesetsByLink, - getChangesetsFromState, - fetchChangesetsByPage, - fetchChangesetsByBranchAndPage, - fetchChangesets + selectListAsCollection } from "../modules/changesets"; import type { History } from "history"; -import type { PagedCollection, Repository } from "@scm-manager/ui-types"; +import type { + Changeset, + PagedCollection, + Repository +} from "@scm-manager/ui-types"; import ChangesetList from "../components/changesets/ChangesetList"; import DropDown from "../components/DropDown"; import { withRouter } from "react-router-dom"; @@ -28,6 +32,7 @@ import { fetchBranches, getBranchNames } from "../modules/branches"; type Props = { repository: Repository, branchName: string, + branchNames: string[], history: History, fetchChangesetsByNamespaceNameAndBranch: ( namespace: string, @@ -35,19 +40,28 @@ type Props = { branch: string ) => void, list: PagedCollection, - fetchChangesetsByLink: string => void, + fetchChangesetsByLink: (Repository, string, string) => void, + fetchChangesetsByPage: (Repository, number) => void, + fetchChangesetsByBranchAndPage: (Repository, string, number) => void, + fetchBranches: Repository => void, page: number, - t: string => string + t: string => string, + match: any, + changesets: Changeset[], + loading: boolean, + error: boolean }; type State = { branch: string }; -class Changesets extends React.PureComponent { +class Changesets extends React.PureComponent { constructor(props) { super(props); - this.state = {}; + this.state = { + branch: "" + }; } onPageChange = (link: string) => { From eaf89511640955a75f66fa2bf8ca230e9065196d Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 4 Oct 2018 20:02:18 +0200 Subject: [PATCH 057/121] Boostrapped BranchChooser --- scm-ui/src/repos/components/DropDown.js | 31 ++++++----- scm-ui/src/repos/containers/BranchChooser.js | 54 ++++++++++++++++++++ scm-ui/src/repos/modules/branches.js | 21 ++------ scm-ui/src/repos/modules/branches.test.js | 8 +++ 4 files changed, 84 insertions(+), 30 deletions(-) create mode 100644 scm-ui/src/repos/containers/BranchChooser.js diff --git a/scm-ui/src/repos/components/DropDown.js b/scm-ui/src/repos/components/DropDown.js index d7494d2576..bd44e30f59 100644 --- a/scm-ui/src/repos/components/DropDown.js +++ b/scm-ui/src/repos/components/DropDown.js @@ -6,25 +6,30 @@ type Props = { options: string[], optionSelected: string => void, preselectedOption: string -} +}; class DropDown extends React.Component { render() { - const {options, preselectedOption} = this.props; - return
- -
+ const { options, preselectedOption } = this.props; + return ( +
+ +
+ ); } - change = (event) => { + change = event => { this.props.optionSelected(event.target.value); - } + }; } export default DropDown; diff --git a/scm-ui/src/repos/containers/BranchChooser.js b/scm-ui/src/repos/containers/BranchChooser.js new file mode 100644 index 0000000000..9a802275e2 --- /dev/null +++ b/scm-ui/src/repos/containers/BranchChooser.js @@ -0,0 +1,54 @@ +// @flow + +import React from "react"; +import type {Repository} from "@scm-manager/ui-types"; +import {connect} from "react-redux"; +import {fetchBranches} from "../modules/branches"; +import DropDown from "../components/DropDown"; + +type Props = { + repository: Repository, + fetchBranches: Repository => void, + callback: Branch => void, //TODO use correct branch type + branches: Branch[], //TODO use correct branch type + selectedBranchName: string +}; + +type State = {}; + +class BranchChooser extends React.Component { + componentDidMount() { + const { repository, fetchBranches } = this.props; + fetchBranches(repository); + } + + render() { + const { selectedBranchName, branches } = this.props; + return ( + b.name)} + preselectedOption={selectedBranchName} + optionSelected={branch => this.branchChanged(branch)} + /> + ); + } + + branchChanged = (branchName: string) => {}; +} + +const mapStateToProps = (state: State) => { + return {}; +}; + +const mapDispatchToProps = (dispatch: any) => { + return { + fetchBranches: (repository: Repository) => { + dispatch(fetchBranches(repository)); + } + }; +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(BranchChooser); diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index b4cddd63a3..c121652b68 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -24,23 +24,6 @@ export function fetchBranches(repository: Repository) { }); }; } -// export function fetchBranchesByNamespaceAndName( -// namespace: string, -// name: string -// ) { -// return function(dispatch: any) { -// dispatch(fetchBranchesPending(namespace, name)); -// return apiClient -// .get(REPO_URL + "/" + namespace + "/" + name + "/branches") -// .then(response => response.json()) -// .then(data => { -// dispatch(fetchBranchesSuccess(data, namespace, name)); -// }) -// .catch(error => { -// dispatch(fetchBranchesFailure(namespace, name, error)); -// }); -// }; -// } // Action creators export function fetchBranchesPending(repository: Repository) { @@ -133,3 +116,7 @@ export function getBranchNames(state: Object, repository: Repository) { } return Object.keys(state.branches[key].byNames); } + +export function getBranches(state: Object, repository: Repository) { + return null; +} diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index f82495f736..98cba858e0 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -141,5 +141,13 @@ describe("branches", () => { expect(names).toContain("branch1"); expect(names).toContain("branch2"); }); + + it("should return branches", () => { + const state = { + branches: { + [key]: {} + } + }; + }); }); }); From 4ce2aae849eb0a1aa3769b7ff60d18dc34702cef Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Fri, 5 Oct 2018 09:55:17 +0200 Subject: [PATCH 058/121] Implemented BranchChooser & selectors --- scm-ui/src/repos/containers/BranchChooser.js | 34 +++++++++---- scm-ui/src/repos/containers/Changesets.js | 9 ++-- scm-ui/src/repos/modules/branches.js | 50 ++++++++++---------- scm-ui/src/repos/modules/branches.test.js | 40 ++++++++++------ scm-ui/src/repos/modules/changesets.js | 6 ++- 5 files changed, 85 insertions(+), 54 deletions(-) diff --git a/scm-ui/src/repos/containers/BranchChooser.js b/scm-ui/src/repos/containers/BranchChooser.js index 9a802275e2..e3b1b0a26a 100644 --- a/scm-ui/src/repos/containers/BranchChooser.js +++ b/scm-ui/src/repos/containers/BranchChooser.js @@ -1,9 +1,9 @@ // @flow import React from "react"; -import type {Repository} from "@scm-manager/ui-types"; -import {connect} from "react-redux"; -import {fetchBranches} from "../modules/branches"; +import type { Repository } from "@scm-manager/ui-types"; +import { connect } from "react-redux"; +import { fetchBranches, getBranch, getBranches } from "../modules/branches"; import DropDown from "../components/DropDown"; type Props = { @@ -14,30 +14,46 @@ type Props = { selectedBranchName: string }; -type State = {}; +type State = { + selectedBranchName: string +}; class BranchChooser extends React.Component { + constructor(props: Props) { + super(props); + this.state = { + selectedBranchName: props.selectedBranchName + }; + } + componentDidMount() { const { repository, fetchBranches } = this.props; fetchBranches(repository); } render() { - const { selectedBranchName, branches } = this.props; + const { branches } = this.props; return ( b.name)} - preselectedOption={selectedBranchName} + preselectedOption={this.state.selectedBranchName} optionSelected={branch => this.branchChanged(branch)} /> ); } - branchChanged = (branchName: string) => {}; + branchChanged = (branchName: string) => { + const { callback } = this.props; + this.setState({ ...this.state, selectedBranchName: branchName }); + const branch = this.props.branches.find(b => b.name === branchName); + callback(branch); + }; } -const mapStateToProps = (state: State) => { - return {}; +const mapStateToProps = (state: State, ownProps: Props) => { + return { + branches: getBranches(state, ownProps.repository) + }; }; const mapDispatchToProps = (dispatch: any) => { diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index d9109bc3b3..58befb8287 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -28,6 +28,7 @@ import ChangesetList from "../components/changesets/ChangesetList"; import DropDown from "../components/DropDown"; import { withRouter } from "react-router-dom"; import { fetchBranches, getBranchNames } from "../modules/branches"; +import BranchChooser from "./BranchChooser"; type Props = { repository: Repository, @@ -148,10 +149,10 @@ class Changesets extends React.PureComponent { - this.branchChanged(branch)} + this.branchChanged(branch.name)} />
diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index c121652b68..5d2a5e4849 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -1,7 +1,11 @@ // @flow -import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; -import {apiClient} from "@scm-manager/ui-components"; -import type {Repository} from "@scm-manager/ui-types"; +import { + FAILURE_SUFFIX, + PENDING_SUFFIX, + SUCCESS_SUFFIX +} from "../../modules/types"; +import { apiClient } from "@scm-manager/ui-components"; +import type { Repository } from "@scm-manager/ui-types"; export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; export const FETCH_BRANCHES_PENDING = `${FETCH_BRANCHES}_${PENDING_SUFFIX}`; @@ -27,29 +31,26 @@ export function fetchBranches(repository: Repository) { // Action creators export function fetchBranchesPending(repository: Repository) { - const { namespace, name } = repository; return { type: FETCH_BRANCHES_PENDING, payload: { repository }, - itemId: namespace + "/" + name + itemId: createKey(repository) }; } export function fetchBranchesSuccess(data: string, repository: Repository) { - const { namespace, name } = repository; return { type: FETCH_BRANCHES_SUCCESS, payload: { data, repository }, - itemId: namespace + "/" + name + itemId: createKey(repository) }; } export function fetchBranchesFailure(repository: Repository, error: Error) { - const { namespace, name } = repository; return { type: FETCH_BRANCHES_FAILURE, payload: { error, repository }, - itemId: namespace + "/" + name + itemId: createKey(repository) }; } @@ -61,8 +62,7 @@ export default function reducer( ): Object { switch (action.type) { case FETCH_BRANCHES_SUCCESS: - const { namespace, name } = action.payload.repository; - const key = `${namespace}/${name}`; + const key = createKey(action.payload.repository); let oldBranchesByNames = { [key]: {} }; if (state[key] !== undefined) { oldBranchesByNames[key] = state[key]; @@ -96,21 +96,8 @@ function extractBranchesByNames(data: any, oldBranchesByNames: any): Branch[] { // Selectors -export function getBranchesForNamespaceAndNameFromState( - namespace: string, - name: string, - state: Object -) { - const key = namespace + "/" + name; - if (!state.branches[key]) { - return null; - } - return Object.values(state.branches[key].byNames); -} - export function getBranchNames(state: Object, repository: Repository) { - const { namespace, name } = repository; - const key = namespace + "/" + name; + const key = createKey(repository); if (!state.branches[key] || !state.branches[key].byNames) { return null; } @@ -118,5 +105,16 @@ export function getBranchNames(state: Object, repository: Repository) { } export function getBranches(state: Object, repository: Repository) { - return null; + const key = createKey(repository); + return Object.values(state.branches[key].byNames); +} + +export function getBranch(state: Object, repository: Repository, name: string) { + const key = createKey(repository); + return state.branches[key].byNames[name]; +} + +function createKey(repository: Repository) { + const { namespace, name } = repository; + return `${namespace}/${name}`; } diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index 98cba858e0..8ee96a8603 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -6,6 +6,8 @@ import reducer, { FETCH_BRANCHES_PENDING, FETCH_BRANCHES_SUCCESS, fetchBranches, + getBranch, + getBranches, getBranchNames } from "./branches"; @@ -125,17 +127,18 @@ describe("branches", () => { }); describe("branch selectors", () => { - it("should return branches names", () => { - const state = { - branches: { - [key]: { - byNames: { - branch1: branch1, - branch2: branch2 - } + const state = { + branches: { + [key]: { + byNames: { + branch1, + branch2 } } - }; + } + }; + + it("should return branches names", () => { const names = getBranchNames(state, repository); expect(names.length).toEqual(2); expect(names).toContain("branch1"); @@ -143,11 +146,20 @@ describe("branches", () => { }); it("should return branches", () => { - const state = { - branches: { - [key]: {} - } - }; + const branches = getBranches(state, repository); + expect(branches.length).toEqual(2); + expect(branches).toContain(branch1); + expect(branches).toContain(branch2); + }); + + it("should return single branch by name", () => { + const branch = getBranch(state, repository, "branch1"); + expect(branch).toEqual(branch1); + }); + + it("should return undefined if branch does not exist", () => { + const branch = getBranch(state, repository, "branch42"); + expect(branch).toBeUndefined(); }); }); }); diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index dffc87268d..2283cff171 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -201,7 +201,11 @@ function extractChangesetsByIds(changesets: any, oldChangesetsByIds: any) { } //selectors -export function getChangesets(state: Object, repository, branch?: string) { +export function getChangesets( + state: Object, + repository: Repository, + branch?: string +) { const key = createItemId(repository, branch); if (!state.changesets.byKey[key]) { return null; From 70362918740ef97a7139200300eb8505322534c2 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Fri, 5 Oct 2018 17:13:12 +0200 Subject: [PATCH 059/121] Refactored branches and changesets modules --- scm-ui/src/repos/containers/BranchChooser.js | 18 ++-- scm-ui/src/repos/containers/Changesets.js | 102 +++++++++---------- scm-ui/src/repos/modules/branches.js | 13 ++- scm-ui/src/repos/modules/changesets.js | 24 ++--- scm-ui/src/repos/modules/changesets.test.js | 33 +++--- 5 files changed, 97 insertions(+), 93 deletions(-) diff --git a/scm-ui/src/repos/containers/BranchChooser.js b/scm-ui/src/repos/containers/BranchChooser.js index e3b1b0a26a..5175f37f50 100644 --- a/scm-ui/src/repos/containers/BranchChooser.js +++ b/scm-ui/src/repos/containers/BranchChooser.js @@ -33,13 +33,17 @@ class BranchChooser extends React.Component { render() { const { branches } = this.props; - return ( - b.name)} - preselectedOption={this.state.selectedBranchName} - optionSelected={branch => this.branchChanged(branch)} - /> - ); + if (branches) { + return ( + b.name)} + preselectedOption={this.state.selectedBranchName} + optionSelected={branch => this.branchChanged(branch)} + /> + ); + } + + return null; } branchChanged = (branchName: string) => { diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 58befb8287..37ac2ba6c5 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -25,9 +25,8 @@ import type { Repository } from "@scm-manager/ui-types"; import ChangesetList from "../components/changesets/ChangesetList"; -import DropDown from "../components/DropDown"; import { withRouter } from "react-router-dom"; -import { fetchBranches, getBranchNames } from "../modules/branches"; +import { fetchBranches, getBranch, getBranchNames } from "../modules/branches"; import BranchChooser from "./BranchChooser"; type Props = { @@ -41,7 +40,7 @@ type Props = { branch: string ) => void, list: PagedCollection, - fetchChangesetsByLink: (Repository, string, string) => void, + fetchChangesetsByLink: (Repository, string, Branch) => void, fetchChangesetsByPage: (Repository, number) => void, fetchChangesetsByBranchAndPage: (Repository, string, number) => void, fetchBranches: Repository => void, @@ -50,7 +49,8 @@ type Props = { match: any, changesets: Changeset[], loading: boolean, - error: boolean + error: boolean, + branch: Branch }; type State = { @@ -58,7 +58,7 @@ type State = { }; class Changesets extends React.PureComponent { - constructor(props) { + constructor(props: Props) { super(props); this.state = { branch: "" @@ -66,8 +66,7 @@ class Changesets extends React.PureComponent { } onPageChange = (link: string) => { - const { repository } = this.props; - const branch = this.props.match.params.branch; + const { repository, branch } = this.props; this.props.fetchChangesetsByLink(repository, link, branch); }; @@ -76,20 +75,18 @@ class Changesets extends React.PureComponent { } updateContent() { - const { repository } = this.props; - - const branchName = this.props.match.params.branch; const { + repository, + branch, + page, fetchChangesetsByPage, - fetchChangesetsByBranchAndPage, - fetchBranches + fetchChangesetsByBranchAndPage } = this.props; - if (branchName) { - fetchChangesetsByBranchAndPage(repository, branchName, this.props.page); + if (branch) { + fetchChangesetsByBranchAndPage(repository, branch, page); } else { - fetchChangesetsByPage(repository, this.props.page); + fetchChangesetsByPage(repository, page); } - fetchBranches(repository); } componentDidUpdate(prevProps: Props, prevState: State, snapshot: any) { @@ -121,7 +118,6 @@ class Changesets extends React.PureComponent { render() { const { changesets, loading, error } = this.props; - if (error) { return ; } @@ -140,27 +136,23 @@ class Changesets extends React.PureComponent { renderList = () => { const branch = this.props.match.params.branch; - const { repository, changesets, branchNames, t } = this.props; + const { repository, changesets, t } = this.props; - if (branchNames && branchNames.length > 0) { - return ( - <> -
- - this.branchChanged(branch.name)} - /> -
- - - ); - } - - return ; + return ( + <> +
+ + this.branchChanged(branch)} + /> +
+ + + ); }; renderPaginator() { @@ -171,11 +163,13 @@ class Changesets extends React.PureComponent { return null; } - branchChanged = (branchName: string): void => { + branchChanged = (branch: Branch): void => { const { history, repository } = this.props; - if (branchName === undefined || branchName === "") { + if (branch === undefined) { history.push(`/repo/${repository.namespace}/${repository.name}/history`); } else { + const branchName = branch.name; + this.setState({ branch: branchName }); history.push( `/repo/${repository.namespace}/${repository.name}/${branchName}/history` ); @@ -183,18 +177,6 @@ class Changesets extends React.PureComponent { }; } -const createKey = ( - namespace: string, - name: string, - branch?: string -): string => { - let key = `${namespace}/${name}`; - if (branch) { - key = key + `/${branch}`; - } - return key; -}; - const getPageFromProps = props => { let page = props.match.params.page; if (page) { @@ -207,9 +189,9 @@ const getPageFromProps = props => { const mapStateToProps = (state, ownProps: Props) => { const { repository } = ownProps; - const { namespace, name } = ownProps.repository; - const { branch } = ownProps.match.params; - const key = createKey(namespace, name, branch); + const branchName = ownProps.match.params.branch; + const branch = getBranch(state, repository, branchName); + const key = createKey(repository, branch); const loading = isFetchChangesetsPending(state, repository, branch); const changesets = getChangesetsFromState(state, key); const branchNames = getBranchNames(state, repository); @@ -223,10 +205,20 @@ const mapStateToProps = (state, ownProps: Props) => { branchNames, error, list, - page + page, + branch }; }; +const createKey = (repository: Repository, branch?: Branch): string => { + const { namespace, name } = repository; + let key = `${namespace}/${name}`; + if (branch && branch.name) { + key = key + `/${branch.name}`; + } + return key; +}; + const mapDispatchToProps = dispatch => { return { fetchBranches: (repository: Repository) => { diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 5d2a5e4849..2e89aa92f0 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -106,12 +106,21 @@ export function getBranchNames(state: Object, repository: Repository) { export function getBranches(state: Object, repository: Repository) { const key = createKey(repository); - return Object.values(state.branches[key].byNames); + if (state.branches[key]) { + if (state.branches[key].byNames) { + return Object.values(state.branches[key].byNames); + } + } } export function getBranch(state: Object, repository: Repository, name: string) { const key = createKey(repository); - return state.branches[key].byNames[name]; + if (state.branches[key]) { + if (state.branches[key].byNames[name]) { + return state.branches[key].byNames[name]; + } + } + return undefined; } function createKey(repository: Repository) { diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index 2283cff171..e1f56e7a16 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -28,7 +28,7 @@ const REPO_URL = "repositories"; export function fetchChangesetsByLink( repository: Repository, link: string, - branch?: string + branch?: Branch ) { return function(dispatch: any) { dispatch(fetchChangesetsPending(repository, branch)); @@ -46,19 +46,19 @@ export function fetchChangesetsByLink( export function fetchChangesetsWithOptions( repository: Repository, - branch?: string, + branch?: Branch, suffix?: string ) { let link = repository._links.changesets.href; - if (branch && branch !== "") { - const halBranch = repository._links.branches.find(b => b.name === branch); - link = halBranch._links.history.href; + if (branch) { + link = branch._links.history.href; } if (suffix) { link = link + `${suffix}`; } + return function(dispatch: any) { dispatch(fetchChangesetsPending(repository, branch)); return apiClient @@ -84,7 +84,7 @@ export function fetchChangesetsByPage(repository: Repository, page: number) { // TODO: Rewrite code to fetch changesets by branches, adjust tests and let BranchChooser fetch branches export function fetchChangesetsByBranchAndPage( repository: Repository, - branch: string, + branch: Branch, page: number ) { return fetchChangesetsWithOptions(repository, branch, `?page=${page - 1}`); @@ -92,14 +92,14 @@ export function fetchChangesetsByBranchAndPage( export function fetchChangesetsByBranch( repository: Repository, - branch: string + branch: Branch ) { return fetchChangesetsWithOptions(repository, branch); } export function fetchChangesetsPending( repository: Repository, - branch?: string + branch?: Branch ): Action { const itemId = createItemId(repository, branch); if (!branch) { @@ -115,7 +115,7 @@ export function fetchChangesetsPending( export function fetchChangesetsSuccess( changesets: any, repository: Repository, - branch?: string + branch?: Branch ): Action { return { type: FETCH_CHANGESETS_SUCCESS, @@ -127,7 +127,7 @@ export function fetchChangesetsSuccess( function fetchChangesetsFailure( repository: Repository, error: Error, - branch?: string + branch?: Branch ): Action { return { type: FETCH_CHANGESETS_FAILURE, @@ -140,11 +140,11 @@ function fetchChangesetsFailure( }; } -function createItemId(repository: Repository, branch?: string): string { +function createItemId(repository: Repository, branch?: Branch): string { const { namespace, name } = repository; let itemId = namespace + "/" + name; if (branch && branch !== "") { - itemId = itemId + "/" + branch; + itemId = itemId + "/" + branch.name; } return itemId; } diff --git a/scm-ui/src/repos/modules/changesets.test.js b/scm-ui/src/repos/modules/changesets.test.js index 0b73db5e9d..3512921db0 100644 --- a/scm-ui/src/repos/modules/changesets.test.js +++ b/scm-ui/src/repos/modules/changesets.test.js @@ -18,6 +18,15 @@ import { isFetchChangesetsPending } from "./changesets"; import reducer from "./changesets"; +const branch = { + name: "specific", + _links: { + history: { + href: + "http://scm/api/rest/v2/repositories/foo/bar/branches/specific/changesets" + } + } +}; const repository = { namespace: "foo", @@ -29,17 +38,7 @@ const repository = { changesets: { href: "http://scm/api/rest/v2/repositories/foo/bar/changesets" }, - branches: [ - { - name: "specific", - _links: { - history: { - href: - "http://scm/api/rest/v2/repositories/foo/bar/branches/specific/changesets" - } - } - } - ] + branches: [branch] } }; @@ -87,7 +86,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: { repository, branch: "specific" }, + payload: { repository, branch }, itemId }, { @@ -99,7 +98,7 @@ describe("changesets", () => { const store = mockStore({}); return store - .dispatch(fetchChangesetsByBranch(repository, "specific")) + .dispatch(fetchChangesetsByBranch(repository, branch)) .then(() => { expect(store.getActions()).toEqual(expectedActions); }); @@ -132,14 +131,14 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: { repository, branch: "specific" }, + payload: { repository, branch }, itemId } ]; const store = mockStore({}); return store - .dispatch(fetchChangesetsByBranch(repository, "specific")) + .dispatch(fetchChangesetsByBranch(repository, branch)) .then(() => { expect(store.getActions()[0]).toEqual(expectedActions[0]); expect(store.getActions()[1].type).toEqual(FETCH_CHANGESETS_FAILURE); @@ -175,7 +174,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: { repository, branch: "specific" }, + payload: { repository, branch }, itemId: "foo/bar/specific" }, { @@ -187,7 +186,7 @@ describe("changesets", () => { const store = mockStore({}); return store - .dispatch(fetchChangesetsByBranchAndPage(repository, "specific", 5)) + .dispatch(fetchChangesetsByBranchAndPage(repository, branch, 5)) .then(() => { expect(store.getActions()).toEqual(expectedActions); }); From e58269444b0838fbc558abf87f8e491539ebda9a Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 8 Oct 2018 12:54:11 +0200 Subject: [PATCH 060/121] Fixed issues preventing paged changeset list to be accessed via URL --- scm-ui/src/repos/containers/BranchChooser.js | 21 +++++--- scm-ui/src/repos/containers/Changesets.js | 56 +++++++++----------- scm-ui/src/repos/modules/branches.js | 5 ++ scm-ui/src/repos/modules/branches.test.js | 14 ++++- scm-ui/src/repos/modules/changesets.js | 22 +++----- 5 files changed, 64 insertions(+), 54 deletions(-) diff --git a/scm-ui/src/repos/containers/BranchChooser.js b/scm-ui/src/repos/containers/BranchChooser.js index 5175f37f50..d8d8aae61e 100644 --- a/scm-ui/src/repos/containers/BranchChooser.js +++ b/scm-ui/src/repos/containers/BranchChooser.js @@ -1,9 +1,11 @@ // @flow import React from "react"; -import type { Repository } from "@scm-manager/ui-types"; -import { connect } from "react-redux"; -import { fetchBranches, getBranch, getBranches } from "../modules/branches"; +import type {Repository} from "@scm-manager/ui-types"; +import {connect} from "react-redux"; +import {fetchBranches, getBranches, isFetchBranchesPending} from "../modules/branches"; + +import {Loading} from "@scm-manager/ui-components"; import DropDown from "../components/DropDown"; type Props = { @@ -11,7 +13,8 @@ type Props = { fetchBranches: Repository => void, callback: Branch => void, //TODO use correct branch type branches: Branch[], //TODO use correct branch type - selectedBranchName: string + selectedBranchName: string, + loading: boolean }; type State = { @@ -32,8 +35,11 @@ class BranchChooser extends React.Component { } render() { - const { branches } = this.props; - if (branches) { + const { branches, loading } = this.props; + if (loading) { + return ; + } + if (branches && branches.length > 0) { return ( b.name)} @@ -56,7 +62,8 @@ class BranchChooser extends React.Component { const mapStateToProps = (state: State, ownProps: Props) => { return { - branches: getBranches(state, ownProps.repository) + branches: getBranches(state, ownProps.repository), + loading: isFetchBranchesPending(state, ownProps.repository) }; }; diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 37ac2ba6c5..0dc85320b5 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -1,12 +1,8 @@ // @flow import React from "react"; -import { connect } from "react-redux"; -import { translate } from "react-i18next"; -import { - ErrorNotification, - Loading, - Paginator -} from "@scm-manager/ui-components"; +import {connect} from "react-redux"; +import {translate} from "react-i18next"; +import {ErrorNotification, Loading, Paginator} from "@scm-manager/ui-components"; import { fetchChangesets, @@ -18,15 +14,11 @@ import { isFetchChangesetsPending, selectListAsCollection } from "../modules/changesets"; -import type { History } from "history"; -import type { - Changeset, - PagedCollection, - Repository -} from "@scm-manager/ui-types"; +import type {History} from "history"; +import type {Changeset, PagedCollection, Repository} from "@scm-manager/ui-types"; import ChangesetList from "../components/changesets/ChangesetList"; -import { withRouter } from "react-router-dom"; -import { fetchBranches, getBranch, getBranchNames } from "../modules/branches"; +import {withRouter} from "react-router-dom"; +import {fetchBranches, getBranch, getBranchNames} from "../modules/branches"; import BranchChooser from "./BranchChooser"; type Props = { @@ -94,23 +86,25 @@ class Changesets extends React.PureComponent { const { namespace, name } = repository; const branch = match.params.branch; - if (branch !== prevState.branch) { - this.updateContent(); - this.setState({ branch }); - } + if (!this.props.loading) { + if (prevProps.branch !== this.props.branch) { + this.updateContent(); + this.setState({ branch }); + } - if (list && (list.page || list.page === 0)) { - // backend starts paging at 0 - const statePage: number = list.page + 1; - if (page !== statePage) { - if (branch) { - this.props.history.push( - `/repo/${namespace}/${name}/${branch}/history/${statePage}` - ); - } else { - this.props.history.push( - `/repo/${namespace}/${name}/history/${statePage}` - ); + if (list && (list.page || list.page === 0)) { + // backend starts paging at 0 + const statePage: number = list.page + 1; + if (page !== statePage) { + if (branch) { + this.props.history.push( + `/repo/${namespace}/${name}/${branch}/history/${statePage}` + ); + } else { + this.props.history.push( + `/repo/${namespace}/${name}/history/${statePage}` + ); + } } } } diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 2e89aa92f0..5f079ff8fd 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -6,6 +6,7 @@ import { } from "../../modules/types"; import { apiClient } from "@scm-manager/ui-components"; import type { Repository } from "@scm-manager/ui-types"; +import { isPending } from "../../modules/pending"; export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; export const FETCH_BRANCHES_PENDING = `${FETCH_BRANCHES}_${PENDING_SUFFIX}`; @@ -123,6 +124,10 @@ export function getBranch(state: Object, repository: Repository, name: string) { return undefined; } +export function isFetchBranchesPending(state: Object, repository: Repository) { + return isPending(state, FETCH_BRANCHES, createKey(repository)); +} + function createKey(repository: Repository) { const { namespace, name } = repository; return `${namespace}/${name}`; diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index 8ee96a8603..cfae7da564 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -2,13 +2,15 @@ import configureMockStore from "redux-mock-store"; import thunk from "redux-thunk"; import fetchMock from "fetch-mock"; import reducer, { + FETCH_BRANCHES, FETCH_BRANCHES_FAILURE, FETCH_BRANCHES_PENDING, FETCH_BRANCHES_SUCCESS, fetchBranches, getBranch, getBranches, - getBranchNames + getBranchNames, + isFetchBranchesPending } from "./branches"; const namespace = "foo"; @@ -138,6 +140,16 @@ describe("branches", () => { } }; + it("should return true, when fetching branches is pending", () => { + const state = { + pending: { + [FETCH_BRANCHES + "/foo/bar"]: true + } + }; + + expect(isFetchBranchesPending(state, repository)).toBeTruthy(); + }); + it("should return branches names", () => { const names = getBranchNames(state, repository); expect(names.length).toEqual(2); diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index e1f56e7a16..4cb71af9cd 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -1,20 +1,11 @@ // @flow -import { - FAILURE_SUFFIX, - PENDING_SUFFIX, - SUCCESS_SUFFIX -} from "../../modules/types"; -import { apiClient } from "@scm-manager/ui-components"; -import { isPending } from "../../modules/pending"; -import { getFailure } from "../../modules/failure"; -import { combineReducers } from "redux"; -import type { - Action, - Changeset, - PagedCollection, - Repository -} from "@scm-manager/ui-types"; +import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; +import {apiClient} from "@scm-manager/ui-components"; +import {isPending} from "../../modules/pending"; +import {getFailure} from "../../modules/failure"; +import {combineReducers} from "redux"; +import type {Action, Changeset, PagedCollection, Repository} from "@scm-manager/ui-types"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -165,6 +156,7 @@ function byKeyReducer( } const byIds = extractChangesetsByIds(changesets, oldChangesets[key].byId); return { + ...state, [key]: { byId: { ...byIds }, list: { From ddcc21c1a8ae19d738e52cfeebd7622047a5fede Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Mon, 8 Oct 2018 13:39:33 +0200 Subject: [PATCH 061/121] add autocomplete endpoint --- .../src/main/java/sonia/scm/GenericDAO.java | 9 + scm-core/src/main/java/sonia/scm/Manager.java | 9 + .../main/java/sonia/scm/ManagerDecorator.java | 5 + .../src/main/java/sonia/scm/ModelObject.java | 2 +- .../java/sonia/scm/ReducedModelObject.java | 15 + .../src/main/java/sonia/scm/group/Group.java | 9 +- .../java/sonia/scm/repository/Changeset.java | 5 + .../java/sonia/scm/repository/Repository.java | 10 +- .../src/main/java/sonia/scm/user/User.java | 2 +- .../main/java/sonia/scm/web/VndMediaType.java | 1 + .../src/test/java/sonia/scm/ManagerTest.java | 5 + .../java/sonia/scm/xml/AbstractXmlDAO.java | 18 +- .../AutoCompleteBadParamException.java | 11 + .../AutoCompleteBadParamExceptionMapper.java | 16 + .../v2/resources/AutoCompleteResource.java | 113 ++++++ .../scm/api/v2/resources/MapperModule.java | 2 + .../v2/resources/ReducedObjectModelDto.java | 16 + .../ReducedObjectModelToDtoMapper.java | 13 + .../sonia/scm/group/DefaultGroupManager.java | 5 + .../repository/DefaultRepositoryManager.java | 6 + .../DefaultAuthorizationCollector.java | 17 + .../sonia/scm/user/DefaultUserManager.java | 6 + .../AbstractManagerResourceTest.java | 5 + .../resources/AutoCompleteResourceTest.java | 368 ++++++++++++++++++ .../scm/api/v2/resources/DispatcherMock.java | 1 + .../v2/resources/UserRootResourceTest.java | 1 - .../DefaultAuthorizationCollectorTest.java | 8 +- 27 files changed, 664 insertions(+), 14 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/ReducedModelObject.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamException.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamExceptionMapper.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelDto.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelToDtoMapper.java create mode 100644 scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java diff --git a/scm-core/src/main/java/sonia/scm/GenericDAO.java b/scm-core/src/main/java/sonia/scm/GenericDAO.java index b63a96f733..a369c2f8c2 100644 --- a/scm-core/src/main/java/sonia/scm/GenericDAO.java +++ b/scm-core/src/main/java/sonia/scm/GenericDAO.java @@ -114,4 +114,13 @@ public interface GenericDAO * @return all items */ public Collection getAll(); + + /** + * Returns items containing the searched string + * + * @param searched the search character + * @param limit the max count of the result entities. if limit is <= 0 return all filtered entities + * @return searched items + */ + Collection getFiltered(String searched, int limit); } diff --git a/scm-core/src/main/java/sonia/scm/Manager.java b/scm-core/src/main/java/sonia/scm/Manager.java index 2925b5b6b4..62384e41d4 100644 --- a/scm-core/src/main/java/sonia/scm/Manager.java +++ b/scm-core/src/main/java/sonia/scm/Manager.java @@ -77,6 +77,15 @@ public interface Manager */ Collection getAll(); + /** + * Returns a {@link java.util.Collection} of filtered objects + * + * @param filter the searched string + * @param limit the max count of the result entities. if limit is <= 0 return all filtered entities + * @return all object in the store + */ + Collection getFiltered(String filter, int limit); + /** * Returns all object of the store sorted by the given {@link java.util.Comparator} * diff --git a/scm-core/src/main/java/sonia/scm/ManagerDecorator.java b/scm-core/src/main/java/sonia/scm/ManagerDecorator.java index 7b3f03ee8c..3938121668 100644 --- a/scm-core/src/main/java/sonia/scm/ManagerDecorator.java +++ b/scm-core/src/main/java/sonia/scm/ManagerDecorator.java @@ -91,6 +91,11 @@ public class ManagerDecorator implements Manager { decorated.refresh(object); } + @Override + public Collection getFiltered(String filter, int limit) { + return decorated.getFiltered(filter, limit); + } + @Override public T get(String id) { diff --git a/scm-core/src/main/java/sonia/scm/ModelObject.java b/scm-core/src/main/java/sonia/scm/ModelObject.java index cca9608ceb..5c387e9ca4 100644 --- a/scm-core/src/main/java/sonia/scm/ModelObject.java +++ b/scm-core/src/main/java/sonia/scm/ModelObject.java @@ -44,7 +44,7 @@ import java.io.Serializable; */ public interface ModelObject extends TypedObject, LastModifiedAware, Cloneable, Validateable, - Serializable + Serializable, ReducedModelObject { /** diff --git a/scm-core/src/main/java/sonia/scm/ReducedModelObject.java b/scm-core/src/main/java/sonia/scm/ReducedModelObject.java new file mode 100644 index 0000000000..b8db8c3ee0 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/ReducedModelObject.java @@ -0,0 +1,15 @@ +package sonia.scm; + + +/** + * This is a reduced form of a model object. + * It can be used as search result to avoid returning the whole object properties. + * + * @author Mohamed Karray + */ +public interface ReducedModelObject { + + String getId(); + + String getDisplayName(); +} diff --git a/scm-core/src/main/java/sonia/scm/group/Group.java b/scm-core/src/main/java/sonia/scm/group/Group.java index 5e7f596c58..6ee27be2fc 100644 --- a/scm-core/src/main/java/sonia/scm/group/Group.java +++ b/scm-core/src/main/java/sonia/scm/group/Group.java @@ -55,12 +55,12 @@ import java.util.List; /** * Organizes users into a group for easier permissions management. - * + * * TODO for 2.0: Use a set instead of a list for members * * @author Sebastian Sdorra */ -@StaticPermissions(value = "group", globalPermissions = {"create", "list"}) +@StaticPermissions(value = "group", globalPermissions = {"create", "list", "autocomplete"}) @XmlRootElement(name = "groups") @XmlAccessorType(XmlAccessType.FIELD) public class Group extends BasicPropertiesAware @@ -309,6 +309,11 @@ public class Group extends BasicPropertiesAware return name; } + @Override + public String getDisplayName() { + return description; + } + /** * Returns a timestamp of the last modified date of this group. * diff --git a/scm-core/src/main/java/sonia/scm/repository/Changeset.java b/scm-core/src/main/java/sonia/scm/repository/Changeset.java index 7397fecabe..7d3a8d6dbf 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Changeset.java +++ b/scm-core/src/main/java/sonia/scm/repository/Changeset.java @@ -256,6 +256,11 @@ public class Changeset extends BasicPropertiesAware implements ModelObject { return id; } + @Override + public String getDisplayName() { + return id; + } + @Override public void setLastModified(Long timestamp) { throw new UnsupportedOperationException("changesets are immutable"); diff --git a/scm-core/src/main/java/sonia/scm/repository/Repository.java b/scm-core/src/main/java/sonia/scm/repository/Repository.java index cad36f2d88..7f2aab6865 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Repository.java +++ b/scm-core/src/main/java/sonia/scm/repository/Repository.java @@ -60,11 +60,12 @@ import java.util.List; */ @StaticPermissions( value = "repository", - permissions = {"read", "modify", "delete", "healthCheck", "pull", "push", "permissionRead", "permissionWrite"} + permissions = {"read", "modify", "delete", "healthCheck", "pull", "push", "permissionRead", "permissionWrite"}, + globalPermissions = {"create", "autocomplete"} ) @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "repositories") -public class Repository extends BasicPropertiesAware implements ModelObject, PermissionObject { +public class Repository extends BasicPropertiesAware implements ModelObject, PermissionObject{ private static final long serialVersionUID = 3486560714961909711L; @@ -183,6 +184,11 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per return id; } + @Override + public String getDisplayName() { + return getNamespaceAndName().toString(); + } + @Override public Long getLastModified() { return lastModified; diff --git a/scm-core/src/main/java/sonia/scm/user/User.java b/scm-core/src/main/java/sonia/scm/user/User.java index 0d909bec8d..2a35f920a8 100644 --- a/scm-core/src/main/java/sonia/scm/user/User.java +++ b/scm-core/src/main/java/sonia/scm/user/User.java @@ -55,7 +55,7 @@ import java.security.Principal; * * @author Sebastian Sdorra */ -@StaticPermissions(value = "user", globalPermissions = {"create", "list"}) +@StaticPermissions(value = "user", globalPermissions = {"create", "list", "autocomplete"}) @XmlRootElement(name = "users") @XmlAccessorType(XmlAccessType.FIELD) public class User extends BasicPropertiesAware implements Principal, ModelObject, PermissionObject diff --git a/scm-core/src/main/java/sonia/scm/web/VndMediaType.java b/scm-core/src/main/java/sonia/scm/web/VndMediaType.java index f0711cd1e4..b6f2210d80 100644 --- a/scm-core/src/main/java/sonia/scm/web/VndMediaType.java +++ b/scm-core/src/main/java/sonia/scm/web/VndMediaType.java @@ -18,6 +18,7 @@ public class VndMediaType { public static final String INDEX = PREFIX + "index" + SUFFIX; public static final String USER = PREFIX + "user" + SUFFIX; public static final String GROUP = PREFIX + "group" + SUFFIX; + public static final String AUTOCOMPLETE = PREFIX + "autocomplete" + SUFFIX; public static final String REPOSITORY = PREFIX + "repository" + SUFFIX; public static final String PERMISSION = PREFIX + "permission" + SUFFIX; public static final String CHANGESET = PREFIX + "changeset" + SUFFIX; diff --git a/scm-core/src/test/java/sonia/scm/ManagerTest.java b/scm-core/src/test/java/sonia/scm/ManagerTest.java index 06c8eb3ea6..309a68e8ca 100644 --- a/scm-core/src/test/java/sonia/scm/ManagerTest.java +++ b/scm-core/src/test/java/sonia/scm/ManagerTest.java @@ -78,6 +78,11 @@ public class ManagerTest { return IntStream.range(0, givenItemCount).boxed().collect(toList()); } + @Override + public Collection getFiltered(String filter, int limit) { + return null; + } + @Override public Collection getAll(Comparator comparator) { return getAll(); } diff --git a/scm-dao-xml/src/main/java/sonia/scm/xml/AbstractXmlDAO.java b/scm-dao-xml/src/main/java/sonia/scm/xml/AbstractXmlDAO.java index 6b74fce7ca..f0907538cf 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/xml/AbstractXmlDAO.java +++ b/scm-dao-xml/src/main/java/sonia/scm/xml/AbstractXmlDAO.java @@ -41,11 +41,13 @@ import org.slf4j.LoggerFactory; import sonia.scm.GenericDAO; import sonia.scm.ModelObject; import sonia.scm.group.xml.XmlGroupDAO; - -//~--- JDK imports ------------------------------------------------------------ +import sonia.scm.store.ConfigurationStore; +import sonia.scm.util.AssertUtil; import java.util.Collection; -import sonia.scm.store.ConfigurationStore; +import java.util.stream.Collectors; + +//~--- JDK imports ------------------------------------------------------------ /** * @@ -234,6 +236,16 @@ public abstract class AbstractXmlDAO getFiltered(String searched, int limit) { + int size = db.values().size(); + AssertUtil.assertIsNotEmpty(searched); + return ImmutableList.copyOf(db.values().stream() + .filter(item -> item.getId().contains(searched) || (item.getDisplayName() != null && item.getDisplayName().contains(searched))) + .limit(limit <= 0 ? size : limit) + .collect(Collectors.toList())); + } + /** * Method description * diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamException.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamException.java new file mode 100644 index 0000000000..1f3f7177bd --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamException.java @@ -0,0 +1,11 @@ +package sonia.scm.api.v2.resources; + +public class AutoCompleteBadParamException extends Exception { + + public static final String PARAMETER_IS_REQUIRED = "The parameter is required."; + public static final String INVALID_PARAMETER_LENGTH = "Invalid parameter length."; + + public AutoCompleteBadParamException(String message) { + super(message); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamExceptionMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamExceptionMapper.java new file mode 100644 index 0000000000..d2b2eeaed3 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamExceptionMapper.java @@ -0,0 +1,16 @@ +package sonia.scm.api.v2.resources; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +@Provider +public class AutoCompleteBadParamExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(AutoCompleteBadParamException exception) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(exception.getMessage()) + .build(); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java new file mode 100644 index 0000000000..5dfa78a762 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java @@ -0,0 +1,113 @@ +package sonia.scm.api.v2.resources; + +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; +import org.apache.commons.lang.StringUtils; +import sonia.scm.group.GroupManager; +import sonia.scm.repository.RepositoryManager; +import sonia.scm.user.UserManager; +import sonia.scm.web.VndMediaType; + +import javax.inject.Inject; +import javax.validation.Valid; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; +import java.util.stream.Collectors; + +import static sonia.scm.api.v2.resources.AutoCompleteBadParamException.INVALID_PARAMETER_LENGTH; +import static sonia.scm.api.v2.resources.AutoCompleteBadParamException.PARAMETER_IS_REQUIRED; + +@Path(AutoCompleteResource.PATH) +public class AutoCompleteResource { + public static final String PATH = "v2/autocomplete/"; + public static final String DEFAULT_LIMIT = "5"; + public static final int MIN_SEARCHED_CHARS = 1; + + private ReducedObjectModelToDtoMapper mapper; + + private UserManager userManager; + private GroupManager groupManager; + private RepositoryManager repositoryManager; + + @Inject + public AutoCompleteResource(ReducedObjectModelToDtoMapper mapper, UserManager userManager, GroupManager groupManager, RepositoryManager repositoryManager) { + this.mapper = mapper; + this.userManager = userManager; + this.groupManager = groupManager; + this.repositoryManager = repositoryManager; + } + + @GET + @Path("user") + @Produces(VndMediaType.AUTOCOMPLETE) + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 400, condition = "if the searched string contains less than 2 characters"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user:autocomplete\" privilege"), + @ResponseCode(code = 500, condition = "internal server error") + }) + public Response searchUser(@QueryParam("filter") String filter, + @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) throws AutoCompleteBadParamException { + validateParams(filter); + return Response.ok(userManager.getFiltered(filter, limit) + .stream() + .map(mapper::map) + .collect(Collectors.toList())) + .build(); + } + + @GET + @Path("group") + @Produces(VndMediaType.AUTOCOMPLETE) + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 400, condition = "if the searched string contains less than 2 characters"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"group:autocomplete\" privilege"), + @ResponseCode(code = 500, condition = "internal server error") + }) + public Response searchGroup(@Valid @QueryParam("filter") String filter, + @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) throws AutoCompleteBadParamException { + validateParams(filter); + return Response.ok(groupManager.getFiltered(filter, limit) + .stream() + .map(mapper::map) + .collect(Collectors.toList())) + .build(); + } + + @GET + @Path("repository") + @Produces(VndMediaType.AUTOCOMPLETE) + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 400, condition = "if the searched string contains less than 2 characters"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"repository:autocomplete\" privilege"), + @ResponseCode(code = 500, condition = "internal server error") + }) + public Response searchRepo(@Valid @QueryParam("filter") String filter, + @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) throws AutoCompleteBadParamException { + validateParams(filter); + return Response.ok(repositoryManager.getFiltered(filter, limit) + .stream() + .map(mapper::map) + .collect(Collectors.toList())) + .build(); + } + + void validateParams(String filter) throws AutoCompleteBadParamException { + if (StringUtils.isBlank(filter)) { + throw new AutoCompleteBadParamException(PARAMETER_IS_REQUIRED); + } + if (filter.length() <= MIN_SEARCHED_CHARS) { + throw new AutoCompleteBadParamException(INVALID_PARAMETER_LENGTH); + } + } + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java index 03b5728627..6497cb9315 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java @@ -37,6 +37,8 @@ public class MapperModule extends AbstractModule { bind(FileObjectToFileObjectDtoMapper.class).to(Mappers.getMapper(FileObjectToFileObjectDtoMapper.class).getClass()); bind(ModificationsToDtoMapper.class).to(Mappers.getMapper(ModificationsToDtoMapper.class).getClass()); + bind(ReducedObjectModelToDtoMapper.class).to(Mappers.getMapper(ReducedObjectModelToDtoMapper.class).getClass()); + // no mapstruct required bind(UIPluginDtoMapper.class); bind(UIPluginDtoCollectionMapper.class); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelDto.java new file mode 100644 index 0000000000..821af03995 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelDto.java @@ -0,0 +1,16 @@ +package sonia.scm.api.v2.resources; + +import de.otto.edison.hal.HalRepresentation; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class ReducedObjectModelDto extends HalRepresentation { + + private String id; + + private String displayName; +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelToDtoMapper.java new file mode 100644 index 0000000000..e188de7d65 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelToDtoMapper.java @@ -0,0 +1,13 @@ +package sonia.scm.api.v2.resources; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import sonia.scm.ReducedModelObject; + +@Mapper +public abstract class ReducedObjectModelToDtoMapper { + + @Mapping(target = "attributes", ignore = true) // We do not map HAL attributes + public abstract ReducedObjectModelDto map(ReducedModelObject modelObject); + +} diff --git a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java index c3dcb6db8c..823ba5a580 100644 --- a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java +++ b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java @@ -242,6 +242,11 @@ public class DefaultGroupManager extends AbstractGroupManager return group; } + @Override + public Collection getFiltered(String filter, int limit) { + GroupPermissions.autocomplete().check(); + return groupDAO.getFiltered(filter, limit); + } /** * Method description * diff --git a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java index 8cb325b818..defd8f2068 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java @@ -243,6 +243,12 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { return repository; } + @Override + public Collection getFiltered(String filter, int limit) { + RepositoryPermissions.autocomplete().check(); + return repositoryDAO.getFiltered(filter, limit); + } + @Override public Collection getAll(Comparator comparator) { List repositories = Lists.newArrayList(); diff --git a/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java b/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java index bf46eb2a6f..f2e50029bd 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java +++ b/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java @@ -52,9 +52,11 @@ import org.slf4j.LoggerFactory; import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; import sonia.scm.group.GroupNames; +import sonia.scm.group.GroupPermissions; import sonia.scm.plugin.Extension; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryDAO; +import sonia.scm.repository.RepositoryPermissions; import sonia.scm.user.User; import sonia.scm.user.UserPermissions; import sonia.scm.util.Util; @@ -256,6 +258,9 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector collectGlobalPermissions(builder, user, groups); collectRepositoryPermissions(builder, user, groups); builder.add(canReadOwnUser(user)); + builder.add(getUserAutocompletePermission()); + builder.add(getGroupAutocompletePermission()); + builder.add(getRepoAutocompletePermission()); permissions = builder.build(); } @@ -264,6 +269,18 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector return info; } + private String getRepoAutocompletePermission() { + return RepositoryPermissions.autocomplete().asShiroString(); + } + + private String getGroupAutocompletePermission() { + return GroupPermissions.autocomplete().asShiroString(); + } + + private String getUserAutocompletePermission() { + return UserPermissions.autocomplete().asShiroString(); + } + private String canReadOwnUser(User user) { return UserPermissions.read(user.getName()).asShiroString(); } diff --git a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java index 876b0f094c..7757e0382a 100644 --- a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java +++ b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java @@ -300,6 +300,12 @@ public class DefaultUserManager extends AbstractUserManager return getAll(null); } + @Override + public Collection getFiltered(String filter, int limit) { + UserPermissions.autocomplete().check(); + return userDAO.getFiltered(filter, limit); + } + /** * Method description * diff --git a/scm-webapp/src/test/java/sonia/scm/api/rest/resources/AbstractManagerResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/rest/resources/AbstractManagerResourceTest.java index 41bcac3c6a..c2d7eef852 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/rest/resources/AbstractManagerResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/rest/resources/AbstractManagerResourceTest.java @@ -105,6 +105,11 @@ public class AbstractManagerResourceTest { return id; } + @Override + public String getDisplayName() { + return id; + } + @Override public void setLastModified(Long timestamp) { diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java new file mode 100644 index 0000000000..a6fd5f1f8a --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java @@ -0,0 +1,368 @@ +package sonia.scm.api.v2.resources; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.support.SubjectThreadState; +import org.apache.shiro.util.ThreadContext; +import org.apache.shiro.util.ThreadState; +import org.assertj.core.util.Lists; +import org.jboss.resteasy.core.Dispatcher; +import org.jboss.resteasy.mock.MockHttpRequest; +import org.jboss.resteasy.mock.MockHttpResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.SCMContextProvider; +import sonia.scm.config.ScmConfiguration; +import sonia.scm.group.DefaultGroupManager; +import sonia.scm.group.Group; +import sonia.scm.group.GroupManager; +import sonia.scm.group.xml.XmlGroupDAO; +import sonia.scm.repository.DefaultRepositoryManager; +import sonia.scm.repository.NamespaceStrategy; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryManager; +import sonia.scm.repository.xml.XmlRepositoryDAO; +import sonia.scm.security.KeyGenerator; +import sonia.scm.store.ConfigurationStore; +import sonia.scm.store.ConfigurationStoreFactory; +import sonia.scm.user.DefaultUserManager; +import sonia.scm.user.User; +import sonia.scm.user.UserManager; +import sonia.scm.user.xml.XmlUserDAO; +import sonia.scm.web.VndMediaType; +import sonia.scm.xml.XmlDatabase; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher; + +@RunWith(MockitoJUnitRunner.Silent.class) +public class AutoCompleteResourceTest { + + public static final String URL = "/" + AutoCompleteResource.PATH; + private final Integer defaultLimit = Integer.valueOf(AutoCompleteResource.DEFAULT_LIMIT); + private Dispatcher dispatcher; + + private final Subject subject = mock(Subject.class); + private final ThreadState subjectThreadState = new SubjectThreadState(subject); + + + private XmlUserDAO userDaoMock; + + private XmlGroupDAO groupDaoMock; + + private XmlRepositoryDAO repoDaoMock; + private XmlDatabase xmlDB; + private ObjectMapper jsonObjectMapper = new ObjectMapper(); + + + @Before + public void prepareEnvironment() { + initMocks(this); + ConfigurationStoreFactory storeFactory = mock(ConfigurationStoreFactory.class); + ConfigurationStore storeConfig = mock(ConfigurationStore.class); + xmlDB = mock(XmlDatabase.class); + when(storeConfig.get()).thenReturn(xmlDB); + when(storeFactory.getStore(any(), any())).thenReturn(storeConfig); + XmlUserDAO userDao = new XmlUserDAO(storeFactory); + userDaoMock = spy(userDao); + XmlGroupDAO groupDAO = new XmlGroupDAO(storeFactory); + groupDaoMock = spy(groupDAO); + XmlRepositoryDAO repoDao = new XmlRepositoryDAO(storeFactory); + repoDaoMock = spy(repoDao); + ReducedObjectModelToDtoMapperImpl mapper = new ReducedObjectModelToDtoMapperImpl(); + UserManager userManager = new DefaultUserManager(userDaoMock); + GroupManager groupManager = new DefaultGroupManager(groupDaoMock); + RepositoryManager repositoryManager = new DefaultRepositoryManager(mock(ScmConfiguration.class), mock(SCMContextProvider.class), mock(KeyGenerator.class), repoDaoMock, new HashSet<>(), mock(NamespaceStrategy.class)); + AutoCompleteResource autoCompleteResource = new AutoCompleteResource(mapper, userManager, groupManager, repositoryManager); + dispatcher = createDispatcher(autoCompleteResource); + subjectThreadState.bind(); + ThreadContext.bind(subject); + when(subject.isPermitted(any(String.class))).thenReturn(true); + } + + @After + public void cleanupContext() { + ThreadContext.unbindSubject(); + } + + @Test + public void shouldGet400OnFailedParameterForUserSearch() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "user") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(400, response.getStatus()); + } + + @Test + public void shouldGet400IfParameterLengthLessThan2CharsForUserSearch() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "user?filter=a") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(400, response.getStatus()); + } + + @Test + public void shouldSearchUsers() throws Exception { + ArrayList users = Lists.newArrayList(createMockUser("YuCantFindMe", "ha ha"), createMockUser("user1", "User 1"), createMockUser("user2", "User 2")); + String searched = "user"; + when(xmlDB.values()).thenReturn(users); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "user?filter=" + searched) + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + + assertResultSize(response, 2); + assertTrue(response.getContentAsString().contains("\"id\":\"user1\"")); + assertTrue(response.getContentAsString().contains("\"displayName\":\"User 1\"")); + assertTrue(response.getContentAsString().contains("\"id\":\"user2\"")); + assertTrue(response.getContentAsString().contains("\"displayName\":\"User 2\"")); + } + + @Test + public void shouldSearchUsersWithLimitLength() throws Exception { + List users = IntStream.range(0, 10).boxed().map(i -> createMockUser("user" + i, "User " + i)).collect(Collectors.toList()); + when(xmlDB.values()).thenReturn(users); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "user?filter=user&limit=1") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + verify(userDaoMock).getFiltered(eq("user"), eq(1)); + assertResultSize(response, 1); + } + + @Test + public void shouldSearchUsersWithDefaultLimitLength() throws Exception { + List userList = IntStream.range(0, 10).boxed().map(i -> createMockUser("user" + i, "User " + i)).collect(Collectors.toList()); + when(xmlDB.values()).thenReturn(userList); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "user?filter=user") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + verify(userDaoMock).getFiltered(eq("user"), eq(defaultLimit)); + assertResultSize(response, defaultLimit); + } + + @Test + public void shouldGet400OnFailedParameterForGroupSearch() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "group") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(400, response.getStatus()); + } + + @Test + public void shouldGet400IfParameterLengthLessThan2CharsForGroupSearch() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "group?filter=a") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(400, response.getStatus()); + } + + @Test + public void shouldSearchGroups() throws Exception { + ArrayList groups = Lists.newArrayList(createMockGroup("YuCantFindMe"), createMockGroup("group_1"), createMockGroup("group_2")); + String searched = "group"; + when(xmlDB.values()).thenReturn(groups); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "group?filter=" + searched) + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + assertResultSize(response, 2); + assertTrue(response.getContentAsString().contains("\"id\":\"group_1\"")); + assertTrue(response.getContentAsString().contains("\"displayName\":\"group_1\"")); + assertTrue(response.getContentAsString().contains("\"id\":\"group_2\"")); + assertTrue(response.getContentAsString().contains("\"displayName\":\"group_2\"")); + } + + @Test + public void shouldSearchGroupsWithLimitLength() throws Exception { + List groups = IntStream.range(0, 10).boxed().map(i -> createMockGroup("group_" + i)).collect(Collectors.toList()); + when(xmlDB.values()).thenReturn(groups); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "group?filter=group&limit=1") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + verify(groupDaoMock).getFiltered(eq("group"), eq(1)); + assertResultSize(response, 1); + } + + @Test + public void shouldSearchGroupsWithDefaultLimitLength() throws Exception { + List groups = IntStream.range(0, 10).boxed().map(i -> createMockGroup("group_" + i)).collect(Collectors.toList()); + when(xmlDB.values()).thenReturn(groups); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "group?filter=group") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + verify(groupDaoMock).getFiltered(eq("group"), eq(defaultLimit)); + assertResultSize(response, defaultLimit); + } + + + @Test + public void shouldGet400OnFailedParameterForRepoSearch() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "repository") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(400, response.getStatus()); + } + + @Test + public void shouldGet400IfParameterLengthLessThan2CharsForRepoSearch() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "repository?filter=a") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(400, response.getStatus()); + } + + @Test + public void shouldSearchRepos() throws Exception { + List repos = Lists.newArrayList(createMockRepo("YCannotFindMe"), createMockRepo("repo1"), createMockRepo("repo2")); + when(xmlDB.values()).thenReturn(repos); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "repository?filter=repo") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + assertResultSize(response, 2); + assertTrue(response.getContentAsString().contains("\"displayName\":\"space/repo1\"")); + assertTrue(response.getContentAsString().contains("\"displayName\":\"space/repo2\"")); + } + + @Test + public void shouldSearchReposWithLimitLength() throws Exception { + List repositories = IntStream.range(0, 10).boxed().map(i -> createMockRepo("repo" + i)).collect(Collectors.toList()); + when(xmlDB.values()).thenReturn(repositories); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "repository?filter=repo&limit=1") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + verify(repoDaoMock).getFiltered(eq("repo"), eq(1)); + assertResultSize(response, 1); + } + + @Test + public void shouldSearchReposWithDefaultLimitLength() throws Exception { + List repositories = IntStream.range(0, 10).boxed().map(i -> createMockRepo("repo" + i)).collect(Collectors.toList()); + when(xmlDB.values()).thenReturn(repositories); + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "repository?filter=repo") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + verify(repoDaoMock).getFiltered(eq("repo"), eq(defaultLimit)); + assertResultSize(response, defaultLimit); + } + + + private User createMockUser(String id, String name) { + return new User(id, name, "em@l.de"); + } + + + private Group createMockGroup(String name) { + Group group = new Group("type", name); + group.setDescription(name); + return group; + } + + private Repository createMockRepo(String repository) { + return new Repository("id", "git", "space", repository); + } + + private void assertResultSize(MockHttpResponse response, int size) throws java.io.IOException { + ReducedObjectModelDto[] reducedObjectModelDtos = jsonObjectMapper.readValue(response.getContentAsString(), ReducedObjectModelDto[].class); + assertTrue(reducedObjectModelDtos.length == size); + } +} diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java index a1abdb6ff4..d28e96d8a4 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java @@ -17,6 +17,7 @@ public class DispatcherMock { dispatcher.getProviderFactory().registerProvider(InternalRepositoryExceptionMapper.class); dispatcher.getProviderFactory().registerProvider(ChangePasswordNotAllowedExceptionMapper.class); dispatcher.getProviderFactory().registerProvider(InvalidPasswordExceptionMapper.class); + dispatcher.getProviderFactory().registerProvider(AutoCompleteBadParamExceptionMapper.class); return dispatcher; } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java index 6ab1dc6aeb..3d33fa0eb6 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java @@ -23,7 +23,6 @@ import javax.servlet.http.HttpServletResponse; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.text.MessageFormat; import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; diff --git a/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java b/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java index 5e7963ef1d..291369e7b8 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java @@ -161,8 +161,8 @@ public class DefaultAuthorizationCollectorTest { AuthorizationInfo authInfo = collector.collect(); assertThat(authInfo.getRoles(), Matchers.contains(Role.USER)); - assertThat(authInfo.getStringPermissions(), hasSize(1)); - assertThat(authInfo.getStringPermissions(), contains("user:read:trillian")); + assertThat(authInfo.getStringPermissions(), hasSize(4)); + assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "repository:autocomplete", "user:read:trillian")); assertThat(authInfo.getObjectPermissions(), nullValue()); } @@ -209,7 +209,7 @@ public class DefaultAuthorizationCollectorTest { AuthorizationInfo authInfo = collector.collect(); assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER)); assertThat(authInfo.getObjectPermissions(), nullValue()); - assertThat(authInfo.getStringPermissions(), containsInAnyOrder("repository:read,pull:one", "repository:read,pull,push:two", "user:read:trillian")); + assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete","repository:autocomplete", "repository:read,pull:one", "repository:read,pull,push:two", "user:read:trillian")); } /** @@ -230,7 +230,7 @@ public class DefaultAuthorizationCollectorTest { AuthorizationInfo authInfo = collector.collect(); assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER)); assertThat(authInfo.getObjectPermissions(), nullValue()); - assertThat(authInfo.getStringPermissions(), containsInAnyOrder("one:one", "two:two", "user:read:trillian")); + assertThat(authInfo.getStringPermissions(), containsInAnyOrder("one:one", "two:two", "user:read:trillian", "user:autocomplete" , "group:autocomplete", "repository:autocomplete")); } private void authenticate(User user, String group, String... groups) { From 8908bf0646eefb6452ae1210a3af538519b7535d Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Mon, 8 Oct 2018 14:33:48 +0200 Subject: [PATCH 062/121] try lerna exec with --bail=false --- scm-ui-components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-ui-components/package.json b/scm-ui-components/package.json index 73c20625bd..b9447e45f9 100644 --- a/scm-ui-components/package.json +++ b/scm-ui-components/package.json @@ -5,7 +5,7 @@ "scripts": { "bootstrap": "lerna bootstrap", "link": "lerna exec -- yarn link", - "unlink": "lerna exec --no-bail -- yarn unlink" + "unlink": "lerna exec --bail=false -- yarn unlink" }, "devDependencies": { "lerna": "^3.2.1" From 9f02102f42324586595520664f6f4f9802ae3df5 Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Mon, 8 Oct 2018 15:51:29 +0200 Subject: [PATCH 063/121] skip yarn unlink --- scm-ui-components/lerna.json | 2 +- scm-ui-components/pom.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scm-ui-components/lerna.json b/scm-ui-components/lerna.json index 02962cf634..37166b8655 100644 --- a/scm-ui-components/lerna.json +++ b/scm-ui-components/lerna.json @@ -2,6 +2,6 @@ "packages": [ "packages/*" ], - "version": "0.0.0", + "version": "3.2.1", "npmClient": "yarn" } diff --git a/scm-ui-components/pom.xml b/scm-ui-components/pom.xml index f5544a9e24..830945a8a3 100644 --- a/scm-ui-components/pom.xml +++ b/scm-ui-components/pom.xml @@ -55,6 +55,7 @@ run + true From dbe9ee59a8fc6a4d5e985867215ca412751f075b Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 8 Oct 2018 17:34:11 +0200 Subject: [PATCH 064/121] Fixed issues noticed in review --- .../ui-types/src/{Branch.js => Branches.js} | 0 .../packages/ui-types/src/Changesets.js | 10 +-- .../packages/ui-types/src/index.js | 4 +- scm-ui/public/locales/en/repos.json | 2 +- .../components/changesets/ChangesetAuthor.js | 26 ++++--- .../components/changesets/ChangesetAvatar.js | 3 +- .../components/changesets/ChangesetList.js | 10 ++- .../components/changesets/ChangesetRow.js | 7 +- scm-ui/src/repos/containers/BranchChooser.js | 16 +++-- scm-ui/src/repos/containers/Changesets.js | 70 ++++++++++--------- scm-ui/src/repos/containers/RepositoryRoot.js | 10 +-- scm-ui/src/repos/modules/branches.js | 35 ++++++++-- scm-ui/src/repos/modules/changesets.js | 63 ++++++++++------- scm-ui/src/repos/modules/changesets.test.js | 8 ++- 14 files changed, 160 insertions(+), 104 deletions(-) rename scm-ui-components/packages/ui-types/src/{Branch.js => Branches.js} (100%) diff --git a/scm-ui-components/packages/ui-types/src/Branch.js b/scm-ui-components/packages/ui-types/src/Branches.js similarity index 100% rename from scm-ui-components/packages/ui-types/src/Branch.js rename to scm-ui-components/packages/ui-types/src/Branches.js diff --git a/scm-ui-components/packages/ui-types/src/Changesets.js b/scm-ui-components/packages/ui-types/src/Changesets.js index 12b87173fe..cab4233a7f 100644 --- a/scm-ui-components/packages/ui-types/src/Changesets.js +++ b/scm-ui-components/packages/ui-types/src/Changesets.js @@ -1,21 +1,21 @@ //@flow import type {Links} from "./hal"; import type {Tag} from "./Tags"; -import type {Branch} from "./Branch"; +import type {Branch} from "./Branches"; export type Changeset = { id: string, date: Date, author: { name: string, - mail: string + mail?: string }, description: string, _links: Links, _embedded: { - tags: Tag[], - branches: Branch[], - parents: ParentChangeset[] + tags?: Tag[], + branches?: Branch[], + parents?: ParentChangeset[] }; } diff --git a/scm-ui-components/packages/ui-types/src/index.js b/scm-ui-components/packages/ui-types/src/index.js index 5e9c14e758..7aea444abb 100644 --- a/scm-ui-components/packages/ui-types/src/index.js +++ b/scm-ui-components/packages/ui-types/src/index.js @@ -9,8 +9,10 @@ export type { Group, Member } from "./Group"; export type { Repository, RepositoryCollection, RepositoryGroup } from "./Repositories"; export type { RepositoryType, RepositoryTypeCollection } from "./RepositoryTypes"; +export type { Branch } from "./Branches"; + export type { Changeset } from "./Changesets"; -export type { Tag } from "./Tags" +export type { Tag } from "./Tags"; export type { Config } from "./Config"; diff --git a/scm-ui/public/locales/en/repos.json b/scm-ui/public/locales/en/repos.json index 67732372a3..b55428e14d 100644 --- a/scm-ui/public/locales/en/repos.json +++ b/scm-ui/public/locales/en/repos.json @@ -23,7 +23,7 @@ "back-label": "Back", "navigation-label": "Navigation", "information": "Information", - "history": "History" + "history": "Commits" }, "create": { "title": "Create Repository", diff --git a/scm-ui/src/repos/components/changesets/ChangesetAuthor.js b/scm-ui/src/repos/components/changesets/ChangesetAuthor.js index d2993daed4..0007b24f31 100644 --- a/scm-ui/src/repos/components/changesets/ChangesetAuthor.js +++ b/scm-ui/src/repos/components/changesets/ChangesetAuthor.js @@ -9,19 +9,25 @@ type Props = { export default class ChangesetAuthor extends React.Component { render() { - const { changeset } = this.props; + const { name } = this.props.changeset.author; + return ( <> - {changeset.author.name}{" "} - - < - {changeset.author.mail} - > - + {name} {this.renderMail()} ); } + + renderMail() { + const { mail } = this.props.changeset.author; + if (mail) { + return ( + + < + {mail} + > + + ); + } + } } diff --git a/scm-ui/src/repos/components/changesets/ChangesetAvatar.js b/scm-ui/src/repos/components/changesets/ChangesetAvatar.js index 0a5afc1778..90f116daed 100644 --- a/scm-ui/src/repos/components/changesets/ChangesetAvatar.js +++ b/scm-ui/src/repos/components/changesets/ChangesetAvatar.js @@ -1,8 +1,7 @@ //@flow import React from "react"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; -import type { Changeset } from "../../../../../scm-ui-components/packages/ui-types/src/index"; -import { Image } from "../../../../../scm-ui-components/packages/ui-components/src/index"; +import type { Changeset } from "@scm-manager/ui-types"; type Props = { changeset: Changeset diff --git a/scm-ui/src/repos/components/changesets/ChangesetList.js b/scm-ui/src/repos/components/changesets/ChangesetList.js index 4dd1762e1c..1eaae67ff0 100644 --- a/scm-ui/src/repos/components/changesets/ChangesetList.js +++ b/scm-ui/src/repos/components/changesets/ChangesetList.js @@ -1,7 +1,7 @@ // @flow import ChangesetRow from "./ChangesetRow"; import React from "react"; -import type { Changeset, Repository } from "../../../../../scm-ui-components/packages/ui-types/src/index"; +import type { Changeset, Repository } from "@scm-manager/ui-types"; import classNames from "classnames"; type Props = { @@ -13,7 +13,13 @@ class ChangesetList extends React.Component { render() { const { repository, changesets } = this.props; const content = changesets.map((changeset, index) => { - return ; + return ( + + ); }); return
{content}
; } diff --git a/scm-ui/src/repos/components/changesets/ChangesetRow.js b/scm-ui/src/repos/components/changesets/ChangesetRow.js index 7ad8c92650..675bbe7cda 100644 --- a/scm-ui/src/repos/components/changesets/ChangesetRow.js +++ b/scm-ui/src/repos/components/changesets/ChangesetRow.js @@ -1,15 +1,12 @@ //@flow import React from "react"; -import type { - Changeset, - Repository -} from "../../../../../scm-ui-components/packages/ui-types/src/index"; +import type { Changeset, Repository } from "@scm-manager/ui-types"; import classNames from "classnames"; import { translate, Interpolate } from "react-i18next"; import ChangesetAvatar from "./ChangesetAvatar"; import ChangesetId from "./ChangesetId"; import injectSheet from "react-jss"; -import { DateFromNow } from "../../../../../scm-ui-components/packages/ui-components/src/index"; +import { DateFromNow } from "@scm-manager/ui-components"; import ChangesetAuthor from "./ChangesetAuthor"; const styles = { diff --git a/scm-ui/src/repos/containers/BranchChooser.js b/scm-ui/src/repos/containers/BranchChooser.js index d8d8aae61e..607d96882c 100644 --- a/scm-ui/src/repos/containers/BranchChooser.js +++ b/scm-ui/src/repos/containers/BranchChooser.js @@ -1,18 +1,22 @@ // @flow import React from "react"; -import type {Repository} from "@scm-manager/ui-types"; -import {connect} from "react-redux"; -import {fetchBranches, getBranches, isFetchBranchesPending} from "../modules/branches"; +import type { Repository, Branch } from "@scm-manager/ui-types"; +import { connect } from "react-redux"; +import { + fetchBranches, + getBranches, + isFetchBranchesPending +} from "../modules/branches"; -import {Loading} from "@scm-manager/ui-components"; +import { Loading } from "@scm-manager/ui-components"; import DropDown from "../components/DropDown"; type Props = { repository: Repository, fetchBranches: Repository => void, - callback: Branch => void, //TODO use correct branch type - branches: Branch[], //TODO use correct branch type + callback: (?Branch) => void, + branches: Branch[], selectedBranchName: string, loading: boolean }; diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 0dc85320b5..7e7dcc33f3 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -1,8 +1,12 @@ // @flow import React from "react"; -import {connect} from "react-redux"; -import {translate} from "react-i18next"; -import {ErrorNotification, Loading, Paginator} from "@scm-manager/ui-components"; +import { connect } from "react-redux"; +import { translate } from "react-i18next"; +import { + ErrorNotification, + Loading, + Paginator +} from "@scm-manager/ui-components"; import { fetchChangesets, @@ -14,11 +18,16 @@ import { isFetchChangesetsPending, selectListAsCollection } from "../modules/changesets"; -import type {History} from "history"; -import type {Changeset, PagedCollection, Repository} from "@scm-manager/ui-types"; +import type { History } from "history"; +import type { + Changeset, + PagedCollection, + Repository, + Branch +} from "@scm-manager/ui-types"; import ChangesetList from "../components/changesets/ChangesetList"; -import {withRouter} from "react-router-dom"; -import {fetchBranches, getBranch, getBranchNames} from "../modules/branches"; +import { withRouter } from "react-router-dom"; +import { fetchBranches, getBranch, getBranchNames } from "../modules/branches"; import BranchChooser from "./BranchChooser"; type Props = { @@ -34,7 +43,7 @@ type Props = { list: PagedCollection, fetchChangesetsByLink: (Repository, string, Branch) => void, fetchChangesetsByPage: (Repository, number) => void, - fetchChangesetsByBranchAndPage: (Repository, string, number) => void, + fetchChangesetsByBranchAndPage: (Repository, Branch, number) => void, fetchBranches: Repository => void, page: number, t: string => string, @@ -63,7 +72,9 @@ class Changesets extends React.PureComponent { }; componentDidMount() { - this.updateContent(); + if (!this.props.loading) { + this.updateContent(); + } } updateContent() { @@ -81,15 +92,14 @@ class Changesets extends React.PureComponent { } } - componentDidUpdate(prevProps: Props, prevState: State, snapshot: any) { + componentDidUpdate(prevProps: Props) { const { page, list, repository, match } = this.props; const { namespace, name } = repository; - const branch = match.params.branch; - + const branch = decodeURIComponent(match.params.branch); if (!this.props.loading) { if (prevProps.branch !== this.props.branch) { - this.updateContent(); this.setState({ branch }); + this.updateContent(); } if (list && (list.page || list.page === 0)) { @@ -98,11 +108,11 @@ class Changesets extends React.PureComponent { if (page !== statePage) { if (branch) { this.props.history.push( - `/repo/${namespace}/${name}/${branch}/history/${statePage}` + `/repo/${namespace}/${name}/${branch}/changesets/${statePage}` ); } else { this.props.history.push( - `/repo/${namespace}/${name}/history/${statePage}` + `/repo/${namespace}/${name}/changesets/${statePage}` ); } } @@ -129,7 +139,7 @@ class Changesets extends React.PureComponent { } renderList = () => { - const branch = this.props.match.params.branch; + const branch = decodeURIComponent(this.props.match.params.branch); const { repository, changesets, t } = this.props; return ( @@ -160,12 +170,16 @@ class Changesets extends React.PureComponent { branchChanged = (branch: Branch): void => { const { history, repository } = this.props; if (branch === undefined) { - history.push(`/repo/${repository.namespace}/${repository.name}/history`); + history.push( + `/repo/${repository.namespace}/${repository.name}/changesets` + ); } else { - const branchName = branch.name; + const branchName = encodeURIComponent(branch.name); this.setState({ branch: branchName }); history.push( - `/repo/${repository.namespace}/${repository.name}/${branchName}/history` + `/repo/${repository.namespace}/${ + repository.name + }/${branchName}/changesets` ); } }; @@ -185,12 +199,11 @@ const mapStateToProps = (state, ownProps: Props) => { const { repository } = ownProps; const branchName = ownProps.match.params.branch; const branch = getBranch(state, repository, branchName); - const key = createKey(repository, branch); const loading = isFetchChangesetsPending(state, repository, branch); - const changesets = getChangesetsFromState(state, key); + const changesets = getChangesetsFromState(state, repository); const branchNames = getBranchNames(state, repository); const error = getFetchChangesetsFailure(state, repository, branch); - const list = selectListAsCollection(state, key); + const list = selectListAsCollection(state, repository); const page = getPageFromProps(ownProps); return { @@ -204,15 +217,6 @@ const mapStateToProps = (state, ownProps: Props) => { }; }; -const createKey = (repository: Repository, branch?: Branch): string => { - const { namespace, name } = repository; - let key = `${namespace}/${name}`; - if (branch && branch.name) { - key = key + `/${branch.name}`; - } - return key; -}; - const mapDispatchToProps = dispatch => { return { fetchBranches: (repository: Repository) => { @@ -226,7 +230,7 @@ const mapDispatchToProps = dispatch => { }, fetchChangesetsByBranchAndPage: ( repository, - branch: string, + branch: Branch, page: number ) => { dispatch(fetchChangesetsByBranchAndPage(repository, branch, page)); @@ -234,7 +238,7 @@ const mapDispatchToProps = dispatch => { fetchChangesetsByLink: ( repository: Repository, link: string, - branch?: string + branch?: Branch ) => { dispatch(fetchChangesetsByLink(repository, link, branch)); } diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index b274540370..ec780a5bda 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -104,22 +104,22 @@ class RepositoryRoot extends React.Component { /> } /> } /> } /> } /> @@ -129,7 +129,7 @@ class RepositoryRoot extends React.Component { diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 5f079ff8fd..6d70ae0925 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -5,7 +5,7 @@ import { SUCCESS_SUFFIX } from "../../modules/types"; import { apiClient } from "@scm-manager/ui-components"; -import type { Repository } from "@scm-manager/ui-types"; +import type { Repository, Action, Branch } from "@scm-manager/ui-types"; import { isPending } from "../../modules/pending"; export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; @@ -16,6 +16,14 @@ export const FETCH_BRANCHES_FAILURE = `${FETCH_BRANCHES}_${FAILURE_SUFFIX}`; // Fetching branches export function fetchBranches(repository: Repository) { + if (!repository._links.branches) { + return { + type: FETCH_BRANCHES_SUCCESS, + payload: { repository, data: {} }, + itemId: createKey(repository) + }; + } + return function(dispatch: any) { dispatch(fetchBranchesPending(repository)); return apiClient @@ -81,7 +89,10 @@ export default function reducer( } } -function extractBranchesByNames(data: any, oldBranchesByNames: any): Branch[] { +function extractBranchesByNames(data: any, oldBranchesByNames: any): ?Object { + if (!data._embedded || !data._embedded.branches) { + return {}; + } const branches = data._embedded.branches; const branchesByNames = {}; @@ -97,10 +108,13 @@ function extractBranchesByNames(data: any, oldBranchesByNames: any): Branch[] { // Selectors -export function getBranchNames(state: Object, repository: Repository) { +export function getBranchNames( + state: Object, + repository: Repository +): ?Array { const key = createKey(repository); if (!state.branches[key] || !state.branches[key].byNames) { - return null; + return []; } return Object.keys(state.branches[key].byNames); } @@ -114,7 +128,11 @@ export function getBranches(state: Object, repository: Repository) { } } -export function getBranch(state: Object, repository: Repository, name: string) { +export function getBranch( + state: Object, + repository: Repository, + name: string +): ?Branch { const key = createKey(repository); if (state.branches[key]) { if (state.branches[key].byNames[name]) { @@ -124,11 +142,14 @@ export function getBranch(state: Object, repository: Repository, name: string) { return undefined; } -export function isFetchBranchesPending(state: Object, repository: Repository) { +export function isFetchBranchesPending( + state: Object, + repository: Repository +): boolean { return isPending(state, FETCH_BRANCHES, createKey(repository)); } -function createKey(repository: Repository) { +function createKey(repository: Repository): string { const { namespace, name } = repository; return `${namespace}/${name}`; } diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index 4cb71af9cd..e7e7601196 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -1,11 +1,21 @@ // @flow -import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; -import {apiClient} from "@scm-manager/ui-components"; -import {isPending} from "../../modules/pending"; -import {getFailure} from "../../modules/failure"; -import {combineReducers} from "redux"; -import type {Action, Changeset, PagedCollection, Repository} from "@scm-manager/ui-types"; +import { + FAILURE_SUFFIX, + PENDING_SUFFIX, + SUCCESS_SUFFIX +} from "../../modules/types"; +import { apiClient } from "@scm-manager/ui-components"; +import { isPending } from "../../modules/pending"; +import { getFailure } from "../../modules/failure"; +import { combineReducers } from "redux"; +import type { + Action, + Changeset, + PagedCollection, + Repository, + Branch +} from "@scm-manager/ui-types"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -69,7 +79,7 @@ export function fetchChangesets(repository: Repository) { } export function fetchChangesetsByPage(repository: Repository, page: number) { - return fetchChangesetsWithOptions(repository, "", `?page=${page - 1}`); + return fetchChangesetsWithOptions(repository, undefined, `?page=${page - 1}`); } // TODO: Rewrite code to fetch changesets by branches, adjust tests and let BranchChooser fetch branches @@ -93,9 +103,7 @@ export function fetchChangesetsPending( branch?: Branch ): Action { const itemId = createItemId(repository, branch); - if (!branch) { - branch = ""; - } + return { type: FETCH_CHANGESETS_PENDING, payload: { repository, branch }, @@ -150,8 +158,13 @@ function byKeyReducer( const changesets = action.payload._embedded.changesets; const changesetIds = changesets.map(c => c.id); const key = action.itemId; + + if (!key) { + return state; + } + let oldChangesets = { [key]: {} }; - if (state[key] !== undefined) { + if (state[key]) { oldChangesets[key] = state[key]; } const byIds = extractChangesetsByIds(changesets, oldChangesets[key].byId); @@ -196,7 +209,7 @@ function extractChangesetsByIds(changesets: any, oldChangesetsByIds: any) { export function getChangesets( state: Object, repository: Repository, - branch?: string + branch?: Branch ) { const key = createItemId(repository, branch); if (!state.changesets.byKey[key]) { @@ -208,7 +221,7 @@ export function getChangesets( export function isFetchChangesetsPending( state: Object, repository: Repository, - branch?: string + branch?: Branch ) { return isPending(state, FETCH_CHANGESETS, createItemId(repository, branch)); } @@ -216,20 +229,21 @@ export function isFetchChangesetsPending( export function getFetchChangesetsFailure( state: Object, repository: Repository, - branch?: string + branch?: Branch ) { return getFailure(state, FETCH_CHANGESETS, createItemId(repository, branch)); } -const selectList = (state: Object, key: string) => { - if (state.changesets.byKey[key] && state.changesets.byKey[key].list) { - return state.changesets.byKey[key].list; +const selectList = (state: Object, repository: Repository) => { + const itemId = createItemId(repository); + if (state.changesets.byKey[itemId] && state.changesets.byKey[itemId].list) { + return state.changesets.byKey[itemId].list; } return {}; }; -const selectListEntry = (state: Object, key: string): Object => { - const list = selectList(state, key); +const selectListEntry = (state: Object, repository: Repository): Object => { + const list = selectList(state, repository); if (list.entry) { return list.entry; } @@ -238,20 +252,21 @@ const selectListEntry = (state: Object, key: string): Object => { export const selectListAsCollection = ( state: Object, - key: string + repository: Repository ): PagedCollection => { - return selectListEntry(state, key); + return selectListEntry(state, repository); }; -export function getChangesetsFromState(state: Object, key: string) { - const changesetIds = selectList(state, key).entries; +export function getChangesetsFromState(state: Object, repository: Repository) { + const itemId = createItemId(repository); + const changesetIds = selectList(state, repository).entries; if (!changesetIds) { return null; } const changesetEntries: Changeset[] = []; for (let id of changesetIds) { - changesetEntries.push(state.changesets.byKey[key].byId[id]); + changesetEntries.push(state.changesets.byKey[itemId].byId[id]); } return changesetEntries; diff --git a/scm-ui/src/repos/modules/changesets.test.js b/scm-ui/src/repos/modules/changesets.test.js index 3512921db0..6a557cf1ac 100644 --- a/scm-ui/src/repos/modules/changesets.test.js +++ b/scm-ui/src/repos/modules/changesets.test.js @@ -20,6 +20,7 @@ import { import reducer from "./changesets"; const branch = { name: "specific", + revision: "123", _links: { history: { href: @@ -31,6 +32,7 @@ const branch = { const repository = { namespace: "foo", name: "bar", + type: "GIT", _links: { self: { href: "http://scm/api/rest/v2/repositories/foo/bar" @@ -63,7 +65,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: { repository, branch: "" }, + payload: { repository }, itemId: "foo/bar" }, { @@ -111,7 +113,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: { repository, branch: "" }, + payload: { repository }, itemId } ]; @@ -152,7 +154,7 @@ describe("changesets", () => { const expectedActions = [ { type: FETCH_CHANGESETS_PENDING, - payload: { repository, branch: "" }, + payload: { repository }, itemId: "foo/bar" }, { From 8de89928b385c107dce0e3e6736fb358a0f86523 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 9 Oct 2018 08:50:20 +0200 Subject: [PATCH 065/121] remove unused imports --- .../main/java/sonia/scm/repository/GitUtil.java | 2 -- .../scm/repository/spi/AbstractGitCommand.java | 15 ++++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 803348dc33..faa654307b 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -39,8 +39,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; -import lombok.AllArgsConstructor; -import lombok.Getter; import org.eclipse.jgit.api.FetchCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java index df21d61eef..2970bbd627 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java @@ -35,22 +35,19 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.base.Strings; -import lombok.AllArgsConstructor; -import lombok.Getter; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; - -//~--- JDK imports ------------------------------------------------------------ - -import java.io.IOException; -import java.util.Optional; - -import org.eclipse.jgit.lib.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.repository.GitConstants; import sonia.scm.repository.GitUtil; +import java.io.IOException; +import java.util.Optional; + +//~--- JDK imports ------------------------------------------------------------ + /** * * @author Sebastian Sdorra From 768309cea45a2efe9981539b618923e103ece25b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 9 Oct 2018 08:52:33 +0200 Subject: [PATCH 066/121] use develop branch instead of default --- .../src/main/java/sonia/scm/repository/GitUtil.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index faa654307b..13340a20e7 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -528,9 +528,9 @@ public final class GitUtil return of(master); } - Ref defaultBranch = refs.get(REF_HEAD_PREFIX + "default"); - if (defaultBranch != null) { - return of(defaultBranch); + Ref develop = refs.get(REF_HEAD_PREFIX + "develop"); + if (develop != null) { + return of(develop); } return refs.entrySet() From 41b47b13dcfbcbabf2afe5319bdcff4e7ec4836d Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Tue, 9 Oct 2018 08:55:57 +0200 Subject: [PATCH 067/121] use javax validation --- .../java/sonia/scm/repository/Repository.java | 2 +- .../java/sonia/scm/xml/AbstractXmlDAO.java | 3 +- .../AutoCompleteBadParamException.java | 11 ------ .../AutoCompleteBadParamExceptionMapper.java | 16 --------- .../v2/resources/AutoCompleteResource.java | 35 +++++++------------ .../scm/api/v2/resources/DispatcherMock.java | 1 - 6 files changed, 16 insertions(+), 52 deletions(-) delete mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamException.java delete mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamExceptionMapper.java diff --git a/scm-core/src/main/java/sonia/scm/repository/Repository.java b/scm-core/src/main/java/sonia/scm/repository/Repository.java index 7f2aab6865..97915eeaa5 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Repository.java +++ b/scm-core/src/main/java/sonia/scm/repository/Repository.java @@ -186,7 +186,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per @Override public String getDisplayName() { - return getNamespaceAndName().toString(); + return getNamespace() + "/" + getName(); } @Override diff --git a/scm-dao-xml/src/main/java/sonia/scm/xml/AbstractXmlDAO.java b/scm-dao-xml/src/main/java/sonia/scm/xml/AbstractXmlDAO.java index f0907538cf..ee1affe252 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/xml/AbstractXmlDAO.java +++ b/scm-dao-xml/src/main/java/sonia/scm/xml/AbstractXmlDAO.java @@ -35,6 +35,7 @@ package sonia.scm.xml; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -241,7 +242,7 @@ public abstract class AbstractXmlDAO item.getId().contains(searched) || (item.getDisplayName() != null && item.getDisplayName().contains(searched))) + .filter(item -> StringUtils.containsIgnoreCase(item.getId(), searched) || (item.getDisplayName() != null && StringUtils.containsIgnoreCase(item.getDisplayName() , searched))) .limit(limit <= 0 ? size : limit) .collect(Collectors.toList())); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamException.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamException.java deleted file mode 100644 index 1f3f7177bd..0000000000 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamException.java +++ /dev/null @@ -1,11 +0,0 @@ -package sonia.scm.api.v2.resources; - -public class AutoCompleteBadParamException extends Exception { - - public static final String PARAMETER_IS_REQUIRED = "The parameter is required."; - public static final String INVALID_PARAMETER_LENGTH = "Invalid parameter length."; - - public AutoCompleteBadParamException(String message) { - super(message); - } -} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamExceptionMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamExceptionMapper.java deleted file mode 100644 index d2b2eeaed3..0000000000 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteBadParamExceptionMapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package sonia.scm.api.v2.resources; - -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.ExceptionMapper; -import javax.ws.rs.ext.Provider; - -@Provider -public class AutoCompleteBadParamExceptionMapper implements ExceptionMapper { - - @Override - public Response toResponse(AutoCompleteBadParamException exception) { - return Response.status(Response.Status.BAD_REQUEST) - .entity(exception.getMessage()) - .build(); - } -} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java index 5dfa78a762..eebec9baa4 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java @@ -2,14 +2,14 @@ package sonia.scm.api.v2.resources; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; -import org.apache.commons.lang.StringUtils; +import org.hibernate.validator.constraints.NotEmpty; import sonia.scm.group.GroupManager; import sonia.scm.repository.RepositoryManager; import sonia.scm.user.UserManager; import sonia.scm.web.VndMediaType; import javax.inject.Inject; -import javax.validation.Valid; +import javax.validation.constraints.Size; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -18,14 +18,16 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.util.stream.Collectors; -import static sonia.scm.api.v2.resources.AutoCompleteBadParamException.INVALID_PARAMETER_LENGTH; -import static sonia.scm.api.v2.resources.AutoCompleteBadParamException.PARAMETER_IS_REQUIRED; @Path(AutoCompleteResource.PATH) public class AutoCompleteResource { public static final String PATH = "v2/autocomplete/"; public static final String DEFAULT_LIMIT = "5"; - public static final int MIN_SEARCHED_CHARS = 1; + public static final int MIN_SEARCHED_CHARS = 2; + + public static final String PARAMETER_IS_REQUIRED = "The parameter is required."; + public static final String INVALID_PARAMETER_LENGTH = "Invalid parameter length."; + private ReducedObjectModelToDtoMapper mapper; @@ -51,9 +53,8 @@ public class AutoCompleteResource { @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user:autocomplete\" privilege"), @ResponseCode(code = 500, condition = "internal server error") }) - public Response searchUser(@QueryParam("filter") String filter, - @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) throws AutoCompleteBadParamException { - validateParams(filter); + public Response searchUser(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("filter") String filter, + @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) { return Response.ok(userManager.getFiltered(filter, limit) .stream() .map(mapper::map) @@ -71,9 +72,8 @@ public class AutoCompleteResource { @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"group:autocomplete\" privilege"), @ResponseCode(code = 500, condition = "internal server error") }) - public Response searchGroup(@Valid @QueryParam("filter") String filter, - @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) throws AutoCompleteBadParamException { - validateParams(filter); + public Response searchGroup(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("filter") String filter, + @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) { return Response.ok(groupManager.getFiltered(filter, limit) .stream() .map(mapper::map) @@ -91,9 +91,8 @@ public class AutoCompleteResource { @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"repository:autocomplete\" privilege"), @ResponseCode(code = 500, condition = "internal server error") }) - public Response searchRepo(@Valid @QueryParam("filter") String filter, - @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) throws AutoCompleteBadParamException { - validateParams(filter); + public Response searchRepo(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("filter") String filter, + @DefaultValue(DEFAULT_LIMIT) @QueryParam("limit") Integer limit) { return Response.ok(repositoryManager.getFiltered(filter, limit) .stream() .map(mapper::map) @@ -101,13 +100,5 @@ public class AutoCompleteResource { .build(); } - void validateParams(String filter) throws AutoCompleteBadParamException { - if (StringUtils.isBlank(filter)) { - throw new AutoCompleteBadParamException(PARAMETER_IS_REQUIRED); - } - if (filter.length() <= MIN_SEARCHED_CHARS) { - throw new AutoCompleteBadParamException(INVALID_PARAMETER_LENGTH); - } - } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java index d28e96d8a4..a1abdb6ff4 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java @@ -17,7 +17,6 @@ public class DispatcherMock { dispatcher.getProviderFactory().registerProvider(InternalRepositoryExceptionMapper.class); dispatcher.getProviderFactory().registerProvider(ChangePasswordNotAllowedExceptionMapper.class); dispatcher.getProviderFactory().registerProvider(InvalidPasswordExceptionMapper.class); - dispatcher.getProviderFactory().registerProvider(AutoCompleteBadParamExceptionMapper.class); return dispatcher; } } From 1606add59a9ee5e010087aecaa1e6eddb57eb788 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Tue, 9 Oct 2018 09:22:06 +0200 Subject: [PATCH 068/121] Show BranchChooser div only when there are branches to choose from --- scm-ui/src/repos/containers/BranchChooser.js | 18 +++++++++++------- scm-ui/src/repos/containers/Changesets.js | 16 ++++++---------- scm-ui/src/repos/modules/branches.js | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/scm-ui/src/repos/containers/BranchChooser.js b/scm-ui/src/repos/containers/BranchChooser.js index 607d96882c..007060acf1 100644 --- a/scm-ui/src/repos/containers/BranchChooser.js +++ b/scm-ui/src/repos/containers/BranchChooser.js @@ -18,7 +18,8 @@ type Props = { callback: (?Branch) => void, branches: Branch[], selectedBranchName: string, - loading: boolean + loading: boolean, + label: string }; type State = { @@ -39,17 +40,20 @@ class BranchChooser extends React.Component { } render() { - const { branches, loading } = this.props; + const { branches, loading, label } = this.props; if (loading) { return ; } if (branches && branches.length > 0) { return ( - b.name)} - preselectedOption={this.state.selectedBranchName} - optionSelected={branch => this.branchChanged(branch)} - /> +
+ + b.name)} + preselectedOption={this.state.selectedBranchName} + optionSelected={branch => this.branchChanged(branch)} + /> +
); } diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 7e7dcc33f3..23841ffe96 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -144,16 +144,12 @@ class Changesets extends React.PureComponent { return ( <> -
- - this.branchChanged(branch)} - /> -
+ this.branchChanged(branch)} + /> ); diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 6d70ae0925..c771a9734e 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -132,14 +132,14 @@ export function getBranch( state: Object, repository: Repository, name: string -): ?Branch { +): Branch { const key = createKey(repository); if (state.branches[key]) { if (state.branches[key].byNames[name]) { return state.branches[key].byNames[name]; } } - return undefined; + return null; } export function isFetchBranchesPending( From 2c476c34ef1f75883dc42c769fde970f5e060f47 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 9 Oct 2018 09:10:20 +0000 Subject: [PATCH 069/121] Close branch feature/harmonize_branches_in_changesets From 24052d7896ff7e7870dcad3d4bfcf7a7a9f1cd0f Mon Sep 17 00:00:00 2001 From: Johannes Schnatterer Date: Tue, 9 Oct 2018 11:17:06 +0200 Subject: [PATCH 070/121] Jenkins: Increases SonarCloud timeout to 5 minutes. Every now and then sonarcloud is under pressure and needs longer than 2 minutes to call our quality gate webhook. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 57cc3b901f..c0ca5f33d0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -125,7 +125,7 @@ boolean isMainBranch() { boolean waitForQualityGateWebhookToBeCalled() { boolean isQualityGateSucceeded = true - timeout(time: 2, unit: 'MINUTES') { // Needed when there is no webhook for example + timeout(time: 5, unit: 'MINUTES') { // Needed when there is no webhook for example def qGate = waitForQualityGate() echo "SonarQube Quality Gate status: ${qGate.status}" if (qGate.status != 'OK') { From 6475320e616e0e08f28aac98544db881c660ad37 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Tue, 9 Oct 2018 11:52:16 +0200 Subject: [PATCH 071/121] Fixed unit test --- scm-ui/src/repos/modules/branches.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index cfae7da564..d9ade07d40 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -171,7 +171,7 @@ describe("branches", () => { it("should return undefined if branch does not exist", () => { const branch = getBranch(state, repository, "branch42"); - expect(branch).toBeUndefined(); + expect(branch).toBeFalsy(); }); }); }); From f95ffe25f30582f6759588183aa10f0d4f4610d7 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Tue, 9 Oct 2018 11:53:06 +0200 Subject: [PATCH 072/121] Fixes NavLink highlighting --- .../packages/ui-components/src/navigation/NavLink.js | 11 +++++++++-- scm-ui/src/repos/containers/RepositoryRoot.js | 7 +++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/scm-ui-components/packages/ui-components/src/navigation/NavLink.js b/scm-ui-components/packages/ui-components/src/navigation/NavLink.js index 3a90fd1fc6..20a7f2469f 100644 --- a/scm-ui-components/packages/ui-components/src/navigation/NavLink.js +++ b/scm-ui-components/packages/ui-components/src/navigation/NavLink.js @@ -7,7 +7,8 @@ import { Route, Link } from "react-router-dom"; type Props = { to: string, label: string, - activeOnlyWhenExact?: boolean + activeOnlyWhenExact?: boolean, + activeWhenMatch?: (route: any) => boolean }; class NavLink extends React.Component { @@ -15,11 +16,17 @@ class NavLink extends React.Component { activeOnlyWhenExact: true }; + + isActive(route: any) { + const { activeWhenMatch } = this.props; + return route.match || (activeWhenMatch && activeWhenMatch(route)); + } + renderLink = (route: any) => { const { to, label } = this.props; return (
  • - + {label}
  • diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index ec780a5bda..e9acf80a5d 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -70,6 +70,12 @@ class RepositoryRoot extends React.Component { this.props.deleteRepo(repository, this.deleted); }; + matches = (route: any) => { + const url = this.matchedUrl(); + const regex = new RegExp(`${url}/?[a-zA-Z0-9_%]*/changesets?.*`); + return route.location.pathname.match(regex); + }; + render() { const { loading, error, repository, t } = this.props; @@ -131,6 +137,7 @@ class RepositoryRoot extends React.Component { activeOnlyWhenExact={false} to={`${url}/changesets`} label={t("repository-root.history")} + activeWhenMatch={this.matches} /> From 89f0556312f09f5ae3044aef8cffbb2549b981da Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Tue, 9 Oct 2018 15:25:47 +0200 Subject: [PATCH 073/121] force install lerna 3.2.1 --- scm-ui-components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-ui-components/package.json b/scm-ui-components/package.json index 73c20625bd..27d9a6cf28 100644 --- a/scm-ui-components/package.json +++ b/scm-ui-components/package.json @@ -8,6 +8,6 @@ "unlink": "lerna exec --no-bail -- yarn unlink" }, "devDependencies": { - "lerna": "^3.2.1" + "lerna": "3.2.1" } } From de805788fc181e2e9757e73ad39fb0fe90595599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 9 Oct 2018 15:35:54 +0200 Subject: [PATCH 074/121] Backed out changeset cee469c7213b --- scm-ui-components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-ui-components/package.json b/scm-ui-components/package.json index b9447e45f9..73c20625bd 100644 --- a/scm-ui-components/package.json +++ b/scm-ui-components/package.json @@ -5,7 +5,7 @@ "scripts": { "bootstrap": "lerna bootstrap", "link": "lerna exec -- yarn link", - "unlink": "lerna exec --bail=false -- yarn unlink" + "unlink": "lerna exec --no-bail -- yarn unlink" }, "devDependencies": { "lerna": "^3.2.1" From e6b241727f5318f65cb2f3cad5fc50252032436e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 9 Oct 2018 15:37:09 +0200 Subject: [PATCH 075/121] Backed out changeset c0ce0773f13d --- scm-ui-components/pom.xml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/scm-ui-components/pom.xml b/scm-ui-components/pom.xml index 830945a8a3..f49d2070cd 100644 --- a/scm-ui-components/pom.xml +++ b/scm-ui-components/pom.xml @@ -48,17 +48,6 @@ - - unlink - package - - run - - - true - - - link package @@ -66,7 +55,17 @@ run - + + + + + unlink + clean + + run + + + From 433cf2a02e4e8c392db902bc190c60c666118d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 9 Oct 2018 15:42:21 +0200 Subject: [PATCH 076/121] Revert to status of v2.0.0-m3 --- scm-ui-components/lerna.json | 2 +- scm-ui-components/pom.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scm-ui-components/lerna.json b/scm-ui-components/lerna.json index 37166b8655..02962cf634 100644 --- a/scm-ui-components/lerna.json +++ b/scm-ui-components/lerna.json @@ -2,6 +2,6 @@ "packages": [ "packages/*" ], - "version": "3.2.1", + "version": "0.0.0", "npmClient": "yarn" } diff --git a/scm-ui-components/pom.xml b/scm-ui-components/pom.xml index f49d2070cd..f5544a9e24 100644 --- a/scm-ui-components/pom.xml +++ b/scm-ui-components/pom.xml @@ -49,7 +49,7 @@ - link + unlink package run @@ -59,13 +59,13 @@ - unlink - clean + link + package run - + From 30ac4be7bfbe7223429053628186ad8ed76d8a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 9 Oct 2018 16:00:03 +0200 Subject: [PATCH 077/121] Backout ui changes --- scm-ui-components/lerna.json | 2 +- scm-ui-components/package.json | 2 +- scm-ui-components/pom.xml | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scm-ui-components/lerna.json b/scm-ui-components/lerna.json index 37166b8655..02962cf634 100644 --- a/scm-ui-components/lerna.json +++ b/scm-ui-components/lerna.json @@ -2,6 +2,6 @@ "packages": [ "packages/*" ], - "version": "3.2.1", + "version": "0.0.0", "npmClient": "yarn" } diff --git a/scm-ui-components/package.json b/scm-ui-components/package.json index b9447e45f9..73c20625bd 100644 --- a/scm-ui-components/package.json +++ b/scm-ui-components/package.json @@ -5,7 +5,7 @@ "scripts": { "bootstrap": "lerna bootstrap", "link": "lerna exec -- yarn link", - "unlink": "lerna exec --bail=false -- yarn unlink" + "unlink": "lerna exec --no-bail -- yarn unlink" }, "devDependencies": { "lerna": "^3.2.1" diff --git a/scm-ui-components/pom.xml b/scm-ui-components/pom.xml index 830945a8a3..f5544a9e24 100644 --- a/scm-ui-components/pom.xml +++ b/scm-ui-components/pom.xml @@ -55,7 +55,6 @@ run - true From 3caac90d3c0f166d2f73cb0b257af5da12de3c73 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Tue, 9 Oct 2018 16:24:19 +0200 Subject: [PATCH 078/121] Fixed minor issues --- scm-ui/src/repos/containers/Changesets.js | 18 ++++++++---------- scm-ui/src/repos/modules/branches.js | 2 +- scm-ui/src/repos/modules/changesets.js | 3 +-- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/scm-ui/src/repos/containers/Changesets.js b/scm-ui/src/repos/containers/Changesets.js index 23841ffe96..afdadc5d7d 100644 --- a/scm-ui/src/repos/containers/Changesets.js +++ b/scm-ui/src/repos/containers/Changesets.js @@ -13,6 +13,7 @@ import { fetchChangesetsByBranchAndPage, fetchChangesetsByLink, fetchChangesetsByPage, + getChangesets, getChangesetsFromState, getFetchChangesetsFailure, isFetchChangesetsPending, @@ -54,16 +55,11 @@ type Props = { branch: Branch }; -type State = { - branch: string -}; +type State = {}; class Changesets extends React.PureComponent { constructor(props: Props) { super(props); - this.state = { - branch: "" - }; } onPageChange = (link: string) => { @@ -95,16 +91,18 @@ class Changesets extends React.PureComponent { componentDidUpdate(prevProps: Props) { const { page, list, repository, match } = this.props; const { namespace, name } = repository; - const branch = decodeURIComponent(match.params.branch); + const branch = match.params.branch; + if (!this.props.loading) { if (prevProps.branch !== this.props.branch) { - this.setState({ branch }); this.updateContent(); } if (list && (list.page || list.page === 0)) { + console.log(list); // backend starts paging at 0 const statePage: number = list.page + 1; + console.log(`page: ${page} - statePage: ${statePage}`); if (page !== statePage) { if (branch) { this.props.history.push( @@ -194,9 +192,9 @@ const getPageFromProps = props => { const mapStateToProps = (state, ownProps: Props) => { const { repository } = ownProps; const branchName = ownProps.match.params.branch; - const branch = getBranch(state, repository, branchName); + const branch = getBranch(state, repository, decodeURIComponent(branchName)); const loading = isFetchChangesetsPending(state, repository, branch); - const changesets = getChangesetsFromState(state, repository); + const changesets = getChangesets(state, repository, branch); const branchNames = getBranchNames(state, repository); const error = getFetchChangesetsFailure(state, repository, branch); const list = selectListAsCollection(state, repository); diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index c771a9734e..4b4297f4c5 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -132,7 +132,7 @@ export function getBranch( state: Object, repository: Repository, name: string -): Branch { +): ?Branch { const key = createKey(repository); if (state.branches[key]) { if (state.branches[key].byNames[name]) { diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index e7e7601196..6770e2257c 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -82,7 +82,6 @@ export function fetchChangesetsByPage(repository: Repository, page: number) { return fetchChangesetsWithOptions(repository, undefined, `?page=${page - 1}`); } -// TODO: Rewrite code to fetch changesets by branches, adjust tests and let BranchChooser fetch branches export function fetchChangesetsByBranchAndPage( repository: Repository, branch: Branch, @@ -171,7 +170,7 @@ function byKeyReducer( return { ...state, [key]: { - byId: { ...byIds }, + byId: byIds, list: { entries: changesetIds, entry: { From 7473f06df99ff01e5ae31376db3443d75ed9b211 Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Tue, 9 Oct 2018 16:46:14 +0200 Subject: [PATCH 079/121] return true if the unlink cmd exit with error --- scm-ui-components/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm-ui-components/package.json b/scm-ui-components/package.json index 27d9a6cf28..527acbd9dc 100644 --- a/scm-ui-components/package.json +++ b/scm-ui-components/package.json @@ -5,9 +5,9 @@ "scripts": { "bootstrap": "lerna bootstrap", "link": "lerna exec -- yarn link", - "unlink": "lerna exec --no-bail -- yarn unlink" + "unlink": "lerna exec --no-bail -- yarn unlink || true" }, "devDependencies": { - "lerna": "3.2.1" + "lerna": "^3.2.1" } } From 9ad2b3ffada9af18e8952d5433493ad5354a222b Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Tue, 9 Oct 2018 16:48:07 +0200 Subject: [PATCH 080/121] add yarn.lock --- scm-ui-components/yarn.lock | 3669 +++++++++++++++ scm-ui/yarn.lock | 8535 +++++++++++++++++++++++++++++++++++ 2 files changed, 12204 insertions(+) create mode 100644 scm-ui-components/yarn.lock create mode 100644 scm-ui/yarn.lock diff --git a/scm-ui-components/yarn.lock b/scm-ui-components/yarn.lock new file mode 100644 index 0000000000..eb7d40a3b3 --- /dev/null +++ b/scm-ui-components/yarn.lock @@ -0,0 +1,3669 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@lerna/add@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.4.1.tgz#d41068317e30f530df48220d256b5e79690b1877" + dependencies: + "@lerna/bootstrap" "^3.4.1" + "@lerna/command" "^3.3.0" + "@lerna/filter-options" "^3.3.2" + "@lerna/npm-conf" "^3.4.1" + "@lerna/validation-error" "^3.0.0" + dedent "^0.7.0" + npm-package-arg "^6.0.0" + p-map "^1.2.0" + pacote "^9.1.0" + semver "^5.5.0" + +"@lerna/batch-packages@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@lerna/batch-packages/-/batch-packages-3.1.2.tgz#74b5312a01a8916204cbc71237ffbe93144b99df" + dependencies: + "@lerna/package-graph" "^3.1.2" + "@lerna/validation-error" "^3.0.0" + npmlog "^4.1.2" + +"@lerna/bootstrap@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.4.1.tgz#10635e9b547fb7d685949ac78e0923f73da2f52a" + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/command" "^3.3.0" + "@lerna/filter-options" "^3.3.2" + "@lerna/has-npm-version" "^3.3.0" + "@lerna/npm-conf" "^3.4.1" + "@lerna/npm-install" "^3.3.0" + "@lerna/rimraf-dir" "^3.3.0" + "@lerna/run-lifecycle" "^3.4.1" + "@lerna/run-parallel-batches" "^3.0.0" + "@lerna/symlink-binary" "^3.3.0" + "@lerna/symlink-dependencies" "^3.3.0" + "@lerna/validation-error" "^3.0.0" + dedent "^0.7.0" + get-port "^3.2.0" + multimatch "^2.1.0" + npm-package-arg "^6.0.0" + npmlog "^4.1.2" + p-finally "^1.0.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + p-waterfall "^1.0.0" + read-package-tree "^5.1.6" + semver "^5.5.0" + +"@lerna/changed@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.4.1.tgz#84a049359a53b8812c3a07a664bd41b1768f5938" + dependencies: + "@lerna/collect-updates" "^3.3.2" + "@lerna/command" "^3.3.0" + "@lerna/listable" "^3.0.0" + "@lerna/output" "^3.0.0" + "@lerna/version" "^3.4.1" + +"@lerna/check-working-tree@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.3.0.tgz#2118f301f28ccb530812e5b27a341b1e6b3c84e2" + dependencies: + "@lerna/describe-ref" "^3.3.0" + "@lerna/validation-error" "^3.0.0" + +"@lerna/child-process@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-3.3.0.tgz#71184a763105b6c8ece27f43f166498d90fe680f" + dependencies: + chalk "^2.3.1" + execa "^1.0.0" + strong-log-transformer "^2.0.0" + +"@lerna/clean@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.3.2.tgz#9a7e8a1e400e580de260fa124945b2939a025069" + dependencies: + "@lerna/command" "^3.3.0" + "@lerna/filter-options" "^3.3.2" + "@lerna/prompt" "^3.3.1" + "@lerna/rimraf-dir" "^3.3.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + p-waterfall "^1.0.0" + +"@lerna/cli@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-3.2.0.tgz#3ed25bcbc0b8f0878bc6a102ee0296f01476cfdf" + dependencies: + "@lerna/global-options" "^3.1.3" + dedent "^0.7.0" + npmlog "^4.1.2" + yargs "^12.0.1" + +"@lerna/collect-updates@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.3.2.tgz#54df5ce59ca05e8aa04ff8a9299f89cc253a9304" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/describe-ref" "^3.3.0" + minimatch "^3.0.4" + npmlog "^4.1.2" + slash "^1.0.0" + +"@lerna/command@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.3.0.tgz#e81c4716a676b02dbe9d3f548d5f45b4ba32c25a" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/package-graph" "^3.1.2" + "@lerna/project" "^3.0.0" + "@lerna/validation-error" "^3.0.0" + "@lerna/write-log-file" "^3.0.0" + dedent "^0.7.0" + execa "^1.0.0" + is-ci "^1.0.10" + lodash "^4.17.5" + npmlog "^4.1.2" + +"@lerna/conventional-commits@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-3.4.1.tgz#0b47f9fc0c4a10951883e949d939188da1b527bc" + dependencies: + "@lerna/validation-error" "^3.0.0" + conventional-changelog-angular "^5.0.1" + conventional-changelog-core "^3.1.0" + conventional-recommended-bump "^4.0.1" + fs-extra "^7.0.0" + get-stream "^4.0.0" + npm-package-arg "^6.0.0" + npmlog "^4.1.2" + semver "^5.5.0" + +"@lerna/create-symlink@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-3.3.0.tgz#91de00fd576018ba4251f0c6a5b4b7f768f22a82" + dependencies: + cmd-shim "^2.0.2" + fs-extra "^7.0.0" + npmlog "^4.1.2" + +"@lerna/create@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.4.1.tgz#7cad78a5701d7666a0f5d0fe0e325acd8d8f5b63" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.3.0" + "@lerna/npm-conf" "^3.4.1" + "@lerna/validation-error" "^3.0.0" + camelcase "^4.1.0" + dedent "^0.7.0" + fs-extra "^7.0.0" + globby "^8.0.1" + init-package-json "^1.10.3" + npm-package-arg "^6.0.0" + pify "^3.0.0" + semver "^5.5.0" + slash "^1.0.0" + validate-npm-package-license "^3.0.3" + validate-npm-package-name "^3.0.0" + whatwg-url "^7.0.0" + +"@lerna/describe-ref@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.3.0.tgz#d373adb530d5428ab91e303ccbfcf51a98374a3a" + dependencies: + "@lerna/child-process" "^3.3.0" + npmlog "^4.1.2" + +"@lerna/diff@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.3.0.tgz#c8130a5f508b47fad5fec81404498bc3acdf9cb5" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.3.0" + "@lerna/validation-error" "^3.0.0" + npmlog "^4.1.2" + +"@lerna/exec@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.3.2.tgz#95ecaca617fd85abdb91e9a378ed06ec1763d665" + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.3.0" + "@lerna/filter-options" "^3.3.2" + "@lerna/run-parallel-batches" "^3.0.0" + "@lerna/validation-error" "^3.0.0" + +"@lerna/filter-options@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.3.2.tgz#ac90702b7876ff4980dcdeaeac049c433dd01773" + dependencies: + "@lerna/collect-updates" "^3.3.2" + "@lerna/filter-packages" "^3.0.0" + dedent "^0.7.0" + +"@lerna/filter-packages@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-3.0.0.tgz#5eb25ad1610f3e2ab845133d1f8d7d40314e838f" + dependencies: + "@lerna/validation-error" "^3.0.0" + multimatch "^2.1.0" + npmlog "^4.1.2" + +"@lerna/get-npm-exec-opts@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.0.0.tgz#8fc7866e8d8e9a2f2dc385287ba32eb44de8bdeb" + dependencies: + npmlog "^4.1.2" + +"@lerna/global-options@^3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-3.1.3.tgz#cf85e24655a91d04d4efc9a80c1f83fc768d08ae" + +"@lerna/has-npm-version@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-3.3.0.tgz#8a73c2c437a0e1e68a19ccbd0dd3c014d4d39135" + dependencies: + "@lerna/child-process" "^3.3.0" + semver "^5.5.0" + +"@lerna/import@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.3.1.tgz#deca8c93c9cc03c5844b975c6da9937dd7530440" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.3.0" + "@lerna/prompt" "^3.3.1" + "@lerna/validation-error" "^3.0.0" + dedent "^0.7.0" + fs-extra "^7.0.0" + p-map-series "^1.0.0" + +"@lerna/init@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.3.0.tgz#998f3497da3d891867c593b808b6db4b8fc4ccb9" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.3.0" + fs-extra "^7.0.0" + p-map "^1.2.0" + write-json-file "^2.3.0" + +"@lerna/link@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.3.0.tgz#c0c05ff52d0f0c659fcf221627edfcd58e477a5c" + dependencies: + "@lerna/command" "^3.3.0" + "@lerna/package-graph" "^3.1.2" + "@lerna/symlink-dependencies" "^3.3.0" + p-map "^1.2.0" + slash "^1.0.0" + +"@lerna/list@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.3.2.tgz#1412b3cce2a83b1baa4ff6fb962d50b46c28ec98" + dependencies: + "@lerna/command" "^3.3.0" + "@lerna/filter-options" "^3.3.2" + "@lerna/listable" "^3.0.0" + "@lerna/output" "^3.0.0" + +"@lerna/listable@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-3.0.0.tgz#27209b1382c87abdbc964220e75c247d803d4199" + dependencies: + chalk "^2.3.1" + columnify "^1.5.4" + +"@lerna/log-packed@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-3.0.4.tgz#6d1f6ce5ca68b9971f2a27f0ecf3c50684be174a" + dependencies: + byte-size "^4.0.3" + columnify "^1.5.4" + has-unicode "^2.0.1" + npmlog "^4.1.2" + +"@lerna/npm-conf@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-3.4.1.tgz#859e931b0bc9a5eed86309cc09508810c1e7d121" + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + +"@lerna/npm-dist-tag@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-3.3.0.tgz#e1c5ab67674216d901266a16846b21cc81ff6afd" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + npmlog "^4.1.2" + +"@lerna/npm-install@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.3.0.tgz#16d00ffd668d11b2386b3ac68bdac2cf8320e533" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + fs-extra "^7.0.0" + npm-package-arg "^6.0.0" + npmlog "^4.1.2" + signal-exit "^3.0.2" + write-pkg "^3.1.0" + +"@lerna/npm-publish@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.3.1.tgz#30384665d7ee387343332ece62ca231207bbabea" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + "@lerna/has-npm-version" "^3.3.0" + "@lerna/log-packed" "^3.0.4" + fs-extra "^7.0.0" + npmlog "^4.1.2" + p-map "^1.2.0" + +"@lerna/npm-run-script@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-3.3.0.tgz#3c79601c27c67121155b20e039be53130217db72" + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + npmlog "^4.1.2" + +"@lerna/output@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/output/-/output-3.0.0.tgz#4ed4a30ed2f311046b714b3840a090990ba3ce35" + dependencies: + npmlog "^4.1.2" + +"@lerna/package-graph@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-3.1.2.tgz#b70298a3a8c82e12090da33233bf242223a38f20" + dependencies: + "@lerna/validation-error" "^3.0.0" + npm-package-arg "^6.0.0" + semver "^5.5.0" + +"@lerna/package@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.0.0.tgz#14afc9a6cb1f7f7b23c1d7c7aa81bdac7d44c0e5" + dependencies: + npm-package-arg "^6.0.0" + write-pkg "^3.1.0" + +"@lerna/project@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.0.0.tgz#4320d2a2b4080cabcf95161d9c48475217d8a545" + dependencies: + "@lerna/package" "^3.0.0" + "@lerna/validation-error" "^3.0.0" + cosmiconfig "^5.0.2" + dedent "^0.7.0" + dot-prop "^4.2.0" + glob-parent "^3.1.0" + globby "^8.0.1" + load-json-file "^4.0.0" + npmlog "^4.1.2" + p-map "^1.2.0" + resolve-from "^4.0.0" + write-json-file "^2.3.0" + +"@lerna/prompt@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-3.3.1.tgz#ec53f9034a7a02a671627241682947f65078ab88" + dependencies: + inquirer "^6.2.0" + npmlog "^4.1.2" + +"@lerna/publish@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.4.1.tgz#abbbc656b3bfafc2289399a46da060b90f6baf32" + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/check-working-tree" "^3.3.0" + "@lerna/child-process" "^3.3.0" + "@lerna/collect-updates" "^3.3.2" + "@lerna/command" "^3.3.0" + "@lerna/describe-ref" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + "@lerna/npm-conf" "^3.4.1" + "@lerna/npm-dist-tag" "^3.3.0" + "@lerna/npm-publish" "^3.3.1" + "@lerna/output" "^3.0.0" + "@lerna/prompt" "^3.3.1" + "@lerna/run-lifecycle" "^3.4.1" + "@lerna/run-parallel-batches" "^3.0.0" + "@lerna/validation-error" "^3.0.0" + "@lerna/version" "^3.4.1" + fs-extra "^7.0.0" + libnpmaccess "^3.0.0" + npm-package-arg "^6.0.0" + npm-registry-fetch "^3.8.0" + npmlog "^4.1.2" + p-finally "^1.0.0" + p-map "^1.2.0" + p-pipe "^1.2.0" + p-reduce "^1.0.0" + semver "^5.5.0" + +"@lerna/resolve-symlink@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-3.3.0.tgz#c5d99a60cb17e2ea90b3521a0ba445478d194a44" + dependencies: + fs-extra "^7.0.0" + npmlog "^4.1.2" + read-cmd-shim "^1.0.1" + +"@lerna/rimraf-dir@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-3.3.0.tgz#687e9bb3668a9e540e281302a52d9a573860f5db" + dependencies: + "@lerna/child-process" "^3.3.0" + npmlog "^4.1.2" + path-exists "^3.0.0" + rimraf "^2.6.2" + +"@lerna/run-lifecycle@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-3.4.1.tgz#6d7e44eada31cb4ec78b18ef050da0d86f6c892b" + dependencies: + "@lerna/npm-conf" "^3.4.1" + npm-lifecycle "^2.0.0" + npmlog "^4.1.2" + +"@lerna/run-parallel-batches@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/run-parallel-batches/-/run-parallel-batches-3.0.0.tgz#468704934084c74991d3124d80607857d4dfa840" + dependencies: + p-map "^1.2.0" + p-map-series "^1.0.0" + +"@lerna/run@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.3.2.tgz#f521f4a22585c90758f34a584cb1871f8bb2a83e" + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/command" "^3.3.0" + "@lerna/filter-options" "^3.3.2" + "@lerna/npm-run-script" "^3.3.0" + "@lerna/output" "^3.0.0" + "@lerna/run-parallel-batches" "^3.0.0" + "@lerna/validation-error" "^3.0.0" + p-map "^1.2.0" + +"@lerna/symlink-binary@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-3.3.0.tgz#99ea570b21baabd61ecab27582eeb1d7b2c5f9cf" + dependencies: + "@lerna/create-symlink" "^3.3.0" + "@lerna/package" "^3.0.0" + fs-extra "^7.0.0" + p-map "^1.2.0" + read-pkg "^3.0.0" + +"@lerna/symlink-dependencies@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-3.3.0.tgz#13bcaed3e37986ab01b13498a459c7f609397dc3" + dependencies: + "@lerna/create-symlink" "^3.3.0" + "@lerna/resolve-symlink" "^3.3.0" + "@lerna/symlink-binary" "^3.3.0" + fs-extra "^7.0.0" + p-finally "^1.0.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + +"@lerna/validation-error@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-3.0.0.tgz#a27e90051c3ba71995e2a800a43d94ad04b3e3f4" + dependencies: + npmlog "^4.1.2" + +"@lerna/version@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.4.1.tgz#029448cccd3ccefb4d5f666933bd13cfb37edab0" + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/check-working-tree" "^3.3.0" + "@lerna/child-process" "^3.3.0" + "@lerna/collect-updates" "^3.3.2" + "@lerna/command" "^3.3.0" + "@lerna/conventional-commits" "^3.4.1" + "@lerna/output" "^3.0.0" + "@lerna/prompt" "^3.3.1" + "@lerna/run-lifecycle" "^3.4.1" + "@lerna/validation-error" "^3.0.0" + chalk "^2.3.1" + dedent "^0.7.0" + minimatch "^3.0.4" + npmlog "^4.1.2" + p-map "^1.2.0" + p-pipe "^1.2.0" + p-reduce "^1.0.0" + p-waterfall "^1.0.0" + semver "^5.5.0" + slash "^1.0.0" + temp-write "^3.4.0" + +"@lerna/write-log-file@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-3.0.0.tgz#2f95fee80c6821fe1ee6ccf8173d2b4079debbd2" + dependencies: + npmlog "^4.1.2" + write-file-atomic "^2.3.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.2.tgz#54c5a964462be3d4d78af631363c18d6fa91ac26" + +JSONStream@^1.0.4, JSONStream@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.4.tgz#615bb2adb0cd34c8f4c447b5f6512fa1d8f16a2e" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + dependencies: + es6-promisify "^5.0.0" + +agentkeepalive@^3.4.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.1.tgz#4eba75cf2ad258fc09efd506cdb8d8c2971d35a4" + dependencies: + humanize-ms "^1.2.1" + +ajv@^5.3.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" + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +aproba@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asap@^2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +async@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + dependencies: + lodash "^4.17.10" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + +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.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + dependencies: + tweetnacl "^0.14.3" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + +byline@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + +byte-size@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.3.tgz#b7c095efc68eadf82985fccd9a2df43a74fa2ccd" + +cacache@^11.0.1, cacache@^11.0.2: + version "11.2.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.2.0.tgz#617bdc0b02844af56310e411c0878941d5739965" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + figgy-pudding "^3.1.0" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.3" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.0" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chalk@^2.0.0, chalk@^2.3.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + +chownr@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + +cmd-shim@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +columnify@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + +combined-stream@1.0.6: + version "1.0.6" + resolved "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + +combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + dependencies: + delayed-stream "~1.0.0" + +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + +compare-func@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" + dependencies: + array-ify "^1.0.0" + dot-prop "^3.0.0" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +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.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-chain@^1.1.11: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +conventional-changelog-angular@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.1.tgz#f96431b76de453333a909decd02b15cb5bd2d364" + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-core@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-3.1.0.tgz#96a81bb3301b4b2a3dc2851cc54c5fb674ac1942" + dependencies: + conventional-changelog-writer "^4.0.0" + conventional-commits-parser "^3.0.0" + dateformat "^3.0.0" + get-pkg-repo "^1.0.0" + git-raw-commits "^2.0.0" + git-remote-origin-url "^2.0.0" + git-semver-tags "^2.0.0" + lodash "^4.2.1" + normalize-package-data "^2.3.5" + q "^1.5.1" + read-pkg "^1.1.0" + read-pkg-up "^1.0.1" + through2 "^2.0.0" + +conventional-changelog-preset-loader@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.0.1.tgz#d134734e0cc1b91b88b30586c5991f31442029f1" + +conventional-changelog-writer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.0.tgz#3ed983c8ef6a3aa51fe44e82c9c75e86f1b5aa42" + dependencies: + compare-func "^1.3.1" + conventional-commits-filter "^2.0.0" + dateformat "^3.0.0" + handlebars "^4.0.2" + json-stringify-safe "^5.0.1" + lodash "^4.2.1" + meow "^4.0.0" + semver "^5.5.0" + split "^1.0.0" + through2 "^2.0.0" + +conventional-commits-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.0.tgz#a0ce1d1ff7a1dd7fab36bee8e8256d348d135651" + dependencies: + is-subset "^0.1.1" + modify-values "^1.0.0" + +conventional-commits-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.0.tgz#7f604549a50bd8f60443fbe515484b1c2f06a5c4" + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + trim-off-newlines "^1.0.0" + +conventional-recommended-bump@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-4.0.1.tgz#304a45a412cfec050a10ea2e7e4a89320eaf3991" + dependencies: + concat-stream "^1.6.0" + conventional-changelog-preset-loader "^2.0.1" + conventional-commits-filter "^2.0.0" + conventional-commits-parser "^3.0.0" + git-raw-commits "^2.0.0" + git-semver-tags "^2.0.0" + meow "^4.0.0" + q "^1.5.1" + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cosmiconfig@^5.0.2: + version "5.0.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + +dargs@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" + dependencies: + number-is-nan "^1.0.0" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +dateformat@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.2.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.5.tgz#c2418fbfd7a29f4d4f70ff4cea604d4b64c46407" + dependencies: + ms "^2.1.1" + +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + dependencies: + xregexp "4.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + dependencies: + clone "^1.0.2" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + +dezalgo@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" + dependencies: + asap "^2.0.0" + wrappy "1" + +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + dependencies: + is-obj "^1.0.0" + +dot-prop@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + dependencies: + is-obj "^1.0.0" + +duplexer@^0.1.1: + version "0.1.1" + resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + dependencies: + once "^1.4.0" + +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + dependencies: + is-arrayish "^0.2.1" + +es6-promise@^4.0.3: + version "4.2.5" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + dependencies: + es6-promise "^4.0.3" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + +external-editor@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +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-glob@^2.0.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.3.tgz#d09d378e9ef6b0076a0fa1ba7519d9d4d9699c28" + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.0.1" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.1" + micromatch "^3.1.10" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +figgy-pudding@^3.1.0, figgy-pudding@^3.2.1, figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + dependencies: + locate-path "^3.0.0" + +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.3.2: + 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" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.0.tgz#8cc3f47ce07ef7b3593a11b9fb245f7e34c041d6" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fstream@^1.0.0, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +genfun@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-4.0.1.tgz#ed10041f2e4a7f1b0a38466d17a5c3e27df1dfc1" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + +get-pkg-repo@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" + dependencies: + hosted-git-info "^2.1.4" + meow "^3.3.0" + normalize-package-data "^2.3.0" + parse-github-repo-url "^1.3.0" + through2 "^2.0.0" + +get-port@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + +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@^3.0.0: + version "3.0.0" + resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +git-raw-commits@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.0.tgz#d92addf74440c14bcc5c83ecce3fb7f8a79118b5" + dependencies: + dargs "^4.0.1" + lodash.template "^4.0.2" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + +git-remote-origin-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + dependencies: + gitconfiglocal "^1.0.0" + pify "^2.3.0" + +git-semver-tags@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-2.0.0.tgz#c218fd895bdf8e8e02f6bde555b2c3893ac73cd7" + dependencies: + meow "^4.0.0" + semver "^5.5.0" + +gitconfiglocal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + dependencies: + ini "^1.3.2" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + +glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +handlebars@^4.0.2: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +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@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" + dependencies: + ajv "^5.3.0" + har-schema "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-unicode@^2.0.0, has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + +http-cache-semantics@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + dependencies: + agent-base "4" + debug "3.1.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-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + dependencies: + ms "^2.0.0" + +iconv-lite@^0.4.24, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + dependencies: + minimatch "^3.0.4" + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@^1.3.2, ini@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +init-package-json@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + +inquirer@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.17.10" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + +ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + dependencies: + ci-info "^1.5.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +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-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + +is-text-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + dependencies: + text-extensions "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +js-yaml@^3.9.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1: + 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@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +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" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + dependencies: + invert-kv "^2.0.0" + +lerna@^3.2.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.4.1.tgz#4acc5a6b9d843993db7a7bb1350274bcaf20ca80" + dependencies: + "@lerna/add" "^3.4.1" + "@lerna/bootstrap" "^3.4.1" + "@lerna/changed" "^3.4.1" + "@lerna/clean" "^3.3.2" + "@lerna/cli" "^3.2.0" + "@lerna/create" "^3.4.1" + "@lerna/diff" "^3.3.0" + "@lerna/exec" "^3.3.2" + "@lerna/import" "^3.3.1" + "@lerna/init" "^3.3.0" + "@lerna/link" "^3.3.0" + "@lerna/list" "^3.3.2" + "@lerna/publish" "^3.4.1" + "@lerna/run" "^3.3.2" + "@lerna/version" "^3.4.1" + import-local "^1.0.0" + npmlog "^4.1.2" + +libnpmaccess@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.0.tgz#33cc9c8a5cb53e87d06bf2e547c2eba974f619af" + dependencies: + aproba "^2.0.0" + get-stream "^4.0.0" + npm-package-arg "^6.1.0" + npm-registry-fetch "^3.8.0" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + +lodash.template@^4.0.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + dependencies: + lodash._reinterpolate "~3.0.0" + +lodash@^4.17.10, lodash@^4.17.5, lodash@^4.2.1: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@^4.1.2, lru-cache@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + dependencies: + pify "^3.0.0" + +make-fetch-happen@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083" + dependencies: + agentkeepalive "^3.4.1" + cacache "^11.0.1" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + lru-cache "^4.1.2" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^4.0.0" + ssri "^6.0.0" + +map-age-cleaner@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz#098fb15538fd3dbe461f12745b0ca8568d4e3f74" + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + +mem@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^1.0.0" + p-is-promise "^1.1.0" + +meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +meow@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist "^1.1.3" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + +merge2@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.2.tgz#03212e3da8d86c4d8523cebd6318193414f94e34" + +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" + dependencies: + mime-db "~1.36.0" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + +minimatch@^3.0.0, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@0.0.8: + version "0.0.8" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1: + version "0.0.10" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: + version "0.5.1" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +modify-values@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +ms@^2.0.0, ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.7, mute-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + +node-fetch-npm@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" + dependencies: + encoding "^0.1.11" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, normalize-package-data@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + +npm-lifecycle@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-2.1.0.tgz#1eda2eedb82db929e3a0c50341ab0aad140ed569" + dependencies: + byline "^5.0.0" + graceful-fs "^4.1.11" + node-gyp "^3.8.0" + resolve-from "^4.0.0" + slide "^1.1.6" + uid-number "0.0.6" + umask "^1.1.0" + which "^1.3.1" + +"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" + dependencies: + hosted-git-info "^2.6.0" + osenv "^0.1.5" + semver "^5.5.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^1.1.10: + version "1.1.11" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-pick-manifest@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.1.0.tgz#dc381bdd670c35d81655e1d5a94aa3dd4d87fce5" + dependencies: + npm-package-arg "^6.0.0" + semver "^5.4.1" + +npm-registry-fetch@^3.0.0, npm-registry-fetch@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz#aa7d9a7c92aff94f48dba0984bdef4bd131c88cc" + dependencies: + JSONStream "^1.3.4" + bluebird "^3.5.1" + figgy-pudding "^3.4.1" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + npm-package-arg "^6.1.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +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.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" + dependencies: + execa "^0.10.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@0, osenv@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + dependencies: + p-limit "^2.0.0" + +p-map-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" + dependencies: + p-reduce "^1.0.0" + +p-map@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + +p-pipe@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9" + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + +p-waterfall@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-1.0.0.tgz#7ed94b3ceb3332782353af6aae11aa9fc235bb00" + dependencies: + p-reduce "^1.0.0" + +pacote@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.1.0.tgz#59810859bbd72984dcb267269259375d32f391e5" + dependencies: + bluebird "^3.5.1" + cacache "^11.0.2" + figgy-pudding "^3.2.1" + get-stream "^3.0.0" + glob "^7.1.2" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + minimatch "^3.0.4" + minipass "^2.3.3" + mississippi "^3.0.0" + mkdirp "^0.5.1" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.10" + npm-pick-manifest "^2.1.0" + npm-registry-fetch "^3.0.0" + osenv "^0.1.5" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + protoduck "^5.0.0" + rimraf "^2.6.2" + safe-buffer "^5.1.2" + semver "^5.5.0" + ssri "^6.0.0" + tar "^4.4.3" + unique-filename "^1.1.0" + which "^1.3.0" + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-github-repo-url@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +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" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + dependencies: + err-code "^1.0.0" + retry "^0.10.0" + +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" + dependencies: + read "1" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + +protoduck@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.0.tgz#752145e6be0ad834cb25716f670a713c860dce70" + dependencies: + genfun "^4.0.1" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + +q@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + +read-cmd-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" + dependencies: + graceful-fs "^4.1.2" + +"read-package-json@1 || 2", read-package-json@^2.0.0: + version "2.0.13" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.13.tgz#2e82ebd9f613baa6d2ebe3aa72cefe3f68e41f4a" + dependencies: + glob "^7.1.1" + json-parse-better-errors "^1.0.1" + normalize-package-data "^2.0.0" + slash "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-tree@^5.1.6: + version "5.2.1" + resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.2.1.tgz#6218b187d6fac82289ce4387bbbaf8eef536ad63" + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + once "^1.3.0" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + +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" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^1.0.0, read-pkg@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read@1, read@~1.0.1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2: + version "2.3.6" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdir-scoped-modules@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@^2.87.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + +rimraf@2, rimraf@^2.5.4, rimraf@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + +rxjs@^6.1.0: + version "6.3.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.4.1, semver@^5.5.0: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slide@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +smart-buffer@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socks-proxy-agent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz#5936bf8b707a993079c6f37db2091821bffa6473" + dependencies: + agent-base "~4.2.0" + socks "~2.2.0" + +socks@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.1.tgz#68ad678b3642fbc5d99c64c165bc561eab0215f9" + dependencies: + ip "^1.1.5" + smart-buffer "^4.0.1" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + dependencies: + is-plain-obj "^1.0.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +spdx-correct@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz#e2a303236cac54b04031fa7a5a79c7e701df852f" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + +split2@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + dependencies: + through2 "^2.0.2" + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + dependencies: + through "2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.14.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + safer-buffer "^2.0.2" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +ssri@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + dependencies: + figgy-pudding "^3.5.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + +strong-log-transformer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.0.0.tgz#fa6d8e0a9e62b3c168c3cad5ae5d00dc97ba26cc" + dependencies: + byline "^5.0.0" + duplexer "^0.1.1" + minimist "^1.2.0" + through "^2.3.4" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + dependencies: + has-flag "^3.0.0" + +tar@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tar@^4.4.3: + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.3.3" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + +temp-write@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-3.4.0.tgz#8cff630fb7e9da05f047c74ce4ce4d685457d492" + dependencies: + graceful-fs "^4.1.2" + is-stream "^1.1.0" + make-dir "^1.0.0" + pify "^3.0.0" + temp-dir "^1.0.0" + uuid "^3.0.1" + +text-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.8.0.tgz#6f343c62268843019b21a616a003557bdb952d2b" + +through2@^2.0.0, through2@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: + version "2.3.8" + resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + +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" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + +uid-number@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +umask@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +uuid@^3.0.1, uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + dependencies: + builtins "^1.0.3" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + dependencies: + defaults "^1.0.3" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +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.9, which@^1.3.0, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + dependencies: + string-width "^1.0.2 || 2" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-json-file@^2.2.0, write-json-file@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^3.0.0" + sort-keys "^2.0.0" + write-file-atomic "^2.0.0" + +write-pkg@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" + +xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + dependencies: + camelcase "^4.1.0" + +yargs@^12.0.1: + version "12.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" + dependencies: + cliui "^4.0.0" + decamelize "^2.0.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" diff --git a/scm-ui/yarn.lock b/scm-ui/yarn.lock new file mode 100644 index 0000000000..a59e6e7612 --- /dev/null +++ b/scm-ui/yarn.lock @@ -0,0 +1,8535 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/core@^7.0.0": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.2.tgz#f8d2a9ceb6832887329a7b60f9d035791400ba4e" + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.1.2" + "@babel/helpers" "^7.1.2" + "@babel/parser" "^7.1.2" + "@babel/template" "^7.1.2" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.1.2" + convert-source-map "^1.1.0" + debug "^3.1.0" + json5 "^0.5.0" + lodash "^4.17.10" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.0.0", "@babel/generator@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.2.tgz#fde75c072575ce7abbd97322e8fef5bae67e4630" + dependencies: + "@babel/types" "^7.1.2" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" + dependencies: + "@babel/helper-explode-assignable-expression" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-builder-react-jsx@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz#fa154cb53eb918cf2a9a7ce928e29eb649c5acdb" + dependencies: + "@babel/types" "^7.0.0" + esutils "^2.0.0" + +"@babel/helper-call-delegate@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a" + dependencies: + "@babel/helper-hoist-variables" "^7.0.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-define-map@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/types" "^7.0.0" + lodash "^4.17.10" + +"@babel/helper-explode-assignable-expression@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" + dependencies: + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-hoist-variables@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88" + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-member-expression-to-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-transforms@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787" + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + lodash "^4.17.10" + +"@babel/helper-optimise-call-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + +"@babel/helper-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" + dependencies: + lodash "^4.17.10" + +"@babel/helper-remap-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-replace-supers@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362" + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-simple-access@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" + dependencies: + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-split-export-declaration@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-wrap-function@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66" + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helpers@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.2.tgz#ab752e8c35ef7d39987df4e8586c63b8846234b5" + dependencies: + "@babel/template" "^7.1.2" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.1.2" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.2.tgz#85c5c47af6d244fab77bce6b9bd830e38c978409" + +"@babel/plugin-proposal-async-generator-functions@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/plugin-syntax-async-generators" "^7.0.0" + +"@babel/plugin-proposal-class-properties@^7.0.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.1.0.tgz#9af01856b1241db60ec8838d84691aa0bd1e8df4" + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + "@babel/plugin-syntax-class-properties" "^7.0.0" + +"@babel/plugin-proposal-json-strings@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.0.0" + +"@babel/plugin-proposal-object-rest-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.2.0" + +"@babel/plugin-syntax-async-generators@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-class-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0.tgz#e051af5d300cbfbcec4a7476e37a803489881634" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-flow@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0.tgz#70638aeaad9ee426bc532e51523cff8ff02f6f17" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-json-strings@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-jsx@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0.tgz#034d5e2b4e14ccaea2e4c137af7e4afb39375ffd" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-object-rest-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-arrow-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + +"@babel/plugin-transform-block-scoped-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-block-scoping@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0.tgz#1745075edffd7cdaf69fab2fb6f9694424b7e9bc" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + lodash "^4.17.10" + +"@babel/plugin-transform-classes@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-define-map" "^7.1.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-destructuring@^7.0.0": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.2.tgz#5fa77d473f5a0a3f5266ad7ce2e8c995a164d60a" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-dotall-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.1.3" + +"@babel/plugin-transform-duplicate-keys@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-exponentiation-operator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-flow-strip-types@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0.tgz#c40ced34c2783985d90d9f9ac77a13e6fb396a01" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.0.0" + +"@babel/plugin-transform-for-of@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-literals@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-amd@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8" + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-commonjs@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + +"@babel/plugin-transform-modules-systemjs@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0.tgz#8873d876d4fee23209decc4d1feab8f198cf2df4" + dependencies: + "@babel/helper-hoist-variables" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-umd@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8" + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-new-target@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-object-super@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + +"@babel/plugin-transform-parameters@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" + dependencies: + "@babel/helper-call-delegate" "^7.1.0" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-react-display-name@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0.tgz#93759e6c023782e52c2da3b75eca60d4f10533ee" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-react-jsx-self@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.0.0.tgz#a84bb70fea302d915ea81d9809e628266bb0bc11" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + +"@babel/plugin-transform-react-jsx-source@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0.tgz#28e00584f9598c0dd279f6280eee213fa0121c3c" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + +"@babel/plugin-transform-react-jsx@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0.tgz#524379e4eca5363cd10c4446ba163f093da75f3e" + dependencies: + "@babel/helper-builder-react-jsx" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + +"@babel/plugin-transform-regenerator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" + dependencies: + regenerator-transform "^0.13.3" + +"@babel/plugin-transform-shorthand-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-sticky-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + +"@babel/plugin-transform-template-literals@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-typeof-symbol@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-unicode-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.1.3" + +"@babel/preset-env@^7.0.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.0.tgz#e67ea5b0441cfeab1d6f41e9b5c79798800e8d11" + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.1.0" + "@babel/plugin-proposal-json-strings" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.1.0" + "@babel/plugin-transform-block-scoped-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.1.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-dotall-regex" "^7.0.0" + "@babel/plugin-transform-duplicate-keys" "^7.0.0" + "@babel/plugin-transform-exponentiation-operator" "^7.1.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.1.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-modules-amd" "^7.1.0" + "@babel/plugin-transform-modules-commonjs" "^7.1.0" + "@babel/plugin-transform-modules-systemjs" "^7.0.0" + "@babel/plugin-transform-modules-umd" "^7.1.0" + "@babel/plugin-transform-new-target" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.1.0" + "@babel/plugin-transform-parameters" "^7.1.0" + "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + "@babel/plugin-transform-typeof-symbol" "^7.0.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + browserslist "^4.1.0" + invariant "^2.2.2" + js-levenshtein "^1.1.3" + semver "^5.3.0" + +"@babel/preset-flow@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + +"@babel/preset-react@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-self" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" + +"@babel/template@^7.1.0", "@babel/template@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.1.2" + "@babel/types" "^7.1.2" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.0.tgz#503ec6669387efd182c3888c4eec07bcc45d91b2" + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.0.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + debug "^3.1.0" + globals "^11.1.0" + lodash "^4.17.10" + +"@babel/types@^7.0.0", "@babel/types@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.2.tgz#183e7952cf6691628afdc2e2b90d03240bac80c0" + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + +"@fortawesome/fontawesome-free@^5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.3.1.tgz#5466b8f31c1f493a96754c1426c25796d0633dd9" + +"@gulp-sourcemaps/identity-map@1.X": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz#1e6fe5d8027b1f285dc0d31762f566bccd73d5a9" + dependencies: + acorn "^5.0.3" + css "^2.2.1" + normalize-path "^2.1.1" + source-map "^0.6.0" + through2 "^2.0.3" + +"@gulp-sourcemaps/map-sources@1.X": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz#890ae7c5d8c877f6d384860215ace9d7ec945bda" + dependencies: + normalize-path "^2.0.1" + through2 "^2.0.3" + +"@octokit/rest@^15.2.6": + version "15.13.0" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.13.0.tgz#078262de2f1d1b02ead7a00c4a3870f517528bcb" + dependencies: + before-after-hook "^1.1.0" + btoa-lite "^1.0.0" + debug "^3.1.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.0" + lodash "^4.17.4" + node-fetch "^2.1.1" + universal-user-agent "^2.0.0" + url-template "^2.0.8" + +"@scm-manager/eslint-config@^0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85" + +"@scm-manager/ui-bundler@^0.0.15": + version "0.0.15" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.15.tgz#8ed4a557d5ae38d6b99493b29608fd6a4c9cd917" + dependencies: + "@babel/core" "^7.0.0" + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/preset-env" "^7.0.0" + "@babel/preset-flow" "^7.0.0" + "@babel/preset-react" "^7.0.0" + "@scm-manager/eslint-config" "^0.0.2" + babel-core "^7.0.0-0" + babel-eslint "^9.0.0-beta.3" + babel-jest "^23.4.2" + babelify "^9.0.0" + browser-sync "^2.24.7" + browserify "^16.2.2" + browserify-css "^0.14.0" + colors "^1.3.1" + commander "^2.17.1" + connect-history-api-fallback "^1.5.0" + eslint "^5.4.0" + eslint-config-react-app "^2.1.0" + eslint-plugin-flowtype "^2.50.0" + eslint-plugin-import "^2.14.0" + eslint-plugin-jsx-a11y "^6.1.1" + eslint-plugin-react "^7.11.1" + fast-xml-parser "^3.12.0" + flow-bin "^0.79.1" + gulp "^3.9.1" + gulp-sourcemaps "^2.6.4" + gulp-uglify "^3.0.1" + jest "^23.5.0" + jest-junit "^5.1.0" + mustache "^2.3.2" + node-mkdirs "^0.0.1" + pom-parser "^1.1.1" + prettier "^1.14.2" + vinyl-buffer "^1.0.1" + vinyl-source-stream "^2.0.0" + watchify "^3.11.0" + +"@scm-manager/ui-extensions@^0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-extensions/-/ui-extensions-0.0.7.tgz#a0a657a1410b78838ba0b36096ef631dca7fe27e" + dependencies: + react "^16.4.2" + react-dom "^16.4.2" + +"@types/node@*": + version "10.11.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.4.tgz#e8bd933c3f78795d580ae41d86590bfc1f4f389d" + +JSONStream@^1.0.3: + version "1.3.4" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.4.tgz#615bb2adb0cd34c8f4c447b5f6512fa1d8f16a2e" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abab@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +accepts@~1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-globals@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103" + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e" + dependencies: + acorn "^5.0.3" + +acorn-node@^1.2.0, acorn-node@^1.3.0, acorn-node@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.6.0.tgz#725c6b8b432451383b5d2816a18a5ab13288aa58" + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + xtend "^4.0.1" + +acorn-walk@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.0.tgz#c957f4a1460da46af4a0388ce28b4c99355b0cbc" + +acorn@5.X, acorn@^5.0.3, acorn@^5.5.3, acorn@^5.6.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + +acorn@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.2.tgz#6a459041c320ab17592c6317abbfdf4bbaa98ca4" + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + +agent-base@4, agent-base@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + dependencies: + es6-promisify "^5.0.0" + +ajv-keywords@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + +ajv@^5.1.0, ajv@^5.3.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.0.1, ajv@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.4.tgz#247d5274110db653706b550fcc2b797ca28cfc59" + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +ansi-wrap@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + +aria-query@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" + dependencies: + ast-types-flow "0.0.7" + commander "^2.11.0" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +array.prototype.flat@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz#812db8f02cad24d3fab65dd67eabe3b8903494a4" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.10.0" + function-bind "^1.1.1" + +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.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +ast-types-flow@0.0.7, ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + +async-each-series@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/async-each-series/-/async-each-series-0.1.1.tgz#7617c1917401fd8ca4a28aadce3dbae98afeb432" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + +async@1.5.2: + version "1.5.2" + resolved "http://registry.npmjs.org/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^2.1.4, async@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + dependencies: + lodash "^4.17.10" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +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, aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + +axios@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.17.1.tgz#2d8e3e5d0bdbd7327f91bc814f5c57660f81824d" + dependencies: + follow-redirects "^1.2.5" + is-buffer "^1.1.5" + +axobject-query@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.1.tgz#05dfa705ada8ad9db993fa6896f22d395b0b0a07" + dependencies: + ast-types-flow "0.0.7" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.0, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-core@^7.0.0-0: + version "7.0.0-bridge.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" + +babel-eslint@^9.0.0-beta.3: + version "9.0.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-9.0.0.tgz#7d9445f81ed9f60aff38115f838970df9f2b6220" + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + eslint-scope "3.7.1" + eslint-visitor-keys "^1.0.0" + +babel-generator@^6.18.0, babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-jest@^23.4.2, babel-jest@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1" + dependencies: + babel-plugin-istanbul "^4.1.6" + babel-preset-jest "^23.2.0" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-istanbul@^4.1.6: + version "4.1.6" + resolved "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-jest-hoist@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" + +babel-plugin-syntax-object-rest-spread@^6.13.0: + version "6.13.0" + resolved "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-jest@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46" + dependencies: + babel-plugin-jest-hoist "^23.2.0" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babelify@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/babelify/-/babelify-9.0.0.tgz#6b2e39ffeeda3765aee60eeb5b581fd947cc64ec" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + +before-after-hook@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.1.0.tgz#83165e15a59460d13702cb8febd6a1807896db5a" + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + dependencies: + callsite "1.0.0" + +big-integer@^1.6.17: + version "1.6.36" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" + +binary-extensions@^1.0.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + +binary@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + dependencies: + buffers "~0.1.1" + chainsaw "~0.1.0" + +bl@^1.2.1: + version "1.2.2" + resolved "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +blob@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.3.3: + version "3.5.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a" + +bluebird@~3.4.1: + version "3.4.7" + resolved "http://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + +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" + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brcast@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/brcast/-/brcast-3.0.1.tgz#6256a8349b20de9eed44257a9b24d71493cd48dd" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + +browser-pack@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.1.0.tgz#c34ba10d0b9ce162b5af227c7131c92c2ecd5774" + dependencies: + JSONStream "^1.0.3" + combine-source-map "~0.8.0" + defined "^1.0.0" + safe-buffer "^5.1.1" + through2 "^2.0.0" + umd "^3.0.0" + +browser-process-hrtime@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" + +browser-resolve@^1.11.0, browser-resolve@^1.11.3, browser-resolve@^1.7.0: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + dependencies: + resolve "1.1.7" + +browser-sync-client@^2.26.0: + version "2.26.0" + resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.26.0.tgz#ea8b38a251e8445177e23a0e37b68b1e4eeff0a0" + dependencies: + mitt "^1.1.3" + rxjs "^5.5.6" + +browser-sync-ui@^2.26.0: + version "2.26.0" + resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-2.26.0.tgz#8fd7ec972fc30288ca3706df6c3e79ef784710e5" + dependencies: + async-each-series "0.1.1" + connect-history-api-fallback "^1" + immutable "^3" + server-destroy "1.0.1" + socket.io-client "^2.0.4" + stream-throttle "^0.1.3" + +browser-sync@^2.24.7: + version "2.26.0" + resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.26.0.tgz#63b401c51b715e85dc4df9ef1d135a63a6d3889e" + dependencies: + browser-sync-client "^2.26.0" + browser-sync-ui "^2.26.0" + bs-recipes "1.3.4" + bs-snippet-injector "^2.0.1" + chokidar "^2.0.4" + connect "3.6.6" + connect-history-api-fallback "^1" + dev-ip "^1.0.1" + easy-extender "^2.3.4" + eazy-logger "^3" + etag "^1.8.1" + fresh "^0.5.2" + fs-extra "3.0.1" + http-proxy "1.15.2" + immutable "^3" + localtunnel "1.9.1" + micromatch "2.3.11" + opn "5.3.0" + portscanner "2.1.1" + qs "6.2.3" + raw-body "^2.3.2" + resp-modifier "6.0.2" + rx "4.1.0" + serve-index "1.9.1" + serve-static "1.13.2" + server-destroy "1.0.1" + socket.io "2.1.1" + ua-parser-js "0.7.17" + yargs "6.4.0" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-css@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/browserify-css/-/browserify-css-0.14.0.tgz#5ece581aa6f8c9aab262956fd06d57c526c9a334" + dependencies: + clean-css "^4.1.5" + concat-stream "^1.6.0" + css "^2.2.1" + find-node-modules "^1.0.4" + lodash "^4.17.4" + mime "^1.3.6" + strip-css-comments "^3.0.0" + through2 "2.0.x" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + dependencies: + pako "~1.0.5" + +browserify@^16.1.0, browserify@^16.2.2: + version "16.2.3" + resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.2.3.tgz#7ee6e654ba4f92bce6ab3599c3485b1cc7a0ad0b" + dependencies: + JSONStream "^1.0.3" + assert "^1.4.0" + browser-pack "^6.0.1" + browser-resolve "^1.11.0" + browserify-zlib "~0.2.0" + buffer "^5.0.2" + cached-path-relative "^1.0.0" + concat-stream "^1.6.0" + console-browserify "^1.1.0" + constants-browserify "~1.0.0" + crypto-browserify "^3.0.0" + defined "^1.0.0" + deps-sort "^2.0.0" + domain-browser "^1.2.0" + duplexer2 "~0.1.2" + events "^2.0.0" + glob "^7.1.0" + has "^1.0.0" + htmlescape "^1.1.0" + https-browserify "^1.0.0" + inherits "~2.0.1" + insert-module-globals "^7.0.0" + labeled-stream-splicer "^2.0.0" + mkdirp "^0.5.0" + module-deps "^6.0.0" + os-browserify "~0.3.0" + parents "^1.0.1" + path-browserify "~0.0.0" + process "~0.11.0" + punycode "^1.3.2" + querystring-es3 "~0.2.0" + read-only-stream "^2.0.0" + readable-stream "^2.0.2" + resolve "^1.1.4" + shasum "^1.0.0" + shell-quote "^1.6.1" + stream-browserify "^2.0.0" + stream-http "^2.0.0" + string_decoder "^1.1.1" + subarg "^1.0.0" + syntax-error "^1.1.1" + through2 "^2.0.0" + timers-browserify "^1.0.1" + tty-browserify "0.0.1" + url "~0.11.0" + util "~0.10.1" + vm-browserify "^1.0.0" + xtend "^4.0.0" + +browserslist@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.2.0.tgz#3e5e5edf7fa9758ded0885cf88c1e4be753a591c" + dependencies: + caniuse-lite "^1.0.30000889" + electron-to-chromium "^1.3.73" + node-releases "^1.0.0-alpha.12" + +bs-recipes@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bs-recipes/-/bs-recipes-1.3.4.tgz#0d2d4d48a718c8c044769fdc4f89592dc8b69585" + +bs-snippet-injector@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz#61b5393f11f52559ed120693100343b6edb04dd5" + +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + dependencies: + node-int64 "^0.4.0" + +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + +buffer-indexof-polyfill@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz#a9fb806ce8145d5428510ce72f278bb363a638bf" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + +buffer@^5.0.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +buffers@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + +bulma-tooltip@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/bulma-tooltip/-/bulma-tooltip-2.0.2.tgz#cf0bf5ad2dc75492cbcbd4816e1a005314dc90ac" + +bulma@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.7.1.tgz#73c2e3b2930c90cc272029cbd19918b493fca486" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cached-path-relative@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caniuse-lite@^1.0.30000889: + version "1.0.30000890" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000890.tgz#86a18ffcc65d79ec6a437e985761b8bf1c4efeaf" + +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + dependencies: + rsvp "^3.3.3" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chainsaw@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + dependencies: + traverse ">=0.3.0 <0.4" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + +cheerio@^1.0.0-rc.2: + version "1.0.0-rc.2" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash "^4.15.0" + parse5 "^3.0.1" + +chokidar@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chokidar@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chownr@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +classnames@^2.2.5: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + +clean-css@^4.1.5: + version "4.2.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" + dependencies: + source-map "~0.6.0" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + +clone@^1.0.0, clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + +cloneable-readable@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + +colors@0.5.x: + version "0.5.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774" + +colors@^1.1.2, colors@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" + +combine-source-map@^0.8.0, combine-source-map@~0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.8.0.tgz#a58d0df042c186fcf822a8e8015f5450d2d79a8b" + dependencies: + convert-source-map "~1.1.0" + inline-source-map "~0.6.0" + lodash.memoize "~3.0.3" + source-map "~0.5.3" + +combined-stream@1.0.6: + version "1.0.6" + resolved "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + +combined-stream@^1.0.5, combined-stream@~1.0.5, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.11.0, commander@^2.17.1, commander@^2.2.0, commander@^2.9.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" + +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + +component-emitter@1.2.1, component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + +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.6.0, concat-stream@^1.6.1, concat-stream@~1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect-history-api-fallback@^1, connect-history-api-fallback@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a" + +connect@3.6.6: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +constants-browserify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + +convert-source-map@1.X, convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + dependencies: + safe-buffer "~5.1.1" + +convert-source-map@~1.1.0: + version "1.1.3" + resolved "http://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +copyfiles@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.1.0.tgz#0e2a4188162d6b2f3c5adfe34e9c0bd564d23164" + dependencies: + glob "^7.0.5" + minimatch "^3.0.3" + mkdirp "^0.5.1" + noms "0.0.0" + through2 "^2.0.1" + yargs "^11.0.0" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +coveralls@^2.11.3: + version "2.13.3" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.13.3.tgz#9ad7c2ae527417f361e8b626483f48ee92dd2bc7" + dependencies: + js-yaml "3.6.1" + lcov-parse "0.0.10" + log-driver "1.2.5" + minimist "1.2.0" + request "2.79.0" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.4, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypt@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +crypto-browserify@^3.0.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-vendor@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-0.3.8.tgz#6421cfd3034ce664fe7673972fd0119fc28941fa" + dependencies: + is-in-browser "^1.0.2" + +css-what@2.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" + +css@2.X, css@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + +cssstyle@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb" + dependencies: + cssom "0.3.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + +damerau-levenshtein@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.1.tgz#d416ac3896918f29ca84d81085bc3705834da579" + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.1.0" + whatwg-url "^7.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + +debug-fabulous@1.X: + version "1.1.0" + resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-1.1.0.tgz#af8a08632465224ef4174a9f06308c3c2a1ebc8e" + dependencies: + debug "3.X" + memoizee "0.4.X" + object-assign "4.X" + +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@3.1.0, debug@=3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +debug@3.X, debug@^3.1.0: + version "3.2.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.5.tgz#c2418fbfd7a29f4d4f70ff4cea604d4b64c46407" + dependencies: + ms "^2.1.1" + +debug@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.0.1.tgz#f9bb36d439b8d1f0dd52d8fb6b46e4ebb8c1cd5b" + dependencies: + ms "^2.1.1" + +decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +decompress-response@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + dependencies: + mimic-response "^1.0.0" + +deep-diff@^0.3.5: + version "0.3.8" + resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + +defaults@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + +deprecated@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" + +deps-sort@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5" + dependencies: + JSONStream "^1.0.3" + shasum "^1.0.0" + subarg "^1.0.0" + through2 "^2.0.0" + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +detect-file@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63" + dependencies: + fs-exists-sync "^0.1.0" + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +detect-newline@2.X, detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + +detective@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-5.1.0.tgz#7a20d89236d7b331ccea65832e7123b5551bb7cb" + dependencies: + acorn-node "^1.3.0" + defined "^1.0.0" + minimist "^1.1.1" + +dev-ip@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dev-ip/-/dev-ip-1.0.1.tgz#a76a3ed1855be7a012bb8ac16cb80f3c00dc28f0" + +diff@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +discontinuous-range@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + dependencies: + esutils "^2.0.2" + +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: + domelementtype "~1.1.1" + entities "~1.1.1" + +domain-browser@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + +domelementtype@1, domelementtype@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domelementtype@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + dependencies: + dom-serializer "0" + domelementtype "1" + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + dependencies: + readable-stream "~1.1.9" + +duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2, duplexer2@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + dependencies: + readable-stream "^2.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +duplexer@^0.1.1, duplexer@~0.1.1: + version "0.1.1" + resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +easy-extender@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/easy-extender/-/easy-extender-2.3.4.tgz#298789b64f9aaba62169c77a2b3b64b4c9589b8f" + dependencies: + lodash "^4.17.10" + +eazy-logger@^3: + version "3.0.2" + resolved "https://registry.yarnpkg.com/eazy-logger/-/eazy-logger-3.0.2.tgz#a325aa5e53d13a2225889b2ac4113b2b9636f4fc" + dependencies: + tfunk "^3.0.1" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +electron-to-chromium@^1.3.73: + version "1.3.75" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.75.tgz#dd04551739e7371862b0ac7f4ddaa9f3f95b7e68" + +elliptic@^6.0.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" + +encodeurl@~1.0.1, encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + +end-of-stream@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" + dependencies: + once "~1.3.0" + +engine.io-client@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.1.1" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.2.tgz#4c0f4cff79aaeecbbdcfdea66a823c6085409196" + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.4" + has-binary2 "~1.0.2" + +engine.io@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.0.tgz#54332506f42f2edc71690d2f2a42349359f3bf7d" + dependencies: + accepts "~1.3.4" + base64id "1.0.0" + cookie "0.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" + +entities@^1.1.1, entities@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" + +enzyme-adapter-react-16@^1.1.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.6.0.tgz#3fca28d3c32f3ff427495380fe2dd51494689073" + dependencies: + enzyme-adapter-utils "^1.8.0" + function.prototype.name "^1.1.0" + object.assign "^4.1.0" + object.values "^1.0.4" + prop-types "^15.6.2" + react-is "^16.5.2" + react-test-renderer "^16.0.0-0" + +enzyme-adapter-utils@^1.8.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.8.1.tgz#a927d840ce2c14b42892a533aec836809d4e022b" + dependencies: + function.prototype.name "^1.1.0" + object.assign "^4.1.0" + prop-types "^15.6.2" + +enzyme@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.7.0.tgz#9b499e8ca155df44fef64d9f1558961ba1385a46" + dependencies: + array.prototype.flat "^1.2.1" + cheerio "^1.0.0-rc.2" + function.prototype.name "^1.1.0" + has "^1.0.3" + is-boolean-object "^1.0.0" + is-callable "^1.1.4" + is-number-object "^1.0.3" + is-string "^1.0.4" + is-subset "^0.1.1" + lodash.escape "^4.0.1" + lodash.isequal "^4.5.0" + object-inspect "^1.6.0" + object-is "^1.0.1" + object.assign "^4.1.0" + object.entries "^1.0.4" + object.values "^1.0.4" + raf "^3.4.0" + rst-selector-parser "^2.2.3" + string.prototype.trim "^1.1.2" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.10.0, es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.46" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572" + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "1" + +es6-iterator@^2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.0.3: + version "4.2.5" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + dependencies: + es6-promise "^4.0.3" + +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" + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escodegen@^1.9.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-config-react-app@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-2.1.0.tgz#23c909f71cbaff76b945b831d2d814b8bde169eb" + +eslint-import-resolver-node@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-flowtype@^2.50.0: + version "2.50.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz#61379d6dce1d010370acd6681740fd913d68175f" + dependencies: + lodash "^4.17.10" + +eslint-plugin-import@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" + dependencies: + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.2.0" + has "^1.0.1" + lodash "^4.17.4" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + resolve "^1.6.0" + +eslint-plugin-jsx-a11y@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz#69bca4890b36dcf0fe16dd2129d2d88b98f33f88" + dependencies: + aria-query "^3.0.0" + array-includes "^3.0.3" + ast-types-flow "^0.0.7" + axobject-query "^2.0.1" + damerau-levenshtein "^1.0.4" + emoji-regex "^6.5.1" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + +eslint-plugin-react@^7.11.1: + version "7.11.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c" + dependencies: + array-includes "^3.0.3" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + prop-types "^15.6.2" + +eslint-scope@3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + +eslint@^5.4.0: + version "5.6.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.6.1.tgz#348134e32ccc09abb2df1bf282b3f6eed8c7b480" + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.5.3" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^2.1.0" + eslint-scope "^4.0.0" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^4.0.0" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + imurmurhash "^0.1.4" + inquirer "^6.1.0" + is-resolvable "^1.1.0" + js-yaml "^3.12.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.5" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^2.0.0" + require-uncached "^1.0.3" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^4.0.3" + text-table "^0.2.0" + +espree@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634" + dependencies: + acorn "^5.6.0" + acorn-jsx "^4.1.1" + +esprima@^2.6.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.0, esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +etag@^1.8.1, etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + dependencies: + d "1" + es5-ext "~0.10.14" + +event-stream@~3.3.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.6.tgz#cac1230890e07e73ec9cacd038f60a5b66173eef" + dependencies: + duplexer "^0.1.1" + flatmap-stream "^0.1.0" + from "^0.1.7" + map-stream "0.0.7" + pause-stream "^0.0.11" + split "^1.0.1" + stream-combiner "^0.2.2" + through "^2.3.8" + +eventemitter3@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + +events@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-2.1.0.tgz#2a9a1e18e6106e0e812aa9ebd4a819b3c29c0ba5" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" + dependencies: + merge "^1.2.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +expand-tilde@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" + dependencies: + os-homedir "^1.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + dependencies: + homedir-polyfill "^1.0.1" + +expect@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^23.6.0" + jest-get-type "^22.1.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.0, extend@~3.0.1, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + +external-editor@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fancy-log@^1.1.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1" + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + time-stamp "^1.0.0" + +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" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +fast-xml-parser@^3.12.0: + version "3.12.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.12.5.tgz#756e4da382f403f88990a62344add00948820fe0" + dependencies: + nimnjs "^1.3.2" + +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + dependencies: + bser "^2.0.0" + +fetch-mock@^6.5.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/fetch-mock/-/fetch-mock-6.5.2.tgz#b3842b305c13ea0f81c85919cfaa7de387adfa3e" + dependencies: + babel-polyfill "^6.26.0" + glob-to-regexp "^0.4.0" + path-to-regexp "^2.2.1" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +find-index@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" + +find-node-modules@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-1.0.4.tgz#b6deb3cccb699c87037677bcede2c5f5862b2550" + dependencies: + findup-sync "0.4.2" + merge "^1.2.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +findup-sync@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.2.tgz#a8117d0f73124f5a4546839579fe52d7129fb5e5" + dependencies: + detect-file "^0.1.0" + is-glob "^2.0.1" + micromatch "^2.3.7" + resolve-dir "^0.1.0" + +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +fined@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476" + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + +flagged-respawn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.0.tgz#4e79ae9b2eb38bf86b3bb56bf3e0a56aa5fcabd7" + +flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +flatmap-stream@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz#d34f39ef3b9aa5a2fc225016bd3adf28ac5ae6ea" + +flow-bin@^0.79.1: + version "0.79.1" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.79.1.tgz#01c9f427baa6556753fa878c192d42e1ecb764b6" + +flow-typed@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.5.1.tgz#0ff565cc94d2af8c557744ba364b6f14726a6b9f" + dependencies: + "@octokit/rest" "^15.2.6" + babel-polyfill "^6.26.0" + colors "^1.1.2" + fs-extra "^5.0.0" + glob "^7.1.2" + got "^7.1.0" + md5 "^2.1.0" + mkdirp "^0.5.1" + rimraf "^2.6.2" + semver "^5.5.0" + table "^4.0.2" + through "^2.3.8" + unzipper "^0.8.11" + which "^1.3.0" + yargs "^4.2.0" + +follow-redirects@^1.2.5: + version "1.5.8" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.8.tgz#1dbfe13e45ad969f813e86c00e5296f525c885a1" + dependencies: + debug "=3.1.0" + +font-awesome@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.1, form-data@~2.3.2: + 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" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2, fresh@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + +from@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + +fs-exists-sync@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" + +fs-extra@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0, fsevents@^1.2.2, fsevents@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +function.prototype.name@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + is-callable "^1.1.3" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" + dependencies: + globule "~0.1.0" + +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + dependencies: + globule "^1.0.0" + +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-assigned-identifiers@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + +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@^3.0.0: + version "3.0.0" + resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^3.1.5: + version "3.1.18" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" + dependencies: + glob "^4.3.1" + glob2base "^0.0.12" + minimatch "^2.0.1" + ordered-read-streams "^0.1.0" + through2 "^0.6.1" + unique-stream "^1.0.0" + +glob-to-regexp@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.0.tgz#49bd677b1671022bd10921c3788f23cdebf9c7e6" + +glob-watcher@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" + dependencies: + gaze "^0.5.1" + +glob2base@^0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" + dependencies: + find-index "^0.1.1" + +glob@^4.3.1: + version "4.5.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "^2.0.1" + once "^1.3.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~3.1.21: + version "3.1.21" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" + dependencies: + graceful-fs "~1.2.0" + inherits "1" + minimatch "~0.2.11" + +global-modules@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" + dependencies: + global-prefix "^0.1.4" + is-windows "^0.2.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" + dependencies: + homedir-polyfill "^1.0.0" + ini "^1.3.4" + is-windows "^0.2.0" + which "^1.2.12" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^11.1.0, globals@^11.7.0: + version "11.8.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.8.0.tgz#c1ef45ee9bed6badf0663c5cb90e8d1adec1321d" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globule@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + +globule@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" + dependencies: + glob "~3.1.21" + lodash "~1.0.1" + minimatch "~0.2.11" + +glogg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810" + dependencies: + sparkles "^1.0.0" + +got@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +graceful-fs@4.X, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +graceful-fs@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + dependencies: + natives "^1.1.0" + +graceful-fs@~1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + +gulp-sourcemaps@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz#cbb2008450b1bcce6cd23bf98337be751bf6e30a" + dependencies: + "@gulp-sourcemaps/identity-map" "1.X" + "@gulp-sourcemaps/map-sources" "1.X" + acorn "5.X" + convert-source-map "1.X" + css "2.X" + debug-fabulous "1.X" + detect-newline "2.X" + graceful-fs "4.X" + source-map "~0.6.0" + strip-bom-string "1.X" + through2 "2.X" + +gulp-uglify@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-3.0.1.tgz#8d3eee466521bea6b10fd75dff72adf8b7ea2d97" + dependencies: + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash "^4.13.1" + make-error-cause "^1.1.1" + safe-buffer "^5.1.2" + through2 "^2.0.0" + uglify-js "^3.0.5" + vinyl-sourcemaps-apply "^0.2.0" + +gulp-util@^3.0.0: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp@^3.9.1: + version "3.9.1" + resolved "http://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" + dependencies: + archy "^1.0.0" + chalk "^1.0.0" + deprecated "^0.0.1" + gulp-util "^3.0.0" + interpret "^1.0.0" + liftoff "^2.1.0" + minimist "^1.1.0" + orchestrator "^0.3.0" + pretty-hrtime "^1.0.0" + semver "^4.1.0" + tildify "^1.0.0" + v8flags "^2.0.2" + vinyl-fs "^0.3.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + dependencies: + glogg "^1.0.0" + +handlebars@^4.0.3: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +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" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +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" + +har-validator@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" + dependencies: + ajv "^5.3.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + dependencies: + sparkles "^1.0.0" + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.0, has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +history@^4.7.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b" + dependencies: + invariant "^2.2.1" + loose-envify "^1.2.0" + resolve-pathname "^2.2.0" + value-equal "^0.4.0" + warning "^3.0.0" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0: + version "2.5.5" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + dependencies: + whatwg-encoding "^1.0.1" + +html-parse-stringify2@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a" + dependencies: + void-elements "^2.0.1" + +htmlescape@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" + +htmlparser2@^3.9.1: + version "3.9.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338" + dependencies: + domelementtype "^1.3.0" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^2.0.2" + +http-errors@1.6.3, http-errors@~1.6.2: + version "1.6.3" + resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + dependencies: + agent-base "4" + debug "3.1.0" + +http-proxy@1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.15.2.tgz#642fdcaffe52d3448d2bda3b0079e9409064da31" + dependencies: + eventemitter3 "1.x.x" + requires-port "1.x.x" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.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" + +https-proxy-agent@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +hyphenate-style-name@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" + +i18next-browser-languagedetector@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-2.2.3.tgz#4196a9964b6d51b76254706a267ba746c9ca19de" + +i18next-fetch-backend@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/i18next-fetch-backend/-/i18next-fetch-backend-0.1.0.tgz#18b67920d0e605e616f93bbdf897e59adf9c9c05" + dependencies: + i18next-xhr-backend "^1.4.3" + +i18next-xhr-backend@^1.4.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/i18next-xhr-backend/-/i18next-xhr-backend-1.5.1.tgz#50282610780c6a696d880dfa7f4ac1d01e8c3ad5" + +i18next@^11.4.0: + version "11.9.0" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-11.9.0.tgz#c30c0a5e0a857124923a8dd1ce8f1df603e30c70" + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + dependencies: + minimatch "^3.0.4" + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + +immutable@^3: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +inline-source-map@~0.6.0: + version "0.6.2" + resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5" + dependencies: + source-map "~0.5.3" + +inquirer@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.17.10" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +insert-module-globals@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.2.0.tgz#ec87e5b42728479e327bd5c5c71611ddfb4752ba" + dependencies: + JSONStream "^1.0.3" + acorn-node "^1.5.2" + combine-source-map "^0.8.0" + concat-stream "^1.6.1" + is-buffer "^1.1.0" + path-is-absolute "^1.0.1" + process "~0.11.0" + through2 "^2.0.0" + undeclared-identifiers "^1.1.2" + xtend "^4.0.0" + +interpret@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + +invariant@^2.0.0, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-boolean-object@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93" + +is-buffer@^1.1.0, is-buffer@^1.1.5, is-buffer@~1.1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + dependencies: + ci-info "^1.5.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +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-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +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" + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-in-browser@^1.0.2, is-in-browser@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" + +is-my-ip-valid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824" + +is-my-json-valid@^2.12.4: + version "2.19.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz#8fd6e40363cd06b963fa877d444bfb5eddc62175" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number-like@^1.0.3: + version "1.0.8" + resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3" + dependencies: + lodash.isfinite "^3.3.2" + +is-number-object@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1, is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + dependencies: + is-unc-path "^1.0.0" + +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-string@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64" + +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + dependencies: + has-symbols "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + +isarray@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.4.tgz#38e7bcbb0f3ba1b7933c86ba1894ddfc3781bbb7" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul-api@^1.3.1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" + dependencies: + async "^2.1.4" + fileset "^2.0.2" + istanbul-lib-coverage "^1.2.1" + istanbul-lib-hook "^1.2.2" + istanbul-lib-instrument "^1.10.2" + istanbul-lib-report "^1.1.5" + istanbul-lib-source-maps "^1.2.6" + istanbul-reports "^1.5.1" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + +istanbul-lib-hook@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" + dependencies: + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" + dependencies: + handlebars "^4.0.3" + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +jest-changed-files@^23.4.2: + version "23.4.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83" + dependencies: + throat "^4.0.0" + +jest-cli@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.1.11" + import-local "^1.0.0" + is-ci "^1.0.10" + istanbul-api "^1.3.1" + istanbul-lib-coverage "^1.2.0" + istanbul-lib-instrument "^1.10.1" + istanbul-lib-source-maps "^1.2.4" + jest-changed-files "^23.4.2" + jest-config "^23.6.0" + jest-environment-jsdom "^23.4.0" + jest-get-type "^22.1.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve-dependencies "^23.6.0" + jest-runner "^23.6.0" + jest-runtime "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + jest-watcher "^23.4.0" + jest-worker "^23.2.0" + micromatch "^2.3.11" + node-notifier "^5.2.1" + prompts "^0.1.9" + realpath-native "^1.0.0" + rimraf "^2.5.4" + slash "^1.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" + which "^1.2.12" + yargs "^11.0.0" + +jest-config@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d" + dependencies: + babel-core "^6.0.0" + babel-jest "^23.6.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^23.4.0" + jest-environment-node "^23.4.0" + jest-get-type "^22.1.0" + jest-jasmine2 "^23.6.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + pretty-format "^23.6.0" + +jest-diff@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-docblock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" + dependencies: + detect-newline "^2.1.0" + +jest-each@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575" + dependencies: + chalk "^2.0.1" + pretty-format "^23.6.0" + +jest-environment-jsdom@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + jsdom "^11.5.1" + +jest-environment-node@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10" + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + +jest-get-type@^22.1.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + +jest-haste-map@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16" + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + invariant "^2.2.4" + jest-docblock "^23.2.0" + jest-serializer "^23.0.1" + jest-worker "^23.2.0" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-jasmine2@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0" + dependencies: + babel-traverse "^6.0.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^23.6.0" + is-generator-fn "^1.0.0" + jest-diff "^23.6.0" + jest-each "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + pretty-format "^23.6.0" + +jest-junit@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-5.2.0.tgz#980401db7aa69999cf117c6d740a8135c22ae379" + dependencies: + jest-config "^23.6.0" + jest-validate "^23.0.1" + mkdirp "^0.5.1" + strip-ansi "^4.0.0" + xml "^1.0.1" + +jest-leak-detector@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de" + dependencies: + pretty-format "^23.6.0" + +jest-matcher-utils@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-message-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134" + +jest-regex-util@^23.3.0: + version "23.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" + +jest-resolve-dependencies@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d" + dependencies: + jest-regex-util "^23.3.0" + jest-snapshot "^23.6.0" + +jest-resolve@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae" + dependencies: + browser-resolve "^1.11.3" + chalk "^2.0.1" + realpath-native "^1.0.0" + +jest-runner@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38" + dependencies: + exit "^0.1.2" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-docblock "^23.2.0" + jest-haste-map "^23.6.0" + jest-jasmine2 "^23.6.0" + jest-leak-detector "^23.6.0" + jest-message-util "^23.4.0" + jest-runtime "^23.6.0" + jest-util "^23.4.0" + jest-worker "^23.2.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082" + dependencies: + babel-core "^6.0.0" + babel-plugin-istanbul "^4.1.6" + chalk "^2.0.1" + convert-source-map "^1.4.0" + exit "^0.1.2" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + realpath-native "^1.0.0" + slash "^1.0.0" + strip-bom "3.0.0" + write-file-atomic "^2.1.0" + yargs "^11.0.0" + +jest-serializer@^23.0.1: + version "23.0.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" + +jest-snapshot@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a" + dependencies: + babel-types "^6.0.0" + chalk "^2.0.1" + jest-diff "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-resolve "^23.6.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^23.6.0" + semver "^5.5.0" + +jest-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^23.4.0" + mkdirp "^0.5.1" + slash "^1.0.0" + source-map "^0.6.0" + +jest-validate@^23.0.1, jest-validate@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^23.6.0" + +jest-watcher@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + string-length "^2.0.0" + +jest-worker@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" + dependencies: + merge-stream "^1.0.1" + +jest@^23.5.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d" + dependencies: + import-local "^1.0.0" + jest-cli "^23.6.0" + +js-base64@^2.1.8: + version "2.4.9" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" + +js-levenshtein@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +js-yaml@^3.12.0, js-yaml@^3.7.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-parse-better-errors@^1.0.1: + 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" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + +json-stable-stringify@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz#611c23e814db375527df851193db59dd2af27f45" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + 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" + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jss-camel-case@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-6.1.0.tgz#ccb1ff8d6c701c02a1fed6fb6fb6b7896e11ce44" + dependencies: + hyphenate-style-name "^1.0.2" + +jss-compose@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-5.0.0.tgz#ce01b2e4521d65c37ea42cf49116e5f7ab596484" + dependencies: + warning "^3.0.0" + +jss-default-unit@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-8.0.2.tgz#cc1e889bae4c0b9419327b314ab1c8e2826890e6" + +jss-expand@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-5.3.0.tgz#02be076efe650125c842f5bb6fb68786fe441ed6" + +jss-extend@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/jss-extend/-/jss-extend-6.2.0.tgz#4af09d0b72fb98ee229970f8ca852fec1ca2a8dc" + dependencies: + warning "^3.0.0" + +jss-global@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-3.0.0.tgz#e19e5c91ab2b96353c227e30aa2cbd938cdaafa2" + +jss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-6.0.1.tgz#ef992b79d6e8f63d939c4397b9d99b5cbbe824ca" + dependencies: + warning "^3.0.0" + +jss-preset-default@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-4.5.0.tgz#d3a457012ccd7a551312014e394c23c4b301cadd" + dependencies: + jss-camel-case "^6.1.0" + jss-compose "^5.0.0" + jss-default-unit "^8.0.2" + jss-expand "^5.3.0" + jss-extend "^6.2.0" + jss-global "^3.0.0" + jss-nested "^6.0.1" + jss-props-sort "^6.0.0" + jss-template "^1.0.1" + jss-vendor-prefixer "^7.0.0" + +jss-props-sort@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-6.0.0.tgz#9105101a3b5071fab61e2d85ea74cc22e9b16323" + +jss-template@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/jss-template/-/jss-template-1.0.1.tgz#09aed9d86cc547b07f53ef355d7e1777f7da430a" + dependencies: + warning "^3.0.0" + +jss-vendor-prefixer@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz#0166729650015ef19d9f02437c73667231605c71" + dependencies: + css-vendor "^0.3.8" + +jss@^9.7.0: + version "9.8.7" + resolved "https://registry.yarnpkg.com/jss/-/jss-9.8.7.tgz#ed9763fc0f2f0260fc8260dac657af61e622ce05" + dependencies: + is-in-browser "^1.1.3" + symbol-observable "^1.1.0" + warning "^3.0.0" + +jsx-ast-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" + dependencies: + array-includes "^3.0.3" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +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" + +kleur@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300" + +labeled-stream-splicer@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz#9cffa32fd99e1612fd1d86a8db962416d5292926" + dependencies: + inherits "^2.0.1" + isarray "^2.0.4" + stream-splicer "^2.0.0" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +lcov-parse@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +liftoff@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" + dependencies: + extend "^3.0.0" + findup-sync "^2.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +limiter@^1.0.5: + version "1.1.3" + resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.3.tgz#32e2eb55b2324076943e5d04c1185ffb387968ef" + +listenercount@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +localtunnel@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.1.tgz#1d1737eab658add5a40266d8e43f389b646ee3b1" + dependencies: + axios "0.17.1" + debug "2.6.9" + openurl "1.1.1" + yargs "6.6.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash-es@^4.17.5: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.11.tgz#145ab4a7ac5c5e52a3531fb4f310255a152b4be0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + +lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + +lodash.clonedeep@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + dependencies: + lodash._root "^3.0.0" + +lodash.escape@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + +lodash.isfinite@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3" + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.memoize@~3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" + +lodash.mergewith@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + +lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.10: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + +lodash@~1.0.1: + version "1.0.2" + resolved "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" + +log-driver@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + +lru-cache@^4.0.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-queue@0.1: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + dependencies: + es5-ext "~0.10.2" + +macos-release@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-1.1.0.tgz#831945e29365b470aa8724b0ab36c8f8959d10fb" + +make-error-cause@^1.1.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d" + dependencies: + make-error "^1.2.0" + +make-error@^1.2.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + dependencies: + kind-of "^6.0.2" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + dependencies: + tmpl "1.0.x" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +map-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +md5@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +memoizee@0.4.X: + version "0.4.14" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" + dependencies: + d "1" + es5-ext "^0.10.45" + es6-weak-map "^2.0.2" + event-emitter "^0.3.5" + is-promise "^2.1" + lru-queue "0.1" + next-tick "1" + timers-ext "^0.1.5" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + +merge@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" + +micromatch@2.3.11, micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19, mime-types@~2.1.7: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" + dependencies: + mime-db "~1.36.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + +mime@^1.3.6: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + +minimatch@^2.0.1: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + dependencies: + brace-expansion "^1.0.0" + +minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1: + version "0.0.10" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + +mitt@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.1.3.tgz#528c506238a05dce11cd914a741ea2cc332da9b8" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +module-deps@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-6.1.0.tgz#d1e1efc481c6886269f7112c52c3236188e16479" + dependencies: + JSONStream "^1.0.3" + browser-resolve "^1.7.0" + cached-path-relative "^1.0.0" + concat-stream "~1.6.0" + defined "^1.0.0" + detective "^5.0.2" + duplexer2 "^0.1.2" + inherits "^2.0.1" + parents "^1.0.0" + readable-stream "^2.0.2" + resolve "^1.4.0" + stream-combiner2 "^1.1.1" + subarg "^1.0.0" + through2 "^2.0.0" + xtend "^4.0.0" + +moment@^2.22.2: + version "2.22.2" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" + +moo@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + +multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + dependencies: + duplexer2 "0.0.2" + +mustache@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.2.tgz#a6d4d9c3f91d13359ab889a812954f9230a3d0c5" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nan@^2.10.0, nan@^2.9.2: + version "2.11.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natives@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.5.tgz#3bdbdb4104023e5dd239b56fc7ef3d9a17acc6aa" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +nearley@^2.7.10: + version "2.15.1" + resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.15.1.tgz#965e4e6ec9ed6b80fc81453e161efbcebb36d247" + dependencies: + moo "^0.4.3" + nomnom "~1.6.2" + railroad-diagrams "^1.0.0" + randexp "0.4.6" + semver "^5.4.1" + +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +next-tick@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + +nimn-date-parser@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nimn-date-parser/-/nimn-date-parser-1.0.0.tgz#4ce55d1fd5ea206bbe82b76276f7b7c582139351" + +nimn_schema_builder@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/nimn_schema_builder/-/nimn_schema_builder-1.1.0.tgz#b370ccf5b647d66e50b2dcfb20d0aa12468cd247" + +nimnjs@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/nimnjs/-/nimnjs-1.3.2.tgz#a6a877968d87fad836375a4f616525e55079a5ba" + dependencies: + nimn-date-parser "^1.0.0" + nimn_schema_builder "^1.0.0" + +node-fetch@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + +node-mkdirs@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/node-mkdirs/-/node-mkdirs-0.0.1.tgz#b20f50ba796a4f543c04a69942d06d06f8aaf552" + +node-notifier@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" + dependencies: + growly "^1.3.0" + semver "^5.4.1" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-releases@^1.0.0-alpha.12: + version "1.0.0-alpha.12" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.12.tgz#32e461b879ea76ac674e511d9832cf29da345268" + dependencies: + semver "^5.3.0" + +node-sass-chokidar@^1.3.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/node-sass-chokidar/-/node-sass-chokidar-1.3.3.tgz#0bc83b6f4a8264ae27cbc80b18c49ed445d07d68" + dependencies: + async-foreach "^0.1.3" + chokidar "^2.0.4" + get-stdin "^4.0.1" + glob "^7.0.3" + meow "^3.7.0" + node-sass "^4.9.2" + sass-graph "^2.1.1" + stdout-stream "^1.4.0" + +node-sass@^4.9.2, node-sass@^4.9.3: + version "4.9.3" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.9.3.tgz#f407cf3d66f78308bb1e346b24fa428703196224" + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash.assign "^4.2.0" + lodash.clonedeep "^4.3.2" + lodash.mergewith "^4.6.0" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.10.0" + node-gyp "^3.8.0" + npmlog "^4.0.0" + request "2.87.0" + sass-graph "^2.2.4" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + +nomnom@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971" + dependencies: + colors "0.5.x" + underscore "~1.4.4" + +noms@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859" + dependencies: + inherits "^2.0.1" + readable-stream "~1.0.31" + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + +npm-packlist@^1.1.6: + version "1.1.11" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-all@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.3.tgz#49f15b55a66bb4101664ce270cb18e7103f8f185" + dependencies: + ansi-styles "^3.2.0" + chalk "^2.1.0" + cross-spawn "^6.0.4" + memorystream "^0.3.1" + minimatch "^3.0.4" + ps-tree "^1.1.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.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: + boolbase "~1.0.0" + +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" + +nwsapi@^2.0.7: + version "2.0.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" + +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" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + +object-assign@4.X, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + +object-is@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" + +object-keys@^1.0.11, object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + +object-path@^0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.entries@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.6.1" + function-bind "^1.1.0" + has "^1.0.1" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + +object.values@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.6.1" + function-bind "^1.1.0" + has "^1.0.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +once@~1.3.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +openurl@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" + +opn@5.3.0: + version "5.3.0" + resolved "http://registry.npmjs.org/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" + dependencies: + is-wsl "^1.1.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +orchestrator@^0.3.0: + version "0.3.8" + resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" + dependencies: + end-of-stream "~0.1.5" + sequencify "~0.0.7" + stream-consume "~0.1.0" + +ordered-read-streams@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" + +os-browserify@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^1.4.0: + version "1.4.0" + resolved "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-2.0.1.tgz#b9a386361c17ae3a21736ef0599405c9a8c5dc5e" + dependencies: + macos-release "^1.0.0" + win-release "^1.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@0, osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +outpipe@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/outpipe/-/outpipe-1.1.1.tgz#50cf8616365e87e031e29a5ec9339a3da4725fa2" + dependencies: + shell-quote "^1.4.2" + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +pako@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + +parents@^1.0.0, parents@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" + dependencies: + path-platform "~0.11.15" + +parse-asn1@^5.0.0: + version "5.1.1" + resolved "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + +parse5@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + dependencies: + "@types/node" "*" + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-browserify@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + +path-platform@~0.11.15: + version "0.11.15" + resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + dependencies: + path-root-regex "^0.1.0" + +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + dependencies: + isarray "0.0.1" + +path-to-regexp@^2.2.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.4.0.tgz#35ce7f333d5616f1c1e1bfe266c3aba2e5b2e704" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + +pause-stream@^0.0.11: + version "0.0.11" + resolved "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + dependencies: + through "~2.3" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.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" + +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + +pom-parser@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pom-parser/-/pom-parser-1.1.1.tgz#6fab4d2498e87c862072ab205aa88b1209e5f966" + dependencies: + bluebird "^3.3.3" + coveralls "^2.11.3" + traverse "^0.6.6" + xml2js "^0.4.9" + +portscanner@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.1.1.tgz#eabb409e4de24950f5a2a516d35ae769343fbb96" + dependencies: + async "1.5.2" + is-number-like "^1.0.3" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +prettier@^1.13.7, prettier@^1.14.2: + version "1.14.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895" + +pretty-format@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process@~0.11.0: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + +prompts@^0.1.9: + version "0.1.14" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" + dependencies: + kleur "^2.0.1" + sisteransi "^0.1.1" + +prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2: + version "15.6.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" + dependencies: + loose-envify "^1.3.1" + object-assign "^4.1.1" + +ps-tree@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" + dependencies: + event-stream "~3.3.0" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.3.2, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + +qs@6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" + +qs@~6.3.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" + +qs@~6.5.1, qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + +querystring-es3@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +raf@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575" + dependencies: + performance-now "^2.1.0" + +railroad-diagrams@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" + +randexp@0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" + dependencies: + discontinuous-range "1.0.0" + ret "~0.1.10" + +randomatic@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +raw-body@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dom@^16.4.2: + version "16.5.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.5.2.tgz#b69ee47aa20bab5327b2b9d7c1fe2a30f2cfa9d7" + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + schedule "^0.5.0" + +react-i18next@^7.9.0: + version "7.13.0" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-7.13.0.tgz#a6f64fd749215ec70400f90da6cbde2a9c5b1588" + dependencies: + hoist-non-react-statics "^2.3.1" + html-parse-stringify2 "2.0.1" + prop-types "^15.6.0" + +react-is@^16.5.2: + version "16.5.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.5.2.tgz#e2a7b7c3f5d48062eb769fcb123505eb928722e3" + +react-jss@^8.6.0: + version "8.6.1" + resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-8.6.1.tgz#a06e2e1d2c4d91b4d11befda865e6c07fbd75252" + dependencies: + hoist-non-react-statics "^2.5.0" + jss "^9.7.0" + jss-preset-default "^4.3.0" + prop-types "^15.6.0" + theming "^1.3.0" + +react-redux@^5.0.7: + version "5.0.7" + resolved "http://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8" + dependencies: + hoist-non-react-statics "^2.5.0" + invariant "^2.0.0" + lodash "^4.17.5" + lodash-es "^4.17.5" + loose-envify "^1.1.0" + prop-types "^15.6.0" + +react-router-dom@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6" + dependencies: + history "^4.7.2" + invariant "^2.2.4" + loose-envify "^1.3.1" + prop-types "^15.6.1" + react-router "^4.3.1" + warning "^4.0.1" + +react-router-enzyme-context@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/react-router-enzyme-context/-/react-router-enzyme-context-1.2.0.tgz#7aa11c80e23278fa31f8a29845f7b37760d99350" + dependencies: + history "^4.7.2" + prop-types "^15.6.0" + +react-router-redux@^5.0.0-alpha.9: + version "5.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/react-router-redux/-/react-router-redux-5.0.0-alpha.9.tgz#825431516e0e6f1fd93b8807f6bd595e23ec3d10" + dependencies: + history "^4.7.2" + prop-types "^15.6.0" + react-router "^4.2.0" + +react-router@^4.2.0, react-router@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e" + dependencies: + history "^4.7.2" + hoist-non-react-statics "^2.5.0" + invariant "^2.2.4" + loose-envify "^1.3.1" + path-to-regexp "^1.7.0" + prop-types "^15.6.1" + warning "^4.0.1" + +react-test-renderer@^16.0.0-0, react-test-renderer@^16.4.1: + version "16.5.2" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.5.2.tgz#92e9d2c6f763b9821b2e0b22f994ee675068b5ae" + dependencies: + object-assign "^4.1.1" + prop-types "^15.6.2" + react-is "^16.5.2" + schedule "^0.5.0" + +react@^16.4.2: + version "16.5.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.5.2.tgz#19f6b444ed139baa45609eee6dc3d318b3895d42" + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + schedule "^0.5.0" + +read-only-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0" + dependencies: + readable-stream "^2.0.2" + +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" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.31: + version "1.0.34" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@^2.3.6: + version "2.3.6" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.1.5: + version "2.1.5" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +realpath-native@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" + dependencies: + util.promisify "^1.0.0" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redux-devtools-extension@^2.13.5: + version "2.13.5" + resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.5.tgz#3ff34f7227acfeef3964194f5f7fc2765e5c5a39" + +redux-logger@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf" + dependencies: + deep-diff "^0.3.5" + +redux-mock-store@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/redux-mock-store/-/redux-mock-store-1.5.3.tgz#1f10528949b7ce8056c2532624f7cafa98576c6d" + dependencies: + lodash.isplainobject "^4.0.6" + +redux-thunk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" + +redux@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.0.tgz#aa698a92b729315d22b34a0553d7e6533555cc03" + dependencies: + loose-envify "^1.1.0" + symbol-observable "^1.2.0" + +regenerate-unicode-properties@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-transform@^0.13.3: + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" + dependencies: + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + +regexpu-core@^4.1.3, regexpu-core@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^7.0.0" + regjsgen "^0.4.0" + regjsparser "^0.3.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.0.2" + +regjsgen@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.4.0.tgz#c1eb4c89a209263f8717c782591523913ede2561" + +regjsparser@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.3.0.tgz#3c326da7fcfd69fa0d332575a41c8c0cdf588c96" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + 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" + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@2.79.0: + version "2.79.0" + resolved "http://registry.npmjs.org/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +request@2.87.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.87.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" + dependencies: + expand-tilde "^1.2.2" + global-modules "^0.2.3" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-pathname@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.6.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" + dependencies: + path-parse "^1.0.5" + +resp-modifier@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/resp-modifier/-/resp-modifier-6.0.2.tgz#b124de5c4fbafcba541f48ffa73970f4aa456b4f" + dependencies: + debug "^2.2.0" + minimatch "^3.0.2" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rst-selector-parser@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91" + dependencies: + lodash.flattendeep "^4.4.0" + nearley "^2.7.10" + +rsvp@^3.3.3: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +rx@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + +rxjs@^5.5.6: + version "5.5.12" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" + dependencies: + symbol-observable "1.0.1" + +rxjs@^6.1.0: + version "6.3.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +sane@^2.0.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + +sass-graph@^2.1.1, sass-graph@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^7.0.0" + +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +schedule@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" + dependencies: + object-assign "^4.1.1" + +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + +semver@^4.1.0: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +sequencify@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" + +serve-index@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +server-destroy@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + +sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4: + version "2.4.11" + resolved "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shasum@^1.0.0: + version "1.0.2" + resolved "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f" + dependencies: + json-stable-stringify "~0.0.0" + sha.js "~2.4.4" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shell-quote@^1.4.2, shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + +sisteransi@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" + +socket.io-client@2.1.1, socket.io-client@^2.0.4: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f" + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~3.1.0" + engine.io-client "~3.2.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.2.0" + to-array "0.1.4" + +socket.io-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" + dependencies: + debug "~3.1.0" + engine.io "~3.2.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.1.1" + socket.io-parser "~3.2.0" + +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.6: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + +source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.3: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + +spdx-correct@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz#e2a303236cac54b04031fa7a5a79c7e701df852f" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + +split@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + dependencies: + through "2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.14.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + safer-buffer "^2.0.2" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stack-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" + dependencies: + readable-stream "^2.0.1" + +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + +stream-browserify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-combiner2@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" + dependencies: + duplexer2 "~0.1.0" + readable-stream "^2.0.2" + +stream-combiner@^0.2.2: + version "0.2.2" + resolved "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + dependencies: + duplexer "~0.1.1" + through "~2.3.4" + +stream-consume@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.1.tgz#d3bdb598c2bd0ae82b8cac7ac50b1107a7996c48" + +stream-http@^2.0.0: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-splicer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/stream-splicer/-/stream-splicer-2.0.0.tgz#1b63be438a133e4b671cc1935197600175910d83" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.2" + +stream-throttle@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/stream-throttle/-/stream-throttle-0.1.3.tgz#add57c8d7cc73a81630d31cd55d3961cfafba9c3" + dependencies: + commander "^2.2.0" + limiter "^1.0.5" + +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string.prototype.padend@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.4.3" + function-bind "^1.0.2" + +string.prototype.trim@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.0" + function-bind "^1.0.2" + +string_decoder@^1.1.1, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +stringstream@~0.0.4: + version "0.0.6" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom-string@1.X: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + +strip-bom@3.0.0, strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-bom@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" + dependencies: + first-chunk-stream "^1.0.0" + is-utf8 "^0.2.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-css-comments@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-css-comments/-/strip-css-comments-3.0.0.tgz#7a5625eff8a2b226cf8947a11254da96e13dae89" + dependencies: + is-regexp "^1.0.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +subarg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" + dependencies: + minimist "^1.1.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + dependencies: + has-flag "^3.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + +symbol-observable@^1.1.0, symbol-observable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + +syntax-error@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.4.0.tgz#2d9d4ff5c064acb711594a3e3b95054ad51d907c" + dependencies: + acorn-node "^1.2.0" + +table@^4.0.2, table@^4.0.3: + version "4.0.3" + resolved "http://registry.npmjs.org/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" + dependencies: + ajv "^6.0.1" + ajv-keywords "^3.0.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + +tar@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tar@^4: + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.3.3" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +test-exclude@^4.2.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +tfunk@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/tfunk/-/tfunk-3.1.0.tgz#38e4414fc64977d87afdaa72facb6d29f82f7b5b" + dependencies: + chalk "^1.1.1" + object-path "^0.9.0" + +theming@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/theming/-/theming-1.3.0.tgz#286d5bae80be890d0adc645e5ca0498723725bdc" + dependencies: + brcast "^3.0.1" + is-function "^1.0.1" + is-plain-object "^2.0.1" + prop-types "^15.5.8" + +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + +through2@2.0.x, through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through2@^0.6.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through@2, "through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.4: + version "2.3.8" + resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tildify@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" + dependencies: + os-homedir "^1.0.0" + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + +timers-browserify@^1.0.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" + dependencies: + process "~0.11.0" + +timers-ext@^0.1.5: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + dependencies: + es5-ext "~0.10.46" + next-tick "1" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + +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" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +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: + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + +traverse@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +"true-case-path@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + dependencies: + glob "^7.1.2" + +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + +tty-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +ua-parser-js@0.7.17: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + +uglify-js@^3.0.5, uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + +umd@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.3.tgz#aa9fe653c42b9097678489c01000acb69f0b26cf" + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + +undeclared-identifiers@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz#7d850a98887cff4bd0bf64999c014d08ed6d1acc" + dependencies: + acorn-node "^1.3.0" + get-assigned-identifiers "^1.2.0" + simple-concat "^1.0.0" + xtend "^4.0.1" + +underscore@~1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz#9f1dc76926d6ccf452310564fd834ace059663d4" + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz#5a533f31b4317ea76f17d807fa0d116546111dd0" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" + +universal-user-agent@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.0.1.tgz#18e591ca52b1cb804f6b9cbc4c336cf8191f80e1" + dependencies: + os-name "^2.0.1" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzipper@^0.8.11: + version "0.8.14" + resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.8.14.tgz#ade0524cd2fc14d11b8de258be22f9d247d3f79b" + dependencies: + big-integer "^1.6.17" + binary "~0.3.0" + bluebird "~3.4.1" + buffer-indexof-polyfill "~1.0.0" + duplexer2 "~0.1.4" + fstream "~1.0.10" + listenercount "~1.0.1" + readable-stream "~2.1.5" + setimmediate "~1.0.4" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + +url@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +util@~0.10.1: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + +uuid@^3.0.0, uuid@^3.1.0, uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + +v8flags@^2.0.2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + dependencies: + user-home "^1.1.1" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +value-equal@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vinyl-buffer/-/vinyl-buffer-1.0.1.tgz#96c1a3479b8c5392542c612029013b5b27f88bbf" + dependencies: + bl "^1.2.1" + through2 "^2.0.3" + +vinyl-fs@^0.3.0: + version "0.3.14" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" + dependencies: + defaults "^1.0.0" + glob-stream "^3.1.5" + glob-watcher "^0.0.6" + graceful-fs "^3.0.0" + mkdirp "^0.5.0" + strip-bom "^1.0.0" + through2 "^0.6.1" + vinyl "^0.4.0" + +vinyl-source-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-2.0.0.tgz#f38a5afb9dd1e93b65d550469ac6182ac4f54b8e" + dependencies: + through2 "^2.0.3" + vinyl "^2.1.0" + +vinyl-sourcemaps-apply@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + dependencies: + source-map "^0.5.1" + +vinyl@^0.4.0: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vm-browserify@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" + +void-elements@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + dependencies: + makeerror "1.0.x" + +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + dependencies: + loose-envify "^1.0.0" + +warning@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.2.tgz#aa6876480872116fa3e11d434b0d0d8d91e44607" + dependencies: + loose-envify "^1.0.0" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + +watchify@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/watchify/-/watchify-3.11.0.tgz#03f1355c643955e7ab8dcbf399f624644221330f" + dependencies: + anymatch "^1.3.0" + browserify "^16.1.0" + chokidar "^1.0.0" + defined "^1.0.0" + outpipe "^1.1.0" + through2 "^2.0.0" + xtend "^4.0.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz#a3d58ef10b76009b042d03e25591ece89b88d171" + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +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.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + dependencies: + string-width "^1.0.2 || 2" + +win-release@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/win-release/-/win-release-1.1.1.tgz#5fa55e02be7ca934edfc12665632e849b72e5209" + dependencies: + semver "^5.0.1" + +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + dependencies: + async-limiter "~1.0.0" + +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + +xml2js@^0.4.9: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + +xml@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" + +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +yargs-parser@^2.4.1: + version "2.4.1" + resolved "http://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + +yargs-parser@^4.1.0, yargs-parser@^4.2.0: + version "4.2.1" + resolved "http://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + dependencies: + camelcase "^3.0.0" + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + dependencies: + camelcase "^3.0.0" + +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + dependencies: + camelcase "^4.1.0" + +yargs@6.4.0: + version "6.4.0" + resolved "http://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz#816e1a866d5598ccf34e5596ddce22d92da490d4" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^4.1.0" + +yargs@6.6.0: + version "6.6.0" + resolved "http://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + +yargs@^11.0.0: + version "11.1.0" + resolved "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + +yargs@^4.2.0: + version "4.8.1" + resolved "http://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + +yargs@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" From 29faaf1c032227596ffa836dd51111797df6fe5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 9 Oct 2018 15:08:33 +0000 Subject: [PATCH 081/121] Close branch feature/autocomplet_endpoint_v2 From 39ba689405e48e099c56343a1d496561ba37917b Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Tue, 9 Oct 2018 15:21:51 +0000 Subject: [PATCH 082/121] Close branch bugfix/lerna_version From 62abae43688d3b80432b33f68772bdd16236db87 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Tue, 9 Oct 2018 21:36:41 +0200 Subject: [PATCH 083/121] Bootstrapped reimplementation of Changeset list --- .../src/repos/containers/BranchChangesets.js | 106 ++++++++++++++++++ .../repos/containers/ChangesetContainer.js | 61 ++++++++++ scm-ui/src/repos/containers/RepositoryRoot.js | 52 ++++----- scm-ui/src/repos/modules/branches.js | 14 +-- 4 files changed, 196 insertions(+), 37 deletions(-) create mode 100644 scm-ui/src/repos/containers/BranchChangesets.js create mode 100644 scm-ui/src/repos/containers/ChangesetContainer.js diff --git a/scm-ui/src/repos/containers/BranchChangesets.js b/scm-ui/src/repos/containers/BranchChangesets.js new file mode 100644 index 0000000000..982c500eab --- /dev/null +++ b/scm-ui/src/repos/containers/BranchChangesets.js @@ -0,0 +1,106 @@ +// @flow +import React from "react"; +import type {Branch, Repository} from "@scm-manager/ui-types"; +import {connect} from "react-redux"; +import {fetchBranches, getBranch, getBranchNames, isFetchBranchesPending} from "../modules/branches"; +import DropDown from "../components/DropDown"; +import type {History} from "history"; +import {withRouter} from "react-router-dom"; +import ChangesetContainer from "./ChangesetContainer"; +import {Loading} from "@scm-manager/ui-components"; + +type Props = { + repository: Repository, + branches: Branch[], + branchNames: string[], + fetchBranches: Repository => void, + history: History, + match: any, + selectedBranch: Branch, + label: string, //TODO: Should this be here? + loading: boolean +}; +type State = {}; + +class BranchChangesets extends React.Component { + componentDidMount() { + this.props.fetchBranches(this.props.repository); + } + + render() { + const { + repository, + branchNames, + match, + selectedBranch, + label, + loading + } = this.props; + const selectedBranchName = match.params.branch; + + if (loading) { + return ; + } + + // TODO: Handle errors + + if (!branchNames || branchNames.length === 0) { + return null; + } + + return ( + <> +
    + + this.branchSelected(branch)} + /> +
    + + + ); + } + + //TODO: Maybe extract this and let it be passed from parent component + branchSelected = (branchName: string) => { + const { namespace, name } = this.props.repository; + if (branchName === "") { + this.props.history.push(`/repo/${namespace}/${name}/changesets`); + } else { + this.props.history.push( + `/repo/${namespace}/${name}/branches/${branchName}/changesets` + ); + } + }; +} + +const mapDispatchToProps = dispatch => { + return { + fetchBranches: (repo: Repository) => { + dispatch(fetchBranches(repo)); + } + }; +}; + +const mapStateToProps = (state: any, ownProps: Props) => { + const loading = isFetchBranchesPending(state, ownProps.repository); + const branchNames = getBranchNames(state, ownProps.repository); + const selectedBranch = getBranch( + state, + ownProps.repository, + ownProps.match.params.branch //TODO: Maybe let parent component pass selected branch + ); + return { + loading, + branchNames, + selectedBranch + }; +}; +export default withRouter( + connect( + mapStateToProps, + mapDispatchToProps + )(BranchChangesets) +); diff --git a/scm-ui/src/repos/containers/ChangesetContainer.js b/scm-ui/src/repos/containers/ChangesetContainer.js new file mode 100644 index 0000000000..d6a473431d --- /dev/null +++ b/scm-ui/src/repos/containers/ChangesetContainer.js @@ -0,0 +1,61 @@ +// @flow + +import React from "react"; +import { withRouter } from "react-router-dom"; +import type { Branch, Changeset, Repository } from "@scm-manager/ui-types"; +import { + fetchChangesetsByBranch, + getChangesets, + isFetchChangesetsPending +} from "../modules/changesets"; +import { connect } from "react-redux"; +import ChangesetList from "../components/changesets/ChangesetList"; +import { Loading } from "@scm-manager/ui-components"; + +type Props = { + fetchChangesetsByBranch: (Repository, Branch) => void, + repository: Repository, //TODO: Do we really need/want this here? + branch: Branch, + changesets: Changeset[], + loading: boolean +}; +type State = {}; + +class ChangesetContainer extends React.Component { + componentDidMount() { + const { fetchChangesetsByBranch, repository, branch } = this.props; + fetchChangesetsByBranch(repository, branch); //TODO: fetch by page + } + + render() { + const { repository, changesets, loading } = this.props; + if (loading) { + return ; + } + if (!changesets || changesets.length === 0) { + return null; + } + return ; + } +} + +const mapDispatchToProps = dispatch => { + return { + fetchChangesetsByBranch: (repo: Repository, branch: Branch) => { + dispatch(fetchChangesetsByBranch(repo, branch)); + } + }; +}; + +const mapStateToProps = (state: any, ownProps: Props) => { + const { repository, branch } = ownProps; + const changesets = getChangesets(state, repository, branch); + const loading = isFetchChangesetsPending(state, repository, branch); + return { changesets, loading }; +}; +export default withRouter( + connect( + mapStateToProps, + mapDispatchToProps + )(ChangesetContainer) +); diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index e9acf80a5d..e3a78d8f34 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -1,31 +1,18 @@ //@flow import React from "react"; -import { - deleteRepo, - fetchRepo, - getFetchRepoFailure, - getRepository, - isFetchRepoPending -} from "../modules/repos"; -import { connect } from "react-redux"; -import { Route } from "react-router-dom"; -import type { Repository } from "@scm-manager/ui-types"; -import { - Page, - Loading, - ErrorPage, - Navigation, - NavLink, - Section -} from "@scm-manager/ui-components"; -import { translate } from "react-i18next"; +import {deleteRepo, fetchRepo, getFetchRepoFailure, getRepository, isFetchRepoPending} from "../modules/repos"; +import {connect} from "react-redux"; +import {Route} from "react-router-dom"; +import type {Repository} from "@scm-manager/ui-types"; +import {ErrorPage, Loading, Navigation, NavLink, Page, Section} from "@scm-manager/ui-components"; +import {translate} from "react-i18next"; import RepositoryDetails from "../components/RepositoryDetails"; import DeleteNavAction from "../components/DeleteNavAction"; import Edit from "../containers/Edit"; -import type { History } from "history"; +import type {History} from "history"; import EditNavLink from "../components/EditNavLink"; -import Changesets from "./Changesets"; +import BranchChangesets from "./BranchChangesets"; type Props = { namespace: string, @@ -94,7 +81,7 @@ class RepositoryRoot extends React.Component { } const url = this.matchedUrl(); - + // TODO: Changesets need to be adjusted (i.e. sub-routes need to be handled in sub-components) return (
    @@ -108,25 +95,34 @@ class RepositoryRoot extends React.Component { path={`${url}/edit`} component={() => } /> + } + render={() => ( + + )} /> } + render={() => ( + + )} /> } + path={`${url}/branches/:branch/changesets`} + render={() => ( + + )} /> } + path={`${url}/branches/:branch/changesets/:page`} + render={() => ( + + )} />
    diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index c771a9734e..6e0ca52d5c 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -1,12 +1,8 @@ // @flow -import { - FAILURE_SUFFIX, - PENDING_SUFFIX, - SUCCESS_SUFFIX -} from "../../modules/types"; -import { apiClient } from "@scm-manager/ui-components"; -import type { Repository, Action, Branch } from "@scm-manager/ui-types"; -import { isPending } from "../../modules/pending"; +import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; +import {apiClient} from "@scm-manager/ui-components"; +import type {Action, Branch, Repository} from "@scm-manager/ui-types"; +import {isPending} from "../../modules/pending"; export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; export const FETCH_BRANCHES_PENDING = `${FETCH_BRANCHES}_${PENDING_SUFFIX}`; @@ -113,7 +109,7 @@ export function getBranchNames( repository: Repository ): ?Array { const key = createKey(repository); - if (!state.branches[key] || !state.branches[key].byNames) { + if (!state.branches || !state.branches[key] || !state.branches[key].byNames) { return []; } return Object.keys(state.branches[key].byNames); From 795d0d8015a1f1627fa6471669b0ee6c7fe49a9a Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Wed, 10 Oct 2018 19:26:29 +0200 Subject: [PATCH 084/121] Implemented LinkPaginator, refactored code for changeset list --- .../ui-components/src/LinkPaginator.js | 129 ++++++++++ .../ui-components/src/buttons/Button.js | 4 +- .../packages/ui-components/src/index.js | 1 + .../src/repos/containers/BranchChangesets.js | 106 -------- scm-ui/src/repos/containers/BranchChooser.js | 157 +++++++----- .../repos/containers/ChangesetContainer.js | 61 ----- scm-ui/src/repos/containers/Changesets.js | 240 ++++-------------- scm-ui/src/repos/containers/RepositoryRoot.js | 55 ++-- scm-ui/src/repos/modules/branches.js | 19 +- scm-ui/src/repos/modules/branches.test.js | 16 ++ scm-ui/src/repos/modules/changesets.js | 50 ++-- scm-ui/src/repos/modules/changesets.test.js | 43 +--- 12 files changed, 374 insertions(+), 507 deletions(-) create mode 100644 scm-ui-components/packages/ui-components/src/LinkPaginator.js delete mode 100644 scm-ui/src/repos/containers/BranchChangesets.js delete mode 100644 scm-ui/src/repos/containers/ChangesetContainer.js diff --git a/scm-ui-components/packages/ui-components/src/LinkPaginator.js b/scm-ui-components/packages/ui-components/src/LinkPaginator.js new file mode 100644 index 0000000000..75e53df62a --- /dev/null +++ b/scm-ui-components/packages/ui-components/src/LinkPaginator.js @@ -0,0 +1,129 @@ +//@flow +import React from "react"; +import {translate} from "react-i18next"; +import type {PagedCollection} from "@scm-manager/ui-types"; +import {Button} from "./buttons"; +import {withRouter} from "react-router-dom"; + +type Props = { + collection: PagedCollection, + t: string => string, + match: any +}; + +class LinkPaginator extends React.Component { + renderFirstButton() { + return ( +
    @@ -131,7 +138,7 @@ class RepositoryRoot extends React.Component { diff --git a/scm-ui/src/repos/modules/branches.js b/scm-ui/src/repos/modules/branches.js index 6e0ca52d5c..2a4580e194 100644 --- a/scm-ui/src/repos/modules/branches.js +++ b/scm-ui/src/repos/modules/branches.js @@ -1,8 +1,13 @@ // @flow -import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; -import {apiClient} from "@scm-manager/ui-components"; -import type {Action, Branch, Repository} from "@scm-manager/ui-types"; -import {isPending} from "../../modules/pending"; +import { + FAILURE_SUFFIX, + PENDING_SUFFIX, + SUCCESS_SUFFIX +} from "../../modules/types"; +import { apiClient } from "@scm-manager/ui-components"; +import type { Action, Branch, Repository } from "@scm-manager/ui-types"; +import { isPending } from "../../modules/pending"; +import { getFailure } from "../../modules/failure"; export const FETCH_BRANCHES = "scm/repos/FETCH_BRANCHES"; export const FETCH_BRANCHES_PENDING = `${FETCH_BRANCHES}_${PENDING_SUFFIX}`; @@ -128,7 +133,7 @@ export function getBranch( state: Object, repository: Repository, name: string -): Branch { +): ?Branch { const key = createKey(repository); if (state.branches[key]) { if (state.branches[key].byNames[name]) { @@ -145,6 +150,10 @@ export function isFetchBranchesPending( return isPending(state, FETCH_BRANCHES, createKey(repository)); } +export function getFetchBranchesFailure(state: Object, repository: Repository) { + return getFailure(state, FETCH_BRANCHES, createKey(repository)); +} + function createKey(repository: Repository): string { const { namespace, name } = repository; return `${namespace}/${name}`; diff --git a/scm-ui/src/repos/modules/branches.test.js b/scm-ui/src/repos/modules/branches.test.js index d9ade07d40..c958f105ef 100644 --- a/scm-ui/src/repos/modules/branches.test.js +++ b/scm-ui/src/repos/modules/branches.test.js @@ -10,6 +10,7 @@ import reducer, { getBranch, getBranches, getBranchNames, + getFetchBranchesFailure, isFetchBranchesPending } from "./branches"; @@ -129,6 +130,8 @@ describe("branches", () => { }); describe("branch selectors", () => { + const error = new Error("Something went wrong"); + const state = { branches: { [key]: { @@ -173,5 +176,18 @@ describe("branches", () => { const branch = getBranch(state, repository, "branch42"); expect(branch).toBeFalsy(); }); + it("should return error if fetching branches failed", () => { + const state = { + failure: { + [FETCH_BRANCHES + "/foo/bar"]: error + } + }; + + expect(getFetchBranchesFailure(state, repository)).toEqual(error); + }); + + it("should return false if fetching branches did not fail", () => { + expect(getFetchBranchesFailure({}, repository)).toBeUndefined(); + }); }); }); diff --git a/scm-ui/src/repos/modules/changesets.js b/scm-ui/src/repos/modules/changesets.js index e7e7601196..191de7b37d 100644 --- a/scm-ui/src/repos/modules/changesets.js +++ b/scm-ui/src/repos/modules/changesets.js @@ -1,21 +1,11 @@ // @flow -import { - FAILURE_SUFFIX, - PENDING_SUFFIX, - SUCCESS_SUFFIX -} from "../../modules/types"; -import { apiClient } from "@scm-manager/ui-components"; -import { isPending } from "../../modules/pending"; -import { getFailure } from "../../modules/failure"; -import { combineReducers } from "redux"; -import type { - Action, - Changeset, - PagedCollection, - Repository, - Branch -} from "@scm-manager/ui-types"; +import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types"; +import {apiClient} from "@scm-manager/ui-components"; +import {isPending} from "../../modules/pending"; +import {getFailure} from "../../modules/failure"; +import {combineReducers} from "redux"; +import type {Action, Branch, Changeset, PagedCollection, Repository} from "@scm-manager/ui-types"; export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS"; export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`; @@ -82,7 +72,6 @@ export function fetchChangesetsByPage(repository: Repository, page: number) { return fetchChangesetsWithOptions(repository, undefined, `?page=${page - 1}`); } -// TODO: Rewrite code to fetch changesets by branches, adjust tests and let BranchChooser fetch branches export function fetchChangesetsByBranchAndPage( repository: Repository, branch: Branch, @@ -167,11 +156,11 @@ function byKeyReducer( if (state[key]) { oldChangesets[key] = state[key]; } - const byIds = extractChangesetsByIds(changesets, oldChangesets[key].byId); + const byIds = extractChangesetsByIds(changesets); return { ...state, [key]: { - byId: { ...byIds }, + byId: byIds, list: { entries: changesetIds, entry: { @@ -191,17 +180,13 @@ export default combineReducers({ byKey: byKeyReducer }); -function extractChangesetsByIds(changesets: any, oldChangesetsByIds: any) { +function extractChangesetsByIds(changesets: any) { const changesetsByIds = {}; for (let changeset of changesets) { changesetsByIds[changeset.id] = changeset; } - for (let id in oldChangesetsByIds) { - changesetsByIds[id] = oldChangesetsByIds[id]; - } - return changesetsByIds; } @@ -234,16 +219,20 @@ export function getFetchChangesetsFailure( return getFailure(state, FETCH_CHANGESETS, createItemId(repository, branch)); } -const selectList = (state: Object, repository: Repository) => { - const itemId = createItemId(repository); +const selectList = (state: Object, repository: Repository, branch?: Branch) => { + const itemId = createItemId(repository, branch); if (state.changesets.byKey[itemId] && state.changesets.byKey[itemId].list) { return state.changesets.byKey[itemId].list; } return {}; }; -const selectListEntry = (state: Object, repository: Repository): Object => { - const list = selectList(state, repository); +const selectListEntry = ( + state: Object, + repository: Repository, + branch?: Branch +): Object => { + const list = selectList(state, repository, branch); if (list.entry) { return list.entry; } @@ -252,9 +241,10 @@ const selectListEntry = (state: Object, repository: Repository): Object => { export const selectListAsCollection = ( state: Object, - repository: Repository + repository: Repository, + branch?: Branch ): PagedCollection => { - return selectListEntry(state, repository); + return selectListEntry(state, repository, branch); }; export function getChangesetsFromState(state: Object, repository: Repository) { diff --git a/scm-ui/src/repos/modules/changesets.test.js b/scm-ui/src/repos/modules/changesets.test.js index 6a557cf1ac..fd33efbc7b 100644 --- a/scm-ui/src/repos/modules/changesets.test.js +++ b/scm-ui/src/repos/modules/changesets.test.js @@ -3,21 +3,21 @@ import configureMockStore from "redux-mock-store"; import thunk from "redux-thunk"; import fetchMock from "fetch-mock"; -import { +import reducer, { FETCH_CHANGESETS, FETCH_CHANGESETS_FAILURE, FETCH_CHANGESETS_PENDING, FETCH_CHANGESETS_SUCCESS, fetchChangesets, - fetchChangesetsByBranchAndPage, fetchChangesetsByBranch, + fetchChangesetsByBranchAndPage, fetchChangesetsByPage, fetchChangesetsSuccess, getChangesets, getFetchChangesetsFailure, isFetchChangesetsPending } from "./changesets"; -import reducer from "./changesets"; + const branch = { name: "specific", revision: "123", @@ -40,7 +40,10 @@ const repository = { changesets: { href: "http://scm/api/rest/v2/repositories/foo/bar/changesets" }, - branches: [branch] + branches: { + href: + "http://scm/api/rest/v2/repositories/foo/bar/branches/specific/branches" + } } }; @@ -238,38 +241,6 @@ describe("changesets", () => { entries: ["changeset1", "changeset2", "changeset3"] }); }); - - it("should not delete existing changesets from state", () => { - const responseBody = { - _embedded: { - changesets: [ - { id: "changeset1", author: { mail: "z@phod.com", name: "zaphod" } } - ], - _embedded: { - tags: [], - branches: [], - parents: [] - } - } - }; - const newState = reducer( - { - byKey: { - "foo/bar": { - byId: { - ["changeset2"]: { - id: "changeset2", - author: { mail: "mail@author.com", name: "author" } - } - } - } - } - }, - fetchChangesetsSuccess(responseBody, repository) - ); - expect(newState.byKey["foo/bar"].byId["changeset2"]).toBeDefined(); - expect(newState.byKey["foo/bar"].byId["changeset1"]).toBeDefined(); - }); }); describe("changeset selectors", () => { From 4e3e0637a4c70f7832c526400aee481cde54f5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maren=20S=C3=BCwer?= Date: Thu, 11 Oct 2018 14:16:34 +0200 Subject: [PATCH 085/121] add table header line for delete button --- scm-ui/src/repos/permissions/containers/Permissions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scm-ui/src/repos/permissions/containers/Permissions.js b/scm-ui/src/repos/permissions/containers/Permissions.js index d29359ed0b..e70e02f443 100644 --- a/scm-ui/src/repos/permissions/containers/Permissions.js +++ b/scm-ui/src/repos/permissions/containers/Permissions.js @@ -121,6 +121,7 @@ class Permissions extends React.Component { {t("permission.group-permission")} {t("permission.type")} + From 2de0287bf9cbc1fd6327b5a6bed4dec9f584e9fc Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 11 Oct 2018 17:29:50 +0200 Subject: [PATCH 086/121] Bootstrapped BranchRoot --- .../ui-components/src/LinkPaginator.js | 2 + .../ui-components/src/buttons/Button.js | 30 ++++---- scm-ui/public/locales/en/repos.json | 9 ++- scm-ui/src/repos/containers/BranchChooser.js | 77 ++++++++++++------- scm-ui/src/repos/containers/BranchRoot.js | 63 +++++++++++++++ scm-ui/src/repos/containers/Changesets.js | 13 ++-- scm-ui/src/repos/containers/RepositoryRoot.js | 54 +++++-------- 7 files changed, 163 insertions(+), 85 deletions(-) create mode 100644 scm-ui/src/repos/containers/BranchRoot.js diff --git a/scm-ui-components/packages/ui-components/src/LinkPaginator.js b/scm-ui-components/packages/ui-components/src/LinkPaginator.js index 75e53df62a..4e21033f93 100644 --- a/scm-ui-components/packages/ui-components/src/LinkPaginator.js +++ b/scm-ui-components/packages/ui-components/src/LinkPaginator.js @@ -12,6 +12,8 @@ type Props = { }; class LinkPaginator extends React.Component { + //TODO: HATEOAS-Links verwenden + renderFirstButton() { return (