diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 14b612bb..1683ade4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,15 +27,27 @@ jobs: - name: Install nodejs uses: actions/setup-node@v3 with: - node-version: 16 + node-version: '16.x' + registry-url: 'https://npm.pkg.github.com' + scope: 'AtlasOfLivingAustralia' - run: npm install - run: npm run package-turf + + + - name: Update your package.json with an npm pre-release version + id: pre-release-version + uses: adobe/update-prerelease-npm-version@v1.0.0 + + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Validate Gradle wrapper uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b - name: Run tests and jacoco coverage report with Gradle - uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + uses: gradle/gradle-build-action@v2.4.2 with: arguments: -PenableJacoco=true test @@ -43,12 +55,12 @@ jobs: run: node_modules/karma/bin/karma start karma.conf.js --single-run --browsers ChromeHeadless - name: Clean to remove clover instrumentation - uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + uses: gradle/gradle-build-action@v2.4.2 with: arguments: clean - name: Publish the JAR to the repository - uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + uses: gradle/gradle-build-action@v2.4.2 with: arguments: publish env: diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 53b57f59..00000000 --- a/.travis.yml +++ /dev/null @@ -1,51 +0,0 @@ -dist: bionic -language: groovy -jdk: -- openjdk11 -sudo: false -addons: - chrome: stable -branches: - only: - - master - - dev - - /^feature\/.*$/ - - /^hotfix\/.*$/ - - grails3 - - devg3 - - grails4 - - grails4-bs-branch - - grails5 - -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ -cache: - directories: - - $HOME/.m2 - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ - -before_install: -- export TZ=Australia/Canberra -- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - -before_script: -- export DETECT_CHROMEDRIVER_VERSION=true -- cd $TRAVIS_BUILD_DIR -- npm install -- npm run-script package-turf -script: -- cd $TRAVIS_BUILD_DIR -#- ./gradlew -PenableClover=true cloverGenerateReport -- node_modules/karma/bin/karma start karma.conf.js --single-run --browsers ChromeHeadless - -# need to gradlew clean before publishing to rebuild without the clover instrumentation. -after_success: - - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && travis_retry ./gradlew clean && ./gradlew publish' - -env: - global: - - TRAVIS_NODE_VERSION="15.4.0" - - secure: APIxsQqe4M4rIPwU1wKwq6DabQ+CrFu2onzp9k8R9Bv0InewxUf0eOWsp8Xl2m3/Lh7IgUkxI5GbuBvZm/j3NRCkA+VuHBSbA1qUu9aDkUQrtyHzkoe+Uk9Ze0QO22O7//WtbtH/bqgvbagCUk1W5sL6h2aL081td760DY+h+D43XvegqFTSE2mWLvZDD7gz3Lw982LLn7DwQhVOAws+h3fXhydRtqSU+ig6SAr1lzhVyrRLFLAqh1V3canZXh1RKZ28aRwEYUxnVi4kVvH254ogx++bL81pmMfatcebsXUCuAfc6FS1m/QGz6wyqdKO0mZIsAavWmtoKBEbzwNMBS0fZVuW9rslRdJd+K+vQOhigTaWyqj7MlfdY7o99y+trcQECvPGDlw0eYThpeRZK1h1r1auOuSZ46FiXRsWtiSQ3f6GQSRERXiKczvlSqZlNWiWswcNtOS60QvMDdRKa2RRLPrtgPNuG/BnHdaH197riTa74jOW3pgjRZTJyT5aRkHTdZS4l1B/JWjZBwY9yjukfwtFql4HHf8o7jtbTUSXqWt80fwlxXQBEcXxKJzn1vpnEpydS/GeftDFOCXfEFZpM+z6ben3Ti5PufjYfX1Emb6ZwEb/IDhYeCK/xTZlvqxbDgepLqeMiuV+CeHo0NBcu3qnORQMiTZCdEs1hFU= - - secure: ufGvrU/vc0XQ8dbcx9ER4eb8MQloeVvC8ToQrwh3T5WUN4CbnugJ2EcSqoGAsXSZ2VUqE8NmdN2VfCQ6KxAtWKvNNxoe1M33DMgS1hRLWOa934Z7+cZ9RlclW29WGi9C4zpPMd4rJdeGyQMr+q4+TZWuk/I48DXRKyWv3FM4t68F52Jlr0wagWPr1oFJScjzJmmAPReJivF8g49d24rE9G2x04PYy/yCOmgiqUuYhArYKmqdquQL2X/SF4ifFpFIADKw9K6Ari48JskwXweuDCzrvHnj7xeDkDt9uiIpe85nf+th9MmS5NOX4nIod8y6NJyTdflD/k1vVRSLILtu21PXXnn7SpuLpS3FuSh4tKjEO3wZrndFiVqMobv7DaYkxshldRMkNHqeyZUThl2H4hskk2BkK/DaHwPg/JDdlyk8MmaN7LJEezmGhIEtZiEm62NVKU5vGDUB2UmyFEhI4UjcIrfyGR77P5xTW4iBHagP10qqMNrNZ8CkaugfuefI9PCK+nt7YuvP1s+AV05TKNrO7QFFw7+6k5Stv+kJb/k6Vfs4hUCM0Uhv01oYr3dZa9s+Sra/BS2mkmdurNcp0s4AZg4HbXcd03dCfA7dF5EVS2pObVViWy8CDUREc2XMWYKxdwals17Q8O7SjSHHzngXX7Jj0lw1EKQQtgoyb6g= diff --git a/build.gradle b/build.gradle index 5951ebaf..580584e4 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ plugins { } -version "6.1-PWA-SNAPSHOT" +version "6.3-PWA-SNAPSHOT" group "org.grails.plugins" apply plugin:"eclipse" diff --git a/gradle.properties b/gradle.properties index 821f49de..ac5c64c9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ groovyVersion=3.0.11 -grailsVersion=5.3.2 +grailsVersion=5.3.5 gorm.version=7.1.2 grailsGradlePluginVersion=5.3.0 org.gradle.daemon=true @@ -14,4 +14,4 @@ org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xss2048k -Xmx1024M exploded=true enableClover=false enableJacoco=true -alaSecurityLibsVersion=6.0.0 \ No newline at end of file +alaSecurityLibsVersion=6.2.0 diff --git a/grails-app/assets/javascripts/feature.js b/grails-app/assets/javascripts/feature.js index aae64e3d..356ef917 100644 --- a/grails-app/assets/javascripts/feature.js +++ b/grails-app/assets/javascripts/feature.js @@ -614,6 +614,8 @@ ecodata.forms.maps.showMapInModal = function(options) { }) .one('hidden.bs.modal', function (e) { + $ok.unbind('click', okPressed); // This is done because otherwise when cancel is pressed the listener isn't removed. + // This check is necessary because the accordion also fires these events which bubble to the modal. if (e.target == this) { self.featureMapInstance.clearDrawnItems(); diff --git a/grails-app/assets/javascripts/forms-knockout-bindings.js b/grails-app/assets/javascripts/forms-knockout-bindings.js index e233e21a..fc707f3b 100644 --- a/grails-app/assets/javascripts/forms-knockout-bindings.js +++ b/grails-app/assets/javascripts/forms-knockout-bindings.js @@ -62,12 +62,13 @@ var config = valueAccessor(); config = $.extend({}, config, defaultConfig); - + var dropzone = $(element); var target = config.target; // Expected to be a ko.observableArray $(element).fileupload({ url:config.url, autoUpload:true, - dataType:'json' + dataType:'json', + dropZone: dropzone }).on('fileuploadadd', function(e, data) { complete(false); progress(1); @@ -481,6 +482,51 @@ } }; + function forceSelect2ToRespectPercentageTableWidths(element, percentageWidth) { + var $parentColumn = $(element).parent('td'); + var $parentTable = $parentColumn.closest('table'); + var resizeHandler = null; + if ($parentColumn.length) { + var select2 = $parentColumn.find('.select2-container'); + function calculateWidth() { + var parentWidth = $parentTable.width(); + + // If the table has overflowed due to long selections then we need to try and find a parent div + // as the div won't have overflowed. + var windowWidth = window.innerWidth; + if (parentWidth > windowWidth) { + var parent = $parentTable.parent('div'); + if (parent.length) { + parentWidth = parent.width(); + } + else { + parentWidth = windowWidth; + } + } + var columnWidth = parentWidth*percentageWidth/100; + + if (columnWidth > 10) { + select2.css('max-width', columnWidth+'px'); + $(element).validationEngine('updatePromptsPosition'); + } + else { + // The table is not visible yet, so wait a bit and try again. + setTimeout(calculateWidth, 200); + } + } + resizeHandler = function() { + clearTimeout(calculateWidth); + setTimeout(calculateWidth, 300); + }; + $(window).on('resize', resizeHandler); + + ko.utils.domNodeDisposal.addDisposeCallback(element, function() { + $(window).off('resize', resizeHandler); + }); + calculateWidth(); + } + + } function applySelect2ValidationCompatibility(element) { var $element = $(element); var select2 = $element.next('.select2-container'); @@ -602,6 +648,12 @@ $element.trigger('change'); }); } + if (options.preserveColumnWidth) { + forceSelect2ToRespectPercentageTableWidths(element, options.preserveColumnWidth); + } + else { + applySelect2ValidationCompatibility(element); + } } }; @@ -615,41 +667,58 @@ }; var options = valueAccessor(); var model = options.value; + if (!ko.isObservable(model, ko.observableArray)) { throw "The options require a key with name 'value' with a value of type ko.observableArray"; } + var constraints; + if (model.hasOwnProperty('constraints')) { + constraints = model.constraints; + } + else { + // Attempt to use the options binding to see if we can observe changes to the constraints + constraints = allBindings.get('options'); + } + // Because constraints can be initialised by an AJAX call, constraints can be added after initialisation // which can result in duplicate OPTIONS tags for pre-selected values, which confuses select2. // Here we watch for changes to the model constraints and make sure any duplicates are removed. - if (model.hasOwnProperty('constraints')) { - if (ko.isObservable(model.constraints)) { - model.constraints.subscribe(function(val) { - var existing = {}; - var duplicates = []; - var currentOptions = $(element).find("option").each(function() { - var val = $(this).val(); - if (existing[val]) { - duplicates.push(this); - } - else { - existing[val] = true; - } - }); - // Remove any duplicates - for (var i=0; i} */ - ko.extenders.numericString = function(target, precision) { + ko.extenders.numericString = function(target, options) { + var defaults = { + decimalPlaces: 2, + removeTrailingZeros: true // backwards compatibility + }; + if (_.isNumber(options)) { + options = {decimalPlaces: options}; + } + options = _.extend({}, defaults, options); + + function roundAndToString(value) { + var roundingMultiplier = Math.pow(10, options.decimalPlaces); + var roundedValue = Math.round(value * roundingMultiplier) / roundingMultiplier; + return roundedValue.toString(); + } + //create a writable computed observable to intercept writes to our observable var result = ko.computed({ read: target, //always return the original observables value @@ -173,18 +188,18 @@ if (typeof val === 'string') { val = newValue.replace(/,|\$/g, ''); } - var current = target(), - roundingMultiplier = Math.pow(10, precision), - newValueAsNum = isNaN(val) ? 0 : parseFloat(+val), - valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier; + var current = target(); + var newValueAsNum = isNaN(val) ? 0 : parseFloat(+val); + + var valueToWrite = options.removeTrailingZeros ? roundAndToString(newValueAsNum) : newValueAsNum.toFixed(options.decimalPlaces); //only write if it changed - if (valueToWrite.toString() !== current || isNaN(val)) { - target(isNaN(val) ? newValue : valueToWrite.toString()); + if (valueToWrite !== current || isNaN(val)) { + target(isNaN(val) ? newValue : valueToWrite); } else { if (newValue !== current) { - target.notifySubscribers(valueToWrite.toString()); + target.notifySubscribers(valueToWrite); } } } diff --git a/grails-app/assets/javascripts/select2-dropdown-placement-override.js b/grails-app/assets/javascripts/select2-dropdown-placement-override.js new file mode 100644 index 00000000..fa38958e --- /dev/null +++ b/grails-app/assets/javascripts/select2-dropdown-placement-override.js @@ -0,0 +1,94 @@ +/** + * This file overrides the default dropdown placement for select2 to support opening the dropdown on the right side + * of the select2 element. This is useful for select2 elements that are placed on the right side of the page. + * To use the right alignment, add the dropdown-right class to the select element with select2 binding applied. + */ +$.fn.select2.amd.require(["select2/utils",'select2/dropdown/attachBody'], function(Utils, AttachBody) { + + AttachBody.prototype._positionDropdown = function () { + var $window = $(window); + + var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above'); + var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below'); + + var newDirection = null; + + var offset = this.$container.offset(); + + offset.bottom = offset.top + this.$container.outerHeight(false); + + var container = { + height: this.$container.outerHeight(false) + }; + + container.top = offset.top; + container.bottom = offset.top + container.height; + + var dropdown = { + height: this.$dropdown.outerHeight(false) + }; + + var viewport = { + top: $window.scrollTop(), + bottom: $window.scrollTop() + $window.height() + }; + + var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); + var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); + + var containerWidth = this.$container.outerWidth() + var right = ($("body").outerWidth() - (offset.left + containerWidth)); + + if (this.$element.hasClass("dropdown-right")) { + var css = { + right: right, + top: container.bottom + }; + } else { + var css = { + left: offset.left, + top: container.bottom + }; + } + + // Determine what the parent element is to use for calciulating the offset + var $offsetParent = this.$dropdownParent; + + // For statically positoned elements, we need to get the element + // that is determining the offset + if ($offsetParent.css('position') === 'static') { + $offsetParent = $offsetParent.offsetParent(); + } + + var parentOffset = $offsetParent.offset(); + + css.top -= parentOffset.top; + css.left -= parentOffset.left; + + if (!isCurrentlyAbove && !isCurrentlyBelow) { + newDirection = 'below'; + } + + if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { + newDirection = 'above'; + } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { + newDirection = 'below'; + } + + if (newDirection == 'above' || + (isCurrentlyAbove && newDirection !== 'below')) { + css.top = container.top - parentOffset.top - dropdown.height; + } + + if (newDirection != null) { + this.$dropdown + .removeClass('select2-dropdown--below select2-dropdown--above') + .addClass('select2-dropdown--' + newDirection); + this.$container + .removeClass('select2-container--below select2-container--above') + .addClass('select2-container--' + newDirection); + } + + this.$dropdownContainer.css(css); + }; +}); \ No newline at end of file diff --git a/grails-app/assets/javascripts/viewModels.js b/grails-app/assets/javascripts/viewModels.js index d53e40f8..d5b6e321 100644 --- a/grails-app/assets/javascripts/viewModels.js +++ b/grails-app/assets/javascripts/viewModels.js @@ -339,9 +339,15 @@ function enmapify(args) { viewModel.getSiteId = function () { return siteIdObservable(); }; - viewModel.loadActivitySite = function () { + viewModel.loadActivitySite = function (data) { var siteId = activityLevelData.activity && activityLevelData.activity.siteId; siteId && siteIdObservable(siteId); + // if siteId is not set, then we need to create a site from lat and lon coordinates + if (edit && !siteIdObservable() && data) { + if (data.decimalLatitude && data.decimalLongitude) { + viewModel.addMarker(data); + } + } }; function isEmpty(value){ diff --git a/grails-app/conf/application.yml b/grails-app/conf/application.yml index 62a8aae7..09a31ec7 100644 --- a/grails-app/conf/application.yml +++ b/grails-app/conf/application.yml @@ -91,6 +91,7 @@ grails: userProfile: userIdAttribute: "username" +--- environments: test: server: diff --git a/grails-app/conf/example_models/behavioursExample.json b/grails-app/conf/example_models/behavioursExample.json index 6d697c36..ec48ab35 100644 --- a/grails-app/conf/example_models/behavioursExample.json +++ b/grails-app/conf/example_models/behavioursExample.json @@ -31,6 +31,38 @@ } } ] + }, + { + "dataType": "text", + "name": "item5", + "behaviour": [ + { + "config": { + "source": { + "url": "/preview/prepopulate", + "params": [ + { + "name": "param", + "type": "computed", + "expression": "item5" + } + ] + }, + "mapping": [ + { + "source-path": "param", + "target": "item6" + } + ], + "target": "$data" + }, + "type": "pre_populate" + } + ] + }, + { + "dataType": "text", + "name": "item6" } ], "viewModel": [ @@ -69,7 +101,40 @@ "title": "Item 4" } ] - + }, + { + "type": "row", + "items": [ + { + "type": "col", + "items": [ + { + "type": "literal", + "source": "Note for this example, data entered into item5 will trigger a pre-pop call and be mapped back to item6. Note that the target of the pre-pop is $data which is the current binding context (or the root object in this case). A current limitation is the load method is used for all keys in the returned data, which means if the data is nested and the pre-pop result does not contain keys for all nested data in the nested target object, the data for missing fields will be set to undefined." + } + ] + } + ] + }, + { + "type": "row", + "items": [ + { + "type": "col", + "items": [ + { + "preLabel": "Item 5", + "source": "item5", + "type": "text" + }, + { + "preLabel": "Item 6", + "source": "item6", + "type": "text" + } + ] + } + ] } ], "title": "Behaviours example" diff --git a/grails-app/conf/example_models/constraintsExample.json b/grails-app/conf/example_models/constraintsExample.json index 299837e9..8832be70 100644 --- a/grails-app/conf/example_models/constraintsExample.json +++ b/grails-app/conf/example_models/constraintsExample.json @@ -20,7 +20,19 @@ "type": "pre-populated", "config": { "source": { - "url": "/preview/prepopulateConstraints" + "url": "/preview/prepopulateConstraints", + "params" : [ + { + "name":"p1", + "value":"1" + }, + { + "name": "p2", + "type": "computed", + "expression": "number1" + } + + ] } }, "excludePath": "list.value1" @@ -65,7 +77,7 @@ "items": [ { "type": "literal", - "source": "

