From 43d85dc4bafdde36c257e5fcb783e2350beff002 Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Wed, 6 Jan 2021 18:09:42 -0500 Subject: [PATCH 1/6] Add JSON2CSV format converter --- client/README.md | 38 ++- client/checkbuild.sh | 7 +- client/package.json | 14 +- client/platform/desktop/backend/ipcService.ts | 2 +- .../desktop/backend/native/common.spec.ts | 2 +- .../platform/desktop/backend/native/common.ts | 13 +- .../platform/desktop/backend/native/linux.ts | 2 +- .../desktop/backend/native/windows.ts | 2 +- .../desktop/backend/serializers/cli.ts | 46 +++- .../desktop/backend/serializers/viame.ts | 143 +++++++++- client/platform/desktop/backend/server.ts | 2 +- .../platform/desktop/frontend/store/index.ts | 2 +- client/src/track.spec.ts | 41 ++- client/src/track.ts | 15 +- client/src/use/useTrackStore.spec.ts | 1 + client/tsconfig.cli.json | 16 +- client/tsconfig.json | 7 +- client/yarn.lock | 246 +++++++++++------- server/viame_server/serializers/viame.py | 4 +- 19 files changed, 452 insertions(+), 151 deletions(-) diff --git a/client/README.md b/client/README.md index 9c0c03b5e..525063c2e 100644 --- a/client/README.md +++ b/client/README.md @@ -20,23 +20,49 @@ yarn build:web # build vue-media-server library yarn build:lib -# build electron +# Electron +yarn serve:electron yarn build:electron -# lint +# lint and test yarn lint yarn lint:templates +yarn test # Local verification of all tests, linting, builds ./checkbuild.sh +``` + +### CLI Tools + +``` bash +# Build +yarn build:cli + +# Watch +yarn watch:cli + +# Run in development mode +yarn divecli --help + +# Parse VIAME CSV +yarn divecli viame2json /path/to/viame.csv + +# Parse DIVE JSON +yarn divecli json2viame /path/to/results.json /path/to/meta.json -# Parser CLI tools -yarn serialize viame /path/to/viame.csv # output to file, suppress yarn's stdout -yarn --silent serialize viame /path/to/viame.csv > tracks.json +yarn --silent divecli viame2json /path/to/viame.csv > tracks.json ``` -See [this issue](https://github.com/vuejs/vue-cli/issues/3065) for details on why our `yarn serve` command is weird. +Configuration abnormalities: + +> **Note** tsconfig.cli.json is used to build the cli. It's necessary to specify the exact files along the import path of the cli.js entrypoint, and if new files are added, they will need to be added manually. Build errors should alert you to this. + +* `tsconfig.json`: `{ target: 'es2018' }` used because renderer/web uses babel but background does not, and [webpack doesn't support esnext](https://stackoverflow.com/questions/58813176/webpack-cant-compile-ts-3-7-optional-chaining-nullish-coalescing) +* [acorn unexpected token webpack issue (unused, just useful)](https://github.com/webpack/webpack/issues/10227) +* [Why our yarn serve is weird](https://github.com/vuejs/vue-cli/issues/3065) +* [Typescript Absolute -> Relative Paths](https://github.com/microsoft/TypeScript/issues/15479) ## Publishing diff --git a/client/checkbuild.sh b/client/checkbuild.sh index 3a7067caa..980c3e6ab 100755 --- a/client/checkbuild.sh +++ b/client/checkbuild.sh @@ -8,11 +8,14 @@ set -e # exit immediately on fail yarn install --frozen-lockfile -yarn test & +yarn test + yarn lint & -yarn lint:templates & +yarn lint:templates + yarn build:web & yarn build:electron & yarn build:lib & +yarn build:cli & time wait diff --git a/client/package.json b/client/package.json index da9b2d1d5..5d471aa1d 100644 --- a/client/package.json +++ b/client/package.json @@ -13,11 +13,12 @@ "build:web": "vue-cli-service build platform/web-girder/main.ts", "build:electron": "vue-cli-service electron:build", "build:lib": "rollup -c", - "build:cli": "tsc -p tsconfig.cli.json", + "build:cli": "tsc -b tsconfig.cli.json && tsc-alias -p tsconfig.cli.json", + "dev:cli": "tsc -w -p tsconfig.cli.json & tsc-alias -w -p tsconfig.cli.json", + "divecli": "node ./bin/platform/desktop/backend/serializers/cli.js", "lint": "vue-cli-service lint src/ viame-web-common/ platform/", "lint:templates": "vtc --workspace . --srcDir src/", - "test": "vue-cli-service test:unit src/ viame-web-common/ platform/", - "serialize": "ts-node --project tsconfig.cli.json platform/desktop/backend/serializers/cli.ts" + "test": "vue-cli-service test:unit src/ viame-web-common/ platform/" }, "resolutions": { "@types/jest": "^25.2.3" @@ -27,7 +28,7 @@ "/lib/" ], "bin": { - "viamecli": "./bin/platform/desktop/backend/serializers/cli.js" + "divecli": "./bin/platform/desktop/backend/serializers/cli.js" }, "main": "lib/index.js", "types": "lib/types/index.d.ts", @@ -42,6 +43,7 @@ "@vue/composition-api": "^1.0.0-beta.18", "axios": "^0.19.2", "core-js": "^3.6.4", + "csv-stringify": "^5.6.0", "d3": "^5.12.0", "geojs": "^0.20.0", "lodash": "^4.17.19", @@ -71,7 +73,6 @@ "@types/range-parser": "^1.2.3", "@types/request": "^2.48.5", "@types/resize-observer-browser": "^0.1.4", - "@types/xml2json": "^0.11.3", "@typescript-eslint/eslint-plugin": "^2.33.0", "@typescript-eslint/parser": "^2.33.0", "@vue/cli-plugin-babel": "~4.3.1", @@ -112,7 +113,7 @@ "sass": "^1.26.3", "sass-loader": "^8.0.2", "ts-jest": "^26.0.0", - "ts-node": "^9.0.0", + "tsc-alias": "^1.2.0", "typescript": "~3.8.3", "vue-cli-plugin-electron-builder": "^2.0.0-beta.5", "vue-cli-plugin-vuetify": "^2.0.5", @@ -121,7 +122,6 @@ "vue-type-check": "^1.0.0", "vuetify-loader": "^1.4.3", "xml-js": "^1.6.11", - "xml2json": "^0.12.0", "yargs": "^16.1.0" }, "jest": { diff --git a/client/platform/desktop/backend/ipcService.ts b/client/platform/desktop/backend/ipcService.ts index c5ad3eb96..6040a6cfc 100644 --- a/client/platform/desktop/backend/ipcService.ts +++ b/client/platform/desktop/backend/ipcService.ts @@ -6,7 +6,7 @@ import { DesktopJobUpdate, RunPipeline, Settings } from 'platform/desktop/consta import linux from './native/linux'; import win32 from './native/windows'; -import common from './native/common'; +import * as common from './native/common'; import settings from './state/settings'; import { listen } from './server'; diff --git a/client/platform/desktop/backend/native/common.spec.ts b/client/platform/desktop/backend/native/common.spec.ts index 3f822e660..f6976d83e 100644 --- a/client/platform/desktop/backend/native/common.spec.ts +++ b/client/platform/desktop/backend/native/common.spec.ts @@ -6,7 +6,7 @@ import { Console } from 'console'; import type { JsonMeta, Settings } from 'platform/desktop/constants'; -import common from './common'; +import * as common from './common'; const pipelines = { 'classify_detections_svm.pipe': '', diff --git a/client/platform/desktop/backend/native/common.ts b/client/platform/desktop/backend/native/common.ts index 91d32d649..fbb15888e 100644 --- a/client/platform/desktop/backend/native/common.ts +++ b/client/platform/desktop/backend/native/common.ts @@ -9,12 +9,12 @@ import moment from 'moment'; import { DatasetType, MultiTrackRecord, Pipelines, SaveDetectionsArgs, FrameImage, DatasetMetaMutable, } from 'viame-web-common/apispec'; +import * as viameSerializers from 'platform/desktop/backend/serializers/viame'; import { websafeImageTypes, websafeVideoTypes, otherImageTypes, JsonMeta, Settings, JsonMetaCurrentVersion, DesktopMetadata, } from 'platform/desktop/constants'; -import * as viameSerializers from 'platform/desktop/backend/serializers/viame'; import { cleanString, makeid } from './utils'; @@ -107,10 +107,10 @@ async function loadJsonMetadata(metaAbsPath: string): Promise { } /** - * _loadJsonTracks load from file + * loadJsonTracks load from file * @param tracksPath a known, existing path */ -async function _loadJsonTracks(tracksAbsPath: string): Promise { +async function loadJsonTracks(tracksAbsPath: string): Promise { const rawBuffer = await fs.readFile(tracksAbsPath, 'utf-8'); const annotationData = JSON.parse(rawBuffer) as MultiTrackRecord; // TODO: somehow verify the schema of this file @@ -160,7 +160,7 @@ async function loadMetadata( async function loadDetections(settings: Settings, datasetId: string) { const projectDirData = await getValidatedProjectDir(settings, datasetId); - return _loadJsonTracks(projectDirData.trackFileAbsPath); + return loadJsonTracks(projectDirData.trackFileAbsPath); } /** @@ -257,7 +257,7 @@ async function _saveSerialized( async function saveDetections(settings: Settings, datasetId: string, args: SaveDetectionsArgs) { /* Update existing track file */ const projectDirInfo = await getValidatedProjectDir(settings, datasetId); - const existing = await _loadJsonTracks(projectDirInfo.trackFileAbsPath); + const existing = await loadJsonTracks(projectDirInfo.trackFileAbsPath); args.delete.forEach((trackId) => delete existing[trackId.toString()]); args.upsert.forEach((track) => { existing[track.trackId.toString()] = track; @@ -466,7 +466,7 @@ async function openLink(url: string) { shell.openExternal(url); } -export default { +export { createKwiverRunWorkingDir, getPipelineList, getProjectDir, @@ -474,6 +474,7 @@ export default { importMedia, loadMetadata, loadJsonMetadata, + loadJsonTracks, loadDetections, openLink, processOtherAnnotationFiles, diff --git a/client/platform/desktop/backend/native/linux.ts b/client/platform/desktop/backend/native/linux.ts index 193b115b9..46817ecd6 100644 --- a/client/platform/desktop/backend/native/linux.ts +++ b/client/platform/desktop/backend/native/linux.ts @@ -13,7 +13,7 @@ import { NvidiaSmiReply, } from 'platform/desktop/constants'; -import common from './common'; +import * as common from './common'; const DefaultSettings: Settings = { // The current settings schema config diff --git a/client/platform/desktop/backend/native/windows.ts b/client/platform/desktop/backend/native/windows.ts index 348fca78a..b0f9a011d 100644 --- a/client/platform/desktop/backend/native/windows.ts +++ b/client/platform/desktop/backend/native/windows.ts @@ -13,7 +13,7 @@ import { NvidiaSmiReply, } from 'platform/desktop/constants'; -import common from './common'; +import * as common from './common'; const DefaultSettings: Settings = { // The current settings schema config diff --git a/client/platform/desktop/backend/serializers/cli.ts b/client/platform/desktop/backend/serializers/cli.ts index 63e3e9cd5..ac79029e1 100755 --- a/client/platform/desktop/backend/serializers/cli.ts +++ b/client/platform/desktop/backend/serializers/cli.ts @@ -5,26 +5,60 @@ * Command-line entrypoints into serializers and other tooling. * See README.md for usage */ +import { Writable } from 'stream'; +import { stdout } from 'process'; import yargs from 'yargs'; -import { parseFile } from './viame'; +// Improper relative paths used because CLI won't work with path aliases +// https://github.com/TypeStrong/ts-node/issues/422 +import { loadJsonTracks, loadJsonMetadata } from 'platform/desktop/backend/native/common'; +import { parseFile, serialize } from './viame'; + +// https://stackoverflow.com/questions/21491567/how-to-implement-a-writable-stream +function echoStream() { + return new Writable({ + write(chunk, encoding, next) { + stdout.write(chunk.toString()); + next(); + }, + }); +} async function parseViameFile(file: string) { const tracks = await parseFile(file); - // eslint-disable-next-line no-console - console.log(JSON.stringify(tracks)); + stdout.write(JSON.stringify(tracks)); +} + +async function parseJsonFile(filepath: string, metapath: string) { + await Promise.all([ + loadJsonTracks(filepath), + loadJsonMetadata(metapath), + ]).then(([input, meta]) => serialize(echoStream(), input, meta)); } const { argv } = yargs - .command('viame [file]', 'Parse VIAME CSV', (y) => { + .command('viame2json [file]', 'Convert VIAME CSV to JSON', (y) => { + y.positional('file', { + description: 'The file to parse', + type: 'string', + }).demandOption('file'); + }) + .command('json2viame [file] [meta]', 'Convert JSON to VIAME CSV', (y) => { y.positional('file', { description: 'The file to parse', type: 'string', - }); + }).demandOption('file'); + y.positional('meta', { + description: 'The metadata to parse', + type: 'string', + }).demandOption('meta'); }) .help(); -if (argv._.includes('viame')) { +if (argv._.includes('viame2json')) { parseViameFile(argv.file as string); } +if (argv._.includes('json2viame')) { + parseJsonFile(argv.file as string, argv.meta as string); +} diff --git a/client/platform/desktop/backend/serializers/viame.ts b/client/platform/desktop/backend/serializers/viame.ts index 14ac174e6..33e5038c1 100644 --- a/client/platform/desktop/backend/serializers/viame.ts +++ b/client/platform/desktop/backend/serializers/viame.ts @@ -4,10 +4,18 @@ */ import csvparser from 'csv-parse'; +import csvstringify from 'csv-stringify'; import fs from 'fs-extra'; -import { pipeline } from 'stream'; +import moment from 'moment'; +import { flattenDeep } from 'lodash'; +import { pipeline, Readable, Writable } from 'stream'; -import { +import { MultiTrackRecord } from 'viame-web-common/apispec'; +import { JsonMeta } from 'platform/desktop/constants'; + +// Imports that involve actual code require relative imports because ts-node barely works +// https://github.com/TypeStrong/ts-node/issues/422 +import Track, { TrackData, Feature, StringKeyObject, ConfidencePair, TrackSupportedFeature, } from 'vue-media-annotator/track'; @@ -18,6 +26,11 @@ const AttrRegex = /^\(atr\) (.*?)\s(.+)/g; const TrackAttrRegex = /^\(trk-atr\) (.*?)\s(.+)/g; const PolyRegex = /^(\(poly\)) ((?:[0-9]+\.*[0-9]*\s*)+)/g; +const AtrToken = '(atr)'; +const TrackAtrToken = '(trk-atr)'; +const PolyToken = '(poly)'; +const KeypointToken = '(kp)'; + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll function getCaptureGroups(regexp: RegExp, str: string) { const iterable = str.matchAll(regexp); @@ -200,7 +213,7 @@ function _parseFeature(row: string[]) { }; } -async function parse(input: fs.ReadStream): Promise { +async function parse(input: Readable): Promise { const parser = csvparser({ delimiter: ',', // comment lines may not have the correct number of columns @@ -269,12 +282,128 @@ async function parseFile(path: string): Promise { return parse(stream); } -// function serialize(data: TrackData[]): string[] { -// return []; -// } +async function writeHeader(writer: Writable, meta: JsonMeta) { + writer.write([ + '# 1: Detection or Track-id', + '2: Video or Image Identifier', + '3: Unique Frame Identifier', + '4-7: Img-bbox(TL_x', + 'TL_y', + 'BR_x', + 'BR_y)', + '8: Detection or Length Confidence', + '9: Target Length (0 or -1 if invalid)', + '10-11+: Repeated Species', + 'Confidence Pairs or Attributes', + ]); + if (meta.fps) { + writer.write([`#meta fps=${meta.fps}`]); + } + writer.write( + [`# Written on ${(new Date()).toLocaleString()} by dive_csv_writer:typescript`], + ); +} + +async function serialize( + stream: Writable, + data: MultiTrackRecord, + meta: JsonMeta, + options = { + excludeBelowThreshold: false, + header: true, + }, +): Promise { + const stringify = csvstringify(); + return new Promise((resolve, reject) => { + pipeline(stringify, stream, (err) => { + // undefined err indicates successful exit + if (err !== undefined) { + reject(err); + } + resolve(); + }); + writeHeader(stringify, meta); + Object.values(data).forEach((track) => { + const filters = meta.confidenceFilters || {}; + if (!options.excludeBelowThreshold + || Track.trackExceedsThreshold(track.confidencePairs, filters) + ) { + const sortedPairs = track.confidencePairs.sort((a, b) => a[1] - b[1]); + track.features.forEach((keyframeFeature, index) => { + const interpolatedFeatures = [keyframeFeature]; + + /* If this is not the final keyframe and interpolation is enabled */ + if (keyframeFeature.interpolate && keyframeFeature.frame < track.end) { + const nextFeature = track.features[index + 1]; + /* Interpolate all features (a, b) NOT INCLUDING a or b */ + for (let f = keyframeFeature.frame + 1; f < nextFeature.frame; f += 1) { + const interpolated = Track.interpolate(f, keyframeFeature, nextFeature); + if (interpolated === null) { + throw new Error('null interpolated track should be impossible here'); + } + interpolatedFeatures.push(interpolated); + } + } + + /* Iterate all features (real and interpolated) */ + interpolatedFeatures.forEach((feature) => { + /* Column 2 is timestamp in video, image name in image sequence */ + let column2 = ''; + if (meta.type === 'image-sequence') { + column2 = meta.originalImageFiles[feature.frame]; + } else if (meta.type === 'video') { + column2 = moment.utc(feature.frame / meta.fps).format('H:M:S.SSS'); + } + + const row = [ + track.trackId, + column2, + feature.frame, + ...(feature.bounds as number[]), + sortedPairs[0][1], + feature.fishLength || -1, + ...flattenDeep(sortedPairs), + ]; + + /* Feature Attributes */ + Object.entries(feature.attributes || {}).forEach(([key, val]) => { + row.push(`${AtrToken} ${key} ${val}`); + }); + + /* Track Attributes */ + Object.entries(track.attributes).forEach(([key, val]) => { + row.push(`${TrackAtrToken} ${key} ${val}`); + }); + + /* Geometry */ + if (feature.geometry && feature.geometry.type === 'FeatureCollection') { + feature.geometry.features.forEach((geoJSONFeature) => { + if (geoJSONFeature.geometry.type === 'Polygon') { + const coordinates = flattenDeep(geoJSONFeature.geometry.coordinates[0]); + row.push(`${PolyToken} ${coordinates.map(Math.round).join(' ')}`); + } else if (geoJSONFeature.geometry.type === 'Point') { + if (geoJSONFeature.properties) { + const kpname = geoJSONFeature.properties.name; + const { coordinates } = geoJSONFeature.geometry; + row.push( + `${KeypointToken} ${kpname} ${coordinates.map(Math.round).join(' ')}`, + ); + } + } + /* TODO support for multiple GeoJSON Objects of the same type */ + }); + } + + stringify.write(row); + }); + }); + } + }); + }); +} export { parse, parseFile, - // serialize, + serialize, }; diff --git a/client/platform/desktop/backend/server.ts b/client/platform/desktop/backend/server.ts index 443b86ce7..ba1378db9 100644 --- a/client/platform/desktop/backend/server.ts +++ b/client/platform/desktop/backend/server.ts @@ -11,7 +11,7 @@ import fs from 'fs-extra'; import { SaveDetectionsArgs } from 'viame-web-common/apispec'; import settings from './state/settings'; -import common from './native/common'; +import * as common from './native/common'; const app = express(); const apirouter = express.Router(); diff --git a/client/platform/desktop/frontend/store/index.ts b/client/platform/desktop/frontend/store/index.ts index e8f239c5e..bebeef72f 100644 --- a/client/platform/desktop/frontend/store/index.ts +++ b/client/platform/desktop/frontend/store/index.ts @@ -2,7 +2,7 @@ import { Api, Pipe } from 'viame-web-common/apispec'; import * as api from 'platform/desktop/frontend/api'; /* Warning, this import involves node.js code for loadDetections (below) */ -import common from 'platform/desktop/backend/native/common'; +import * as common from 'platform/desktop/backend/native/common'; import { settings } from './settings'; import { getRecents, setRecents, RecentsKey } from './dataset'; diff --git a/client/src/track.spec.ts b/client/src/track.spec.ts index a3ac2b077..398cb4440 100644 --- a/client/src/track.spec.ts +++ b/client/src/track.spec.ts @@ -1,7 +1,7 @@ /// import Vue from 'vue'; import CompositionApi from '@vue/composition-api'; -import Track, { TrackData } from './track'; +import Track, { ConfidencePair, TrackData } from './track'; import { RectBounds } from './utils'; Vue.use(CompositionApi); @@ -73,6 +73,9 @@ describe('Track', () => { expect(f4).toStrictEqual([null, null, feature]); expect(track.begin).toBe(3); expect(track.end).toBe(3); + expect(() => track.setFeature({ + frame: 4, + })).toThrow('must be called with keyframe'); }); it('should fail to initialize with non-sparse array', () => { @@ -88,3 +91,39 @@ describe('Track', () => { })).toThrowError(); }); }); + +describe('trackExceedsThreshold', () => { + it('correctly determine if a confidence pair set exceeds any thresholds', () => { + const pairs: ConfidencePair[] = [ + ['foo', 0.05], + ['bar', 0.1], + ['baz', 0.1000001], + ]; + expect(Track.trackExceedsThreshold(pairs, { + default: 0.1, + })).toEqual([ + ['bar', 0.1], + ['baz', 0.1000001], + ]); + expect(Track.trackExceedsThreshold(pairs, { + default: 2, + })).toEqual([]); + expect(Track.trackExceedsThreshold(pairs, { + default: 0.1, + baz: 0.2, + })).toEqual([ + ['bar', 0.1], + ]); + expect(Track.trackExceedsThreshold(pairs, { + bar: 0.2, + })).toEqual([ + ['foo', 0.05], + ['baz', 0.1000001], + ]); + }); + it('other edge cases', () => { + expect(Track.trackExceedsThreshold([], {})).toEqual([]); + expect(Track.trackExceedsThreshold([['foo', 1]], {})).toEqual([['foo', 1]]); + expect(Track.trackExceedsThreshold([['foo', 0]], {})).toEqual([['foo', 0]]); + }); +}); diff --git a/client/src/track.ts b/client/src/track.ts index 911e31c79..a805c660a 100644 --- a/client/src/track.ts +++ b/client/src/track.ts @@ -259,9 +259,10 @@ export default class Track { Math.round(feature.bounds[3]), ]; } - if (feature.keyframe) { - listInsert(this.featureIndex, feature.frame); + if (!this.features[feature.frame].keyframe) { + throw new Error('setFeature must be called with keyframe=true OR to update an existing keyframe'); } + listInsert(this.featureIndex, feature.frame); const fg = this.features[feature.frame].geometry || { type: 'FeatureCollection', features: [] }; geometry.forEach((geo) => { const i = fg.features @@ -485,4 +486,14 @@ export default class Track { }); return track; } + + /** + * Figure out if any confidence pairs are above any corresponding thresholds + */ + static trackExceedsThreshold( + pairs: Array, thresholds: Record, + ): Array { + const defaultThresh = thresholds.default || 0; + return pairs.filter(([name, value]) => value >= (thresholds[name] || defaultThresh)); + } } diff --git a/client/src/use/useTrackStore.spec.ts b/client/src/use/useTrackStore.spec.ts index ac061f9cf..fc525c84d 100644 --- a/client/src/use/useTrackStore.spec.ts +++ b/client/src/use/useTrackStore.spec.ts @@ -73,6 +73,7 @@ describe('useTrackStore', () => { called = false; track.setFeature({ + keyframe: true, frame: 0, }); await Vue.nextTick(); diff --git a/client/tsconfig.cli.json b/client/tsconfig.cli.json index 5c89d65ab..9beb2ef01 100644 --- a/client/tsconfig.cli.json +++ b/client/tsconfig.cli.json @@ -1,12 +1,20 @@ { "extends": "./tsconfig.json", "compilerOptions": { - /* Jest requires es5, not sure why */ - "target": "ES2017", + "target": "es2017", "module": "commonjs", "outDir": "./bin", + "declaration": true, + "declarationDir": "./bin/types", }, "include": [ - "platform/desktop/backend/serializers/cli.ts", - ], + "platform/desktop/backend/serializers/*.ts", + "platform/desktop/backend/serializers/*.ts", + "platform/desktop/backend/common/*.ts", + "viame-web-common/apispec.ts", + "src/@types/*.ts", + "src/track.ts", + "src/utils.ts", + "src/listUtils.ts" + ] } diff --git a/client/tsconfig.json b/client/tsconfig.json index 9056e76eb..566151eb6 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "esnext", + "target": "es2018", "module": "esnext", "strict": true, "jsx": "preserve", @@ -22,7 +22,10 @@ ], "viame-web-common/*": [ "viame-web-common/*" - ] + ], + "platform": [ + "platform/*" + ], }, "lib": [ "ES2017.Object", diff --git a/client/yarn.lock b/client/yarn.lock index dad99334f..5c2817bb0 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -1525,6 +1525,20 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jfonx/console-utils@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@jfonx/console-utils/-/console-utils-1.0.3.tgz#cbb7f911e4191a4a2fe1ba4807d29f100b5d099f" + integrity sha512-/XbnqjWc7yNZVLAJJO9rimfIz9DYte+cj3EF9hwhIv7vw6ok2t3cjl0huYsmD89srKH03vWjeqAcIH86CuYj3g== + dependencies: + colors "^1.3.3" + +"@jfonx/file-utils@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@jfonx/file-utils/-/file-utils-1.0.0.tgz#2d3d5d9978a23a05f8de6dc8164c2ee3b565149a" + integrity sha512-+gqUMbScweBpWKoQGlERJgqFH1jtWwVCqRMCpHLvJyHRTxxoNIdjdeQM+c/iv9ExRYNBU/mJgCjFYbCte6U9bw== + dependencies: + "@jfonx/console-utils" "^1.0.3" + "@mdi/font@^3.9.97": version "3.9.97" resolved "https://registry.yarnpkg.com/@mdi/font/-/font-3.9.97.tgz#b9f31e05574452e84f57e5b81d34ffd593bc9c29" @@ -2400,13 +2414,6 @@ resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.2.tgz#927997342bb9f4a5185a86e6579a0a18afc33b0a" integrity sha512-67ZgZpAlhIICIdfQrB5fnDvaKFcDxpKibxznfYRVAT4mQE41Dido/3Ty+E3xGBmTogc5+0Qb8tWhna+5B8z1iQ== -"@types/xml2json@^0.11.3": - version "0.11.3" - resolved "https://registry.yarnpkg.com/@types/xml2json/-/xml2json-0.11.3.tgz#c0fb144d61753c1e0f54aee750608b00184d3241" - integrity sha512-iuN41kDZvCGfr43ra1WizAZl2y+0v1z9UPf93B9g4629F9jaA6CZywx80GZwqosS2e7aGZEGIaU1DeU0sKFEZw== - dependencies: - "@types/node" "*" - "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" @@ -3082,20 +3089,15 @@ acorn@^5.5.0, acorn@^5.5.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== -acorn@^6.0.1, acorn@^6.2.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== - -acorn@^6.0.2, acorn@^6.0.7, acorn@^6.4.1: +acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.2.1, acorn@^6.4.1: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== acorn@^7.1.0, acorn@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" - integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== address@^1.1.2: version "1.1.2" @@ -3327,11 +3329,6 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -4627,6 +4624,21 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" +chokidar@^3.0.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.0.tgz#458a4816a415e9d3b3caa4faec2b96a6935a9e65" + integrity sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + chokidar@^3.0.2, chokidar@^3.4.1: version "3.4.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" @@ -4945,6 +4957,11 @@ color@^3.0.0: color-convert "^1.9.1" color-string "^1.5.2" +colors@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + columnify@1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" @@ -5547,6 +5564,11 @@ csv-parse@*, csv-parse@^4.13.1: resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.13.1.tgz#63cd8317847a3dadc139cb911fba4acf7e4ef0f5" integrity sha512-5up4YofuK2EGBYlEsEKeTvgJhBnqorrNrLsgQgv9+1lLbDEEqZhtPzxDmqmVV7rrZ+hd1QHnuK0a0IKeTpMvSA== +csv-stringify@^5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.6.0.tgz#3dcde51da7561f5052220f1847bfd4db7618fcfa" + integrity sha512-E0LNLevBrwaJ1WKsl4HUPOmK96WyhizTfY79mJgfr2dsIb6zyJd3B9+lToO7gSkTaKi8CIo0Pd0vDGfa0whozg== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -6036,6 +6058,11 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" @@ -7073,6 +7100,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + expect@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" @@ -7408,6 +7442,14 @@ find-cache-dir@^3.0.0, find-cache-dir@^3.2.0, find-cache-dir@^3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-node-modules@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.1.0.tgz#d9179cd1abd517622353f766da0807f912d21b06" + integrity sha512-aMVxgoGzmZQFzqouGzKpc573hAB7LVe/0ADEqE9GZIOd81dgYA+FD2nmYZy2ELdoEx9nBTdQGzDidhy9R0UX4Q== + dependencies: + findup-sync "^4.0.0" + merge "^1.2.1" + find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" @@ -7443,6 +7485,16 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +findup-sync@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" + integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^4.0.2" + resolve-dir "^1.0.1" + flat-cache@^1.2.1: version "1.3.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" @@ -7641,6 +7693,11 @@ fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== +fsevents@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" + integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== + fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" @@ -7883,6 +7940,26 @@ global-dirs@^2.0.1: dependencies: ini "^1.3.5" +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + global-tunnel-ng@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f" @@ -8226,21 +8303,6 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoek@5.x.x: - version "5.0.4" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.4.tgz#0f7fa270a1cafeb364a4b2ddfaa33f864e4157da" - integrity sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w== - -hoek@6.x.x: - version "6.1.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.3.tgz#73b7d33952e01fe27a38b0457294b79dd8da242c" - integrity sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ== - -hoek@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" - integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA== - home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -8249,6 +8311,13 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + hoopy@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" @@ -9147,7 +9216,7 @@ is-whitespace@^0.3.0: resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" integrity sha1-Fjnssb4DauxppUy7QBz77XEUq38= -is-windows@^1.0.2: +is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== @@ -9177,13 +9246,6 @@ isbinaryfile@^4.0.6: resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.6.tgz#edcb62b224e2b4710830b67498c8e4e5a4d2610b" integrity sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg== -isemail@3.x.x: - version "3.2.0" - resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" - integrity sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg== - dependencies: - punycode "2.x.x" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -10085,15 +10147,6 @@ jest@^26.0.1: import-local "^3.0.2" jest-cli "^26.0.1" -joi@^13.1.2: - version "13.7.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-13.7.0.tgz#cfd85ebfe67e8a1900432400b4d03bbd93fb879f" - integrity sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q== - dependencies: - hoek "5.x.x" - isemail "3.x.x" - topo "3.x.x" - jquery@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5" @@ -10867,7 +10920,7 @@ make-dir@^3.0.2: dependencies: semver "^6.0.0" -make-error@1.x, make-error@^1.1.1: +make-error@1.x: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -11043,6 +11096,11 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== +merge@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -11405,14 +11463,6 @@ node-cache@^4.1.1: clone "2.x" lodash "^4.17.15" -node-expat@^2.3.18: - version "2.3.18" - resolved "https://registry.yarnpkg.com/node-expat/-/node-expat-2.3.18.tgz#d9e6949cecda15e131f14259b73dc7b9ed7bc560" - integrity sha512-9dIrDxXePa9HSn+hhlAg1wXkvqOjxefEbMclGxk2cEnq/Y3U7Qo5HNNqeo3fQ4bVmLhcdt3YN1TZy7WMZy4MHw== - dependencies: - bindings "^1.5.0" - nan "^2.13.2" - node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -12125,6 +12175,11 @@ parse-json@^5.0.0: json-parse-better-errors "^1.0.1" lines-and-columns "^1.1.6" +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + parse5-htmlparser2-tree-adapter@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-5.1.1.tgz#e8c743d4e92194d5293ecde2b08be31e67461cbc" @@ -13109,16 +13164,16 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@2.x.x, punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - punycode@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + pupa@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" @@ -13683,6 +13738,14 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" @@ -14438,7 +14501,7 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" -source-map-support@^0.5.17, source-map-support@^0.5.19, source-map-support@^0.5.6: +source-map-support@^0.5.19, source-map-support@^0.5.6: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -15383,13 +15446,6 @@ token-stream@0.0.1: resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" integrity sha1-zu78cXp2xDFvEm0LnbqlXX598Bo= -topo@3.x.x: - version "3.0.3" - resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" - integrity sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ== - dependencies: - hoek "6.x.x" - toposort@^1.0.0: version "1.0.7" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" @@ -15518,22 +15574,24 @@ ts-loader@^6.2.2: micromatch "^4.0.0" semver "^6.0.0" -ts-node@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.0.0.tgz#e7699d2a110cc8c0d3b831715e417688683460b3" - integrity sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg== - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== +tsc-alias@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tsc-alias/-/tsc-alias-1.2.0.tgz#5fb35147d4452a0afda519e0200e8af78920e5c1" + integrity sha512-0ukUfVHR9ij4icfvPg7z6GOD/vRWTd67diEY5Nx9+kmSfanCoCInUFxjnglFiMjcav3N+Aoua3m/2+KbflA/bQ== + dependencies: + "@jfonx/console-utils" "^1.0.3" + "@jfonx/file-utils" "^1.0.0" + chokidar "^3.0.0" + commander "^2.19.0" + find-node-modules "^2.1.0" + globby "^9.2.0" + normalize-path "^3.0.0" + tsconfig-paths@^3.9.0: version "3.9.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" @@ -16960,7 +17018,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1, which@^1.2.9, which@^1.3.0: +which@1, which@^1.2.14, which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -17175,15 +17233,6 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -xml2json@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/xml2json/-/xml2json-0.12.0.tgz#b2ae450b267033b76d896f86e022fa7bff678572" - integrity sha512-EPJHRWJnJUYbJlzR4pBhZODwWdi2IaYGtDdteJi0JpZ4OD31IplWALuit8r73dJuM4iHZdDVKY1tLqY2UICejg== - dependencies: - hoek "^4.2.1" - joi "^13.1.2" - node-expat "^2.3.18" - xmlbuilder@15.1.1: version "15.1.1" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" @@ -17435,11 +17484,6 @@ yauzl@^2.10.0: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - yorkie@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9" diff --git a/server/viame_server/serializers/viame.py b/server/viame_server/serializers/viame.py index 4c7c84c8f..6d044f907 100644 --- a/server/viame_server/serializers/viame.py +++ b/server/viame_server/serializers/viame.py @@ -33,7 +33,9 @@ def writeHeader(writer: '_csv._writer', metadata: Dict): writer.writerow([f'# metadata -{metadata_str}']) writer.writerow( - [f'# Written on {datetime.datetime.now().ctime()} by: viame_web_csv_writer'] + [ + f'# Written on {datetime.datetime.now().ctime()} by: viame_web_csv_writer:python' + ] ) From 86705f6a2d2c0ec812fa9628eba05b284313b12c Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Thu, 7 Jan 2021 15:38:05 -0500 Subject: [PATCH 2/6] Fix json --- client/tsconfig.cli.json | 2 +- client/tsconfig.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/tsconfig.cli.json b/client/tsconfig.cli.json index 9beb2ef01..affff4960 100644 --- a/client/tsconfig.cli.json +++ b/client/tsconfig.cli.json @@ -5,7 +5,7 @@ "module": "commonjs", "outDir": "./bin", "declaration": true, - "declarationDir": "./bin/types", + "declarationDir": "./bin/types" }, "include": [ "platform/desktop/backend/serializers/*.ts", diff --git a/client/tsconfig.json b/client/tsconfig.json index 566151eb6..1f8dca3cc 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -25,7 +25,7 @@ ], "platform": [ "platform/*" - ], + ] }, "lib": [ "ES2017.Object", @@ -47,7 +47,7 @@ "platform/**/*.ts", "src/**/*.ts", "src/**/*.vue", - "tests/**/*.ts", + "tests/**/*.ts" ], "exclude": [ "node_modules" From 9b5e8f2055ae429b18aef5a8e4d0efde7be40fe8 Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Fri, 8 Jan 2021 10:43:14 -0500 Subject: [PATCH 3/6] Resolve comments --- .../platform/desktop/backend/serializers/viame.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/platform/desktop/backend/serializers/viame.ts b/client/platform/desktop/backend/serializers/viame.ts index 33e5038c1..57c07766d 100644 --- a/client/platform/desktop/backend/serializers/viame.ts +++ b/client/platform/desktop/backend/serializers/viame.ts @@ -300,7 +300,7 @@ async function writeHeader(writer: Writable, meta: JsonMeta) { writer.write([`#meta fps=${meta.fps}`]); } writer.write( - [`# Written on ${(new Date()).toLocaleString()} by dive_csv_writer:typescript`], + [`# Written on ${(new Date()).toLocaleString().replace(',', '')} by dive_writer:typescript`], ); } @@ -325,10 +325,10 @@ async function serialize( writeHeader(stringify, meta); Object.values(data).forEach((track) => { const filters = meta.confidenceFilters || {}; - if (!options.excludeBelowThreshold - || Track.trackExceedsThreshold(track.confidencePairs, filters) - ) { - const sortedPairs = track.confidencePairs.sort((a, b) => a[1] - b[1]); + const pairsAboveThreshold = Track.trackExceedsThreshold(track.confidencePairs, filters); + if (!options.excludeBelowThreshold || pairsAboveThreshold.length) { + /* Include only the pairs that exceed the threshold in CSV output */ + const sortedPairs = pairsAboveThreshold.sort((a, b) => a[1] - b[1]); track.features.forEach((keyframeFeature, index) => { const interpolatedFeatures = [keyframeFeature]; @@ -360,7 +360,7 @@ async function serialize( column2, feature.frame, ...(feature.bounds as number[]), - sortedPairs[0][1], + sortedPairs[0][1], // always take highest confidence to be track confidence feature.fishLength || -1, ...flattenDeep(sortedPairs), ]; @@ -383,7 +383,7 @@ async function serialize( row.push(`${PolyToken} ${coordinates.map(Math.round).join(' ')}`); } else if (geoJSONFeature.geometry.type === 'Point') { if (geoJSONFeature.properties) { - const kpname = geoJSONFeature.properties.name; + const kpname = geoJSONFeature.properties.key; const { coordinates } = geoJSONFeature.geometry; row.push( `${KeypointToken} ${kpname} ${coordinates.map(Math.round).join(' ')}`, From 193e86d2012f02bb493830e984b808f98803852c Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Fri, 8 Jan 2021 11:03:41 -0500 Subject: [PATCH 4/6] Remove unused elements from tsconfig --- client/tsconfig.json | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/client/tsconfig.json b/client/tsconfig.json index 1f8dca3cc..9276a84cb 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -12,10 +12,6 @@ "allowSyntheticDefaultImports": true, "sourceMap": false, "baseUrl": ".", - "types": [ - "vuetify", - "webpack-env" - ], "paths": { "vue-media-annotator/*": [ "src/*" @@ -28,16 +24,8 @@ ] }, "lib": [ - "ES2017.Object", "esnext", - "dom", - "dom.iterable", - "scripthost" - ], - "typeRoots": [ - "src/@types", - "./node_modules/@types", - "./node_modules/vuetify/types" + "dom" ] }, "include": [ From 180861c271321991f225953bb37b598caebd1972 Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Fri, 8 Jan 2021 13:17:15 -0500 Subject: [PATCH 5/6] Remove outdated comments --- client/platform/desktop/backend/serializers/cli.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/platform/desktop/backend/serializers/cli.ts b/client/platform/desktop/backend/serializers/cli.ts index ac79029e1..db8d21834 100755 --- a/client/platform/desktop/backend/serializers/cli.ts +++ b/client/platform/desktop/backend/serializers/cli.ts @@ -5,13 +5,11 @@ * Command-line entrypoints into serializers and other tooling. * See README.md for usage */ + import { Writable } from 'stream'; import { stdout } from 'process'; - import yargs from 'yargs'; -// Improper relative paths used because CLI won't work with path aliases -// https://github.com/TypeStrong/ts-node/issues/422 import { loadJsonTracks, loadJsonMetadata } from 'platform/desktop/backend/native/common'; import { parseFile, serialize } from './viame'; From ea34e4513040c220225f9da593e8c985f1b0f346 Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Fri, 8 Jan 2021 14:38:10 -0500 Subject: [PATCH 6/6] Address more comments --- client/README.md | 2 +- client/platform/desktop/backend/serializers/viame.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/client/README.md b/client/README.md index 525063c2e..b32a05d40 100644 --- a/client/README.md +++ b/client/README.md @@ -40,7 +40,7 @@ yarn test yarn build:cli # Watch -yarn watch:cli +yarn dev:cli # Run in development mode yarn divecli --help diff --git a/client/platform/desktop/backend/serializers/viame.ts b/client/platform/desktop/backend/serializers/viame.ts index 57c07766d..a2ebb4530 100644 --- a/client/platform/desktop/backend/serializers/viame.ts +++ b/client/platform/desktop/backend/serializers/viame.ts @@ -325,10 +325,12 @@ async function serialize( writeHeader(stringify, meta); Object.values(data).forEach((track) => { const filters = meta.confidenceFilters || {}; - const pairsAboveThreshold = Track.trackExceedsThreshold(track.confidencePairs, filters); - if (!options.excludeBelowThreshold || pairsAboveThreshold.length) { - /* Include only the pairs that exceed the threshold in CSV output */ - const sortedPairs = pairsAboveThreshold.sort((a, b) => a[1] - b[1]); + /* Include only the pairs that exceed the threshold in CSV output */ + const confidencePairs = options.excludeBelowThreshold + ? Track.trackExceedsThreshold(track.confidencePairs, filters) + : track.confidencePairs; + if (confidencePairs.length) { + const sortedPairs = confidencePairs.sort((a, b) => a[1] - b[1]); track.features.forEach((keyframeFeature, index) => { const interpolatedFeatures = [keyframeFeature]; @@ -393,12 +395,12 @@ async function serialize( /* TODO support for multiple GeoJSON Objects of the same type */ }); } - stringify.write(row); }); }); } }); + stringify.end(); }); }