From 94cacc21271ad6899481af43721caa7196a846e0 Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Thu, 10 May 2018 20:37:34 -0400 Subject: [PATCH 01/10] Use Lerna (#209) * Prep the repo for separately developed components * Fix uberinternal yarn.lock issues * Upgrade react to 16.3.2 * Update readme to account for on Lerna changes Signed-off-by: Joe Farro Directed graph layout and presentation (#212) * Prep the repo for separately developed components Signed-off-by: Joe Farro * WIP - Very rough graph layout functionality Signed-off-by: Joe Farro * Graph layout functionality is in solid shape Outstanding: * tests * calculate edges via several workers when there are many edges Signed-off-by: Joe Farro * Fix minor misc issues with plexus layout Signed-off-by: Joe Farro * Fix uberinternal yarn.lock issues Signed-off-by: Joe Farro * Fix uberinternal yarn.lock issues Signed-off-by: Joe Farro * Upgrade react to 16.3.2 Signed-off-by: Joe Farro * Upgrade flow to 0.71.0 Signed-off-by: Joe Farro * Very rough React graph component Signed-off-by: Joe Farro * Enable custom props for graph elements Signed-off-by: Joe Farro * The graph refreshes when it gets new data Signed-off-by: Joe Farro * Make the jaeger-ui package private Signed-off-by: Joe Farro * Misc cleanup for plexus package.json Signed-off-by: Joe Farro * Fix issues with plexus package.json Signed-off-by: Joe Farro * Don't output a CSS file for plexus Signed-off-by: Joe Farro * Increase plexus node spacing for neato layouts Signed-off-by: Joe Farro * Update plexus to 0.0.1-dev.2 Signed-off-by: Joe Farro * Adding new issue and pull request template (#219) Signed-off-by: Prakriti * plexus readme, remove `LayoutManager.dispose()` Signed-off-by: Joe Farro * remove unecessary package Signed-off-by: Joe Farro * Add more complex graphs to plexus demo Signed-off-by: Joe Farro * Start the worker ID at 0 Signed-off-by: Joe Farro Search page functionality for trace diffs Signed-off-by: Joe Farro Stub for trace diff page, update redux state shape - Better redux state shape for trace diff - Refer to traces selected for comparison as trace diff cohort - Better redux state shape for fetched trace data - Before: One loading prop to keep track of all search and individual trace fetching - After: Loading is tracked separately for serach and for each individual trace being fetched - This is better all around and lays the ground-work for fetching multiple individual traces which will be necessary for trace diff page when hit directly via URL (will need to fetch two or more traces) Signed-off-by: Joe Farro Optimization for trace mini-map rendering On a trace with ~16k spans reduced minimap rendering from ~250ms to ~20ms. For context, the initial render of the trace was around 1.22s. Signed-off-by: Joe Farro Redux cleanup, hydrate diff cohort on search page - Merge TraceSummary into Trace - Redux action to fetch multiple traces by ID - Create a small-sized variation of the loading indicator - SearchTracePage loads trace data for traces in the diff cohort - Show loading indicator when trace data is being loaded - Show inline error when trace loading fails - Strip failed traces from diff cohort when linking to diff page - Diff page forces redux state based on URL params Signed-off-by: Joe Farro Trace diff page header functionality - Fetch traces that need to be loaded - Keep the URL and redux state in sync after changes to A or B - Allow entering traces by ID - Allow selecting other traces in the cohort - Indicate when loading a trace failed Signed-off-by: Joe Farro Convert trace to a DAG Apply three transforms to spans when converting to DAG: - Adopt peer.service for service name when a client span is missing the corresponding server span - Ignore client spans when the only child is a reasonable server span - Try to figure out a better operation name when operation === the http.method tag The conversion can be optimized; it takes about 230ms on a trace with ~35k spans. A trace with ~9k spans takes about 50ms. Signed-off-by: Joe Farro Add useDotEdges and totalMemory options to plexus - Option in plexus to set the totalMemory viz.js uses - Sometimes viz.js runs out of memory on large graphs, especially when using the neato engine, increasing the total memeory can help - Option in plexus to use dot edges in plexus graphs - Useful for trees (neato and plexus are very similar) or large graphs (neato is too slow) Signed-off-by: Joe Farro Initial trace diff graph - Ability to create diff of two TraceDag instances - Additional transforms to trim superfluous nodes - skipAnnotationSpans - skipClientSpans Signed-off-by: Joe Farro Add zoom and pan to plexus - Zoom and pan - Add graph state as param to setOn* props - Enable scaling edge stroke based on zoom level Signed-off-by: Joe Farro Add zoom to trace diff and increase color contrast - Add zoom pan to trace diff - On node hover show node @ 1x zoom (useful when zoomed out) - Higher contrast colors for trace diff DAG - Allowing scrolling for errors - Fix issue with node sizing during measurement phase Signed-off-by: Joe Farro Add a minimap to plexus to help zoom and pan Also added to trace-diffs Signed-off-by: Joe Farro Guard plexus zoom functionality with a flag Signed-off-by: Joe Farro Fixes and optimizations to plexus and trace diffs - Bug fix: Each graph should have a unique edge arrow def IRI - Keep strokes from scaling into invisibility when zooming - Remove redundant root node - Apply zoom transforms to the node and edge containers - Scale the arrow def based on the current zoom (when zoom is enabled) by scaling the coords in the marker and path definitions - Add a convenience prop-factory that toggles a class, "is-small", based on the current zoom level - Use "is-small" to toggle the visibility of node text and edge stroke width based on the current zoom level - Change prop factories to be grouped by feature instead of context - In many cases the prop factory can be applied to multiple contexts, e.g. to both the edges container and an edge path - Make Node and EdgePath components PureComponents - Wrap rendering the nodes and edges in a PureComponent to prevent unnecessary renders - Remove DirectedGraphState from the edge and node factory prop functions to prevent rendering with every transform change Signed-off-by: Joe Farro Add additional layout options to plexus Signed-off-by: Joe Farro Lighten trace diff color scheme Signed-off-by: Joe Farro Use green instead of blue in trace diff coloring Green is more commonly used to show additions Signed-off-by: Joe Farro Add "Compare" to the top nav and other small fixes Signed-off-by: Joe Farro Adding new issue and pull request template (#219) Signed-off-by: Prakriti Integrate Google Analytics into Search Page (#220) * Integrate GA into search page Signed-off-by: Davit Yeghshatyan * Review changes Signed-off-by: Davit Yeghshatyan * Remove tracking of actual values Signed-off-by: Davit Yeghshatyan Timeline Expand and Collapse Features (#221) * Add expansion and collapsing features Signed-off-by: Davit Yeghshatyan * Use Icon component Signed-off-by: Davit Yeghshatyan * Use spans upstream Signed-off-by: Davit Yeghshatyan * Improve css Signed-off-by: Davit Yeghshatyan * Rotate collapse buttons Signed-off-by: Davit Yeghshatyan * Remove debug logging Signed-off-by: Davit Yeghshatyan * Remove spans from TimelineHeaderRow Signed-off-by: Davit Yeghshatyan * Add unit test for TimelineCollapser Signed-off-by: Davit Yeghshatyan * Use popover Signed-off-by: Davit Yeghshatyan * Add TimelineCollapser test Signed-off-by: Davit Yeghshatyan * Revert "Use popover" This reverts commit 6152402 Signed-off-by: Davit Yeghshatyan * Add tests for duck.js Signed-off-by: Davit Yeghshatyan * Add more tests for duck.js Signed-off-by: Davit Yeghshatyan * Add more tests for index.js Signed-off-by: Davit Yeghshatyan * Add keyboard shortcuts Signed-off-by: Davit Yeghshatyan * Update changelog Signed-off-by: Davit Yeghshatyan * Make review changes Signed-off-by: Davit Yeghshatyan Squashed commits from develop-directed-graph (#224) Signed-off-by: Joe Farro Lazily initialize the first worker in plexus Signed-off-by: Joe Farro Fix issue with trace diff URL from auth redirects The trace diff url was of the form: /trace/:diff?b= But, during OneLogin / SAML auth redirects it would get URL encoded and then not URL decoded resulting in it being interpreted as a trace ID. Move to the following form with three literal periods between the IDs: /trace/... Other misc fixes and tweaks: - Fix an issue where selecting a cohort of traces and then clicking the "Compare" button in the top nav cleared the cohort - Fix an issue where removing a trace from the cohort on the search page would not clear the trace from A or B, effectively preventing traces set as A or B from ever being removed - Clean up route definitions Signed-off-by: Joe Farro Fix trace detail tracking for revised redux shape Signed-off-by: Joe Farro --- .flowconfig | 12 +- .github/PULL_REQUEST_TEMPLATE.md | 18 + .github/issue_template.md | 47 +- .gitignore | 3 + .travis.yml | 12 +- CHANGELOG.md | 4 + README.md | 26 +- lerna.json | 7 + package.json | 111 +- .../jaeger-ui/config-overrides-antd-vars.less | 3 + .../jaeger-ui/config-overrides.js | 0 packages/jaeger-ui/package.json | 96 + .../jaeger-ui/public}/favicon.ico | Bin .../jaeger-ui/public}/index.html | 0 .../jaeger-ui/src}/actions/jaeger-api.js | 6 + .../jaeger-ui/src}/actions/jaeger-api.test.js | 0 {src => packages/jaeger-ui/src}/api/jaeger.js | 0 .../jaeger-ui/src}/api/jaeger.test.js | 0 .../jaeger-ui/src}/components/App/NotFound.js | 0 .../jaeger-ui/src}/components/App/Page.css | 0 .../jaeger-ui/src}/components/App/Page.js | 33 +- .../src}/components/App/Page.test.js | 27 +- .../jaeger-ui/src}/components/App/TopNav.js | 71 +- .../src}/components/App/TopNav.test.js | 27 +- .../components/App/TraceIDSearchInput.css | 0 .../src}/components/App/TraceIDSearchInput.js | 0 .../jaeger-ui/src}/components/App/index.css | 0 .../jaeger-ui/src}/components/App/index.js | 26 +- .../src}/components/App/index.test.js | 0 .../src}/components/DependencyGraph/DAG.js | 0 .../components/DependencyGraph/DAG.test.js | 0 .../DependencyGraph/DependencyForceGraph.js | 0 .../DependencyForceGraph.test.js | 0 .../src}/components/DependencyGraph/index.css | 0 .../src}/components/DependencyGraph/index.js | 5 +- .../components/DependencyGraph/index.test.js | 7 +- .../src/components/DependencyGraph/url.js | 31 + .../components/SearchTracePage/SearchForm.css | 0 .../components/SearchTracePage/SearchForm.js | 350 +- .../SearchTracePage/SearchForm.markers.js | 0 .../SearchTracePage/SearchForm.test.js | 0 .../SearchTracePage/SearchForm.track.js | 57 + .../SearchTracePage/SearchForm.track.test.js | 56 + .../SearchResults/DiffSelection.css | 34 + .../SearchResults/DiffSelection.js | 82 + .../SearchResults/ResultItem.css | 19 - .../SearchResults/ResultItem.js | 106 + .../SearchResults/ResultItem.markers.js | 0 .../SearchResults/ResultItem.test.js | 32 +- .../SearchResults/ResultItemTitle.css | 63 + .../SearchResults/ResultItemTitle.js | 94 + .../SearchResults/ScatterPlot.css | 0 .../SearchResults/ScatterPlot.js | 0 .../SearchResults/ScatterPlot.test.js | 0 .../SearchTracePage/SearchResults/index.css | 0 .../SearchTracePage/SearchResults/index.js | 64 +- .../SearchResults/index.markers.js | 0 .../SearchResults/index.test.js | 3 +- .../SearchResults/react-vis.css | 1 + .../src}/components/SearchTracePage/index.css | 0 .../src}/components/SearchTracePage/index.js | 79 +- .../components/SearchTracePage/index.test.js | 28 +- .../src/components/SearchTracePage/url.js | 33 + .../src/components/TraceDiff/TraceDiff.css | 24 + .../src/components/TraceDiff/TraceDiff.js | 185 + .../TraceDiffGraph/TraceDiffGraph.css | 92 + .../TraceDiffGraph/TraceDiffGraph.js | 118 + .../TraceDiff/TraceDiffGraph/drawNode.css | 96 + .../TraceDiff/TraceDiffGraph/drawNode.js | 87 + .../TraceDiff/TraceDiffGraph}/index.js | 5 +- .../TraceDiff/TraceDiffHeader/CohortTable.css | 24 + .../TraceDiff/TraceDiffHeader/CohortTable.js | 135 + .../TraceDiffHeader/TraceDiffHeader.css | 47 + .../TraceDiffHeader/TraceDiffHeader.js | 145 + .../TraceDiff/TraceDiffHeader/TraceHeader.css | 60 + .../TraceDiff/TraceDiffHeader/TraceHeader.js | 105 + .../TraceDiff/TraceDiffHeader/TraceIdInput.js | 29 + .../TraceDiff/TraceDiffHeader/index.js | 17 + .../src/components/TraceDiff/duck.js | 99 + .../src/components/TraceDiff/getValidState.js | 24 + .../src/components/TraceDiff/index.js | 17 + .../jaeger-ui/src/components/TraceDiff/url.js | 35 + .../TracePage/ArchiveNotifier/duck.js | 0 .../TracePage/ArchiveNotifier/index.css | 0 .../TracePage/ArchiveNotifier/index.js | 0 .../TracePage/KeyboardShortcutsHelp.css | 0 .../TracePage/KeyboardShortcutsHelp.js | 4 + .../TracePage/KeyboardShortcutsHelp.track.js | 0 .../components/TracePage/ScrollManager.js | 2 +- .../TracePage/ScrollManager.test.js | 0 .../TracePage/SpanGraph/CanvasSpanGraph.css | 0 .../TracePage/SpanGraph/CanvasSpanGraph.js | 0 .../SpanGraph/CanvasSpanGraph.test.js | 0 .../TracePage/SpanGraph/GraphTicks.css | 0 .../TracePage/SpanGraph/GraphTicks.js | 0 .../TracePage/SpanGraph/GraphTicks.test.js | 0 .../TracePage/SpanGraph/Scrubber.css | 0 .../TracePage/SpanGraph/Scrubber.js | 0 .../TracePage/SpanGraph/Scrubber.test.js | 0 .../TracePage/SpanGraph/TickLabels.css | 0 .../TracePage/SpanGraph/TickLabels.js | 0 .../TracePage/SpanGraph/TickLabels.test.js | 0 .../TracePage/SpanGraph/ViewingLayer.css | 0 .../TracePage/SpanGraph/ViewingLayer.js | 0 .../TracePage/SpanGraph/ViewingLayer.test.js | 0 .../components/TracePage/SpanGraph/index.js | 2 +- .../TracePage/SpanGraph/index.test.js | 0 .../TracePage/SpanGraph/render-into-canvas.js | 14 +- .../SpanGraph/render-into-canvas.test.js | 0 .../components/TracePage/TracePageHeader.css | 0 .../components/TracePage/TracePageHeader.js | 0 .../TracePage/TracePageHeader.markers.js | 0 .../TracePage/TracePageHeader.test.js | 0 .../TracePage/TracePageHeader.track.js | 0 .../TraceTimelineViewer/ListView/Positions.js | 0 .../ListView/Positions.test.js | 0 .../ListView/__snapshots__/index.test.js.snap | 0 .../TraceTimelineViewer/ListView/index.js | 0 .../ListView/index.test.js | 0 .../TracePage/TraceTimelineViewer/SpanBar.css | 0 .../TracePage/TraceTimelineViewer/SpanBar.js | 0 .../TraceTimelineViewer/SpanBar.test.js | 0 .../TraceTimelineViewer/SpanBarRow.css | 0 .../TraceTimelineViewer/SpanBarRow.js | 0 .../TraceTimelineViewer/SpanBarRow.test.js | 0 .../SpanDetail/AccordianKeyValues.css | 0 .../SpanDetail/AccordianKeyValues.js | 0 .../SpanDetail/AccordianKeyValues.markers.js | 0 .../SpanDetail/AccordianKeyValues.test.js | 0 .../SpanDetail/AccordianLogs.css | 0 .../SpanDetail/AccordianLogs.js | 3 +- .../SpanDetail/AccordianLogs.test.js | 0 .../SpanDetail/DetailState.js | 2 +- .../SpanDetail/KeyValuesTable.css | 0 .../SpanDetail/KeyValuesTable.js | 0 .../SpanDetail/KeyValuesTable.test.js | 0 .../TraceTimelineViewer/SpanDetail/index.css | 0 .../TraceTimelineViewer/SpanDetail/index.js | 2 +- .../SpanDetail/index.test.js | 0 .../TraceTimelineViewer/SpanDetailRow.css | 0 .../TraceTimelineViewer/SpanDetailRow.js | 2 +- .../TraceTimelineViewer/SpanDetailRow.test.js | 0 .../TraceTimelineViewer/SpanTreeOffset.css | 0 .../TraceTimelineViewer/SpanTreeOffset.js | 0 .../TracePage/TraceTimelineViewer/Ticks.css | 0 .../TracePage/TraceTimelineViewer/Ticks.js | 0 .../TraceTimelineViewer/Ticks.test.js | 0 .../TimelineHeaderRow/TimelineCollapser.css | 30 + .../TimelineHeaderRow/TimelineCollapser.js | 48 + .../TimelineCollapser.test.js | 32 + .../TimelineColumnResizer.css | 0 .../TimelineColumnResizer.js | 0 .../TimelineColumnResizer.test.js | 0 .../TimelineHeaderRow/TimelineHeaderRow.css | 3 +- .../TimelineHeaderRow/TimelineHeaderRow.js | 15 + .../TimelineHeaderRow.test.js | 17 + .../TimelineViewingLayer.css | 0 .../TimelineHeaderRow/TimelineViewingLayer.js | 0 .../TimelineViewingLayer.test.js | 0 .../TimelineHeaderRow/index.js | 0 .../TraceTimelineViewer/TimelineRow.css | 0 .../TraceTimelineViewer/TimelineRow.js | 0 .../VirtualizedTraceView.css | 0 .../VirtualizedTraceView.js | 2 +- .../VirtualizedTraceView.test.js | 0 .../TracePage/TraceTimelineViewer/duck.js | 76 + .../TraceTimelineViewer/duck.test.js | 106 +- .../TraceTimelineViewer/duck.track.js | 3 +- .../TraceTimelineViewer/duck.track.test.js | 5 +- .../TraceTimelineViewer/get-filtered-spans.js | 0 .../TracePage/TraceTimelineViewer/grid.css | 0 .../TracePage/TraceTimelineViewer/index.css | 0 .../TracePage/TraceTimelineViewer/index.js | 127 + .../TraceTimelineViewer/index.test.js | 26 +- .../TracePage/TraceTimelineViewer/utils.js | 0 .../TraceTimelineViewer/utils.test.js | 0 .../src}/components/TracePage/Tween.js | 0 .../src}/components/TracePage/Tween.test.js | 0 .../src}/components/TracePage/index.css | 0 .../src}/components/TracePage/index.js | 64 +- .../src}/components/TracePage/index.test.js | 25 +- .../src}/components/TracePage/index.track.js | 0 .../components/TracePage/index.track.test.js | 0 .../TracePage/keyboard-shortcuts.js | 45 +- .../src}/components/TracePage/scroll-page.js | 0 .../components/TracePage/scroll-page.test.js | 0 .../src}/components/TracePage/types.js | 0 .../jaeger-ui/src/components/TracePage/url.js | 23 + .../src/components/common/BreakableText.css | 20 + .../src/components/common/BreakableText.js | 51 + .../src}/components/common/ErrorMessage.css | 0 .../src}/components/common/ErrorMessage.js | 35 +- .../components/common/ErrorMessage.test.js | 0 .../src}/components/common/LabeledList.css | 0 .../src}/components/common/LabeledList.js | 0 .../components/common/LoadingIndicator.css | 6 +- .../components/common/LoadingIndicator.js | 11 +- .../src/components/common/RelativeDate.js | 33 + .../src/components/common/TraceName.css | 19 + .../src/components/common/TraceName.js | 63 + .../src}/components/common/VirtSelect.css | 0 .../src}/components/common/VirtSelect.js | 0 .../src}/components/common/utils.css | 19 +- .../src}/constants/default-config.js | 0 packages/jaeger-ui/src/constants/index.js | 30 + .../jaeger-ui/src/constants/search-form.js | 19 + packages/jaeger-ui/src/constants/tag-keys.js | 19 + .../jaeger-ui/src}/demo/.eslintrc | 0 .../src}/demo/dependency-generators.js | 0 .../jaeger-ui/src}/demo/jaeger-mock.js | 0 .../jaeger-ui/src}/demo/trace-generators.js | 0 .../jaeger-ui/src}/img/jaeger-logo.svg | 0 {src => packages/jaeger-ui/src}/index.js | 0 .../jaeger-ui/src}/middlewares/index.js | 5 +- .../jaeger-ui/src}/middlewares/index.test.js | 0 .../jaeger-ui/src}/middlewares/track.js | 5 +- .../jaeger-ui/src}/model/order-by.js | 0 packages/jaeger-ui/src/model/search.js | 38 + packages/jaeger-ui/src/model/search.test.js | 51 + .../jaeger-ui/src/model/trace-dag/DagNode.js | 42 + .../src/model/trace-dag/DenseTrace.js | 90 + .../jaeger-ui/src/model/trace-dag/TraceDag.js | 106 + .../src/model/trace-dag/convPlexus.js | 48 + .../src/model/trace-dag/denseTransforms.js | 135 + .../jaeger-ui/src/model/trace-dag/types.js | 42 + .../jaeger-ui/src}/model/trace-viewer.js | 0 .../src}/model/transform-trace-data.js | 13 +- .../jaeger-ui/src}/propTypes/dependencies.js | 0 .../jaeger-ui/src}/reducers/config.js | 0 .../jaeger-ui/src}/reducers/dependencies.js | 0 .../src}/reducers/dependencies.test.js | 0 .../jaeger-ui/src}/reducers/index.js | 0 .../jaeger-ui/src}/reducers/services.js | 0 .../jaeger-ui/src}/reducers/services.test.js | 0 packages/jaeger-ui/src/reducers/trace.js | 132 + .../jaeger-ui/src}/reducers/trace.test.js | 49 +- .../jaeger-ui/src}/selectors/dependencies.js | 0 .../jaeger-ui/src}/selectors/process.js | 0 .../jaeger-ui/src}/selectors/process.test.js | 0 .../jaeger-ui/src}/selectors/span.js | 0 .../jaeger-ui/src}/selectors/span.test.js | 0 .../jaeger-ui/src}/selectors/trace.fixture.js | 0 .../jaeger-ui/src}/selectors/trace.js | 0 .../jaeger-ui/src}/selectors/trace.test.js | 0 {src => packages/jaeger-ui/src}/setupTests.js | 0 .../jaeger-ui/src}/site-prefix.js | 0 .../jaeger-ui/src}/types/api-error.js | 0 .../jaeger-ui/src}/types/archive.js | 0 .../jaeger-ui/src}/types/config.js | 0 packages/jaeger-ui/src/types/index.js | 60 + .../jaeger-ui/src}/types/search.js | 0 packages/jaeger-ui/src/types/trace-diff.js | 21 + .../jaeger-ui/src/types/trace-timeline.js | 25 + .../jaeger-ui/src/types/trace.js | 2 + .../DraggableManager/DraggableManager.js | 0 .../DraggableManager/DraggableManager.test.js | 0 .../src}/utils/DraggableManager/README.md | 0 .../DraggableManager/demo/DividerDemo.css | 0 .../DraggableManager/demo/DividerDemo.js | 0 .../demo/DraggableManagerDemo.css | 0 .../demo/DraggableManagerDemo.js | 0 .../DraggableManager/demo/RegionDemo.css | 0 .../utils/DraggableManager/demo/RegionDemo.js | 0 .../utils/DraggableManager/demo/demo-ux.gif | Bin .../src}/utils/DraggableManager/demo/index.js | 0 .../src}/utils/DraggableManager/index.js | 0 .../src}/utils/DraggableManager/types.js | 0 .../utils/DraggableManager/update-types.js | 0 .../jaeger-ui/src}/utils/TreeNode.js | 0 .../jaeger-ui/src}/utils/TreeNode.test.js | 0 .../jaeger-ui/src}/utils/color-generator.js | 0 .../src}/utils/color-generator.test.js | 0 .../jaeger-ui/src}/utils/config/get-config.js | 0 .../src}/utils/config/get-config.test.js | 0 .../src}/utils/config/process-deprecation.js | 0 .../utils/config/process-deprecation.test.js | 0 .../jaeger-ui/src}/utils/configure-store.js | 10 +- .../src}/utils/configure-store.test.js | 0 {src => packages/jaeger-ui/src}/utils/date.js | 7 +- .../src}/utils/generate-action-types.js | 0 .../src}/utils/get-last-xform-cacher.js | 0 .../src}/utils/get-last-xform-cacher.test.js | 0 .../jaeger-ui/src}/utils/number.js | 0 .../jaeger-ui/src}/utils/number.test.js | 0 .../jaeger-ui/src}/utils/prefix-url.js | 0 .../jaeger-ui/src}/utils/prefix-url.test.js | 0 .../src}/utils/redux-form-field-adapter.js | 0 .../jaeger-ui/src}/utils/regexp-escape.js | 0 .../src}/utils/regexp-escape.test.js | 0 {src => packages/jaeger-ui/src}/utils/sort.js | 0 .../jaeger-ui/src}/utils/sort.test.js | 0 .../src}/utils/test/requestAnimationFrame.js | 0 .../jaeger-ui/src}/utils/tracking/README.md | 0 .../jaeger-ui/src}/utils/tracking/common.js | 0 .../src}/utils/tracking/conv-raven-to-ga.js | 0 .../utils/tracking/conv-raven-to-ga.test.js | 0 .../jaeger-ui/src}/utils/tracking/fixtures.js | 0 .../jaeger-ui/src}/utils/tracking/index.js | 0 .../src}/utils/tracking/index.test.js | 0 packages/plexus/.gitignore | 4 + packages/plexus/README.md | 13 + packages/plexus/demo/src/data-dag.js | 98 + packages/plexus/demo/src/data-large.js | 498 ++ packages/plexus/demo/src/data-small.js | 84 + packages/plexus/demo/src/index.css | 75 + packages/plexus/demo/src/index.js | 122 + packages/plexus/nwb.config.js | 67 + packages/plexus/package.json | 34 + .../plexus/src/DirectedGraph/DirectedGraph.js | 341 ++ packages/plexus/src/DirectedGraph/MiniMap.js | 99 + .../src/DirectedGraph/builtins/EdgeArrow.js | 28 + .../DirectedGraph/builtins/EdgeArrowDef.js | 60 + .../src/DirectedGraph/builtins/EdgePath.js | 72 + .../DirectedGraph/builtins/EdgesContainer.js | 32 + .../plexus/src/DirectedGraph/builtins/Node.js | 60 + .../src/DirectedGraph/builtins/PureEdges.js | 43 + .../src/DirectedGraph/builtins/PureNodes.js | 75 + packages/plexus/src/DirectedGraph/index.js | 17 + .../prop-factories/classNameIsSmall.js | 27 + .../prop-factories/mergePropSetters.js | 42 + .../prop-factories/scaledStrokeWidth.js | 50 + .../plexus/src/DirectedGraph/resetZoomIcon.js | 29 + .../src/DirectedGraph/transform-utils.js | 90 + packages/plexus/src/DirectedGraph/types.js | 55 + .../plexus/src/LayoutManager/Coordinator.js | 251 + .../plexus/src/LayoutManager/LayoutManager.js | 128 + .../src/LayoutManager/dot/conv-coord.js | 61 + .../plexus/src/LayoutManager/dot/convPlain.js | 163 + .../plexus/src/LayoutManager/dot/toDot.js | 92 + .../plexus/src/LayoutManager/getLayout.js | 103 + packages/plexus/src/LayoutManager/index.js | 17 + .../plexus/src/LayoutManager/layout.worker.js | 47 + .../plexus/src/LayoutManager/match-inputs.js | 45 + packages/plexus/src/LayoutManager/types.js | 63 + packages/plexus/src/index.js | 22 + packages/plexus/src/input.fixture.js | 46 + packages/plexus/src/types/ErrorEvent.js | 23 + packages/plexus/src/types/layout.js | 94 + scripts/check-license.sh | 2 +- .../SearchResults/ResultItem.js | 91 - .../SearchResults/react-vis.css | 1 - .../TracePage/TraceTimelineViewer/index.js | 80 - src/model/search.js | 115 - src/model/search.test.js | 133 - src/reducers/trace.js | 69 - yarn.lock | 4018 ++++++++++++++++- 346 files changed, 11374 insertions(+), 1306 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 lerna.json rename config-overrides-antd-vars.less => packages/jaeger-ui/config-overrides-antd-vars.less (94%) rename config-overrides.js => packages/jaeger-ui/config-overrides.js (100%) create mode 100644 packages/jaeger-ui/package.json rename {public => packages/jaeger-ui/public}/favicon.ico (100%) rename {public => packages/jaeger-ui/public}/index.html (100%) rename {src => packages/jaeger-ui/src}/actions/jaeger-api.js (90%) rename {src => packages/jaeger-ui/src}/actions/jaeger-api.test.js (100%) rename {src => packages/jaeger-ui/src}/api/jaeger.js (100%) rename {src => packages/jaeger-ui/src}/api/jaeger.test.js (100%) rename {src => packages/jaeger-ui/src}/components/App/NotFound.js (100%) rename {src => packages/jaeger-ui/src}/components/App/Page.css (100%) rename {src => packages/jaeger-ui/src}/components/App/Page.js (66%) rename {src => packages/jaeger-ui/src}/components/App/Page.test.js (70%) rename {src => packages/jaeger-ui/src}/components/App/TopNav.js (58%) rename {src => packages/jaeger-ui/src}/components/App/TopNav.test.js (87%) rename {src => packages/jaeger-ui/src}/components/App/TraceIDSearchInput.css (100%) rename {src => packages/jaeger-ui/src}/components/App/TraceIDSearchInput.js (100%) rename {src => packages/jaeger-ui/src}/components/App/index.css (100%) rename {src => packages/jaeger-ui/src}/components/App/index.js (64%) rename {src => packages/jaeger-ui/src}/components/App/index.test.js (100%) rename {src => packages/jaeger-ui/src}/components/DependencyGraph/DAG.js (100%) rename {src => packages/jaeger-ui/src}/components/DependencyGraph/DAG.test.js (100%) rename {src => packages/jaeger-ui/src}/components/DependencyGraph/DependencyForceGraph.js (100%) rename {src => packages/jaeger-ui/src}/components/DependencyGraph/DependencyForceGraph.test.js (100%) rename {src => packages/jaeger-ui/src}/components/DependencyGraph/index.css (100%) rename {src => packages/jaeger-ui/src}/components/DependencyGraph/index.js (96%) rename {src => packages/jaeger-ui/src}/components/DependencyGraph/index.test.js (96%) create mode 100644 packages/jaeger-ui/src/components/DependencyGraph/url.js rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchForm.css (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchForm.js (58%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchForm.markers.js (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchForm.test.js (100%) create mode 100644 packages/jaeger-ui/src/components/SearchTracePage/SearchForm.track.js create mode 100644 packages/jaeger-ui/src/components/SearchTracePage/SearchForm.track.test.js create mode 100644 packages/jaeger-ui/src/components/SearchTracePage/SearchResults/DiffSelection.css create mode 100644 packages/jaeger-ui/src/components/SearchTracePage/SearchResults/DiffSelection.js rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/ResultItem.css (71%) create mode 100644 packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.js rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/ResultItem.markers.js (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/ResultItem.test.js (71%) create mode 100644 packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItemTitle.css create mode 100644 packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItemTitle.js rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/ScatterPlot.css (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/ScatterPlot.js (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/ScatterPlot.test.js (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/index.css (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/index.js (64%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/index.markers.js (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/SearchResults/index.test.js (98%) create mode 120000 packages/jaeger-ui/src/components/SearchTracePage/SearchResults/react-vis.css rename {src => packages/jaeger-ui/src}/components/SearchTracePage/index.css (100%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/index.js (71%) rename {src => packages/jaeger-ui/src}/components/SearchTracePage/index.test.js (82%) create mode 100644 packages/jaeger-ui/src/components/SearchTracePage/url.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiff.css create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiff.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/TraceDiffGraph.css create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/TraceDiffGraph.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/drawNode.css create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/drawNode.js rename {src/constants => packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph}/index.js (84%) create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/CohortTable.css create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/CohortTable.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceDiffHeader.css create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceDiffHeader.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceHeader.css create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceHeader.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceIdInput.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/index.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/duck.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/getValidState.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/index.js create mode 100644 packages/jaeger-ui/src/components/TraceDiff/url.js rename {src => packages/jaeger-ui/src}/components/TracePage/ArchiveNotifier/duck.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/ArchiveNotifier/index.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/ArchiveNotifier/index.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/KeyboardShortcutsHelp.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/KeyboardShortcutsHelp.js (95%) rename {src => packages/jaeger-ui/src}/components/TracePage/KeyboardShortcutsHelp.track.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/ScrollManager.js (99%) rename {src => packages/jaeger-ui/src}/components/TracePage/ScrollManager.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/CanvasSpanGraph.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/CanvasSpanGraph.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/CanvasSpanGraph.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/GraphTicks.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/GraphTicks.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/GraphTicks.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/Scrubber.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/Scrubber.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/Scrubber.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/TickLabels.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/TickLabels.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/TickLabels.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/ViewingLayer.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/ViewingLayer.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/ViewingLayer.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/index.js (98%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/index.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/render-into-canvas.js (85%) rename {src => packages/jaeger-ui/src}/components/TracePage/SpanGraph/render-into-canvas.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TracePageHeader.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TracePageHeader.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TracePageHeader.markers.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TracePageHeader.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TracePageHeader.track.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/ListView/Positions.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/ListView/Positions.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/ListView/__snapshots__/index.test.js.snap (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/ListView/index.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/ListView/index.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanBar.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanBar.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanBar.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanBarRow.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanBarRow.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanBarRow.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.markers.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.js (97%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/DetailState.js (97%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/index.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/index.js (98%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetail/index.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetailRow.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetailRow.js (97%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanDetailRow.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanTreeOffset.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/SpanTreeOffset.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/Ticks.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/Ticks.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/Ticks.test.js (100%) create mode 100644 packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.css create mode 100644 packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.js create mode 100644 packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.css (94%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.js (84%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.test.js (84%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/index.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineRow.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/TimelineRow.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.js (99%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/duck.js (68%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/duck.test.js (69%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/duck.track.js (96%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/duck.track.test.js (95%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/get-filtered-spans.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/grid.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/index.css (100%) create mode 100644 packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.js rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/index.test.js (57%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/utils.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/TraceTimelineViewer/utils.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/Tween.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/Tween.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/index.css (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/index.js (85%) rename {src => packages/jaeger-ui/src}/components/TracePage/index.test.js (94%) rename {src => packages/jaeger-ui/src}/components/TracePage/index.track.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/index.track.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/keyboard-shortcuts.js (63%) rename {src => packages/jaeger-ui/src}/components/TracePage/scroll-page.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/scroll-page.test.js (100%) rename {src => packages/jaeger-ui/src}/components/TracePage/types.js (100%) create mode 100644 packages/jaeger-ui/src/components/TracePage/url.js create mode 100644 packages/jaeger-ui/src/components/common/BreakableText.css create mode 100644 packages/jaeger-ui/src/components/common/BreakableText.js rename {src => packages/jaeger-ui/src}/components/common/ErrorMessage.css (100%) rename {src => packages/jaeger-ui/src}/components/common/ErrorMessage.js (70%) rename {src => packages/jaeger-ui/src}/components/common/ErrorMessage.test.js (100%) rename {src => packages/jaeger-ui/src}/components/common/LabeledList.css (100%) rename {src => packages/jaeger-ui/src}/components/common/LabeledList.js (100%) rename {src => packages/jaeger-ui/src}/components/common/LoadingIndicator.css (92%) rename {src => packages/jaeger-ui/src}/components/common/LoadingIndicator.js (81%) create mode 100644 packages/jaeger-ui/src/components/common/RelativeDate.js create mode 100644 packages/jaeger-ui/src/components/common/TraceName.css create mode 100644 packages/jaeger-ui/src/components/common/TraceName.js rename {src => packages/jaeger-ui/src}/components/common/VirtSelect.css (100%) rename {src => packages/jaeger-ui/src}/components/common/VirtSelect.js (100%) rename {src => packages/jaeger-ui/src}/components/common/utils.css (88%) rename {src => packages/jaeger-ui/src}/constants/default-config.js (100%) create mode 100644 packages/jaeger-ui/src/constants/index.js create mode 100644 packages/jaeger-ui/src/constants/search-form.js create mode 100644 packages/jaeger-ui/src/constants/tag-keys.js rename {src => packages/jaeger-ui/src}/demo/.eslintrc (100%) rename {src => packages/jaeger-ui/src}/demo/dependency-generators.js (100%) rename {src => packages/jaeger-ui/src}/demo/jaeger-mock.js (100%) rename {src => packages/jaeger-ui/src}/demo/trace-generators.js (100%) rename {src => packages/jaeger-ui/src}/img/jaeger-logo.svg (100%) rename {src => packages/jaeger-ui/src}/index.js (100%) rename {src => packages/jaeger-ui/src}/middlewares/index.js (90%) rename {src => packages/jaeger-ui/src}/middlewares/index.test.js (100%) rename {src => packages/jaeger-ui/src}/middlewares/track.js (79%) rename {src => packages/jaeger-ui/src}/model/order-by.js (100%) create mode 100644 packages/jaeger-ui/src/model/search.js create mode 100644 packages/jaeger-ui/src/model/search.test.js create mode 100644 packages/jaeger-ui/src/model/trace-dag/DagNode.js create mode 100644 packages/jaeger-ui/src/model/trace-dag/DenseTrace.js create mode 100644 packages/jaeger-ui/src/model/trace-dag/TraceDag.js create mode 100644 packages/jaeger-ui/src/model/trace-dag/convPlexus.js create mode 100644 packages/jaeger-ui/src/model/trace-dag/denseTransforms.js create mode 100644 packages/jaeger-ui/src/model/trace-dag/types.js rename {src => packages/jaeger-ui/src}/model/trace-viewer.js (100%) rename {src => packages/jaeger-ui/src}/model/transform-trace-data.js (89%) rename {src => packages/jaeger-ui/src}/propTypes/dependencies.js (100%) rename {src => packages/jaeger-ui/src}/reducers/config.js (100%) rename {src => packages/jaeger-ui/src}/reducers/dependencies.js (100%) rename {src => packages/jaeger-ui/src}/reducers/dependencies.test.js (100%) rename {src => packages/jaeger-ui/src}/reducers/index.js (100%) rename {src => packages/jaeger-ui/src}/reducers/services.js (100%) rename {src => packages/jaeger-ui/src}/reducers/services.test.js (100%) create mode 100644 packages/jaeger-ui/src/reducers/trace.js rename {src => packages/jaeger-ui/src}/reducers/trace.test.js (55%) rename {src => packages/jaeger-ui/src}/selectors/dependencies.js (100%) rename {src => packages/jaeger-ui/src}/selectors/process.js (100%) rename {src => packages/jaeger-ui/src}/selectors/process.test.js (100%) rename {src => packages/jaeger-ui/src}/selectors/span.js (100%) rename {src => packages/jaeger-ui/src}/selectors/span.test.js (100%) rename {src => packages/jaeger-ui/src}/selectors/trace.fixture.js (100%) rename {src => packages/jaeger-ui/src}/selectors/trace.js (100%) rename {src => packages/jaeger-ui/src}/selectors/trace.test.js (100%) rename {src => packages/jaeger-ui/src}/setupTests.js (100%) rename {src => packages/jaeger-ui/src}/site-prefix.js (100%) rename {src => packages/jaeger-ui/src}/types/api-error.js (100%) rename {src => packages/jaeger-ui/src}/types/archive.js (100%) rename {src => packages/jaeger-ui/src}/types/config.js (100%) create mode 100644 packages/jaeger-ui/src/types/index.js rename {src => packages/jaeger-ui/src}/types/search.js (100%) create mode 100644 packages/jaeger-ui/src/types/trace-diff.js create mode 100644 packages/jaeger-ui/src/types/trace-timeline.js rename src/types/index.js => packages/jaeger-ui/src/types/trace.js (95%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/DraggableManager.js (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/DraggableManager.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/README.md (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/demo/DividerDemo.css (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/demo/DividerDemo.js (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/demo/DraggableManagerDemo.css (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/demo/DraggableManagerDemo.js (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/demo/RegionDemo.css (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/demo/RegionDemo.js (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/demo/demo-ux.gif (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/demo/index.js (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/index.js (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/types.js (100%) rename {src => packages/jaeger-ui/src}/utils/DraggableManager/update-types.js (100%) rename {src => packages/jaeger-ui/src}/utils/TreeNode.js (100%) rename {src => packages/jaeger-ui/src}/utils/TreeNode.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/color-generator.js (100%) rename {src => packages/jaeger-ui/src}/utils/color-generator.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/config/get-config.js (100%) rename {src => packages/jaeger-ui/src}/utils/config/get-config.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/config/process-deprecation.js (100%) rename {src => packages/jaeger-ui/src}/utils/config/process-deprecation.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/configure-store.js (84%) rename {src => packages/jaeger-ui/src}/utils/configure-store.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/date.js (94%) rename {src => packages/jaeger-ui/src}/utils/generate-action-types.js (100%) rename {src => packages/jaeger-ui/src}/utils/get-last-xform-cacher.js (100%) rename {src => packages/jaeger-ui/src}/utils/get-last-xform-cacher.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/number.js (100%) rename {src => packages/jaeger-ui/src}/utils/number.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/prefix-url.js (100%) rename {src => packages/jaeger-ui/src}/utils/prefix-url.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/redux-form-field-adapter.js (100%) rename {src => packages/jaeger-ui/src}/utils/regexp-escape.js (100%) rename {src => packages/jaeger-ui/src}/utils/regexp-escape.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/sort.js (100%) rename {src => packages/jaeger-ui/src}/utils/sort.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/test/requestAnimationFrame.js (100%) rename {src => packages/jaeger-ui/src}/utils/tracking/README.md (100%) rename {src => packages/jaeger-ui/src}/utils/tracking/common.js (100%) rename {src => packages/jaeger-ui/src}/utils/tracking/conv-raven-to-ga.js (100%) rename {src => packages/jaeger-ui/src}/utils/tracking/conv-raven-to-ga.test.js (100%) rename {src => packages/jaeger-ui/src}/utils/tracking/fixtures.js (100%) rename {src => packages/jaeger-ui/src}/utils/tracking/index.js (100%) rename {src => packages/jaeger-ui/src}/utils/tracking/index.test.js (100%) create mode 100644 packages/plexus/.gitignore create mode 100644 packages/plexus/README.md create mode 100644 packages/plexus/demo/src/data-dag.js create mode 100644 packages/plexus/demo/src/data-large.js create mode 100644 packages/plexus/demo/src/data-small.js create mode 100644 packages/plexus/demo/src/index.css create mode 100644 packages/plexus/demo/src/index.js create mode 100644 packages/plexus/nwb.config.js create mode 100644 packages/plexus/package.json create mode 100644 packages/plexus/src/DirectedGraph/DirectedGraph.js create mode 100644 packages/plexus/src/DirectedGraph/MiniMap.js create mode 100644 packages/plexus/src/DirectedGraph/builtins/EdgeArrow.js create mode 100644 packages/plexus/src/DirectedGraph/builtins/EdgeArrowDef.js create mode 100644 packages/plexus/src/DirectedGraph/builtins/EdgePath.js create mode 100644 packages/plexus/src/DirectedGraph/builtins/EdgesContainer.js create mode 100644 packages/plexus/src/DirectedGraph/builtins/Node.js create mode 100644 packages/plexus/src/DirectedGraph/builtins/PureEdges.js create mode 100644 packages/plexus/src/DirectedGraph/builtins/PureNodes.js create mode 100644 packages/plexus/src/DirectedGraph/index.js create mode 100644 packages/plexus/src/DirectedGraph/prop-factories/classNameIsSmall.js create mode 100644 packages/plexus/src/DirectedGraph/prop-factories/mergePropSetters.js create mode 100644 packages/plexus/src/DirectedGraph/prop-factories/scaledStrokeWidth.js create mode 100644 packages/plexus/src/DirectedGraph/resetZoomIcon.js create mode 100644 packages/plexus/src/DirectedGraph/transform-utils.js create mode 100644 packages/plexus/src/DirectedGraph/types.js create mode 100644 packages/plexus/src/LayoutManager/Coordinator.js create mode 100644 packages/plexus/src/LayoutManager/LayoutManager.js create mode 100644 packages/plexus/src/LayoutManager/dot/conv-coord.js create mode 100644 packages/plexus/src/LayoutManager/dot/convPlain.js create mode 100644 packages/plexus/src/LayoutManager/dot/toDot.js create mode 100644 packages/plexus/src/LayoutManager/getLayout.js create mode 100644 packages/plexus/src/LayoutManager/index.js create mode 100644 packages/plexus/src/LayoutManager/layout.worker.js create mode 100644 packages/plexus/src/LayoutManager/match-inputs.js create mode 100644 packages/plexus/src/LayoutManager/types.js create mode 100644 packages/plexus/src/index.js create mode 100644 packages/plexus/src/input.fixture.js create mode 100644 packages/plexus/src/types/ErrorEvent.js create mode 100644 packages/plexus/src/types/layout.js delete mode 100644 src/components/SearchTracePage/SearchResults/ResultItem.js delete mode 120000 src/components/SearchTracePage/SearchResults/react-vis.css delete mode 100644 src/components/TracePage/TraceTimelineViewer/index.js delete mode 100644 src/model/search.js delete mode 100644 src/model/search.test.js delete mode 100644 src/reducers/trace.js diff --git a/.flowconfig b/.flowconfig index 1918d25cae..fa03d719ed 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,9 +1,9 @@ [ignore] -# node_module packages that have a .flowconfig in conflict with this file -/node_modules/uber-licence -/node_modules/redux-form -/node_modules/react-motion -/node_modules/draft-js +.*/node_modules/uber-licence/.* +.*/node_modules/redux-form/.* +.*/node_modules/react-motion/.* +.*/node_modules/draft-js/.* +.*/node_modules/nwb/.* [include] @@ -13,4 +13,4 @@ [options] [version] -0.64.0 +0.71.0 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..2564119ccb --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ + + +## Which problem is this PR solving? +- + +## Short description of the changes +- diff --git a/.github/issue_template.md b/.github/issue_template.md index 1795163e37..7a5851ba91 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,39 +1,28 @@ -**Description** +## Requirement - what kind of business use case are you trying to solve? - - -**Steps to reproduce the issue:** -1. -2. -3. - -**Describe the results you received:** + +## Problem - what in Jaeger blocks you from solving the requirement? -**Describe the results you expected:** + + +## Proposal - what do you suggest to solve the problem or improve the existing situation? -**Additional information you deem important (e.g. issue happens only occasionally):** + +## Any open questions to address -**Additional environment details (Browser, etc.):** + diff --git a/.gitignore b/.gitignore index d4a605e219..29cbb21930 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ coverage .DS_Store npm-debug.log .vscode +.idea +yarn-error.log +lerna-debug.log diff --git a/.travis.yml b/.travis.yml index 6514240380..3eca28fcf3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,11 @@ language: node_js node_js: - '6' -cache: - directories: - - node_modules +cache: yarn script: - - npm run lint - - npm run coverage - - npm run build + - yarn lint + - yarn coverage + - yarn build after_success: - - npm install -g codecov + - yarn global add codecov - codecov diff --git a/CHANGELOG.md b/CHANGELOG.md index b11ae5473f..47cdc2e541 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes merged into master +### [#221](https://github.com/jaegertracing/jaeger-ui/pull/221) Timeline Expand and Collapse Features + +* Partially addresses [#160](https://github.com/jaegertracing/jaeger-ui/issues/160) - Heuristics for collapsing spans + ### [#191](https://github.com/jaegertracing/jaeger-ui/pull/191) Add GA event tracking for actions in trace view * Partially addresses [#157](https://github.com/jaegertracing/jaeger-ui/issues/157) - Enhanced Google Analytics integration diff --git a/README.md b/README.md index a1f4c8821d..cf2e69fcbc 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,16 @@ git clone https://github.com/jaegertracing/jaeger-ui.git cd jaeger-ui ``` -Use the recommended npm and Node versions: (defined in [.nvmrc](./.nvmrc) file): +Use the recommended Node versions: (defined in [.nvmrc](./.nvmrc) file): ``` nvm use ``` -Install dependencies via `npm` or `yarn`: +Install dependencies via `yarn`: ``` -npm install +yarn install # or yarn ``` @@ -46,25 +46,25 @@ ssh -fN -L 16686:$BACKEND_HOST:$BACKEND_PORT $BACKEND_PORT Start the development server with hot loading: ``` -npm start +cd packages/jaeger-ui && yarn start ``` #### Commands -| Command | Description | -| --------------- | ----------------------------------------------------------- | -| `npm start` | Starts development server with hot reloading and api proxy. | -| `npm test` | Runs all the tests | -| `npm run lint` | Lint the project (eslint, prettier, flow) | -| `npm run build` | Runs production build. Outputs files to `/dist`. | +| Command | Description | +| ------------------------------------- | ------------------------------------------------------------------- | +| `cd packages/jaeger-ui && yarn start` | Starts development server with hot reloading and api proxy. | +| `yarn test` | Run all the tests | +| `yarn lint` | Lint the project (eslint, prettier, flow) | +| `yarn build` | Runs production build. Outputs files to `packages/jaeger-ui/build`. | ## Build -Running build will output all the static files to the `./dist` folder: +Running build will output all the static files to the `packages/jaeger-ui/build` folder: ``` -npm install -npm run build +yarn install +yarn build ``` ## UI Configuration diff --git a/lerna.json b/lerna.json new file mode 100644 index 0000000000..03cfbda637 --- /dev/null +++ b/lerna.json @@ -0,0 +1,7 @@ +{ + "lerna": "2.10.2", + "packages": ["packages/*"], + "version": "independent", + "npmClient": "yarn", + "useWorkspaces": true +} diff --git a/package.json b/package.json index 80c41931ad..c9974228c9 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,8 @@ { - "name": "jaeger-ui", - "version": "0.0.1", - "main": "src/index.js", - "license": "MIT", - "proxy": { - "/api": { - "target": "http://localhost:16686", - "logLevel": "silent", - "secure": false, - "changeOrigin": true, - "ws": true, - "xfwd": true - } - }, - "homepage": ".", + "private": true, + "license": "Apache-2.0", "devDependencies": { "babel-eslint": "^7.2.3", - "babel-plugin-import": "^1.6.3", - "bluebird": "^3.5.0", - "enzyme": "^3.2.0", - "enzyme-adapter-react-16": "^1.1.0", - "enzyme-to-json": "^3.3.0", "eslint": "^4.5.0", "eslint-config-airbnb": "^15.1.0", "eslint-config-prettier": "^2.3.0", @@ -29,88 +11,25 @@ "eslint-plugin-import": "^2.7.0", "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-react": "^7.2.1", + "flow-bin": "^0.71.0", "glow": "^1.2.2", "husky": "^0.14.3", - "less-vars-to-js": "^1.2.1", - "lint-staged": "^4.0.3", - "prettier": "^1.10.2", - "react-app-rewire-less": "^2.1.0", - "react-app-rewired": "^1.4.0", - "react-scripts": "^1.0.11", - "react-test-renderer": "^15.6.1", - "sinon": "^3.2.1" - }, - "dependencies": { - "antd": "^3.0.3", - "chance": "^1.0.10", - "classnames": "^2.2.5", - "combokeys": "^3.0.0", - "cytoscape": "^3.2.1", - "cytoscape-dagre": "^2.0.0", - "d3-scale": "^1.0.6", - "dagre": "^0.7.4", - "deep-freeze": "^0.0.1", - "flow-bin": "^0.64.0", - "fuzzy": "^0.1.3", - "global": "^4.3.2", - "history": "^4.6.3", - "is-promise": "^2.1.0", - "isomorphic-fetch": "^2.2.1", - "jest": "^21.2.1", - "json-markup": "^1.1.0", - "lodash": "^4.17.4", - "logfmt": "^1.2.0", - "moment": "^2.18.1", - "prop-types": "^15.5.10", - "query-string": "^5.0.0", - "raven-js": "^3.22.1", - "react": "^16.0.0", - "react-dimensions": "^1.3.0", - "react-dom": "^16.0.0", - "react-ga": "^2.4.1", - "react-helmet": "^5.1.3", - "react-icons": "^2.2.7", - "react-metrics": "^2.3.2", - "react-redux": "^5.0.6", - "react-router-dom": "^4.1.2", - "react-router-redux": "5.0.0-alpha.6", - "react-virtualized-select": "^3.1.0", - "react-vis": "^1.7.2", - "react-vis-force": "^0.3.1", - "recompose": "^0.25.0", - "redux": "^3.7.2", - "redux-actions": "^2.2.1", - "redux-async-middleware": "^0.0.0", - "redux-form": "^7.0.3", - "redux-promise-middleware": "^4.3.0", - "reselect": "^3.0.1", - "store": "^2.0.12", - "tween-functions": "^1.2.0", - "u-basscss": "2.0.0" + "lerna": "^2.10.2", + "lint-staged": "^7.0.4", + "prettier": "^1.10.2" }, + "workspaces": ["packages/*"], "scripts": { - "start": "react-app-rewired start", - "start:ga-debug": - "REACT_APP_GA_DEBUG=1 REACT_APP_VSN_STATE=$(./scripts/get-tracking-version.js) react-app-rewired start", - "build": "REACT_APP_VSN_STATE=$(./scripts/get-tracking-version.js) react-app-rewired build", - "eject": "react-scripts eject", - "test": "CI=1 react-app-rewired test --env=jsdom --color", - "test-dev": "react-app-rewired test --env=jsdom", - "coverage": "npm run test -- --coverage", - "lint": "npm run eslint && npm run prettier && npm run flow && npm run check-license", - "eslint": "eslint src", + "build": "lerna run build", "check-license": "./scripts/check-license.sh", - "prettier": "prettier --write 'src/**/*.{css,js,json,md}' '*.{css,js,json,md}'", + "coverage": "lerna run coverage", + "eslint": "eslint 'scripts/*.js' 'packages/*/src/**/*.js' 'packages/*/*.js'", "flow": "glow", - "precommit": "lint-staged" - }, - "jest": { - "collectCoverageFrom": [ - "src/**/*.js", - "!src/utils/DraggableManager/demo/*.js", - "!src/utils/test/**/*.js", - "!src/demo/**/*.js" - ] + "lint": "npm run eslint && npm run prettier && npm run flow && npm run check-license", + "precommit": "lint-staged", + "prettier": + "prettier --write '{.,scripts}/*.{js,json,md}' 'packages/*/{src,demo/src}/**/*.{css,js,json,md}' 'packages/*/*.{css,js,json,md}'", + "test": "lerna run test" }, "prettier": { "printWidth": 110, diff --git a/config-overrides-antd-vars.less b/packages/jaeger-ui/config-overrides-antd-vars.less similarity index 94% rename from config-overrides-antd-vars.less rename to packages/jaeger-ui/config-overrides-antd-vars.less index 53cceab91b..31ecdf902d 100644 --- a/config-overrides-antd-vars.less +++ b/packages/jaeger-ui/config-overrides-antd-vars.less @@ -19,3 +19,6 @@ @layout-zero-trigger-height : 42px; @menu-dark-bg: #151515; + +// Table +@table-row-hover-bg:#e5f2f2; diff --git a/config-overrides.js b/packages/jaeger-ui/config-overrides.js similarity index 100% rename from config-overrides.js rename to packages/jaeger-ui/config-overrides.js diff --git a/packages/jaeger-ui/package.json b/packages/jaeger-ui/package.json new file mode 100644 index 0000000000..48b1f2e03c --- /dev/null +++ b/packages/jaeger-ui/package.json @@ -0,0 +1,96 @@ +{ + "private": true, + "name": "jaeger-ui", + "version": "0.0.1", + "main": "src/index.js", + "license": "Apache-2.0", + "proxy": { + "/api": { + "target": "http://localhost:16686", + "logLevel": "silent", + "secure": false, + "changeOrigin": true, + "ws": true, + "xfwd": true + } + }, + "homepage": ".", + "devDependencies": { + "babel-plugin-import": "^1.6.3", + "bluebird": "^3.5.0", + "enzyme": "^3.2.0", + "enzyme-adapter-react-16": "^1.1.0", + "enzyme-to-json": "^3.3.0", + "less-vars-to-js": "^1.2.1", + "react-app-rewire-less": "^2.1.0", + "react-app-rewired": "^1.4.0", + "react-scripts": "^1.0.11", + "react-test-renderer": "^15.6.1", + "sinon": "^3.2.1" + }, + "dependencies": { + "@jaegertracing/plexus": "0.0.1-dev.2", + "antd": "^3.0.3", + "chance": "^1.0.10", + "classnames": "^2.2.5", + "combokeys": "^3.0.0", + "cytoscape": "^3.2.1", + "cytoscape-dagre": "^2.0.0", + "d3-scale": "^1.0.6", + "dagre": "^0.7.4", + "deep-freeze": "^0.0.1", + "fuzzy": "^0.1.3", + "global": "^4.3.2", + "history": "^4.6.3", + "is-promise": "^2.1.0", + "isomorphic-fetch": "^2.2.1", + "jest": "^21.2.1", + "json-markup": "^1.1.0", + "lodash": "^4.17.4", + "logfmt": "^1.2.0", + "moment": "^2.18.1", + "prop-types": "^15.5.10", + "query-string": "^5.0.0", + "raven-js": "^3.22.1", + "react": "^16.3.2", + "react-dimensions": "^1.3.0", + "react-dom": "^16.3.2", + "react-ga": "^2.4.1", + "react-helmet": "^5.1.3", + "react-icons": "^2.2.7", + "react-metrics": "^2.3.2", + "react-redux": "^5.0.6", + "react-router-dom": "^4.1.2", + "react-router-redux": "5.0.0-alpha.6", + "react-virtualized-select": "^3.1.0", + "react-vis": "^1.7.2", + "react-vis-force": "^0.3.1", + "recompose": "^0.25.0", + "redux": "^3.7.2", + "redux-actions": "^2.2.1", + "redux-async-middleware": "^0.0.0", + "redux-form": "^7.0.3", + "redux-promise-middleware": "^4.3.0", + "reselect": "^3.0.1", + "store": "^2.0.12", + "tween-functions": "^1.2.0", + "u-basscss": "2.0.0" + }, + "scripts": { + "build": "REACT_APP_VSN_STATE=$(../../scripts/get-tracking-version.js) react-app-rewired build", + "coverage": "npm run test -- --coverage", + "start:ga-debug": + "REACT_APP_GA_DEBUG=1 REACT_APP_VSN_STATE=$(../../scripts/get-tracking-version.js) react-app-rewired start", + "start": "react-app-rewired start", + "test-dev": "react-app-rewired test --env=jsdom", + "test": "CI=1 react-app-rewired test --env=jsdom --color" + }, + "jest": { + "collectCoverageFrom": [ + "src/**/*.js", + "!src/utils/DraggableManager/demo/*.js", + "!src/utils/test/**/*.js", + "!src/demo/**/*.js" + ] + } +} diff --git a/public/favicon.ico b/packages/jaeger-ui/public/favicon.ico similarity index 100% rename from public/favicon.ico rename to packages/jaeger-ui/public/favicon.ico diff --git a/public/index.html b/packages/jaeger-ui/public/index.html similarity index 100% rename from public/index.html rename to packages/jaeger-ui/public/index.html diff --git a/src/actions/jaeger-api.js b/packages/jaeger-ui/src/actions/jaeger-api.js similarity index 90% rename from src/actions/jaeger-api.js rename to packages/jaeger-ui/src/actions/jaeger-api.js index 56cdc6889b..dfd94ab81d 100644 --- a/src/actions/jaeger-api.js +++ b/packages/jaeger-ui/src/actions/jaeger-api.js @@ -21,6 +21,12 @@ export const fetchTrace = createAction( id => ({ id }) ); +export const fetchMultipleTraces = createAction( + '@JAEGER_API/FETCH_MULTIPLE_TRACES', + ids => JaegerAPI.searchTraces({ traceID: ids }), + ids => ({ ids }) +); + export const archiveTrace = createAction( '@JAEGER_API/ARCHIVE_TRACE', id => JaegerAPI.archiveTrace(id), diff --git a/src/actions/jaeger-api.test.js b/packages/jaeger-ui/src/actions/jaeger-api.test.js similarity index 100% rename from src/actions/jaeger-api.test.js rename to packages/jaeger-ui/src/actions/jaeger-api.test.js diff --git a/src/api/jaeger.js b/packages/jaeger-ui/src/api/jaeger.js similarity index 100% rename from src/api/jaeger.js rename to packages/jaeger-ui/src/api/jaeger.js diff --git a/src/api/jaeger.test.js b/packages/jaeger-ui/src/api/jaeger.test.js similarity index 100% rename from src/api/jaeger.test.js rename to packages/jaeger-ui/src/api/jaeger.test.js diff --git a/src/components/App/NotFound.js b/packages/jaeger-ui/src/components/App/NotFound.js similarity index 100% rename from src/components/App/NotFound.js rename to packages/jaeger-ui/src/components/App/NotFound.js diff --git a/src/components/App/Page.css b/packages/jaeger-ui/src/components/App/Page.css similarity index 100% rename from src/components/App/Page.css rename to packages/jaeger-ui/src/components/App/Page.css diff --git a/src/components/App/Page.js b/packages/jaeger-ui/src/components/App/Page.js similarity index 66% rename from src/components/App/Page.js rename to packages/jaeger-ui/src/components/App/Page.js index 53cca06ec1..fc6f697ff9 100644 --- a/src/components/App/Page.js +++ b/packages/jaeger-ui/src/components/App/Page.js @@ -22,47 +22,44 @@ import type { Location } from 'react-router-dom'; import { withRouter } from 'react-router-dom'; import TopNav from './TopNav'; -import type { Config } from '../../types/config'; import { trackPageView } from '../../utils/tracking'; import './Page.css'; -type PageProps = { - location: Location, +type Props = { + pathname: string, + search: string, children: React.Node, - config: Config, }; const { Header, Content } = Layout; // export for tests -export class PageImpl extends React.Component { - props: PageProps; +export class PageImpl extends React.Component { + props: Props; componentDidMount() { - const { pathname, search } = this.props.location; + const { pathname, search } = this.props; trackPageView(pathname, search); } - componentWillReceiveProps(nextProps: PageProps) { - const { pathname, search } = this.props.location; - const { pathname: nextPathname, search: nextSearch } = nextProps.location; + componentWillReceiveProps(nextProps: Props) { + const { pathname, search } = this.props; + const { pathname: nextPathname, search: nextSearch } = nextProps; if (pathname !== nextPathname || search !== nextSearch) { trackPageView(nextPathname, nextSearch); } } render() { - const { children, config, location } = this.props; - const menu = config && config.menu; return (
- +
- {children} + {this.props.children}
); @@ -70,10 +67,10 @@ export class PageImpl extends React.Component { } // export for tests -export function mapStateToProps(state: { config: Config, router: { location: Location } }, ownProps: any) { - const { config } = state; - const { location } = state.router; - return { ...ownProps, config, location }; +export function mapStateToProps(state: { router: { location: Location } }) { + const { pathname, search } = state.router.location; + return { pathname, search }; } +// export default withRouter(connect(mapStateToProps)(PageImpl)); export default withRouter(connect(mapStateToProps)(PageImpl)); diff --git a/src/components/App/Page.test.js b/packages/jaeger-ui/src/components/App/Page.test.js similarity index 70% rename from src/components/App/Page.test.js rename to packages/jaeger-ui/src/components/App/Page.test.js index 6761b444e8..c8e5fef3b3 100644 --- a/src/components/App/Page.test.js +++ b/packages/jaeger-ui/src/components/App/Page.test.js @@ -24,16 +24,12 @@ import { trackPageView } from '../../utils/tracking'; describe('mapStateToProps()', () => { it('maps state to props', () => { + const pathname = 'a-pathname'; + const search = 'a-search'; const state = { - config: {}, - router: { location: {} }, + router: { location: { pathname, search } }, }; - const ownProps = { a: {} }; - expect(mapStateToProps(state, ownProps)).toEqual({ - config: state.config, - location: state.router.location, - a: ownProps.a, - }); + expect(mapStateToProps(state)).toEqual({ pathname, search }); }); }); @@ -44,11 +40,8 @@ describe('', () => { beforeEach(() => { trackPageView.mockReset(); props = { - location: { - pathname: String(Math.random()), - search: String(Math.random()), - }, - config: { menu: [] }, + pathname: String(Math.random()), + search: String(Math.random()), }; wrapper = mount(); }); @@ -58,14 +51,14 @@ describe('', () => { }); it('tracks an initial page-view', () => { - const { pathname, search } = props.location; + const { pathname, search } = props; expect(trackPageView.mock.calls).toEqual([[pathname, search]]); }); it('tracks a pageView when the location changes', () => { trackPageView.mockReset(); - const location = { pathname: 'le-path', search: 'searching' }; - wrapper.setProps({ location }); - expect(trackPageView.mock.calls).toEqual([[location.pathname, location.search]]); + props = { pathname: 'le-path', search: 'searching' }; + wrapper.setProps(props); + expect(trackPageView.mock.calls).toEqual([[props.pathname, props.search]]); }); }); diff --git a/src/components/App/TopNav.js b/packages/jaeger-ui/src/components/App/TopNav.js similarity index 58% rename from src/components/App/TopNav.js rename to packages/jaeger-ui/src/components/App/TopNav.js index 146d105735..d414395836 100644 --- a/src/components/App/TopNav.js +++ b/packages/jaeger-ui/src/components/App/TopNav.js @@ -16,28 +16,38 @@ import React from 'react'; import { Dropdown, Icon, Menu } from 'antd'; -import { Link } from 'react-router-dom'; +import { connect } from 'react-redux'; +import { Link, withRouter } from 'react-router-dom'; import TraceIDSearchInput from './TraceIDSearchInput'; -import type { ConfigMenuItem, ConfigMenuGroup } from '../../types/config'; +import * as dependencies from '../DependencyGraph/url'; +import * as searchUrl from '../SearchTracePage/url'; +import * as diffUrl from '../TraceDiff/url'; import { getConfigValue } from '../../utils/config/get-config'; import prefixUrl from '../../utils/prefix-url'; -type TopNavProps = { - activeKey: string, - menuConfig: (ConfigMenuItem | ConfigMenuGroup)[], -}; +import type { ReduxState } from '../../types'; +import type { ConfigMenuItem, ConfigMenuGroup } from '../../types/config'; + +type Props = ReduxState; const NAV_LINKS = [ { - to: prefixUrl('/search'), + to: searchUrl.getUrl(), + matches: searchUrl.matches, text: 'Search', }, + { + to: (props: Props) => diffUrl.getUrl(props.traceDiff), + matches: diffUrl.matches, + text: 'Compare', + }, ]; if (getConfigValue('dependencies.menuEnabled')) { NAV_LINKS.push({ - to: prefixUrl('/dependencies'), + to: dependencies.getUrl(), + matches: dependencies.matches, text: 'Dependencies', }); } @@ -66,20 +76,23 @@ function CustomNavDropdown({ label, items }: ConfigMenuGroup) { ); } -export default function TopNav(props: TopNavProps) { - const { activeKey, menuConfig } = props; - const menuItems = Array.isArray(menuConfig) ? menuConfig : []; +export function TopNavImpl(props: Props) { + const { config, router } = props; + const { pathname } = router.location; + const menuItems = Array.isArray(config.menu) ? config.menu : []; return ( ); } -TopNav.defaultProps = { +TopNavImpl.defaultProps = { menuConfig: [], }; -TopNav.CustomNavDropdown = CustomNavDropdown; +TopNavImpl.CustomNavDropdown = CustomNavDropdown; + +function mapStateToProps(state: Props) { + return state; +} + +export default withRouter(connect(mapStateToProps)(TopNavImpl)); diff --git a/src/components/App/TopNav.test.js b/packages/jaeger-ui/src/components/App/TopNav.test.js similarity index 87% rename from src/components/App/TopNav.test.js rename to packages/jaeger-ui/src/components/App/TopNav.test.js index 33817f0fd7..e38254d003 100644 --- a/src/components/App/TopNav.test.js +++ b/packages/jaeger-ui/src/components/App/TopNav.test.js @@ -16,7 +16,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { Link } from 'react-router-dom'; -import TopNav from './TopNav'; +import { TopNavImpl as TopNav } from './TopNav'; describe('', () => { const labelGitHub = 'GitHub'; @@ -34,16 +34,21 @@ describe('', () => { ]; const defaultProps = { - menuConfig: [ - { - label: labelGitHub, - url: githubUrl, - }, - { - label: labelAbout, - items: dropdownItems, - }, - ], + config: { + menu: [ + { + label: labelGitHub, + url: githubUrl, + }, + { + label: labelAbout, + items: dropdownItems, + }, + ], + }, + router: { + location: { location: { pathname: 'some-path ' } }, + }, }; let wrapper; diff --git a/src/components/App/TraceIDSearchInput.css b/packages/jaeger-ui/src/components/App/TraceIDSearchInput.css similarity index 100% rename from src/components/App/TraceIDSearchInput.css rename to packages/jaeger-ui/src/components/App/TraceIDSearchInput.css diff --git a/src/components/App/TraceIDSearchInput.js b/packages/jaeger-ui/src/components/App/TraceIDSearchInput.js similarity index 100% rename from src/components/App/TraceIDSearchInput.js rename to packages/jaeger-ui/src/components/App/TraceIDSearchInput.js diff --git a/src/components/App/index.css b/packages/jaeger-ui/src/components/App/index.css similarity index 100% rename from src/components/App/index.css rename to packages/jaeger-ui/src/components/App/index.css diff --git a/src/components/App/index.js b/packages/jaeger-ui/src/components/App/index.js similarity index 64% rename from src/components/App/index.js rename to packages/jaeger-ui/src/components/App/index.js index 57337b0bf7..1a5ac67ea5 100644 --- a/src/components/App/index.js +++ b/packages/jaeger-ui/src/components/App/index.js @@ -20,9 +20,14 @@ import { ConnectedRouter } from 'react-router-redux'; import NotFound from './NotFound'; import Page from './Page'; -import { ConnectedDependencyGraphPage } from '../DependencyGraph'; -import { ConnectedSearchTracePage } from '../SearchTracePage'; -import { ConnectedTracePage } from '../TracePage'; +import DependencyGraph from '../DependencyGraph'; +import { ROUTE_PATH as dependenciesPath } from '../DependencyGraph/url'; +import SearchTracePage from '../SearchTracePage'; +import { ROUTE_PATH as searchPath } from '../SearchTracePage/url'; +import TraceDiff from '../TraceDiff'; +import { ROUTE_PATH as traceDiffPath } from '../TraceDiff/url'; +import TracePage from '../TracePage'; +import { ROUTE_PATH as tracePath } from '../TracePage/url'; import JaegerAPI, { DEFAULT_API_ROOT } from '../../api/jaeger'; import configureStore from '../../utils/configure-store'; import prefixUrl from '../../utils/prefix-url'; @@ -45,12 +50,15 @@ export default class JaegerUIApp extends Component { - - - - - - + + + + + + + + + diff --git a/src/components/App/index.test.js b/packages/jaeger-ui/src/components/App/index.test.js similarity index 100% rename from src/components/App/index.test.js rename to packages/jaeger-ui/src/components/App/index.test.js diff --git a/src/components/DependencyGraph/DAG.js b/packages/jaeger-ui/src/components/DependencyGraph/DAG.js similarity index 100% rename from src/components/DependencyGraph/DAG.js rename to packages/jaeger-ui/src/components/DependencyGraph/DAG.js diff --git a/src/components/DependencyGraph/DAG.test.js b/packages/jaeger-ui/src/components/DependencyGraph/DAG.test.js similarity index 100% rename from src/components/DependencyGraph/DAG.test.js rename to packages/jaeger-ui/src/components/DependencyGraph/DAG.test.js diff --git a/src/components/DependencyGraph/DependencyForceGraph.js b/packages/jaeger-ui/src/components/DependencyGraph/DependencyForceGraph.js similarity index 100% rename from src/components/DependencyGraph/DependencyForceGraph.js rename to packages/jaeger-ui/src/components/DependencyGraph/DependencyForceGraph.js diff --git a/src/components/DependencyGraph/DependencyForceGraph.test.js b/packages/jaeger-ui/src/components/DependencyGraph/DependencyForceGraph.test.js similarity index 100% rename from src/components/DependencyGraph/DependencyForceGraph.test.js rename to packages/jaeger-ui/src/components/DependencyGraph/DependencyForceGraph.test.js diff --git a/src/components/DependencyGraph/index.css b/packages/jaeger-ui/src/components/DependencyGraph/index.css similarity index 100% rename from src/components/DependencyGraph/index.css rename to packages/jaeger-ui/src/components/DependencyGraph/index.css diff --git a/src/components/DependencyGraph/index.js b/packages/jaeger-ui/src/components/DependencyGraph/index.js similarity index 96% rename from src/components/DependencyGraph/index.js rename to packages/jaeger-ui/src/components/DependencyGraph/index.js index 350828d275..1a75997d1c 100644 --- a/src/components/DependencyGraph/index.js +++ b/packages/jaeger-ui/src/components/DependencyGraph/index.js @@ -40,7 +40,8 @@ export const GRAPH_TYPES = { const dagMaxNumServices = getConfigValue('dependencies.dagMaxNumServices') || FALLBACK_DAG_MAX_NUM_SERVICES; -export default class DependencyGraphPage extends Component { +// export for tests +export class DependencyGraphPageImpl extends Component { static propTypes = { // eslint-disable-next-line react/forbid-prop-types dependencies: PropTypes.any.isRequired, @@ -129,4 +130,4 @@ export function mapDispatchToProps(dispatch) { return { fetchDependencies }; } -export const ConnectedDependencyGraphPage = connect(mapStateToProps, mapDispatchToProps)(DependencyGraphPage); +export default connect(mapStateToProps, mapDispatchToProps)(DependencyGraphPageImpl); diff --git a/src/components/DependencyGraph/index.test.js b/packages/jaeger-ui/src/components/DependencyGraph/index.test.js similarity index 96% rename from src/components/DependencyGraph/index.test.js rename to packages/jaeger-ui/src/components/DependencyGraph/index.test.js index a2b4574eae..8217131298 100644 --- a/src/components/DependencyGraph/index.test.js +++ b/packages/jaeger-ui/src/components/DependencyGraph/index.test.js @@ -18,7 +18,12 @@ import { shallow } from 'enzyme'; import DAG from './DAG'; import DependencyForceGraph from './DependencyForceGraph'; -import DependencyGraph, { GRAPH_TYPES, mapDispatchToProps, mapStateToProps } from './index'; +import { + DependencyGraphPageImpl as DependencyGraph, + GRAPH_TYPES, + mapDispatchToProps, + mapStateToProps, +} from './index'; import LoadingIndicator from '../common/LoadingIndicator'; const childId = 'boomya'; diff --git a/packages/jaeger-ui/src/components/DependencyGraph/url.js b/packages/jaeger-ui/src/components/DependencyGraph/url.js new file mode 100644 index 0000000000..79bea821d8 --- /dev/null +++ b/packages/jaeger-ui/src/components/DependencyGraph/url.js @@ -0,0 +1,31 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { matchPath } from 'react-router-dom'; + +import prefixUrl from '../../utils/prefix-url'; + +export const ROUTE_PATH = prefixUrl('/dependencies'); + +const ROUTE_MATCHER = { path: ROUTE_PATH, strict: true, exact: true }; + +export function matches(path: string) { + return Boolean(matchPath(path, ROUTE_MATCHER)); +} + +export function getUrl() { + return ROUTE_PATH; +} diff --git a/src/components/SearchTracePage/SearchForm.css b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.css similarity index 100% rename from src/components/SearchTracePage/SearchForm.css rename to packages/jaeger-ui/src/components/SearchTracePage/SearchForm.css diff --git a/src/components/SearchTracePage/SearchForm.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.js similarity index 58% rename from src/components/SearchTracePage/SearchForm.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchForm.js index 3b4d385aed..5db0e88b80 100644 --- a/src/components/SearchTracePage/SearchForm.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.js @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; +import * as React from 'react'; import { Form, Input, Button, Popover, Select } from 'antd'; import logfmtParser from 'logfmt/lib/logfmt_parser'; import { stringify as logfmtStringify } from 'logfmt/lib/stringify'; @@ -26,10 +26,12 @@ import { Field, reduxForm, formValueSelector } from 'redux-form'; import store from 'store'; import * as markers from './SearchForm.markers'; +import { trackFormInput } from './SearchForm.track'; import VirtSelect from '../common/VirtSelect'; import * as jaegerApiActions from '../../actions/jaeger-api'; import { formatDate, formatTime } from '../../utils/date'; import reduxFormFieldAdapter from '../../utils/redux-form-field-adapter'; +import { DEFAULT_OPERATION, DEFAULT_LIMIT, DEFAULT_LOOKBACK } from '../../constants/search-form'; import './SearchForm.css'; @@ -134,9 +136,11 @@ export function submitForm(fields, searchTraces) { end = times.end; } + trackFormInput(resultsLimit, operation, tags, minDuration, maxDuration, lookback); + searchTraces({ service, - operation: operation !== 'all' ? operation : undefined, + operation: operation !== DEFAULT_OPERATION ? operation : undefined, limit: resultsLimit, lookback, start, @@ -147,149 +151,86 @@ export function submitForm(fields, searchTraces) { }); } -export function SearchFormImpl(props) { - const { handleSubmit, selectedLookback, selectedService = '-', services, submitting: disabled } = props; - const selectedServicePayload = services.find(s => s.name === selectedService); - const opsForSvc = (selectedServicePayload && selectedServicePayload.operations) || []; - const noSelectedService = selectedService === '-' || !selectedService; - const tz = selectedLookback === 'custom' ? new Date().toTimeString().replace(/^.*?GMT/, 'UTC') : null; - return ( -
- - Service ({services.length}) - - } - > - ({ label: v.name, value: v.name })), - required: true, - }} - /> - - - Operation ({opsForSvc ? opsForSvc.length : 0}) - - } - > - ({ label: v, value: v })), - required: true, - }} - /> - - - - Tags{' '} - - Values should be in the{' '} - - logfmt - {' '} - format. - , -
    -
  • Use space for conjunctions
  • -
  • Values containing whitespace should be enclosed in quotes
  • -
, - ]} - content={ -
- - error=true db.statement="select * from User" - -
- } - > - - - - } - > - - - - - - - - - - - - - - - - - {selectedLookback === 'custom' && [ +export class SearchFormImpl extends React.PureComponent { + render() { + const { + handleSubmit, + selectedLookback, + selectedService = '-', + services, + submitting: disabled, + } = this.props; + const selectedServicePayload = services.find(s => s.name === selectedService); + const opsForSvc = (selectedServicePayload && selectedServicePayload.operations) || []; + const noSelectedService = selectedService === '-' || !selectedService; + const tz = selectedLookback === 'custom' ? new Date().toTimeString().replace(/^.*?GMT/, 'UTC') : null; + return ( + - Start Time{' '} - - Times are expressed in {tz} - - } - > - - - + + Service ({services.length}) + } > ({ label: v.name, value: v.name })), + required: true, + }} + /> + + + Operation ({opsForSvc ? opsForSvc.length : 0}) + + } + > + ({ label: v, value: v })), + required: true, + }} /> - - , + - End Time{' '} + Tags{' '} - Times are expressed in {tz} - + Values should be in the{' '} + + logfmt + {' '} + format. + , +
    +
  • Use space for conjunctions
  • +
  • Values containing whitespace should be enclosed in quotes
  • +
, + ]} + content={ +
+ + error=true db.statement="select * from User" + +
} > @@ -298,44 +239,115 @@ export function SearchFormImpl(props) { } > +
+ + + + + + + + + + + + + + + {selectedLookback === 'custom' && [ + + Start Time{' '} + + Times are expressed in {tz} + + } + > + + + + } + > + + + , + + + End Time{' '} + + Times are expressed in {tz} + + } + > + + + + } + > + + + , + ]} + + + - - , - ]} - - - - - - - - - - - - - - - - ); + + + + + + + + + + + + + ); + } } SearchFormImpl.propTypes = { @@ -459,13 +471,13 @@ export function mapStateToProps(state) { destroyOnUnmount: false, initialValues: { service: service || lastSearchService || '-', - resultsLimit: limit || 20, - lookback: lookback || '1h', + resultsLimit: limit || DEFAULT_LIMIT, + lookback: lookback || DEFAULT_LOOKBACK, startDate: queryStartDate || today, startDateTime: queryStartDateTime || '00:00', endDate: queryEndDate || today, endDateTime: queryEndDateTime || currentTime, - operation: operation || lastSearchOperation || 'all', + operation: operation || lastSearchOperation || DEFAULT_OPERATION, tags, minDuration: minDuration || null, maxDuration: maxDuration || null, diff --git a/src/components/SearchTracePage/SearchForm.markers.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.markers.js similarity index 100% rename from src/components/SearchTracePage/SearchForm.markers.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchForm.markers.js diff --git a/src/components/SearchTracePage/SearchForm.test.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.test.js similarity index 100% rename from src/components/SearchTracePage/SearchForm.test.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchForm.test.js diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.track.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.track.js new file mode 100644 index 0000000000..89702edac7 --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.track.js @@ -0,0 +1,57 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import type { Store } from 'redux'; + +import * as constants from '../../constants/search-form'; +import { trackEvent } from '../../utils/tracking'; + +export const ACTION_SET = 'set'; +export const ACTION_CLEAR = 'clear'; +export const ACTION_DEFAULT = 'default'; + +export const CATEGORY_SORTBY = `jaeger/ux/search/results/sortby`; +export const FORM_CATEGORY_BASE = 'jaeger/ux/search/form'; +export const CATEGORY_OPERATION = `${FORM_CATEGORY_BASE}/operation`; +export const CATEGORY_LOOKBACK = `${FORM_CATEGORY_BASE}/lookback`; +export const CATEGORY_TAGS = `${FORM_CATEGORY_BASE}/tags`; +export const CATEGORY_MIN_DURATION = `${FORM_CATEGORY_BASE}/min_duration`; +export const CATEGORY_MAX_DURATION = `${FORM_CATEGORY_BASE}/max_duration`; +export const CATEGORY_LIMIT = `${FORM_CATEGORY_BASE}/limit`; + +export function trackFormInput( + resultsLimit: number, + operation: string, + tags: any, + minDuration: number, + maxDuration: number, + lookback: string +) { + trackEvent(CATEGORY_OPERATION, operation === constants.DEFAULT_OPERATION ? ACTION_DEFAULT : ACTION_SET); + trackEvent(CATEGORY_LIMIT, resultsLimit === constants.DEFAULT_LIMIT ? ACTION_DEFAULT : ACTION_SET); + trackEvent(CATEGORY_MAX_DURATION, maxDuration ? ACTION_SET : ACTION_CLEAR); + trackEvent(CATEGORY_MIN_DURATION, minDuration ? ACTION_SET : ACTION_CLEAR); + trackEvent(CATEGORY_TAGS, tags ? ACTION_SET : ACTION_CLEAR); + trackEvent(CATEGORY_LOOKBACK, lookback); +} + +export const middlewareHooks = { + [constants.FORM_CHANGE_ACTION_TYPE]: (store: Store, action: any) => { + if (action.meta.form === 'sortBy') { + trackEvent(CATEGORY_SORTBY, action.payload); + } + }, +}; diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.track.test.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.track.test.js new file mode 100644 index 0000000000..f6d29fa75d --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.track.test.js @@ -0,0 +1,56 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* eslint-disable import/first */ +jest.mock('../../utils/tracking'); + +import { + middlewareHooks, + trackFormInput, + CATEGORY_LIMIT, + CATEGORY_LOOKBACK, + CATEGORY_MAX_DURATION, + CATEGORY_MIN_DURATION, + CATEGORY_OPERATION, + CATEGORY_SORTBY, + CATEGORY_TAGS, +} from './SearchForm.track'; +import { FORM_CHANGE_ACTION_TYPE } from '../../constants/search-form'; +import { trackEvent } from '../../utils/tracking'; + +describe('GA tracking', () => { + it('tracks changing sort criteria', () => { + const action = { meta: { form: 'sortBy' }, payload: 'MOST_RECENT' }; + middlewareHooks[FORM_CHANGE_ACTION_TYPE]({}, action); + expect(trackEvent.mock.calls.length).toBe(1); + expect(trackEvent.mock.calls[0]).toEqual([CATEGORY_SORTBY, expect.any(String)]); + }); + + it('sends form input to GA', () => { + trackEvent.mockClear(); + trackFormInput(0, '', {}, 0, 0, ''); + expect(trackEvent.mock.calls.length).toBe(6); + const categoriesTracked = trackEvent.mock.calls.map(call => call[0]).sort(); + expect(categoriesTracked).toEqual( + [ + CATEGORY_OPERATION, + CATEGORY_LIMIT, + CATEGORY_TAGS, + CATEGORY_MAX_DURATION, + CATEGORY_MIN_DURATION, + CATEGORY_LOOKBACK, + ].sort() + ); + }); +}); diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/DiffSelection.css b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/DiffSelection.css new file mode 100644 index 0000000000..96b9dc1ee7 --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/DiffSelection.css @@ -0,0 +1,34 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.DiffSelection.is-non-empty { + position: sticky; + top: 47px; + z-index: 1; +} + +.DiffSelection--message { + background: #f5f5f5; + z-index: 11; + background: #e5f2f2; + border: 1px solid #87c3c3; + padding: 1rem; +} + +.DiffSelection--selectedItems { + border: 1px solid #ccc; + border-bottom: none; +} diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/DiffSelection.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/DiffSelection.js new file mode 100644 index 0000000000..70daf02b7f --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/DiffSelection.js @@ -0,0 +1,82 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { Button } from 'antd'; +import { Link } from 'react-router-dom'; + +import ResultItemTitle from './ResultItemTitle'; +import { getUrl } from '../../TraceDiff/url'; +import { fetchedState } from '../../../constants'; + +import type { FetchedTrace } from '../../../types'; + +import './DiffSelection.css'; + +type Props = { + toggleComparison: (string, boolean) => void, + traces: FetchedTrace[], +}; + +const CTA_MESSAGE =

Compare traces by selecting result items

; + +export default class DiffSelection extends React.PureComponent { + props: Props; + + render() { + const { toggleComparison, traces } = this.props; + const cohort = traces.filter(ft => ft.state !== fetchedState.ERROR).map(ft => ft.id); + const compareHref = cohort.length > 1 ? getUrl({ cohort }) : null; + const compareBtn = ( + + ); + return ( +
+ {traces.length > 0 && ( +
+ {traces.map(fetchedTrace => { + const { data = {}, error, id, state } = fetchedTrace; + return ( + + ); + })} +
+ )} +
+ {traces.length > 0 ? ( + + {compareHref ? {compareBtn} : compareBtn} +

{cohort.length} Selected for comparison

+
+ ) : ( + CTA_MESSAGE + )} +
+
+ ); + } +} diff --git a/src/components/SearchTracePage/SearchResults/ResultItem.css b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.css similarity index 71% rename from src/components/SearchTracePage/SearchResults/ResultItem.css rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.css index 93c0094cc6..f53f6b91ec 100644 --- a/src/components/SearchTracePage/SearchResults/ResultItem.css +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.css @@ -24,25 +24,6 @@ limitations under the License. border-color: #d8d8d8; } -.ResultItem--title { - background: #ececec; - border-bottom: 1px solid #d8d8d8; - padding: 0.5rem; - position: relative; -} - -.ResultItem--durationBar { - background: #d7e7ea; - bottom: 0; - left: 0; - position: absolute; - top: 0; -} - -.ResultItem:hover > * > .ResultItem--durationBar { - background: #c5dde0; -} - .ResultItem--serviceTag { border-left-width: 15px; margin: 0; diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.js new file mode 100644 index 0000000000..fce348dbe2 --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.js @@ -0,0 +1,106 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { Col, Divider, Row, Tag } from 'antd'; +import { Link } from 'react-router-dom'; + +import { sortBy } from 'lodash'; +import moment from 'moment'; + +import * as markers from './ResultItem.markers'; +import ResultItemTitle from './ResultItemTitle'; +import colorGenerator from '../../../utils/color-generator'; +import { formatRelativeDate } from '../../../utils/date'; + +import type { Trace } from '../../../types/trace'; + +import './ResultItem.css'; + +type Props = { + durationPercent: number, + isInDiffCohort: boolean, + linkTo: string, + toggleComparison: string => void, + trace: Trace, +}; + +const isErrorTag = ({ key, value }) => key === 'error' && (value === true || value === 'true'); + +export default class ResultItem extends React.PureComponent { + props: Props; + + render() { + const { durationPercent, isInDiffCohort, linkTo, toggleComparison, trace } = this.props; + const { duration, services, startTime, spans, traceName, traceID } = trace; + const mDate = moment(startTime / 1000); + const timeStr = mDate.format('h:mm:ss a'); + const fromNow = mDate.fromNow(); + const numSpans = spans.length; + const numErredSpans = spans.filter(sp => sp.tags.some(isErrorTag)).length; + return ( +
+ + + + + + {numSpans} Span{numSpans > 1 && 's'} + + {Boolean(numErredSpans) && ( + + {numErredSpans} Error{numErredSpans > 1 && 's'} + + )} + + +
    + {sortBy(services, s => s.name).map(service => { + const { name, numberOfSpans: count } = service; + return ( +
  • + + {name} ({count}) + +
  • + ); + })} +
+ + + {formatRelativeDate(startTime / 1000)} + + {timeStr.slice(0, -3)} {timeStr.slice(-2)} +
+ {fromNow} + +
+ +
+ ); + } +} diff --git a/src/components/SearchTracePage/SearchResults/ResultItem.markers.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.markers.js similarity index 100% rename from src/components/SearchTracePage/SearchResults/ResultItem.markers.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.markers.js diff --git a/src/components/SearchTracePage/SearchResults/ResultItem.test.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.test.js similarity index 71% rename from src/components/SearchTracePage/SearchResults/ResultItem.test.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.test.js index 4ea7bb7ed5..df79c3a9e2 100644 --- a/src/components/SearchTracePage/SearchResults/ResultItem.test.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.test.js @@ -18,43 +18,25 @@ import { shallow } from 'enzyme'; import ResultItem from './ResultItem'; import * as markers from './ResultItem.markers'; +import traceGenerator from '../../../demo/trace-generators'; +import transformTraceData from '../../../model/transform-trace-data'; -const testTraceProps = { - duration: 100, - services: [ - { - name: 'Service A', - numberOfSpans: 2, - percentOfTrace: 50, - }, - ], - startTime: Date.now(), - numberOfSpans: 5, -}; +const trace = transformTraceData(traceGenerator.trace({})); it(' should render base case correctly', () => { - const wrapper = shallow(); - + const wrapper = shallow(); const numberOfSpanText = wrapper .find(`[data-test="${markers.NUM_SPANS}"]`) .first() .render() .text(); const numberOfServicesTags = wrapper.find(`[data-test="${markers.SERVICE_TAGS}"]`).find(Tag).length; - expect(numberOfSpanText).toBe('5 Spans'); - expect(numberOfServicesTags).toBe(1); + expect(numberOfSpanText).toBe(`${trace.spans.length} Spans`); + expect(numberOfServicesTags).toBe(trace.services.length); }); it(' should not render any ServiceTags when there are no services', () => { - const wrapper = shallow( - - ); + const wrapper = shallow(); const numberOfServicesTags = wrapper.find(`[data-test="${markers.SERVICE_TAGS}"]`).find(Tag).length; expect(numberOfServicesTags).toBe(0); }); diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItemTitle.css b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItemTitle.css new file mode 100644 index 0000000000..8415c99d6e --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItemTitle.css @@ -0,0 +1,63 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.ResultItemTitle { + background: #ececec; + border-bottom: 1px solid #d8d8d8; + display: flex; +} + +.ResultItemTitle--item { + color: inherit; + padding: 0.5rem; + position: relative; +} + +.ResultItemTitle--item:first-child { + border-right: 1px solid #ddd; +} + +.ResultItemTitle--item:hover { + background: #e4e4e4; + border-color: #ccc; +} + +.ResultItemTitle--title { + margin: 0; + position: relative; +} + +.ResultItemTitle--title.is-error { + color: #c00; +} + +.ResultItemTitle--idExcerpt { + color: #888; + font-weight: normal; + padding-left: 0.5rem; +} + +.ResultItemTitle--durationBar { + background: #d7e7ea; + bottom: 0; + left: 0; + position: absolute; + top: 0; +} + +.ResultItemTitle--item:hover > .ResultItemTitle--durationBar { + background: #c5dde0; +} diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItemTitle.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItemTitle.js new file mode 100644 index 0000000000..b544eaa9d5 --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItemTitle.js @@ -0,0 +1,94 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { Checkbox } from 'antd'; +import { Link } from 'react-router-dom'; + +import TraceName from '../../common/TraceName'; +import { fetchedState } from '../../../constants'; +import { formatDuration } from '../../../utils/date'; + +import type { FetchedState } from '../../../types'; +import type { ApiError } from '../../../types/api-error'; + +import './ResultItemTitle.css'; + +type Props = { + duration: number, + durationPercent: number, + error?: ApiError, + isInDiffCohort: boolean, + linkTo: ?string, + state: ?FetchedState, + toggleComparison: (string, boolean) => void, + traceID: string, + traceName: string, +}; + +export default class ResultItemTitle extends React.PureComponent { + props: Props; + + static defaultProps = { + durationPercent: 0, + error: undefined, + state: fetchedState.DONE, + linkTo: null, + }; + + toggleComparison = () => { + const { isInDiffCohort, toggleComparison, traceID } = this.props; + toggleComparison(traceID, isInDiffCohort); + }; + + render() { + const { + duration, + durationPercent, + error, + isInDiffCohort, + linkTo, + state, + traceID, + traceName, + } = this.props; + let WrapperComponent = 'div'; + const wrapperProps: { [string]: string } = { className: 'ResultItemTitle--item ub-flex-auto' }; + if (linkTo) { + WrapperComponent = Link; + wrapperProps.to = linkTo; + } + const isErred = state === fetchedState.ERROR; + return ( +
+ + + + {duration != null && {formatDuration(duration)}} +

+ + {traceID.slice(0, 7)} +

+
+
+ ); + } +} diff --git a/src/components/SearchTracePage/SearchResults/ScatterPlot.css b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ScatterPlot.css similarity index 100% rename from src/components/SearchTracePage/SearchResults/ScatterPlot.css rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ScatterPlot.css diff --git a/src/components/SearchTracePage/SearchResults/ScatterPlot.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ScatterPlot.js similarity index 100% rename from src/components/SearchTracePage/SearchResults/ScatterPlot.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ScatterPlot.js diff --git a/src/components/SearchTracePage/SearchResults/ScatterPlot.test.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ScatterPlot.test.js similarity index 100% rename from src/components/SearchTracePage/SearchResults/ScatterPlot.test.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ScatterPlot.test.js diff --git a/src/components/SearchTracePage/SearchResults/index.css b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.css similarity index 100% rename from src/components/SearchTracePage/SearchResults/index.css rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.css diff --git a/src/components/SearchTracePage/SearchResults/index.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.js similarity index 64% rename from src/components/SearchTracePage/SearchResults/index.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.js index 26d7fd0b5f..b7a9affcd8 100644 --- a/src/components/SearchTracePage/SearchResults/index.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.js @@ -17,8 +17,8 @@ import * as React from 'react'; import { Select } from 'antd'; import { Field, reduxForm, formValueSelector } from 'redux-form'; -import { Link } from 'react-router-dom'; +import DiffSelection from './DiffSelection'; import * as markers from './index.markers'; import ResultItem from './ResultItem'; import ScatterPlot from './ScatterPlot'; @@ -28,13 +28,19 @@ import { getPercentageOfDuration } from '../../../utils/date'; import prefixUrl from '../../../utils/prefix-url'; import reduxFormFieldAdapter from '../../../utils/redux-form-field-adapter'; +import type { FetchedTrace } from '../../../types'; + import './index.css'; type SearchResultsProps = { + cohortAddTrace: string => void, + cohortRemoveTrace: string => void, + diffCohort: FetchedTrace[], goToTrace: string => void, loading: boolean, maxTraceDuration: number, - traces: {}[], + skipMessage?: boolean, + traces: TraceSummary[], }; const Option = Select.Option; @@ -69,18 +75,44 @@ export const sortFormSelector = formValueSelector('traceResultsSort'); export default class SearchResults extends React.PureComponent { props: SearchResultsProps; + toggleComparison = (traceID: string, remove: boolean) => { + const { cohortAddTrace, cohortRemoveTrace } = this.props; + if (remove) { + cohortRemoveTrace(traceID); + } else { + cohortAddTrace(traceID); + } + }; + render() { - const { goToTrace, loading, maxTraceDuration, traces } = this.props; + const { loading, diffCohort, skipMessage, traces } = this.props; + const diffSelection = ; if (loading) { - return ; + return ( + + {diffCohort.length > 0 && diffSelection} + + + ); } if (!Array.isArray(traces) || !traces.length) { + if (skipMessage && !diffCohort.length) { + return null; + } + if (skipMessage && diffCohort.length) { + return diffSelection; + } return ( -
- No trace results. Try another query. -
+ + {diffCohort.length > 0 && diffSelection} +
+ No trace results. Try another query. +
+
); } + const { goToTrace, maxTraceDuration } = this.props; + const cohortIds = new Set(diffCohort.map(datum => datum.id)); return (
@@ -88,10 +120,10 @@ export default class SearchResults extends React.PureComponent ({ - x: t.timestamp, + x: t.startTime, y: t.duration, traceID: t.traceID, - size: t.numberOfSpans, + size: t.spans.length, name: t.traceName, }))} onValueClick={t => { @@ -108,15 +140,17 @@ export default class SearchResults extends React.PureComponent
+ {diffSelection}
    {traces.map(trace => (
  • - - - +
  • ))}
diff --git a/src/components/SearchTracePage/SearchResults/index.markers.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.markers.js similarity index 100% rename from src/components/SearchTracePage/SearchResults/index.markers.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.markers.js diff --git a/src/components/SearchTracePage/SearchResults/index.test.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.test.js similarity index 98% rename from src/components/SearchTracePage/SearchResults/index.test.js rename to packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.test.js index c8ac6bdaf6..df5ad9f588 100644 --- a/src/components/SearchTracePage/SearchResults/index.test.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.test.js @@ -29,10 +29,11 @@ describe('', () => { beforeEach(() => { traces = [{ traceID: 'a', spans: [], processes: {} }, { traceID: 'b', spans: [], processes: {} }]; props = { - traces, + diffCohort: [], goToTrace: () => {}, loading: false, maxTraceDuration: 1, + traces, }; wrapper = shallow(); }); diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/react-vis.css b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/react-vis.css new file mode 120000 index 0000000000..7cb9d77574 --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/react-vis.css @@ -0,0 +1 @@ +../../../../../../node_modules/react-vis/dist/style.css \ No newline at end of file diff --git a/src/components/SearchTracePage/index.css b/packages/jaeger-ui/src/components/SearchTracePage/index.css similarity index 100% rename from src/components/SearchTracePage/index.css rename to packages/jaeger-ui/src/components/SearchTracePage/index.css diff --git a/src/components/SearchTracePage/index.js b/packages/jaeger-ui/src/components/SearchTracePage/index.js similarity index 71% rename from src/components/SearchTracePage/index.js rename to packages/jaeger-ui/src/components/SearchTracePage/index.js index c832f0590b..65cd1b59d8 100644 --- a/src/components/SearchTracePage/index.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/index.js @@ -14,7 +14,6 @@ import React, { Component } from 'react'; import { Col, Row } from 'antd'; -import _values from 'lodash/values'; import PropTypes from 'prop-types'; import queryString from 'query-string'; import { connect } from 'react-redux'; @@ -22,23 +21,37 @@ import { bindActionCreators } from 'redux'; import store from 'store'; import * as jaegerApiActions from '../../actions/jaeger-api'; +import { actions as traceDiffActions } from '../TraceDiff/duck'; import SearchForm from './SearchForm'; import SearchResults, { sortFormSelector } from './SearchResults'; import ErrorMessage from '../common/ErrorMessage'; import LoadingIndicator from '../common/LoadingIndicator'; -import { sortTraces, getTraceSummaries } from '../../model/search'; +import { fetchedState } from '../../constants'; +import { sortTraces } from '../../model/search'; import getLastXformCacher from '../../utils/get-last-xform-cacher'; import prefixUrl from '../../utils/prefix-url'; import './index.css'; import JaegerLogo from '../../img/jaeger-logo.svg'; -export default class SearchTracePage extends Component { +// export for tests +export class SearchTracePageImpl extends Component { componentDidMount() { - const { searchTraces, urlQueryParams, fetchServices, fetchServiceOperations } = this.props; + const { + diffCohort, + fetchMultipleTraces, + searchTraces, + urlQueryParams, + fetchServices, + fetchServiceOperations, + } = this.props; if (urlQueryParams.service || urlQueryParams.traceID) { searchTraces(urlQueryParams); } + const needForDiffs = diffCohort.filter(ft => ft.state == null).map(ft => ft.id); + if (needForDiffs.length) { + fetchMultipleTraces(needForDiffs); + } fetchServices(); const { service } = store.get('lastSearch') || {}; if (service && service !== '-') { @@ -52,6 +65,9 @@ export default class SearchTracePage extends Component { render() { const { + cohortAddTrace, + cohortRemoveTrace, + diffCohort, errors, isHomepage, loadingServices, @@ -79,6 +95,18 @@ export default class SearchTracePage extends Component { {errors.map(err => )}
)} + {!showErrors && ( + + )} {showLogo && ( )} - {!showErrors && - !showLogo && ( - - )}
@@ -103,10 +122,13 @@ export default class SearchTracePage extends Component { } } -SearchTracePage.propTypes = { +SearchTracePageImpl.propTypes = { isHomepage: PropTypes.bool, // eslint-disable-next-line react/forbid-prop-types traceResults: PropTypes.array, + diffCohort: PropTypes.array, + cohortAddTrace: PropTypes.func, + cohortRemoveTrace: PropTypes.func, maxTraceDuration: PropTypes.number, loadingServices: PropTypes.bool, loadingTraces: PropTypes.bool, @@ -124,6 +146,7 @@ SearchTracePage.propTypes = { history: PropTypes.shape({ push: PropTypes.func, }), + fetchMultipleTraces: PropTypes.func, fetchServiceOperations: PropTypes.func, fetchServices: PropTypes.func, errors: PropTypes.arrayOf( @@ -134,11 +157,20 @@ SearchTracePage.propTypes = { }; const stateTraceXformer = getLastXformCacher(stateTrace => { - const { traces: traceMap, loading: loadingTraces, error: traceError } = stateTrace; - const { traces, maxDuration } = getTraceSummaries(_values(traceMap)); + const { traces: traceMap, search } = stateTrace; + const { results, state, error: traceError } = search; + const loadingTraces = state === fetchedState.LOADING; + const traces = results.map(id => traceMap[id].data); + const maxDuration = Math.max.apply(null, traces.map(tr => tr.duration)); return { traces, maxDuration, traceError, loadingTraces }; }); +const stateTraceDiffXformer = getLastXformCacher((stateTrace, stateTraceDiff) => { + const { traces } = stateTrace; + const { cohort } = stateTraceDiff; + return cohort.map(id => traces[id] || { id }); +}); + const sortedTracesXformer = getLastXformCacher((traces, sortBy) => { const traceResults = traces.slice(); sortTraces(traceResults, sortBy); @@ -166,6 +198,7 @@ export function mapStateToProps(state) { const query = queryString.parse(state.router.location.search); const isHomepage = !Object.keys(query).length; const { traces, maxDuration, traceError, loadingTraces } = stateTraceXformer(state.trace); + const diffCohort = stateTraceDiffXformer(state.trace, state.traceDiff); const { loadingServices, services, serviceError } = stateServicesXformer(state.services); const errors = []; if (traceError) { @@ -177,11 +210,12 @@ export function mapStateToProps(state) { const sortBy = sortFormSelector(state, 'sortBy'); const traceResults = sortedTracesXformer(traces, sortBy); return { + diffCohort, isHomepage, + loadingServices, + loadingTraces, services, traceResults, - loadingTraces, - loadingServices, errors: errors.length ? errors : null, maxTraceDuration: maxDuration, sortTracesBy: sortBy, @@ -190,14 +224,19 @@ export function mapStateToProps(state) { } function mapDispatchToProps(dispatch) { - const { searchTraces, fetchServices, fetchServiceOperations } = bindActionCreators( + const { fetchMultipleTraces, fetchServiceOperations, fetchServices, searchTraces } = bindActionCreators( jaegerApiActions, dispatch ); + const { cohortAddTrace, cohortRemoveTrace } = bindActionCreators(traceDiffActions, dispatch); return { + cohortAddTrace, + cohortRemoveTrace, + fetchMultipleTraces, fetchServiceOperations, fetchServices, searchTraces, }; } -export const ConnectedSearchTracePage = connect(mapStateToProps, mapDispatchToProps)(SearchTracePage); + +export default connect(mapStateToProps, mapDispatchToProps)(SearchTracePageImpl); diff --git a/src/components/SearchTracePage/index.test.js b/packages/jaeger-ui/src/components/SearchTracePage/index.test.js similarity index 82% rename from src/components/SearchTracePage/index.test.js rename to packages/jaeger-ui/src/components/SearchTracePage/index.test.js index 7bd04d0975..0c93ea1275 100644 --- a/src/components/SearchTracePage/index.test.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/index.test.js @@ -31,9 +31,10 @@ import React from 'react'; import { shallow, mount } from 'enzyme'; import store from 'store'; -import SearchTracePage, { mapStateToProps } from './index'; +import { SearchTracePageImpl as SearchTracePage, mapStateToProps } from './index'; import SearchForm from './SearchForm'; import LoadingIndicator from '../common/LoadingIndicator'; +import { fetchedState } from '../../constants'; import traceGenerator from '../../demo/trace-generators'; import { MOST_RECENT } from '../../model/order-by'; import transformTraceData from '../../model/transform-trace-data'; @@ -51,6 +52,7 @@ describe('', () => { loadingServices: false, loadingTraces: false, maxTraceDuration: 100, + diffCohort: [], numberOfTraceResults: traceResults.length, services: null, sortTracesBy: MOST_RECENT, @@ -103,7 +105,15 @@ describe('', () => { describe('mapStateToProps()', () => { it('converts state to the necessary props', () => { const trace = transformTraceData(traceGenerator.trace({})); - const stateTrace = { traces: [trace], loading: false, error: null }; + const stateTrace = { + search: { + results: [trace.traceID], + state: fetchedState.DONE, + }, + traces: { + [trace.traceID]: { id: trace.traceID, data: trace, state: fetchedState.DONE }, + }, + }; const stateServices = { loading: false, services: ['svc-a'], @@ -113,13 +123,21 @@ describe('mapStateToProps()', () => { const state = { router: { location: { search: '' } }, trace: stateTrace, + traceDiff: { + cohort: [trace.traceID], + }, services: stateServices, }; - const { maxTraceDuration, traceResults, numberOfTraceResults, ...rest } = mapStateToProps(state); - expect(traceResults.length).toBe(stateTrace.traces.length); + const { maxTraceDuration, traceResults, diffCohort, numberOfTraceResults, ...rest } = mapStateToProps( + state + ); + expect(traceResults.length).toBe(stateTrace.search.results.length); expect(traceResults[0].traceID).toBe(trace.traceID); - expect(maxTraceDuration).toBe(trace.duration / 1000); + expect(maxTraceDuration).toBe(trace.duration); + expect(diffCohort.length).toBe(state.traceDiff.cohort.length); + expect(diffCohort[0].id).toBe(trace.traceID); + expect(diffCohort[0].data.traceID).toBe(trace.traceID); expect(rest).toEqual({ isHomepage: true, diff --git a/packages/jaeger-ui/src/components/SearchTracePage/url.js b/packages/jaeger-ui/src/components/SearchTracePage/url.js new file mode 100644 index 0000000000..130485c8e6 --- /dev/null +++ b/packages/jaeger-ui/src/components/SearchTracePage/url.js @@ -0,0 +1,33 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import queryString from 'query-string'; +import { matchPath } from 'react-router-dom'; + +import prefixUrl from '../../utils/prefix-url'; + +export const ROUTE_PATH = prefixUrl('/search'); + +const ROUTE_MATCHER = { path: ROUTE_PATH, strict: true, exact: true }; + +export function matches(path: string) { + return Boolean(matchPath(path, ROUTE_MATCHER)); +} + +export function getUrl(query?: ?Object) { + const search = query ? queryString.stringify(query) : ''; + return prefixUrl(`/search?${search}`); +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiff.css b/packages/jaeger-ui/src/components/TraceDiff/TraceDiff.css new file mode 100644 index 0000000000..e628fe8f83 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiff.css @@ -0,0 +1,24 @@ +/* +Copyright (c) 2018 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.TraceDiff--graphWrapper { + background: #f0f0f0; + bottom: 0; + left: 0; + position: fixed; + right: 0; + top: 0; +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiff.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiff.js new file mode 100644 index 0000000000..15fa072b2d --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiff.js @@ -0,0 +1,185 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import queryString from 'query-string'; +import { connect } from 'react-redux'; +import { bindActionCreators } from 'redux'; + +import type { Match, RouterHistory } from 'react-router-dom'; + +import { actions as diffActions } from './duck'; +import { getUrl } from './url'; +import TraceDiffGraph from './TraceDiffGraph'; +import TraceDiffHeader from './TraceDiffHeader'; +import * as jaegerApiActions from '../../actions/jaeger-api'; +import { TOP_NAV_HEIGHT } from '../../constants'; + +import type { FetchedTrace, ReduxState } from '../../types'; +import type { TraceDiffState } from '../../types/trace-diff'; + +import './TraceDiff.css'; + +type Props = { + a: ?string, + b: ?string, + cohort: string[], + fetchMultipleTraces: (string[]) => void, + forceState: TraceDiffState => void, + history: RouterHistory, + tracesData: Map, + traceDiffState: TraceDiffState, +}; + +type State = { + graphTopOffset: number, +}; + +function syncStates(urlSt, reduxSt, forceState) { + const { a: urlA, b: urlB } = urlSt; + const { a: reduxA, b: reduxB } = reduxSt; + if (urlA !== reduxA || urlB !== reduxB) { + forceState(urlSt); + return; + } + const urlCohort = new Set(urlSt.cohort || []); + const reduxCohort = new Set(reduxSt.cohort || []); + if (urlCohort.size !== reduxCohort.size) { + forceState(urlSt); + return; + } + const needSync = Array.from(urlCohort).some(id => !reduxCohort.has(id)); + if (needSync) { + forceState(urlSt); + } +} + +export class TraceDiffImpl extends React.PureComponent { + props: Props; + headerWrapperElm: ?Element; + + constructor() { + super(); + this.headerWrapperElm = null; + this.state = { + graphTopOffset: TOP_NAV_HEIGHT, + }; + } + + componentDidMount() { + this.processProps(); + } + + componentDidUpdate() { + this.setGraphTopOffset(); + this.processProps(); + } + + headerWrapperRef = (elm: ?Element) => { + this.headerWrapperElm = elm; + this.setGraphTopOffset(); + }; + + setGraphTopOffset() { + if (this.headerWrapperElm) { + const graphTopOffset = TOP_NAV_HEIGHT + this.headerWrapperElm.clientHeight; + if (this.state.graphTopOffset !== graphTopOffset) { + this.setState({ graphTopOffset }); + } + } else { + this.setState({ graphTopOffset: TOP_NAV_HEIGHT }); + } + } + + processProps() { + const { a, b, cohort, fetchMultipleTraces, forceState, tracesData, traceDiffState } = this.props; + syncStates({ a, b, cohort }, traceDiffState, forceState); + const cohortData = cohort.map(id => tracesData.get(id) || { id, state: null }); + const needForDiffs = cohortData.filter(ft => ft.state == null).map(ft => ft.id); + if (needForDiffs.length) { + fetchMultipleTraces(needForDiffs); + } + } + + diffSetUrl(change: { newA?: ?string, newB?: ?string }) { + const { newA, newB } = change; + const { a, b, cohort, history } = this.props; + const url = getUrl({ a: newA || a, b: newB || b, cohort }); + history.push(url); + } + + diffSetA = (id: string) => { + const newA = id.toLowerCase(); + this.diffSetUrl({ newA }); + }; + + diffSetB = (id: string) => { + const newB = id.toLowerCase(); + this.diffSetUrl({ newB }); + }; + + render() { + const { a, b, cohort, tracesData } = this.props; + const { graphTopOffset } = this.state; + const traceA = a ? tracesData.get(a) || { id: a } : null; + const traceB = b ? tracesData.get(b) || { id: b } : null; + const cohortData: FetchedTrace[] = cohort.map(id => tracesData.get(id) || { id }); + return ( + +
+ +
+
+ +
+
+ ); + } +} + +// TODO(joe): simplify but do not invalidate the URL +export function mapStateToProps(state: ReduxState, ownProps: { match: Match }) { + const { a, b } = ownProps.match.params; + const { cohort: origCohort = [] } = queryString.parse(state.router.location.search); + const fullCohortSet: Set = new Set([].concat(a, b, origCohort).filter(Boolean)); + const cohort: string[] = Array.from(fullCohortSet); + const { traces } = state.trace; + const kvPairs = cohort.map(id => [id, traces[id] || { id, state: null }]); + const tracesData: Map = new Map(kvPairs); + return { + a, + b, + cohort, + tracesData, + traceDiffState: state.traceDiff, + }; +} + +// export for tests +export function mapDispatchToProps(dispatch: Function) { + const { fetchMultipleTraces } = bindActionCreators(jaegerApiActions, dispatch); + const { forceState } = bindActionCreators(diffActions, dispatch); + return { fetchMultipleTraces, forceState }; +} + +export default connect(mapStateToProps, mapDispatchToProps)(TraceDiffImpl); diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/TraceDiffGraph.css b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/TraceDiffGraph.css new file mode 100644 index 0000000000..9d2353eb4b --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/TraceDiffGraph.css @@ -0,0 +1,92 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.TraceDiffGraph--graphWrapper { + bottom: 0; + cursor: move; + left: 0; + overflow: auto; + position: absolute; + right: 0; + top: 0; +} + +.TraceDiffGraph--errorsWrapper { + background: #eee; + bottom: 0; + left: 0; + overflow: auto; + padding: 5rem 3.5rem; + position: absolute; + right: 0; + top: 0; +} + +.TraceDiffGraph--errorMessage { + font-size: 1.8rem; +} + +.TraceDiffGraph--dag { + stroke-width: 1.2; +} + +.TraceDiffGraph--dag.is-small { + stroke-width: 0.7; +} + +/* DAG minimap */ + +.TraceDiffGraph--miniMap { + align-items: flex-end; + bottom: 1rem; + display: flex; + left: 1rem; + position: absolute; + z-index: 1; +} + +.TraceDiffGraph--miniMap > .plexus-MiniMap--item { + border: 1px solid #777; + background: #999; + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + margin-right: 1rem; + position: relative; +} + +.TraceDiffGraph--miniMap > .plexus-MiniMap--map { + /* dynamic widht, height */ + box-sizing: content-box; + cursor: not-allowed; +} + +.TraceDiffGraph--miniMap .plexus-MiniMap--mapActive { + /* dynamic: width, height, transform */ + background: #ccc; + position: absolute; +} + +.TraceDiffGraph--miniMap > .plexus-MiniMap--button { + background: #ccc; + color: #888; + cursor: pointer; + font-size: 1.6em; + line-height: 0; + padding: 0.1rem; +} + +.TraceDiffGraph--miniMap > .plexus-MiniMap--button:hover { + background: #ddd; +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/TraceDiffGraph.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/TraceDiffGraph.js new file mode 100644 index 0000000000..2f182644f1 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/TraceDiffGraph.js @@ -0,0 +1,118 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { DirectedGraph, LayoutManager } from '@jaegertracing/plexus'; + +import drawNode from './drawNode'; +import ErrorMessage from '../../common/ErrorMessage'; +import LoadingIndicator from '../../common/LoadingIndicator'; +import { fetchedState } from '../../../constants'; +import convPlexus from '../../../model/trace-dag/convPlexus'; +import TraceDag from '../../../model/trace-dag/TraceDag'; + +import type { FetchedTrace } from '../../../types'; + +import './TraceDiffGraph.css'; + +type Props = { + a: ?FetchedTrace, + b: ?FetchedTrace, +}; + +const { classNameIsSmall } = DirectedGraph.propsFactories; + +function setOnEdgesContainer(state: Object) { + const { zoomTransform } = state; + if (!zoomTransform) { + return null; + } + const { k } = zoomTransform; + const opacity = 0.1 + k * 0.9; + return { style: { opacity } }; +} + +export default class TraceDiffGraph extends React.PureComponent { + props: Props; + + layoutManager: LayoutManager; + + constructor(props: Props) { + super(props); + this.layoutManager = new LayoutManager({ useDotEdges: true, splines: 'polyline' }); + } + + componentWillUnmount() { + this.layoutManager.stopAndRelease(); + } + + render() { + const { a, b } = this.props; + if (!a || !b) { + return

At least two Traces are needed

; + } + if (a.error || b.error) { + return ( +
+ {a.error && ( + + )} + {b.error && ( + + )} +
+ ); + } + if (a.state === fetchedState.LOADING || b.state === fetchedState.LOADING) { + return ; + } + const aData = a.data; + const bData = b.data; + if (!aData || !bData) { + return
; + } + const aTraceDag = TraceDag.newFromTrace(aData); + const bTraceDag = TraceDag.newFromTrace(bData); + const diffDag = TraceDag.diff(aTraceDag, bTraceDag); + const { edges, vertices } = convPlexus(diffDag.nodesMap); + + return ( +
+ +
+ ); + } +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/drawNode.css b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/drawNode.css new file mode 100644 index 0000000000..f09ba89814 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/drawNode.css @@ -0,0 +1,96 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.DiffNode { + background: #bbb; + border: 1px solid #777; + box-shadow: 0 0px 3px rgba(0, 0, 0, 0.2); + cursor: pointer; + white-space: nowrap; +} + +.TraceDiffGraph--dag.is-small .DiffNode > tbody { + opacity: 0; +} + +.DiffNode.is-changed { + color: rgba(0, 0, 0, 0.85); +} + +.DiffNode.is-more { + background: #78d539; + border-color: #2a8f04; +} + +.DiffNode.is-added { + background: #2a8f04; + border: none; + color: #fff; +} + +.DiffNode.is-less { + border-color: #cc1616; + background: #ffa39e; +} + +.DiffNode.is-removed { + background: #cc1616; + border: none; + color: #fff; +} + +.DiffNode--metricCell { + padding: 0.3rem 0.5rem; + background: rgba(255, 255, 255, 0.3); +} + +.DiffNode--metricCell.is-changed { + font-weight: 500; +} + +.DiffNode--metricCell.is-added, +.DiffNode--metricCell.is-removed { + background: rgba(0, 0, 0, 0.2); +} + +.DiffNode--metricSymbol { + margin: 0 0.1em; +} + +.DiffNode--labelCell { + padding: 0.3rem 0.5rem 0.3rem 0.75rem; +} + +/* Tweak the popover aesthetics - unfortunate but necessary */ + +.DiffNode--popover .ant-popover-inner-content { + padding: 0; + position: relative; +} + +.DiffNode--popover.is-same .ant-popover-arrow { + background: #777; +} + +.DiffNode--popover.is-more .ant-popover-arrow, +.DiffNode--popover.is-added .ant-popover-arrow { + background: #2a8f04; +} + +.DiffNode--popover.is-less .ant-popover-arrow, +.DiffNode--popover.is-removed .ant-popover-arrow { + background: #cc1616; +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/drawNode.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/drawNode.js new file mode 100644 index 0000000000..cbe2d3b9f6 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/drawNode.js @@ -0,0 +1,87 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { Popover } from 'antd'; +import cx from 'classnames'; + +import type { PVertex } from '../../../model/trace-dag/types'; + +import './drawNode.css'; + +type Props = { + a: number, + b: number, + operation: string, + service: string, +}; + +const abs = Math.abs; +const max = Math.max; + +class DiffNode extends React.PureComponent { + props: Props; + + render() { + const { a, b, operation, service } = this.props; + const isSame = a === b; + const className = cx({ + 'is-same': isSame, + 'is-changed': !isSame, + 'is-more': b > a && a > 0, + 'is-added': a === 0, + 'is-less': a > b && b > 0, + 'is-removed': b === 0, + }); + const chgSign = a < b ? '+' : '-'; + const table = ( + + + + + + + + {isSame ? null : ( + + )} + + + +
+ {isSame ? null : {chgSign}} + {isSame ? a : abs(b - a)} + + {service} +
+ {chgSign} + {a === 0 || b === 0 ? 100 : abs((a - b) / max(a, b) * 100).toFixed(0)} + % + {operation}
+ ); + + return ( + + {table} + + ); + } +} + +export default function drawNode(vertex: PVertex) { + const { data, operation, service } = vertex.data; + return ; +} diff --git a/src/constants/index.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/index.js similarity index 84% rename from src/constants/index.js rename to packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/index.js index d6515888f5..61c7e35901 100644 --- a/src/constants/index.js +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffGraph/index.js @@ -1,3 +1,5 @@ +// @flow + // Copyright (c) 2017 Uber Technologies, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,5 +14,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -export const FALLBACK_DAG_MAX_NUM_SERVICES = 100; -export const FALLBACK_TRACE_NAME = ''; +export { default } from './TraceDiffGraph'; diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/CohortTable.css b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/CohortTable.css new file mode 100644 index 0000000000..2e6348c6c1 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/CohortTable.css @@ -0,0 +1,24 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.CohortTable--traceName { + color: rgba(0, 0, 0, 0.85); +} + +.CohortTable--needMoreMsg { + border-radius: 4px; + padding: 1rem; +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/CohortTable.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/CohortTable.js new file mode 100644 index 0000000000..a7b36d6021 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/CohortTable.js @@ -0,0 +1,135 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { Table, Tag } from 'antd'; + +import RelativeDate from '../../common/RelativeDate'; +import TraceName from '../../common/TraceName'; +import { fetchedState } from '../../../constants'; +import { formatDuration } from '../../../utils/date'; + +import type { FetchedTrace } from '../../../types'; + +import './CohortTable.css'; + +type Props = { + selection: { + [string]: { label: string }, + }, + current: ?string, + cohort: FetchedTrace[], + selectTrace: string => void, +}; + +const { Column } = Table; + +const defaultRowSelection = { + hideDefaultSelections: true, + type: 'radio', +}; + +const NEED_MORE_TRACES_MESSAGE = ( +

+ Enter a Trace ID or perform a search and select from the results. +

+); + +export default class CohortTable extends React.PureComponent { + props: Props; + + getCheckboxProps = (record: FetchedTrace) => { + const { current, selection } = this.props; + const { id, state } = record; + if (state === fetchedState.ERROR || (id in selection && id !== current)) { + return { disabled: true }; + } + return {}; + }; + + render() { + const { cohort, current, selection, selectTrace } = this.props; + const rowSelection = { + ...defaultRowSelection, + getCheckboxProps: this.getCheckboxProps, + onChange: ids => selectTrace(ids[0]), + selectedRowKeys: current ? [current] : [], + }; + + return [ + + {value && value.slice(0, 7)}} + /> + { + const { data, error, id, state } = record; + const { traceName } = data || {}; + const { label } = selection[id] || {}; + return ( + + {label != null && ( + + {label} + + )} + + + ); + }} + /> + + record.state === fetchedState.DONE && ( + + ) + } + /> + record.state === fetchedState.DONE && formatDuration(value)} + /> + +
, + cohort.length < 2 && NEED_MORE_TRACES_MESSAGE, + ]; + } +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceDiffHeader.css b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceDiffHeader.css new file mode 100644 index 0000000000..f4d0904859 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceDiffHeader.css @@ -0,0 +1,47 @@ +/* +Copyright (c) 2018 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.TraecDiffHeader { + background: #fff; + border-bottom: 1px solid #d8d8d8; + box-shadow: 0 2px 5px 0px rgba(0, 0, 0, 0.35); + display: flex; + flex: 0; + position: relative; + z-index: 1; +} + +.TraecDiffHeader--labelItem, +.TraecDiffHeader--labelItem-darkened { + align-items: center; + border-right: 1px solid #d8d8d8; + display: flex; + padding: 0 1.25rem; +} + +.TraecDiffHeader--labelItem-darkened { + background: #eee; +} + +/* Unfortunate but necessary */ + +.TraceDiffHeader--popover .ant-popover-title { + padding: 0.25rem; +} + +.TraceDiffHeader--popover .ant-popover-inner-content { + padding: 0; +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceDiffHeader.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceDiffHeader.js new file mode 100644 index 0000000000..59bce3ee40 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceDiffHeader.js @@ -0,0 +1,145 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { Popover } from 'antd'; + +import CohortTable from './CohortTable'; +import TraceHeader from './TraceHeader'; +import TraceIdInput from './TraceIdInput'; + +import type { FetchedTrace } from '../../../types'; + +import './TraceDiffHeader.css'; + +type Props = { + a: ?FetchedTrace, + b: ?FetchedTrace, + cohort: FetchedTrace[], + diffSetA: string => void, + diffSetB: string => void, +}; + +type State = { + tableVisible: ?('a' | 'b'), +}; + +export default class TraceDiffHeader extends React.PureComponent { + props: Props; + + _toggleTableA: boolean => void; + _toggleTableB: boolean => void; + _diffSetA: string => void; + _diffSetB: string => void; + + state = { + tableVisible: null, + }; + + constructor(props: Props) { + super(props); + this._toggleTableA = this._toggleTable.bind(this, 'a'); + this._toggleTableB = this._toggleTable.bind(this, 'b'); + this._diffSetA = this._diffSetTrace.bind(this, 'a'); + this._diffSetB = this._diffSetTrace.bind(this, 'b'); + } + + _toggleTable(which: 'a' | 'b', visible: boolean) { + const tableVisible = visible ? which : null; + this.setState({ tableVisible }); + } + + _diffSetTrace(which: 'a' | 'b', id: string) { + if (which === 'a') { + this.props.diffSetA(id); + } else { + this.props.diffSetB(id); + } + this.setState({ tableVisible: null }); + } + + render() { + const { a, b, cohort } = this.props; + const { tableVisible } = this.state; + const { data: aData = {}, id: aId, state: aState, error: aError } = a || {}; + const { data: bData = {}, id: bId, state: bState, error: bError } = b || {}; + const selection = { + [aId || '_']: { label: 'A' }, + [bId || '__']: { label: 'B' }, + }; + const cohortTableA = ( + + ); + const cohortTableB = ( + + ); + return ( +
+
+

A

+
+ } + content={cohortTableA} + visible={tableVisible === 'a'} + onVisibleChange={this._toggleTableA} + > +
+ +
+
+
+

VS

+
+
+

B

+
+ } + content={cohortTableB} + visible={tableVisible === 'b'} + onVisibleChange={this._toggleTableB} + > +
+ +
+
+
+ ); + } +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceHeader.css b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceHeader.css new file mode 100644 index 0000000000..8e4b005cce --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceHeader.css @@ -0,0 +1,60 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.TraecDiffHeader--traceHeader { + align-items: stretch; + background: #fafafa; + border-right: 1px solid #d8d8d8; + display: flex; + flex-direction: column; + flex: 1; +} + +.TraecDiffHeader--traceTitle { + align-items: center; + background: #fff; + border-bottom: 1px solid #eee; + display: flex; + flex: 1; + font-size: 1.8em; + margin: 0; + padding: 0.25rem 2.5rem 0.25rem 1.25rem; + position: relative; +} + +.TraecDiffHeader--traceTitle.is-error { + color: #c00; +} + +.TraecDiffHeader--traceTitleChevron { + color: rgba(0, 0, 0, 0.85); + font-size: 0.75em; + margin-right: 0.75em; + position: absolute; + right: 0; + top: calc(50% - 0.5em); +} + +.TraecDiffHeader--traceAttributes { + list-style: none; + margin: 0; + padding: 0.25rem 1.25rem; +} + +.TraecDiffHeader--traceAttr { + display: inline-block; + margin-right: 1rem; +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceHeader.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceHeader.js new file mode 100644 index 0000000000..35a313c2ef --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceHeader.js @@ -0,0 +1,105 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import IoChevronDown from 'react-icons/lib/io/chevron-down'; + +import RelativeDate from '../../common/RelativeDate'; +import TraceName from '../../common/TraceName'; +import { fetchedState } from '../../../constants'; +import { formatDuration } from '../../../utils/date'; + +import type { FetchedState } from '../../../types'; +import type { ApiError } from '../../../types/api-error'; + +import './TraceHeader.css'; + +type Props = { + duration: ?number, + error?: ApiError, + startTime: ?number, + state: ?FetchedState, + traceID: ?string, + traceName: ?string, + totalSpans: ?number, +}; + +type AttrsProps = { + startTime: ?number, + duration: ?number, + totalSpans: ?number, +}; + +function EmptyAttrs() { + return ( +
    +
  •  
  • +
+ ); +} + +function Attrs(props: AttrsProps) { + const { startTime, duration, totalSpans } = props; + return ( +
    +
  • + + + +
  • +
  • + Duration: + {formatDuration(duration || 0)} +
  • +
  • + Spans: {totalSpans || 0} +
  • +
+ ); +} + +export default function TraceHeader(props: Props) { + const { duration, error, startTime, state, traceID, totalSpans, traceName } = props; + const AttrsComponent = state === fetchedState.DONE ? Attrs : EmptyAttrs; + return ( +
+

+ + {traceID ? ( + + {' '} + + {(traceID || '').slice(0, 7)} + + + ) : ( + Select a Trace... + )} + + +

+ +
+ ); +} + +TraceHeader.defaultProps = { + startTime: null, + duration: null, + error: undefined, + state: undefined, + totalSpans: null, +}; diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceIdInput.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceIdInput.js new file mode 100644 index 0000000000..ab5fd68927 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/TraceIdInput.js @@ -0,0 +1,29 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { Input } from 'antd'; + +type Props = { + selectTrace: string => void, +}; + +const { Search } = Input; + +export default function TraceIdInput(props: Props) { + const { selectTrace } = props; + return ; +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/index.js b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/index.js new file mode 100644 index 0000000000..01846c3ac4 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/TraceDiffHeader/index.js @@ -0,0 +1,17 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export { default } from './TraceDiffHeader'; diff --git a/packages/jaeger-ui/src/components/TraceDiff/duck.js b/packages/jaeger-ui/src/components/TraceDiff/duck.js new file mode 100644 index 0000000000..22cdbc7732 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/duck.js @@ -0,0 +1,99 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { createActions, handleActions } from 'redux-actions'; + +import generateActionTypes from '../../utils/generate-action-types'; + +// traceDiff { +// a: ?id, +// b: ?id +// cohort: id[], +// } + +export function newInitialState() { + return { + cohort: [], + a: null, + b: null, + }; +} + +export const actionTypes = generateActionTypes('@jaeger-ui/trace-diff', [ + 'COHORT_ADD_TRACE', + 'COHORT_REMOVE_TRACE', + 'DIFF_SET_A', + 'DIFF_SET_B', + 'FORCE_STATE', +]); + +const fullActions = createActions({ + [actionTypes.COHORT_ADD_TRACE]: traceID => ({ traceID }), + [actionTypes.COHORT_REMOVE_TRACE]: traceID => ({ traceID }), + [actionTypes.DIFF_SET_A]: traceID => ({ traceID }), + [actionTypes.DIFF_SET_B]: traceID => ({ traceID }), + [actionTypes.FORCE_STATE]: newState => ({ newState }), +}); + +export const actions = fullActions.jaegerUi.traceDiff; + +function cohortAddTrace(state, { payload }) { + const { traceID } = payload; + const cohort = state.cohort.slice(); + if (cohort.indexOf(traceID) >= 0) { + return state; + } + cohort.push(traceID); + return { ...state, cohort }; +} + +function cohortRemoveTrace(state, { payload }) { + const { traceID } = payload; + const cohort = state.cohort.slice(); + const i = cohort.indexOf(traceID); + if (i < 0) { + return state; + } + cohort.splice(i, 1); + const a = state.a === traceID ? null : state.a; + const b = state.b === traceID ? null : state.b; + return { ...state, a, b, cohort }; +} + +function diffSetA(state, { payload }) { + const a = payload.traceID; + return { ...state, a }; +} + +function diffSetB(state, { payload }) { + const b = payload.traceID; + return { ...state, b }; +} + +function forceState(state, { payload }) { + return payload.newState; +} + +export default handleActions( + { + [actionTypes.COHORT_ADD_TRACE]: cohortAddTrace, + [actionTypes.COHORT_REMOVE_TRACE]: cohortRemoveTrace, + [actionTypes.DIFF_SET_A]: diffSetA, + [actionTypes.DIFF_SET_B]: diffSetB, + [actionTypes.FORCE_STATE]: forceState, + }, + newInitialState() +); diff --git a/packages/jaeger-ui/src/components/TraceDiff/getValidState.js b/packages/jaeger-ui/src/components/TraceDiff/getValidState.js new file mode 100644 index 0000000000..ad1701ba47 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/getValidState.js @@ -0,0 +1,24 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export default function getValidState(state?: ?{ a?: ?string, b?: ?string, cohort: string[] }) { + const { a: stA, b: stB, cohort: stCohort } = state || {}; + const cohortSet = new Set([].concat(stA, stB, stCohort || []).filter(Boolean)); + const cohort: string[] = Array.from(cohortSet); + const a = cohort[0]; + const b = cohort[1]; + return { a, b, cohort }; +} diff --git a/packages/jaeger-ui/src/components/TraceDiff/index.js b/packages/jaeger-ui/src/components/TraceDiff/index.js new file mode 100644 index 0000000000..2ee73a6cf8 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/index.js @@ -0,0 +1,17 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export { default } from './TraceDiff'; diff --git a/packages/jaeger-ui/src/components/TraceDiff/url.js b/packages/jaeger-ui/src/components/TraceDiff/url.js new file mode 100644 index 0000000000..072d054801 --- /dev/null +++ b/packages/jaeger-ui/src/components/TraceDiff/url.js @@ -0,0 +1,35 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import queryString from 'query-string'; +import { matchPath } from 'react-router-dom'; + +import getValidState from './getValidState'; +import prefixUrl from '../../utils/prefix-url'; + +export const ROUTE_PATH = prefixUrl('/trace/:a?\\.\\.\\.:b?'); + +const ROUTE_MATCHER = { path: ROUTE_PATH, strict: true, exact: true }; + +export function matches(path: string) { + return Boolean(matchPath(path, ROUTE_MATCHER)); +} + +export function getUrl(state?: ?{ a?: ?string, b?: ?string, cohort: string[] }) { + const { a, b, cohort } = getValidState(state); + const search = queryString.stringify({ cohort }); + return prefixUrl(`/trace/${a || ''}...${b || ''}${search ? '?' : ''}${search}`); +} diff --git a/src/components/TracePage/ArchiveNotifier/duck.js b/packages/jaeger-ui/src/components/TracePage/ArchiveNotifier/duck.js similarity index 100% rename from src/components/TracePage/ArchiveNotifier/duck.js rename to packages/jaeger-ui/src/components/TracePage/ArchiveNotifier/duck.js diff --git a/src/components/TracePage/ArchiveNotifier/index.css b/packages/jaeger-ui/src/components/TracePage/ArchiveNotifier/index.css similarity index 100% rename from src/components/TracePage/ArchiveNotifier/index.css rename to packages/jaeger-ui/src/components/TracePage/ArchiveNotifier/index.css diff --git a/src/components/TracePage/ArchiveNotifier/index.js b/packages/jaeger-ui/src/components/TracePage/ArchiveNotifier/index.js similarity index 100% rename from src/components/TracePage/ArchiveNotifier/index.js rename to packages/jaeger-ui/src/components/TracePage/ArchiveNotifier/index.js diff --git a/src/components/TracePage/KeyboardShortcutsHelp.css b/packages/jaeger-ui/src/components/TracePage/KeyboardShortcutsHelp.css similarity index 100% rename from src/components/TracePage/KeyboardShortcutsHelp.css rename to packages/jaeger-ui/src/components/TracePage/KeyboardShortcutsHelp.css diff --git a/src/components/TracePage/KeyboardShortcutsHelp.js b/packages/jaeger-ui/src/components/TracePage/KeyboardShortcutsHelp.js similarity index 95% rename from src/components/TracePage/KeyboardShortcutsHelp.js rename to packages/jaeger-ui/src/components/TracePage/KeyboardShortcutsHelp.js index f2037ecf61..30328eef43 100644 --- a/src/components/TracePage/KeyboardShortcutsHelp.js +++ b/packages/jaeger-ui/src/components/TracePage/KeyboardShortcutsHelp.js @@ -49,6 +49,10 @@ const descriptions = { zoomInFast: 'Zoom in — Large', zoomOut: 'Zoom out', zoomOutFast: 'Zoom out — Large', + collapseAll: 'Collapse All', + expandAll: 'Expand All', + collapseOne: 'Collapse One Level', + expandOne: 'Expand One Level', }; function convertKeys(keyConfig: string | string[]): string[][] { diff --git a/src/components/TracePage/KeyboardShortcutsHelp.track.js b/packages/jaeger-ui/src/components/TracePage/KeyboardShortcutsHelp.track.js similarity index 100% rename from src/components/TracePage/KeyboardShortcutsHelp.track.js rename to packages/jaeger-ui/src/components/TracePage/KeyboardShortcutsHelp.track.js diff --git a/src/components/TracePage/ScrollManager.js b/packages/jaeger-ui/src/components/TracePage/ScrollManager.js similarity index 99% rename from src/components/TracePage/ScrollManager.js rename to packages/jaeger-ui/src/components/TracePage/ScrollManager.js index e7d151bf54..a1175437a3 100644 --- a/src/components/TracePage/ScrollManager.js +++ b/packages/jaeger-ui/src/components/TracePage/ScrollManager.js @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import type { Span, Trace } from '../../types'; +import type { Span, Trace } from '../../types/trace'; /** * `Accessors` is necessary because `ScrollManager` needs to be created by diff --git a/src/components/TracePage/ScrollManager.test.js b/packages/jaeger-ui/src/components/TracePage/ScrollManager.test.js similarity index 100% rename from src/components/TracePage/ScrollManager.test.js rename to packages/jaeger-ui/src/components/TracePage/ScrollManager.test.js diff --git a/src/components/TracePage/SpanGraph/CanvasSpanGraph.css b/packages/jaeger-ui/src/components/TracePage/SpanGraph/CanvasSpanGraph.css similarity index 100% rename from src/components/TracePage/SpanGraph/CanvasSpanGraph.css rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/CanvasSpanGraph.css diff --git a/src/components/TracePage/SpanGraph/CanvasSpanGraph.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/CanvasSpanGraph.js similarity index 100% rename from src/components/TracePage/SpanGraph/CanvasSpanGraph.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/CanvasSpanGraph.js diff --git a/src/components/TracePage/SpanGraph/CanvasSpanGraph.test.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/CanvasSpanGraph.test.js similarity index 100% rename from src/components/TracePage/SpanGraph/CanvasSpanGraph.test.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/CanvasSpanGraph.test.js diff --git a/src/components/TracePage/SpanGraph/GraphTicks.css b/packages/jaeger-ui/src/components/TracePage/SpanGraph/GraphTicks.css similarity index 100% rename from src/components/TracePage/SpanGraph/GraphTicks.css rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/GraphTicks.css diff --git a/src/components/TracePage/SpanGraph/GraphTicks.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/GraphTicks.js similarity index 100% rename from src/components/TracePage/SpanGraph/GraphTicks.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/GraphTicks.js diff --git a/src/components/TracePage/SpanGraph/GraphTicks.test.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/GraphTicks.test.js similarity index 100% rename from src/components/TracePage/SpanGraph/GraphTicks.test.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/GraphTicks.test.js diff --git a/src/components/TracePage/SpanGraph/Scrubber.css b/packages/jaeger-ui/src/components/TracePage/SpanGraph/Scrubber.css similarity index 100% rename from src/components/TracePage/SpanGraph/Scrubber.css rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/Scrubber.css diff --git a/src/components/TracePage/SpanGraph/Scrubber.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/Scrubber.js similarity index 100% rename from src/components/TracePage/SpanGraph/Scrubber.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/Scrubber.js diff --git a/src/components/TracePage/SpanGraph/Scrubber.test.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/Scrubber.test.js similarity index 100% rename from src/components/TracePage/SpanGraph/Scrubber.test.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/Scrubber.test.js diff --git a/src/components/TracePage/SpanGraph/TickLabels.css b/packages/jaeger-ui/src/components/TracePage/SpanGraph/TickLabels.css similarity index 100% rename from src/components/TracePage/SpanGraph/TickLabels.css rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/TickLabels.css diff --git a/src/components/TracePage/SpanGraph/TickLabels.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/TickLabels.js similarity index 100% rename from src/components/TracePage/SpanGraph/TickLabels.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/TickLabels.js diff --git a/src/components/TracePage/SpanGraph/TickLabels.test.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/TickLabels.test.js similarity index 100% rename from src/components/TracePage/SpanGraph/TickLabels.test.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/TickLabels.test.js diff --git a/src/components/TracePage/SpanGraph/ViewingLayer.css b/packages/jaeger-ui/src/components/TracePage/SpanGraph/ViewingLayer.css similarity index 100% rename from src/components/TracePage/SpanGraph/ViewingLayer.css rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/ViewingLayer.css diff --git a/src/components/TracePage/SpanGraph/ViewingLayer.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/ViewingLayer.js similarity index 100% rename from src/components/TracePage/SpanGraph/ViewingLayer.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/ViewingLayer.js diff --git a/src/components/TracePage/SpanGraph/ViewingLayer.test.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/ViewingLayer.test.js similarity index 100% rename from src/components/TracePage/SpanGraph/ViewingLayer.test.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/ViewingLayer.test.js diff --git a/src/components/TracePage/SpanGraph/index.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/index.js similarity index 98% rename from src/components/TracePage/SpanGraph/index.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/index.js index 1dc76ed97e..dfbed2cded 100644 --- a/src/components/TracePage/SpanGraph/index.js +++ b/packages/jaeger-ui/src/components/TracePage/SpanGraph/index.js @@ -20,7 +20,7 @@ import CanvasSpanGraph from './CanvasSpanGraph'; import TickLabels from './TickLabels'; import ViewingLayer from './ViewingLayer'; import type { ViewRange, ViewRangeTimeUpdate } from '../types'; -import type { Span, Trace } from '../../../types'; +import type { Span, Trace } from '../../../types/trace'; const TIMELINE_TICK_INTERVAL = 4; diff --git a/src/components/TracePage/SpanGraph/index.test.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/index.test.js similarity index 100% rename from src/components/TracePage/SpanGraph/index.test.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/index.test.js diff --git a/src/components/TracePage/SpanGraph/render-into-canvas.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/render-into-canvas.js similarity index 85% rename from src/components/TracePage/SpanGraph/render-into-canvas.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/render-into-canvas.js index 55b81bf871..6dc565d65b 100644 --- a/src/components/TracePage/SpanGraph/render-into-canvas.js +++ b/packages/jaeger-ui/src/components/TracePage/SpanGraph/render-into-canvas.js @@ -42,6 +42,7 @@ export default function renderIntoCanvas( itemHeight = 1 / (MIN_TOTAL_HEIGHT / items.length); } const ctx = canvas.getContext('2d'); + const fillCache: Map = new Map(); for (let i = 0; i < items.length; i++) { const { valueWidth, valueOffset, serviceName } = items[i]; // eslint-disable-next-line no-bitwise @@ -51,9 +52,16 @@ export default function renderIntoCanvas( if (width < MIN_WIDTH) { width = MIN_WIDTH; } - ctx.fillStyle = `rgba(${getFillColor(serviceName) - .concat(ALPHA) - .join()})`; + let fillStyle = fillCache.get(serviceName); + if (fillStyle) { + ctx.fillStyle = fillStyle; + } else { + fillStyle = `rgba(${getFillColor(serviceName) + .concat(ALPHA) + .join()})`; + fillCache.set(serviceName, fillStyle); + ctx.fillStyle = fillStyle; + } ctx.fillRect(x, i * itemYChange, width, itemHeight); } } diff --git a/src/components/TracePage/SpanGraph/render-into-canvas.test.js b/packages/jaeger-ui/src/components/TracePage/SpanGraph/render-into-canvas.test.js similarity index 100% rename from src/components/TracePage/SpanGraph/render-into-canvas.test.js rename to packages/jaeger-ui/src/components/TracePage/SpanGraph/render-into-canvas.test.js diff --git a/src/components/TracePage/TracePageHeader.css b/packages/jaeger-ui/src/components/TracePage/TracePageHeader.css similarity index 100% rename from src/components/TracePage/TracePageHeader.css rename to packages/jaeger-ui/src/components/TracePage/TracePageHeader.css diff --git a/src/components/TracePage/TracePageHeader.js b/packages/jaeger-ui/src/components/TracePage/TracePageHeader.js similarity index 100% rename from src/components/TracePage/TracePageHeader.js rename to packages/jaeger-ui/src/components/TracePage/TracePageHeader.js diff --git a/src/components/TracePage/TracePageHeader.markers.js b/packages/jaeger-ui/src/components/TracePage/TracePageHeader.markers.js similarity index 100% rename from src/components/TracePage/TracePageHeader.markers.js rename to packages/jaeger-ui/src/components/TracePage/TracePageHeader.markers.js diff --git a/src/components/TracePage/TracePageHeader.test.js b/packages/jaeger-ui/src/components/TracePage/TracePageHeader.test.js similarity index 100% rename from src/components/TracePage/TracePageHeader.test.js rename to packages/jaeger-ui/src/components/TracePage/TracePageHeader.test.js diff --git a/src/components/TracePage/TracePageHeader.track.js b/packages/jaeger-ui/src/components/TracePage/TracePageHeader.track.js similarity index 100% rename from src/components/TracePage/TracePageHeader.track.js rename to packages/jaeger-ui/src/components/TracePage/TracePageHeader.track.js diff --git a/src/components/TracePage/TraceTimelineViewer/ListView/Positions.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/Positions.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/ListView/Positions.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/Positions.js diff --git a/src/components/TracePage/TraceTimelineViewer/ListView/Positions.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/Positions.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/ListView/Positions.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/Positions.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/ListView/__snapshots__/index.test.js.snap b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/__snapshots__/index.test.js.snap similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/ListView/__snapshots__/index.test.js.snap rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/__snapshots__/index.test.js.snap diff --git a/src/components/TracePage/TraceTimelineViewer/ListView/index.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/index.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/ListView/index.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/index.js diff --git a/src/components/TracePage/TraceTimelineViewer/ListView/index.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/index.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/ListView/index.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/index.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanBar.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBar.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanBar.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBar.css diff --git a/src/components/TracePage/TraceTimelineViewer/SpanBar.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBar.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanBar.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBar.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanBar.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBar.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanBar.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBar.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanBarRow.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBarRow.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanBarRow.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBarRow.css diff --git a/src/components/TracePage/TraceTimelineViewer/SpanBarRow.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBarRow.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanBarRow.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBarRow.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanBarRow.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBarRow.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanBarRow.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanBarRow.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.css diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.markers.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.markers.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.markers.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.markers.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.css diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.js similarity index 97% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.js index a3df52a8bc..6981163d51 100644 --- a/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.js @@ -21,7 +21,8 @@ import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right'; import AccordianKeyValues from './AccordianKeyValues'; import { formatDuration } from '../utils'; -import type { Log } from '../../../../types'; + +import type { Log } from '../../../../types/trace'; import './AccordianLogs.css'; diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/DetailState.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/DetailState.js similarity index 97% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/DetailState.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/DetailState.js index fa8aa34d73..0242e07ded 100644 --- a/src/components/TracePage/TraceTimelineViewer/SpanDetail/DetailState.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/DetailState.js @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import type { Log } from '../../../../types'; +import type { Log } from '../../../../types/trace'; /** * Which items of a {@link SpanDetail} component are expanded. diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.css diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/index.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.css diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.js similarity index 98% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/index.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.js index cec43234ad..148b46edb7 100644 --- a/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.js @@ -22,7 +22,7 @@ import AccordianLogs from './AccordianLogs'; import DetailState from './DetailState'; import { formatDuration } from '../utils'; import LabeledList from '../../../common/LabeledList'; -import type { Log, Span } from '../../../../types'; +import type { Log, Span } from '../../../../types/trace'; import './index.css'; diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetail/index.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/index.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetailRow.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.css diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.js similarity index 97% rename from src/components/TracePage/TraceTimelineViewer/SpanDetailRow.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.js index 771edcd6d7..90f85cccaf 100644 --- a/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.js @@ -20,7 +20,7 @@ import SpanDetail from './SpanDetail'; import DetailState from './SpanDetail/DetailState'; import SpanTreeOffset from './SpanTreeOffset'; import TimelineRow from './TimelineRow'; -import type { Log, Span } from '../../../types'; +import type { Log, Span } from '../../../types/trace'; import './SpanDetailRow.css'; diff --git a/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanDetailRow.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetailRow.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/SpanTreeOffset.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanTreeOffset.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanTreeOffset.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanTreeOffset.css diff --git a/src/components/TracePage/TraceTimelineViewer/SpanTreeOffset.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanTreeOffset.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/SpanTreeOffset.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanTreeOffset.js diff --git a/src/components/TracePage/TraceTimelineViewer/Ticks.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/Ticks.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/Ticks.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/Ticks.css diff --git a/src/components/TracePage/TraceTimelineViewer/Ticks.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/Ticks.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/Ticks.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/Ticks.js diff --git a/src/components/TracePage/TraceTimelineViewer/Ticks.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/Ticks.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/Ticks.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/Ticks.test.js diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.css new file mode 100644 index 0000000000..6be2e0d87a --- /dev/null +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.css @@ -0,0 +1,30 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.TimelineCollapser { + float: right; + margin: 0 0.8rem 0 0; + display: inline-block; +} + +.TimelineCollapser--btn, +.TimelineCollapser--btn-expand { + margin-right: 0.3rem; +} + +.TimelineCollapser--btn-expand { + transform: rotate(90deg); +} diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.js new file mode 100644 index 0000000000..2e905d72d5 --- /dev/null +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.js @@ -0,0 +1,48 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React from 'react'; + +import { Tooltip, Icon } from 'antd'; + +import './TimelineCollapser.css'; + +type CollapserProps = { + onCollapseAll: () => void, + onCollapseOne: () => void, + onExpandOne: () => void, + onExpandAll: () => void, +}; + +export default function TimelineCollapser(props: CollapserProps) { + const { onExpandAll, onExpandOne, onCollapseAll, onCollapseOne } = props; + return ( + + + + + + + + + + + + + + + ); +} diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js new file mode 100644 index 0000000000..56b8bff95a --- /dev/null +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js @@ -0,0 +1,32 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React from 'react'; +import { shallow } from 'enzyme'; + +import TimelineCollapser from './TimelineCollapser'; + +describe('', () => { + it('renders without exploding', () => { + const props = { + onCollapseAll: () => {}, + onCollapseOne: () => {}, + onExpandAll: () => {}, + onExpandOne: () => {}, + }; + const wrapper = shallow(); + expect(wrapper).toBeDefined(); + expect(wrapper.find('.TimelineCollapser').length).toBe(1); + }); +}); diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.css diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.js diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.css similarity index 94% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.css index fe615e0762..45eb9c5c2d 100644 --- a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.css +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.css @@ -26,8 +26,9 @@ limitations under the License. } .TimelineHeaderRow--title { + display: inline-block; overflow: hidden; - margin: 0 0.75rem 0 0.5rem; + margin: 0 0 0 0.5rem; text-overflow: ellipsis; white-space: nowrap; } diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.js similarity index 84% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.js index ba3fc2838a..9c0a1e922a 100644 --- a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.js @@ -16,6 +16,7 @@ import * as React from 'react'; +import TimelineCollapser from './TimelineCollapser'; import TimelineColumnResizer from './TimelineColumnResizer'; import TimelineViewingLayer from './TimelineViewingLayer'; import Ticks from '../Ticks'; @@ -28,7 +29,11 @@ type TimelineHeaderRowProps = { duration: number, nameColumnWidth: number, numTicks: number, + onCollapseAll: () => void, + onCollapseOne: () => void, onColummWidthChange: number => void, + onExpandAll: () => void, + onExpandOne: () => void, updateNextViewRangeTime: ViewRangeTimeUpdate => void, updateViewRangeTime: (number, number, ?string) => void, viewRangeTime: ViewRangeTime, @@ -39,7 +44,11 @@ export default function TimelineHeaderRow(props: TimelineHeaderRowProps) { duration, nameColumnWidth, numTicks, + onCollapseAll, + onCollapseOne, onColummWidthChange, + onExpandAll, + onExpandOne, updateViewRangeTime, updateNextViewRangeTime, viewRangeTime, @@ -49,6 +58,12 @@ export default function TimelineHeaderRow(props: TimelineHeaderRowProps) {

Service & Operation

+
', () => { let wrapper; @@ -28,7 +29,11 @@ describe('', () => { nameColumnWidth, duration: 1234, numTicks: 5, + onCollapseAll: () => {}, + onCollapseOne: () => {}, onColummWidthChange: () => {}, + onExpandAll: () => {}, + onExpandOne: () => {}, updateNextViewRangeTime: () => {}, updateViewRangeTime: () => {}, viewRangeTime: { @@ -92,4 +97,16 @@ describe('', () => { ); expect(wrapper.containsMatchingElement(elm)).toBe(true); }); + + it('renders the TimelineCollapser', () => { + const elm = ( + + ); + expect(wrapper.containsMatchingElement(elm)).toBe(true); + }); }); diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.css diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.js diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/index.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/index.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/index.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow/index.js diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineRow.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineRow.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineRow.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineRow.css diff --git a/src/components/TracePage/TraceTimelineViewer/TimelineRow.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineRow.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/TimelineRow.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineRow.js diff --git a/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.css diff --git a/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.js similarity index 99% rename from src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.js index c19e87d099..4f69602e68 100644 --- a/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.js @@ -32,7 +32,7 @@ import { spanContainsErredSpan, } from './utils'; import type { Accessors } from '../ScrollManager'; -import type { Log, Span, Trace } from '../../../types'; +import type { Log, Span, Trace } from '../../../types/trace'; import colorGenerator from '../../../utils/color-generator'; import './VirtualizedTraceView.css'; diff --git a/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/VirtualizedTraceView.test.js diff --git a/src/components/TracePage/TraceTimelineViewer/duck.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.js similarity index 68% rename from src/components/TracePage/TraceTimelineViewer/duck.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.js index ed8cda9300..d4e1db9b49 100644 --- a/src/components/TracePage/TraceTimelineViewer/duck.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.js @@ -49,6 +49,10 @@ export const actionTypes = generateActionTypes('@jaeger-ui/trace-timeline-viewer 'SET_TRACE', 'SET_SPAN_NAME_COLUMN_WIDTH', 'CHILDREN_TOGGLE', + 'EXPAND_ALL', + 'COLLAPSE_ALL', + 'EXPAND_ONE', + 'COLLAPSE_ONE', 'DETAIL_TOGGLE', 'DETAIL_TAGS_TOGGLE', 'DETAIL_PROCESS_TOGGLE', @@ -61,6 +65,10 @@ const fullActions = createActions({ [actionTypes.SET_TRACE]: traceID => ({ traceID }), [actionTypes.SET_SPAN_NAME_COLUMN_WIDTH]: width => ({ width }), [actionTypes.CHILDREN_TOGGLE]: spanID => ({ spanID }), + [actionTypes.EXPAND_ALL]: () => ({}), + [actionTypes.EXPAND_ONE]: spans => ({ spans }), + [actionTypes.COLLAPSE_ALL]: spans => ({ spans }), + [actionTypes.COLLAPSE_ONE]: spans => ({ spans }), [actionTypes.DETAIL_TOGGLE]: spanID => ({ spanID }), [actionTypes.DETAIL_TAGS_TOGGLE]: spanID => ({ spanID }), [actionTypes.DETAIL_PROCESS_TOGGLE]: spanID => ({ spanID }), @@ -97,6 +105,70 @@ function childrenToggle(state, { payload }) { return { ...state, childrenHiddenIDs }; } +function shouldDisableCollapse(allSpans, hiddenSpansIds) { + const allParentSpans = allSpans.filter(s => s.hasChildren); + return allParentSpans.length === hiddenSpansIds.size; +} + +export function expandAll(state) { + const childrenHiddenIDs = new Set(); + return { ...state, childrenHiddenIDs }; +} + +export function collapseAll(state, { payload }) { + const { spans } = payload; + if (shouldDisableCollapse(spans, state.childrenHiddenIDs)) { + return state; + } + const childrenHiddenIDs = spans.reduce((res, s) => { + if (s.hasChildren) { + res.add(s.spanID); + } + return res; + }, new Set()); + return { ...state, childrenHiddenIDs }; +} + +export function collapseOne(state, { payload }) { + const { spans } = payload; + if (shouldDisableCollapse(spans, state.childrenHiddenIDs)) { + return state; + } + let nearestCollapsedAncestor; + const childrenHiddenIDs = spans.reduce((res, curSpan) => { + if (nearestCollapsedAncestor && curSpan.depth <= nearestCollapsedAncestor.depth) { + res.add(nearestCollapsedAncestor.spanID); + nearestCollapsedAncestor = curSpan; + } else if (curSpan.hasChildren && !res.has(curSpan.spanID)) { + nearestCollapsedAncestor = curSpan; + } + return res; + }, new Set(state.childrenHiddenIDs)); + childrenHiddenIDs.add(nearestCollapsedAncestor.spanID); + return { ...state, childrenHiddenIDs }; +} + +export function expandOne(state, { payload }) { + const { spans } = payload; + if (state.childrenHiddenIDs.size === 0) { + return state; + } + let prevExpandedDepth = -1; + let expandNextHiddenSpan = true; + const childrenHiddenIDs = spans.reduce((res, s) => { + if (s.depth <= prevExpandedDepth) { + expandNextHiddenSpan = true; + } + if (expandNextHiddenSpan && res.has(s.spanID)) { + res.delete(s.spanID); + expandNextHiddenSpan = false; + prevExpandedDepth = s.depth; + } + return res; + }, new Set(state.childrenHiddenIDs)); + return { ...state, childrenHiddenIDs }; +} + function detailToggle(state, { payload }) { const { spanID } = payload; const detailStates = new Map(state.detailStates); @@ -149,6 +221,10 @@ export default handleActions( [actionTypes.SET_TRACE]: setTrace, [actionTypes.SET_SPAN_NAME_COLUMN_WIDTH]: setColumnWidth, [actionTypes.CHILDREN_TOGGLE]: childrenToggle, + [actionTypes.EXPAND_ALL]: expandAll, + [actionTypes.EXPAND_ONE]: expandOne, + [actionTypes.COLLAPSE_ALL]: collapseAll, + [actionTypes.COLLAPSE_ONE]: collapseOne, [actionTypes.DETAIL_TOGGLE]: detailToggle, [actionTypes.DETAIL_TAGS_TOGGLE]: detailTagsToggle, [actionTypes.DETAIL_PROCESS_TOGGLE]: detailProcessToggle, diff --git a/src/components/TracePage/TraceTimelineViewer/duck.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.test.js similarity index 69% rename from src/components/TracePage/TraceTimelineViewer/duck.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.test.js index b63c488a4d..499a668fb3 100644 --- a/src/components/TracePage/TraceTimelineViewer/duck.test.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.test.js @@ -14,7 +14,7 @@ import { createStore } from 'redux'; -import reducer, { actions, newInitialState } from './duck'; +import reducer, { actions, newInitialState, collapseAll, collapseOne, expandAll, expandOne } from './duck'; import DetailState from './SpanDetail/DetailState'; import transformTraceData from '../../../model/transform-trace-data'; import traceGenerator from '../../../demo/trace-generators'; @@ -129,6 +129,110 @@ describe('TraceTimelineViewer/duck', () => { }); }); + describe('expands and collapses all spans', () => { + // 0 + // - 1 + // --- 2 + // - 3 + // --- 4 + const spans = [ + { spanID: 0, depth: 0, hasChildren: true }, + { spanID: 1, depth: 1, hasChildren: true }, + { spanID: 2, depth: 2, hasChildren: false }, + { spanID: 3, depth: 1, hasChildren: true }, + { spanID: 4, depth: 2, hasChildren: false }, + ]; + + const oneSpanCollapsed = new Set([1]); + const allSpansCollapsed = new Set([0, 1, 3]); + const oneLevelCollapsed = new Set([1, 3]); + + // Tests for corner cases of reducers + const tests = [ + { + msg: 'expand all', + action: expandAll, + initial: allSpansCollapsed, + resultant: new Set(), + }, + { + msg: 'collapse all, no-op', + action: collapseAll, + initial: allSpansCollapsed, + resultant: allSpansCollapsed, + }, + { + msg: 'expand one', + action: expandOne, + initial: allSpansCollapsed, + resultant: oneLevelCollapsed, + }, + { + msg: 'expand one, one collapsed', + action: expandOne, + initial: oneSpanCollapsed, + resultant: new Set(), + }, + { + msg: 'collapse one, no-op', + action: collapseOne, + initial: allSpansCollapsed, + resultant: allSpansCollapsed, + }, + { + msg: 'collapse one, one collapsed', + action: collapseOne, + initial: oneSpanCollapsed, + resultant: oneLevelCollapsed, + }, + ]; + + tests.forEach(info => { + const { msg, action, initial, resultant } = info; + + it(msg, () => { + const { childrenHiddenIDs } = action({ childrenHiddenIDs: initial }, { payload: { spans } }); + expect(childrenHiddenIDs).toEqual(resultant); + }); + }); + + // Tests to verify correct behaviour of actions + const dispatchTests = [ + { + msg: 'expand all, no-op', + action: actions.expandAll(), + resultant: new Set(), + }, + { + msg: 'collapse all', + action: actions.collapseAll(spans), + resultant: allSpansCollapsed, + }, + { + msg: 'expand one, no-op', + action: actions.expandOne(spans), + resultant: new Set(), + }, + { + msg: 'collapse one', + action: actions.collapseOne(spans), + resultant: oneLevelCollapsed, + }, + ]; + + dispatchTests.forEach(info => { + const { msg, action, resultant } = info; + + it(msg, () => { + const st0 = store.getState(); + store.dispatch(action); + const st1 = store.getState(); + expect(st0.childrenHiddenIDs).toEqual(new Set()); + expect(st1.childrenHiddenIDs).toEqual(resultant); + }); + }); + }); + describe("toggles a detail's sub-sections", () => { const id = trace.spans[0].spanID; const baseDetail = new DetailState(); diff --git a/src/components/TracePage/TraceTimelineViewer/duck.track.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.track.js similarity index 96% rename from src/components/TracePage/TraceTimelineViewer/duck.track.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.track.js index 77fa53d616..6d87f13372 100644 --- a/src/components/TracePage/TraceTimelineViewer/duck.track.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.track.js @@ -37,7 +37,8 @@ function trackParent(store: Store, action: any) { const { spanID } = action.payload; const traceID = st.traceTimeline.traceID; const isHidden = st.traceTimeline.childrenHiddenIDs.has(spanID); - const span = st.trace.traces[traceID].spans.find(sp => sp.spanID === spanID); + const trace = st.trace.traces[traceID].data; + const span = trace.spans.find(sp => sp.spanID === spanID); if (span) { trackEvent(CATEGORY_PARENT, getToggleValue(!isHidden), span.depth); } diff --git a/src/components/TracePage/TraceTimelineViewer/duck.track.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.track.test.js similarity index 95% rename from src/components/TracePage/TraceTimelineViewer/duck.track.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.track.test.js index 87950d2b7c..f14bce23a4 100644 --- a/src/components/TracePage/TraceTimelineViewer/duck.track.test.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/duck.track.test.js @@ -18,6 +18,7 @@ jest.mock('../../../utils/tracking'); import DetailState from './SpanDetail/DetailState'; import * as track from './duck.track'; import { actionTypes as types } from './duck'; +import { fetchedState } from '../../../constants'; import { trackEvent } from '../../../utils/tracking'; describe('middlewareHooks', () => { @@ -30,7 +31,9 @@ describe('middlewareHooks', () => { trace: { traces: { [traceID]: { - spans: [{ spanID, depth: spanDepth }], + id: traceID, + data: { spans: [{ spanID, depth: spanDepth }] }, + state: fetchedState.DONE, }, }, }, diff --git a/src/components/TracePage/TraceTimelineViewer/get-filtered-spans.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/get-filtered-spans.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/get-filtered-spans.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/get-filtered-spans.js diff --git a/src/components/TracePage/TraceTimelineViewer/grid.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/grid.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/grid.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/grid.css diff --git a/src/components/TracePage/TraceTimelineViewer/index.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.css similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/index.css rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.css diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.js new file mode 100644 index 0000000000..de33beae86 --- /dev/null +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.js @@ -0,0 +1,127 @@ +git // @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React from 'react'; +import { connect } from 'react-redux'; +import { bindActionCreators } from 'redux'; + +import { actions } from './duck'; +import TimelineHeaderRow from './TimelineHeaderRow'; +import VirtualizedTraceView from './VirtualizedTraceView'; +import { merge as mergeShortcuts } from '../keyboard-shortcuts'; + +import type { Accessors } from '../ScrollManager'; +import type { ViewRange, ViewRangeTimeUpdate } from '../types'; +import type { Span, Trace } from '../../../types/trace'; + +import './index.css'; + +type TraceTimelineViewerProps = { + registerAccessors: Accessors => void, + setSpanNameColumnWidth: number => void, + collapseAll: (Span[]) => void, + collapseOne: (Span[]) => void, + expandAll: () => void, + expandOne: (Span[]) => void, + spanNameColumnWidth: number, + textFilter: ?string, + trace: Trace, + updateNextViewRangeTime: ViewRangeTimeUpdate => void, + updateViewRangeTime: (number, number, ?string) => void, + viewRange: ViewRange, +}; + +const NUM_TICKS = 5; + +/** + * `TraceTimelineViewer` now renders the header row because it is sensitive to + * `props.viewRange.time.cursor`. If `VirtualizedTraceView` renders it, it will + * re-render the ListView every time the cursor is moved on the trace minimap + * or `TimelineHeaderRow`. + */ +export class TraceTimelineViewerImpl extends React.PureComponent { + props: TraceTimelineViewerProps; + + componentDidMount() { + mergeShortcuts({ + collapseAll: this.collapseAll, + expandAll: this.expandAll, + collapseOne: this.collapseOne, + expandOne: this.expandOne, + }); + } + + collapseAll = () => { + this.props.collapseAll(this.props.trace.spans); + }; + + collapseOne = () => { + this.props.collapseOne(this.props.trace.spans); + }; + + expandAll = () => { + this.props.expandAll(); + }; + + expandOne = () => { + this.props.expandOne(this.props.trace.spans); + }; + + render() { + const { + setSpanNameColumnWidth, + updateNextViewRangeTime, + updateViewRangeTime, + viewRange, + ...rest + } = this.props; + const { spanNameColumnWidth, trace } = rest; + + return ( +
+ + +
+ ); + } +} + +function mapStateToProps(state, ownProps) { + const spanNameColumnWidth = state.traceTimeline.spanNameColumnWidth; + return { spanNameColumnWidth, ...ownProps }; +} + +function mapDispatchToProps(dispatch) { + const { setSpanNameColumnWidth, expandAll, expandOne, collapseAll, collapseOne } = bindActionCreators( + actions, + dispatch + ); + return { setSpanNameColumnWidth, expandAll, expandOne, collapseAll, collapseOne }; +} + +export default connect(mapStateToProps, mapDispatchToProps)(TraceTimelineViewerImpl); diff --git a/src/components/TracePage/TraceTimelineViewer/index.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.test.js similarity index 57% rename from src/components/TracePage/TraceTimelineViewer/index.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.test.js index a0a3ebd8a7..01f86a1690 100644 --- a/src/components/TracePage/TraceTimelineViewer/index.test.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.test.js @@ -15,9 +15,10 @@ import React from 'react'; import { shallow } from 'enzyme'; -import TraceTimelineViewer from './index'; +import TraceTimelineViewer, { TraceTimelineViewerImpl } from './index'; import traceGenerator from '../../../demo/trace-generators'; import transformTraceData from '../../../model/transform-trace-data'; +import TimelineHeaderRow from './TimelineHeaderRow'; describe('', () => { const trace = transformTraceData(traceGenerator.trace({})); @@ -29,6 +30,11 @@ describe('', () => { current: [0, 1], }, }, + spanNameColumnWidth: 0.5, + expandAll: jest.fn(), + collapseAll: jest.fn(), + expandOne: jest.fn(), + collapseOne: jest.fn(), }; const options = { context: { @@ -37,17 +43,33 @@ describe('', () => { return { traceTimeline: { spanNameColumnWidth: 0.25 } }; }, subscribe() {}, + dispatch() {}, }, }, }; let wrapper; + let connectedWrapper; beforeEach(() => { - wrapper = shallow(, options); + wrapper = shallow(, options); + connectedWrapper = shallow(, options); }); it('it does not explode', () => { expect(wrapper).toBeDefined(); + expect(connectedWrapper).toBeDefined(); + }); + + it('it sets up actions', () => { + const headerRow = wrapper.find(TimelineHeaderRow); + headerRow.props().onCollapseAll(); + headerRow.props().onExpandAll(); + headerRow.props().onExpandOne(); + headerRow.props().onCollapseOne(); + expect(props.collapseAll.mock.calls.length).toBe(1); + expect(props.expandAll.mock.calls.length).toBe(1); + expect(props.expandOne.mock.calls.length).toBe(1); + expect(props.collapseOne.mock.calls.length).toBe(1); }); }); diff --git a/src/components/TracePage/TraceTimelineViewer/utils.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/utils.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/utils.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/utils.js diff --git a/src/components/TracePage/TraceTimelineViewer/utils.test.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/utils.test.js similarity index 100% rename from src/components/TracePage/TraceTimelineViewer/utils.test.js rename to packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/utils.test.js diff --git a/src/components/TracePage/Tween.js b/packages/jaeger-ui/src/components/TracePage/Tween.js similarity index 100% rename from src/components/TracePage/Tween.js rename to packages/jaeger-ui/src/components/TracePage/Tween.js diff --git a/src/components/TracePage/Tween.test.js b/packages/jaeger-ui/src/components/TracePage/Tween.test.js similarity index 100% rename from src/components/TracePage/Tween.test.js rename to packages/jaeger-ui/src/components/TracePage/Tween.test.js diff --git a/src/components/TracePage/index.css b/packages/jaeger-ui/src/components/TracePage/index.css similarity index 100% rename from src/components/TracePage/index.css rename to packages/jaeger-ui/src/components/TracePage/index.css diff --git a/src/components/TracePage/index.js b/packages/jaeger-ui/src/components/TracePage/index.js similarity index 85% rename from src/components/TracePage/index.js rename to packages/jaeger-ui/src/components/TracePage/index.js index 6344585ec5..eb8eaa28ca 100644 --- a/src/components/TracePage/index.js +++ b/packages/jaeger-ui/src/components/TracePage/index.js @@ -26,24 +26,25 @@ import { bindActionCreators } from 'redux'; import ArchiveNotifier from './ArchiveNotifier'; import { actions as archiveActions } from './ArchiveNotifier/duck'; import { trackFilter, trackRange } from './index.track'; -import type { CombokeysHandler, ShortcutCallbacks } from './keyboard-shortcuts'; -import { init as initShortcuts, reset as resetShortcuts } from './keyboard-shortcuts'; +import { merge as mergeShortcuts, reset as resetShortcuts } from './keyboard-shortcuts'; import { cancel as cancelScroll, scrollBy, scrollTo } from './scroll-page'; import ScrollManager from './ScrollManager'; import SpanGraph from './SpanGraph'; import TracePageHeader from './TracePageHeader'; import { trackSlimHeaderToggle } from './TracePageHeader.track'; import TraceTimelineViewer from './TraceTimelineViewer'; -import type { ViewRange, ViewRangeTimeUpdate } from './types'; import ErrorMessage from '../common/ErrorMessage'; import LoadingIndicator from '../common/LoadingIndicator'; import * as jaegerApiActions from '../../actions/jaeger-api'; +import { fetchedState } from '../../constants'; import { getTraceName } from '../../model/trace-viewer'; -import type { Trace } from '../../types'; -import type { TraceArchive, TracesArchive } from '../../types/archive'; -import type { Config } from '../../types/config'; import prefixUrl from '../../utils/prefix-url'; +import type { CombokeysHandler, ShortcutCallbacks } from './keyboard-shortcuts'; +import type { ViewRange, ViewRangeTimeUpdate } from './types'; +import type { FetchedTrace, ReduxState } from '../../types'; +import type { TraceArchive } from '../../types/archive'; + import './index.css'; type TracePageProps = { @@ -54,8 +55,7 @@ type TracePageProps = { fetchTrace: string => void, history: RouterHistory, id: string, - loading: boolean, - trace: ?Trace, + trace: ?FetchedTrace, }; type TracePageState = { @@ -93,7 +93,8 @@ export function makeShortcutCallbacks(adjRange: (number, number) => void): Short return _mapValues(shortcutConfig, getHandler); } -export default class TracePage extends React.PureComponent { +// export for tests +export class TracePageImpl extends React.PureComponent { props: TracePageProps; state: TracePageState; @@ -113,10 +114,12 @@ export default class TracePage extends React.PureComponent :
; + if (!trace || trace.state === fetchedState.LOADING) { + return ; } - if (trace instanceof Error) { - return ; + const { data } = trace; + if (trace.state === fetchedState.ERROR || !data) { + return ; } - const { duration, processes, spans, startTime, traceID } = trace; + const { duration, processes, spans, startTime, traceID } = data; const maxSpanDepth = _maxBy(spans, 'depth').depth + 1; const numberOfServices = new Set(_values(processes).map(p => p.serviceName)).size; return ( @@ -283,7 +288,7 @@ export default class TracePage extends React.PureComponent {!slimView && ( ', () => { const trace = transformTraceData(traceGenerator.trace({})); const defaultProps = { - trace, + trace: { data: trace, state: fetchedState.DONE }, fetchTrace() {}, id: trace.traceID, }; @@ -91,10 +93,10 @@ describe('', () => { expect(wrapper.find(SpanGraph).length).toBe(1); }); - it('renders an empty page when not provided a trace', () => { + it('renders a a loading indicator when not provided a fetched trace', () => { wrapper.setProps({ trace: null }); - const isEmpty = wrapper.matchesElement(
); - expect(isEmpty).toBe(true); + const loading = wrapper.find(LoadingIndicator); + expect(loading.length).toBe(1); }); it('renders an error message when given an error', () => { @@ -126,7 +128,7 @@ describe('', () => { // mount because `.componentDidUpdate()` wrapper = mount(); wrapper.setState({ viewRange: { time: [0.2, 0.8] } }); - wrapper.setProps({ trace: altTrace }); + wrapper.setProps({ id: altTrace.traceID, trace: { data: altTrace, state: fetchedState.DONE } }); expect(wrapper.state('viewRange')).toEqual({ time: { current: [0, 1] } }); }); @@ -134,17 +136,18 @@ describe('', () => { wrapper = shallow(); const scrollManager = wrapper.instance()._scrollManager; scrollManager.setTrace = jest.fn(); - wrapper.setProps({ trace }); + wrapper.setProps({ trace: { data: trace } }); expect(scrollManager.setTrace.mock.calls).toEqual([[trace]]); }); it('performs misc cleanup when unmounting', () => { + resetShortcuts.mockReset(); wrapper = shallow(); const scrollManager = wrapper.instance()._scrollManager; scrollManager.destroy = jest.fn(); wrapper.unmount(); expect(scrollManager.destroy.mock.calls).toEqual([[]]); - expect(resetShortcuts.mock.calls).toEqual([[]]); + expect(resetShortcuts.mock.calls).toEqual([[], []]); expect(cancelScroll.mock.calls).toEqual([[]]); }); @@ -353,9 +356,8 @@ describe('mapStateToProps()', () => { const trace = {}; const state = { trace: { - loading: false, traces: { - [id]: trace, + [id]: { data: trace, state: fetchedState.DONE }, }, }, config: { @@ -371,10 +373,9 @@ describe('mapStateToProps()', () => { const props = mapStateToProps(state, ownProps); expect(props).toEqual({ id, - trace, - loading: state.trace.loading, archiveEnabled: false, archiveTraceState: undefined, + trace: { data: {}, state: fetchedState.DONE }, }); }); }); diff --git a/src/components/TracePage/index.track.js b/packages/jaeger-ui/src/components/TracePage/index.track.js similarity index 100% rename from src/components/TracePage/index.track.js rename to packages/jaeger-ui/src/components/TracePage/index.track.js diff --git a/src/components/TracePage/index.track.test.js b/packages/jaeger-ui/src/components/TracePage/index.track.test.js similarity index 100% rename from src/components/TracePage/index.track.test.js rename to packages/jaeger-ui/src/components/TracePage/index.track.test.js diff --git a/src/components/TracePage/keyboard-shortcuts.js b/packages/jaeger-ui/src/components/TracePage/keyboard-shortcuts.js similarity index 63% rename from src/components/TracePage/keyboard-shortcuts.js rename to packages/jaeger-ui/src/components/TracePage/keyboard-shortcuts.js index eef93268a4..b8d2281486 100644 --- a/src/components/TracePage/keyboard-shortcuts.js +++ b/packages/jaeger-ui/src/components/TracePage/keyboard-shortcuts.js @@ -27,19 +27,24 @@ type CombokeysType = { }; export type ShortcutCallbacks = { - scrollPageDown: CombokeysHandler, - scrollPageUp: CombokeysHandler, - scrollToNextVisibleSpan: CombokeysHandler, - scrollToPrevVisibleSpan: CombokeysHandler, + scrollPageDown?: CombokeysHandler, + scrollPageUp?: CombokeysHandler, + scrollToNextVisibleSpan?: CombokeysHandler, + scrollToPrevVisibleSpan?: CombokeysHandler, // view range - panLeft: CombokeysHandler, - panLeftFast: CombokeysHandler, - panRight: CombokeysHandler, - panRightFast: CombokeysHandler, - zoomIn: CombokeysHandler, - zoomInFast: CombokeysHandler, - zoomOut: CombokeysHandler, - zoomOutFast: CombokeysHandler, + panLeft?: CombokeysHandler, + panLeftFast?: CombokeysHandler, + panRight?: CombokeysHandler, + panRightFast?: CombokeysHandler, + zoomIn?: CombokeysHandler, + zoomInFast?: CombokeysHandler, + zoomOut?: CombokeysHandler, + zoomOutFast?: CombokeysHandler, + // collapse/expand + collapseAll?: CombokeysHandler, + expandAll?: CombokeysHandler, + collapseOne?: CombokeysHandler, + expandOne?: CombokeysHandler, }; export const kbdMappings = { @@ -55,6 +60,10 @@ export const kbdMappings = { zoomInFast: 'shift+up', zoomOut: 'down', zoomOutFast: 'shift+down', + collapseAll: ']', + expandAll: '[', + collapseOne: 'p', + expandOne: 'o', }; let instance: ?CombokeysType; @@ -66,11 +75,13 @@ function getInstance(): CombokeysType { return instance; } -export function init(callbacks: ShortcutCallbacks) { - const combokeys = getInstance(); - combokeys.reset(); - Object.keys(kbdMappings).forEach(name => { - combokeys.bind(kbdMappings[name], callbacks[name]); +export function merge(callbacks: ShortcutCallbacks) { + const inst = getInstance(); + Object.keys(callbacks).forEach(name => { + const keysHandler = callbacks[name]; + if (keysHandler) { + inst.bind(kbdMappings[name], keysHandler); + } }); } diff --git a/src/components/TracePage/scroll-page.js b/packages/jaeger-ui/src/components/TracePage/scroll-page.js similarity index 100% rename from src/components/TracePage/scroll-page.js rename to packages/jaeger-ui/src/components/TracePage/scroll-page.js diff --git a/src/components/TracePage/scroll-page.test.js b/packages/jaeger-ui/src/components/TracePage/scroll-page.test.js similarity index 100% rename from src/components/TracePage/scroll-page.test.js rename to packages/jaeger-ui/src/components/TracePage/scroll-page.test.js diff --git a/src/components/TracePage/types.js b/packages/jaeger-ui/src/components/TracePage/types.js similarity index 100% rename from src/components/TracePage/types.js rename to packages/jaeger-ui/src/components/TracePage/types.js diff --git a/packages/jaeger-ui/src/components/TracePage/url.js b/packages/jaeger-ui/src/components/TracePage/url.js new file mode 100644 index 0000000000..885b0c4182 --- /dev/null +++ b/packages/jaeger-ui/src/components/TracePage/url.js @@ -0,0 +1,23 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import prefixUrl from '../../utils/prefix-url'; + +export const ROUTE_PATH = prefixUrl('/trace/:id'); + +export function getUrl(id: string) { + return prefixUrl(`/trace/${id}`); +} diff --git a/packages/jaeger-ui/src/components/common/BreakableText.css b/packages/jaeger-ui/src/components/common/BreakableText.css new file mode 100644 index 0000000000..60b3711c18 --- /dev/null +++ b/packages/jaeger-ui/src/components/common/BreakableText.css @@ -0,0 +1,20 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.BreakableText { + display: inline-block; + white-space: pre; +} diff --git a/packages/jaeger-ui/src/components/common/BreakableText.js b/packages/jaeger-ui/src/components/common/BreakableText.js new file mode 100644 index 0000000000..1598bcfe3c --- /dev/null +++ b/packages/jaeger-ui/src/components/common/BreakableText.js @@ -0,0 +1,51 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +import './BreakableText.css'; + +const WORD_RX = /\W*\w+\W*/g; + +type Props = { + text: string, + className?: string, + wordRegexp?: RegExp, +}; + +export default function BreakableText(props: Props) { + const { className, text, wordRegexp = WORD_RX } = props; + if (!text) { + return typeof text === 'string' ? text : null; + } + const spans = []; + wordRegexp.exec(''); + let match = wordRegexp.exec(text); + while (match) { + spans.push( + + {match[0]} + + ); + match = wordRegexp.exec(text); + } + return spans; +} + +BreakableText.defaultProps = { + className: 'BreakableText', + wordRegexp: WORD_RX, +}; diff --git a/src/components/common/ErrorMessage.css b/packages/jaeger-ui/src/components/common/ErrorMessage.css similarity index 100% rename from src/components/common/ErrorMessage.css rename to packages/jaeger-ui/src/components/common/ErrorMessage.css diff --git a/src/components/common/ErrorMessage.js b/packages/jaeger-ui/src/components/common/ErrorMessage.js similarity index 70% rename from src/components/common/ErrorMessage.js rename to packages/jaeger-ui/src/components/common/ErrorMessage.js index 1817eff8b8..066affb3e4 100644 --- a/src/components/common/ErrorMessage.js +++ b/packages/jaeger-ui/src/components/common/ErrorMessage.js @@ -22,6 +22,8 @@ import './ErrorMessage.css'; type ErrorMessageProps = { className?: string, + detailClassName?: string, + messageClassName?: string, error: ApiError, }; @@ -29,6 +31,7 @@ type SubPartProps = { className?: string, error: ApiError, wrap?: boolean, + wrapperClassName?: string, }; function ErrorAttr({ name, value }: { name: string, value: any }) { @@ -41,15 +44,16 @@ function ErrorAttr({ name, value }: { name: string, value: any }) { } function Message(props: SubPartProps) { - const { className, error, wrap } = props; + const { className, error, wrap, wrapperClassName } = props; + const cssClass = `ErrorMessage--msg ${className || ''}`; let msg: React.Node; if (typeof error === 'string') { - msg =

{error}

; + msg =

{error}

; } else { - msg =

{error.message}

; + msg =

{error.message}

; } if (wrap) { - return
{msg}
; + return
{msg}
; } return msg; } @@ -57,17 +61,18 @@ function Message(props: SubPartProps) { Message.defaultProps = { className: undefined, wrap: false, + wrapperClassName: undefined, }; function Details(props: SubPartProps) { - const { className, error, wrap } = props; + const { className, error, wrap, wrapperClassName } = props; if (typeof error === 'string') { return null; } const { httpStatus, httpStatusText, httpUrl, httpQuery, httpBody } = error; const bodyExcerpt = httpBody && httpBody.length > 1024 ? `${httpBody.slice(0, 1021).trim()}...` : httpBody; const details = ( -
+
{httpStatus ? : null} @@ -81,7 +86,7 @@ function Details(props: SubPartProps) { ); if (wrap) { - return
{details}
; + return
{details}
; } return details; } @@ -89,25 +94,33 @@ function Details(props: SubPartProps) { Details.defaultProps = { className: undefined, wrap: false, + wrapperClassName: undefined, }; -export default function ErrorMessage({ className, error }: ErrorMessageProps) { +export default function ErrorMessage({ + className, + detailClassName, + error, + messageClassName, +}: ErrorMessageProps) { if (!error) { return null; } if (typeof error === 'string') { - return ; + return ; } return (
- -
+ +
); } ErrorMessage.defaultProps = { className: undefined, + detailClassName: undefined, + messageClassName: undefined, }; ErrorMessage.Message = Message; diff --git a/src/components/common/ErrorMessage.test.js b/packages/jaeger-ui/src/components/common/ErrorMessage.test.js similarity index 100% rename from src/components/common/ErrorMessage.test.js rename to packages/jaeger-ui/src/components/common/ErrorMessage.test.js diff --git a/src/components/common/LabeledList.css b/packages/jaeger-ui/src/components/common/LabeledList.css similarity index 100% rename from src/components/common/LabeledList.css rename to packages/jaeger-ui/src/components/common/LabeledList.css diff --git a/src/components/common/LabeledList.js b/packages/jaeger-ui/src/components/common/LabeledList.js similarity index 100% rename from src/components/common/LabeledList.js rename to packages/jaeger-ui/src/components/common/LabeledList.js diff --git a/src/components/common/LoadingIndicator.css b/packages/jaeger-ui/src/components/common/LoadingIndicator.css similarity index 92% rename from src/components/common/LoadingIndicator.css rename to packages/jaeger-ui/src/components/common/LoadingIndicator.css index 7caaae008a..b576c37ab4 100644 --- a/src/components/common/LoadingIndicator.css +++ b/packages/jaeger-ui/src/components/common/LoadingIndicator.css @@ -35,8 +35,12 @@ limitations under the License. 0 -0.5px rgba(0, 128, 128, 0.6); } -.LoadingIndicator--centered { +.LoadingIndicator.is-centered { display: block; margin-left: auto; margin-right: auto; } + +.LoadingIndicator.is-small { + font-size: 0.7em; +} diff --git a/src/components/common/LoadingIndicator.js b/packages/jaeger-ui/src/components/common/LoadingIndicator.js similarity index 81% rename from src/components/common/LoadingIndicator.js rename to packages/jaeger-ui/src/components/common/LoadingIndicator.js index 7af781c0c5..1cdb4e2342 100644 --- a/src/components/common/LoadingIndicator.js +++ b/packages/jaeger-ui/src/components/common/LoadingIndicator.js @@ -22,15 +22,22 @@ import './LoadingIndicator.css'; type LoadingIndicatorProps = { centered?: boolean, className?: string, + small?: boolean, }; export default function LoadingIndicator(props: LoadingIndicatorProps) { - const { centered, className, ...rest } = props; - const cls = `LoadingIndicator ${centered ? 'LoadingIndicator--centered' : ''} ${className || ''}`; + const { centered, className, small, ...rest } = props; + const cls = ` + LoadingIndicator + ${centered ? 'is-centered' : ''} + ${small ? 'is-small' : ''} + ${className || ''} + `; return ; } LoadingIndicator.defaultProps = { centered: false, className: undefined, + small: false, }; diff --git a/packages/jaeger-ui/src/components/common/RelativeDate.js b/packages/jaeger-ui/src/components/common/RelativeDate.js new file mode 100644 index 0000000000..1c8cbe2a8e --- /dev/null +++ b/packages/jaeger-ui/src/components/common/RelativeDate.js @@ -0,0 +1,33 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import moment from 'moment'; + +import { formatRelativeDate } from '../../utils/date'; + +type Props = { + fullMonthName: ?boolean, + includeTime: ?boolean, + value: number | Date | any, +}; + +export default function RelativeDate(props: Props) { + const { value, includeTime, fullMonthName } = props; + const m = !(value instanceof moment) ? moment(value) : value; + const dateStr = formatRelativeDate(m, Boolean(fullMonthName)); + const timeStr = includeTime ? `, ${m.format('h:mm:ss a')}` : ''; + return `${dateStr}${timeStr}`; +} diff --git a/packages/jaeger-ui/src/components/common/TraceName.css b/packages/jaeger-ui/src/components/common/TraceName.css new file mode 100644 index 0000000000..403dd75098 --- /dev/null +++ b/packages/jaeger-ui/src/components/common/TraceName.css @@ -0,0 +1,19 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.TraceName.is-error { + color: #c00; +} diff --git a/packages/jaeger-ui/src/components/common/TraceName.js b/packages/jaeger-ui/src/components/common/TraceName.js new file mode 100644 index 0000000000..cdc4b7bb0b --- /dev/null +++ b/packages/jaeger-ui/src/components/common/TraceName.js @@ -0,0 +1,63 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +import BreakableText from '../common/BreakableText'; +import LoadingIndicator from '../common/LoadingIndicator'; +import { fetchedState, FALLBACK_TRACE_NAME } from '../../constants'; + +import type { FetchedState } from '../../types'; +import type { ApiError } from '../../types/api-error'; + +import './TraceName.css'; + +type Props = { + breakable?: boolean, + className?: string, + error: ?ApiError, + state: ?FetchedState, + traceName: ?string, +}; + +export default function TraceName(props: Props) { + const { breakable, className, error, state, traceName } = props; + const isErred = state === fetchedState.ERROR; + let title = traceName || FALLBACK_TRACE_NAME; + let errorCssClass = ''; + if (isErred) { + errorCssClass = 'is-error'; + let titleStr = ''; + if (error) { + titleStr = typeof error === 'string' ? error : error.message || String(error); + } + if (!titleStr) { + titleStr = 'Error: Unknown error'; + } + title = ; + } else if (state === fetchedState.LOADING) { + title = ; + } else { + const text = traceName || FALLBACK_TRACE_NAME; + title = breakable ? : text; + } + return {title}; +} + +TraceName.defaultProps = { + breakable: false, + className: '', +}; diff --git a/src/components/common/VirtSelect.css b/packages/jaeger-ui/src/components/common/VirtSelect.css similarity index 100% rename from src/components/common/VirtSelect.css rename to packages/jaeger-ui/src/components/common/VirtSelect.css diff --git a/src/components/common/VirtSelect.js b/packages/jaeger-ui/src/components/common/VirtSelect.js similarity index 100% rename from src/components/common/VirtSelect.js rename to packages/jaeger-ui/src/components/common/VirtSelect.js diff --git a/src/components/common/utils.css b/packages/jaeger-ui/src/components/common/utils.css similarity index 88% rename from src/components/common/utils.css rename to packages/jaeger-ui/src/components/common/utils.css index a9642006a8..9f5992ba65 100644 --- a/src/components/common/utils.css +++ b/packages/jaeger-ui/src/components/common/utils.css @@ -18,6 +18,10 @@ limitations under the License. width: 100%; } +.u-flex-1 { + flex: 1; +} + .u-mt-vast { margin-top: 13rem; } @@ -26,6 +30,10 @@ limitations under the License. cursor: pointer; } +.u-tx-muted { + color: #aaa; +} + .u-tx-ellipsis { text-overflow: ellipsis; } @@ -60,14 +68,13 @@ limitations under the License. } .u-simple-scrollbars::-webkit-scrollbar-thumb { - background: rgba(0, 0, 0, 0.15); + background: rgba(0, 0, 0, 0.2); } -.u-simple-scrollbars::-webkit-scrollbar-thumb:window-inactive { - background: rgba(0, 0, 0, 0.15); +.u-simple-scrollbars:hover::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.35); } -.u-simple-scrollbars::-webkit-scrollbar-thumb:hover { - background: rgba(128, 135, 139, 0.8); - background: rgba(0, 0, 0, 0.4); +.u-simple-scrollbars::-webkit-scrollbar-thumb:window-inactive { + background: rgba(0, 0, 0, 0.15); } diff --git a/src/constants/default-config.js b/packages/jaeger-ui/src/constants/default-config.js similarity index 100% rename from src/constants/default-config.js rename to packages/jaeger-ui/src/constants/default-config.js diff --git a/packages/jaeger-ui/src/constants/index.js b/packages/jaeger-ui/src/constants/index.js new file mode 100644 index 0000000000..98484f0ad3 --- /dev/null +++ b/packages/jaeger-ui/src/constants/index.js @@ -0,0 +1,30 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export const TOP_NAV_HEIGHT = 47; + +export const FALLBACK_DAG_MAX_NUM_SERVICES = 100; +export const FALLBACK_TRACE_NAME = ''; + +export const FETCH_DONE = 'FETCH_DONE'; +export const FETCH_ERROR = 'FETCH_ERROR'; +export const FETCH_LOADING = 'FETCH_LOADING'; + +export const fetchedState = { + DONE: FETCH_DONE, + ERROR: FETCH_ERROR, + LOADING: FETCH_LOADING, +}; diff --git a/packages/jaeger-ui/src/constants/search-form.js b/packages/jaeger-ui/src/constants/search-form.js new file mode 100644 index 0000000000..e716b295af --- /dev/null +++ b/packages/jaeger-ui/src/constants/search-form.js @@ -0,0 +1,19 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export const DEFAULT_OPERATION = 'all'; +export const DEFAULT_LOOKBACK = '1h'; +export const DEFAULT_LIMIT = 20; + +export const FORM_CHANGE_ACTION_TYPE = '@@redux-form/CHANGE'; diff --git a/packages/jaeger-ui/src/constants/tag-keys.js b/packages/jaeger-ui/src/constants/tag-keys.js new file mode 100644 index 0000000000..266677b36a --- /dev/null +++ b/packages/jaeger-ui/src/constants/tag-keys.js @@ -0,0 +1,19 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export const HTTP_METHOD = 'http.method'; +export const PEER_SERVICE = 'peer.service'; +export const SPAN_KIND = 'span.kind'; diff --git a/src/demo/.eslintrc b/packages/jaeger-ui/src/demo/.eslintrc similarity index 100% rename from src/demo/.eslintrc rename to packages/jaeger-ui/src/demo/.eslintrc diff --git a/src/demo/dependency-generators.js b/packages/jaeger-ui/src/demo/dependency-generators.js similarity index 100% rename from src/demo/dependency-generators.js rename to packages/jaeger-ui/src/demo/dependency-generators.js diff --git a/src/demo/jaeger-mock.js b/packages/jaeger-ui/src/demo/jaeger-mock.js similarity index 100% rename from src/demo/jaeger-mock.js rename to packages/jaeger-ui/src/demo/jaeger-mock.js diff --git a/src/demo/trace-generators.js b/packages/jaeger-ui/src/demo/trace-generators.js similarity index 100% rename from src/demo/trace-generators.js rename to packages/jaeger-ui/src/demo/trace-generators.js diff --git a/src/img/jaeger-logo.svg b/packages/jaeger-ui/src/img/jaeger-logo.svg similarity index 100% rename from src/img/jaeger-logo.svg rename to packages/jaeger-ui/src/img/jaeger-logo.svg diff --git a/src/index.js b/packages/jaeger-ui/src/index.js similarity index 100% rename from src/index.js rename to packages/jaeger-ui/src/index.js diff --git a/src/middlewares/index.js b/packages/jaeger-ui/src/middlewares/index.js similarity index 90% rename from src/middlewares/index.js rename to packages/jaeger-ui/src/middlewares/index.js index a5fbf72d3a..f60dfac9eb 100644 --- a/src/middlewares/index.js +++ b/packages/jaeger-ui/src/middlewares/index.js @@ -13,12 +13,11 @@ // limitations under the License. import promiseMiddleware from 'redux-promise-middleware'; -import queryString from 'query-string'; import { change } from 'redux-form'; import { replace } from 'react-router-redux'; import { searchTraces, fetchServiceOperations } from '../actions/jaeger-api'; -import prefixUrl from '../utils/prefix-url'; +import { getUrl as getSearchUrl } from '../components/SearchTracePage/url'; export { default as trackMiddleware } from './track'; @@ -40,7 +39,7 @@ export const loadOperationsForServiceMiddleware = store => next => action => { export const historyUpdateMiddleware = store => next => action => { if (action.type === String(searchTraces)) { - const url = prefixUrl(`/search?${queryString.stringify(action.meta.query)}`); + const url = getSearchUrl(action.meta.query); store.dispatch(replace(url)); } next(action); diff --git a/src/middlewares/index.test.js b/packages/jaeger-ui/src/middlewares/index.test.js similarity index 100% rename from src/middlewares/index.test.js rename to packages/jaeger-ui/src/middlewares/index.test.js diff --git a/src/middlewares/track.js b/packages/jaeger-ui/src/middlewares/track.js similarity index 79% rename from src/middlewares/track.js rename to packages/jaeger-ui/src/middlewares/track.js index 5d3ce67f46..9e4ccb04e8 100644 --- a/src/middlewares/track.js +++ b/packages/jaeger-ui/src/middlewares/track.js @@ -14,9 +14,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { middlewareHooks } from '../components/TracePage/TraceTimelineViewer/duck.track'; +import { middlewareHooks as searchHooks } from '../components/SearchTracePage/SearchForm.track'; +import { middlewareHooks as timelineHooks } from '../components/TracePage/TraceTimelineViewer/duck.track'; import { isGaEnabled } from '../utils/tracking'; +const middlewareHooks = { ...timelineHooks, ...searchHooks }; + function trackingMiddleware(store: { getState: () => any }) { return function inner(next: any => void) { return function core(action: any) { diff --git a/src/model/order-by.js b/packages/jaeger-ui/src/model/order-by.js similarity index 100% rename from src/model/order-by.js rename to packages/jaeger-ui/src/model/order-by.js diff --git a/packages/jaeger-ui/src/model/search.js b/packages/jaeger-ui/src/model/search.js new file mode 100644 index 0000000000..1a55526248 --- /dev/null +++ b/packages/jaeger-ui/src/model/search.js @@ -0,0 +1,38 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { LEAST_SPANS, LONGEST_FIRST, MOST_RECENT, MOST_SPANS, SHORTEST_FIRST } from './order-by'; + +import type { Trace } from '../types/trace'; + +const comparators = { + [MOST_RECENT]: (a, b) => +(b.startTime > a.startTime) || +(a.startTime === b.startTime) - 1, + [SHORTEST_FIRST]: (a, b) => +(a.duration > b.duration) || +(a.duration === b.duration) - 1, + [LONGEST_FIRST]: (a, b) => +(b.duration > a.duration) || +(a.duration === b.duration) - 1, + [MOST_SPANS]: (a, b) => +(b.spans.length > a.spans.length) || +(a.spans.length === b.spans.length) - 1, + [LEAST_SPANS]: (a, b) => +(a.spans.length > b.spans.length) || +(a.spans.length === b.spans.length) - 1, +}; + +/** + * Sorts `Trace[]`, in place. + * + * @param {Trace[]} traces The `Trace` array to sort. + * @param {string} sortBy A sort specification, see ./order-by.js. + */ +export function sortTraces(traces: Trace[], sortBy: string) { + const comparator = comparators[sortBy] || comparators[LONGEST_FIRST]; + traces.sort(comparator); +} diff --git a/packages/jaeger-ui/src/model/search.test.js b/packages/jaeger-ui/src/model/search.test.js new file mode 100644 index 0000000000..cfbe173bc3 --- /dev/null +++ b/packages/jaeger-ui/src/model/search.test.js @@ -0,0 +1,51 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import _maxBy from 'lodash/maxBy'; +import _minBy from 'lodash/minBy'; + +import * as orderBy from './order-by'; +import { sortTraces } from './search'; +import traceGenerator from '../demo/trace-generators'; +import transformTraceData from '../model/transform-trace-data'; + +describe('sortTraces()', () => { + const idMinSpans = 4; + const idMaxSpans = 2; + const traces = [ + { ...transformTraceData(traceGenerator.trace({ numberOfSpans: 3 })), traceID: 1 }, + { ...transformTraceData(traceGenerator.trace({ numberOfSpans: 100 })), traceID: idMaxSpans }, + { ...transformTraceData(traceGenerator.trace({ numberOfSpans: 5 })), traceID: 3 }, + { ...transformTraceData(traceGenerator.trace({ numberOfSpans: 1 })), traceID: idMinSpans }, + ]; + + const { MOST_SPANS, LEAST_SPANS, LONGEST_FIRST, SHORTEST_FIRST, MOST_RECENT } = orderBy; + + const expecations = { + [MOST_RECENT]: _maxBy(traces, trace => trace.startTime).traceID, + [LONGEST_FIRST]: _maxBy(traces, trace => trace.duration).traceID, + [SHORTEST_FIRST]: _minBy(traces, trace => trace.duration).traceID, + [MOST_SPANS]: idMaxSpans, + [LEAST_SPANS]: idMinSpans, + }; + expecations.invalidOrderBy = expecations[LONGEST_FIRST]; + + Object.keys(expecations).forEach(sortBy => { + it(`sorts by ${sortBy}`, () => { + const traceID = expecations[sortBy]; + sortTraces(traces, sortBy); + expect(traces[0].traceID).toBe(traceID); + }); + }); +}); diff --git a/packages/jaeger-ui/src/model/trace-dag/DagNode.js b/packages/jaeger-ui/src/model/trace-dag/DagNode.js new file mode 100644 index 0000000000..6a16689a70 --- /dev/null +++ b/packages/jaeger-ui/src/model/trace-dag/DagNode.js @@ -0,0 +1,42 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import type { NodeID } from './types'; + +export default class DagNode { + static getID(service: string, operation: string, parentID?: ?string): NodeID { + const name = `${service}\t${operation}`; + return parentID ? `${parentID}\n${name}` : name; + } + + service: string; + operation: string; + parentID: ?NodeID; + id: NodeID; + count: number; + children: Set; + data: T; + + constructor(service: string, operation: string, parentID?: ?NodeID, data: T) { + this.service = service; + this.operation = operation; + this.parentID = parentID; + this.id = DagNode.getID(service, operation, parentID); + this.count = 0; + this.children = new Set(); + this.data = data; + } +} diff --git a/packages/jaeger-ui/src/model/trace-dag/DenseTrace.js b/packages/jaeger-ui/src/model/trace-dag/DenseTrace.js new file mode 100644 index 0000000000..bea6da4cdb --- /dev/null +++ b/packages/jaeger-ui/src/model/trace-dag/DenseTrace.js @@ -0,0 +1,90 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import denseTransforms from './denseTransforms'; + +import type { DenseSpan } from './types'; +import type { Span, Trace } from '../../types/trace'; + +function convSpans(spans: Span[]) { + const map: Map = new Map(); + const roots: Set = new Set(); + const ids: string[] = []; + spans.forEach(span => { + const { spanID: id, operationName: operation, process, references, tags: spanTags } = span; + ids.push(id); + const { serviceName: service } = process; + const tags = spanTags.reduce((accum, tag) => { + const { key, value } = tag; + // eslint-disable-next-line no-param-reassign + accum[key] = value; + return accum; + }, {}); + let parentID: ?string = null; + if (references && references.length) { + const { refType, spanID } = references[0]; + if (refType !== 'CHILD_OF' && refType !== 'FOLLOWS_FROM') { + console.warn(`Unrecognized ref type: ${refType}`); + } else { + parentID = spanID; + } + } + + const denseSpan = { + id, + operation, + parentID, + service, + span, + tags, + children: new Set(), + skipToChild: false, + }; + const parent = parentID && map.get(parentID); + if (!parent) { + // some root spans have a parent ID but it is missing + roots.add(id); + } else { + parent.children.add(id); + } + map.set(id, denseSpan); + }); + return { ids, map, roots }; +} + +function makeDense(spanIDs: string[], map: Map) { + spanIDs.forEach(id => { + const denseSpan = map.get(id); + // make flow happy + if (denseSpan) { + denseTransforms(denseSpan, map); + } + }); +} + +export default class DenseTrace { + trace: Trace; + rootIDs: Set; + denseSpansMap: Map; + + constructor(trace: Trace) { + this.trace = trace; + const { ids, map, roots } = convSpans(trace.spans); + makeDense(ids, map); + this.rootIDs = roots; + this.denseSpansMap = map; + } +} diff --git a/packages/jaeger-ui/src/model/trace-dag/TraceDag.js b/packages/jaeger-ui/src/model/trace-dag/TraceDag.js new file mode 100644 index 0000000000..4606e24bd2 --- /dev/null +++ b/packages/jaeger-ui/src/model/trace-dag/TraceDag.js @@ -0,0 +1,106 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import DagNode from './DagNode'; +import DenseTrace from './DenseTrace'; + +import type { NodeID } from './types'; +import type { Trace } from '../../types/trace'; + +type DiffCounts = { + a: number, + b: number, +}; + +export default class TraceDag { + static newFromTrace(trace: Trace) { + const dt: TraceDag<> = new TraceDag(); + dt._initFromTrace(trace); + return dt; + } + + static diff(a: TraceDag, b: TraceDag) { + const dt: TraceDag = new TraceDag(); + let key = 'a'; + + function pushDagNode(src: DagNode) { + const node = dt._getDagNode(src.service, src.operation, src.parentID, { a: 0, b: 0 }); + const { data } = node; + data[key] = src.count; + node.count = data.b - data.a; + if (!node.parentID) { + dt.rootIDs.add(node.id); + } + } + key = 'a'; + [...a.nodesMap.values()].forEach(pushDagNode); + key = 'b'; + [...b.nodesMap.values()].forEach(pushDagNode); + return dt; + } + + denseTrace: ?DenseTrace; + nodesMap: Map>; + rootIDs: Set; + + constructor() { + this.denseTrace = null; + this.nodesMap = new Map(); + this.rootIDs = new Set(); + } + + _initFromTrace(trace: Trace, data: T) { + this.denseTrace = new DenseTrace(trace); + [...this.denseTrace.rootIDs].forEach(id => this._addDenseSpan(id, null, data)); + } + + _getDagNode(service: string, operation: string, parentID?: ?NodeID, data: T): DagNode { + const nodeID = DagNode.getID(service, operation, parentID); + let node = this.nodesMap.get(nodeID); + if (node) { + return node; + } + node = new DagNode(service, operation, parentID, data); + this.nodesMap.set(nodeID, node); + if (!parentID) { + this.rootIDs.add(nodeID); + } else { + const parentDag = this.nodesMap.get(parentID); + if (parentDag) { + parentDag.children.add(nodeID); + } + } + return node; + } + + _addDenseSpan(spanID: string, parentNodeID?: ?NodeID, data: T) { + const denseSpan = this.denseTrace && this.denseTrace.denseSpansMap.get(spanID); + if (!denseSpan) { + console.warn(`Missing dense span: ${spanID}`); + return; + } + const { children, operation, service, skipToChild } = denseSpan; + let nodeID: ?string = null; + if (!skipToChild) { + const node = this._getDagNode(service, operation, parentNodeID, data); + node.count++; + nodeID = node.id; + } else { + nodeID = parentNodeID; + } + [...children].forEach(id => this._addDenseSpan(id, nodeID, data)); + } +} diff --git a/packages/jaeger-ui/src/model/trace-dag/convPlexus.js b/packages/jaeger-ui/src/model/trace-dag/convPlexus.js new file mode 100644 index 0000000000..2342822aaf --- /dev/null +++ b/packages/jaeger-ui/src/model/trace-dag/convPlexus.js @@ -0,0 +1,48 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import DagNode from './DagNode'; + +import type { NodeID, PEdge, PVertex } from './types'; + +export default function convPlexus(nodesMap: Map>) { + const vertices: PVertex[] = []; + const edges: PEdge[] = []; + const ids = [...nodesMap.keys()]; + const keyMap: Map = new Map(ids.map((id: NodeID, i: number) => [id, i])); + for (let i = 0; i < ids.length; i++) { + const id = ids[i]; + const dagNode = nodesMap.get(id); + if (!dagNode) { + // should not happen, keep flow happy + continue; + } + vertices.push({ + key: i, + label: `${dagNode.count} | ${dagNode.operation}`, + data: dagNode, + }); + const parentKey = dagNode.parentID && keyMap.get(dagNode.parentID); + if (parentKey == null) { + continue; + } + edges.push({ + from: parentKey, + to: i, + }); + } + return { edges, vertices }; +} diff --git a/packages/jaeger-ui/src/model/trace-dag/denseTransforms.js b/packages/jaeger-ui/src/model/trace-dag/denseTransforms.js new file mode 100644 index 0000000000..5397454322 --- /dev/null +++ b/packages/jaeger-ui/src/model/trace-dag/denseTransforms.js @@ -0,0 +1,135 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as tagKeys from '../../constants/tag-keys'; + +import type { DenseSpan } from './types'; + +// - if span +// - is client span +// - is leaf +// - has parent.operation startsWith self-tag peer.service +// - has parent.operation endsWith self.operation +// - set self.service = self-tag peer.service +function fixLeafService(denseSpan: DenseSpan, map: Map) { + const { children, operation, parentID, tags } = denseSpan; + const parent = parentID != null && map.get(parentID); + const kind = tags[tagKeys.SPAN_KIND]; + const peerSvc = tags[tagKeys.PEER_SERVICE]; + if (!parent || children.size > 0 || kind !== 'client' || !peerSvc) { + return; + } + const { operation: parentOp } = parent; + if (parentOp.indexOf(peerSvc) === 0 && parentOp.slice(-operation.length) === operation) { + // eslint-disable-next-line no-param-reassign + denseSpan.service = peerSvc; + } +} + +// - if span +// - is server span +// - parent is client span +// - parent has one child (self) +// - (parent.operation OR parent-tag peer.service) startsWith self.service +// - set parent.skipToChild = true +function skipClient(denseSpan: DenseSpan, map: Map) { + const { parentID, service, tags } = denseSpan; + const parent = parentID != null && map.get(parentID); + if (!parent) { + return; + } + const kind = tags[tagKeys.SPAN_KIND]; + const parentKind = parent.tags[tagKeys.SPAN_KIND]; + const parentPeerSvc = parent.tags[tagKeys.PEER_SERVICE] || ''; + if (kind === 'server' && parentKind === 'client' && parent.children.size === 1) { + parent.skipToChild = parent.operation.indexOf(service) === 0 || parentPeerSvc.indexOf(service) === 0; + } +} + +// - if span +// - is server span +// - has operation === tag http.method +// - (parent.operation OR parent-tag peer.service) startsWith self.service +// - fix self.operation +function fixHttpOperation(denseSpan: DenseSpan, map: Map) { + const { parentID, operation, service, tags } = denseSpan; + const parent = parentID != null && map.get(parentID); + if (!parent) { + return; + } + const kind = tags[tagKeys.SPAN_KIND]; + const httpMethod = tags[tagKeys.HTTP_METHOD]; + if (kind !== 'server' || operation !== httpMethod) { + return; + } + const parentPeerSvc = parent.tags[tagKeys.PEER_SERVICE] || ''; + if (parent.operation.indexOf(service) === 0 || parentPeerSvc.indexOf(service) === 0) { + const rx = new RegExp(`^${service}(::)?`); + const endpoint = parent.operation.replace(rx, ''); + // eslint-disable-next-line no-param-reassign + denseSpan.operation = `${httpMethod} ${endpoint}`; + } +} + +// - if span +// - has no tags +// - has only one child +// - parent.process === self.process +// - set self.skipToChild = true +function skipAnnotationSpans(denseSpan: DenseSpan, map: Map) { + const { children, parentID, span } = denseSpan; + if (children.size !== 1 || span.tags.length !== 0) { + return; + } + const parent = parentID != null && map.get(parentID); + const childID = [...children][0]; + const child = childID != null && map.get(childID); + if (!parent || !child) { + return; + } + // eslint-disable-next-line no-param-reassign + denseSpan.skipToChild = parent.span.processID === span.processID; +} + +// - if span +// - is a client span +// - has only one child +// - the child is a server span +// - parent.span.processID === self.span.processID +// - set parent.skipToChild = true +function skipClientSpans(denseSpan: DenseSpan, map: Map) { + const { children, parentID, span, tags } = denseSpan; + if (children.size !== 1 || tags[tagKeys.SPAN_KIND] !== 'client') { + return; + } + const parent = parentID != null && map.get(parentID); + const childID = [...children][0]; + const child = childID != null && map.get(childID); + if (!parent || !child) { + return; + } + // eslint-disable-next-line no-param-reassign + denseSpan.skipToChild = + child.tags[tagKeys.SPAN_KIND] === 'client' && parent.span.processID === span.processID; +} + +export default function denseTransforms(denseSpan: DenseSpan, map: Map) { + fixLeafService(denseSpan, map); + skipClient(denseSpan, map); + fixHttpOperation(denseSpan, map); + skipAnnotationSpans(denseSpan, map); + skipClientSpans(denseSpan, map); +} diff --git a/packages/jaeger-ui/src/model/trace-dag/types.js b/packages/jaeger-ui/src/model/trace-dag/types.js new file mode 100644 index 0000000000..5526d15038 --- /dev/null +++ b/packages/jaeger-ui/src/model/trace-dag/types.js @@ -0,0 +1,42 @@ +// @flow + +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import DagNode from './DagNode'; + +import type { Span } from '../../types/trace'; + +export type NodeID = string; + +export type DenseSpan = { + span: Span, + id: string, + service: string, + operation: string, + tags: { [string]: any }, + parentID: ?string, + skipToChild: boolean, + children: Set, +}; + +export type PVertex = { + key: string | number, + data: DagNode, +}; + +export type PEdge = { + from: string | number, + to: string | number, +}; diff --git a/src/model/trace-viewer.js b/packages/jaeger-ui/src/model/trace-viewer.js similarity index 100% rename from src/model/trace-viewer.js rename to packages/jaeger-ui/src/model/trace-viewer.js diff --git a/src/model/transform-trace-data.js b/packages/jaeger-ui/src/model/transform-trace-data.js similarity index 89% rename from src/model/transform-trace-data.js rename to packages/jaeger-ui/src/model/transform-trace-data.js index 4b1a5fe1ed..16fc7e94a8 100644 --- a/src/model/transform-trace-data.js +++ b/packages/jaeger-ui/src/model/transform-trace-data.js @@ -17,7 +17,8 @@ import _isEqual from 'lodash/isEqual'; import { getTraceSpanIdsAsTree } from '../selectors/trace'; -import type { Process, Span, SpanData, Trace, TraceData } from '../types'; + +import type { Process, Span, SpanData, Trace, TraceData } from '../types/trace'; type SpanWithProcess = SpanData & { process: Process }; @@ -75,6 +76,8 @@ export default function transfromTraceData(data: TraceData & { spans: SpanWithPr // siblings are sorted by start time const tree = getTraceSpanIdsAsTree(data); const spans: Span[] = []; + const svcCounts: { [string]: number } = {}; + let traceName = ''; tree.walk((spanID, node, depth) => { if (spanID === '__root__') { @@ -84,6 +87,11 @@ export default function transfromTraceData(data: TraceData & { spans: SpanWithPr if (!span) { return; } + const { serviceName } = span.process; + svcCounts[serviceName] = (svcCounts[serviceName] || 0) + 1; + if (!span.references || !span.references.length) { + traceName = `${serviceName}: ${span.operationName}`; + } spans.push({ relativeStartTime: span.startTime - traceStartTime, depth: depth - 1, @@ -101,9 +109,12 @@ export default function transfromTraceData(data: TraceData & { spans: SpanWithPr traceID: span.traceID, }); }); + const services = Object.keys(svcCounts).map(name => ({ name, numberOfSpans: svcCounts[name] })); return { + services, spans, traceID, + traceName, // can't use spread operator for intersection types // repl: https://goo.gl/4Z23MJ // issue: https://github.com/facebook/flow/issues/1511 diff --git a/src/propTypes/dependencies.js b/packages/jaeger-ui/src/propTypes/dependencies.js similarity index 100% rename from src/propTypes/dependencies.js rename to packages/jaeger-ui/src/propTypes/dependencies.js diff --git a/src/reducers/config.js b/packages/jaeger-ui/src/reducers/config.js similarity index 100% rename from src/reducers/config.js rename to packages/jaeger-ui/src/reducers/config.js diff --git a/src/reducers/dependencies.js b/packages/jaeger-ui/src/reducers/dependencies.js similarity index 100% rename from src/reducers/dependencies.js rename to packages/jaeger-ui/src/reducers/dependencies.js diff --git a/src/reducers/dependencies.test.js b/packages/jaeger-ui/src/reducers/dependencies.test.js similarity index 100% rename from src/reducers/dependencies.test.js rename to packages/jaeger-ui/src/reducers/dependencies.test.js diff --git a/src/reducers/index.js b/packages/jaeger-ui/src/reducers/index.js similarity index 100% rename from src/reducers/index.js rename to packages/jaeger-ui/src/reducers/index.js diff --git a/src/reducers/services.js b/packages/jaeger-ui/src/reducers/services.js similarity index 100% rename from src/reducers/services.js rename to packages/jaeger-ui/src/reducers/services.js diff --git a/src/reducers/services.test.js b/packages/jaeger-ui/src/reducers/services.test.js similarity index 100% rename from src/reducers/services.test.js rename to packages/jaeger-ui/src/reducers/services.test.js diff --git a/packages/jaeger-ui/src/reducers/trace.js b/packages/jaeger-ui/src/reducers/trace.js new file mode 100644 index 0000000000..42f167dff2 --- /dev/null +++ b/packages/jaeger-ui/src/reducers/trace.js @@ -0,0 +1,132 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { handleActions } from 'redux-actions'; + +import { fetchTrace, fetchMultipleTraces, searchTraces } from '../actions/jaeger-api'; +import { fetchedState } from '../constants'; +import transformTraceData from '../model/transform-trace-data'; + +const initialState = { + traces: {}, + search: { + results: [], + }, +}; + +function fetchTraceStarted(state, { meta }) { + const { id } = meta; + const traces = { ...state.traces, [id]: { id, state: fetchedState.LOADING } }; + return { ...state, traces }; +} + +function fetchTraceDone(state, { meta, payload }) { + const { id } = meta; + const data = transformTraceData(payload.data[0]); + let trace; + if (!data) { + trace = { id, state: fetchedState.ERROR, error: new Error('Invalid trace data recieved.') }; + } else { + trace = { data, id, state: fetchedState.DONE }; + } + const traces = { ...state.traces, [id]: trace }; + return { ...state, traces }; +} + +function fetchTraceErred(state, { meta, payload }) { + const { id } = meta; + const trace = { id, error: payload, state: fetchedState.ERROR }; + const traces = { ...state.traces, [id]: trace }; + return { ...state, traces }; +} + +function fetchMultipleTracesStarted(state, { meta }) { + const { ids } = meta; + const traces = { ...state.traces }; + ids.forEach(id => { + traces[id] = { id, state: fetchedState.LOADING }; + }); + return { ...state, traces }; +} + +function fetchMultipleTracesDone(state, { payload }) { + const traces = { ...state.traces }; + payload.data.forEach(raw => { + const data = transformTraceData(raw); + traces[data.traceID] = { data, id: data.traceID, state: fetchedState.DONE }; + }); + if (payload.errors) { + payload.errors.forEach(err => { + const { msg, traceID } = err; + const error = new Error(`Error: ${msg} - ${traceID}`); + traces[traceID] = { error, id: traceID, state: fetchedState.ERROR }; + }); + } + return { ...state, traces }; +} + +function fetchMultipleTracesErred(state, { meta, payload }) { + const { ids } = meta; + const traces = { ...state.traces }; + const error = payload; + ids.forEach(id => { + traces[id] = { error, id, state: fetchedState.ERROR }; + }); + return { ...state, traces }; +} + +function fetchSearchStarted(state) { + const search = { + results: [], + state: fetchedState.LOADING, + }; + return { ...state, search }; +} + +function searchDone(state, { payload }) { + const processed = payload.data.map(transformTraceData); + const resultTraces = {}; + const results = []; + for (let i = 0; i < processed.length; i++) { + const data = processed[i]; + const id = data.traceID; + resultTraces[id] = { data, id, state: fetchedState.DONE }; + results.push(id); + } + const traces = { ...state.traces, ...resultTraces }; + const search = { results, state: fetchedState.DONE }; + return { ...state, search, traces }; +} + +function searchErred(state, { payload }) { + const search = { error: payload, results: [], state: fetchedState.ERROR }; + return { ...state, search }; +} + +export default handleActions( + { + [`${fetchTrace}_PENDING`]: fetchTraceStarted, + [`${fetchTrace}_FULFILLED`]: fetchTraceDone, + [`${fetchTrace}_REJECTED`]: fetchTraceErred, + + [`${fetchMultipleTraces}_PENDING`]: fetchMultipleTracesStarted, + [`${fetchMultipleTraces}_FULFILLED`]: fetchMultipleTracesDone, + [`${fetchMultipleTraces}_REJECTED`]: fetchMultipleTracesErred, + + [`${searchTraces}_PENDING`]: fetchSearchStarted, + [`${searchTraces}_FULFILLED`]: searchDone, + [`${searchTraces}_REJECTED`]: searchErred, + }, + initialState +); diff --git a/src/reducers/trace.test.js b/packages/jaeger-ui/src/reducers/trace.test.js similarity index 55% rename from src/reducers/trace.test.js rename to packages/jaeger-ui/src/reducers/trace.test.js index 7b8acb2bc6..95fab6d28b 100644 --- a/src/reducers/trace.test.js +++ b/packages/jaeger-ui/src/reducers/trace.test.js @@ -12,29 +12,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as jaegerApiActions from '../../src/actions/jaeger-api'; -import traceReducer from '../../src/reducers/trace'; -import traceGenerator from '../../src/demo/trace-generators'; -import transformTraceData from '../../src/model/transform-trace-data'; +import * as jaegerApiActions from '../actions/jaeger-api'; +import { fetchedState } from '../constants'; +import traceGenerator from '../demo/trace-generators'; +import transformTraceData from '../model/transform-trace-data'; +import traceReducer from '../reducers/trace'; -const generatedTrace = traceGenerator.trace({ numberOfSpans: 1 }); -const { traceID } = generatedTrace; +const trace = traceGenerator.trace({ numberOfSpans: 1 }); +const { traceID: id } = trace; it('trace reducer should set loading true on a fetch', () => { const state = traceReducer(undefined, { type: `${jaegerApiActions.fetchTrace}_PENDING`, + meta: { id }, }); - expect(state.loading).toBe(true); + const outcome = { [id]: { id, state: fetchedState.LOADING } }; + expect(state.traces).toEqual(outcome); }); it('trace reducer should handle a successful FETCH_TRACE', () => { const state = traceReducer(undefined, { type: `${jaegerApiActions.fetchTrace}_FULFILLED`, - payload: { data: [generatedTrace] }, - meta: { id: traceID }, + payload: { data: [trace] }, + meta: { id }, }); - expect(state.traces).toEqual({ [traceID]: transformTraceData(generatedTrace) }); - expect(state.loading).toBe(false); + expect(state.traces).toEqual({ [id]: { id, data: transformTraceData(trace), state: fetchedState.DONE } }); }); it('trace reducer should handle a failed FETCH_TRACE', () => { @@ -42,19 +44,30 @@ it('trace reducer should handle a failed FETCH_TRACE', () => { const state = traceReducer(undefined, { type: `${jaegerApiActions.fetchTrace}_REJECTED`, payload: error, - meta: { id: traceID }, + meta: { id }, }); - expect(state.traces).toEqual({ [traceID]: error }); - expect(state.traces[traceID]).toBe(error); - expect(state.loading).toBe(false); + expect(state.traces).toEqual({ [id]: { error, id, state: fetchedState.ERROR } }); + expect(state.traces[id].error).toBe(error); }); it('trace reducer should handle a successful SEARCH_TRACES', () => { const state = traceReducer(undefined, { type: `${jaegerApiActions.searchTraces}_FULFILLED`, - payload: { data: [generatedTrace] }, + payload: { data: [trace] }, meta: { query: 'whatever' }, }); - expect(state.traces).toEqual({ [traceID]: transformTraceData(generatedTrace) }); - expect(state.loading).toBe(false); + const outcome = { + traces: { + [id]: { + id, + data: transformTraceData(trace), + state: fetchedState.DONE, + }, + }, + search: { + state: fetchedState.DONE, + results: [id], + }, + }; + expect(state).toEqual(outcome); }); diff --git a/src/selectors/dependencies.js b/packages/jaeger-ui/src/selectors/dependencies.js similarity index 100% rename from src/selectors/dependencies.js rename to packages/jaeger-ui/src/selectors/dependencies.js diff --git a/src/selectors/process.js b/packages/jaeger-ui/src/selectors/process.js similarity index 100% rename from src/selectors/process.js rename to packages/jaeger-ui/src/selectors/process.js diff --git a/src/selectors/process.test.js b/packages/jaeger-ui/src/selectors/process.test.js similarity index 100% rename from src/selectors/process.test.js rename to packages/jaeger-ui/src/selectors/process.test.js diff --git a/src/selectors/span.js b/packages/jaeger-ui/src/selectors/span.js similarity index 100% rename from src/selectors/span.js rename to packages/jaeger-ui/src/selectors/span.js diff --git a/src/selectors/span.test.js b/packages/jaeger-ui/src/selectors/span.test.js similarity index 100% rename from src/selectors/span.test.js rename to packages/jaeger-ui/src/selectors/span.test.js diff --git a/src/selectors/trace.fixture.js b/packages/jaeger-ui/src/selectors/trace.fixture.js similarity index 100% rename from src/selectors/trace.fixture.js rename to packages/jaeger-ui/src/selectors/trace.fixture.js diff --git a/src/selectors/trace.js b/packages/jaeger-ui/src/selectors/trace.js similarity index 100% rename from src/selectors/trace.js rename to packages/jaeger-ui/src/selectors/trace.js diff --git a/src/selectors/trace.test.js b/packages/jaeger-ui/src/selectors/trace.test.js similarity index 100% rename from src/selectors/trace.test.js rename to packages/jaeger-ui/src/selectors/trace.test.js diff --git a/src/setupTests.js b/packages/jaeger-ui/src/setupTests.js similarity index 100% rename from src/setupTests.js rename to packages/jaeger-ui/src/setupTests.js diff --git a/src/site-prefix.js b/packages/jaeger-ui/src/site-prefix.js similarity index 100% rename from src/site-prefix.js rename to packages/jaeger-ui/src/site-prefix.js diff --git a/src/types/api-error.js b/packages/jaeger-ui/src/types/api-error.js similarity index 100% rename from src/types/api-error.js rename to packages/jaeger-ui/src/types/api-error.js diff --git a/src/types/archive.js b/packages/jaeger-ui/src/types/archive.js similarity index 100% rename from src/types/archive.js rename to packages/jaeger-ui/src/types/archive.js diff --git a/src/types/config.js b/packages/jaeger-ui/src/types/config.js similarity index 100% rename from src/types/config.js rename to packages/jaeger-ui/src/types/config.js diff --git a/packages/jaeger-ui/src/types/index.js b/packages/jaeger-ui/src/types/index.js new file mode 100644 index 0000000000..a08112c927 --- /dev/null +++ b/packages/jaeger-ui/src/types/index.js @@ -0,0 +1,60 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import type { ContextRouter } from 'react-router-dom'; + +import type { ApiError } from './api-error'; +import type { TracesArchive } from './archive'; +import type { Config } from './config'; +import type { Trace } from './trace'; +import type { TraceDiffState } from './trace-diff'; +import type { TraceTimeline } from './trace-timeline'; + +export type FetchedState = 'FETCH_DONE' | 'FETCH_ERROR' | 'FETCH_LOADING'; + +export type FetchedTrace = { + data?: Trace, + error?: ApiError, + id: string, + state?: FetchedState, +}; + +export type ReduxState = { + archive: TracesArchive, + config: Config, + dependencies: { + dependencies: { parent: string, child: string, callCount: number }[], + loading: boolean, + error: ?ApiError, + }, + services: { + services: ?(string[]), + operationsForService: { [string]: string[] }, + loading: boolean, + error: ?ApiError, + }, + router: ContextRouter, + trace: { + traces: { [string]: FetchedTrace }, + search: { + error?: ApiError, + results: string[], + state?: FetchedState, + }, + }, + traceDiff: TraceDiffState, + traceTimeline: TraceTimeline, +}; diff --git a/src/types/search.js b/packages/jaeger-ui/src/types/search.js similarity index 100% rename from src/types/search.js rename to packages/jaeger-ui/src/types/search.js diff --git a/packages/jaeger-ui/src/types/trace-diff.js b/packages/jaeger-ui/src/types/trace-diff.js new file mode 100644 index 0000000000..932f18ba75 --- /dev/null +++ b/packages/jaeger-ui/src/types/trace-diff.js @@ -0,0 +1,21 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export type TraceDiffState = { + a: ?string, + b: ?string, + cohort: string[], +}; diff --git a/packages/jaeger-ui/src/types/trace-timeline.js b/packages/jaeger-ui/src/types/trace-timeline.js new file mode 100644 index 0000000000..94457a4b2a --- /dev/null +++ b/packages/jaeger-ui/src/types/trace-timeline.js @@ -0,0 +1,25 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import DetailState from '../components/TracePage/TraceTimelineViewer/SpanDetail/DetailState'; + +export type TraceTimeline = { + traceID: ?string, + spanNameColumnWidth: number, + childrenHiddenIDs: Set, + findMatches: ?Set, + detailStates: Map, +}; diff --git a/src/types/index.js b/packages/jaeger-ui/src/types/trace.js similarity index 95% rename from src/types/index.js rename to packages/jaeger-ui/src/types/trace.js index 55ca7d2028..0ca3fb13f6 100644 --- a/src/types/index.js +++ b/packages/jaeger-ui/src/types/trace.js @@ -68,4 +68,6 @@ export type Trace = TraceData & { endTime: number, spans: Span[], startTime: number, + traceName: string, + services: { name: string, numberOfSpans: number }[], }; diff --git a/src/utils/DraggableManager/DraggableManager.js b/packages/jaeger-ui/src/utils/DraggableManager/DraggableManager.js similarity index 100% rename from src/utils/DraggableManager/DraggableManager.js rename to packages/jaeger-ui/src/utils/DraggableManager/DraggableManager.js diff --git a/src/utils/DraggableManager/DraggableManager.test.js b/packages/jaeger-ui/src/utils/DraggableManager/DraggableManager.test.js similarity index 100% rename from src/utils/DraggableManager/DraggableManager.test.js rename to packages/jaeger-ui/src/utils/DraggableManager/DraggableManager.test.js diff --git a/src/utils/DraggableManager/README.md b/packages/jaeger-ui/src/utils/DraggableManager/README.md similarity index 100% rename from src/utils/DraggableManager/README.md rename to packages/jaeger-ui/src/utils/DraggableManager/README.md diff --git a/src/utils/DraggableManager/demo/DividerDemo.css b/packages/jaeger-ui/src/utils/DraggableManager/demo/DividerDemo.css similarity index 100% rename from src/utils/DraggableManager/demo/DividerDemo.css rename to packages/jaeger-ui/src/utils/DraggableManager/demo/DividerDemo.css diff --git a/src/utils/DraggableManager/demo/DividerDemo.js b/packages/jaeger-ui/src/utils/DraggableManager/demo/DividerDemo.js similarity index 100% rename from src/utils/DraggableManager/demo/DividerDemo.js rename to packages/jaeger-ui/src/utils/DraggableManager/demo/DividerDemo.js diff --git a/src/utils/DraggableManager/demo/DraggableManagerDemo.css b/packages/jaeger-ui/src/utils/DraggableManager/demo/DraggableManagerDemo.css similarity index 100% rename from src/utils/DraggableManager/demo/DraggableManagerDemo.css rename to packages/jaeger-ui/src/utils/DraggableManager/demo/DraggableManagerDemo.css diff --git a/src/utils/DraggableManager/demo/DraggableManagerDemo.js b/packages/jaeger-ui/src/utils/DraggableManager/demo/DraggableManagerDemo.js similarity index 100% rename from src/utils/DraggableManager/demo/DraggableManagerDemo.js rename to packages/jaeger-ui/src/utils/DraggableManager/demo/DraggableManagerDemo.js diff --git a/src/utils/DraggableManager/demo/RegionDemo.css b/packages/jaeger-ui/src/utils/DraggableManager/demo/RegionDemo.css similarity index 100% rename from src/utils/DraggableManager/demo/RegionDemo.css rename to packages/jaeger-ui/src/utils/DraggableManager/demo/RegionDemo.css diff --git a/src/utils/DraggableManager/demo/RegionDemo.js b/packages/jaeger-ui/src/utils/DraggableManager/demo/RegionDemo.js similarity index 100% rename from src/utils/DraggableManager/demo/RegionDemo.js rename to packages/jaeger-ui/src/utils/DraggableManager/demo/RegionDemo.js diff --git a/src/utils/DraggableManager/demo/demo-ux.gif b/packages/jaeger-ui/src/utils/DraggableManager/demo/demo-ux.gif similarity index 100% rename from src/utils/DraggableManager/demo/demo-ux.gif rename to packages/jaeger-ui/src/utils/DraggableManager/demo/demo-ux.gif diff --git a/src/utils/DraggableManager/demo/index.js b/packages/jaeger-ui/src/utils/DraggableManager/demo/index.js similarity index 100% rename from src/utils/DraggableManager/demo/index.js rename to packages/jaeger-ui/src/utils/DraggableManager/demo/index.js diff --git a/src/utils/DraggableManager/index.js b/packages/jaeger-ui/src/utils/DraggableManager/index.js similarity index 100% rename from src/utils/DraggableManager/index.js rename to packages/jaeger-ui/src/utils/DraggableManager/index.js diff --git a/src/utils/DraggableManager/types.js b/packages/jaeger-ui/src/utils/DraggableManager/types.js similarity index 100% rename from src/utils/DraggableManager/types.js rename to packages/jaeger-ui/src/utils/DraggableManager/types.js diff --git a/src/utils/DraggableManager/update-types.js b/packages/jaeger-ui/src/utils/DraggableManager/update-types.js similarity index 100% rename from src/utils/DraggableManager/update-types.js rename to packages/jaeger-ui/src/utils/DraggableManager/update-types.js diff --git a/src/utils/TreeNode.js b/packages/jaeger-ui/src/utils/TreeNode.js similarity index 100% rename from src/utils/TreeNode.js rename to packages/jaeger-ui/src/utils/TreeNode.js diff --git a/src/utils/TreeNode.test.js b/packages/jaeger-ui/src/utils/TreeNode.test.js similarity index 100% rename from src/utils/TreeNode.test.js rename to packages/jaeger-ui/src/utils/TreeNode.test.js diff --git a/src/utils/color-generator.js b/packages/jaeger-ui/src/utils/color-generator.js similarity index 100% rename from src/utils/color-generator.js rename to packages/jaeger-ui/src/utils/color-generator.js diff --git a/src/utils/color-generator.test.js b/packages/jaeger-ui/src/utils/color-generator.test.js similarity index 100% rename from src/utils/color-generator.test.js rename to packages/jaeger-ui/src/utils/color-generator.test.js diff --git a/src/utils/config/get-config.js b/packages/jaeger-ui/src/utils/config/get-config.js similarity index 100% rename from src/utils/config/get-config.js rename to packages/jaeger-ui/src/utils/config/get-config.js diff --git a/src/utils/config/get-config.test.js b/packages/jaeger-ui/src/utils/config/get-config.test.js similarity index 100% rename from src/utils/config/get-config.test.js rename to packages/jaeger-ui/src/utils/config/get-config.test.js diff --git a/src/utils/config/process-deprecation.js b/packages/jaeger-ui/src/utils/config/process-deprecation.js similarity index 100% rename from src/utils/config/process-deprecation.js rename to packages/jaeger-ui/src/utils/config/process-deprecation.js diff --git a/src/utils/config/process-deprecation.test.js b/packages/jaeger-ui/src/utils/config/process-deprecation.test.js similarity index 100% rename from src/utils/config/process-deprecation.test.js rename to packages/jaeger-ui/src/utils/config/process-deprecation.test.js diff --git a/src/utils/configure-store.js b/packages/jaeger-ui/src/utils/configure-store.js similarity index 84% rename from src/utils/configure-store.js rename to packages/jaeger-ui/src/utils/configure-store.js index ab0f5c2a4f..c6593d60c1 100644 --- a/src/utils/configure-store.js +++ b/packages/jaeger-ui/src/utils/configure-store.js @@ -16,17 +16,19 @@ import { createStore, combineReducers, applyMiddleware, compose } from 'redux'; import { routerReducer, routerMiddleware } from 'react-router-redux'; import { window } from 'global'; +import traceDiff from '../components/TraceDiff/duck'; +import archive from '../components/TracePage/ArchiveNotifier/duck'; +import traceTimeline from '../components/TracePage/TraceTimelineViewer/duck'; import jaegerReducers from '../reducers'; import * as jaegerMiddlewares from '../middlewares'; -import archiveReducer from '../components/TracePage/ArchiveNotifier/duck'; -import traceTimelineViewReducer from '../components/TracePage/TraceTimelineViewer/duck'; export default function configureStore(history) { return createStore( combineReducers({ ...jaegerReducers, - archive: archiveReducer, - traceTimeline: traceTimelineViewReducer, + archive, + traceDiff, + traceTimeline, router: routerReducer, }), compose( diff --git a/src/utils/configure-store.test.js b/packages/jaeger-ui/src/utils/configure-store.test.js similarity index 100% rename from src/utils/configure-store.test.js rename to packages/jaeger-ui/src/utils/configure-store.test.js diff --git a/src/utils/date.js b/packages/jaeger-ui/src/utils/date.js similarity index 94% rename from src/utils/date.js rename to packages/jaeger-ui/src/utils/date.js index 0aa42cb051..6d125f76b4 100644 --- a/src/utils/date.js +++ b/packages/jaeger-ui/src/utils/date.js @@ -102,11 +102,12 @@ export function formatDuration(duration, inputUnit = 'microseconds') { return _.round(d, 2) + units; } -export function formatRelativeDate(value) { +export function formatRelativeDate(value, fullMonthName = false) { const m = !(value instanceof moment) ? moment(value) : value; + const monthFormat = fullMonthName ? 'MMMM' : 'MMM'; const dt = new Date(); if (dt.getFullYear() !== m.year()) { - return m.format('MMM D, YYYY'); + return m.format(`${monthFormat} D, YYYY`); } const mMonth = m.month(); const mDate = m.date(); @@ -118,5 +119,5 @@ export function formatRelativeDate(value) { if (mMonth === dt.getMonth() && mDate === dt.getDate()) { return YESTERDAY; } - return m.format('MMM D'); + return m.format(`${monthFormat} D`); } diff --git a/src/utils/generate-action-types.js b/packages/jaeger-ui/src/utils/generate-action-types.js similarity index 100% rename from src/utils/generate-action-types.js rename to packages/jaeger-ui/src/utils/generate-action-types.js diff --git a/src/utils/get-last-xform-cacher.js b/packages/jaeger-ui/src/utils/get-last-xform-cacher.js similarity index 100% rename from src/utils/get-last-xform-cacher.js rename to packages/jaeger-ui/src/utils/get-last-xform-cacher.js diff --git a/src/utils/get-last-xform-cacher.test.js b/packages/jaeger-ui/src/utils/get-last-xform-cacher.test.js similarity index 100% rename from src/utils/get-last-xform-cacher.test.js rename to packages/jaeger-ui/src/utils/get-last-xform-cacher.test.js diff --git a/src/utils/number.js b/packages/jaeger-ui/src/utils/number.js similarity index 100% rename from src/utils/number.js rename to packages/jaeger-ui/src/utils/number.js diff --git a/src/utils/number.test.js b/packages/jaeger-ui/src/utils/number.test.js similarity index 100% rename from src/utils/number.test.js rename to packages/jaeger-ui/src/utils/number.test.js diff --git a/src/utils/prefix-url.js b/packages/jaeger-ui/src/utils/prefix-url.js similarity index 100% rename from src/utils/prefix-url.js rename to packages/jaeger-ui/src/utils/prefix-url.js diff --git a/src/utils/prefix-url.test.js b/packages/jaeger-ui/src/utils/prefix-url.test.js similarity index 100% rename from src/utils/prefix-url.test.js rename to packages/jaeger-ui/src/utils/prefix-url.test.js diff --git a/src/utils/redux-form-field-adapter.js b/packages/jaeger-ui/src/utils/redux-form-field-adapter.js similarity index 100% rename from src/utils/redux-form-field-adapter.js rename to packages/jaeger-ui/src/utils/redux-form-field-adapter.js diff --git a/src/utils/regexp-escape.js b/packages/jaeger-ui/src/utils/regexp-escape.js similarity index 100% rename from src/utils/regexp-escape.js rename to packages/jaeger-ui/src/utils/regexp-escape.js diff --git a/src/utils/regexp-escape.test.js b/packages/jaeger-ui/src/utils/regexp-escape.test.js similarity index 100% rename from src/utils/regexp-escape.test.js rename to packages/jaeger-ui/src/utils/regexp-escape.test.js diff --git a/src/utils/sort.js b/packages/jaeger-ui/src/utils/sort.js similarity index 100% rename from src/utils/sort.js rename to packages/jaeger-ui/src/utils/sort.js diff --git a/src/utils/sort.test.js b/packages/jaeger-ui/src/utils/sort.test.js similarity index 100% rename from src/utils/sort.test.js rename to packages/jaeger-ui/src/utils/sort.test.js diff --git a/src/utils/test/requestAnimationFrame.js b/packages/jaeger-ui/src/utils/test/requestAnimationFrame.js similarity index 100% rename from src/utils/test/requestAnimationFrame.js rename to packages/jaeger-ui/src/utils/test/requestAnimationFrame.js diff --git a/src/utils/tracking/README.md b/packages/jaeger-ui/src/utils/tracking/README.md similarity index 100% rename from src/utils/tracking/README.md rename to packages/jaeger-ui/src/utils/tracking/README.md diff --git a/src/utils/tracking/common.js b/packages/jaeger-ui/src/utils/tracking/common.js similarity index 100% rename from src/utils/tracking/common.js rename to packages/jaeger-ui/src/utils/tracking/common.js diff --git a/src/utils/tracking/conv-raven-to-ga.js b/packages/jaeger-ui/src/utils/tracking/conv-raven-to-ga.js similarity index 100% rename from src/utils/tracking/conv-raven-to-ga.js rename to packages/jaeger-ui/src/utils/tracking/conv-raven-to-ga.js diff --git a/src/utils/tracking/conv-raven-to-ga.test.js b/packages/jaeger-ui/src/utils/tracking/conv-raven-to-ga.test.js similarity index 100% rename from src/utils/tracking/conv-raven-to-ga.test.js rename to packages/jaeger-ui/src/utils/tracking/conv-raven-to-ga.test.js diff --git a/src/utils/tracking/fixtures.js b/packages/jaeger-ui/src/utils/tracking/fixtures.js similarity index 100% rename from src/utils/tracking/fixtures.js rename to packages/jaeger-ui/src/utils/tracking/fixtures.js diff --git a/src/utils/tracking/index.js b/packages/jaeger-ui/src/utils/tracking/index.js similarity index 100% rename from src/utils/tracking/index.js rename to packages/jaeger-ui/src/utils/tracking/index.js diff --git a/src/utils/tracking/index.test.js b/packages/jaeger-ui/src/utils/tracking/index.test.js similarity index 100% rename from src/utils/tracking/index.test.js rename to packages/jaeger-ui/src/utils/tracking/index.test.js diff --git a/packages/plexus/.gitignore b/packages/plexus/.gitignore new file mode 100644 index 0000000000..45a3870978 --- /dev/null +++ b/packages/plexus/.gitignore @@ -0,0 +1,4 @@ +demo/dist +es +lib +umd diff --git a/packages/plexus/README.md b/packages/plexus/README.md new file mode 100644 index 0000000000..16824a28ad --- /dev/null +++ b/packages/plexus/README.md @@ -0,0 +1,13 @@ +# plexus + +plexus is a React component for rendering directed graphs. + +## Why? + +To support directed graphs in Jaeger-UI, we surveyed the JavaScript libraries and utilities available for rendering directed graphs. The landscape is impressive, but we concluded the venerable [GraphViz](https://graphviz.gitlab.io/) ([alt](https://www.graphviz.org/)) is the right tool for us. + +GraphViz is awesome, but the output formats don't fit our needs. We've elected to use GraphViz to generate the layouts (node positioning, edge routing) and React for rendering. + +## viz.js + +The excellent [viz.js](https://github.com/mdaines/viz.js) is used, in a WebWorker, to generate GraphViz as plain-text output which is then parsed and provided to a React component which does the rendering. diff --git a/packages/plexus/demo/src/data-dag.js b/packages/plexus/demo/src/data-dag.js new file mode 100644 index 0000000000..4b9fb82ed5 --- /dev/null +++ b/packages/plexus/demo/src/data-dag.js @@ -0,0 +1,98 @@ +const paths = ` +packages +packages/jaeger-ui +packages/jaeger-ui/build +packages/jaeger-ui/build/static +packages/jaeger-ui/build/static/css +packages/jaeger-ui/build/static/js +packages/jaeger-ui/build/static/media +packages/jaeger-ui/node_modules +packages/jaeger-ui/node_modules/.bin +packages/jaeger-ui/node_modules/bluebird +packages/jaeger-ui/node_modules/bluebird/js +packages/jaeger-ui/node_modules/bluebird/js/browser +packages/jaeger-ui/node_modules/bluebird/js/release +packages/jaeger-ui/node_modules/moment +packages/jaeger-ui/node_modules/moment/locale +packages/jaeger-ui/node_modules/moment/min +packages/jaeger-ui/node_modules/moment/src +packages/jaeger-ui/node_modules/moment/src/lib +packages/jaeger-ui/node_modules/moment/src/lib/create +packages/jaeger-ui/node_modules/moment/src/lib/duration +packages/jaeger-ui/node_modules/moment/src/lib/format +packages/jaeger-ui/node_modules/moment/src/lib/locale +packages/jaeger-ui/node_modules/moment/src/lib/moment +packages/jaeger-ui/node_modules/moment/src/lib/parse +packages/jaeger-ui/node_modules/moment/src/lib/units +packages/jaeger-ui/node_modules/moment/src/lib/utils +packages/jaeger-ui/node_modules/moment/src/locale +packages/jaeger-ui/public +packages/jaeger-ui/src +packages/jaeger-ui/src/actions +packages/jaeger-ui/src/api +packages/jaeger-ui/src/components +packages/jaeger-ui/src/components/App +packages/jaeger-ui/src/components/DependencyGraph +packages/jaeger-ui/src/components/SearchTracePage +packages/jaeger-ui/src/components/SearchTracePage/SearchResults +packages/jaeger-ui/src/components/TracePage +packages/jaeger-ui/src/components/TracePage/ArchiveNotifier +packages/jaeger-ui/src/components/TracePage/SpanGraph +packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer +packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView +packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/ListView/__snapshots__ +packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail +packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/TimelineHeaderRow +packages/jaeger-ui/src/components/common +packages/jaeger-ui/src/constants +packages/jaeger-ui/src/demo +packages/jaeger-ui/src/img +packages/jaeger-ui/src/middlewares +packages/jaeger-ui/src/model +packages/jaeger-ui/src/propTypes +packages/jaeger-ui/src/reducers +packages/jaeger-ui/src/selectors +packages/jaeger-ui/src/types +packages/jaeger-ui/src/utils +packages/jaeger-ui/src/utils/DraggableManager +packages/jaeger-ui/src/utils/DraggableManager/demo +packages/jaeger-ui/src/utils/config +packages/jaeger-ui/src/utils/test +packages/jaeger-ui/src/utils/tracking +packages/plexus +packages/plexus/demo +packages/plexus/demo/dist +packages/plexus/demo/src +packages/plexus/lib +packages/plexus/lib/DirectedGraph +packages/plexus/lib/DirectedGraph/builtins +packages/plexus/lib/LayoutManager +packages/plexus/lib/LayoutManager/dot +packages/plexus/lib/types +packages/plexus/node_modules +packages/plexus/node_modules/.bin +packages/plexus/node_modules/.cache +packages/plexus/node_modules/.cache/babel-loader +packages/plexus/src +packages/plexus/src/DirectedGraph +packages/plexus/src/DirectedGraph/builtins +packages/plexus/src/LayoutManager +packages/plexus/src/LayoutManager/dot +packages/plexus/src/types +packages/plexus/umd +packages/plexus/umd/@jaegertracing +`; + +export const vertices = []; +export const edges = []; + +paths + .trim() + .split('\n') + .forEach(line => { + const folders = line.split('/'); + vertices.push({ key: line, label: folders.slice(-1)[0] }); + if (folders.length > 1) { + edges.push({ from: folders.slice(0, -1).join('/'), to: line }); + } + }); diff --git a/packages/plexus/demo/src/data-large.js b/packages/plexus/demo/src/data-large.js new file mode 100644 index 0000000000..8f9ce8cd0b --- /dev/null +++ b/packages/plexus/demo/src/data-large.js @@ -0,0 +1,498 @@ +import * as React from 'react'; + +export default { + edges: [ + { + from: 'fervent::ferve/fervent', + to: 'carson::carso/carson', + }, + { + from: 'fervent::ferve/fervent', + to: 'volhard::volha/volhard', + }, + { + from: 'fervent::ferve/fervent', + to: 'yalow::yalow/yalow', + }, + { + from: 'fervent::ferve/fervent', + to: 'mystifying::mysti/mystifying', + }, + { + from: 'fervent::ferve/fervent', + to: 'meninsky::menin/meninsky', + }, + { + from: 'fervent::ferve/fervent', + to: 'admiring::admir/admiring', + }, + { + from: 'fervent::ferve/fervent', + to: 'fervent::ferve/fervent', + }, + { + from: 'fervent::ferve/fervent', + to: 'hoover::hoove/hoover', + }, + { + from: 'fervent::ferve/fervent', + to: 'brahmagupta::brahm/brahmagupta', + }, + { + from: 'fervent::ferve/fervent', + to: 'banach::banac/banach', + }, + { + from: 'fervent::ferve/fervent', + to: 'chatterjee::chatt/chatterjee', + }, + { + from: 'fervent::ferve/fervent', + to: 'unruffled::unruf/unruffled', + }, + { + from: 'fervent::ferve/fervent', + to: 'shockley::shock/shockley', + }, + { + from: 'fervent::ferve/fervent', + to: 'pasteur::paste/pasteur', + }, + { + from: 'fervent::ferve/fervent', + to: 'upbeat::upbea/upbeat', + }, + { + from: 'fervent::ferve/fervent', + to: 'darwin::darwi/darwin', + }, + { + from: 'fervent::ferve/fervent', + to: 'priceless::price/priceless', + }, + { + from: 'fervent::ferve/fervent', + to: 'sammet::samme/sammet', + }, + { + from: 'fervent::ferve/fervent', + to: 'serene::seren/serene', + }, + { + from: 'fervent::ferve/fervent', + to: 'vigorous::vigor/vigorous', + }, + { + from: 'fervent::ferve/fervent', + to: 'gracious::graci/gracious', + }, + { + from: 'fervent::ferve/fervent', + to: 'hardcore::hardc/hardcore', + }, + { + from: 'fervent::ferve/fervent', + to: 'elastic::elast/elastic', + }, + { + from: 'fervent::ferve/fervent', + to: 'dazzling::dazzl/dazzling', + }, + { + from: 'fervent::ferve/fervent', + to: 'neumann::neuma/neumann', + }, + { + from: 'keller::kelle/keller', + to: 'fervent::ferve/fervent', + }, + { + from: 'keller::kelle/keller', + to: 'shockley::shock/shockley', + }, + { + from: 'carson::carso/carson', + to: 'heuristic::heuri/heuristic', + }, + { + from: 'murdock::murdo/murdock', + to: 'fervent::ferve/fervent', + }, + { + from: 'mystifying::mysti/mystifying', + to: 'eloquent::eloqu/eloquent', + }, + { + from: 'mystifying::mysti/mystifying', + to: 'peaceful::peace/peaceful', + }, + { + from: 'shockley::shock/shockley', + to: 'fervent::ferve/fervent', + }, + { + from: 'shockley::shock/shockley', + to: 'volhard::volha/volhard', + }, + { + from: 'shockley::shock/shockley', + to: 'brahmagupta::brahm/brahmagupta', + }, + { + from: 'shockley::shock/shockley', + to: 'mystifying::mysti/mystifying', + }, + { + from: 'shockley::shock/shockley', + to: 'darwin::darwi/darwin', + }, + { + from: 'shockley::shock/shockley', + to: 'upbeat::upbea/upbeat', + }, + { + from: 'brahmagupta::brahm/brahmagupta', + to: 'infallible::infal/infallible', + }, + { + from: 'brahmagupta::brahm/brahmagupta', + to: 'heuristic::heuri/heuristic', + }, + { + from: 'brahmagupta::brahm/brahmagupta', + to: 'easley::easle/easley', + }, + { + from: 'infallible::infal/infallible', + to: 'sharp::sharp/sharp', + }, + { + from: 'banach::banac/banach', + to: 'lalande::lalan/lalande', + }, + { + from: 'banach::banac/banach', + to: 'brave::brave/brave', + }, + { + from: 'banach::banac/banach', + to: 'wright::wrigh/wright', + }, + { + from: 'banach::banac/banach', + to: 'jones::jones/jones', + }, + { + from: 'banach::banac/banach', + to: 'bose::bose/bose', + }, + { + from: 'banach::banac/banach', + to: 'ecstatic::ecsta/ecstatic', + }, + { + from: 'banach::banac/banach', + to: 'volhard::volha/volhard', + }, + { + from: 'banach::banac/banach', + to: 'tereshkova::teres/tereshkova', + }, + { + from: 'banach::banac/banach', + to: 'lichterman::licht/lichterman', + }, + { + from: 'chatterjee::chatt/chatterjee', + to: 'heuristic::heuri/heuristic', + }, + { + from: 'sharp::sharp/sharp', + to: 'sharp::sharp/sharp', + }, + { + from: 'lalande::lalan/lalande', + to: 'visvesvaraya::visve/visvesvaraya', + }, + { + from: 'upbeat::upbea/upbeat', + to: 'tereshkova::teres/tereshkova', + }, + { + from: 'upbeat::upbea/upbeat', + to: 'volhard::volha/volhard', + }, + { + from: 'priceless::price/priceless', + to: 'priceless::price/priceless', + }, + { + from: 'sammet::samme/sammet', + to: 'mclean::mclea/mclean', + }, + { + from: 'mclean::mclea/mclean', + to: 'stupefied::stupe/stupefied', + }, + { + from: 'wright::wrigh/wright', + to: 'bhabha::bhabh/bhabha', + }, + { + from: 'jones::jones/jones', + to: 'youthful::youth/youthful', + }, + { + from: 'jones::jones/jones', + to: 'heuristic::heuri/heuristic', + }, + { + from: 'youthful::youth/youthful', + to: 'lumiere::lumie/lumiere', + }, + { + from: 'lumiere::lumie/lumiere', + to: 'lumiere::lumie/lumiere', + }, + { + from: 'ecstatic::ecsta/ecstatic', + to: 'golick::golic/golick', + }, + { + from: 'ecstatic::ecsta/ecstatic', + to: 'goldstine::golds/goldstine', + }, + { + from: 'ecstatic::ecsta/ecstatic', + to: 'volhard::volha/volhard', + }, + { + from: 'golick::golic/golick', + to: 'zhukovsky::zhuko/zhukovsky', + }, + { + from: 'zhukovsky::zhuko/zhukovsky', + to: 'zhukovsky::zhuko/zhukovsky', + }, + { + from: 'goldstine::golds/goldstine', + to: 'dubinsky::dubin/dubinsky', + }, + { + from: 'dubinsky::dubin/dubinsky', + to: 'dubinsky::dubin/dubinsky', + }, + { + from: 'vigorous::vigor/vigorous', + to: 'joliot::jolio/joliot', + }, + { + from: 'vigorous::vigor/vigorous', + to: 'vigorous::vigor/vigorous', + }, + { + from: 'vigorous::vigor/vigorous', + to: 'pensive::pensi/pensive', + }, + { + from: 'jolly::jolly/jolly', + to: 'fervent::ferve/fervent', + }, + { + from: 'euclid::eucli/euclid', + to: 'jolly::jolly/jolly', + }, + { + from: 'boring::borin/boring', + to: 'fervent::ferve/fervent', + }, + { + from: 'fermi::fermi/fermi', + to: 'fervent::ferve/fervent', + }, + ], + vertices: [ + { + key: 'fervent::ferve/fervent', + }, + { + key: 'carson::carso/carson', + }, + { + key: 'volhard::volha/volhard', + }, + { + key: 'yalow::yalow/yalow', + }, + { + key: 'mystifying::mysti/mystifying', + }, + { + key: 'meninsky::menin/meninsky', + }, + { + key: 'admiring::admir/admiring', + }, + { + key: 'hoover::hoove/hoover', + }, + { + key: 'brahmagupta::brahm/brahmagupta', + }, + { + key: 'banach::banac/banach', + }, + { + key: 'chatterjee::chatt/chatterjee', + }, + { + key: 'unruffled::unruf/unruffled', + }, + { + key: 'shockley::shock/shockley', + }, + { + key: 'pasteur::paste/pasteur', + }, + { + key: 'upbeat::upbea/upbeat', + }, + { + key: 'darwin::darwi/darwin', + }, + { + key: 'priceless::price/priceless', + }, + { + key: 'sammet::samme/sammet', + }, + { + key: 'serene::seren/serene', + }, + { + key: 'vigorous::vigor/vigorous', + }, + { + key: 'gracious::graci/gracious', + }, + { + key: 'hardcore::hardc/hardcore', + }, + { + key: 'elastic::elast/elastic', + }, + { + key: 'dazzling::dazzl/dazzling', + }, + { + key: 'neumann::neuma/neumann', + }, + { + key: 'keller::kelle/keller', + }, + { + key: 'heuristic::heuri/heuristic', + }, + { + key: 'murdock::murdo/murdock', + }, + { + key: 'eloquent::eloqu/eloquent', + }, + { + key: 'peaceful::peace/peaceful', + }, + { + key: 'infallible::infal/infallible', + }, + { + key: 'easley::easle/easley', + }, + { + key: 'sharp::sharp/sharp', + }, + { + key: 'lalande::lalan/lalande', + }, + { + key: 'brave::brave/brave', + }, + { + key: 'wright::wrigh/wright', + }, + { + key: 'jones::jones/jones', + }, + { + key: 'bose::bose/bose', + }, + { + key: 'ecstatic::ecsta/ecstatic', + }, + { + key: 'tereshkova::teres/tereshkova', + }, + { + key: 'lichterman::licht/lichterman', + }, + { + key: 'visvesvaraya::visve/visvesvaraya', + }, + { + key: 'mclean::mclea/mclean', + }, + { + key: 'stupefied::stupe/stupefied', + }, + { + key: 'bhabha::bhabh/bhabha', + }, + { + key: 'youthful::youth/youthful', + }, + { + key: 'lumiere::lumie/lumiere', + }, + { + key: 'golick::golic/golick', + }, + { + key: 'goldstine::golds/goldstine', + }, + { + key: 'zhukovsky::zhuko/zhukovsky', + }, + { + key: 'dubinsky::dubin/dubinsky', + }, + { + key: 'joliot::jolio/joliot', + }, + { + key: 'pensive::pensi/pensive', + }, + { + key: 'jolly::jolly/jolly', + }, + { + key: 'euclid::eucli/euclid', + }, + { + key: 'boring::borin/boring', + }, + { + key: 'fermi::fermi/fermi', + }, + ], +}; + +export function getNodeLabel(vertex) { + const [svc, op] = vertex.key.split('::', 2); + return ( + + {svc} +
+ {op} +
+ ); +} diff --git a/packages/plexus/demo/src/data-small.js b/packages/plexus/demo/src/data-small.js new file mode 100644 index 0000000000..ff6a3bf3bb --- /dev/null +++ b/packages/plexus/demo/src/data-small.js @@ -0,0 +1,84 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +export const varied = { + vertices: [ + { key: 'string key 0', data: { value: new Date(), message: 'vertex w a string key that has spaces' } }, + { + key: 1, + label: 'Key is the number 1Key is the number 1Key', + data: { err: new Error(9), message: 'vertex with a number key and a string label' }, + }, + { key: '2', label:

OMG an H3

, data: { message: 'label is an H3 React element' } }, + { + key: 33, + label: 'Key is the number 1Key is the number 1Key', + data: { value: /abc/, message: 'data contains a RegExp and the node lacks a label' }, + }, + ], + edges: [ + { from: 'string key 0', to: 1, label: 'The Great Edge Label', data: 'Edge with a string label' }, + { + from: 'string key 0', + to: '2', + label: Drop it like its hot, + data: 'edge with a React.Node label', + }, + { from: '1', to: '2', data: 'edge sans label' }, + { from: '2', to: 33, isBidirectional: true, data: 'A bidirection edge' }, + ], +}; + +export const colored = { + vertices: [ + { key: 'string key 0', data: 'red' }, + { + key: 1, + label: 'Key is the number 1', + data: 'blue', + }, + { key: '2', label:

OMG an H3

, data: 'green' }, + { key: 33, data: 'teal' }, + ], + edges: [ + { from: 'string key 0', to: 1, label: 'The Great Edge Label', data: '#c00' }, + { + from: 'string key 0', + to: '2', + label: Drop it like its hot, + data: '#0c0', + }, + { from: '1', to: '2', data: '#00c' }, + { from: '2', to: 33, isBidirectional: true, data: '#c0c' }, + ], +}; + +export function getColorNodeLabel(vertex) { + let { label } = vertex; + label = label == null ? String(vertex.key) : label; + if (typeof label !== 'string' && !React.isValidElement(label)) { + label = String(label); + } + return {label}; +} + +export function setOnColorNode(vertex) { + const style = { border: `1px solid ${vertex.data}` }; + return { style }; +} +export function setOnColorEdge(edge) { + return { stroke: edge.data }; +} diff --git a/packages/plexus/demo/src/index.css b/packages/plexus/demo/src/index.css new file mode 100644 index 0000000000..81b65e4853 --- /dev/null +++ b/packages/plexus/demo/src/index.css @@ -0,0 +1,75 @@ +html { + font-family: Arial, Helvetica, sans-serif; +} + +.DemoGraph { + border: 1px solid blue; + overflow: hidden; + height: 500px; + width: 800px; + position: relative; +} + +.DemoGraph--dag { + background: #999; + stroke-width: 1.7; +} + +.DemoGraph--dag.is-small { + stroke-width: 1; +} + +.DemoGraph--node { + background: #fff; + border: 1px solid #666; + box-shadow: 0 0 7px 1px rgba(0, 0, 0, 0.4); + padding: 0.8em 1.25em; +} + +.DemoGraph--dag.is-small .DemoGraph--nodeLabel { + opacity: 0; +} + +/* DAG minimap */ + +.Demo--miniMap { + align-items: flex-end; + bottom: 1rem; + display: flex; + left: 1rem; + position: absolute; + z-index: 1; +} + +.Demo--miniMap > .plexus-MiniMap--item { + border: 1px solid #333; + background: #555; + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + margin-right: 1rem; + position: relative; +} + +.Demo--miniMap > .plexus-MiniMap--map { + /* dynamic width, height */ + box-sizing: content-box; +} + +.Demo--miniMap .plexus-MiniMap--mapActive { + /* dynamic: width, height, transform */ + background: #bbb; + outline: 1px solid #333; + position: absolute; +} + +.Demo--miniMap > .plexus-MiniMap--button { + color: #bbb; + cursor: pointer; + font-size: 1.6em; + line-height: 0; + padding: 0.1rem; +} + +.Demo--miniMap > .plexus-MiniMap--button:hover { + background: #444; + color: #ddd; +} diff --git a/packages/plexus/demo/src/index.js b/packages/plexus/demo/src/index.js new file mode 100644 index 0000000000..1f2273da72 --- /dev/null +++ b/packages/plexus/demo/src/index.js @@ -0,0 +1,122 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { render } from 'react-dom'; + +import largeDg, { getNodeLabel as getLargeNodeLabel } from './data-large'; +import { edges as dagEdges, vertices as dagVertices } from './data-dag'; +import { colored as colorData, getColorNodeLabel, setOnColorEdge, setOnColorNode } from './data-small'; +import { DirectedGraph, LayoutManager } from '../../src'; + +import './index.css'; + +const { classNameIsSmall } = DirectedGraph.propsFactories; + +const addAnAttr = () => ({ 'data-rando': Math.random() }); +const setNodeClassName = () => ({ className: 'DemoGraph--node' }); + +class Demo extends React.Component { + constructor(props) { + super(props); + this.layoutManager = new LayoutManager(); + this.dagLayoutManager = new LayoutManager({ useDotEdges: true }); + this.largeDotLayoutManager = new LayoutManager({ useDotEdges: true }); + this.largeDotPolylineLayoutManager = new LayoutManager({ + useDotEdges: true, + splines: 'polyline', + ranksep: 8, + }); + this.largeNeatoLayoutManager = new LayoutManager(); + } + render() { + return ( +
+

Directed graph with cycles - dot edges

+
+
+ +
+
+

Directed graph with cycles - neato edges

+
+
+ +
+
+

Directed graph with cycles - dot edges - polylines

+
+
+ +
+
+

Small graph with data driven rendering

+ +

Medium DAG

+ +
+ ); + } +} + +render(, document.querySelector('#demo')); diff --git a/packages/plexus/nwb.config.js b/packages/plexus/nwb.config.js new file mode 100644 index 0000000000..8f5673e970 --- /dev/null +++ b/packages/plexus/nwb.config.js @@ -0,0 +1,67 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// make sure the worker files are run through the babel-loader before the worker-loader +function setBabelPre(config) { + const babel = config.module.rules.find(rule => /babel-loader/.test(rule.loader)); + babel.enforce = 'pre'; + return config; +} + +module.exports = function nwbConfig() { + return { + type: 'react-component', + npm: { + esModules: false, + cjs: true, + umd: { + global: 'JaegerPlexus', + externals: { + react: 'React', + 'react-dom': 'ReactDom', + }, + }, + }, + babel: { + config(cfg) { + // eslint-disable-next-line no-param-reassign + cfg.compact = true; + return cfg; + }, + }, + devServer: { hot: false }, + webpack: { + extractText: { + filename: process.env.NODE_ENV === 'production' ? `plexus.[contenthash:8].css` : 'plexus.css', + }, + extra: { + devtool: 'source-map', + module: { + rules: [ + { + test: /\.worker\.js$/, + use: [ + { + loader: require.resolve('worker-loader'), + options: { inline: true, fallback: false, name: '[name].[hash:8].js' }, + }, + ], + }, + ], + }, + }, + config: setBabelPre, + }, + }; +}; diff --git a/packages/plexus/package.json b/packages/plexus/package.json new file mode 100644 index 0000000000..f0dd9b78c3 --- /dev/null +++ b/packages/plexus/package.json @@ -0,0 +1,34 @@ +{ + "name": "@jaegertracing/plexus", + "version": "0.0.1-dev.2", + "description": "Direct Graph React component", + "main": "umd/@jaegertracing/plexus.js", + "files": ["lib", "umd"], + "scripts": { + "build": "nwb build-react-component", + "clean": "nwb clean-module && nwb clean-demo", + "start": "nwb serve-react-demo", + "test": "echo 'NO TESTS YET'", + "coverage": "echo 'NO TESTS YET'", + "test:dev": "nwb test-react --server" + }, + "dependencies": { + "d3-selection": "^1.3.0", + "d3-zoom": "^1.7.1", + "viz.js": "^1.8.1" + }, + "peerDependencies": { + "react": "16.x" + }, + "devDependencies": { + "nwb": "0.21.x", + "react": "^16.3.2", + "react-dom": "^16.3.2", + "worker-loader": "^1.1.1" + }, + "author": "", + "homepage": "https://github.com/jaegertracing/jaeger-ui", + "license": "Apache-2.0", + "repository": "https://github.com/jaegertracing/jaeger-ui.git", + "keywords": ["react-component"] +} diff --git a/packages/plexus/src/DirectedGraph/DirectedGraph.js b/packages/plexus/src/DirectedGraph/DirectedGraph.js new file mode 100644 index 0000000000..f1a0bf7629 --- /dev/null +++ b/packages/plexus/src/DirectedGraph/DirectedGraph.js @@ -0,0 +1,341 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; +import { select } from 'd3-selection'; +import { zoom as d3Zoom, zoomIdentity, zoomTransform as getTransform } from 'd3-zoom'; + +import EdgeArrowDef from './builtins/EdgeArrowDef'; +import EdgesContainer from './builtins/EdgesContainer'; +import PureEdges from './builtins/PureEdges'; +import PureNodes from './builtins/PureNodes'; +import MiniMap from './MiniMap'; +import classNameIsSmall from './prop-factories/classNameIsSmall'; +import mergePropSetters, { mergeClassNameAndStyle } from './prop-factories/mergePropSetters'; +import scaledStrokeWidth from './prop-factories/scaledStrokeWidth'; +import { + constrainZoom, + DEFAULT_SCALE_EXTENT, + fitWithinContainer, + getScaleExtent, + getZoomAttr, + getZoomStyle, +} from './transform-utils'; + +import type { D3Transform, DirectedGraphProps, DirectedGraphState } from './types'; +import type { Cancelled, LayoutDone, PositionsDone, Vertex } from '../types/layout'; + +const PHASE_NO_DATA = 0; +const PHASE_CALC_SIZES = 1; +const PHASE_CALC_POSITIONS = 2; +const PHASE_CALC_EDGES = 3; +const PHASE_DONE = 4; + +const WRAPPER_STYLE_ZOOM = { + height: '100%', + overflow: 'hidden', + position: 'relative', + width: '100%', +}; + +const WRAPPER_STYLE = { + position: 'relative', +}; + +let idCounter = 0; + +// eslint-disable-next-line no-unused-vars +function defaultGetNodeLabel(vertex: Vertex) { + const { label } = vertex; + if (label != null) { + if (typeof label === 'string' || React.isValidElement(label)) { + return label; + } + return String(label); + } + return String(vertex.key); +} + +export default class DirectedGraph extends React.PureComponent { + arrowId: string; + arrowIriRef: string; + // ref API defs in flow seem to be a WIP + // https://github.com/facebook/flow/issues/6103 + rootRef: { current: HTMLDivElement | null }; + rootSelection: any; + vertexRefs: { current: HTMLElement | null }[]; + zoom: any; + + static propsFactories = { + classNameIsSmall, + mergePropSetters, + scaledStrokeWidth, + }; + + static defaultProps = { + arrowScaleDampener: undefined, + className: '', + classNamePrefix: 'plexus', + // getEdgeLabel: defaultGetEdgeLabel, + getNodeLabel: defaultGetNodeLabel, + minimap: false, + minimapClassName: '', + zoom: false, + zoomTransform: zoomIdentity, + }; + + state = { + edges: [], + layoutPhase: PHASE_NO_DATA, + sizeVertices: null, + layoutEdges: null, + layoutGraph: null, + layoutVertices: null, + vertexRefs: [], + vertices: [], + zoomEnabled: false, + zoomTransform: zoomIdentity, + }; + + static getDerivedStateFromProps(nextProps: DirectedGraphProps, prevState: DirectedGraphState) { + const { edges, vertices, zoom: zoomEnabled } = nextProps; + const { edges: stEdges, vertices: stVertices, zoomEnabled: stZoomEnabled } = prevState; + if (zoomEnabled !== stZoomEnabled) { + throw new Error('Zoom cannot be toggled'); + } + if (edges === stEdges && vertices === stVertices) { + return null; + } + return { + edges, + vertices, + layoutPhase: PHASE_CALC_SIZES, + vertexRefs: vertices.map(React.createRef), + sizeVertices: null, + layoutEdges: null, + layoutGraph: null, + layoutVertices: null, + }; + } + + constructor(props: DirectedGraphProps) { + super(props); + const { edges, vertices, zoom: zoomEnabled } = props; + if (Array.isArray(edges) && edges.length && Array.isArray(vertices) && vertices.length) { + this.state.layoutPhase = PHASE_CALC_SIZES; + this.state.edges = edges; + this.state.vertices = vertices; + this.state.vertexRefs = vertices.map(React.createRef); + } + this.state.zoomEnabled = zoomEnabled; + const idBase = `plexus--DirectedGraph--${idCounter}`; + idCounter += 1; + this.arrowId = EdgeArrowDef.getId(idBase); + this.arrowIriRef = EdgeArrowDef.getIriRef(idBase); + this.rootRef = React.createRef(); + if (zoomEnabled) { + this.zoom = d3Zoom() + .scaleExtent(DEFAULT_SCALE_EXTENT) + .constrain(this._constrainZoom) + .on('zoom', this._onZoomed); + } + } + + componentDidMount() { + this._setSizeVertices(); + this.rootSelection = select(this.rootRef.current); + } + + componentDidUpdate() { + const { layoutPhase } = this.state; + if (layoutPhase === PHASE_CALC_SIZES) { + this._setSizeVertices(); + } + } + + _onPositionsDone = (result: Cancelled | PositionsDone) => { + if (!result.isCancelled) { + const { graph: layoutGraph, vertices: layoutVertices } = result; + this.setState({ layoutGraph, layoutVertices, layoutPhase: PHASE_CALC_EDGES }); + } + }; + + _onLayoutDone = (result: Cancelled | LayoutDone) => { + const root = this.rootRef.current; + if (result.isCancelled || !root) { + return; + } + const { zoomEnabled } = this.state; + const { edges: layoutEdges, graph: layoutGraph, vertices: layoutVertices } = result; + const { clientHeight: height, clientWidth: width } = root; + let zoomTransform = zoomIdentity; + if (zoomEnabled) { + const scaleExtent = getScaleExtent(layoutGraph.width, layoutGraph.height, width, height); + zoomTransform = fitWithinContainer(layoutGraph.width, layoutGraph.height, width, height); + this.zoom.scaleExtent(scaleExtent); + this.rootSelection.call(this.zoom); + // set the initial transform + this.zoom.transform(this.rootSelection, zoomTransform); + } + this.setState({ layoutEdges, layoutGraph, layoutVertices, zoomTransform, layoutPhase: PHASE_DONE }); + }; + + _onZoomed = () => { + const root = this.rootRef.current; + if (!root) { + return; + } + const zoomTransform = getTransform(root); + this.setState({ zoomTransform }); + }; + + _constrainZoom = (transform: D3Transform, extent: [[number, number], [number, number]]) => { + const [, [vw, vh]] = extent; + const { height: h, width: w } = this.state.layoutGraph || {}; + if (h == null || w == null) { + // for flow + return transform; + } + return constrainZoom(transform, w, h, vw, vh); + }; + + _resetZoom = () => { + const root = this.rootRef.current; + const layoutGraph = this.state.layoutGraph; + if (!root || !layoutGraph) { + return; + } + const { clientHeight: height, clientWidth: width } = root; + const zoomTransform = fitWithinContainer(layoutGraph.width, layoutGraph.height, width, height); + this.zoom.transform(this.rootSelection, zoomTransform); + this.setState({ zoomTransform }); + }; + + _setSizeVertices() { + const { edges, layoutManager, vertices } = this.props; + const sizeVertices = this.state.vertexRefs + .map((ref, i) => { + const { current } = ref; + return !current + ? null + : { + height: current.offsetHeight, + vertex: vertices[i], + width: current.offsetWidth, + }; + }) + .filter(Boolean); + const { positions, layout } = layoutManager.getLayout(edges, sizeVertices); + positions.then(this._onPositionsDone); + layout.then(this._onLayoutDone); + this.setState({ sizeVertices, layoutPhase: PHASE_CALC_POSITIONS }); + } + + _renderVertices() { + const { classNamePrefix, getNodeLabel, setOnNode, vertices } = this.props; + const { layoutVertices, vertexRefs } = this.state; + return ( + + ); + } + + _renderEdges() { + const { setOnEdgePath } = this.props; + const { layoutEdges } = this.state; + return ( + layoutEdges && ( + + ) + ); + } + + render() { + const { + arrowScaleDampener, + className, + classNamePrefix, + minimap: minimapEnabled, + minimapClassName, + setOnEdgesContainer, + setOnNodesContainer, + setOnRoot, + } = this.props; + const { layoutPhase: phase, layoutGraph, zoomEnabled, zoomTransform } = this.state; + const { height, width } = layoutGraph || {}; + const { current: rootElm } = this.rootRef; + const haveEdges = phase === PHASE_DONE; + + const nodesContainerProps = mergeClassNameAndStyle( + (setOnNodesContainer && setOnNodesContainer(this.state)) || {}, + { + style: { + ...(zoomEnabled ? getZoomStyle(zoomTransform) : null), + position: 'absolute', + top: 0, + left: 0, + }, + className: `${classNamePrefix}-DirectedGraph--nodeContainer`, + } + ); + const rootProps = mergeClassNameAndStyle((setOnRoot && setOnRoot(this.state)) || {}, { + style: zoomEnabled ? WRAPPER_STYLE_ZOOM : WRAPPER_STYLE, + className: `${classNamePrefix}-DirectedGraph ${className}`, + }); + + return ( +
+ {layoutGraph && + haveEdges && ( + + + {this._renderEdges()} + + )} +
{this._renderVertices()}
+ {zoomEnabled && + minimapEnabled && + layoutGraph && + rootElm && ( + + )} +
+ ); + } +} diff --git a/packages/plexus/src/DirectedGraph/MiniMap.js b/packages/plexus/src/DirectedGraph/MiniMap.js new file mode 100644 index 0000000000..79ac63b765 --- /dev/null +++ b/packages/plexus/src/DirectedGraph/MiniMap.js @@ -0,0 +1,99 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +import resetZoomIcon from './resetZoomIcon'; + +/* eslint-disable react/no-unused-prop-types */ +type Props = { + classNamePrefix?: ?string, + className?: ?string, + contentHeight: number, + contentWidth: number, + viewAll: () => void, + viewportHeight: number, + viewportWidth: number, + k: number, + x: number, + y: number, +}; +/* eslint-enable react/no-unused-prop-types */ + +const LENGTH_TARGET_PX = 80; + +function getMapSize(props: Props) { + const { contentHeight: ch, contentWidth: cw } = props; + if (ch > cw) { + return { height: LENGTH_TARGET_PX, width: LENGTH_TARGET_PX * cw / ch }; + } + return { height: LENGTH_TARGET_PX * ch / cw, width: LENGTH_TARGET_PX }; +} + +function getViewTransform(props: Props, displaySize: { width: number, height: number }) { + const { contentHeight: ch, contentWidth: cw, viewportHeight: vh, viewportWidth: vw, k, x, y } = props; + const { height: dh, width: dw } = displaySize; + const sch = ch * k; + const scw = cw * k; + const left = Math.max(-x / scw, 0); + const right = Math.min((-x + vw) / scw, 1); + const top = Math.max(-y / sch, 0); + const bottom = Math.min((-y + vh) / sch, 1); + return { + transform: ` + translate(${(left * dw).toFixed(2)}px, ${(top * dh).toFixed(2)}px) + scale(${right - left}, ${bottom - top}) + `, + transformOrigin: '0 0', + }; +} + +function getClassNames(props: Props) { + const { className, classNamePrefix } = props; + const base = `${classNamePrefix || 'plexus'}-MiniMap`; + return { + root: `${base} ${className || ''}`, + item: `${base}--item`, + map: `${base}--map`, + mapActive: `${base}--mapActive`, + button: `${base}--button`, + }; +} + +export default class MiniMap extends React.PureComponent { + props: Props; + + static defaultProps = { + className: '', + classNamePrefix: 'plexus', + }; + + render() { + const css = getClassNames(this.props); + const mapSize = getMapSize(this.props); + const activeXform = getViewTransform(this.props, mapSize); + return ( +
+
+
+
+
+ {resetZoomIcon} +
+
+ ); + } +} diff --git a/packages/plexus/src/DirectedGraph/builtins/EdgeArrow.js b/packages/plexus/src/DirectedGraph/builtins/EdgeArrow.js new file mode 100644 index 0000000000..ebaaeaf0e5 --- /dev/null +++ b/packages/plexus/src/DirectedGraph/builtins/EdgeArrow.js @@ -0,0 +1,28 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +const id = 'edgeArrow'; +export const iriRef = `url(#${id})`; + +export const arrowDef = ( + + + +); + +export const defs = {arrowDef}; diff --git a/packages/plexus/src/DirectedGraph/builtins/EdgeArrowDef.js b/packages/plexus/src/DirectedGraph/builtins/EdgeArrowDef.js new file mode 100644 index 0000000000..fd1c2dee48 --- /dev/null +++ b/packages/plexus/src/DirectedGraph/builtins/EdgeArrowDef.js @@ -0,0 +1,60 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +type Props = { + id: string, + scaleDampener: number, + zoomScale?: ?number, +}; + +export default class EdgeArrowDef extends React.PureComponent { + props: Props; + + static defaultProps = { + zoomScale: null, + scaleDampener: 0.6, + }; + + static getId(idBase: string) { + return `${idBase}--edgeArrow`; + } + + static getIriRef(idBase: string) { + return `url(#${EdgeArrowDef.getId(idBase)})`; + } + + render() { + const { id, scaleDampener, zoomScale } = this.props; + const scale = zoomScale != null ? Math.max(scaleDampener / zoomScale, 1) : 1; + return ( + + + + + + ); + } +} diff --git a/packages/plexus/src/DirectedGraph/builtins/EdgePath.js b/packages/plexus/src/DirectedGraph/builtins/EdgePath.js new file mode 100644 index 0000000000..16804098ee --- /dev/null +++ b/packages/plexus/src/DirectedGraph/builtins/EdgePath.js @@ -0,0 +1,72 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +type Props = + | Object + | { + markerEnd: string, + pathPoints: [number, number][], + }; + +const D_CMDS = ['M', 'C']; + +// const strokeDefId = 'pathStroke'; +// const strokeReference = `url(#${strokeDefId})`; + +// export function EdgePathStrokeDef(props) { +// const strokeDef = ( +// +// +// +// +// +// +// ); +// return props.enclose ? {strokeDef} : strokeDef; +// } + +// NOTE: This function is necessary for gradient stroke +// function renderPathPoint(pt, i) { +// let [x, y] = pt; +// if (i === 0) { +// // add a small amount of jitter (1% of a pixel) to avert an issue with +// // bounding-box based linear gradients +// // https://stackoverflow.com/q/13223636/1888292 +// y += 0.01; +// } +// return `${D_CMDS[i] || ''}${x},${y}`; +// } + +export default class EdgePath extends React.PureComponent { + props: Props; + + render() { + const { markerEnd, pathPoints, ...rest } = this.props; + const d = pathPoints.map((pt, i) => `${D_CMDS[i] || ''}${pt.join(',')}`).join(' '); + return ( + + ); + } +} diff --git a/packages/plexus/src/DirectedGraph/builtins/EdgesContainer.js b/packages/plexus/src/DirectedGraph/builtins/EdgesContainer.js new file mode 100644 index 0000000000..9726014b8f --- /dev/null +++ b/packages/plexus/src/DirectedGraph/builtins/EdgesContainer.js @@ -0,0 +1,32 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +type Props = { + children: React.Node, + height: number, + width: number, +}; + +export default function EdgesContainer(props: Props) { + const { children, height, width, ...rest } = props; + return ( + + {children} + + ); +} diff --git a/packages/plexus/src/DirectedGraph/builtins/Node.js b/packages/plexus/src/DirectedGraph/builtins/Node.js new file mode 100644 index 0000000000..f4215fa855 --- /dev/null +++ b/packages/plexus/src/DirectedGraph/builtins/Node.js @@ -0,0 +1,60 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +type Props = + | Object + | { + classNamePrefix: string, + forwardedRef: any, + hidden?: boolean, + labelFactory: Function, + left?: number, + top?: number, + vertex: any, + }; + +class Node extends React.PureComponent { + props: Props; + + static defaultProps = { + hidden: false, + left: null, + top: null, + }; + + render() { + const { classNamePrefix, hidden, labelFactory, vertex, left, top, forwardedRef, ...rest } = this.props; + const p: Object = rest; + p.style = { + ...p.style, + position: 'absolute', + transform: left == null || top == null ? undefined : `translate(${left}px,${top}px)`, + visibility: hidden ? 'hidden' : undefined, + }; + p.className = `${classNamePrefix}-Node ${p.className || ''}`; + return ( +
+ {labelFactory(vertex)} +
+ ); + } +} + +// ghetto fabulous cast because the 16.3 API is not in flow yet +// https://github.com/facebook/flow/issues/6103 +export default (React: any).forwardRef((props, ref) => ); diff --git a/packages/plexus/src/DirectedGraph/builtins/PureEdges.js b/packages/plexus/src/DirectedGraph/builtins/PureEdges.js new file mode 100644 index 0000000000..546f84b738 --- /dev/null +++ b/packages/plexus/src/DirectedGraph/builtins/PureEdges.js @@ -0,0 +1,43 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +import EdgePath from './EdgePath'; + +import type { Edge, LayoutEdge } from '../../types/layout'; + +type Props = { + arrowIriRef: string, + layoutEdges: LayoutEdge[], + setOnEdgePath: ?(Edge) => ?Object, +}; + +export default class PureEdges extends React.PureComponent { + props: Props; + + render() { + const { arrowIriRef, layoutEdges, setOnEdgePath } = this.props; + return layoutEdges.map(edge => ( + + )); + } +} diff --git a/packages/plexus/src/DirectedGraph/builtins/PureNodes.js b/packages/plexus/src/DirectedGraph/builtins/PureNodes.js new file mode 100644 index 0000000000..719f68bcb2 --- /dev/null +++ b/packages/plexus/src/DirectedGraph/builtins/PureNodes.js @@ -0,0 +1,75 @@ +// @flow + +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as React from 'react'; + +import Node from './Node'; + +import type { LayoutVertex, Vertex } from '../../types/layout'; + +type Props = { + classNamePrefix: string, + getNodeLabel: ?(Vertex) => string | React.Node, + layoutVertices: ?(LayoutVertex[]), + setOnNode: ?(Vertex) => ?Object, + vertexRefs: { current: HTMLElement | null }[], + vertices: Vertex[], +}; + +export default class PureEdges extends React.PureComponent { + props: Props; + + _renderVertices() { + const { classNamePrefix, getNodeLabel, setOnNode, vertices, vertexRefs } = this.props; + return vertices.map((v, i) => ( +
- - {numberOfSpans} Span{numberOfSpans > 1 && 's'} - - {Boolean(numberOfErredSpans) && ( - - {numberOfErredSpans} Error{numberOfErredSpans > 1 && 's'} - - )} - - -
    - {sortBy(services, s => s.name).map(service => { - const { name, numberOfSpans: count } = service; - return ( -
  • - - {name} ({count}) - -
  • - ); - })} -
- - - {formatRelativeDate(timestamp)} - - {timeStr.slice(0, -3)} {timeStr.slice(-2)} -
- {fromNow} - - - - ); - } -} diff --git a/src/components/SearchTracePage/SearchResults/react-vis.css b/src/components/SearchTracePage/SearchResults/react-vis.css deleted file mode 120000 index 8fc839f747..0000000000 --- a/src/components/SearchTracePage/SearchResults/react-vis.css +++ /dev/null @@ -1 +0,0 @@ -../../../../node_modules/react-vis/dist/style.css \ No newline at end of file diff --git a/src/components/TracePage/TraceTimelineViewer/index.js b/src/components/TracePage/TraceTimelineViewer/index.js deleted file mode 100644 index c3bc9a0469..0000000000 --- a/src/components/TracePage/TraceTimelineViewer/index.js +++ /dev/null @@ -1,80 +0,0 @@ -// @flow - -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import React from 'react'; -import { connect } from 'react-redux'; - -import { actions } from './duck'; -import TimelineHeaderRow from './TimelineHeaderRow'; -import VirtualizedTraceView from './VirtualizedTraceView'; -import type { Accessors } from '../ScrollManager'; -import type { ViewRange, ViewRangeTimeUpdate } from '../types'; -import type { Trace } from '../../../types'; - -import './index.css'; - -type TraceTimelineViewerProps = { - registerAccessors: Accessors => void, - setSpanNameColumnWidth: number => void, - spanNameColumnWidth: number, - textFilter: ?string, - trace: Trace, - updateNextViewRangeTime: ViewRangeTimeUpdate => void, - updateViewRangeTime: (number, number, ?string) => void, - viewRange: ViewRange, -}; - -const NUM_TICKS = 5; - -/** - * `TraceTimelineViewer` now renders the header row because it is sensitive to - * `props.viewRange.time.cursor`. If `VirtualizedTraceView` renders it, it will - * re-render the ListView every time the cursor is moved on the trace minimap - * or `TimelineHeaderRow`. - */ -function TraceTimelineViewer(props: TraceTimelineViewerProps) { - const { setSpanNameColumnWidth, updateNextViewRangeTime, updateViewRangeTime, viewRange, ...rest } = props; - const { spanNameColumnWidth, trace } = rest; - return ( -
- - -
- ); -} - -function mapStateToProps(state, ownProps) { - const spanNameColumnWidth = state.traceTimeline.spanNameColumnWidth; - return { spanNameColumnWidth, ...ownProps }; -} - -function mapDispatchToProps(dispatch) { - const setSpanNameColumnWidth = (...args) => { - const action = actions.setSpanNameColumnWidth(...args); - return dispatch(action); - }; - return { setSpanNameColumnWidth }; -} - -export default connect(mapStateToProps, mapDispatchToProps)(TraceTimelineViewer); diff --git a/src/model/search.js b/src/model/search.js deleted file mode 100644 index 62dd3ac961..0000000000 --- a/src/model/search.js +++ /dev/null @@ -1,115 +0,0 @@ -// @flow - -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import _map from 'lodash/map'; -import _values from 'lodash/values'; - -import { LEAST_SPANS, LONGEST_FIRST, MOST_RECENT, MOST_SPANS, SHORTEST_FIRST } from './order-by'; -import type { Trace } from '../types'; -import type { TraceSummaries, TraceSummary } from '../types/search'; - -const isErrorTag = ({ key, value }) => key === 'error' && (value === true || value === 'true'); - -/** - * Transforms a trace from the HTTP response to the data structure needed by the search page. Note: exported - * for unit tests. - * - * @param trace Trace data in the format sent over the wire. - * @return {TraceSummary} Summary of the trace data for use in the search results. - */ -export function getTraceSummary(trace: Trace): TraceSummary { - const { processes, spans, traceID } = trace; - - let traceName = ''; - let minTs = Number.MAX_SAFE_INTEGER; - let maxTs = Number.MIN_SAFE_INTEGER; - let numErrorSpans = 0; - // serviceName -> { name, numberOfSpans } - const serviceMap = {}; - for (let i = 0; i < spans.length; i++) { - const { duration, processID, references, startTime, tags } = spans[i]; - // time bounds of trace - minTs = minTs > startTime ? startTime : minTs; - maxTs = maxTs < startTime + duration ? startTime + duration : maxTs; - // number of error tags - if (tags.some(isErrorTag)) { - numErrorSpans += 1; - } - // number of span per service - const { serviceName } = processes[processID]; - let svcData = serviceMap[serviceName]; - if (svcData) { - svcData.numberOfSpans += 1; - } else { - svcData = { - name: serviceName, - numberOfSpans: 1, - }; - serviceMap[serviceName] = svcData; - } - if (!references || !references.length) { - const { operationName } = spans[i]; - traceName = `${svcData.name}: ${operationName}`; - } - } - return { - traceName, - traceID, - duration: (maxTs - minTs) / 1000, - numberOfErredSpans: numErrorSpans, - numberOfSpans: spans.length, - services: _values(serviceMap), - timestamp: minTs / 1000, - }; -} - -/** - * Transforms `Trace` values into `TraceSummary` values and finds the max duration of the traces. - * - * @param {(Trace | Error)[]} _traces The trace data in the format from the HTTP request. - * @return {TraceSummaries} The `{ traces, maxDuration }` value. - */ -export function getTraceSummaries(_traces: (Trace | Error)[]): TraceSummaries { - const traces = _traces - .map(item => { - if (item instanceof Error) { - return null; - } - return getTraceSummary(item); - }) - .filter(Boolean); - const maxDuration = Math.max(..._map(traces, 'duration')); - return { maxDuration, traces }; -} - -const comparators = { - [MOST_RECENT]: (a, b) => +(b.timestamp > a.timestamp) || +(a.timestamp === b.timestamp) - 1, - [SHORTEST_FIRST]: (a, b) => +(a.duration > b.duration) || +(a.duration === b.duration) - 1, - [LONGEST_FIRST]: (a, b) => +(b.duration > a.duration) || +(a.duration === b.duration) - 1, - [MOST_SPANS]: (a, b) => +(b.numberOfSpans > a.numberOfSpans) || +(a.numberOfSpans === b.numberOfSpans) - 1, - [LEAST_SPANS]: (a, b) => +(a.numberOfSpans > b.numberOfSpans) || +(a.numberOfSpans === b.numberOfSpans) - 1, -}; - -/** - * Sorts `TraceSummary[]`, in place. - * - * @param {TraceSummary[]} traces The `TraceSummary` array to sort. - * @param {string} sortBy A sort specification, see ./order-by.js. - */ -export function sortTraces(traces: TraceSummary[], sortBy: string) { - const comparator = comparators[sortBy] || comparators[LONGEST_FIRST]; - traces.sort(comparator); -} diff --git a/src/model/search.test.js b/src/model/search.test.js deleted file mode 100644 index 866ca82a75..0000000000 --- a/src/model/search.test.js +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import _maxBy from 'lodash/maxBy'; -import _minBy from 'lodash/minBy'; - -import * as orderBy from './order-by'; -import { getTraceSummaries, getTraceSummary, sortTraces } from './search'; -import traceGenerator from '../demo/trace-generators'; -import transformTraceData from '../model/transform-trace-data'; - -describe('getTraceSummary()', () => { - let trace; - let summary; - - beforeEach(() => { - trace = transformTraceData(traceGenerator.trace({ numberOfSpans: 2 })); - summary = getTraceSummary(trace); - }); - - it('derives duration, timestamp and numberOfSpans', () => { - expect(summary.numberOfSpans).toBe(trace.spans.length); - expect(summary.duration).toBe(trace.duration / 1000); - expect(summary.timestamp).toBe(Math.floor(trace.startTime / 1000)); - }); - - it('handles error spans', () => { - const errorTag = { key: 'error', value: true }; - expect(summary.numberOfErredSpans).toBe(0); - trace.spans[0].tags.push(errorTag); - expect(getTraceSummary(trace).numberOfErredSpans).toBe(1); - trace.spans[1].tags.push(errorTag); - expect(getTraceSummary(trace).numberOfErredSpans).toBe(2); - }); - - it('generates the traceName', () => { - trace = { - traceID: 'main-id', - spans: [ - { - traceID: 'main-id', - processID: 'pid0', - spanID: 'span-id-0', - operationName: 'op0', - startTime: 1502221240933000, - duration: 236857, - tags: [], - }, - { - traceID: 'main-id', - processID: 'pid1', - spanID: 'span-child', - operationName: 'op1', - startTime: 1502221241144382, - duration: 25305, - tags: [], - references: [{ refType: 'CHILD_OF', traceID: 'main-id', spanID: 'span-id-0' }], - }, - ], - duration: 236857, - timestamp: 1502221240933000, - processes: { - pid0: { - processID: 'pid0', - serviceName: 'serviceA', - tags: [], - }, - pid1: { - processID: 'pid1', - serviceName: 'serviceB', - tags: [], - }, - }, - }; - const { traceName } = getTraceSummary(trace); - expect(traceName).toBe('serviceA: op0'); - }); - - xit('derives services summations', () => {}); -}); - -describe('getTraceSummaries()', () => { - it('finds the max duration', () => { - const traces = [ - transformTraceData(traceGenerator.trace({})), - transformTraceData(traceGenerator.trace({})), - ]; - const maxDuration = _maxBy(traces, 'duration').duration / 1000; - expect(getTraceSummaries(traces).maxDuration).toBe(maxDuration); - }); -}); - -describe('sortTraces()', () => { - const idMinSpans = 4; - const idMaxSpans = 2; - const rawTraces = [ - { ...transformTraceData(traceGenerator.trace({ numberOfSpans: 3 })), traceID: 1 }, - { ...transformTraceData(traceGenerator.trace({ numberOfSpans: 100 })), traceID: idMaxSpans }, - { ...transformTraceData(traceGenerator.trace({ numberOfSpans: 5 })), traceID: 3 }, - { ...transformTraceData(traceGenerator.trace({ numberOfSpans: 1 })), traceID: idMinSpans }, - ]; - const { traces } = getTraceSummaries(rawTraces); - - const { MOST_SPANS, LEAST_SPANS, LONGEST_FIRST, SHORTEST_FIRST, MOST_RECENT } = orderBy; - - const expecations = { - [MOST_RECENT]: _maxBy(traces, trace => trace.timestamp).traceID, - [LONGEST_FIRST]: _maxBy(traces, trace => trace.duration).traceID, - [SHORTEST_FIRST]: _minBy(traces, trace => trace.duration).traceID, - [MOST_SPANS]: idMaxSpans, - [LEAST_SPANS]: idMinSpans, - }; - expecations.invalidOrderBy = expecations[LONGEST_FIRST]; - - Object.keys(expecations).forEach(sortBy => { - it(`sorts by ${sortBy}`, () => { - const traceID = expecations[sortBy]; - sortTraces(traces, sortBy); - expect(traces[0].traceID).toBe(traceID); - }); - }); -}); diff --git a/src/reducers/trace.js b/src/reducers/trace.js deleted file mode 100644 index a918797c28..0000000000 --- a/src/reducers/trace.js +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import keyBy from 'lodash/keyBy'; -import { handleActions } from 'redux-actions'; - -import { fetchTrace, searchTraces } from '../actions/jaeger-api'; -import transformTraceData from '../model/transform-trace-data'; - -const initialState = { - traces: {}, - loading: false, - error: null, -}; - -function fetchStarted(state) { - return { ...state, loading: true }; -} - -function fetchTraceDone(state, { meta, payload }) { - const trace = transformTraceData(payload.data[0]); - let traces; - if (!trace) { - traces = { ...state.traces, [meta.id]: new Error('Invalid trace data recieved.') }; - } else { - traces = { ...state.traces, [trace.traceID]: trace }; - } - return { ...state, traces, loading: false }; -} - -function fetchTraceErred(state, { meta, payload }) { - const traces = { ...state.traces, [meta.id]: payload }; - return { ...state, traces, loading: false }; -} - -function searchDone(state, { payload }) { - const processed = payload.data.map(transformTraceData); - const traces = keyBy(processed, 'traceID'); - return { ...state, traces, error: null, loading: false }; -} - -function searchErred(state, action) { - const error = action.payload; - return { ...state, error, loading: false, traces: [] }; -} - -export default handleActions( - { - [`${fetchTrace}_PENDING`]: fetchStarted, - [`${fetchTrace}_FULFILLED`]: fetchTraceDone, - [`${fetchTrace}_REJECTED`]: fetchTraceErred, - - [`${searchTraces}_PENDING`]: fetchStarted, - [`${searchTraces}_FULFILLED`]: searchDone, - [`${searchTraces}_REJECTED`]: searchErred, - }, - initialState -); diff --git a/yarn.lock b/yarn.lock index c61d77539c..7a352df0a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,12 @@ # yarn lockfile v1 +"@babel/code-frame@^7.0.0-beta.35": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" + dependencies: + "@babel/highlight" "7.0.0-beta.44" + "@babel/code-frame@^7.0.0-beta.38": version "7.0.0-beta.39" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.39.tgz#91c90bb65207fc5a55128cb54956ded39e850457" @@ -17,6 +23,14 @@ "@babel/types" "7.0.0-beta.35" lodash "^4.2.0" +"@babel/highlight@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + "@babel/types@7.0.0-beta.35": version "7.0.0-beta.35" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.35.tgz#cf933a9a9a38484ca724b335b88d83726d5ab960" @@ -29,7 +43,14 @@ version "8.5.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.1.tgz#4ec3020bcdfe2abffeef9ba3fbf26fca097514b5" -abab@^1.0.3: +JSONStream@^1.0.3, JSONStream@^1.0.4: + version "1.3.2" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abab@^1.0.3, abab@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" @@ -37,6 +58,10 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + accepts@~1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" @@ -44,6 +69,13 @@ accepts@~1.3.4: mime-types "~2.1.16" negotiator "0.6.1" +accepts@~1.3.5: + 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-dynamic-import@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" @@ -56,12 +88,25 @@ acorn-globals@^3.1.0: dependencies: acorn "^4.0.4" +acorn-globals@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + dependencies: + acorn "^5.0.0" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" dependencies: acorn "^3.0.4" +acorn-node@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.3.0.tgz#5f86d73346743810ef1269b901dbcbded020861b" + dependencies: + acorn "^5.4.1" + xtend "^4.0.1" + acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" @@ -74,20 +119,47 @@ acorn@^5.0.0, acorn@^5.2.1: version "5.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822" +acorn@^5.3.0, acorn@^5.4.1: + version "5.5.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + add-dom-event-listener@1.x: version "1.0.2" resolved "https://registry.yarnpkg.com/add-dom-event-listener/-/add-dom-event-listener-1.0.2.tgz#8faed2c41008721cf111da1d30d995b85be42bed" dependencies: object-assign "4.x" +add-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" + address@1.0.3, address@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" +addressparser@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/addressparser/-/addressparser-1.0.1.tgz#47afbe1a2a9262191db6838e4fd1d39b40821746" + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + +agent-base@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" + dependencies: + extend "~3.0.0" + semver "~5.0.1" + ajv-keywords@^2.0.0, ajv-keywords@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" +ajv-keywords@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be" + ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -104,6 +176,15 @@ ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.0, ajv@^5.2.3: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +ajv@^6.1.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.4.0.tgz#d3aff78e9277549771daf0164cff48482b754fc6" + dependencies: + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + uri-js "^3.0.2" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -120,6 +201,16 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" +amqplib@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/amqplib/-/amqplib-0.5.2.tgz#d2d7313c7ffaa4d10bcf1e6252de4591b6cc7b63" + dependencies: + bitsyntax "~0.0.4" + bluebird "^3.4.6" + buffer-more-ints "0.0.2" + readable-stream "1.x >=1.1.9" + safe-buffer "^5.0.1" + ansi-align@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-1.1.0.tgz#2f0c1658829739add5ebb15e6b0c6e3423f016ba" @@ -156,6 +247,12 @@ ansi-styles@^3.0.0, ansi-styles@^3.1.0, ansi-styles@^3.2.0: dependencies: color-convert "^1.9.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" + antd@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/antd/-/antd-3.0.3.tgz#ba9519fb8f6fa45b54b248b6139381ff83d5f382" @@ -203,6 +300,10 @@ antd@^3.0.3: shallowequal "^1.0.1" warning "~3.0.0" +any-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242" + anymatch@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" @@ -217,7 +318,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -app-root-path@^2.0.0: +app-root-path@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.0.1.tgz#cd62dcf8e4fd5a417efc664d2e5b10653c651b46" @@ -227,7 +328,7 @@ append-transform@^0.4.0: dependencies: default-require-extensions "^1.0.0" -aproba@^1.0.3: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -239,8 +340,8 @@ are-we-there-yet@~1.1.2: readable-stream "^2.0.6" argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" dependencies: sprintf-js "~1.0.2" @@ -292,6 +393,10 @@ array-flatten@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296" +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + array-includes@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" @@ -307,6 +412,10 @@ 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@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + array-tree-filter@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/array-tree-filter/-/array-tree-filter-1.0.1.tgz#0a8ad1eefd38ce88858632f9cc0423d7634e4d5d" @@ -333,6 +442,10 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" +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" @@ -361,7 +474,7 @@ 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.1.1: +assert@^1.1.1, assert@^1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" dependencies: @@ -375,21 +488,35 @@ 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" +ast-types@0.x.x: + version "0.11.3" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.3.tgz#c20757fe72ee71278ea0ff3d87e5c2ca30d9edf8" + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" +astw@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/astw/-/astw-2.2.0.tgz#7bd41784d32493987aeb239b6b4e1c57a873b917" + dependencies: + acorn "^4.0.3" + async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + async-validator@1.x: version "1.8.2" resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-1.8.2.tgz#b77597226e96242f8d531c0d46ae295f62422ba4" dependencies: babel-runtime "6.x" -async@^1.4.0, async@^1.5.2: +async@1.x, async@^1.4.0, async@^1.5.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -399,6 +526,16 @@ async@^2.1.2, async@^2.1.4, async@^2.4.1: dependencies: lodash "^4.14.0" +async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + +async@~2.1.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" + dependencies: + lodash "^4.14.0" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -418,6 +555,17 @@ autoprefixer@7.1.6: postcss "^6.0.13" postcss-value-parser "^3.2.3" +autoprefixer@7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.5.tgz#04ccbd0c6a61131b6d13f53d371926092952d192" + dependencies: + browserslist "^2.11.1" + caniuse-lite "^1.0.30000791" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^6.0.16" + postcss-value-parser "^3.2.3" + autoprefixer@^6.3.1: version "6.7.7" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" @@ -441,12 +589,39 @@ aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" +axios@^0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.15.3.tgz#2c9d638b2e191a08ea1d6cc988eadd6ba5bdc053" + dependencies: + follow-redirects "1.0.0" + axobject-query@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-0.1.0.tgz#62f59dbc59c9f9242759ca349960e7a2fe3c36c0" dependencies: ast-types-flow "0.0.7" +babel-cli@6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" + dependencies: + babel-core "^6.26.0" + babel-polyfill "^6.26.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + commander "^2.11.0" + convert-source-map "^1.5.0" + fs-readdir-recursive "^1.0.0" + glob "^7.1.2" + lodash "^4.17.4" + output-file-sync "^1.1.2" + path-is-absolute "^1.0.1" + slash "^1.0.0" + source-map "^0.5.6" + v8flags "^2.1.1" + optionalDependencies: + chokidar "^1.6.1" + babel-code-frame@6.26.0, babel-code-frame@^6.11.0, babel-code-frame@^6.22.0, 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" @@ -501,6 +676,14 @@ babel-generator@^6.18.0, babel-generator@^6.26.0: source-map "^0.5.6" trim-right "^1.0.1" +babel-helper-bindify-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" @@ -543,6 +726,15 @@ babel-helper-explode-assignable-expression@^6.24.1: babel-traverse "^6.24.1" babel-types "^6.24.1" +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" @@ -639,6 +831,10 @@ babel-messages@^6.23.0: dependencies: babel-runtime "^6.22.0" +babel-plugin-add-module-exports@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz#9ae9a1f4a8dc67f0cdec4f4aeda1e43a5ff65e25" + babel-plugin-check-es2015-constants@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" @@ -659,7 +855,14 @@ babel-plugin-import@^1.6.3: dependencies: "@babel/helper-module-imports" "^7.0.0-beta.34" -babel-plugin-istanbul@^4.0.0: +babel-plugin-inferno@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-inferno/-/babel-plugin-inferno-3.3.1.tgz#7ca11124b8bfef4658ef6041b835cb1fbccb00bc" + dependencies: + babel-plugin-syntax-jsx "^6.18.0" + inferno-vnode-flags "3.10.1" + +babel-plugin-istanbul@4.1.5, babel-plugin-istanbul@^4.0.0: version "4.1.5" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz#6760cdd977f411d3e175bb064f2bc327d99b2b6e" dependencies: @@ -675,14 +878,43 @@ babel-plugin-jest-hoist@^21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz#2cef637259bd4b628a6cace039de5fcd14dbb006" +babel-plugin-lodash@3.2.11: + version "3.2.11" + resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.2.11.tgz#21c8fdec9fe1835efaa737873e3902bdd66d5701" + dependencies: + glob "^7.1.1" + lodash "^4.17.2" + +babel-plugin-react-transform@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-react-transform/-/babel-plugin-react-transform-3.0.0.tgz#402f25137b7bb66e9b54ead75557dfbc7ecaaa74" + dependencies: + lodash "^4.6.1" + babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-constructor-call@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" + babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" +babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-do-expressions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" + babel-plugin-syntax-dynamic-import@6.18.0, babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" @@ -691,11 +923,19 @@ babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" +babel-plugin-syntax-export-extensions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" + babel-plugin-syntax-flow@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" -babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: +babel-plugin-syntax-function-bind@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz#48c495f177bdf31a981e732f55adc0bdd2601f46" + +babel-plugin-syntax-jsx@6.18.0, babel-plugin-syntax-jsx@^6.18.0, babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" @@ -707,6 +947,14 @@ babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" +babel-plugin-transform-async-generator-functions@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" @@ -715,7 +963,15 @@ babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async- babel-plugin-syntax-async-functions "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-class-properties@6.24.1: +babel-plugin-transform-class-constructor-call@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" + dependencies: + babel-plugin-syntax-class-constructor-call "^6.18.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-class-properties@6.24.1, babel-plugin-transform-class-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" dependencies: @@ -724,6 +980,31 @@ babel-plugin-transform-class-properties@6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" +babel-plugin-transform-decorators-legacy@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz#741b58f6c5bce9e6027e0882d9c994f04f366925" + dependencies: + babel-plugin-syntax-decorators "^6.1.18" + babel-runtime "^6.2.0" + babel-template "^6.3.0" + +babel-plugin-transform-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + dependencies: + babel-helper-explode-class "^6.24.1" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-do-expressions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz#28ccaf92812d949c2cd1281f690c8fdc468ae9bb" + dependencies: + babel-plugin-syntax-do-expressions "^6.8.0" + babel-runtime "^6.22.0" + babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" @@ -892,7 +1173,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0: babel-runtime "^6.22.0" regexpu-core "^2.0.0" -babel-plugin-transform-exponentiation-operator@^6.22.0: +babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" dependencies: @@ -900,6 +1181,13 @@ babel-plugin-transform-exponentiation-operator@^6.22.0: babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" +babel-plugin-transform-export-extensions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653" + dependencies: + babel-plugin-syntax-export-extensions "^6.8.0" + babel-runtime "^6.22.0" + babel-plugin-transform-flow-strip-types@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" @@ -907,7 +1195,14 @@ babel-plugin-transform-flow-strip-types@^6.22.0: babel-plugin-syntax-flow "^6.18.0" babel-runtime "^6.22.0" -babel-plugin-transform-object-rest-spread@6.26.0: +babel-plugin-transform-function-bind@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz#c6fb8e96ac296a310b8cf8ea401462407ddf6a97" + dependencies: + babel-plugin-syntax-function-bind "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@6.26.0, babel-plugin-transform-object-rest-spread@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" dependencies: @@ -948,6 +1243,10 @@ babel-plugin-transform-react-jsx@6.24.1, babel-plugin-transform-react-jsx@^6.24. babel-plugin-syntax-jsx "^6.8.0" babel-runtime "^6.22.0" +babel-plugin-transform-react-remove-prop-types@0.4.10: + version "0.4.10" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.10.tgz#3c7f3a03ad8aa6bb8c00e93fd13a433910444545" + babel-plugin-transform-regenerator@6.26.0, babel-plugin-transform-regenerator@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" @@ -967,6 +1266,14 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" +babel-polyfill@6.26.0, 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-env@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" @@ -1057,6 +1364,41 @@ babel-preset-react@6.24.1: babel-plugin-transform-react-jsx-source "^6.22.0" babel-preset-flow "^6.23.0" +babel-preset-stage-0@6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz#5642d15042f91384d7e5af8bc88b1db95b039e6a" + dependencies: + babel-plugin-transform-do-expressions "^6.22.0" + babel-plugin-transform-function-bind "^6.22.0" + babel-preset-stage-1 "^6.24.1" + +babel-preset-stage-1@6.24.1, babel-preset-stage-1@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0" + dependencies: + babel-plugin-transform-class-constructor-call "^6.24.1" + babel-plugin-transform-export-extensions "^6.22.0" + babel-preset-stage-2 "^6.24.1" + +babel-preset-stage-2@6.24.1, babel-preset-stage-2@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.24.1" + babel-plugin-transform-decorators "^6.24.1" + babel-preset-stage-3 "^6.24.1" + +babel-preset-stage-3@6.24.1, babel-preset-stage-3@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-generator-functions "^6.24.1" + babel-plugin-transform-async-to-generator "^6.24.1" + babel-plugin-transform-exponentiation-operator "^6.24.1" + babel-plugin-transform-object-rest-spread "^6.22.0" + babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" @@ -1069,14 +1411,14 @@ babel-register@^6.26.0: mkdirp "^0.5.1" source-map-support "^0.4.15" -babel-runtime@6.26.0, babel-runtime@6.x, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: +babel-runtime@6.26.0, babel-runtime@6.x, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.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: +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.3.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" dependencies: @@ -1113,6 +1455,10 @@ babylon@^6.17.0, 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@^0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" @@ -1121,10 +1467,18 @@ 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.2.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" +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" @@ -1151,6 +1505,12 @@ beeper@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" +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.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" @@ -1159,17 +1519,33 @@ binary-extensions@^1.0.0: version "1.11.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" +bitsyntax@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/bitsyntax/-/bitsyntax-0.0.4.tgz#eb10cc6f82b8c490e3e85698f07e83d46e0cba82" + dependencies: + buffer-more-ints "0.0.2" + +bl@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" + dependencies: + readable-stream "~2.0.5" + blessed@^0.1.81: version "0.1.81" resolved "https://registry.yarnpkg.com/blessed/-/blessed-0.1.81.tgz#f962d687ec2c369570ae71af843256e6d0ca1129" +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.4.7: +bluebird@^3.3.0, bluebird@^3.4.6, bluebird@^3.4.7, bluebird@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1181,7 +1557,7 @@ 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" -body-parser@1.18.2: +body-parser@1.18.2, body-parser@^1.16.1: version "1.18.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" dependencies: @@ -1243,13 +1619,26 @@ boxen@^0.6.0: string-width "^1.0.1" widest-line "^1.0.0" -brace-expansion@^1.0.0, brace-expansion@^1.1.7: +brace-expansion@^1.0.0: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" dependencies: balanced-match "^1.0.0" concat-map "0.0.1" +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@^0.1.2: + version "0.1.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-0.1.5.tgz#c085711085291d8b75fdd74eab0f8597280711e6" + dependencies: + expand-range "^0.1.0" + braces@^1.8.2: version "1.8.5" resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" @@ -1274,16 +1663,50 @@ braces@^2.3.0: split-string "^3.0.2" to-regex "^3.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" + brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" -browser-resolve@^1.11.2: +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.2" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + +browser-resolve@^1.11.0, browser-resolve@^1.11.2, browser-resolve@^1.7.0: version "1.11.2" resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" dependencies: resolve "1.1.7" +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.1.1" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f" @@ -1330,12 +1753,64 @@ browserify-sign@^4.0.0: inherits "^2.0.1" parse-asn1 "^5.0.0" -browserify-zlib@^0.2.0: +browserify-zlib@^0.2.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@^14.5.0: + version "14.5.0" + resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5" + 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.5.1" + 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.1.0" + duplexer2 "~0.1.2" + events "~1.1.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" + module-deps "^4.0.8" + 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.0.0" + subarg "^1.0.0" + syntax-error "^1.1.1" + through2 "^2.0.0" + timers-browserify "^1.0.1" + tty-browserify "~0.0.0" + url "~0.11.0" + util "~0.10.1" + vm-browserify "~0.0.1" + xtend "^4.0.0" + browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: version "1.7.7" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" @@ -1343,7 +1818,7 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" -browserslist@^2.1.2, browserslist@^2.5.1: +browserslist@^2.1.2, browserslist@^2.11.1, browserslist@^2.5.1: version "2.11.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" dependencies: @@ -1362,10 +1837,18 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" +buffer-from@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" + buffer-indexof@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" +buffer-more-ints@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz#26b3885d10fa13db7fc01aae3aab870199e0124c" + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -1378,6 +1861,25 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.1.0.tgz#c913e43678c7cb7c8bd16afbcddb6c5505e8f9fe" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +buildmail@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/buildmail/-/buildmail-4.0.1.tgz#877f7738b78729871c9a105e3b837d2be11a7a72" + dependencies: + addressparser "1.0.1" + libbase64 "0.1.0" + libmime "3.0.0" + libqp "1.1.0" + nodemailer-fetch "1.6.0" + nodemailer-shared "1.1.0" + punycode "1.4.1" + builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1386,10 +1888,32 @@ 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" +byline@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" +cacache@^10.0.1: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + 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" @@ -1404,12 +1928,20 @@ cache-base@^1.0.1: 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" @@ -1477,6 +2009,10 @@ caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000792: version "1.0.30000792" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000792.tgz#d0cea981f8118f3961471afbb43c9a1e5bbf0332" +caniuse-lite@^1.0.30000791: + version "1.0.30000830" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000830.tgz#cb96b8a2dd3cbfe04acea2af3c4e894249095328" + capture-stack-trace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" @@ -1485,6 +2021,10 @@ case-sensitive-paths-webpack-plugin@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.1.1.tgz#3d29ced8c1f124bf6f53846fb3f5894731fdc909" +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" @@ -1506,7 +2046,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0: +chalk@2.3.0, chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" dependencies: @@ -1522,6 +2062,14 @@ chalk@^2.0.1: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +chalk@^2.3.1, chalk@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.0.tgz#a060a297a6b57e15b61ca63ce84995daa0fe6e52" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chance@^1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/chance/-/chance-1.0.10.tgz#03500b04ad94e778dd2891b09ec73a6ad87b1996" @@ -1545,7 +2093,7 @@ cheerio@^1.0.0-rc.2: lodash "^4.15.0" parse5 "^3.0.1" -chokidar@^1.6.0, chokidar@^1.7.0: +chokidar@^1.4.1, chokidar@^1.6.0, chokidar@^1.6.1, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: @@ -1577,6 +2125,10 @@ chokidar@^2.0.0: optionalDependencies: fsevents "^1.0.0" +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + ci-info@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4" @@ -1592,6 +2144,10 @@ circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" +circular-json@^0.5.1: + version "0.5.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.3.tgz#eb1b783333bb125784647d1a76377caf1499efb1" + clap@^1.0.9: version "1.2.3" resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" @@ -1641,6 +2197,10 @@ cli-spinners@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" +cli-spinners@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" + cli-truncate@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" @@ -1676,10 +2236,21 @@ clone@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" +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" +co@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/co/-/co-3.0.6.tgz#1445f226c5eb956138e68c9ac30167ea7d2e6bda" + coa@~1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" @@ -1733,10 +2304,36 @@ colors@0.5.x: version "0.5.1" resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774" +colors@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794" + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" +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" + +combine-lists@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/combine-lists/-/combine-lists-1.0.1.tgz#458c07e09e0d900fc28b70a3fec2dacd1d2cb7f6" + dependencies: + lodash "^4.5.0" + +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.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" @@ -1747,13 +2344,21 @@ combokeys@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/combokeys/-/combokeys-3.0.0.tgz#955c59a3959af40d26846ab6fc3c682448e7572e" +command-join@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/command-join/-/command-join-2.0.0.tgz#52e8b984f4872d952ff1bdc8b98397d27c7144cf" + +commander@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + commander@2.12.x: version "2.12.2" resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" -commander@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" +commander@^2.11.0, commander@^2.14.1, commander@^2.9.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" commander@~2.13.0: version "2.13.0" @@ -1763,13 +2368,24 @@ commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" +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-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + component-classes@1.x, component-classes@^1.2.5, component-classes@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/component-classes/-/component-classes-1.2.6.tgz#c642394c3618a4d8b0b8919efccbbd930e5cd691" dependencies: component-indexof "0.0.3" -component-emitter@^1.2.1: +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" @@ -1777,6 +2393,10 @@ component-indexof@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/component-indexof/-/component-indexof-0.0.3.tgz#11d091312239eb8f32c8f25ae9cb002ffe8d3c24" +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + compressible@~2.0.11: version "2.0.12" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66" @@ -1799,7 +2419,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.6.0: +concat-stream@1.6.0, concat-stream@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1807,6 +2427,23 @@ concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +concat-stream@^1.4.10, concat-stream@^1.5.0, concat-stream@^1.6.1: + 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" + +concat-stream@~1.5.0, concat-stream@~1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" + dependencies: + inherits "~2.0.1" + readable-stream "~2.0.0" + typedarray "~0.0.5" + configstore@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" @@ -1825,6 +2462,15 @@ connect-history-api-fallback@^1.3.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.0: + 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" @@ -1835,7 +2481,7 @@ 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: +constants-browserify@^1.0.0, constants-browserify@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -1855,10 +2501,164 @@ content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" +conventional-changelog-angular@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz#b27f2b315c16d0a1f23eb181309d0e6a4698ea0f" + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-atom@^0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-0.2.8.tgz#8037693455990e3256f297320a45fa47ee553a14" + dependencies: + q "^1.5.1" + +conventional-changelog-cli@^1.3.13: + version "1.3.22" + resolved "https://registry.yarnpkg.com/conventional-changelog-cli/-/conventional-changelog-cli-1.3.22.tgz#13570fe1728f56f013ff7a88878ff49d5162a405" + dependencies: + add-stream "^1.0.0" + conventional-changelog "^1.1.24" + lodash "^4.2.1" + meow "^4.0.0" + tempfile "^1.1.1" + +conventional-changelog-codemirror@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.3.8.tgz#a1982c8291f4ee4d6f2f62817c6b2ecd2c4b7b47" + dependencies: + q "^1.5.1" + +conventional-changelog-core@^2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-2.0.11.tgz#19b5fbd55a9697773ed6661f4e32030ed7e30287" + dependencies: + conventional-changelog-writer "^3.0.9" + conventional-commits-parser "^2.1.7" + dateformat "^3.0.0" + get-pkg-repo "^1.0.0" + git-raw-commits "^1.3.6" + git-remote-origin-url "^2.0.0" + git-semver-tags "^1.3.6" + 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-ember@^0.3.12: + version "0.3.12" + resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-0.3.12.tgz#b7d31851756d0fcb49b031dffeb6afa93b202400" + dependencies: + q "^1.5.1" + +conventional-changelog-eslint@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.9.tgz#b13cc7e4b472c819450ede031ff1a75c0e3d07d3" + dependencies: + q "^1.5.1" + +conventional-changelog-express@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-0.3.6.tgz#4a6295cb11785059fb09202180d0e59c358b9c2c" + dependencies: + q "^1.5.1" + +conventional-changelog-jquery@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz#0208397162e3846986e71273b6c79c5b5f80f510" + dependencies: + q "^1.4.1" + +conventional-changelog-jscs@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz#0479eb443cc7d72c58bf0bcf0ef1d444a92f0e5c" + dependencies: + q "^1.4.1" + +conventional-changelog-jshint@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-0.3.8.tgz#9051c1ac0767abaf62a31f74d2fe8790e8acc6c8" + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-preset-loader@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-1.1.8.tgz#40bb0f142cd27d16839ec6c74ee8db418099b373" + +conventional-changelog-writer@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-3.0.9.tgz#4aecdfef33ff2a53bb0cf3b8071ce21f0e994634" + dependencies: + compare-func "^1.3.1" + conventional-commits-filter "^1.1.6" + 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-changelog@^1.1.24: + version "1.1.24" + resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-1.1.24.tgz#3d94c29c960f5261c002678315b756cdd3d7d1f0" + dependencies: + conventional-changelog-angular "^1.6.6" + conventional-changelog-atom "^0.2.8" + conventional-changelog-codemirror "^0.3.8" + conventional-changelog-core "^2.0.11" + conventional-changelog-ember "^0.3.12" + conventional-changelog-eslint "^1.0.9" + conventional-changelog-express "^0.3.6" + conventional-changelog-jquery "^0.1.0" + conventional-changelog-jscs "^0.1.0" + conventional-changelog-jshint "^0.3.8" + conventional-changelog-preset-loader "^1.1.8" + +conventional-commits-filter@^1.1.1, conventional-commits-filter@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-1.1.6.tgz#4389cd8e58fe89750c0b5fb58f1d7f0cc8ad3831" + dependencies: + is-subset "^0.1.1" + modify-values "^1.0.0" + +conventional-commits-parser@^2.1.1, conventional-commits-parser@^2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz#eca45ed6140d72ba9722ee4132674d639e644e8e" + 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@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-1.2.1.tgz#1b7137efb5091f99fe009e2fe9ddb7cc490e9375" + dependencies: + concat-stream "^1.4.10" + conventional-commits-filter "^1.1.1" + conventional-commits-parser "^2.1.1" + git-raw-commits "^1.3.0" + git-semver-tags "^1.3.0" + meow "^3.3.0" + object-assign "^4.0.1" + convert-source-map@^1.4.0, convert-source-map@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" +convert-source-map@~1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -1867,14 +2667,58 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +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" +copy-template-dir@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/copy-template-dir/-/copy-template-dir-1.3.0.tgz#b580010c78ade116a5b8ed29a8848faf7c165074" + dependencies: + end-of-stream "^1.1.0" + graceful-fs "^4.1.3" + maxstache "^1.0.0" + maxstache-stream "^1.0.0" + mkdirp "^0.5.1" + noop2 "^2.0.0" + pump "^1.0.0" + readdirp "^2.0.0" + run-parallel "^1.1.4" + +copy-webpack-plugin@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.3.1.tgz#19ba6370bf6f8e263cbd66185a2b79f2321a9302" + dependencies: + cacache "^10.0.1" + find-cache-dir "^1.0.0" + globby "^7.1.1" + is-glob "^4.0.0" + loader-utils "^0.2.15" + lodash "^4.3.0" + minimatch "^3.0.4" + p-limit "^1.0.0" + pify "^3.0.0" + serialize-javascript "^1.4.0" + core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" +core-js@^2.2.0: + version "2.5.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.5.tgz#b14dde936c640c0579a6b50cabcc132dd6127e3b" + core-js@^2.4.0, core-js@^2.5.0: version "2.5.3" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" @@ -1883,19 +2727,6 @@ 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@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-1.1.0.tgz#0dea0f9804efdfb929fbb1b188e25553ea053d37" - dependencies: - graceful-fs "^4.1.2" - js-yaml "^3.4.3" - minimist "^1.2.0" - object-assign "^4.0.1" - os-homedir "^1.0.1" - parse-json "^2.2.0" - pinkie-promise "^2.0.0" - require-from-string "^1.1.0" - cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: version "2.2.2" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892" @@ -1908,6 +2739,15 @@ cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: parse-json "^2.2.0" require-from-string "^1.1.0" +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + create-ecdh@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" @@ -1915,7 +2755,7 @@ create-ecdh@^4.0.0: bn.js "^4.1.0" elliptic "^6.0.0" -create-error-class@^3.0.1: +create-error-class@^3.0.0, create-error-class@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" dependencies: @@ -1965,6 +2805,16 @@ cross-spawn@5.1.0, cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.4.tgz#bbf44ccb30fb8314a08f178b62290c669c36d808" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -1977,7 +2827,7 @@ cryptiles@3.x.x: dependencies: boom "5.x.x" -crypto-browserify@^3.11.0: +crypto-browserify@^3.0.0, crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" dependencies: @@ -2023,6 +2873,25 @@ css-loader@0.28.7: postcss-value-parser "^3.3.0" source-list-map "^2.0.0" +css-loader@0.28.9: + version "0.28.9" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.9.tgz#68064b85f4e271d7ce4c48a58300928e535d1c95" + dependencies: + babel-code-frame "^6.26.0" + css-selector-tokenizer "^0.7.0" + cssnano "^3.10.0" + icss-utils "^2.1.0" + loader-utils "^1.0.2" + lodash.camelcase "^4.3.0" + object-assign "^4.1.1" + postcss "^5.0.6" + postcss-modules-extract-imports "^1.2.0" + postcss-modules-local-by-default "^1.2.0" + postcss-modules-scope "^1.1.0" + postcss-modules-values "^1.3.0" + postcss-value-parser "^3.3.0" + source-list-map "^2.0.0" + css-select@^1.1.0, css-select@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" @@ -2048,7 +2917,7 @@ cssesc@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" -"cssnano@>=2.6.1 <4": +"cssnano@>=2.6.1 <4", cssnano@^3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" dependencies: @@ -2108,6 +2977,14 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + cytoscape-dagre@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/cytoscape-dagre/-/cytoscape-dagre-2.0.0.tgz#5f5801bca8b8faa3affc978be26ced08189db4f5" @@ -2155,6 +3032,17 @@ d3-dispatch@1: version "1.0.3" resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.3.tgz#46e1491eaa9b58c358fce5be4e8bed626e7871f8" +d3-drag@1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.2.1.tgz#df8dd4c502fb490fc7462046a8ad98a5c479282d" + dependencies: + d3-dispatch "1" + d3-selection "1" + +d3-ease@1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e" + d3-force@^1.0.2: version "1.0.6" resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.0.6.tgz#ea7e1b7730e2664cd314f594d6718c57cc132b79" @@ -2218,6 +3106,10 @@ d3-scale@^1.0.5, d3-scale@^1.0.6: d3-time "1" d3-time-format "2" +d3-selection@1, d3-selection@^1.1.0, d3-selection@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d" + d3-shape@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777" @@ -2238,10 +3130,31 @@ d3-timer@1: version "1.0.6" resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.6.tgz#4044bf15d7025c06ce7d1149f73cd07b54dbd784" +d3-transition@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.1.1.tgz#d8ef89c3b848735b060e54a39b32aaebaa421039" + dependencies: + d3-color "1" + d3-dispatch "1" + d3-ease "1" + d3-interpolate "1" + d3-selection "^1.1.0" + d3-timer "1" + d3-voronoi@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c" +d3-zoom@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.7.1.tgz#02f43b3c3e2db54f364582d7e4a236ccc5506b63" + dependencies: + d3-dispatch "1" + d3-drag "1" + d3-interpolate "1" + d3-selection "1" + d3-transition "1" + d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" @@ -2259,32 +3172,71 @@ damerau-levenshtein@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" +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" +data-uri-to-buffer@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" + +data-urls@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.0.tgz#24802de4e81c298ea8a9388bb0d8e461c774684f" + dependencies: + abab "^1.0.4" + whatwg-mimetype "^2.0.0" + whatwg-url "^6.4.0" + date-fns@^1.27.2: - version "1.28.5" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.28.5.tgz#257cfc45d322df45ef5658665967ee841cd73faf" + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + +date-format@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-1.2.0.tgz#615e828e233dd1ab9bb9ae0950e0ceccfa6ecad8" date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: +dateformat@^1.0.6: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +dateformat@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + +debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9, debug@~2.6.4, debug@~2.6.6: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: ms "2.0.0" -debug@^3.0.1, debug@^3.1.0: +debug@3.1.0, debug@^3.0.1, 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@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + decamelize-keys@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -2300,6 +3252,10 @@ 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" + deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -2322,7 +3278,13 @@ default-require-extensions@^1.0.0: dependencies: strip-bom "^2.0.0" -define-properties@^1.1.2: +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-properties@^1.1.2, define-properties@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" dependencies: @@ -2341,10 +3303,25 @@ define-property@^1.0.0: 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" +degenerator@~1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" + dependencies: + ast-types "0.x.x" + escodegen "1.x.x" + esprima "3.x.x" + del@^2.0.2, del@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -2380,10 +3357,19 @@ depd@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" -depd@~1.1.1: +depd@~1.1.1, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" +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" @@ -2401,6 +3387,10 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -2416,14 +3406,36 @@ detect-port-alt@1.1.5: address "^1.0.1" debug "^2.6.0" -diff@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9" +detect-port@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.2.2.tgz#57a44533632d8bc74ad255676866ca43f96c7469" + dependencies: + address "^1.0.1" + debug "^2.6.0" + +detective@^4.0.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" + dependencies: + acorn "^5.2.1" + defined "^1.0.0" + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + +diff@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" -diff@^3.2.0: +diff@3.4.0, diff@^3.2.0: version "3.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" +diff@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9" + diffie-hellman@^5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" @@ -2432,6 +3444,13 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +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" + discontinuous-range@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" @@ -2494,6 +3513,15 @@ dom-scroll-into-view@1.x, dom-scroll-into-view@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz#e8f36732dd089b0201a88d7815dc3f88e6d66c7e" +dom-serialize@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -2511,7 +3539,7 @@ dom-walk@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" -domain-browser@^1.1.1: +domain-browser@^1.1.1, domain-browser@~1.1.0: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" @@ -2523,6 +3551,12 @@ domelementtype@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" +domexception@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + domhandler@2.1: version "2.1.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.1.0.tgz#d2646f5e57f6c3bab11cf6cb05d3c0acf7412594" @@ -2569,6 +3603,10 @@ dotenv@4.0.0, dotenv@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d" +double-ended-queue@^2.1.0-0: + version "2.1.0-0" + resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + draft-js@^0.10.0, draft-js@~0.10.0: version "0.10.4" resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.4.tgz#147741642097c8120d8edc232e9503e8b7fb8d35" @@ -2577,16 +3615,29 @@ draft-js@^0.10.0, draft-js@~0.10.0: immutable "~3.7.4" object-assign "^4.1.0" -duplexer2@^0.1.4: +duplexer2@^0.1.2, duplexer2@^0.1.4, duplexer2@~0.1.0, duplexer2@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" dependencies: readable-stream "^2.0.2" -duplexer@^0.1.1: +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +duplexer@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" +duplexify@^3.4.2, duplexify@^3.5.3: + version "3.5.4" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4" + 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.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -2633,12 +3684,61 @@ encodeurl@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + 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" + +engine.io-client@~3.1.0: + version "3.1.6" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.6.tgz#5bdeb130f8b94a50ac5cbeb72583e7a4a063ddfd" + 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.1.0: + version "3.1.5" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.1.5.tgz#0e7ef9d690eb0b35597f1d4ad02a26ca2dba3845" + 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" + optionalDependencies: + uws "~9.14.0" + enhanced-resolve@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" @@ -2652,6 +3752,10 @@ enquire.js@^2.1.1, enquire.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/enquire.js/-/enquire.js-2.1.6.tgz#3e8780c9b8b835084c3f60e166dbc3c2a3c89814" +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" @@ -2703,12 +3807,24 @@ errno@^0.1.1, errno@^0.1.3, errno@^0.1.4: dependencies: prr "~1.0.1" +errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + dependencies: + prr "~1.0.1" + error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" dependencies: is-arrayish "^0.2.1" +error-stack-parser@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-1.3.6.tgz#e0e73b93e417138d1cd7c0b746b1a4a14854c292" + dependencies: + stackframe "^0.3.1" + es-abstract@^1.5.1, es-abstract@^1.7.0: version "1.10.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" @@ -2767,6 +3883,10 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" +es6-promise@^4.0.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" + es6-promise@^4.0.5: version "4.2.2" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.2.tgz#f722d7769af88bd33bc13ec6605e1f92966b82d9" @@ -2805,6 +3925,28 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +escodegen@1.x.x, escodegen@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + escodegen@^1.6.1: version "1.9.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852" @@ -3060,11 +4202,11 @@ espree@^3.5.0, espree@^3.5.1: acorn "^5.2.1" acorn-jsx "^3.0.0" -esprima@^2.6.0: +esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" -esprima@^3.1.3: +esprima@3.x.x, esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -3085,6 +4227,10 @@ esrecurse@^4.1.0: estraverse "^4.1.0" object-assign "^4.0.1" +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + 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" @@ -3108,14 +4254,22 @@ eventemitter3@1.x.x, eventemitter3@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" +eventemitter3@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.0.1.tgz#4ce66c3fc5b5a6b9f2245e359e1938f1ab10f960" + eventlistener@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/eventlistener/-/eventlistener-0.0.1.tgz#ed2baabb852227af2bcf889152c72c63ca532eb8" -events@^1.0.0: +events@^1.0.0, events@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" +eventsource-polyfill@0.9.6: + version "0.9.6" + resolved "https://registry.yarnpkg.com/eventsource-polyfill/-/eventsource-polyfill-0.9.6.tgz#10e0d187f111b167f28fdab918843ce7d818f13c" + eventsource@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" @@ -3159,6 +4313,18 @@ execa@^0.8.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" + 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" + exenv@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" @@ -3167,6 +4333,14 @@ exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" +expand-braces@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" + dependencies: + array-slice "^0.2.3" + array-unique "^0.2.1" + braces "^0.1.2" + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -3185,6 +4359,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-range@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044" + dependencies: + is-number "^0.1.1" + repeat-string "^0.2.2" + expand-range@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" @@ -3197,6 +4378,18 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" +expect@1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-1.20.2.tgz#d458fe4c56004036bae3232416a3f6361f04f965" + dependencies: + define-properties "~1.1.2" + has "^1.0.1" + is-equal "^1.5.1" + is-regex "^1.0.3" + object-inspect "^1.1.0" + object-keys "^1.0.9" + tmatch "^2.0.1" + expect@^21.2.1: version "21.2.1" resolved "https://registry.yarnpkg.com/expect/-/expect-21.2.1.tgz#003ac2ac7005c3c29e73b38a272d4afadd6d1d7b" @@ -3208,6 +4401,17 @@ expect@^21.2.1: jest-message-util "^21.2.1" jest-regex-util "^21.2.0" +expect@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.3.tgz#d5a29d0a0e1fb2153557caef2674d4547e914674" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^22.4.3" + jest-get-type "^22.4.3" + jest-matcher-utils "^22.4.3" + jest-message-util "^22.4.3" + jest-regex-util "^22.4.3" + express@^4.13.3: version "4.16.2" resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" @@ -3243,20 +4447,55 @@ express@^4.13.3: utils-merge "1.0.1" vary "~1.1.2" +express@^4.16.2: + version "4.16.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.2" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.3" + qs "6.5.1" + range-parser "~1.2.0" + safe-buffer "5.1.1" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + 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.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.1: +extend@3, extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -3274,7 +4513,7 @@ extglob@^0.3.1: dependencies: is-extglob "^1.0.0" -extglob@^2.0.2: +extglob@^2.0.2, extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" dependencies: @@ -3296,6 +4535,15 @@ extract-text-webpack-plugin@3.0.2: schema-utils "^0.3.0" webpack-sources "^1.0.1" +extract-zip@^1.6.5: + version "1.6.6" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" + dependencies: + concat-stream "1.6.0" + debug "2.6.9" + mkdirp "0.5.0" + yauzl "2.4.1" + extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -3368,19 +4616,25 @@ fbjs@^0.8.15, fbjs@^0.8.16: setimmediate "^1.0.5" ua-parser-js "^0.7.9" -figures@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" + pend "~1.2.0" -figures@^2.0.0: +figures@2.0.0, 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" +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + 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" @@ -3395,6 +4649,17 @@ file-loader@1.1.5: loader-utils "^1.0.2" schema-utils "^0.3.0" +file-loader@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.6.tgz#7b9a8f2c58f00a77fddf49e940f7ac978a3ea0e8" + dependencies: + loader-utils "^1.0.2" + schema-utils "^0.3.0" + +file-uri-to-path@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -3445,6 +4710,18 @@ finalhandler@1.1.0: statuses "~1.3.1" unpipe "~1.0.0" +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + find-cache-dir@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" @@ -3461,6 +4738,10 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -3487,9 +4768,28 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -flow-bin@^0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.64.0.tgz#ddd3fb3b183ab1ab35a5d5dec9caf5ebbcded167" +flow-bin@^0.71.0: + version "0.71.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.71.0.tgz#fd1b27a6458c3ebaa5cb811853182ed631918b70" + +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" + +follow-redirects@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.0.0.tgz#8e34298cbd2e176f254effec75a1c78cc849fd37" + dependencies: + debug "^2.2.0" + +follow-redirects@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.4.1.tgz#d8120f4518190f55aac65bb6fc7b85fcd666d6aa" + dependencies: + debug "^3.1.0" for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" @@ -3509,6 +4809,14 @@ 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.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.11" + form-data@~2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" @@ -3545,6 +4853,19 @@ fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" +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-access@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" + dependencies: + null-check "^1.0.0" + fs-extra@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" @@ -3553,6 +4874,14 @@ fs-extra@3.0.1: 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-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -3563,6 +4892,43 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" +fs-extra@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + +fs-extra@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + +fs-extra@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-readdir-recursive@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + +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" @@ -3598,6 +4964,13 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" +ftp@~0.3.10: + version "0.3.10" + resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" + dependencies: + readable-stream "1.1.x" + xregexp "2.0.0" + 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" @@ -3631,10 +5004,38 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +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-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" +get-own-enumerable-property-symbols@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b" + +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" @@ -3647,6 +5048,17 @@ get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" +get-uri@2: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.1.tgz#dbdcacacd8c608a38316869368117697a1631c59" + dependencies: + data-uri-to-buffer "1" + debug "2" + extend "3" + file-uri-to-path "1" + ftp "~0.3.10" + readable-stream "2" + 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" @@ -3657,6 +5069,36 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +git-raw-commits@^1.3.0, git-raw-commits@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-1.3.6.tgz#27c35a32a67777c1ecd412a239a6c19d71b95aff" + 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@^1.3.0, git-semver-tags@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-1.3.6.tgz#357ea01f7280794fe0927f2806bee6414d2caba5" + 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-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -3677,7 +5119,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: +glob@7.1.2, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -3688,6 +5130,16 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-modules@1.0.0, global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -3738,6 +5190,17 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + glow@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/glow/-/glow-1.2.2.tgz#41630d723483a89c4a3add3cc5871f775daa3036" @@ -3779,7 +5242,23 @@ got@^5.0.0: unzip-response "^1.0.2" url-parse-lax "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -3789,6 +5268,10 @@ graphlib@^1.0.5: dependencies: lodash "^3.10.0" +growl@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -3799,6 +5282,13 @@ gzip-size@3.0.0: dependencies: duplexer "^0.1.1" +gzip-size@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c" + dependencies: + duplexer "^0.1.1" + pify "^3.0.0" + hammerjs@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" @@ -3807,7 +5297,7 @@ handle-thing@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" -handlebars@^4.0.3: +handlebars@^4.0.1, handlebars@^4.0.2, handlebars@^4.0.3: version "4.0.11" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" dependencies: @@ -3825,6 +5315,15 @@ 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@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" @@ -3845,6 +5344,16 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-binary2@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.2.tgz#e83dba49f0b9be4d026d27365350d9f03f54be98" + 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" @@ -3853,6 +5362,10 @@ has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +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: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -3884,7 +5397,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1: +has@^1.0.0, has@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" dependencies: @@ -3910,6 +5423,13 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" +hasha@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-2.2.0.tgz#78d7cbfc1e6d66303fe79837365984517b2f6ee1" + dependencies: + is-stream "^1.0.1" + pinkie-promise "^2.0.0" + hawk@3.1.3, hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -3928,7 +5448,7 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" -he@1.1.x: +he@1.1.1, he@1.1.x: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -3936,6 +5456,13 @@ heap@^0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" +hipchat-notifier@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz#b6d249755437c191082367799d3ba9a0f23b231e" + dependencies: + lodash "^4.0.0" + request "^2.0.0" + history@^4.5.1, history@^4.6.0, history@^4.6.3: version "4.6.3" resolved "https://registry.yarnpkg.com/history/-/history-4.6.3.tgz#6d723a8712c581d6bef37e8c26f4aedc6eb86967" @@ -3991,6 +5518,10 @@ hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" +hosted-git-info@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222" + hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" @@ -4004,7 +5535,7 @@ html-comment-regex@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" -html-encoding-sniffer@^1.0.1: +html-encoding-sniffer@^1.0.1, 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: @@ -4038,6 +5569,21 @@ html-webpack-plugin@2.29.0: pretty-error "^2.0.2" toposort "^1.0.0" +html-webpack-plugin@2.30.1: + version "2.30.1" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz#7f9c421b7ea91ec460f56527d78df484ee7537d5" + dependencies: + bluebird "^3.4.7" + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + toposort "^1.0.0" + +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" @@ -4075,6 +5621,14 @@ http-parser-js@>=0.4.0: version "0.4.9" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.9.tgz#ea1a04fb64adff0242e9974f297dd4c3cad271e1" +http-proxy-agent@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz#cc1ce38e453bf984a0f7702d2dd59c73d081284a" + dependencies: + agent-base "2" + debug "2" + extend "3" + http-proxy-middleware@~0.17.4: version "0.17.4" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" @@ -4084,6 +5638,14 @@ http-proxy-middleware@~0.17.4: lodash "^4.17.2" micromatch "^2.3.11" +http-proxy@^1.13.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + http-proxy@^1.16.2: version "1.16.2" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" @@ -4107,10 +5669,29 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +httpntlm@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/httpntlm/-/httpntlm-1.6.1.tgz#ad01527143a2e8773cfae6a96f58656bb52a34b2" + dependencies: + httpreq ">=0.4.22" + underscore "~1.7.0" + +httpreq@>=0.4.22: + version "0.4.24" + resolved "https://registry.yarnpkg.com/httpreq/-/httpreq-0.4.24.tgz#4335ffd82cd969668a39465c929ac61d6393627f" + 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@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" + dependencies: + agent-base "2" + debug "2" + extend "3" + husky@^0.14.3: version "0.14.3" resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" @@ -4119,6 +5700,10 @@ husky@^0.14.3: normalize-path "^1.0.0" strip-indent "^2.0.0" +iconv-lite@0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" + iconv-lite@0.4.19, iconv-lite@^0.4.17: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" @@ -4141,7 +5726,11 @@ ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" -ignore@^3.3.3: +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore@^3.3.3, ignore@^3.3.5: version "3.3.7" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" @@ -4186,6 +5775,18 @@ indexof@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" +inferno-vnode-flags@3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/inferno-vnode-flags/-/inferno-vnode-flags-3.10.1.tgz#88a4528a3b4df0f33a3ace68dc45f05b651c0e41" + +inflection@~1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.10.0.tgz#5bffcb1197ad3e81050f8e17e21668087ee9eb2f" + +inflection@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.3.8.tgz#cbd160da9f75b14c3cc63578d4f396784bf3014e" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -4201,11 +5802,17 @@ 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: +ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" -inquirer@3.3.0, inquirer@^3.0.6: +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@3.3.0, inquirer@^3.0.6, inquirer@^3.2.2: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" dependencies: @@ -4224,6 +5831,20 @@ inquirer@3.3.0, inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" +insert-module-globals@^7.0.0: + version "7.0.6" + resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.6.tgz#15a31d9d394e76d08838b9173016911d7fd4ea1b" + dependencies: + JSONStream "^1.0.3" + combine-source-map "^0.8.0" + concat-stream "^1.6.1" + is-buffer "^1.1.0" + lexical-scope "^1.2.0" + path-is-absolute "^1.0.1" + process "~0.11.0" + through2 "^2.0.0" + xtend "^4.0.0" + internal-ip@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" @@ -4244,7 +5865,11 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" -ip@^1.1.0, ip@^1.1.5: +ip@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.0.1.tgz#c7e356cdea225ae71b36d70f2e71a92ba4e42590" + +ip@^1.1.0, ip@^1.1.2, ip@^1.1.4, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -4252,6 +5877,10 @@ ipaddr.js@1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" +ipaddr.js@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" + is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" @@ -4272,13 +5901,23 @@ is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" +is-arrow-function@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-arrow-function/-/is-arrow-function-2.0.3.tgz#29be2c2d8d9450852b8bbafb635ba7b8d8e87ec2" + dependencies: + is-callable "^1.0.4" + 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-buffer@^1.1.5: +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: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -4288,7 +5927,7 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-callable@^1.1.1, is-callable@^1.1.3: +is-callable@^1.0.4, is-callable@^1.1.1, is-callable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" @@ -4322,7 +5961,7 @@ is-descriptor@^0.1.0: is-data-descriptor "^0.1.4" kind-of "^5.0.0" -is-descriptor@^1.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: @@ -4344,6 +5983,22 @@ is-equal-shallow@^0.1.3: dependencies: is-primitive "^2.0.0" +is-equal@^1.5.1: + version "1.5.5" + resolved "https://registry.yarnpkg.com/is-equal/-/is-equal-1.5.5.tgz#5e85f1957e052883247feb386965a3bba15fbb3d" + dependencies: + has "^1.0.1" + is-arrow-function "^2.0.3" + is-boolean-object "^1.0.0" + is-callable "^1.1.3" + is-date-object "^1.0.1" + is-generator-function "^1.0.6" + is-number-object "^1.0.3" + is-regex "^1.0.3" + is-string "^1.0.4" + is-symbol "^1.0.1" + object.entries "^1.0.4" + 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" @@ -4378,6 +6033,14 @@ 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-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-generator-function@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" + 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" @@ -4396,10 +6059,32 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" +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.17.2" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz#6b2103a288e94ef3de5cf15d29dd85fc4b78d65c" + 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-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" +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@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" + is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -4412,16 +6097,32 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-obj@^1.0.0: +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" +is-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" + dependencies: + symbol-observable "^0.2.2" + is-odd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088" dependencies: is-number "^3.0.0" +is-odd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" + dependencies: + is-number "^4.0.0" + 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" @@ -4460,16 +6161,24 @@ 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: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" -is-regex@^1.0.4: +is-regex@^1.0.3, 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-resolvable@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4" @@ -4486,6 +6195,10 @@ is-stream@^1.0.0, is-stream@^1.0.1, 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" @@ -4500,6 +6213,12 @@ is-symbol@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" +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" @@ -4512,6 +6231,10 @@ is-windows@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9" +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" @@ -4524,6 +6247,18 @@ 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" + +isbinaryfile@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -4612,6 +6347,25 @@ istanbul-reports@^1.1.3: dependencies: handlebars "^4.0.3" +istanbul@^0.4.0: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + jest-changed-files@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-20.0.3.tgz#9394d5cc65c438406149bef1bf4d52b68e03e3f8" @@ -4722,6 +6476,22 @@ jest-config@^21.2.1: jest-validate "^21.2.1" pretty-format "^21.2.1" +jest-config@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.3.tgz#0e9d57db267839ea31309119b41dc2fa31b76403" + dependencies: + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^22.4.3" + jest-environment-node "^22.4.3" + jest-get-type "^22.4.3" + jest-jasmine2 "^22.4.3" + jest-regex-util "^22.4.3" + jest-resolve "^22.4.3" + jest-util "^22.4.3" + jest-validate "^22.4.3" + pretty-format "^22.4.3" + jest-diff@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-20.0.3.tgz#81f288fd9e675f0fb23c75f1c2b19445fe586617" @@ -4740,6 +6510,15 @@ jest-diff@^21.2.1: jest-get-type "^21.2.0" pretty-format "^21.2.1" +jest-diff@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.3.tgz#e18cc3feff0aeef159d02310f2686d4065378030" + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + jest-docblock@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-20.0.3.tgz#17bea984342cc33d83c50fbe1545ea0efaa44712" @@ -4764,6 +6543,14 @@ jest-environment-jsdom@^21.2.1: jest-util "^21.2.1" jsdom "^9.12.0" +jest-environment-jsdom@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz#d67daa4155e33516aecdd35afd82d4abf0fa8a1e" + dependencies: + jest-mock "^22.4.3" + jest-util "^22.4.3" + jsdom "^11.5.1" + jest-environment-node@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-20.0.3.tgz#d488bc4612af2c246e986e8ae7671a099163d403" @@ -4778,10 +6565,21 @@ jest-environment-node@^21.2.1: jest-mock "^21.2.0" jest-util "^21.2.1" +jest-environment-node@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.3.tgz#54c4eaa374c83dd52a9da8759be14ebe1d0b9129" + dependencies: + jest-mock "^22.4.3" + jest-util "^22.4.3" + jest-get-type@^21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23" +jest-get-type@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + jest-haste-map@^20.0.4: version "20.0.5" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-20.0.5.tgz#abad74efb1a005974a7b6517e11010709cab9112" @@ -4831,6 +6629,22 @@ jest-jasmine2@^21.2.1: jest-snapshot "^21.2.1" p-cancelable "^0.3.0" +jest-jasmine2@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.3.tgz#4daf64cd14c793da9db34a7c7b8dcfe52a745965" + dependencies: + chalk "^2.0.1" + co "^4.6.0" + expect "^22.4.3" + graceful-fs "^4.1.11" + is-generator-fn "^1.0.0" + jest-diff "^22.4.3" + jest-matcher-utils "^22.4.3" + jest-message-util "^22.4.3" + jest-snapshot "^22.4.3" + jest-util "^22.4.3" + source-map-support "^0.5.0" + jest-matcher-utils@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz#b3a6b8e37ca577803b0832a98b164f44b7815612" @@ -4846,6 +6660,14 @@ jest-matcher-utils@^21.2.1: jest-get-type "^21.2.0" pretty-format "^21.2.1" +jest-matcher-utils@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + jest-matchers@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-20.0.3.tgz#ca69db1c32db5a6f707fa5e0401abb55700dfd60" @@ -4871,6 +6693,16 @@ jest-message-util@^21.2.1: micromatch "^2.3.11" slash "^1.0.0" +jest-message-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.3.tgz#cf3d38aafe4befddbfc455e57d65d5239e399eb7" + 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@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-20.0.3.tgz#8bc070e90414aa155c11a8d64c869a0d5c71da59" @@ -4879,6 +6711,10 @@ jest-mock@^21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-21.2.0.tgz#7eb0770e7317968165f61ea2a7281131534b3c0f" +jest-mock@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.4.3.tgz#f63ba2f07a1511772cdc7979733397df770aabc7" + jest-regex-util@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-20.0.3.tgz#85bbab5d133e44625b19faf8c6aa5122d085d762" @@ -4887,6 +6723,10 @@ jest-regex-util@^21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-21.2.0.tgz#1b1e33e63143babc3e0f2e6c9b5ba1eb34b2d530" +jest-regex-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.4.3.tgz#a826eb191cdf22502198c5401a1fc04de9cef5af" + jest-resolve-dependencies@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz#6e14a7b717af0f2cb3667c549de40af017b1723a" @@ -4915,6 +6755,13 @@ jest-resolve@^21.2.0: chalk "^2.0.1" is-builtin-module "^1.0.0" +jest-resolve@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.3.tgz#0ce9d438c8438229aa9b916968ec6b05c1abb4ea" + dependencies: + browser-resolve "^1.11.2" + chalk "^2.0.1" + jest-runner@^21.2.1: version "21.2.1" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-21.2.1.tgz#194732e3e518bfb3d7cbfc0fd5871246c7e1a467" @@ -4994,6 +6841,17 @@ jest-snapshot@^21.2.1: natural-compare "^1.4.0" pretty-format "^21.2.1" +jest-snapshot@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.3.tgz#b5c9b42846ffb9faccb76b841315ba67887362d2" + dependencies: + chalk "^2.0.1" + jest-diff "^22.4.3" + jest-matcher-utils "^22.4.3" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^22.4.3" + jest-util@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-20.0.3.tgz#0c07f7d80d82f4e5a67c6f8b9c3fe7f65cfd32ad" @@ -5018,6 +6876,18 @@ jest-util@^21.2.1: jest-validate "^21.2.1" mkdirp "^0.5.1" +jest-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.3.tgz#c70fec8eec487c37b10b0809dc064a7ecf6aafac" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^22.4.3" + mkdirp "^0.5.1" + source-map "^0.6.0" + jest-validate@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-20.0.3.tgz#d0cfd1de4f579f298484925c280f8f1d94ec3cab" @@ -5036,6 +6906,16 @@ jest-validate@^21.2.1: leven "^2.1.0" pretty-format "^21.2.1" +jest-validate@^22.4.0, jest-validate@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.3.tgz#0780954a5a7daaeec8d3c10834b9280865976b30" + dependencies: + chalk "^2.0.1" + jest-config "^22.4.3" + jest-get-type "^22.4.3" + leven "^2.1.0" + pretty-format "^22.4.3" + jest@20.0.4: version "20.0.4" resolved "https://registry.yarnpkg.com/jest/-/jest-20.0.4.tgz#3dd260c2989d6dad678b1e9cc4d91944f6d602ac" @@ -5056,7 +6936,14 @@ js-tokens@^3.0.0, 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.4.3, js-yaml@^3.7.0, js-yaml@^3.9.1: +js-yaml@3.x, js-yaml@^3.4.3, js-yaml@^3.9.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^3.7.0, js-yaml@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: @@ -5074,6 +6961,37 @@ 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.8.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.8.0.tgz#a52e9a7d2b931284f62c80dad5f17d7390499d8b" + dependencies: + abab "^1.0.4" + acorn "^5.3.0" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle ">= 0.2.37 < 0.3.0" + data-urls "^1.0.0" + domexception "^1.0.0" + escodegen "^1.9.0" + html-encoding-sniffer "^1.0.2" + left-pad "^1.2.0" + nwmatcher "^1.4.3" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.83.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.3" + 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.0" + ws "^4.0.0" + xml-name-validator "^3.0.0" + jsdom@^9.12.0: version "9.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4" @@ -5132,7 +7050,13 @@ json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@~5.0.1: +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.x, 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" @@ -5162,10 +7086,24 @@ jsonfile@^3.0.0: 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" @@ -5189,6 +7127,97 @@ just-extend@^1.1.22: version "1.1.22" resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.22.tgz#3330af756cab6a542700c64b2e4e4aa062d52fff" +karma-chrome-launcher@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf" + dependencies: + fs-access "^1.0.0" + which "^1.2.1" + +karma-coverage@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-1.1.1.tgz#5aff8b39cf6994dc22de4c84362c76001b637cf6" + dependencies: + dateformat "^1.0.6" + istanbul "^0.4.0" + lodash "^3.8.0" + minimatch "^3.0.0" + source-map "^0.5.1" + +karma-mocha-reporter@2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz#15120095e8ed819186e47a0b012f3cd741895560" + dependencies: + chalk "^2.1.0" + log-symbols "^2.1.0" + strip-ansi "^4.0.0" + +karma-mocha@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-1.3.0.tgz#eeaac7ffc0e201eb63c467440d2b69c7cf3778bf" + dependencies: + minimist "1.2.0" + +karma-phantomjs-launcher@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz#d23ca34801bda9863ad318e3bb4bd4062b13acd2" + dependencies: + lodash "^4.0.1" + phantomjs-prebuilt "^2.1.7" + +karma-sourcemap-loader@0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" + dependencies: + graceful-fs "^4.1.2" + +karma-webpack@2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-2.0.9.tgz#61c88091f7dd910635134c032b266a465affb57f" + dependencies: + async "~0.9.0" + loader-utils "^0.2.5" + lodash "^3.8.0" + source-map "^0.5.6" + webpack-dev-middleware "^1.12.0" + +karma@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/karma/-/karma-2.0.0.tgz#a02698dd7f0f05ff5eb66ab8f65582490b512e58" + dependencies: + bluebird "^3.3.0" + body-parser "^1.16.1" + browserify "^14.5.0" + chokidar "^1.4.1" + colors "^1.1.0" + combine-lists "^1.0.0" + connect "^3.6.0" + core-js "^2.2.0" + di "^0.0.1" + dom-serialize "^2.2.0" + expand-braces "^0.1.1" + glob "^7.1.1" + graceful-fs "^4.1.2" + http-proxy "^1.13.0" + isbinaryfile "^3.0.0" + lodash "^4.17.4" + log4js "^2.3.9" + mime "^1.3.4" + minimatch "^3.0.2" + optimist "^0.6.1" + qjobs "^1.1.4" + range-parser "^1.2.0" + rimraf "^2.6.0" + safe-buffer "^5.0.1" + socket.io "2.0.4" + source-map "^0.6.1" + tmp "0.0.33" + useragent "^2.1.12" + +kew@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" + killable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b" @@ -5219,6 +7248,14 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +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" + latest-version@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" @@ -5245,6 +7282,54 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +left-pad@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + +lerna@^2.10.2: + version "2.10.2" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-2.10.2.tgz#3a0d54d398360fecc5918207c6d7ab68a5443d9f" + dependencies: + async "^1.5.0" + chalk "^2.1.0" + cmd-shim "^2.0.2" + columnify "^1.5.4" + command-join "^2.0.0" + conventional-changelog-cli "^1.3.13" + conventional-recommended-bump "^1.2.1" + dedent "^0.7.0" + execa "^0.8.0" + find-up "^2.1.0" + fs-extra "^4.0.1" + get-port "^3.2.0" + glob "^7.1.2" + glob-parent "^3.1.0" + globby "^6.1.0" + graceful-fs "^4.1.11" + hosted-git-info "^2.5.0" + inquirer "^3.2.2" + is-ci "^1.0.10" + load-json-file "^4.0.0" + lodash "^4.17.4" + minimatch "^3.0.4" + npmlog "^4.1.2" + p-finally "^1.0.0" + package-json "^4.0.1" + path-exists "^3.0.0" + read-cmd-shim "^1.0.1" + read-pkg "^3.0.0" + rimraf "^2.6.1" + safe-buffer "^5.1.1" + semver "^5.4.1" + signal-exit "^3.0.2" + slash "^1.0.0" + strong-log-transformer "^1.0.6" + temp-write "^3.3.0" + write-file-atomic "^2.3.0" + write-json-file "^2.2.0" + write-pkg "^3.1.0" + yargs "^8.0.2" + less-loader@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.0.5.tgz#ae155a7406cac6acd293d785587fcff0f478c4dd" @@ -5281,27 +7366,62 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lint-staged@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-4.0.3.tgz#1ce55591bc2c83a781a90b69a0a0c8aa0fc6370b" +lexical-scope@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/lexical-scope/-/lexical-scope-1.2.0.tgz#fcea5edc704a4b3a8796cdca419c3a0afaf22df4" dependencies: - app-root-path "^2.0.0" - cosmiconfig "^1.1.0" - execa "^0.8.0" - listr "^0.12.0" - lodash.chunk "^4.2.0" - minimatch "^3.0.0" + astw "^2.0.0" + +libbase64@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/libbase64/-/libbase64-0.1.0.tgz#62351a839563ac5ff5bd26f12f60e9830bb751e6" + +libmime@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/libmime/-/libmime-3.0.0.tgz#51a1a9e7448ecbd32cda54421675bb21bc093da6" + dependencies: + iconv-lite "0.4.15" + libbase64 "0.1.0" + libqp "1.1.0" + +libqp@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/libqp/-/libqp-1.1.0.tgz#f5e6e06ad74b794fb5b5b66988bf728ef1dedbe8" + +lint-staged@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.0.4.tgz#1aa7f27427e4c4c85d4d6524ac98aac10cbaf1b8" + dependencies: + app-root-path "^2.0.1" + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "^4.0.0" + debug "^3.1.0" + dedent "^0.7.0" + execa "^0.9.0" + find-parent-dir "^0.3.0" + is-glob "^4.0.0" + jest-validate "^22.4.0" + listr "^0.13.0" + lodash "^4.17.5" + log-symbols "^2.2.0" + micromatch "^3.1.8" npm-which "^3.0.1" p-map "^1.1.1" - staged-git-files "0.0.4" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.1" + staged-git-files "1.1.1" + string-argv "^0.0.2" + stringify-object "^3.2.2" listr-silent-renderer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" -listr-update-renderer@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9" +listr-update-renderer@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" dependencies: chalk "^1.1.3" cli-truncate "^0.2.1" @@ -5313,33 +7433,34 @@ listr-update-renderer@^0.2.0: strip-ansi "^3.0.1" listr-verbose-renderer@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.0.tgz#44dc01bb0c34a03c572154d4d08cde9b1dc5620f" + version "0.4.1" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" dependencies: chalk "^1.1.3" cli-cursor "^1.0.2" date-fns "^1.27.2" figures "^1.7.0" -listr@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a" +listr@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d" dependencies: chalk "^1.1.3" cli-truncate "^0.2.1" figures "^1.7.0" indent-string "^2.1.0" + is-observable "^0.2.0" is-promise "^2.1.0" is-stream "^1.1.0" listr-silent-renderer "^1.1.1" - listr-update-renderer "^0.2.0" + listr-update-renderer "^0.4.0" listr-verbose-renderer "^0.4.0" log-symbols "^1.0.2" log-update "^1.0.2" ora "^0.2.3" p-map "^1.1.1" - rxjs "^5.0.0-beta.11" - stream-to-observable "^0.1.0" + rxjs "^5.4.2" + stream-to-observable "^0.2.0" strip-ansi "^3.0.1" load-json-file@^1.0.0: @@ -5381,7 +7502,7 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@^0.2.16: +loader-utils@^0.2.15, loader-utils@^0.2.16, loader-utils@^0.2.5: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: @@ -5390,7 +7511,7 @@ loader-utils@^0.2.16: json5 "^0.5.0" object-assign "^4.0.1" -loader-utils@^1.0.2, loader-utils@^1.1.0: +loader-utils@^1.0.0, loader-utils@^1.0.2, loader-utils@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" dependencies: @@ -5425,10 +7546,6 @@ lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" -lodash.chunk@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc" - lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" @@ -5484,6 +7601,10 @@ lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" +lodash.memoize@~3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" + lodash.merge@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" @@ -5492,7 +7613,11 @@ lodash.reduce@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" -lodash.template@^4.4.0: +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, lodash.template@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" dependencies: @@ -5517,10 +7642,14 @@ lodash.uniq@^4.5.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" -lodash@^3.10.0: +lodash@^3.10.0, lodash@^3.8.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" +lodash@^4.0.0, lodash@^4.0.1, lodash@^4.17.5, lodash@^4.5.0, lodash@^4.6.1: + version "4.17.5" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + lodash@~2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" @@ -5531,6 +7660,12 @@ log-symbols@^1.0.2: dependencies: chalk "^1.0.0" +log-symbols@^2.1.0, log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + dependencies: + chalk "^2.0.1" + log-update@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" @@ -5538,6 +7673,25 @@ log-update@^1.0.2: ansi-escapes "^1.0.0" cli-cursor "^1.0.2" +log4js@^2.3.9: + version "2.5.3" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-2.5.3.tgz#38bb7bde5e9c1c181bd75e8bc128c5cd0409caf1" + dependencies: + circular-json "^0.5.1" + date-format "^1.2.0" + debug "^3.1.0" + semver "^5.3.0" + streamroller "^0.7.0" + optionalDependencies: + amqplib "^0.5.2" + axios "^0.15.3" + hipchat-notifier "^1.1.0" + loggly "^1.1.0" + mailgun-js "^0.7.0" + nodemailer "^2.5.0" + redis "^2.7.1" + slack-node "~0.2.0" + logfmt@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/logfmt/-/logfmt-1.2.0.tgz#1ccc067c1cfe65f3ecf5856c09d2654f69203572" @@ -5546,6 +7700,14 @@ logfmt@^1.2.0: split "0.2.x" through "2.3.x" +loggly@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/loggly/-/loggly-1.1.1.tgz#0a0fc1d3fa3a5ec44fdc7b897beba2a4695cebee" + dependencies: + json-stringify-safe "5.0.x" + request "2.75.x" + timespan "2.3.x" + loglevel@^1.4.1: version "1.6.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" @@ -5583,17 +7745,42 @@ lowercase-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" -lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" +lru-cache@4.1.x, lru-cache@^4.0.1, lru-cache@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" dependencies: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@~2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.6.5.tgz#e56d6354148ede8d7707b58d143220fd08df0fd5" + macaddress@^0.2.8: version "0.2.8" resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" +mailcomposer@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/mailcomposer/-/mailcomposer-4.0.1.tgz#0e1c44b2a07cf740ee17dc149ba009f19cadfeb4" + dependencies: + buildmail "4.0.1" + libmime "3.0.0" + +mailgun-js@^0.7.0: + version "0.7.15" + resolved "https://registry.yarnpkg.com/mailgun-js/-/mailgun-js-0.7.15.tgz#ee366a20dac64c3c15c03d6c1b3e0ed795252abb" + dependencies: + async "~2.1.2" + debug "~2.2.0" + form-data "~2.1.1" + inflection "~1.10.0" + is-stream "^1.1.0" + path-proxy "~1.0.0" + proxy-agent "~2.0.0" + q "~1.4.0" + tsscmp "~1.0.0" + make-dir@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51" @@ -5628,6 +7815,19 @@ math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" +maxstache-stream@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/maxstache-stream/-/maxstache-stream-1.0.4.tgz#9c7f5cab7e5fdd2d90da86143b4e9631ea328040" + dependencies: + maxstache "^1.0.0" + pump "^1.0.0" + split2 "^1.0.0" + through2 "^2.0.0" + +maxstache@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/maxstache/-/maxstache-1.0.7.tgz#2231d5180ba783d5ecfc31c45fedac7ae4276984" + md5.js@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" @@ -5645,7 +7845,7 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" -memory-fs@^0.4.0, memory-fs@~0.4.1: +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" dependencies: @@ -5729,6 +7929,24 @@ micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +micromatch@^3.1.8: + 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" @@ -5744,6 +7962,16 @@ mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + +mime-types@^2.1.11, mime-types@~2.1.18: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + dependencies: + mime-db "~1.33.0" + mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" @@ -5754,7 +7982,7 @@ mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" -mime@^1.2.11, mime@^1.4.1, mime@^1.5.0: +mime@^1.2.11, mime@^1.3.4, mime@^1.4.1, mime@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -5784,18 +8012,18 @@ 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 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, 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" + minimatch@3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: brace-expansion "^1.0.0" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, 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" @@ -5807,14 +8035,33 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: +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 "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" +minimist@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" + minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + 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 "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mixin-deep@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.0.tgz#47a8732ba97799457c8c1eca28f95132d7e8150a" @@ -5822,12 +8069,57 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" + dependencies: + minimist "0.0.8" + mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" +mocha@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" + dependencies: + browser-stdout "1.3.0" + commander "2.11.0" + debug "3.1.0" + diff "3.3.1" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.3" + he "1.1.1" + mkdirp "0.5.1" + supports-color "4.4.0" + +modify-values@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + +module-deps@^4.0.8: + version "4.1.1" + resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-4.1.1.tgz#23215833f1da13fd606ccb8087b44852dcb821fd" + dependencies: + JSONStream "^1.0.3" + browser-resolve "^1.7.0" + cached-path-relative "^1.0.0" + concat-stream "~1.5.0" + defined "^1.0.0" + detective "^4.0.0" + duplexer2 "^0.1.2" + inherits "^2.0.1" + parents "^1.0.0" + readable-stream "^2.0.2" + resolve "^1.1.3" + stream-combiner2 "^1.1.1" + subarg "^1.0.0" + through2 "^2.0.0" + xtend "^4.0.0" + moment@2.x, moment@^2.19.3: version "2.20.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" @@ -5836,6 +8128,25 @@ moment@^2.18.1: version "2.18.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" +moment@^2.6.0: + version "2.22.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad" + +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@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -5884,6 +8195,23 @@ nanomatch@^1.2.5: snapdragon "^0.8.1" to-regex "^3.0.1" +nanomatch@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + 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-odd "^2.0.0" + 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" + native-promise-only@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11" @@ -5910,6 +8238,14 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" +netmask@~1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" + +nice-try@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" + nise@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/nise/-/nise-1.0.1.tgz#0da92b10a854e97c0f496f6c2845a301280b3eef" @@ -5997,6 +8333,59 @@ node-status-codes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" +node-uuid@~1.4.7: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + +nodemailer-direct-transport@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz#e96fafb90358560947e569017d97e60738a50a86" + dependencies: + nodemailer-shared "1.1.0" + smtp-connection "2.12.0" + +nodemailer-fetch@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz#79c4908a1c0f5f375b73fe888da9828f6dc963a4" + +nodemailer-shared@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz#cf5994e2fd268d00f5cf0fa767a08169edb07ec0" + dependencies: + nodemailer-fetch "1.6.0" + +nodemailer-smtp-pool@2.8.2: + version "2.8.2" + resolved "https://registry.yarnpkg.com/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz#2eb94d6cf85780b1b4725ce853b9cbd5e8da8c72" + dependencies: + nodemailer-shared "1.1.0" + nodemailer-wellknown "0.1.10" + smtp-connection "2.12.0" + +nodemailer-smtp-transport@2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz#03d71c76314f14ac7dbc7bf033a6a6d16d67fb77" + dependencies: + nodemailer-shared "1.1.0" + nodemailer-wellknown "0.1.10" + smtp-connection "2.12.0" + +nodemailer-wellknown@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz#586db8101db30cb4438eb546737a41aad0cf13d5" + +nodemailer@^2.5.0: + version "2.7.2" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-2.7.2.tgz#f242e649aeeae39b6c7ed740ef7b061c404d30f9" + dependencies: + libmime "3.0.0" + mailcomposer "4.0.1" + nodemailer-direct-transport "3.3.2" + nodemailer-shared "1.1.0" + nodemailer-smtp-pool "2.8.2" + nodemailer-smtp-transport "2.7.2" + socks "1.1.9" + nomnom@~1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971" @@ -6004,6 +8393,16 @@ nomnom@~1.6.2: colors "0.5.x" underscore "~1.4.4" +noop2@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/noop2/-/noop2-2.0.0.tgz#4b636015e9882b54783c02b412f699d8c5cd0a5b" + +nopt@3.x: + 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" @@ -6011,7 +8410,7 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: +normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" dependencies: @@ -6043,9 +8442,17 @@ normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" +npm-install-webpack2-plugin@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npm-install-webpack2-plugin/-/npm-install-webpack2-plugin-5.0.1.tgz#d691a40f48a3077407ace0bb4c919180b96e8290" + dependencies: + cross-spawn "^5.0.1" + memory-fs "^0.4.1" + resolve "^1.2.0" + npm-path@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.3.tgz#15cff4e1c89a38da77f56f6055b24f975dfb2bbe" + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" dependencies: which "^1.2.10" @@ -6063,7 +8470,7 @@ npm-which@^3.0.1: npm-path "^2.0.2" which "^1.2.10" -npmlog@^4.0.2: +npmlog@^4.0.2, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: @@ -6078,6 +8485,10 @@ nth-check@~1.0.1: dependencies: boolbase "~1.0.0" +null-check@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" + num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" @@ -6086,10 +8497,96 @@ 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" +nwb@0.21.x: + version "0.21.5" + resolved "https://registry.yarnpkg.com/nwb/-/nwb-0.21.5.tgz#8fc50eda7e3d5137801f6747bb9776d00d69cd88" + dependencies: + autoprefixer "7.2.5" + babel-cli "6.26.0" + babel-core "6.26.0" + babel-loader "7.1.2" + babel-plugin-add-module-exports "0.2.1" + babel-plugin-inferno "3.3.1" + babel-plugin-istanbul "4.1.5" + babel-plugin-lodash "3.2.11" + babel-plugin-react-transform "3.0.0" + babel-plugin-syntax-dynamic-import "6.18.0" + babel-plugin-syntax-jsx "6.18.0" + babel-plugin-transform-decorators-legacy "1.3.4" + babel-plugin-transform-react-constant-elements "6.23.0" + babel-plugin-transform-react-jsx "6.24.1" + babel-plugin-transform-react-jsx-self "6.22.0" + babel-plugin-transform-react-jsx-source "6.22.0" + babel-plugin-transform-react-remove-prop-types "0.4.10" + babel-plugin-transform-runtime "6.23.0" + babel-polyfill "6.26.0" + babel-preset-env "1.6.1" + babel-preset-react "6.24.1" + babel-preset-stage-0 "6.24.1" + babel-preset-stage-1 "6.24.1" + babel-preset-stage-2 "6.24.1" + babel-preset-stage-3 "6.24.1" + babel-runtime "6.26.0" + case-sensitive-paths-webpack-plugin "2.1.1" + chalk "2.3.0" + copy-template-dir "1.3.0" + copy-webpack-plugin "4.3.1" + cross-spawn "6.0.4" + css-loader "0.28.9" + debug "3.1.0" + detect-port "1.2.2" + diff "3.4.0" + eventsource-polyfill "0.9.6" + expect "1.20.2" + extract-text-webpack-plugin "3.0.2" + figures "2.0.0" + file-loader "1.1.6" + filesize "3.5.11" + fs-extra "5.0.0" + gzip-size "4.1.0" + html-webpack-plugin "2.30.1" + inquirer "3.3.0" + karma "2.0.0" + karma-chrome-launcher "2.2.0" + karma-coverage "1.1.1" + karma-mocha "1.3.0" + karma-mocha-reporter "2.2.5" + karma-phantomjs-launcher "1.0.4" + karma-sourcemap-loader "0.3.7" + karma-webpack "2.0.9" + minimist "1.2.0" + mocha "4.1.0" + npm-install-webpack2-plugin "5.0.1" + object-assign "4.1.1" + opn "5.2.0" + ora "1.3.0" + phantomjs-prebuilt "2.1.16" + postcss-loader "2.0.10" + promise "8.0.1" + react-transform-catch-errors "1.0.2" + react-transform-hmr "1.0.4" + redbox-noreact "1.1.0" + resolve "1.5.0" + run-series "1.1.4" + semver "5.5.0" + style-loader "0.20.1" + uglifyjs-webpack-plugin "1.1.8" + url-loader "0.6.2" + webpack "3.10.0" + webpack-dev-middleware "1.12.2" + webpack-dev-server "2.9.7" + webpack-hot-middleware "2.21.0" + webpack-merge "4.1.1" + whatwg-fetch "2.0.3" + "nwmatcher@>= 1.3.9 < 2.0.0": version "1.4.3" resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c" +nwmatcher@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" + 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" @@ -6098,6 +8595,10 @@ object-assign@4.1.1, object-assign@4.x, object-assign@^4.0.1, object-assign@^4.1 version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +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" @@ -6110,11 +8611,15 @@ object-hash@^1.1.4: version "1.2.0" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.2.0.tgz#e96af0e96981996a1d47f88ead8f74f1ebc4422b" +object-inspect@^1.1.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.5.0.tgz#9d876c11e40f485c79215670281b767488f9bfe3" + 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.10, object-keys@^1.0.8: +object-keys@^1.0.10, object-keys@^1.0.8, object-keys@^1.0.9: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -6190,7 +8695,7 @@ on-headers@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -once@^1.3.0, once@^1.3.3, once@^1.4.0: +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: @@ -6198,7 +8703,7 @@ once@^1.3.0, once@^1.3.3, once@^1.4.0: onetime@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" onetime@^2.0.0: version "2.0.1" @@ -6230,6 +8735,15 @@ optionator@^0.8.1, optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" +ora@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-1.3.0.tgz#80078dd2b92a934af66a3ad72a5b910694ede51a" + dependencies: + chalk "^1.1.1" + cli-cursor "^2.1.0" + cli-spinners "^1.0.0" + log-symbols "^1.0.2" + ora@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" @@ -6245,7 +8759,7 @@ original@>=0.0.5: dependencies: url-parse "1.0.x" -os-browserify@^0.3.0: +os-browserify@^0.3.0, os-browserify@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -6278,6 +8792,14 @@ osenv@^0.1.0, osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +output-file-sync@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + p-cancelable@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" @@ -6286,7 +8808,7 @@ 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: +p-limit@^1.0.0, p-limit@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" dependencies: @@ -6306,6 +8828,30 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" +pac-proxy-agent@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz#34a385dfdf61d2f0ecace08858c745d3e791fd4d" + dependencies: + agent-base "2" + debug "2" + extend "3" + get-uri "2" + http-proxy-agent "1" + https-proxy-agent "1" + pac-resolver "~2.0.0" + raw-body "2" + socks-proxy-agent "2" + +pac-resolver@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-2.0.0.tgz#99b88d2f193fbdeefc1c9a529c1f3260ab5277cd" + dependencies: + co "~3.0.6" + degenerator "~1.0.2" + ip "1.0.1" + netmask "~1.0.4" + thunkify "~2.1.1" + package-json@^2.0.0: version "2.4.0" resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb" @@ -6315,16 +8861,39 @@ package-json@^2.0.0: registry-url "^3.0.3" semver "^5.1.0" +package-json@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" +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" + param-case@2.1.x: version "2.1.1" resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" dependencies: no-case "^2.2.0" +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.0" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" @@ -6335,6 +8904,10 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" +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-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -6361,6 +8934,10 @@ 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@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" @@ -6371,6 +8948,18 @@ parse5@^3.0.1: 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" @@ -6379,7 +8968,7 @@ 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: +path-browserify@0.0.0, path-browserify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" @@ -6405,7 +8994,7 @@ 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.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -6413,6 +9002,16 @@ path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" +path-platform@~0.11.15: + version "0.11.15" + resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" + +path-proxy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-proxy/-/path-proxy-1.0.0.tgz#18e8a36859fc9d2f1a53b48dee138543c020de5e" + dependencies: + inflection "~1.3.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -6453,6 +9052,10 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" @@ -6461,6 +9064,20 @@ performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" +phantomjs-prebuilt@2.1.16, phantomjs-prebuilt@^2.1.7: + version "2.1.16" + resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz#efd212a4a3966d3647684ea8ba788549be2aefef" + dependencies: + es6-promise "^4.0.3" + extract-zip "^1.6.5" + fs-extra "^1.0.0" + hasha "^2.2.0" + kew "^0.7.0" + progress "^1.1.8" + request "^2.81.0" + request-progress "^2.0.1" + which "^1.2.10" + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -6491,6 +9108,10 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +please-upgrade-node@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.1.tgz#0a681f2c18915e5433a5ca2cd94e0b8206a782db" + pluralize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" @@ -6499,6 +9120,10 @@ 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" + portfinder@^1.0.9: version "1.0.13" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" @@ -6601,6 +9226,15 @@ postcss-load-plugins@^2.3.0: cosmiconfig "^2.1.1" object-assign "^4.1.0" +postcss-loader@2.0.10: + version "2.0.10" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.0.10.tgz#090db0540140bd56a7a7f717c41bc29aeef4c674" + dependencies: + loader-utils "^1.1.0" + postcss "^6.0.0" + postcss-load-config "^1.2.0" + schema-utils "^0.3.0" + postcss-loader@2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.0.8.tgz#8c67ddb029407dfafe684a406cfc16bad2ce0814" @@ -6677,21 +9311,27 @@ postcss-modules-extract-imports@^1.0.0: dependencies: postcss "^6.0.1" -postcss-modules-local-by-default@^1.0.1: +postcss-modules-extract-imports@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85" + dependencies: + postcss "^6.0.1" + +postcss-modules-local-by-default@^1.0.1, postcss-modules-local-by-default@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" dependencies: css-selector-tokenizer "^0.7.0" postcss "^6.0.1" -postcss-modules-scope@^1.0.0: +postcss-modules-scope@^1.0.0, postcss-modules-scope@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" dependencies: css-selector-tokenizer "^0.7.0" postcss "^6.0.1" -postcss-modules-values@^1.1.0: +postcss-modules-values@^1.1.0, postcss-modules-values@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" dependencies: @@ -6795,6 +9435,14 @@ postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.13: source-map "^0.6.1" supports-color "^5.1.0" +postcss@^6.0.16: + version "6.0.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.21.tgz#8265662694eddf9e9a5960db6da33c39e4cd069d" + dependencies: + chalk "^2.3.2" + source-map "^0.6.1" + supports-color "^5.3.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -6836,6 +9484,13 @@ pretty-format@^21.2.1: ansi-regex "^3.0.0" ansi-styles "^3.2.0" +pretty-format@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f" + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + private@^0.1.6, private@^0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -6844,7 +9499,11 @@ 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.10: +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@^0.11.10, process@~0.11.0: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -6852,10 +9511,18 @@ process@~0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + promise@8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/promise/-/promise-8.0.1.tgz#e45d68b00a17647b6da711bf85ed6ed47208f450" @@ -6890,6 +9557,26 @@ proxy-addr@~2.0.2: forwarded "~0.1.2" ipaddr.js "1.5.2" +proxy-addr@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.6.0" + +proxy-agent@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-2.0.0.tgz#57eb5347aa805d74ec681cb25649dba39c933499" + dependencies: + agent-base "2" + debug "2" + extend "3" + http-proxy-agent "1" + https-proxy-agent "1" + lru-cache "~2.6.5" + pac-proxy-agent "1" + socks-proxy-agent "2" + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -6908,21 +9595,59 @@ public-encrypt@^4.0.0: parse-asn1 "^5.0.0" randombytes "^2.0.1" +pump@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^2.0.0, pump@^2.0.1: + 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" + +pumpify@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb" + dependencies: + duplexify "^3.5.3" + inherits "^2.0.3" + pump "^2.0.0" + punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" -punycode@^1.2.4, punycode@^1.4.1: +punycode@1.4.1, punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -q@^1.1.2: +punycode@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + +q@^1.1.2, q@^1.4.1, q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" -qs@6.5.1, qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" +q@~1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" + +qjobs@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + +qs@6.5.1, qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +qs@~6.2.0: + version "6.2.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" qs@~6.4.0: version "6.4.0" @@ -6943,7 +9668,7 @@ query-string@^5.0.0: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -querystring-es3@^0.2.0: +querystring-es3@^0.2.0, querystring-es3@~0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -7006,7 +9731,7 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -range-parser@^1.0.3, range-parser@~1.2.0: +range-parser@^1.0.3, range-parser@^1.2.0, range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" @@ -7014,7 +9739,7 @@ raven-js@^3.22.1: version "3.22.1" resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.22.1.tgz#1117f00dfefaa427ef6e1a7d50bbb1fb998a24da" -raw-body@2.3.2: +raw-body@2, raw-body@2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" dependencies: @@ -7361,6 +10086,10 @@ react-app-rewired@^1.4.0: cross-spawn "^5.1.0" dotenv "^4.0.0" +react-deep-force-update@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.1.tgz#bcd31478027b64b3339f108921ab520b4313dc2c" + react-dev-utils@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.0.tgz#425ac7c9c40c2603bc4f7ab8836c1406e96bb473" @@ -7390,9 +10119,9 @@ react-dimensions@^1.3.0: dependencies: element-resize-event "^2.0.4" -react-dom@^16.0.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044" +react-dom@^16.3.2: + version "16.3.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.3.2.tgz#cb90f107e09536d683d84ed5d4888e9640e0e4df" dependencies: fbjs "^0.8.16" loose-envify "^1.1.0" @@ -7464,6 +10193,13 @@ react-motion@^0.4.8: prop-types "^15.5.8" raf "^3.1.0" +react-proxy@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a" + dependencies: + lodash "^4.6.1" + react-deep-force-update "^1.0.0" + react-redux@^5.0.6: version "5.0.6" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946" @@ -7590,6 +10326,17 @@ react-test-renderer@^16.0.0-0: object-assign "^4.1.1" prop-types "^15.6.0" +react-transform-catch-errors@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/react-transform-catch-errors/-/react-transform-catch-errors-1.0.2.tgz#1b4d4a76e97271896fc16fe3086c793ec88a9eeb" + +react-transform-hmr@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb" + dependencies: + global "^4.3.0" + react-proxy "^1.1.7" + react-virtualized-select@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/react-virtualized-select/-/react-virtualized-select-3.1.0.tgz#968e89c4d74d98890cacf480378b6abee743c2d8" @@ -7640,7 +10387,7 @@ react-vis@^1.7.2: react-motion "^0.4.8" react-test-renderer "^15.5.4" -"react@^15.6.2 || ^16.0", react@^16.0.0: +"react@^15.6.2 || ^16.0": version "16.2.0" resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba" dependencies: @@ -7649,6 +10396,15 @@ react-vis@^1.7.2: object-assign "^4.1.1" prop-types "^15.6.0" +react@^16.3.2: + version "16.3.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.3.2.tgz#fdc8420398533a1e58872f59091b272ce2f91ea9" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.0" + read-all-stream@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" @@ -7656,6 +10412,18 @@ read-all-stream@^3.0.0: pinkie-promise "^2.0.0" readable-stream "^2.0.0" +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-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" @@ -7677,7 +10445,7 @@ read-pkg-up@^3.0.0: find-up "^2.0.0" read-pkg "^3.0.0" -read-pkg@^1.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: @@ -7701,6 +10469,18 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" +"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.4, readable-stream@^2.1.5, readable-stream@^2.3.0: + version "2.3.6" + resolved "https://registry.yarnpkg.com/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.0: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" @@ -7710,6 +10490,15 @@ readable-stream@1.0: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@1.1.x, "readable-stream@1.x >=1.1.9": + version "1.1.14" + resolved "https://registry.yarnpkg.com/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.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" @@ -7722,6 +10511,17 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" +readable-stream@~2.0.0, readable-stream@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + dependencies: + 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.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -7746,6 +10546,12 @@ recursive-readdir@2.2.1: dependencies: minimatch "3.0.3" +redbox-noreact@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/redbox-noreact/-/redbox-noreact-1.1.0.tgz#970d6f68574dae17554a34d55321057297ac8b37" + dependencies: + error-stack-parser "1.3.6" + redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -7760,6 +10566,22 @@ redent@^2.0.0: indent-string "^3.0.0" strip-indent "^2.0.0" +redis-commands@^1.2.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.5.tgz#4495889414f1e886261180b1442e7295602d83a2" + +redis-parser@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" + +redis@^2.7.1: + version "2.8.0" + resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02" + dependencies: + double-ended-queue "^2.1.0-0" + redis-commands "^1.2.0" + redis-parser "^2.6.0" + reduce-css-calc@^1.2.6: version "1.3.0" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" @@ -7830,6 +10652,10 @@ regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" +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" @@ -7854,6 +10680,13 @@ regex-not@^1.0.0: dependencies: extend-shallow "^2.0.1" +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" + regexpu-core@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" @@ -7915,6 +10748,10 @@ repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" +repeat-string@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae" + 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" @@ -7925,6 +10762,52 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" +request-progress@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-2.0.1.tgz#5d36bb57961c673aa5b788dbc8141fdf23b44e08" + dependencies: + throttleit "^1.0.0" + +request-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.75.x: + version "2.75.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + bl "~1.1.2" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.0.0" + 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" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.2.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + request@2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -7952,6 +10835,33 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" +request@^2.0.0, request@^2.74.0, request@^2.81.0, request@^2.83.0: + version "2.85.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" + 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" + hawk "~6.0.2" + 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" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + request@^2.79.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" @@ -7979,6 +10889,15 @@ request@^2.79.0: tunnel-agent "^0.6.0" uuid "^3.1.0" +requestretry@^1.2.2: + version "1.13.0" + resolved "https://registry.yarnpkg.com/requestretry/-/requestretry-1.13.0.tgz#213ec1006eeb750e8b8ce54176283d15a8d55d94" + dependencies: + extend "^3.0.0" + lodash "^4.15.0" + request "^2.74.0" + when "^3.7.7" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -7987,6 +10906,10 @@ require-from-string@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" +require-from-string@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + 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" @@ -7998,7 +10921,7 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" -requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0: +requires-port@1.0.x, requires-port@1.x.x, requires-port@^1.0.0, requires-port@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -8035,16 +10958,22 @@ 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: +resolve@1.1.7, resolve@1.1.x: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.3.2, resolve@^1.5.0: +resolve@1.5.0, resolve@^1.3.2, resolve@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" dependencies: path-parse "^1.0.5" +resolve@^1.1.3, resolve@^1.1.4, resolve@^1.2.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3" + dependencies: + path-parse "^1.0.5" + restore-cursor@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" @@ -8069,7 +10998,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.0, 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: @@ -8102,6 +11031,20 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-parallel@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.8.tgz#70e4e788f13a1ad9603254f6a2277f3843a5845c" + +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" + +run-series@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/run-series/-/run-series-1.1.4.tgz#89a73ddc5e75c9ef8ab6320c0a1600d6a41179b9" + rx-lite-aggregates@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" @@ -8112,16 +11055,22 @@ rx-lite@*, rx-lite@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" -rxjs@^5.0.0-beta.11: - version "5.4.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.3.tgz#0758cddee6033d68e0fd53676f0f3596ce3d483f" +rxjs@^5.4.2: + version "5.5.10" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.10.tgz#fde02d7a614f6c8683d0d1957827f492e09db045" dependencies: - symbol-observable "^1.0.1" + symbol-observable "1.0.1" safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +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" + samsam@1.x, samsam@^1.1.3: version "1.2.1" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.2.1.tgz#edd39093a3184370cb859243b2bdf255e7d8ea67" @@ -8152,7 +11101,7 @@ sane@~1.6.0: walker "~1.0.5" watch "~0.10.0" -sax@^1.2.1, sax@~1.2.1: +sax@^1.2.1, sax@^1.2.4, sax@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -8162,6 +11111,13 @@ schema-utils@^0.3.0: dependencies: ajv "^5.0.0" +schema-utils@^0.4.0, schema-utils@^0.4.2, schema-utils@^0.4.3: + version "0.4.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -8178,10 +11134,14 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: +"semver@2 || 3 || 4 || 5", semver@5.5.0, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" +semver@~5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" + send@0.16.1: version "0.16.1" resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" @@ -8200,6 +11160,28 @@ send@0.16.1: range-parser "~1.2.0" statuses "~1.3.1" +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" + +serialize-javascript@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" + serve-index@^1.7.2: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -8221,6 +11203,15 @@ serve-static@1.13.1: parseurl "~1.3.2" send "0.16.1" +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" + serviceworker-cache-polyfill@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/serviceworker-cache-polyfill/-/serviceworker-cache-polyfill-4.0.0.tgz#de19ee73bef21ab3c0740a37b33db62464babdeb" @@ -8276,6 +11267,13 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sha.js@~2.4.4: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shallow-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.0.0.tgz#508d1838b3de590ab8757b011b25e430900945f7" @@ -8290,6 +11288,13 @@ shallowequal@^1.0.1, shallowequal@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.0.2.tgz#1561dbdefb8c01408100319085764da3fcf83f8f" +shasum@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/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" @@ -8300,7 +11305,7 @@ 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.6.1: +shell-quote@1.6.1, shell-quote@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" dependencies: @@ -8331,6 +11336,12 @@ sinon@^3.2.1: text-encoding "0.6.4" type-detect "^4.0.0" +slack-node@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/slack-node/-/slack-node-0.2.0.tgz#de4b8dddaa8b793f61dbd2938104fdabf37dfa30" + dependencies: + requestretry "^1.2.2" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -8353,6 +11364,17 @@ slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" +smart-buffer@^1.0.13, smart-buffer@^1.0.4: + version "1.1.15" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16" + +smtp-connection@2.12.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/smtp-connection/-/smtp-connection-2.12.0.tgz#d76ef9127cb23c2259edb1e8349c2e8d5e2d74c1" + dependencies: + httpntlm "1.6.1" + nodemailer-shared "1.1.0" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -8392,6 +11414,47 @@ sntp@2.x.x: dependencies: hoek "4.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.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.4.tgz#0918a552406dc5e540b380dcd97afc4a64332f8e" + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~2.6.4" + engine.io-client "~3.1.0" + 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.1.1" + to-array "0.1.4" + +socket.io-parser@~3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.3.tgz#ed2da5ee79f10955036e3da413bfd7f1e4d86c8e" + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + has-binary2 "~1.0.2" + isarray "2.0.1" + +socket.io@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.0.4.tgz#c1a4590ceff87ecf13c72652f046f716b29e6014" + dependencies: + debug "~2.6.6" + engine.io "~3.1.0" + socket.io-adapter "~1.1.0" + socket.io-client "2.0.4" + socket.io-parser "~3.1.1" + sockjs-client@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" @@ -8410,12 +11473,40 @@ sockjs@0.3.18: faye-websocket "^0.10.0" uuid "^2.0.2" +socks-proxy-agent@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz#86ebb07193258637870e13b7bd99f26c663df3d3" + dependencies: + agent-base "2" + extend "3" + socks "~1.1.5" + +socks@1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.9.tgz#628d7e4d04912435445ac0b6e459376cb3e6d691" + dependencies: + ip "^1.1.2" + smart-buffer "^1.0.4" + +socks@~1.1.5: + version "1.1.10" + resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a" + dependencies: + ip "^1.1.4" + smart-buffer "^1.0.13" + sort-keys@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" dependencies: is-plain-obj "^1.0.0" +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-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" @@ -8436,11 +11527,17 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" +source-map-support@^0.5.0: + version "0.5.4" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8" + dependencies: + 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.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.6: +source-map@0.5.x, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -8450,10 +11547,16 @@ source-map@^0.4.4: dependencies: amdefine ">=0.0.4" -source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, 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" +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + dependencies: + amdefine ">=0.0.4" + spawndamnit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/spawndamnit/-/spawndamnit-1.0.0.tgz#b5d4a1a73016dbcca8f8b1e283eee76a649161b8" @@ -8504,12 +11607,30 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split2@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/split2/-/split2-1.1.1.tgz#162d9b18865f02ab2f2ad9585522db9b54c481f9" + dependencies: + through2 "~2.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@0.2.x: version "0.2.10" resolved "https://registry.yarnpkg.com/split/-/split-0.2.10.tgz#67097c601d697ce1368f418f06cd201cf0521a57" dependencies: through "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" @@ -8528,9 +11649,23 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -staged-git-files@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-0.0.4.tgz#d797e1b551ca7a639dec0237dc6eb4bb9be17d35" +ssri@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" + dependencies: + safe-buffer "^5.1.1" + +stack-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + +stackframe@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4" + +staged-git-files@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.1.tgz#37c2218ef0d6d26178b1310719309a16a59f8f7b" static-extend@^0.1.1: version "0.1.2" @@ -8539,7 +11674,7 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.3.1 < 2": +"statuses@>= 1.3.1 < 2", statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" @@ -8547,17 +11682,45 @@ statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + store@^2.0.12: version "2.0.12" resolved "https://registry.yarnpkg.com/store/-/store-2.0.12.tgz#8c534e2a0b831f72b75fc5f1119857c44ef5d593" -stream-browserify@^2.0.1: +stream-browserify@^2.0.0, stream-browserify@^2.0.1: 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-each@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.0.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.1.tgz#d0441be1a457a73a733a8a7b53570bebd9ef66a4" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.3" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + stream-http@^2.7.2: version "2.8.0" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.0.tgz#fd86546dac9b1c91aff8fc5d287b98fafb41bc10" @@ -8568,14 +11731,40 @@ stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" -stream-to-observable@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +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-to-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10" + dependencies: + any-observable "^0.2.0" + +streamroller@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-0.7.0.tgz#a1d1b7cf83d39afb0d63049a5acbf93493bdf64b" + dependencies: + date-format "^1.2.0" + debug "^3.1.0" + mkdirp "^0.5.1" + readable-stream "^2.3.0" strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + string-convert@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97" @@ -8608,7 +11797,7 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@^1.0.0, string_decoder@~1.0.3: +string_decoder@^1.0.0, string_decoder@~1.0.0, string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" dependencies: @@ -8618,6 +11807,20 @@ string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" +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" + +stringify-object@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.2.tgz#9853052e5a88fb605a44cd27445aa257ad7ffbcd" + dependencies: + get-own-enumerable-property-symbols "^2.0.1" + is-obj "^1.0.1" + is-regexp "^1.0.0" + stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -8662,6 +11865,16 @@ 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" +strong-log-transformer@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-1.0.6.tgz#f7fb93758a69a571140181277eea0c2eb1301fa3" + dependencies: + byline "^5.0.0" + duplexer "^0.1.1" + minimist "^0.1.0" + moment "^2.6.0" + through "^2.3.4" + style-loader@0.19.0: version "0.19.0" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.19.0.tgz#7258e788f0fee6a42d710eaf7d6c2412a4c50759" @@ -8669,11 +11882,30 @@ style-loader@0.19.0: loader-utils "^1.0.2" schema-utils "^0.3.0" +style-loader@0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.20.1.tgz#33ac2bf4d5c65a8906bc586ad253334c246998d0" + dependencies: + loader-utils "^1.1.0" + schema-utils "^0.4.3" + +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@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + dependencies: + has-flag "^2.0.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, supports-color@^3.2.3: +supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: @@ -8691,6 +11923,12 @@ supports-color@^5.1.0: dependencies: has-flag "^2.0.0" +supports-color@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + svgo@^0.7.0: version "0.7.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" @@ -8733,14 +11971,28 @@ sw-toolbox@^3.4.0: path-to-regexp "^1.0.1" serviceworker-cache-polyfill "^4.0.0" -symbol-observable@^1.0.1, symbol-observable@^1.0.3, symbol-observable@^1.0.4: +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@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" + +symbol-observable@^1.0.3, symbol-observable@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" -symbol-tree@^3.2.1: +symbol-tree@^3.2.1, 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.1: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" @@ -8777,6 +12029,28 @@ tar@^2.2.1: fstream "^1.0.2" inherits "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.3.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" + +tempfile@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-1.1.1.tgz#5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2" + dependencies: + os-tmpdir "^1.0.0" + uuid "^2.0.1" + test-exclude@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" @@ -8791,6 +12065,10 @@ text-encoding@0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" +text-extensions@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" + text-table@0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -8803,10 +12081,25 @@ throat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" -through@2, through@2.3.x, through@^2.3.6: +throttleit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" + +through2@^2.0.0, through2@^2.0.2, through2@~2.0.0: + 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.3.x, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" +thunkify@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" + thunky@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-0.1.0.tgz#bf30146824e2b6e67b0f2d7a4ac8beb26908684e" @@ -8819,13 +12112,31 @@ timed-out@^3.0.0: version "3.1.3" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217" +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-browserify@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6" dependencies: setimmediate "^1.0.4" -tmp@^0.0.33: +timespan@2.3.x: + version "2.3.0" + resolved "https://registry.yarnpkg.com/timespan/-/timespan-2.3.0.tgz#4902ce040bd13d845c8f59b27e9d59bad6f39929" + +tmatch@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tmatch/-/tmatch-2.0.1.tgz#0c56246f33f30da1b8d3d72895abaf16660f38cf" + +tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" dependencies: @@ -8835,6 +12146,10 @@ 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" @@ -8868,16 +12183,37 @@ to-regex@^3.0.1: extend-shallow "^2.0.1" regex-not "^1.0.0" +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" + toposort@^1.0.0: version "1.0.6" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" +tough-cookie@>=2.3.3, 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" + tough-cookie@^2.3.2, tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" dependencies: punycode "^1.4.1" +tr46@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -8890,20 +12226,36 @@ 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" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" +tsscmp@~1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.5.tgz#7dc4a33af71581ab4337da91d85ca5427ebd9a97" + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" +tty-browserify@~0.0.0: + 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" + tween-functions@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/tween-functions/-/tween-functions-1.2.0.tgz#1ae3a50e7c60bb3def774eac707acbca73bbc3ff" @@ -8929,7 +12281,14 @@ type-is@~1.6.15: media-typer "0.3.0" mime-types "~2.1.15" -typedarray@^0.0.6: +type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -8941,6 +12300,13 @@ ua-parser-js@^0.7.9: version "0.7.14" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca" +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + uglify-js@3.3.x, uglify-js@^3.0.13: version "3.3.7" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.7.tgz#28463e7c7451f89061d2b235e30925bf5625e14d" @@ -8961,6 +12327,19 @@ uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" +uglifyjs-webpack-plugin@1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.8.tgz#1302fb9471a7daf3d0a5174da6d65f0f415e75ad" + dependencies: + cacache "^10.0.1" + find-cache-dir "^1.0.0" + schema-utils "^0.4.2" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + uglifyjs-webpack-plugin@^0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" @@ -8973,10 +12352,22 @@ uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" +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" + underscore@~1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" +underscore@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" + union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" @@ -9000,6 +12391,18 @@ uniqs@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + universalify@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" @@ -9019,6 +12422,10 @@ unzip-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + update-notifier@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-1.0.3.tgz#8f92c515482bd6831b7c93013e70f87552c7cf5a" @@ -9036,6 +12443,12 @@ upper-case@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" +uri-js@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-3.0.2.tgz#f90b858507f81dea4dcfbb3c4c3dbfa2b557faaa" + dependencies: + punycode "^2.1.0" + urijs@^1.16.1: version "1.19.0" resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.0.tgz#d8aa284d0e7469703a6988ad045c4cbfdf08ada0" @@ -9072,7 +12485,7 @@ url-parse@^1.1.8: querystringify "~1.0.0" requires-port "~1.0.0" -url@^0.11.0: +url@^0.11.0, url@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" dependencies: @@ -9087,6 +12500,17 @@ use@^2.0.0: isobject "^3.0.0" lazy-cache "^2.0.2" +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + +useragent@^2.1.12: + version "2.3.0" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" + dependencies: + lru-cache "4.1.x" + tmp "0.0.x" + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -9098,7 +12522,7 @@ util.promisify@^1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" -util@0.10.3, util@^0.10.3: +util@0.10.3, util@^0.10.3, util@~0.10.1: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" dependencies: @@ -9120,10 +12544,20 @@ uuid@^2.0.1, uuid@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" -uuid@^3.0.0, uuid@^3.1.0: +uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" +uws@~9.14.0: + version "9.14.0" + resolved "https://registry.yarnpkg.com/uws/-/uws-9.14.0.tgz#fac8386befc33a7a3705cbd58dc47b430ca4dd95" + +v8flags@^2.1.1: + 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.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" @@ -9151,12 +12585,26 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vm-browserify@0.0.4: +viz.js@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/viz.js/-/viz.js-1.8.1.tgz#277ab3cf4367c608a95b281a7472083c3e2ee6cf" + +vm-browserify@0.0.4, vm-browserify@~0.0.1: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" dependencies: indexof "0.0.1" +void-elements@^2.0.0: + 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" @@ -9200,15 +12648,21 @@ wbuf@^1.1.0, wbuf@^1.7.2: dependencies: minimalistic-assert "^1.0.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@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" -webidl-conversions@^4.0.0: +webidl-conversions@^4.0.0, webidl-conversions@^4.0.1, webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" -webpack-dev-middleware@^1.11.0: +webpack-dev-middleware@1.12.2, webpack-dev-middleware@^1.11.0, webpack-dev-middleware@^1.12.0: version "1.12.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e" dependencies: @@ -9250,6 +12704,47 @@ webpack-dev-server@2.9.4: webpack-dev-middleware "^1.11.0" yargs "^6.6.0" +webpack-dev-server@2.9.7: + version "2.9.7" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.7.tgz#100ad6a14775478924d417ca6dcfb9d52a98faed" + dependencies: + ansi-html "0.0.7" + array-includes "^3.0.3" + bonjour "^3.5.0" + chokidar "^1.6.0" + compression "^1.5.2" + connect-history-api-fallback "^1.3.0" + debug "^3.1.0" + del "^3.0.0" + express "^4.16.2" + html-entities "^1.2.0" + http-proxy-middleware "~0.17.4" + import-local "^0.1.1" + internal-ip "1.2.0" + ip "^1.1.5" + killable "^1.0.0" + loglevel "^1.4.1" + opn "^5.1.0" + portfinder "^1.0.9" + selfsigned "^1.9.1" + serve-index "^1.7.2" + sockjs "0.3.18" + sockjs-client "1.1.4" + spdy "^3.4.1" + strip-ansi "^3.0.1" + supports-color "^4.2.1" + webpack-dev-middleware "^1.11.0" + yargs "^6.6.0" + +webpack-hot-middleware@2.21.0: + version "2.21.0" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.21.0.tgz#7b3c113a7a4b301c91e0749573c7aab28b414b52" + dependencies: + ansi-html "0.0.7" + html-entities "^1.2.0" + querystring "^0.2.0" + strip-ansi "^3.0.0" + webpack-manifest-plugin@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-1.3.2.tgz#5ea8ee5756359ddc1d98814324fe43496349a7d4" @@ -9257,13 +12752,46 @@ webpack-manifest-plugin@1.3.2: fs-extra "^0.30.0" lodash ">=3.5 <5" -webpack-sources@^1.0.1: +webpack-merge@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.1.tgz#f1197a0a973e69c6fbeeb6d658219aa8c0c13555" + dependencies: + lodash "^4.17.4" + +webpack-sources@^1.0.1, webpack-sources@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" dependencies: source-list-map "^2.0.0" source-map "~0.6.1" +webpack@3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725" + dependencies: + acorn "^5.0.0" + acorn-dynamic-import "^2.0.0" + ajv "^5.1.5" + ajv-keywords "^2.0.0" + async "^2.1.2" + enhanced-resolve "^3.4.0" + escope "^3.6.0" + interpret "^1.0.0" + json-loader "^0.5.4" + json5 "^0.5.1" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + mkdirp "~0.5.0" + node-libs-browser "^2.0.0" + source-map "^0.5.3" + supports-color "^4.2.1" + tapable "^0.2.7" + uglifyjs-webpack-plugin "^0.4.6" + watchpack "^1.4.0" + webpack-sources "^1.0.1" + yargs "^8.0.2" + webpack@3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83" @@ -9302,7 +12830,7 @@ websocket-extensions@>=0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" -whatwg-encoding@^1.0.1: +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" dependencies: @@ -9312,6 +12840,10 @@ whatwg-fetch@2.0.3, whatwg-fetch@>=0.10.0: version "2.0.3" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" +whatwg-mimetype@^2.0.0, whatwg-mimetype@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4" + whatwg-url@^4.3.0: version "4.8.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0" @@ -9319,6 +12851,18 @@ whatwg-url@^4.3.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +whatwg-url@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.0" + webidl-conversions "^4.0.1" + +when@^3.7.7: + version "3.7.8" + resolved "https://registry.yarnpkg.com/when/-/when-3.7.8.tgz#c7130b6a7ea04693e842cdc9e7a1f2aa39a39f82" + whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" @@ -9331,7 +12875,7 @@ which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@^1.2.10, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: +which@^1.1.1, which@^1.2.1, which@^1.2.10, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: @@ -9357,14 +12901,14 @@ wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" +wordwrap@^1.0.0, wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + 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" - worker-farm@^1.3.1: version "1.5.2" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.2.tgz#32b312e5dc3d5d45d79ef44acc2587491cd729ae" @@ -9372,6 +12916,19 @@ worker-farm@^1.3.1: errno "^0.1.4" xtend "^4.0.1" +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + dependencies: + errno "~0.1.7" + +worker-loader@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-1.1.1.tgz#920d74ddac6816fc635392653ed8b4af1929fd92" + dependencies: + loader-utils "^1.0.0" + schema-utils "^0.4.0" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -9391,7 +12948,7 @@ write-file-atomic@^1.1.2: imurmurhash "^0.1.4" slide "^1.1.5" -write-file-atomic@^2.1.0: +write-file-atomic@^2.0.0, write-file-atomic@^2.1.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: @@ -9399,12 +12956,45 @@ write-file-atomic@^2.1.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write-json-file@^2.2.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.1.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.1.0.tgz#030a9994cc9993d25b4e75a9f1a1923607291ce9" + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + 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@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.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" + xdg-basedir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" @@ -9419,7 +13009,19 @@ xml-name-validator@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" -xtend@^4.0.0, xtend@^4.0.1: +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" + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + +xregexp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" + +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" @@ -9427,6 +13029,10 @@ y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" +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" @@ -9529,3 +13135,13 @@ yargs@~3.10.0: cliui "^2.1.0" decamelize "^1.0.0" window-size "0.1.0" + +yauzl@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" + dependencies: + fd-slicer "~1.0.1" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" From db6e33fd5b1a11632eb9e9448d6cd9ddc23343e2 Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Tue, 31 Jul 2018 11:47:37 -0400 Subject: [PATCH 02/10] Typo Signed-off-by: Joe Farro --- .../src/components/TracePage/TraceTimelineViewer/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.js index de33beae86..db10c2650f 100644 --- a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.js +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.js @@ -1,4 +1,4 @@ -git // @flow +// @flow // Copyright (c) 2017 Uber Technologies, Inc. // From 485eefb69da9174113e8601b7c928b56b7a41829 Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Tue, 31 Jul 2018 16:24:55 -0400 Subject: [PATCH 03/10] Fix #232 Split leaf from parent nodes in the tree Signed-off-by: Joe Farro --- .../jaeger-ui/src/model/trace-dag/DagNode.js | 8 ++++---- .../jaeger-ui/src/model/trace-dag/TraceDag.js | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/jaeger-ui/src/model/trace-dag/DagNode.js b/packages/jaeger-ui/src/model/trace-dag/DagNode.js index 6a16689a70..ae8cdb6f7e 100644 --- a/packages/jaeger-ui/src/model/trace-dag/DagNode.js +++ b/packages/jaeger-ui/src/model/trace-dag/DagNode.js @@ -17,8 +17,8 @@ import type { NodeID } from './types'; export default class DagNode { - static getID(service: string, operation: string, parentID?: ?string): NodeID { - const name = `${service}\t${operation}`; + static getID(service: string, operation: string, hasChildren: boolean, parentID?: ?string): NodeID { + const name = `${service}\t${operation}${hasChildren ? '' : '\t__LEAF__'}`; return parentID ? `${parentID}\n${name}` : name; } @@ -30,11 +30,11 @@ export default class DagNode { children: Set; data: T; - constructor(service: string, operation: string, parentID?: ?NodeID, data: T) { + constructor(service: string, operation: string, hasChildren: boolean, parentID?: ?NodeID, data: T) { this.service = service; this.operation = operation; this.parentID = parentID; - this.id = DagNode.getID(service, operation, parentID); + this.id = DagNode.getID(service, operation, hasChildren, parentID); this.count = 0; this.children = new Set(); this.data = data; diff --git a/packages/jaeger-ui/src/model/trace-dag/TraceDag.js b/packages/jaeger-ui/src/model/trace-dag/TraceDag.js index 4606e24bd2..fdb627f706 100644 --- a/packages/jaeger-ui/src/model/trace-dag/TraceDag.js +++ b/packages/jaeger-ui/src/model/trace-dag/TraceDag.js @@ -37,7 +37,10 @@ export default class TraceDag { let key = 'a'; function pushDagNode(src: DagNode) { - const node = dt._getDagNode(src.service, src.operation, src.parentID, { a: 0, b: 0 }); + const node = dt._getDagNode(src.service, src.operation, src.children.size > 0, src.parentID, { + a: 0, + b: 0, + }); const { data } = node; data[key] = src.count; node.count = data.b - data.a; @@ -67,13 +70,19 @@ export default class TraceDag { [...this.denseTrace.rootIDs].forEach(id => this._addDenseSpan(id, null, data)); } - _getDagNode(service: string, operation: string, parentID?: ?NodeID, data: T): DagNode { - const nodeID = DagNode.getID(service, operation, parentID); + _getDagNode( + service: string, + operation: string, + hasChildren: boolean, + parentID?: ?NodeID, + data: T + ): DagNode { + const nodeID = DagNode.getID(service, operation, hasChildren, parentID); let node = this.nodesMap.get(nodeID); if (node) { return node; } - node = new DagNode(service, operation, parentID, data); + node = new DagNode(service, operation, hasChildren, parentID, data); this.nodesMap.set(nodeID, node); if (!parentID) { this.rootIDs.add(nodeID); @@ -95,7 +104,7 @@ export default class TraceDag { const { children, operation, service, skipToChild } = denseSpan; let nodeID: ?string = null; if (!skipToChild) { - const node = this._getDagNode(service, operation, parentNodeID, data); + const node = this._getDagNode(service, operation, children.size > 0, parentNodeID, data); node.count++; nodeID = node.id; } else { From 98f06d62a516f8a3aa70284daccae4bdf3c9175b Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Mon, 6 Aug 2018 18:17:46 -0400 Subject: [PATCH 04/10] plexus - Fix chart style issues and bump version Also tweak the demo a bit. Signed-off-by: Joe Farro --- packages/jaeger-ui/package.json | 2 +- packages/plexus/demo/src/index.css | 18 +++++++++++++----- packages/plexus/demo/src/index.js | 12 ++++++++++-- packages/plexus/package.json | 2 +- .../plexus/src/DirectedGraph/DirectedGraph.js | 13 ++++++++----- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/packages/jaeger-ui/package.json b/packages/jaeger-ui/package.json index 48b1f2e03c..b7712397c1 100644 --- a/packages/jaeger-ui/package.json +++ b/packages/jaeger-ui/package.json @@ -29,7 +29,7 @@ "sinon": "^3.2.1" }, "dependencies": { - "@jaegertracing/plexus": "0.0.1-dev.2", + "@jaegertracing/plexus": "0.0.1-dev.3", "antd": "^3.0.3", "chance": "^1.0.10", "classnames": "^2.2.5", diff --git a/packages/plexus/demo/src/index.css b/packages/plexus/demo/src/index.css index 81b65e4853..09e1d56d54 100644 --- a/packages/plexus/demo/src/index.css +++ b/packages/plexus/demo/src/index.css @@ -3,7 +3,8 @@ html { } .DemoGraph { - border: 1px solid blue; + border: 1px solid #666; + cursor: move; overflow: hidden; height: 500px; width: 800px; @@ -11,21 +12,28 @@ html { } .DemoGraph--dag { - background: #999; + background: #f0f0f0; stroke-width: 1.7; } .DemoGraph--dag.is-small { - stroke-width: 1; + stroke-width: 0.85; } .DemoGraph--node { - background: #fff; - border: 1px solid #666; + background: #bbb; + border: 1px solid #999; box-shadow: 0 0 7px 1px rgba(0, 0, 0, 0.4); + cursor: pointer; padding: 0.8em 1.25em; } +.DemoGraph--node:hover { + background: #666; + color: #fff; + border-color: #333; +} + .DemoGraph--dag.is-small .DemoGraph--nodeLabel { opacity: 0; } diff --git a/packages/plexus/demo/src/index.js b/packages/plexus/demo/src/index.js index 1f2273da72..dc11be464d 100644 --- a/packages/plexus/demo/src/index.js +++ b/packages/plexus/demo/src/index.js @@ -25,8 +25,14 @@ import './index.css'; const { classNameIsSmall } = DirectedGraph.propsFactories; +const ROOT_STYLE = { style: { float: 'left' } }; +const setLargeRootStyle = () => ROOT_STYLE; const addAnAttr = () => ({ 'data-rando': Math.random() }); -const setNodeClassName = () => ({ className: 'DemoGraph--node' }); +const setNodeClassName = vertex => ({ + className: 'DemoGraph--node', + // eslint-disable-next-line no-console + onClick: () => console.log(vertex.key), +}); class Demo extends React.Component { constructor(props) { @@ -41,6 +47,7 @@ class Demo extends React.Component { }); this.largeNeatoLayoutManager = new LayoutManager(); } + render() { return (
@@ -97,7 +104,7 @@ class Demo extends React.Component {

Small graph with data driven rendering

diff --git a/packages/plexus/package.json b/packages/plexus/package.json index f0dd9b78c3..772e90b6be 100644 --- a/packages/plexus/package.json +++ b/packages/plexus/package.json @@ -1,6 +1,6 @@ { "name": "@jaegertracing/plexus", - "version": "0.0.1-dev.2", + "version": "0.0.1-dev.3", "description": "Direct Graph React component", "main": "umd/@jaegertracing/plexus.js", "files": ["lib", "umd"], diff --git a/packages/plexus/src/DirectedGraph/DirectedGraph.js b/packages/plexus/src/DirectedGraph/DirectedGraph.js index f1a0bf7629..784b22c4d6 100644 --- a/packages/plexus/src/DirectedGraph/DirectedGraph.js +++ b/packages/plexus/src/DirectedGraph/DirectedGraph.js @@ -297,6 +297,13 @@ export default class DirectedGraph extends React.PureComponent {layoutGraph && haveEdges && ( - + Date: Mon, 13 Aug 2018 00:43:39 -0400 Subject: [PATCH 05/10] Fix yarn workspace based install Signed-off-by: Joe Farro --- lerna.json | 2 +- package.json | 1 + packages/plexus/package.json | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lerna.json b/lerna.json index 03cfbda637..d1fc74aa9b 100644 --- a/lerna.json +++ b/lerna.json @@ -1,7 +1,7 @@ { "lerna": "2.10.2", - "packages": ["packages/*"], "version": "independent", "npmClient": "yarn", + "npmClientArgs": ["--pure-lockfile"], "useWorkspaces": true } diff --git a/package.json b/package.json index eca60349a3..fae8febd65 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "flow": "glow", "lint": "npm run eslint && npm run prettier && npm run flow && npm run check-license", "precommit": "lint-staged", + "prepare": "lerna run --stream --sort prepublishOnly", "prettier": "prettier --write '{.,scripts}/*.{js,json,md}' 'packages/*/{src,demo/src}/**/*.{css,js,json,md}' 'packages/*/*.{css,js,json,md}'", "test": "lerna run test", diff --git a/packages/plexus/package.json b/packages/plexus/package.json index 772e90b6be..493dcd239d 100644 --- a/packages/plexus/package.json +++ b/packages/plexus/package.json @@ -7,9 +7,10 @@ "scripts": { "build": "nwb build-react-component", "clean": "nwb clean-module && nwb clean-demo", + "coverage": "echo 'NO TESTS YET'", + "prepublishOnly": "nwb build-react-component --no-demo", "start": "nwb serve-react-demo", "test": "echo 'NO TESTS YET'", - "coverage": "echo 'NO TESTS YET'", "test:dev": "nwb test-react --server" }, "dependencies": { From 3e81de9fd706c34ddefe304ca9e639cdf84da7db Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Mon, 13 Aug 2018 00:47:59 -0400 Subject: [PATCH 06/10] In CI, fail if an update to yarn.lock is needed Signed-off-by: Joe Farro --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3eca28fcf3..55ef430144 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ language: node_js node_js: - '6' cache: yarn +install: + - yarn install --frozen-lockfile script: - yarn lint - yarn coverage From 2538fbaf06879927ac36c2582aaa5ad585665a82 Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Mon, 13 Aug 2018 01:09:05 -0400 Subject: [PATCH 07/10] Misc cleanup Signed-off-by: Joe Farro --- packages/jaeger-ui/src/components/App/Page.js | 1 - .../SearchResults/ResultItem.test.js | 8 ++++---- .../SearchTracePage/SearchResults/index.js | 14 +++++--------- .../src/components/SearchTracePage/index.test.js | 4 ++-- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/packages/jaeger-ui/src/components/App/Page.js b/packages/jaeger-ui/src/components/App/Page.js index fc6f697ff9..47fe93fd98 100644 --- a/packages/jaeger-ui/src/components/App/Page.js +++ b/packages/jaeger-ui/src/components/App/Page.js @@ -72,5 +72,4 @@ export function mapStateToProps(state: { router: { location: Location } }) { return { pathname, search }; } -// export default withRouter(connect(mapStateToProps)(PageImpl)); export default withRouter(connect(mapStateToProps)(PageImpl)); diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.test.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.test.js index df79c3a9e2..c25130617a 100644 --- a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.test.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/ResultItem.test.js @@ -30,13 +30,13 @@ it(' should render base case correctly', () => { .first() .render() .text(); - const numberOfServicesTags = wrapper.find(`[data-test="${markers.SERVICE_TAGS}"]`).find(Tag).length; + const serviceTags = wrapper.find(`[data-test="${markers.SERVICE_TAGS}"]`).find(Tag); expect(numberOfSpanText).toBe(`${trace.spans.length} Spans`); - expect(numberOfServicesTags).toBe(trace.services.length); + expect(serviceTags).toHaveLength(trace.services.length); }); it(' should not render any ServiceTags when there are no services', () => { const wrapper = shallow(); - const numberOfServicesTags = wrapper.find(`[data-test="${markers.SERVICE_TAGS}"]`).find(Tag).length; - expect(numberOfServicesTags).toBe(0); + const serviceTags = wrapper.find(`[data-test="${markers.SERVICE_TAGS}"]`).find(Tag); + expect(serviceTags).toHaveLength(0); }); diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.js index b7a9affcd8..bfaa2a670c 100644 --- a/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchResults/index.js @@ -96,18 +96,14 @@ export default class SearchResults extends React.PureComponent {diffCohort.length > 0 && diffSelection} -
- No trace results. Try another query. -
+ {!skipMessage && ( +
+ No trace results. Try another query. +
+ )} ); } diff --git a/packages/jaeger-ui/src/components/SearchTracePage/index.test.js b/packages/jaeger-ui/src/components/SearchTracePage/index.test.js index 0c93ea1275..b5c4630f10 100644 --- a/packages/jaeger-ui/src/components/SearchTracePage/index.test.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/index.test.js @@ -132,10 +132,10 @@ describe('mapStateToProps()', () => { const { maxTraceDuration, traceResults, diffCohort, numberOfTraceResults, ...rest } = mapStateToProps( state ); - expect(traceResults.length).toBe(stateTrace.search.results.length); + expect(traceResults).toHaveLength(stateTrace.search.results.length); expect(traceResults[0].traceID).toBe(trace.traceID); expect(maxTraceDuration).toBe(trace.duration); - expect(diffCohort.length).toBe(state.traceDiff.cohort.length); + expect(diffCohort).toHaveLength(state.traceDiff.cohort.length); expect(diffCohort[0].id).toBe(trace.traceID); expect(diffCohort[0].data.traceID).toBe(trace.traceID); From 088a58f7ef4c81f04859bfe6e86b0337990ccc71 Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Mon, 13 Aug 2018 01:37:14 -0400 Subject: [PATCH 08/10] Use stable yarn in CI Signed-off-by: Joe Farro --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 55ef430144..ce03103125 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ language: node_js node_js: - '6' cache: yarn +before_install: + # update yarn - travis is using an old version + # https://yarnpkg.com/en/docs/install#alternatives-stable + - curl -o- -L https://yarnpkg.com/install.sh | bash install: - yarn install --frozen-lockfile script: From d4c3ead7e01748289121ee5335f3ff01731ce502 Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Mon, 13 Aug 2018 01:39:01 -0400 Subject: [PATCH 09/10] Use yarn in package.json scripts Signed-off-by: Joe Farro --- package.json | 6 +++--- packages/jaeger-ui/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index fae8febd65..05dc0dc24c 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "coverage": "lerna run coverage", "eslint": "eslint 'scripts/*.js' 'packages/*/src/**/*.js' 'packages/*/*.js'", "flow": "glow", - "lint": "npm run eslint && npm run prettier && npm run flow && npm run check-license", + "lint": "yarn run eslint && yarn run prettier && yarn run flow && yarn run check-license", "precommit": "lint-staged", "prepare": "lerna run --stream --sort prepublishOnly", "prettier": @@ -40,7 +40,7 @@ "trailingComma": "es5" }, "lint-staged": { - "*.{css,js,json}": ["npm run lint", "npm run test", "git add"], - "*.md": ["npm run prettier", "git add"] + "*.{css,js,json}": ["yarn run lint", "yarn run test", "git add"], + "*.md": ["yarn run prettier", "git add"] } } diff --git a/packages/jaeger-ui/package.json b/packages/jaeger-ui/package.json index b7712397c1..021afd6575 100644 --- a/packages/jaeger-ui/package.json +++ b/packages/jaeger-ui/package.json @@ -78,7 +78,7 @@ }, "scripts": { "build": "REACT_APP_VSN_STATE=$(../../scripts/get-tracking-version.js) react-app-rewired build", - "coverage": "npm run test -- --coverage", + "coverage": "yarn run test -- --coverage", "start:ga-debug": "REACT_APP_GA_DEBUG=1 REACT_APP_VSN_STATE=$(../../scripts/get-tracking-version.js) react-app-rewired start", "start": "react-app-rewired start", From ee397010469cd1a87e390e666c598120fecc273d Mon Sep 17 00:00:00 2001 From: Joe Farro Date: Mon, 13 Aug 2018 01:44:22 -0400 Subject: [PATCH 10/10] Use newly downloaded yarn in CI Signed-off-by: Joe Farro --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index ce03103125..6f2ad2599c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ language: node_js node_js: - '6' cache: yarn +env: + global: + # so the yarn installed in before_install will be used + - PATH=$HOME/.yarn/bin:$PATH before_install: # update yarn - travis is using an old version # https://yarnpkg.com/en/docs/install#alternatives-stable