From d3f453a4fb3f7eaac9031026dc95bff0a076dec3 Mon Sep 17 00:00:00 2001 From: Brice Maron Date: Sat, 3 Sep 2022 18:00:54 +0200 Subject: [PATCH] feat: add prettier config --- .editorconfig | 10 ++ .git-blame-ignore-revs | 2 + .github/actions/setup-and-validate/action.yml | 6 +- .github/workflows/validate-pr.yml | 2 +- .prettierignore | 13 +++ .prettierrc.json | 4 + .../Conversion/AddContextToTranslations.ts | 2 - UI/OpeningHours/OpeningHoursVisualization.ts | 61 +++++----- UI/Popup/TagRenderingQuestion.ts | 104 +++++++++--------- customGenerator.html | 25 +++-- package-lock.json | 28 ++++- package.json | 6 +- 12 files changed, 159 insertions(+), 104 deletions(-) create mode 100644 .editorconfig create mode 100644 .git-blame-ignore-revs create mode 100644 .prettierignore create mode 100644 .prettierrc.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..0642402e9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 + +[*.ts] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..47185e7c0 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# to be filled once final sha is known +# Prettier init diff --git a/.github/actions/setup-and-validate/action.yml b/.github/actions/setup-and-validate/action.yml index 431cdc864..cc9ded1b7 100644 --- a/.github/actions/setup-and-validate/action.yml +++ b/.github/actions/setup-and-validate/action.yml @@ -4,9 +4,11 @@ runs: using: "composite" steps: - name: Set up Node.js - uses: actions/setup-node@v1.4.6 + uses: actions/setup-node@v3 with: - node-version: '16' + node-version: "16" + cache: "npm" + cache-dependency-path: package-lock.json - name: install deps run: npm ci diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml index c1bbcbcf5..4e64746f8 100644 --- a/.github/workflows/validate-pr.yml +++ b/.github/workflows/validate-pr.yml @@ -6,7 +6,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup and validate themes uses: ./.github/actions/setup-and-validate diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..76f9aac83 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,13 @@ +node_modules +.git +langs/ +vendor/ +dist/ +.cache +assets/generated/ +assets/themes/ +assets/layers/ +Docs/Tools/stats/ +Docs/Layers/ +Docs/Schemas/ +Docs/TagInfo/ \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..7acf4f02d --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "semi": false, + "printWidth": 100 +} diff --git a/Models/ThemeConfig/Conversion/AddContextToTranslations.ts b/Models/ThemeConfig/Conversion/AddContextToTranslations.ts index af9961a89..335f3d761 100644 --- a/Models/ThemeConfig/Conversion/AddContextToTranslations.ts +++ b/Models/ThemeConfig/Conversion/AddContextToTranslations.ts @@ -44,7 +44,6 @@ export class AddContextToTranslations extends DesugaringStep { * layers: [ * { * tagRenderings:[ - * * {id: "some-tr", * question:{ * en:"Question?" @@ -59,7 +58,6 @@ export class AddContextToTranslations extends DesugaringStep { * layers: [ * { * tagRenderings:[ - * * {id: "some-tr", * question:{ * _context: "prefix:context.layers.0.tagRenderings.some-tr.question" diff --git a/UI/OpeningHours/OpeningHoursVisualization.ts b/UI/OpeningHours/OpeningHoursVisualization.ts index f6f3a3c18..b0a8ee95c 100644 --- a/UI/OpeningHours/OpeningHoursVisualization.ts +++ b/UI/OpeningHours/OpeningHoursVisualization.ts @@ -1,15 +1,15 @@ -import {UIEventSource} from "../../Logic/UIEventSource"; +import { UIEventSource } from "../../Logic/UIEventSource"; import Combine from "../Base/Combine"; -import {FixedUiElement} from "../Base/FixedUiElement"; -import {OH} from "./OpeningHours"; +import { FixedUiElement } from "../Base/FixedUiElement"; +import { OH } from "./OpeningHours"; import Translations from "../i18n/Translations"; import Constants from "../../Models/Constants"; import BaseUIElement from "../BaseUIElement"; import Toggle from "../Input/Toggle"; -import {VariableUiElement} from "../Base/VariableUIElement"; +import { VariableUiElement } from "../Base/VariableUIElement"; import Table from "../Base/Table"; -import {Translation} from "../i18n/Translation"; -import {OsmConnection} from "../../Logic/Osm/OsmConnection"; +import { Translation } from "../i18n/Translation"; +import { OsmConnection } from "../../Logic/Osm/OsmConnection"; export default class OpeningHoursVisualization extends Toggle { private static readonly weekdays: Translation[] = [ @@ -35,24 +35,24 @@ export default class OpeningHoursVisualization extends Toggle { return value; }) // This mapping will absorb all other changes to tags in order to prevent regeneration .map(ohtext => { - if (ohtext === undefined) { - return new FixedUiElement("No opening hours defined with key " + key).SetClass("alert") - } - try { - return OpeningHoursVisualization.CreateFullVisualisation( - OH.CreateOhObject(tags.data, ohtext)) - } catch (e) { - console.warn(e, e.stack); - return new Combine([Translations.t.general.opening_hours.error_loading, - new Toggle( - new FixedUiElement(e).SetClass("subtle"), - undefined, - state?.osmConnection?.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAndWikiLinked) - ) - ]); - } - + if (ohtext === undefined) { + return new FixedUiElement("No opening hours defined with key " + key).SetClass("alert") } + try { + return OpeningHoursVisualization.CreateFullVisualisation( + OH.CreateOhObject(tags.data, ohtext)) + } catch (e) { + console.warn(e, e.stack); + return new Combine([Translations.t.general.opening_hours.error_loading, + new Toggle( + new FixedUiElement(e).SetClass("subtle"), + undefined, + state?.osmConnection?.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAndWikiLinked) + ) + ]); + } + + } )) super( @@ -105,7 +105,7 @@ export default class OpeningHoursVisualization extends Toggle { } private static ConstructVizTable(oh: any, ranges: { isOpen: boolean; isSpecial: boolean; comment: string; startDate: Date; endDate: Date }[][], - rangeStart: Date): BaseUIElement { + rangeStart: Date): BaseUIElement { const isWeekstable: boolean = oh.isWeekStable(); @@ -158,7 +158,7 @@ export default class OpeningHoursVisualization extends Toggle { } return new Table(undefined, [[" ", header], ...weekdays], - {contentStyle: [["width: 5%", `position: relative; height: ${headerHeight}`], ...weekdayStyles]} + { contentStyle: [["width: 5%", `position: relative; height: ${headerHeight}`], ...weekdayStyles] } ).SetClass("w-full") .SetStyle("border-collapse: collapse; word-break; word-break: normal; word-wrap: normal") @@ -166,8 +166,8 @@ export default class OpeningHoursVisualization extends Toggle { } private static CreateRangeElem(availableArea: number, earliestOpen: number, latestclose: number, - range: { isOpen: boolean; isSpecial: boolean; comment: string; startDate: Date; endDate: Date }, - isWeekstable: boolean): BaseUIElement { + range: { isOpen: boolean; isSpecial: boolean; comment: string; startDate: Date; endDate: Date }, + isWeekstable: boolean): BaseUIElement { const textToShow = range.comment ?? (isWeekstable ? "" : range.startDate.toLocaleDateString()); @@ -179,6 +179,7 @@ export default class OpeningHoursVisualization extends Toggle { startOfDay.setHours(0, 0, 0, 0); // @ts-ignore const startpoint = (range.startDate - startOfDay) / 1000 - earliestOpen; + // prettier-ignore // @ts-ignore const width = (100 * (range.endDate - range.startDate) / 1000) / (latestclose - earliestOpen); const startPercentage = (100 * startpoint / availableArea); @@ -270,8 +271,8 @@ export default class OpeningHoursVisualization extends Toggle { return Translations.t.general.opening_hours.closed_permanently.Clone() } const willOpenAt = `${opensAtDate.getDate()}/${opensAtDate.getMonth() + 1} ${OH.hhmm(opensAtDate.getHours(), opensAtDate.getMinutes())}` - return Translations.t.general.opening_hours.closed_until.Subs({date: willOpenAt}) + return Translations.t.general.opening_hours.closed_until.Subs({ date: willOpenAt }) } - -} \ No newline at end of file + +} diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index c3f22967e..a8f13bb88 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -1,38 +1,38 @@ -import {Store, Stores, UIEventSource} from "../../Logic/UIEventSource"; +import { Store, Stores, UIEventSource } from "../../Logic/UIEventSource"; import Combine from "../Base/Combine"; -import {InputElement, ReadonlyInputElement} from "../Input/InputElement"; +import { InputElement, ReadonlyInputElement } from "../Input/InputElement"; import ValidatedTextField from "../Input/ValidatedTextField"; -import {FixedInputElement} from "../Input/FixedInputElement"; -import {RadioButton} from "../Input/RadioButton"; -import {Utils} from "../../Utils"; +import { FixedInputElement } from "../Input/FixedInputElement"; +import { RadioButton } from "../Input/RadioButton"; +import { Utils } from "../../Utils"; import CheckBoxes from "../Input/Checkboxes"; import InputElementMap from "../Input/InputElementMap"; -import {SaveButton} from "./SaveButton"; -import {VariableUiElement} from "../Base/VariableUIElement"; +import { SaveButton } from "./SaveButton"; +import { VariableUiElement } from "../Base/VariableUIElement"; import Translations from "../i18n/Translations"; -import {FixedUiElement} from "../Base/FixedUiElement"; -import {Translation} from "../i18n/Translation"; +import { FixedUiElement } from "../Base/FixedUiElement"; +import { Translation } from "../i18n/Translation"; import Constants from "../../Models/Constants"; -import {SubstitutedTranslation} from "../SubstitutedTranslation"; -import {TagsFilter} from "../../Logic/Tags/TagsFilter"; -import {Tag} from "../../Logic/Tags/Tag"; -import {And} from "../../Logic/Tags/And"; -import {TagUtils, UploadableTag} from "../../Logic/Tags/TagUtils"; +import { SubstitutedTranslation } from "../SubstitutedTranslation"; +import { TagsFilter } from "../../Logic/Tags/TagsFilter"; +import { Tag } from "../../Logic/Tags/Tag"; +import { And } from "../../Logic/Tags/And"; +import { TagUtils, UploadableTag } from "../../Logic/Tags/TagUtils"; import BaseUIElement from "../BaseUIElement"; -import {DropDown} from "../Input/DropDown"; +import { DropDown } from "../Input/DropDown"; import InputElementWrapper from "../Input/InputElementWrapper"; import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"; -import TagRenderingConfig, {Mapping} from "../../Models/ThemeConfig/TagRenderingConfig"; -import {Unit} from "../../Models/Unit"; +import TagRenderingConfig, { Mapping } from "../../Models/ThemeConfig/TagRenderingConfig"; +import { Unit } from "../../Models/Unit"; import VariableInputElement from "../Input/VariableInputElement"; import Toggle from "../Input/Toggle"; import Img from "../Base/Img"; import FeaturePipelineState from "../../Logic/State/FeaturePipelineState"; import Title from "../Base/Title"; -import {OsmConnection} from "../../Logic/Osm/OsmConnection"; -import {GeoOperations} from "../../Logic/GeoOperations"; -import {SearchablePillsSelector} from "../Input/SearchableMappingsSelector"; -import {OsmTags} from "../../Models/OsmFeature"; +import { OsmConnection } from "../../Logic/Osm/OsmConnection"; +import { GeoOperations } from "../../Logic/GeoOperations"; +import { SearchablePillsSelector } from "../Input/SearchableMappingsSelector"; +import { OsmTags } from "../../Models/OsmFeature"; /** * Shows the question element. @@ -41,15 +41,15 @@ import {OsmTags} from "../../Models/OsmFeature"; export default class TagRenderingQuestion extends Combine { constructor(tags: UIEventSource & { id: string }>, - configuration: TagRenderingConfig, - state?: FeaturePipelineState, - options?: { - units?: Unit[], - afterSave?: () => void, - cancelButton?: BaseUIElement, - saveButtonConstr?: (src: Store) => BaseUIElement, - bottomText?: (src: Store) => BaseUIElement - } + configuration: TagRenderingConfig, + state?: FeaturePipelineState, + options?: { + units?: Unit[], + afterSave?: () => void, + cancelButton?: BaseUIElement, + saveButtonConstr?: (src: Store) => BaseUIElement, + bottomText?: (src: Store) => BaseUIElement + } ) { const applicableMappingsSrc = @@ -84,24 +84,24 @@ export default class TagRenderingQuestion extends Combine { const feedback = new UIEventSource(undefined) const inputElement: ReadonlyInputElement = new VariableInputElement(applicableMappingsSrc.map(applicableMappings => { - return TagRenderingQuestion.GenerateInputElement(state, configuration, applicableMappings, applicableUnit, tags, feedback) - } + return TagRenderingQuestion.GenerateInputElement(state, configuration, applicableMappings, applicableUnit, tags, feedback) + } )) const save = () => { - - - const selection = TagUtils.FlattenMultiAnswer(TagUtils.FlattenAnd( inputElement.GetValue().data, tags.data)); + + + const selection = TagUtils.FlattenMultiAnswer(TagUtils.FlattenAnd(inputElement.GetValue().data, tags.data)); if (selection) { (state?.changes) .applyAction(new ChangeTagAction( tags.data.id, selection, tags.data, { - theme: state?.layoutToUse?.id ?? "unkown", - changeType: "answer", - } + theme: state?.layoutToUse?.id ?? "unkown", + changeType: "answer", + } )).then(_ => { - console.log("Tagchanges applied") - }) + console.log("Tagchanges applied") + }) if (options.afterSave) { options.afterSave(); } @@ -229,7 +229,7 @@ export default class TagRenderingQuestion extends Combine { if (configuration.multiAnswer) { return TagRenderingQuestion.GenerateMultiAnswer(configuration, inputEls, ff, applicableMappings.map(mp => mp.ifnot)) } else { - return new RadioButton(inputEls, {selectFirstAsDefault: false}) + return new RadioButton(inputEls, { selectFirstAsDefault: false }) } } @@ -267,7 +267,6 @@ export default class TagRenderingQuestion extends Combine { * freeform: { * key:"key" * }, - * * mappings: [ * { * if:"x=y", @@ -298,7 +297,6 @@ export default class TagRenderingQuestion extends Combine { * freeform: { * key:"key" * }, - * * mappings: [ * { * if:"x=y", @@ -338,7 +336,7 @@ export default class TagRenderingQuestion extends Combine { const ff = configuration.freeform let onEmpty: BaseUIElement = undefined if (ff !== undefined) { - onEmpty = new VariableUiElement(searchValue.map(search => configuration.render.Subs({[ff.key]: search}))) + onEmpty = new VariableUiElement(searchValue.map(search => configuration.render.Subs({ [ff.key]: search }))) } const mode = configuration.multiAnswer ? "select-many" : "select-one"; @@ -357,7 +355,7 @@ export default class TagRenderingQuestion extends Combine { return Translations.t.general.useSearch; } return new Combine([ - Translations.t.general.useSearchForMore.Subs({total: applicableMappings.length}), + Translations.t.general.useSearchForMore.Subs({ total: applicableMappings.length }), new SearchablePillsSelector(priority, { selectedElements: tooMuchElementsValue, hideSearchBar: true, @@ -468,7 +466,7 @@ export default class TagRenderingQuestion extends Combine { }, (tags: UploadableTag) => { // {key --> values[]} - + const presentTags = TagUtils.SplitKeys([tags]); const indices: number[] = [] // We also collect the values that have to be added to the freeform field @@ -595,9 +593,9 @@ export default class TagRenderingQuestion extends Combine { return tag; } return new And([ - tag, - ...freeform.addExtraTags - ] + tag, + ...freeform.addExtraTags + ] ); }; @@ -637,7 +635,7 @@ export default class TagRenderingQuestion extends Combine { // Add a length check input?.GetValue().addCallbackD((v: string | undefined) => { if (v?.length >= 255) { - feedback.setData(Translations.t.validation.tooLong.Subs({count: v.length})) + feedback.setData(Translations.t.validation.tooLong.Subs({ count: v.length })) } }) @@ -657,8 +655,8 @@ export default class TagRenderingQuestion extends Combine { } public static CreateTagExplanation(selectedValue: Store, - tags: Store, - state?: { osmConnection?: OsmConnection }) { + tags: Store, + state?: { osmConnection?: OsmConnection }) { return new VariableUiElement( selectedValue.map( (tagsFilter: TagsFilter) => { @@ -680,4 +678,4 @@ export default class TagRenderingQuestion extends Combine { ).SetClass("block break-all") } -} \ No newline at end of file +} diff --git a/customGenerator.html b/customGenerator.html index ffa831d38..45cd309f5 100644 --- a/customGenerator.html +++ b/customGenerator.html @@ -1,15 +1,16 @@ + + The custom generator has moved (temporarily), go to + + Redirecting you to the development version - - -The custom generator has moved (temporarily), go to -Redirecting you to the development version - - - - - + + diff --git a/package-lock.json b/package-lock.json index b0c1b1239..8100ca3af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "0.0.5", "license": "GPL", "dependencies": { - "@parcel/service-worker": "^2.6.0", "@turf/boolean-intersects": "^6.5.0", "@turf/buffer": "^6.5.0", "@turf/collect": "^6.5.0", @@ -49,6 +48,7 @@ "devDependencies": { "@babel/polyfill": "^7.10.4", "@babel/preset-env": "7.13.8", + "@parcel/service-worker": "^2.6.0", "@types/chai": "^4.3.0", "@types/geojson": "^7946.0.10", "@types/leaflet-markercluster": "^1.0.3", @@ -66,6 +66,7 @@ "fs": "0.0.1-security", "mocha": "^9.2.2", "parcel": "^1.2.4", + "prettier": "2.7.1", "read-file": "^0.2.0", "sharp": "^0.30.5", "ts-node": "^10.9.1", @@ -1542,6 +1543,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/@parcel/service-worker/-/service-worker-2.6.0.tgz", "integrity": "sha512-rOKRPoipOsg5XsYbag0mQ0WtVTscHjblL/zc0VA6O3ju5hgLAPVM4UmfdljuRVgRoMHSCV7wz1qAh9okvNqdjw==", + "dev": true, "engines": { "node": ">= 12.0.0", "parcel": "^2.6.0" @@ -12630,6 +12632,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -17943,7 +17960,8 @@ "@parcel/service-worker": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/@parcel/service-worker/-/service-worker-2.6.0.tgz", - "integrity": "sha512-rOKRPoipOsg5XsYbag0mQ0WtVTscHjblL/zc0VA6O3ju5hgLAPVM4UmfdljuRVgRoMHSCV7wz1qAh9okvNqdjw==" + "integrity": "sha512-rOKRPoipOsg5XsYbag0mQ0WtVTscHjblL/zc0VA6O3ju5hgLAPVM4UmfdljuRVgRoMHSCV7wz1qAh9okvNqdjw==", + "dev": true }, "@parcel/utils": { "version": "1.11.0", @@ -26760,6 +26778,12 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", diff --git a/package.json b/package.json index b3207bfbc..bd6ad2489 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "generate:charging-stations": "cd ./assets/layers/charging_station && ts-node csvToJson.ts && cd -", "prepare-deploy": "npm run generate:service-worker && ./scripts/build.sh", "gittag": "ts-node scripts/printVersion.ts | bash", + "format": "npx prettier --write '**/*.ts'", "lint": "tslint --project . -c tslint.json '**.ts' ", "clean:tests": "(find . -type f -name \"*.doctest.ts\" | xargs rm)", "clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(404\\|index\\|land\\|test\\|preferences\\|customGenerator\\|professional\\|automaton\\|import_helper\\|import_viewer\\|theme\\).html\" | xargs rm) && (ls | grep \"^index_[a-zA-Z_-]\\+\\.ts$\" | xargs rm) && (ls | grep \".*.webmanifest$\" | grep -v \"manifest.webmanifest\" | xargs rm)", @@ -51,7 +52,7 @@ "weblate-add-upstream": "git remote add weblate-github git@github.com:weblate/MapComplete.git", "weblate-fix": "git remote update weblate-github; git merge weblate-github/weblate-mapcomplete-core; git merge weblate-github/weblate-mapcomplete-layers; git merge weblate-github/weblate-mapcomplete-layer-translations", "weblate-fix-heavy": "git remote rm weblate-layers; git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layers/; git remote update weblate-layers; git merge weblate-layers/master", - "housekeeping": "npm run generate && npm run generate:docs && npm run generate:contributor-list && git add Docs/* && git commit assets/ langs/ Docs/ -m 'Housekeeping...'", + "housekeeping": "npm run generate && npm run generate:docs && npm run generate:contributor-list && npm run format && git add *.ts && git add Docs/* && git commit assets/ langs/ Docs/ -m 'Housekeeping...'", "parseSchools": "ts-node scripts/schools/amendSchoolData.ts", "steal": "ts-node scripts/thieves/stealLanguages.ts" }, @@ -68,7 +69,6 @@ "not op_mini all" ], "dependencies": { - "@parcel/service-worker": "^2.6.0", "@turf/boolean-intersects": "^6.5.0", "@turf/buffer": "^6.5.0", "@turf/collect": "^6.5.0", @@ -108,6 +108,7 @@ "devDependencies": { "@babel/polyfill": "^7.10.4", "@babel/preset-env": "7.13.8", + "@parcel/service-worker": "^2.6.0", "@types/chai": "^4.3.0", "@types/geojson": "^7946.0.10", "@types/leaflet-markercluster": "^1.0.3", @@ -125,6 +126,7 @@ "fs": "0.0.1-security", "mocha": "^9.2.2", "parcel": "^1.2.4", + "prettier": "2.7.1", "read-file": "^0.2.0", "sharp": "^0.30.5", "ts-node": "^10.9.1",