This example illustrates the use of computed constraints

The 'Value 2' field will only allow each item in the dropdown to be selected once, no matter how many times 'Value 2' appears on the page.

For each selection made in a 'Value 2' field, that value will be added as a selectable option in the 'Value 3' field.

" + "source": "

This example illustrates the use of computed constraints

The 'Value 2' field will only allow each item in the dropdown to be selected once, no matter how many times 'Value 2' appears on the page.

For each selection made in a 'Value 2' field, that value will be added as a selectable option in the 'Value 3' field.

Note also that the constraints for 'value1' include a parameter that references a form variable. When that variable changes, the constraint pre-population is re-executed

" } ] }, diff --git a/grails-app/services/au/org/ala/ecodata/forms/ActivityFormService.groovy b/grails-app/services/au/org/ala/ecodata/forms/ActivityFormService.groovy index a18f232d..27d4922e 100644 --- a/grails-app/services/au/org/ala/ecodata/forms/ActivityFormService.groovy +++ b/grails-app/services/au/org/ala/ecodata/forms/ActivityFormService.groovy @@ -10,6 +10,7 @@ import org.grails.web.json.JSONObject class ActivityFormService { static final String ACTIVITY_FORM_PATH = '/activityForm' + static final String ACTIVITY_FORM_SEARCH_PATH = '/activityForm/search' def webService def grailsApplication @@ -66,6 +67,21 @@ class ActivityFormService { model } + /** + * Returns a Map with keys: [resp:List, statusCode:<>] + * @param criteria Used to build a GORM criteria query, e.g. [category:'paratoo'] + */ + Map searchActivityForms(Map criteria) { + String url = grailsApplication.config.getProperty('ecodata.service.url') + + ACTIVITY_FORM_SEARCH_PATH + Map result = webService.doPost(url, criteria) + if (!result || result.error) { + result = null + } + + result + } + private Map missingForm(String name, Integer version) { String message = "No activity form found with name ${name}" if (version) { diff --git a/grails-app/services/au/org/ala/ecodata/forms/WebService.groovy b/grails-app/services/au/org/ala/ecodata/forms/WebService.groovy index 745a8d00..50be027f 100644 --- a/grails-app/services/au/org/ala/ecodata/forms/WebService.groovy +++ b/grails-app/services/au/org/ala/ecodata/forms/WebService.groovy @@ -30,4 +30,8 @@ class WebService { def doPostWithParams(String url, Map params) { [:] } + + def doPost(String url, Map params) { + [:] + } } diff --git a/grails-app/taglib/au/org/ala/ecodata/forms/ModelJSTagLib.groovy b/grails-app/taglib/au/org/ala/ecodata/forms/ModelJSTagLib.groovy index e7c8c661..52ea12a8 100644 --- a/grails-app/taglib/au/org/ala/ecodata/forms/ModelJSTagLib.groovy +++ b/grails-app/taglib/au/org/ala/ecodata/forms/ModelJSTagLib.groovy @@ -130,7 +130,13 @@ class ModelJSTagLib { */ void renderDataModelItem(JSModelRenderContext ctx) { Map mod = ctx.dataModel - if (mod.computed) { + if (mod.dataType == 'date') { + dateViewModel(ctx) + } + else if (mod.dataType == 'time') { + timeViewModel(ctx) + } + else if (mod.computed && !mod.computed.source) { computedModel(ctx) } else if (mod.dataType == 'text') { @@ -151,12 +157,6 @@ class ModelJSTagLib { else if (mod.dataType == 'species') { speciesModel(ctx) } - else if (mod.dataType == 'date') { - dateViewModel(ctx) - } - else if (mod.dataType == 'time') { - timeViewModel(ctx) - } else if (mod.dataType == 'document') { documentViewModel(ctx) } @@ -200,7 +200,7 @@ class ModelJSTagLib { void renderLoad(List items, JSModelRenderContext ctx) { ctx.out << "self.loadData = function(data) {\n" - + out << INDENT * 1 << "var initialisers = [];\n" JSModelRenderContext child = ctx.createChildContext() Map attrs = ctx.attrs @@ -209,7 +209,7 @@ class ModelJSTagLib { child.dataModel = mod if (mod.dataType == 'list') { - out << INDENT * 1 << "self.load${mod.name}(data.${mod.name});\n" + out << INDENT * 1 << "initialisers = initialisers.concat(self.load${mod.name}(data.${mod.name}));\n" loadColumnTotals out, attrs, mod } else if (mod.dataType == 'matrix') { out << INDENT * 1 << "self.load${mod.name.capitalize()}(data.${mod.name});\n" @@ -217,7 +217,7 @@ class ModelJSTagLib { renderInitialiser(child) } } - + out << INDENT * 1 << "return initialisers;\n" ctx.out << "};\n" } @@ -266,9 +266,12 @@ class ModelJSTagLib { out << INDENT*4 << "${ctx.propertyPath}['${mod.name}'](ecodata.forms.orDefault(data['${mod.name}'], '${attrs.user.displayName}'));\n" } else { if (requiresMetadataExtender(mod)) { - out << INDENT*4 << "${ctx.propertyPath}['${mod.name}'].load(${value});\n" + out << INDENT*4 << "initialisers.push(${ctx.propertyPath}['${mod.name}'].load(${value}));\n" + } + else { + out << INDENT*4 << "${ctx.propertyPath}['${mod.name}'](${value});\n" } - out << INDENT*4 << "${ctx.propertyPath}['${mod.name}'](${value});\n" + } } else if (mod.dataType in ['image', 'photoPoints', 'audio', 'set']) { @@ -298,7 +301,7 @@ class ModelJSTagLib { if (data.${mod.name} && typeof data.${mod.name} !== 'undefined') { self.data.${mod.name}(data.${mod.name}); } else { - self.loadActivitySite(); + self.loadActivitySite({decimalLatitude: data.${mod.name}Latitude, decimalLongitude: data.${mod.name}Longitude}); } if (data.${mod.name}Accuracy){ @@ -528,8 +531,6 @@ class ModelJSTagLib { } renderLoad(ctx.dataModel.columns, childCtx) - out << INDENT*4 << "self.loadData(data || {});\n" - out << INDENT*2 << "};\n" } @@ -569,6 +570,9 @@ class ModelJSTagLib { if (requiresMetadataExtender(ctx.dataModel)) { extenders.add("{metadata:{metadata:self.dataModel['${ctx.fieldName()}'], context:self.\$context, config:config}}") } + if (ctx.dataModel.computed?.source) { + extenders.add("{dataLoader:true}") + } extenders.each { extenderJS += ".extend(${it})" @@ -578,7 +582,7 @@ class ModelJSTagLib { } private boolean requiresMetadataExtender(Map dataModel) { - dataModel.dataType == 'feature' || dataModel.behaviour || dataModel.warning || dataModel.constraints || dataModel.displayOptions || (dataModel.validate instanceof List) || dataModel.scores + dataModel.dataType == 'feature' || dataModel.behaviour || dataModel.warning || dataModel.constraints || dataModel.displayOptions || (dataModel.validate instanceof List) || dataModel.scores || dataModel.computed?.source } @@ -620,11 +624,22 @@ class ModelJSTagLib { def numberViewModel(JSModelRenderContext ctx) { int decimalPlaces = ctx.dataModel.decimalPlaces ?: 2 - observable(ctx, ["{numericString:${decimalPlaces}}"]) + + Map options = new HashMap(ctx.viewModel()?.displayOptions ?: [:]) + options.decimalPlaces = decimalPlaces + String optionString = (options as JSON).toString() + observable(ctx, ["{numericString:${optionString}}"]) } def dateViewModel(JSModelRenderContext ctx) { - observable(ctx, ["{simpleDate: false}"]) + List extenders = ["{simpleDate: {includeTime:false}}"] + if (ctx.dataModel.computed) { + extenders = ["{simpleDate: {includeTime:false, readOnly:true}}"] + computedModel(ctx, extenders) + } + else { + observable(ctx, extenders) + } } def booleanViewModel(JSModelRenderContext ctx) { @@ -670,7 +685,7 @@ class ModelJSTagLib { observable(ctx, ["{feature:config}"]) } - def computedModel(JSModelRenderContext ctx) { + def computedModel(JSModelRenderContext ctx, List extenders = []) { // TODO computed values within tables are rendered differently to values outside tables for historical reasons // This should be tidied up. @@ -681,10 +696,11 @@ class ModelJSTagLib { computedValueRenderer.computedViewModel(ctx.out, ctx.attrs, ctx.dataModel, ctx.propertyPath, ctx.propertyPath) } - if (requiresMetadataExtender(ctx.dataModel)) { - ctx.out << INDENT*3 << "${ctx.propertyPath}.${ctx.dataModel.name} = ${ctx.propertyPath}.${ctx.dataModel.name}${extenderJS(ctx, [])};\n" + if (extenders || requiresMetadataExtender(ctx.dataModel)) { + ctx.out << INDENT*3 << "${ctx.propertyPath}.${ctx.dataModel.name} = ${ctx.propertyPath}.${ctx.dataModel.name}${extenderJS(ctx, extenders)};\n" } + } def audioModel(JSModelRenderContext ctx) { @@ -734,13 +750,13 @@ class ModelJSTagLib { boolean userAddedRows = Boolean.valueOf(viewModel?.userAddedRows) def defaultRows = [] model.defaultRows?.eachWithIndex { row, i -> - defaultRows << INDENT*5 + "${ctx.propertyPath}.${model.name}.addRow(${row.toString()});" + defaultRows << INDENT*5 + "rowInitialisers = rowInitialisers.concat(${ctx.propertyPath}.${model.name}.addRow(${row.toString()}));" } def insertDefaultModel = defaultRows.join('\n') // If there are no default rows, insert a single blank row and make it available for editing. if (attrs.edit && model.defaultRows == null) { - insertDefaultModel = "${ctx.propertyPath}.${model.name}.addRow();" + insertDefaultModel = "rowInitialisers = rowInitialisers.concat(${ctx.propertyPath}.${model.name}.addRow());" } out << """var context = _.extend({}, context, {parent:self, listName:'${model.name}'});""" @@ -748,7 +764,9 @@ class ModelJSTagLib { observableArray(ctx, [extender], false) out << """ ${ctx.propertyPath}.${model.name}.loadDefaults = function() { + var rowInitialisers = []; ${insertDefaultModel} + return rowInitialisers; }; """ diff --git a/grails-app/views/output/_dateDataTypeEditModelTemplate.gsp b/grails-app/views/output/_dateDataTypeEditModelTemplate.gsp index bc091f23..5355b7e3 100644 --- a/grails-app/views/output/_dateDataTypeEditModelTemplate.gsp +++ b/grails-app/views/output/_dateDataTypeEditModelTemplate.gsp @@ -1,5 +1,5 @@
- +
diff --git a/karma.conf.js b/karma.conf.js index d4667b71..1ef19cce 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -75,7 +75,7 @@ module.exports = function (config) { 'type':"text", check: { global: { - lines: 43 + lines: 47.6 } } }, diff --git a/package-lock.json b/package-lock.json index 39cb31c6..853bffbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "ecodata-client-plugin", - "version": "4.0", + "name": "@atlasoflivingaustralia/ecodata-client-plugin", + "version": "6.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "ecodata-client-plugin", - "version": "4.0", + "name": "@atlasoflivingaustralia/ecodata-client-plugin", + "version": "6.2.0", "dependencies": { "bootstrap": "^4.6.0", "browserify": "^16.2.3" @@ -19,18 +19,17 @@ "@turf/convex": "^6.0.2", "@turf/length": "^6.0.2", "@turf/simplify": "^5.1.5", - "chromedriver": "^117.0.3", + "chromedriver": "121.0.0", "geojson2svg": "^1.2.3", "handlebars": "^4.7.7", "jasmine-ajax": "^4.0.0", "jasmine-core": "^5.1.1", "jasmine-jquery": "^2.1.1", - "jquery": "^3.6.0", + "jquery": "^3.6.2", "karma": "^6.4.2", "karma-chrome-launcher": "^3.1.0", "karma-coverage": "^2.2.1", "karma-jasmine": "^4.0.1", - "karma-verbose-reporter": "^0.0.8", "knockout": "^3.5.0", "leaflet": "^1.4.0", "leaflet-draw": "^1.0.4", @@ -51,12 +50,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -64,31 +63,31 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.15.tgz", - "integrity": "sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", + "@babel/generator": "^7.23.3", "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.22.15", - "@babel/helpers": "^7.22.15", - "@babel/parser": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15", - "convert-source-map": "^1.7.0", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", @@ -103,9 +102,9 @@ } }, "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "node_modules/@babel/core/node_modules/debug": { @@ -132,12 +131,12 @@ "dev": true }, "node_modules/@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", "dev": true, "dependencies": { - "@babel/types": "^7.22.15", + "@babel/types": "^7.23.4", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -163,22 +162,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -209,16 +208,16 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", - "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.15" + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -252,18 +251,18 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -279,26 +278,26 @@ } }, "node_modules/@babel/helpers": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", - "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", + "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.23.4", + "@babel/types": "^7.23.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, @@ -307,9 +306,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -333,19 +332,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", - "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15", + "@babel/parser": "^7.23.4", + "@babel/types": "^7.23.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -377,13 +376,13 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -447,9 +446,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -465,10 +464,16 @@ "node": ">=6" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true + }, "node_modules/@testim/chrome-version": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.3.tgz", - "integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz", + "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", "dev": true }, "node_modules/@turf/area": { @@ -617,12 +622,6 @@ "@turf/helpers": "^5.1.5" } }, - "node_modules/@types/component-emitter": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", - "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==", - "dev": true - }, "node_modules/@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -630,10 +629,13 @@ "dev": true }, "node_modules/@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/node": { "version": "14.6.4", @@ -769,13 +771,14 @@ } }, "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" } }, "node_modules/assert": { @@ -806,12 +809,12 @@ "dev": true }, "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -1044,28 +1047,80 @@ } }, "node_modules/browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dependencies": { - "bn.js": "^4.1.0", + "bn.js": "^5.0.0", "randombytes": "^2.0.1" } }, + "node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, "node_modules/browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/browserify-sign/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, + "node_modules/browserify-sign/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", @@ -1113,9 +1168,9 @@ "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" }, "node_modules/browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "dev": true, "funding": [ { @@ -1132,10 +1187,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -1196,9 +1251,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001527", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001527.tgz", - "integrity": "sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ==", + "version": "1.0.30001564", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", + "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", "dev": true, "funding": [ { @@ -1257,19 +1312,19 @@ } }, "node_modules/chromedriver": { - "version": "117.0.3", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-117.0.3.tgz", - "integrity": "sha512-c2rk2eGK5zZFBJMdviUlAJfQEBuPNIKfal4+rTFVYAmrWbMPYAqPozB+rIkc1lDP/Ryw44lPiqKglrI01ILhTQ==", + "version": "121.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-121.0.0.tgz", + "integrity": "sha512-ZIKEdZrQAfuzT/RRofjl8/EZR99ghbdBXNTOcgJMKGP6N/UL6lHUX4n6ONWBV18pDvDFfQJ0x58h5AdOaXIOMw==", "dev": true, "hasInstallScript": true, "dependencies": { - "@testim/chrome-version": "^1.1.3", - "axios": "^1.4.0", - "compare-versions": "^6.0.0", + "@testim/chrome-version": "^1.1.4", + "axios": "^1.6.5", + "compare-versions": "^6.1.0", "extract-zip": "^2.0.1", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^1.1.0", - "tcp-port-used": "^1.0.1" + "tcp-port-used": "^1.0.2" }, "bin": { "chromedriver": "bin/chromedriver" @@ -1279,12 +1334,20 @@ } }, "node_modules/chromedriver/node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/chromedriver/node_modules/extract-zip": { @@ -1349,15 +1412,6 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -1397,15 +1451,9 @@ "optional": true }, "node_modules/compare-versions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.0.0.tgz", - "integrity": "sha512-s2MzYxfRsE9f/ow8hjn7ysa7pod1xhHdQMsgiJtKx6XSNf4x2N1KG4fjrkUmXcP/e9Y2ZX4zB6sHIso0Lm6evQ==", - "dev": true - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", "dev": true }, "node_modules/concat-map": { @@ -1594,9 +1642,9 @@ } }, "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "node_modules/defined": { @@ -1723,9 +1771,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.509", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.509.tgz", - "integrity": "sha512-G5KlSWY0zzhANtX15tkikHl4WB7zil2Y65oT52EZUL194abjUXBZym12Ht7Bhuwm/G3LJFEqMADyv2Cks56dmg==", + "version": "1.4.594", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.594.tgz", + "integrity": "sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==", "dev": true }, "node_modules/elliptic": { @@ -1772,9 +1820,9 @@ } }, "node_modules/engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -1786,16 +1834,16 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "ws": "~8.11.0" }, "engines": { "node": ">=10.0.0" } }, "node_modules/engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -1921,9 +1969,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true, "funding": [ { @@ -2342,12 +2390,12 @@ } }, "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/is-binary-path": { @@ -2404,14 +2452,14 @@ "dev": true }, "node_modules/is2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.1.tgz", - "integrity": "sha512-+WaJvnaA7aJySz2q/8sLjMb2Mw14KTplHmSwcSpZ/fWJPkUmqw3YTzSWbPJ7OAwRvdYTWF2Wg+yYJ1AdP5Z8CA==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz", + "integrity": "sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==", "dev": true, "dependencies": { "deep-is": "^0.1.3", - "ip-regex": "^2.1.0", - "is-url": "^1.2.2" + "ip-regex": "^4.1.0", + "is-url": "^1.2.4" }, "engines": { "node": ">=v0.10.0" @@ -2441,9 +2489,9 @@ "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "engines": { "node": ">=8" @@ -2569,9 +2617,9 @@ "dev": true }, "node_modules/jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", + "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -2733,18 +2781,6 @@ "integrity": "sha512-Hu1dmuoGcZ7AfyynN3LsfruwMbxMALMka+YtZeGoLuDEySVmVAPaonkNoBRIw/ectu8b9tVQCJNgp4a4knp+tg==", "dev": true }, - "node_modules/karma-verbose-reporter": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/karma-verbose-reporter/-/karma-verbose-reporter-0.0.8.tgz", - "integrity": "sha512-wHgevIcEpfgKwR3CnWd8t1ErzWeVlctO7ZtXkKFR1inb006ogz+7ZKg95eIVOnHCYWL3Gdy1dRMOGjVP0n4MlA==", - "dev": true, - "dependencies": { - "colors": "1.4.0" - }, - "peerDependencies": { - "karma": ">=0.12" - } - }, "node_modules/karma/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3273,15 +3309,15 @@ } }, "node_modules/parse-asn1": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dependencies": { - "asn1.js": "^4.0.0", + "asn1.js": "^5.2.0", "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, "node_modules/parseurl": { @@ -3628,8 +3664,7 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { "version": "6.3.1", @@ -3692,36 +3727,38 @@ "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" }, "node_modules/socket.io": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.1.tgz", - "integrity": "sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.0.4" + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "dependencies": { + "ws": "~8.11.0" + } }, "node_modules/socket.io-parser": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz", - "integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "dependencies": { - "@types/component-emitter": "^1.2.10", - "component-emitter": "~1.3.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" }, "engines": { @@ -3905,22 +3942,30 @@ } }, "node_modules/tcp-port-used": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.1.tgz", - "integrity": "sha512-rwi5xJeU6utXoEIiMvVBMc9eJ2/ofzB+7nLOdnZuFTmNCLqRiQh2sMG9MqCxHU/69VC/Fwp5dV9306Qd54ll1Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz", + "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==", "dev": true, "dependencies": { - "debug": "4.1.0", - "is2": "2.0.1" + "debug": "4.3.1", + "is2": "^2.0.6" } }, "node_modules/tcp-port-used/node_modules/debug": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", - "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/tcp-port-used/node_modules/ms": { @@ -4115,9 +4160,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -4216,9 +4261,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -4273,38 +4318,38 @@ } }, "@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", "dev": true, "requires": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" } }, "@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", "dev": true }, "@babel/core": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.15.tgz", - "integrity": "sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", + "@babel/generator": "^7.23.3", "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.22.15", - "@babel/helpers": "^7.22.15", - "@babel/parser": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15", - "convert-source-map": "^1.7.0", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", @@ -4312,9 +4357,9 @@ }, "dependencies": { "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "debug": { @@ -4335,12 +4380,12 @@ } }, "@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", "dev": true, "requires": { - "@babel/types": "^7.22.15", + "@babel/types": "^7.23.4", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -4360,19 +4405,19 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { @@ -4394,16 +4439,16 @@ } }, "@babel/helper-module-transforms": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", - "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.15" + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/helper-simple-access": { @@ -4425,15 +4470,15 @@ } }, "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -4443,31 +4488,31 @@ "dev": true }, "@babel/helpers": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", - "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", + "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", "dev": true, "requires": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.23.4", + "@babel/types": "^7.23.4" } }, "@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", "dev": true }, "@babel/template": { @@ -4482,19 +4527,19 @@ } }, "@babel/traverse": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", - "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15", + "@babel/parser": "^7.23.4", + "@babel/types": "^7.23.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -4517,13 +4562,13 @@ } }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -4569,9 +4614,9 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.1.0", @@ -4584,10 +4629,16 @@ "integrity": "sha512-dEFzJiGg2O6+vsgJxt/6ILXewWHWBKQUWyj2u1BiRlYKLvGTO1CV2NlwiTkMOsXEwRSSdFV+WoCY9N9Nx34+Ew==", "dev": true }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true + }, "@testim/chrome-version": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.3.tgz", - "integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz", + "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", "dev": true }, "@turf/area": { @@ -4740,12 +4791,6 @@ } } }, - "@types/component-emitter": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", - "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==", - "dev": true - }, "@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -4753,10 +4798,13 @@ "dev": true }, "@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "requires": { + "@types/node": "*" + } }, "@types/node": { "version": "14.6.4", @@ -4862,13 +4910,14 @@ } }, "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" } }, "assert": { @@ -4901,12 +4950,12 @@ "dev": true }, "axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dev": true, "requires": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -5143,26 +5192,62 @@ } }, "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "requires": { - "bn.js": "^4.1.0", + "bn.js": "^5.0.0", "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + } } }, "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "requires": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } } }, "browserify-zlib": { @@ -5174,15 +5259,15 @@ } }, "browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "update-browserslist-db": "^1.0.13" } }, "buffer-crc32": { @@ -5228,9 +5313,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001527", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001527.tgz", - "integrity": "sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ==", + "version": "1.0.30001564", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", + "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", "dev": true }, "chalk": { @@ -5261,27 +5346,27 @@ } }, "chromedriver": { - "version": "117.0.3", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-117.0.3.tgz", - "integrity": "sha512-c2rk2eGK5zZFBJMdviUlAJfQEBuPNIKfal4+rTFVYAmrWbMPYAqPozB+rIkc1lDP/Ryw44lPiqKglrI01ILhTQ==", + "version": "121.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-121.0.0.tgz", + "integrity": "sha512-ZIKEdZrQAfuzT/RRofjl8/EZR99ghbdBXNTOcgJMKGP6N/UL6lHUX4n6ONWBV18pDvDFfQJ0x58h5AdOaXIOMw==", "dev": true, "requires": { - "@testim/chrome-version": "^1.1.3", - "axios": "^1.4.0", - "compare-versions": "^6.0.0", + "@testim/chrome-version": "^1.1.4", + "axios": "^1.6.5", + "compare-versions": "^6.1.0", "extract-zip": "^2.0.1", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^1.1.0", - "tcp-port-used": "^1.0.1" + "tcp-port-used": "^1.0.2" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "extract-zip": { @@ -5337,12 +5422,6 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, "combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -5378,15 +5457,9 @@ "optional": true }, "compare-versions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.0.0.tgz", - "integrity": "sha512-s2MzYxfRsE9f/ow8hjn7ysa7pod1xhHdQMsgiJtKx6XSNf4x2N1KG4fjrkUmXcP/e9Y2ZX4zB6sHIso0Lm6evQ==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", "dev": true }, "concat-map": { @@ -5554,9 +5627,9 @@ } }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "defined": { @@ -5660,9 +5733,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.509", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.509.tgz", - "integrity": "sha512-G5KlSWY0zzhANtX15tkikHl4WB7zil2Y65oT52EZUL194abjUXBZym12Ht7Bhuwm/G3LJFEqMADyv2Cks56dmg==", + "version": "1.4.594", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.594.tgz", + "integrity": "sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==", "dev": true }, "elliptic": { @@ -5708,9 +5781,9 @@ } }, "engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -5722,7 +5795,7 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "ws": "~8.11.0" }, "dependencies": { "debug": { @@ -5743,9 +5816,9 @@ } }, "engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", "dev": true }, "ent": { @@ -5833,9 +5906,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true }, "form-data": { @@ -6159,9 +6232,9 @@ } }, "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", "dev": true }, "is-binary-path": { @@ -6206,14 +6279,14 @@ "dev": true }, "is2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.1.tgz", - "integrity": "sha512-+WaJvnaA7aJySz2q/8sLjMb2Mw14KTplHmSwcSpZ/fWJPkUmqw3YTzSWbPJ7OAwRvdYTWF2Wg+yYJ1AdP5Z8CA==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz", + "integrity": "sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==", "dev": true, "requires": { "deep-is": "^0.1.3", - "ip-regex": "^2.1.0", - "is-url": "^1.2.2" + "ip-regex": "^4.1.0", + "is-url": "^1.2.4" } }, "isarray": { @@ -6234,9 +6307,9 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true }, "istanbul-lib-instrument": { @@ -6337,9 +6410,9 @@ "dev": true }, "jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", + "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==" }, "js-tokens": { "version": "4.0.0", @@ -6577,15 +6650,6 @@ } } }, - "karma-verbose-reporter": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/karma-verbose-reporter/-/karma-verbose-reporter-0.0.8.tgz", - "integrity": "sha512-wHgevIcEpfgKwR3CnWd8t1ErzWeVlctO7ZtXkKFR1inb006ogz+7ZKg95eIVOnHCYWL3Gdy1dRMOGjVP0n4MlA==", - "dev": true, - "requires": { - "colors": "1.4.0" - } - }, "knockout": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/knockout/-/knockout-3.5.0.tgz", @@ -6907,15 +6971,15 @@ } }, "parse-asn1": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "requires": { - "asn1.js": "^4.0.0", + "asn1.js": "^5.2.0", "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, "parseurl": { @@ -7209,8 +7273,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { "version": "6.3.1", @@ -7264,17 +7327,17 @@ "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" }, "socket.io": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.1.tgz", - "integrity": "sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.0.4" + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" }, "dependencies": { "debug": { @@ -7295,19 +7358,21 @@ } }, "socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "requires": { + "ws": "~8.11.0" + } }, "socket.io-parser": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz", - "integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "requires": { - "@types/component-emitter": "^1.2.10", - "component-emitter": "~1.3.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" }, "dependencies": { @@ -7441,22 +7506,22 @@ } }, "tcp-port-used": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.1.tgz", - "integrity": "sha512-rwi5xJeU6utXoEIiMvVBMc9eJ2/ofzB+7nLOdnZuFTmNCLqRiQh2sMG9MqCxHU/69VC/Fwp5dV9306Qd54ll1Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz", + "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==", "dev": true, "requires": { - "debug": "4.1.0", - "is2": "2.0.1" + "debug": "4.3.1", + "is2": "^2.0.6" }, "dependencies": { "debug": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", - "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -7606,9 +7671,9 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "requires": { "escalade": "^3.1.1", @@ -7677,9 +7742,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index 9fc012b7..0a816328 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,15 @@ { - "name": "ecodata-client-plugin", - "version": "4.0", + "name": "@atlasoflivingaustralia/ecodata-client-plugin", + "version": "6.2.0", + "repository": { + "type": "git", + "url": "https://github.com/AtlasOfLivingAustralia/ecodata-client-plugin.git" + }, + "publishConfig": { + "registry": "https://npm.pkg.github.com/" + }, "description": "Karma / jasmine configuration for testing project javascript", "main": "test/unit/javascript", - "private": true, "directories": { "test": "test" }, @@ -15,13 +21,13 @@ "@turf/convex": "^6.0.2", "@turf/length": "^6.0.2", "@turf/simplify": "^5.1.5", - "chromedriver": "^117.0.3", + "chromedriver": "121.0.0", "geojson2svg": "^1.2.3", "handlebars": "^4.7.7", "jasmine-ajax": "^4.0.0", "jasmine-core": "^5.1.1", "jasmine-jquery": "^2.1.1", - "jquery": "^3.6.0", + "jquery": "^3.6.2", "karma": "^6.4.2", "karma-chrome-launcher": "^3.1.0", "karma-coverage": "^2.2.1", diff --git a/src/integration-test/groovy/au/org/ala/ecodata/forms/ImageTypeSpec.groovy b/src/integration-test/groovy/au/org/ala/ecodata/forms/ImageTypeSpec.groovy index 9a995a1c..0e82442b 100644 --- a/src/integration-test/groovy/au/org/ala/ecodata/forms/ImageTypeSpec.groovy +++ b/src/integration-test/groovy/au/org/ala/ecodata/forms/ImageTypeSpec.groovy @@ -4,7 +4,6 @@ import geb.spock.GebReportingSpec import grails.testing.mixin.integration.Integration import org.springframework.boot.test.context.SpringBootTest import pages.PreviewPage - @Integration @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) class ImageTypeSpec extends GebReportingSpec { diff --git a/src/integration-test/resources/GebConfig.groovy b/src/integration-test/resources/GebConfig.groovy index 2f0bfe23..59693179 100644 --- a/src/integration-test/resources/GebConfig.groovy +++ b/src/integration-test/resources/GebConfig.groovy @@ -6,7 +6,7 @@ if (!System.getProperty("webdriver.chrome.driver")) { System.setProperty("webdriver.chrome.driver", "node_modules/chromedriver/bin/chromedriver") } driver = { new ChromeDriver() } -baseUrl = 'http://devt.ala.org.au:8087/' +baseUrl = 'http://localhost:8087/' atCheckWaiting = true waiting { timeout = 20 diff --git a/src/main/groovy/au/org/ala/ecodata/forms/ComputedValueRenderer.groovy b/src/main/groovy/au/org/ala/ecodata/forms/ComputedValueRenderer.groovy index 0ad64c18..bfbc246a 100644 --- a/src/main/groovy/au/org/ala/ecodata/forms/ComputedValueRenderer.groovy +++ b/src/main/groovy/au/org/ala/ecodata/forms/ComputedValueRenderer.groovy @@ -17,7 +17,20 @@ class ComputedValueRenderer { String expression = computed.expression int decimalPlaces = getNumberOfDecimalPlaces(model, computed) - out << "return ecodata.forms.expressionEvaluator.evaluate('${expression}', ${dependantContext}, ${decimalPlaces});\n"; + String expressionType + switch (model.dataType) { + case 'text': + case 'date': + expressionType = 'evaluateString' + break + case 'stringList': + expressionType = 'evaluateArray' + break + default: + expressionType = "evaluate" + } + out << "var expression = '${expression.encodeAsJavaScript()}';\n" + out << "return ecodata.forms.expressionEvaluator.${expressionType}(expression, ${dependantContext}, ${decimalPlaces});\n"; } private int getNumberOfDecimalPlaces(Map model, Map computed) { @@ -37,40 +50,54 @@ class ComputedValueRenderer { } def computedObservable(model, propertyContext, dependantContext, out) { - out << INDENT*5 << "${propertyContext}.${model.name} = ko.computed(function () {\n" + + boolean needsDefer = model.computed.defer + String endFunction = "});\n" + String computedParams = "function ()" + if (needsDefer) { + computedParams = "{deferEvaluation:true, read:function ()" + endFunction = "}});\n" + } + + out << INDENT*5 << "${propertyContext}.${model.name} = ko.computed($computedParams {\n" if (model.computed.expression) { renderJSExpression(model, "self", out) } else { - // must be at least one dependant - def numbers = [] - def checkNumberness = [] - model.computed.dependents.each { - def ref = it - def path = dependantContext - if (ref.startsWith('$')) { - ref = ref[1..-1] - path = "self.data" - } - numbers << "Number(${path}.${ref}())" - checkNumberness << "isNaN(Number(${path}.${ref}()))" - } - out << INDENT * 6 << "if (" + checkNumberness.join(' || ') + ") { return 0; }\n" - if (model.computed.operation == 'divide') { - // can't divide by zero - out << INDENT * 6 << "if (${numbers[-1]} === 0) { return 0; }\n" - } - def expression = numbers.join(" ${operators[model.computed.operation]} ") - if (model.computed.rounding) { - expression = "neat_number(${expression},${model.computed.rounding})" - } - out << INDENT * 6 << "return " + expression + ";\n" + renderLegacyComputed(model, dependantContext, out) } - out << INDENT * 5 << "});\n" + out << INDENT*5 << endFunction } + private void renderLegacyComputed(model, dependantContext, out) { + // must be at least one dependant + def numbers = [] + def checkNumberness = [] + model.computed.dependents.each { + def ref = it + def path = dependantContext + if (ref.startsWith('$')) { + ref = ref[1..-1] + path = "self.data" + } + numbers << "Number(${path}.${ref}())" + checkNumberness << "isNaN(Number(${path}.${ref}()))" + } + out << INDENT * 6 << "if (" + checkNumberness.join(' || ') + ") { return 0; }\n" + if (model.computed.operation == 'divide') { + // can't divide by zero + out << INDENT * 6 << "if (${numbers[-1]} === 0) { return 0; }\n" + } + def expression = numbers.join(" ${operators[model.computed.operation]} ") + if (model.computed.rounding) { + expression = "neat_number(${expression},${model.computed.rounding})" + } + out << INDENT * 6 << "return " + expression + ";\n" + } + + def computedViewModel(out, attrs, model, propertyContext, dependantContext) { computedViewModel(out, attrs, model, propertyContext, dependantContext, null) } diff --git a/src/main/groovy/au/org/ala/ecodata/forms/ConstraintType.groovy b/src/main/groovy/au/org/ala/ecodata/forms/ConstraintType.groovy index 17067e43..7681e362 100644 --- a/src/main/groovy/au/org/ala/ecodata/forms/ConstraintType.groovy +++ b/src/main/groovy/au/org/ala/ecodata/forms/ConstraintType.groovy @@ -12,7 +12,8 @@ enum ConstraintType { ENABLE("enable", true, false), ENABLE_AND_CLEAR("enableAndClear", true, false), DISABLE("disable", true, false), - CONDITIONAL_VALIDATION("conditionalValidation", false, false) + CONDITIONAL_VALIDATION("conditionalValidation", false, false), + PRE_POPULATE("triggerPrePopulate", false, false) /** The knockout data binding that implements this constraint */ String binding diff --git a/src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy b/src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy index a3b44ba3..bcf9b521 100644 --- a/src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy +++ b/src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy @@ -86,7 +86,7 @@ public class EditModelWidgetRenderer implements ModelWidgetRenderer { @Override void renderSimpleDate(WidgetRenderContext context) { context.databindAttrs.add 'datepicker', context.source + '.date' - context.writer << "" + context.writer << "" } @Override @@ -116,6 +116,9 @@ public class EditModelWidgetRenderer implements ModelWidgetRenderer { context.databindAttrs.add 'optionsCaption', '"Please select"' context.attributes.addSpan("form-control form-control-sm") + if (isReadOnly(context)) { // HTML Select elements don't support the readonly attribute so we add disabled. This will break validation though. + context.databindAttrs.add('disableClick', 'true') + } context.writer << "" } @@ -134,10 +137,13 @@ public class EditModelWidgetRenderer implements ModelWidgetRenderer { context.writer << "
" } + private static boolean isReadOnly(WidgetRenderContext context) { + context.model.readonly || context.dataModel.computed + } @Override void renderSelectMany(WidgetRenderContext context) { - if (context.model.readonly) { + if (isReadOnly(context)) { renderSelectManyAsString(context) } else { @@ -147,16 +153,23 @@ public class EditModelWidgetRenderer implements ModelWidgetRenderer { @Override void renderSelect2Many(WidgetRenderContext context) { - context.databindAttrs.add 'options', context.source + '.constraints' - context.databindAttrs.add 'optionsValue', context.source + '.constraints.value' - context.databindAttrs.add 'optionsText', context.source + '.constraints.text' - String options = "{value: ${context.source}, tags:true, allowClear:false}" - if (context.model.displayOptions) { - options = "_.extend({value:${context.source}}, ${context.source}.displayOptions)" + if (isReadOnly(context)) { + renderSelectManyAsString(context) } - context.databindAttrs.add 'multiSelect2', options - context.writer << "" + else { + context.databindAttrs.add 'options', context.source + '.constraints' + context.databindAttrs.add 'optionsValue', context.source + '.constraints.value' + context.databindAttrs.add 'optionsText', context.source + '.constraints.text' + + String options = "{value: ${context.source}, tags:true, allowClear:false}" + if (context.model.displayOptions) { + options = "_.extend({value:${context.source}}, ${context.source}.displayOptions)" + } + context.databindAttrs.add 'multiSelect2', options + context.writer << "" + } + } @Override diff --git a/src/main/groovy/au/org/ala/ecodata/forms/ValidationHelper.groovy b/src/main/groovy/au/org/ala/ecodata/forms/ValidationHelper.groovy index 2a04ab00..637ccf7c 100644 --- a/src/main/groovy/au/org/ala/ecodata/forms/ValidationHelper.groovy +++ b/src/main/groovy/au/org/ala/ecodata/forms/ValidationHelper.groovy @@ -92,7 +92,7 @@ class ValidationHelper { criteria.each { switch (it.rule) { case 'required': - if (model.type == 'selectMany') { + if (model.type == 'selectMany' && !model.readonly && !dataModel.readonly) { values << 'minCheckbox[1]' } else { diff --git a/src/test/groovy/au/org/ala/ecodata/forms/ActivityFormServiceSpec.groovy b/src/test/groovy/au/org/ala/ecodata/forms/ActivityFormServiceSpec.groovy index 6567ef25..0d8cba3d 100644 --- a/src/test/groovy/au/org/ala/ecodata/forms/ActivityFormServiceSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/forms/ActivityFormServiceSpec.groovy @@ -80,4 +80,12 @@ class ActivityFormServiceSpec extends Specification implements ServiceUnitTest