From f4b2677a5aeebffd816c0921cc61e4d0580f5e8f Mon Sep 17 00:00:00 2001 From: Davin Shearer Date: Thu, 19 Oct 2023 12:14:23 -0400 Subject: [PATCH] =?UTF-8?q?upgrade=20=CE=A9edit=E2=84=A2=20to=20v0.9.75?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 22 +- src/dataEditor/dataEditorClient.ts | 62 ++++-- .../CustomByteDisplay/DataLineFeed.svelte | 135 +++++++----- .../CustomByteDisplay/DataValue.svelte | 81 ++----- .../DataDisplays/Header/DisplayHeader.svelte | 6 +- .../Header/fieldsets/FileMetrics.svelte | 2 +- .../Header/fieldsets/SearchReplace.svelte | 33 ++- .../Header/fieldsets/SearchReplace.ts | 50 +++-- src/svelte/src/components/dataEditor.svelte | 5 +- src/svelte/src/components/globalStyles.css | 2 + src/svelte/src/stores/index.ts | 11 +- src/svelte/src/utilities/display.ts | 1 - src/svelte/src/utilities/highlights.ts | 193 ++++++++++++----- yarn.lock | 205 +++++++++++------- 14 files changed, 486 insertions(+), 322 deletions(-) diff --git a/package.json b/package.json index 185359bd0..e60527646 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "svelte:check": "svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@omega-edit/client": "0.9.73", + "@omega-edit/client": "0.9.75", "@viperproject/locate-java-home": "1.1.13", "@vscode/debugadapter": "1.63.0", "await-notify": "1.0.1", @@ -53,21 +53,21 @@ "jsonc-parser": "3.2.0", "semver": "7.5.4", "unzip-stream": "0.3.1", - "wait-port": "1.0.4", + "wait-port": "1.1.0", "xdg-app-paths": "8.3.0" }, "devDependencies": { "@tsconfig/svelte": "^5.0.2", "@types/glob": "^8.0.0", - "@types/mocha": "^10.0.1", - "@types/node": "^20.6.1", + "@types/mocha": "^10.0.3", + "@types/node": "^20.8.7", "@types/vscode": "^1.67.2", - "@types/vscode-webview": "^1.57.2", + "@types/vscode-webview": "^1.57.3", "@vscode/debugadapter-testsupport": "1.63.0", - "@vscode/test-electron": "2.3.4", - "@vscode/vsce": "2.21.0", - "chai": "^4.3.8", - "concurrently": "^8.2.1", + "@vscode/test-electron": "2.3.5", + "@vscode/vsce": "2.21.1", + "chai": "^4.3.10", + "concurrently": "^8.2.2", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", "css-minimizer-webpack-plugin": "^5.0.1", @@ -77,9 +77,9 @@ "prettier": "3.0.3", "prettier-plugin-svelte": "3.0.3", "run-func": "^3.0.0", - "sass": "^1.67.0", + "sass": "^1.69.4", "svelte": "^3.55.0", - "svelte-check": "^3.5.1", + "svelte-check": "^3.5.2", "svelte-loader": "^3.1.9", "svelte-preprocess": "^5.0.4", "ts-loader": "9.4.4", diff --git a/src/dataEditor/dataEditorClient.ts b/src/dataEditor/dataEditorClient.ts index 2cf0dbf29..b03b3a204 100644 --- a/src/dataEditor/dataEditorClient.ts +++ b/src/dataEditor/dataEditorClient.ts @@ -30,6 +30,7 @@ import { getClient, getClientVersion, getComputedFileSize, + getContentType, getCounts, getLogger, getServerHeartbeat, @@ -248,14 +249,17 @@ export class DataEditorClient implements vscode.Disposable { assert(this.omegaSessionId.length > 0, 'omegaSessionId is not set') addActiveSession(this.omegaSessionId) - this.contentType = createSessionResponse.hasContentType() - ? (createSessionResponse.getContentType() as string) - : 'unknown' - assert(this.contentType.length > 0, 'contentType is not set') - this.fileSize = createSessionResponse.hasFileSize() ? (createSessionResponse.getFileSize() as number) : 0 + + const contentTypeResponse = await getContentType( + this.omegaSessionId, + 0, + Math.min(1024, this.fileSize) + ) + this.contentType = contentTypeResponse.getContentType() + assert(this.contentType.length > 0, 'contentType is not set') } catch { const msg = `Failed to create session for ${this.fileToEdit}` getLogger().error({ @@ -669,12 +673,12 @@ async function createDataEditorWebviewPanel( configureOmegaEditPort() assert(omegaEditPort > 0, 'omega edit port not configured') - // only start uo the server if one is not already running + // only start up the server if one is not already running if (!(await checkServerListening(omegaEditPort, OMEGA_EDIT_HOST))) { await setupLogging() setAutoFixViewportDataLength(true) await serverStart() - client = getClient(omegaEditPort, OMEGA_EDIT_HOST) + client = await getClient(omegaEditPort, OMEGA_EDIT_HOST) assert( await checkServerListening(omegaEditPort, OMEGA_EDIT_HOST), 'server not listening' @@ -1138,9 +1142,9 @@ async function serverStart() { const animationInterval = 400 // ms per frame const animationFrames = ['', '.', '..', '...'] const animationIntervalId = setInterval(() => { - const frame = animationFrames[animationFrame % animationFrames.length] - statusBarItem.text = `${serverStartingText} ${frame}` - ++animationFrame + statusBarItem.text = `${serverStartingText} ${ + animationFrames[++animationFrame % animationFrames.length] + }` }, animationInterval) const config = vscode.workspace.getConfiguration('dataEditor') const logLevel = @@ -1152,6 +1156,8 @@ async function serverStart() { logLevel ) if (!fs.existsSync(logConfigFile)) { + clearInterval(animationIntervalId) + statusBarItem.dispose() throw new Error(`Log config file '${logConfigFile}' not found`) } @@ -1173,11 +1179,35 @@ async function serverStart() { }, SERVER_START_TIMEOUT * 1000) }), ])) as number | undefined + clearInterval(animationIntervalId) if (serverPid === undefined || serverPid <= 0) { + statusBarItem.dispose() throw new Error('Server failed to start or PID is invalid') } - const clientVersion = getClientVersion() - serverInfo = await getServerInfo() + // this makes sure the server if fully online and ready to take requests + statusBarItem.text = `Initializing Ωedit server on port ${omegaEditPort}` + for (let i = 1; i <= 60; ++i) { + try { + await getServerInfo() + break + } catch (err) { + statusBarItem.text = `Initializing Ωedit server on port ${omegaEditPort} (${i}/60)` + } + // wait 1 second before trying again + await new Promise((resolve) => { + setTimeout(() => { + resolve(true) + }, 1000) + }) + } + try { + serverInfo = await getServerInfo() + } catch (err) { + statusBarItem.dispose() + await serverStop() + throw new Error('Server failed to initialize') + } + statusBarItem.text = `Ωedit server on port ${omegaEditPort} initialized` const serverVersion = serverInfo.serverVersion // if the OS is not Windows, check that the server PID matches the one started // NOTE: serverPid is the PID of the server wrapper script on Windows @@ -1185,19 +1215,21 @@ async function serverStart() { !os.platform().toLowerCase().startsWith('win') && serverInfo.serverProcessId !== serverPid ) { + statusBarItem.dispose() throw new Error( `server PID mismatch ${serverInfo.serverProcessId} != ${serverPid}` ) } + const clientVersion = getClientVersion() if (serverVersion !== clientVersion) { + statusBarItem.dispose() throw new Error( `Server version ${serverVersion} and client version ${clientVersion} must match` ) } - // get an initial heartbeat to ensure the server is up and running + // get an initial heartbeat await getHeartbeat() - clearInterval(animationIntervalId) - statusBarItem.text = `Ωedit server v${serverVersion} started on port ${omegaEditPort} with PID ${serverInfo.serverProcessId}` + statusBarItem.text = `Ωedit server v${serverVersion} ready on port ${omegaEditPort} with PID ${serverInfo.serverProcessId}` setTimeout(() => { statusBarItem.dispose() }, 5000) diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte index 644ec8eae..dfd8ff098 100644 --- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte +++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte @@ -31,6 +31,8 @@ limitations under the License. seekOffsetInput, visableViewports, dataDislayLineAmount, + replaceQuery, + searchResultsUpdated, } from '../../../stores' import { EditByteModes, @@ -62,10 +64,12 @@ limitations under the License. type CSSThemeClass, } from '../../../utilities/colorScheme' import { - selectionHighlights, - searchResultsHighlights, - updateSearchResultsHighlights, - searchResultsUpdated, + CATEGORY_ONE_MASK, + CATEGORY_TWO_MASK, + viewportByteIndicators, + type ByteValueIndications, + IndicatorCategoryShift, + byteCategoryValue, } from '../../../utilities/highlights' import { bytesPerRow } from '../../../stores' export let awaitViewportSeek: boolean @@ -169,7 +173,7 @@ limitations under the License. bytes: Array highlight: 'even' | 'odd' } - + enum ViewportScrollDirection { DECREMENT = -1, NONE = 0, @@ -181,10 +185,13 @@ limitations under the License. let viewportDataContainer: HTMLDivElement let selectedByteElement: HTMLDivElement let themeClass: CSSThemeClass - let activeSelection: Uint8Array let lineTopFileOffset: number - let searchResults: Uint8Array + let makingSelection = false + $: { + makingSelection = + $selectionDataStore.startOffset >= 0 && $selectionDataStore.active === false + } onMount(() => { viewportDataContainer = document.getElementById( CONTAINER_ID @@ -215,13 +222,10 @@ limitations under the License. } $: { - activeSelection = $selectionHighlights - searchResults = $searchResultsHighlights if ( - (viewportData.fileOffset >= 0 && - !awaitViewportSeek && - $dataFeedLineTop >= 0) || - $searchResultsUpdated + viewportData.fileOffset >= 0 && + !awaitViewportSeek && + $dataFeedLineTop >= 0 ) { if ( viewportLines.length !== 0 && @@ -243,6 +247,11 @@ limitations under the License. } } $: byteElementWidth = byteDivWidthFromRadix(dataRadix) + $: { + viewportByteIndicators.updateSelectionIndications($selectionDataStore.startOffset, $selectionDataStore.endOffset) + viewportByteIndicators.updateSearchIndications($searchQuery.searchResults, $searchQuery.byteLength) + viewportByteIndicators.updateReplaceIndications($replaceQuery.results, viewportData.fileOffset) + } function generate_line_data( startIndex: number, @@ -359,21 +368,21 @@ limitations under the License. : atViewportHead && !atFileHead } - function mousedown(event: CustomEvent) { + function mousedown(event: ByteSelectionEvent) { selectionDataStore.update((selections) => { selections.active = false - selections.startOffset = event.detail.targetByte.offset + selections.startOffset = event.targetByte.offset selections.endOffset = -1 selections.originalEndOffset = -1 return selections }) } - function mouseup(event: CustomEvent) { + function mouseup(event: ByteSelectionEvent) { selectionDataStore.update((selections) => { selections.active = true - selections.endOffset = event.detail.targetByte.offset - selections.originalEndOffset = event.detail.targetByte.offset + selections.endOffset = event.targetByte.offset + selections.originalEndOffset = event.targetByte.offset adjust_event_offsets() return selections }) @@ -383,7 +392,7 @@ limitations under the License. return } - set_byte_selection(event.detail) + set_byte_selection(event) } function adjust_event_offsets() { @@ -471,6 +480,48 @@ limitations under the License. } } + function mouseover_handler(e: Event) { + if(!makingSelection) return + + const target = e.target as HTMLDivElement + let targetViewportIndex = parseInt(target.getAttribute('offset')!) + + selectionDataStore.update((selections) => { + selections.endOffset = targetViewportIndex + adjust_event_offsets() + return selections + }) + } + + function mouseclick_handler(e: Event) { + const type = e.type + const targetElement = e.target as HTMLDivElement + let targetViewportIndex = parseInt(targetElement.getAttribute('offset')!) + let byteText: string | undefined = targetElement.innerHTML + let byteValue: number = byteText === undefined ? -1 : parseInt(byteText) + + if (targetElement.id.includes('logical')) byteText = String.fromCharCode(byteValue) + let targetByte: ByteValue = { + offset: targetViewportIndex, + text: byteText, + value: byteValue + } + const byteSelectionEvent: ByteSelectionEvent = + { + targetElement: targetElement, + targetByte: targetByte, + fromViewport: targetElement.id.includes('logical') ? 'logical' : 'physical', + } + + switch(type) { + case 'mousedown': + mousedown(byteSelectionEvent) + break + case 'mouseup': + mouseup(byteSelectionEvent) + } + } + window.addEventListener('keydown', navigation_keydown_event) window.addEventListener('message', (msg) => { switch (msg.data.command) { @@ -485,16 +536,11 @@ limitations under the License. selectedByteElement = document.getElementById( $selectedByte.offset.toString() ) as HTMLDivElement - - updateSearchResultsHighlights( - $searchQuery.searchResults, - viewportData.fileOffset, - $searchQuery.byteLength - ) } break } }) + {#if $selectionDataStore.active && $editMode == EditByteModes.Single} @@ -508,7 +554,13 @@ limitations under the License. {/key} {/if} -
+ + + +
{#each viewportLines as viewportLine, i}
@@ -523,17 +575,12 @@ limitations under the License. {#each viewportLine.bytes as byte} > - activeSelection[byte.offset]} id={'physical'} - radix={dataRadix} + indicators={{ + cat1: byteCategoryValue($viewportByteIndicators[byte.offset] & CATEGORY_ONE_MASK, IndicatorCategoryShift.CategoryOne), + cat2: byteCategoryValue($viewportByteIndicators[byte.offset] & CATEGORY_TWO_MASK, IndicatorCategoryShift.CategoryTwo) }} width={byteElementWidth} disabled={byte.value === -1} - bind:selectionData={$selectionDataStore} - on:mouseup={mouseup} - on:mousedown={mousedown} /> {/each}
@@ -546,17 +593,12 @@ limitations under the License. {#each viewportLine.bytes as byte} > - activeSelection[byte.offset]} + indicators={{ + cat1: byteCategoryValue($viewportByteIndicators[byte.offset] & CATEGORY_ONE_MASK, IndicatorCategoryShift.CategoryOne), + cat2: byteCategoryValue($viewportByteIndicators[byte.offset] & CATEGORY_TWO_MASK, IndicatorCategoryShift.CategoryTwo) }} id={'logical'} - radix={dataRadix} width={byteElementWidth} disabled={byte.value === -1} - bind:selectionData={$selectionDataStore} - on:mouseup={mouseup} - on:mousedown={mousedown} /> {/each}
@@ -697,15 +739,6 @@ limitations under the License. flex-direction: column; margin: 0 5px; } - span.submit-bpr-input { - font-size: 14px; - cursor: pointer; - margin: 0 5px; - } - span.submit-bpr-input:hover { - font-weight: bold; - cursor: pointer; - } div.container { display: flex; flex-direction: column; diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte index ab12df431..f8a94298a 100644 --- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte +++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte @@ -15,61 +15,23 @@ See the License for the specific language governing permissions and limitations under the License. --> @@ -78,33 +40,22 @@ limitations under the License. {:else if id === 'physical'}
{byte.text}
{:else}
{latin1Undefined(byte.value) ? '' : String.fromCharCode(byte.value)}
@@ -118,7 +69,6 @@ limitations under the License. align-items: center; flex-direction: row; font-family: var(--monospace-font); - /* border-radius: 5px; */ border-style: solid; border-width: 2px; border-color: transparent; @@ -126,21 +76,20 @@ limitations under the License. text-align: center; transition: all 0.25s; } - div.byte.isSelected, + div.byte.selected, div.byte.isSearchResult, - div.byte.possibleSelection { + div.byte.isReplaceResult { border-radius: 5px; } - div.byte.isSelected { + div.byte.selected { background-color: var(--color-secondary-light); color: var(--color-secondary-darkest); } div.byte.isSearchResult { - background-color: var(--color-tertiary-light); - color: var(--color-secondary-darkest); + border-color: var(--color-search-result); } - div.byte.possibleSelection { - border-color: var(--color-secondary-light); + div.byte.isReplaceResult { + border-color: var(--color-replace-result); } div.byte:hover { border-color: var(--color-secondary-mid); diff --git a/src/svelte/src/components/DataDisplays/Header/DisplayHeader.svelte b/src/svelte/src/components/DataDisplays/Header/DisplayHeader.svelte index 4628e7858..86552922b 100644 --- a/src/svelte/src/components/DataDisplays/Header/DisplayHeader.svelte +++ b/src/svelte/src/components/DataDisplays/Header/DisplayHeader.svelte @@ -127,14 +127,14 @@ limitations under the License. {#if $displayRadix === RADIX_OPTIONS.Binary} {#each offsetLine as offset}
-
{offset}
-
{bitIndexStr}
+
{offset}
+
{bitIndexStr}
{/each} {:else} {#each offsetLine as offset}
- {offset} + {offset}
{/each} {/if} diff --git a/src/svelte/src/components/Header/fieldsets/FileMetrics.svelte b/src/svelte/src/components/Header/fieldsets/FileMetrics.svelte index 21dc3b1cc..62ff4c54c 100644 --- a/src/svelte/src/components/Header/fieldsets/FileMetrics.svelte +++ b/src/svelte/src/components/Header/fieldsets/FileMetrics.svelte @@ -19,7 +19,7 @@ limitations under the License. import FlexContainer from '../../layouts/FlexContainer.svelte' import { MessageCommand } from '../../../utilities/message' import { vscode } from '../../../utilities/vscode' - import { saveable, fileMetrics } from '../../../stores' + import { saveable, fileMetrics, replaceQuery } from '../../../stores' import { createEventDispatcher } from 'svelte' import SidePanel from '../../layouts/SidePanel.svelte' import ByteFrequencyGraph from '../../DataMetrics/DataMetrics.svelte' diff --git a/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte b/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte index 12c8c90b4..d73623ea5 100644 --- a/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte +++ b/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte @@ -42,13 +42,8 @@ limitations under the License. import { createEventDispatcher } from 'svelte' import { UIThemeCSSClass } from '../../../utilities/colorScheme' import ToggleableButton from '../../Inputs/Buttons/ToggleableButton.svelte' - import { - clearSearchResultsHighlights, - updateSearchResultsHighlights, - } from '../../../utilities/highlights' - import { viewport } from '../../../stores' import { EditActionRestrictions } from '../../../stores/configuration' - import { OffsetSearchType } from './SearchReplace' + import { OffsetSearchType, clear_queryable_results } from './SearchReplace' import Tooltip from '../../layouts/Tooltip.svelte' const eventDispatcher = createEventDispatcher() @@ -201,7 +196,8 @@ limitations under the License. searchStarted = false replaceStarted = false matchOffset = -1 - clearSearchResultsHighlights() + clear_queryable_results() + eventDispatcher('clearDataDisplays') } @@ -210,25 +206,24 @@ limitations under the License. // handle search results case MessageCommand.searchResults: if (msg.data.data.searchResults.length > 0) { - $searchQuery.searchResults = msg.data.data.searchResults - $searchQuery.byteLength = msg.data.data.searchDataBytesLength + searchQuery.updateSearchResults(msg.data.data) switch (direction) { case 'Home': - hasNext = msg.data.data.overflow + hasNext = $searchQuery.overflow hasPrev = false break case 'End': hasNext = false - hasPrev = msg.data.data.overflow + hasPrev = $searchQuery.overflow break case 'Forward': - hasNext = msg.data.data.overflow + hasNext = $searchQuery.overflow hasPrev = justReplaced ? preReplaceHasPrev : true justReplaced = false break case 'Backward': hasNext = true - hasPrev = msg.data.data.overflow + hasPrev = $searchQuery.overflow break } matchOffset = $searchQuery.searchResults[0] @@ -240,17 +235,12 @@ limitations under the License. showReplaceOptions = true showSearchOptions = false } - $searchQuery.overflow = msg.data.data.overflow } else { matchOffset = -1 $searchQuery.overflow = showSearchOptions = showReplaceOptions = false + searchQuery.clear() } searchStarted = replaceStarted = false - updateSearchResultsHighlights( - $searchQuery.searchResults, - $viewport.fileOffset, - $searchQuery.byteLength - ) $searchQuery.processing = false break @@ -259,8 +249,11 @@ limitations under the License. searchStarted = replaceStarted = false if (msg.data.data.replacementsCount > 0) { // subtract 1 from the next offset because search next will add 1 - clearSearchResultsHighlights() matchOffset = msg.data.data.nextOffset - 1 + replaceQuery.add_result({ + byteLength: msg.data.data.replaceDataBytesLength, + offset: msg.data.data.nextOffset - msg.data.data.replaceDataBytesLength + }) preReplaceHasPrev = hasPrev justReplaced = true searchNext() diff --git a/src/svelte/src/components/Header/fieldsets/SearchReplace.ts b/src/svelte/src/components/Header/fieldsets/SearchReplace.ts index e1f739b94..9ead5dbb0 100644 --- a/src/svelte/src/components/Header/fieldsets/SearchReplace.ts +++ b/src/svelte/src/components/Header/fieldsets/SearchReplace.ts @@ -16,8 +16,7 @@ */ import { SimpleWritable } from '../../../stores/localStore' -import { addressRadix, seekOffsetInput } from '../../../stores' -import { get } from 'svelte/store' +import { replaceQuery, searchQuery } from '../../../stores' export enum OffsetSearchType { ABSOLUTE, @@ -52,34 +51,51 @@ export class SearchQuery extends SimpleWritable { return query }) } - public updateSearchResults(offset?: number) { + public updateSearchResults(msgData: any) { this.update((query) => { - query.searchIndex = !offset - ? Math.abs( - (query.searchResults.length + query.searchIndex) % - query.searchResults.length - ) - : Math.abs( - (query.searchResults.length + offset) % query.searchResults.length - ) - - seekOffsetInput.update((_) => { - return query.searchResults[query.searchIndex].toString( - get(addressRadix) - ) - }) + query.searchResults = msgData.searchResults + query.byteLength = msgData.searchDataBytesLength + query.overflow = msgData.overflow return query }) } } +/** +Object that defines describes an instance of a replacement that occured during a Search & Replace query. +@param offset **File** offset of where the replacement occured. +@param byteLength Byte length of the replacement data. +*/ +export type DataReplacement = { + offset: number + byteLength: number +} + class ReplaceData implements QueryableData { input: string = '' processing: boolean = false isValid: boolean = false + results: Array = [] } export class ReplaceQuery extends SimpleWritable { protected init(): ReplaceData { return new ReplaceData() } + public add_result(result: DataReplacement) { + this.update((data) => { + data.results.push(result) + return data + }) + } + public clear() { + this.update((data) => { + data.results = [] + return data + }) + } +} + +export function clear_queryable_results() { + searchQuery.clear() + replaceQuery.clear() } diff --git a/src/svelte/src/components/dataEditor.svelte b/src/svelte/src/components/dataEditor.svelte index 32b52854b..33d89a12a 100644 --- a/src/svelte/src/components/dataEditor.svelte +++ b/src/svelte/src/components/dataEditor.svelte @@ -61,7 +61,6 @@ limitations under the License. ViewportData_t, } from './DataDisplays/CustomByteDisplay/BinaryData' import { byte_count_divisible_offset } from '../utilities/display' - import { clearSearchResultsHighlights } from '../utilities/highlights' import Help from './layouts/Help.svelte' $: $UIThemeCSSClass = $darkUITheme ? CSSThemeClass.Dark : CSSThemeClass.Light @@ -248,13 +247,13 @@ limitations under the License. function clearQueryableData() { searchQuery.clear() - clearSearchResultsHighlights() } function handleKeyBind(event: Event) { const kbdEvent = event as KeyboardEvent if (key_is_mappable(kbdEvent.key)) { - elementKeypressEventMap.run(document.activeElement.id, kbdEvent) + if(document.activeElement) // document.activeElement is possibly undefined / null + elementKeypressEventMap.run(document.activeElement.id, kbdEvent) return } if ($editMode === EditByteModes.Multiple) return diff --git a/src/svelte/src/components/globalStyles.css b/src/svelte/src/components/globalStyles.css index 916f9b3e3..765897f77 100644 --- a/src/svelte/src/components/globalStyles.css +++ b/src/svelte/src/components/globalStyles.css @@ -60,6 +60,8 @@ html { --color-tertiary-dark: #5f816b; --color-tertiary-darkest: #232f27; --color-alternate-grey: #bbb5bd; + --color-search-result: #69a0a7; + --color-replace-result: #5f816b; } /* Global LEGEND Styles */ diff --git a/src/svelte/src/stores/index.ts b/src/svelte/src/stores/index.ts index 66b3c8ea0..a0e8c14ad 100644 --- a/src/svelte/src/stores/index.ts +++ b/src/svelte/src/stores/index.ts @@ -43,7 +43,6 @@ import { type RadixValues, type BytesPerRow, EditActionRestrictions, - VIEWPORT_CAPACITY_MAX, } from './configuration' import type { AvailableHelpSections } from '../components/layouts/Help' @@ -76,6 +75,10 @@ export enum EditModeRestrictions { OverwriteOnly, } +/**************************************************************************/ +/* Writable Stores */ +/**************************************************************************/ + // noinspection JSUnusedGlobalSymbols // theme to use for the UI @@ -155,6 +158,12 @@ export const dataDislayLineAmount = writable(20) export type VisibleViewports = 'physical' | 'logical' | 'all' export const visableViewports = writable('all' as VisibleViewports) + +export const searchResultsUpdated = writable(false) + +/**************************************************************************/ +/* Derived Stores */ +/**************************************************************************/ // Can the user's selection derive both edit modes? export const regularSizedFile = derived(fileMetrics, ($fileMetrics) => { return $fileMetrics.computedSize >= 2 diff --git a/src/svelte/src/utilities/display.ts b/src/svelte/src/utilities/display.ts index 6b0f522a3..481d5390b 100644 --- a/src/svelte/src/utilities/display.ts +++ b/src/svelte/src/utilities/display.ts @@ -12,7 +12,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - import { EditByteModes, type BytesPerRow, diff --git a/src/svelte/src/utilities/highlights.ts b/src/svelte/src/utilities/highlights.ts index bb00644db..7940d6a89 100644 --- a/src/svelte/src/utilities/highlights.ts +++ b/src/svelte/src/utilities/highlights.ts @@ -15,62 +15,157 @@ * limitations under the License. */ -import { derived, readable, writable } from 'svelte/store' -import { selectionDataStore } from '../stores' +import { get } from 'svelte/store' +import { searchResultsUpdated, selectionDataStore, viewport } from '../stores' +import { VIEWPORT_CAPACITY_MAX } from '../stores/configuration' +import { SimpleWritable } from '../stores/localStore' +import type { DataReplacement } from '../components/Header/fieldsets/SearchReplace' -let selectionHighlightLUT = new Uint8Array(1024) -export let selectionHighlightMask = writable(0) +/** `0b0000 1111` */ +export const CATEGORY_ONE_MASK = 0x0f +/** `0b1111 0000` */ +export const CATEGORY_TWO_MASK = 0xf0 -let searchResultsHighlightLUT = new Uint8Array(1024).fill(0) +export type ByteValueIndications = { + cat1: number + cat2: number +} + +export enum IndicatorCategoryShift { + CategoryOne = 0, + CategoryTwo = 4, +} + +/** +`Uint8Array` byte index's map for bits[0-3]: `bbbb 0000`. Category 1 attributes change +the background color of a `ByteValue`. + +- `bbbb 0000`: (0) Viewport byte index has no category 1 attribute. +- `bbbb 0001`: (1) Viewport byte index is a byte within the user's selection range. +*/ +enum CategoryOneIndications { + None = 0, + Selected = 1, +} +export const CategoryOneIndicators = ['', 'selected'] + +/** +`Uint8Array` byte index's map for bits[4-7]: `0000 bbbb`. Category 2 attributes change +the border color of a `ByteValue`. + +- `0000 bbbb`: (0) Viewport byte index has no category 2 attribute. +- `0001 bbbb`: (16) Viewport byte index is a search result. +- `0010 bbbb`: (17) Viewport byte index is a replace result. -export enum HightlightCategoryMasks { +> **NOTE:** bits[4-7] get shifted by 4 bits when querying categories. +*/ +enum CategoryTwoIndications { None = 0, - ActiveSelection = 1, - ConsideredForSelection = 2, - SearchResult = 4, + IsSearchResult = 1, + IsReplaceResult = 2, +} +export const CategoryTwoIndicators = ['', 'isSearchResult', 'isReplaceResult'] + +export function byteCategoryValue( + indicationValue: number, + category: IndicatorCategoryShift +): number { + return indicationValue >> category +} + +type IndexCriteria = { + start: number + end: number + data: any[] } -export const selectionHighlights = derived( - [selectionDataStore, selectionHighlightMask], - ([$selectionData, $selectionHighlightMask]) => { - let start = $selectionData.startOffset - let end = - $selectionHighlightMask === 0 - ? $selectionData.originalEndOffset - : $selectionData.endOffset - if (start > end && end > -1) [start, end] = [end, start] - - for (let i = 0; i < 1024; i++) { - selectionHighlightLUT[i] = - i >= start && i <= end ? 1 << $selectionHighlightMask : 0 +class ViewportByteIndications extends SimpleWritable { + protected init(): Uint8Array { + return new Uint8Array(VIEWPORT_CAPACITY_MAX).fill(0) + } + private obtainIterationCriteria( + data: any[], + viewportFileOffset: number + ): IndexCriteria { + const start = data.findIndex((x) => x >= viewportFileOffset) + const end = data.findIndex( + (x) => x >= viewportFileOffset + VIEWPORT_CAPACITY_MAX + ) + let ret: IndexCriteria = { + start: start, + end: end, + data: data.slice(start, end >= 0 ? end : data.length), } + return ret + } + public clearSearchIndications() { + this.store.update((indications) => { + return indications.map((byte) => { + byte &= ~(byte & CATEGORY_TWO_MASK) + return byte + }) + }) + } + public updateSearchIndications(data: number[], byteWidth: number) { + this.store.update((indications) => { + const viewportFileOffset = get(viewport).fileOffset + const searchCriteria = this.obtainIterationCriteria( + data, + viewportFileOffset + ) + + this.clearSearchIndications() - return selectionHighlightLUT + searchCriteria.data.forEach((offset) => { + for (let i = 0; i < byteWidth; i++) + indications[offset - viewportFileOffset + i] |= + CategoryTwoIndications.IsSearchResult << + IndicatorCategoryShift.CategoryTwo + }) + searchResultsUpdated.set(true) + return indications + }) + } + public updateReplaceIndications( + data: DataReplacement[], + viewportFileOffset: number + ) { + this.update((indications) => { + const criteriaStart = data.findIndex( + (replacementData) => replacementData.offset >= viewportFileOffset + ) + const criteriaEnd = data.findIndex( + (replacementData) => + replacementData.offset >= viewportFileOffset + VIEWPORT_CAPACITY_MAX + ) + const matchingReplacements = data.slice( + criteriaStart, + criteriaEnd >= 0 ? criteriaEnd : data.length + ) + + matchingReplacements.forEach((replacementData) => { + for (let i = 0; i < replacementData.byteLength; i++) + indications[replacementData.offset - viewportFileOffset + i] |= + CategoryTwoIndications.IsReplaceResult << + IndicatorCategoryShift.CategoryTwo + }) + return indications + }) + } + public updateSelectionIndications(start: number, end: number) { + this.store.update((indications) => { + if (start > end && end > -1) [start, end] = [end, start] + + for (let i = 0; i < VIEWPORT_CAPACITY_MAX; i++) { + indications[i] = + i >= start && i <= end + ? CategoryOneIndications.Selected & CATEGORY_ONE_MASK + : CategoryOneIndications.None & CATEGORY_ONE_MASK + } + + return indications + }) } -) - -export const searchResultsHighlights = readable(searchResultsHighlightLUT) -export const searchResultsUpdated = writable(false) -export function updateSearchResultsHighlights( - data: number[], - viewportFileOffset: number, - byteWidth: number -) { - const criteriaStart = data.findIndex((x) => x >= viewportFileOffset) - const criteriaEnd = data.findIndex((x) => x >= viewportFileOffset + 1024) - const searchCriteria = data.slice( - criteriaStart, - criteriaEnd >= 0 ? criteriaEnd : data.length - ) - - searchResultsHighlightLUT.fill(0) - - searchCriteria.forEach((offset) => { - for (let i = 0; i < byteWidth; i++) - searchResultsHighlightLUT[offset - viewportFileOffset + i] = 1 - }) - searchResultsUpdated.set(true) -} -export function clearSearchResultsHighlights() { - searchResultsHighlightLUT.fill(0) } + +export const viewportByteIndicators = new ViewportByteIndications() diff --git a/yarn.lock b/yarn.lock index aa684d65c..9cfbf2820 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,10 +21,10 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@grpc/grpc-js@1.9.2": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.2.tgz#151148f6485eab8fb13fe53042d25f4ffa9c7d09" - integrity sha512-Lf2pUhNTaviEdEaGgjU+29qw3arX7Qd/45q66F3z1EV5hroE6wM9xSHPvjB8EY+b1RmKZgwnLWXQorC6fZ9g5g== +"@grpc/grpc-js@1.9.5": + version "1.9.5" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.5.tgz#22e283754b7b10d1ad26c3fb21849028dcaabc53" + integrity sha512-iouYNlPxRAwZ2XboDT+OfRKHuaKHiqjB5VFYZ0NFrHkbEF+AV3muIUY9olQsp8uxU4VvRCMiRk9ftzFDGb61aw== dependencies: "@grpc/proto-loader" "^0.7.8" "@types/node" ">=12.12.47" @@ -127,22 +127,22 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@omega-edit/client@0.9.73": - version "0.9.73" - resolved "https://registry.yarnpkg.com/@omega-edit/client/-/client-0.9.73.tgz#7ed91c3666693d4f86d9454fa53bc58dd166fb1a" - integrity sha512-zawWipddEpa0+k2xTXLnOkFLOBBBlZ5ozZx8MAxJK9Ce75Ifn8f4/mBwC95BU9uhuT9bVIBeN79ta+tDoGdddA== +"@omega-edit/client@0.9.75": + version "0.9.75" + resolved "https://registry.yarnpkg.com/@omega-edit/client/-/client-0.9.75.tgz#187613f855f6d1a0eafd264c9a744fa3cc8e8ef0" + integrity sha512-ayKaiWJRllfklQ0qKOA52izmZZocmdmROap62LtzcWbPaNbUDU3JxYwbBSslKUI5fA4AzrbPofzDph0BF0Ltqw== dependencies: - "@grpc/grpc-js" "1.9.2" - "@omega-edit/server" "0.9.73" - "@types/google-protobuf" "3.15.6" + "@grpc/grpc-js" "1.9.5" + "@omega-edit/server" "0.9.75" + "@types/google-protobuf" "3.15.7" google-protobuf "3.21.2" - pino "8.15.1" - wait-port "1.0.4" + pino "8.16.0" + wait-port "1.1.0" -"@omega-edit/server@0.9.73": - version "0.9.73" - resolved "https://registry.yarnpkg.com/@omega-edit/server/-/server-0.9.73.tgz#2f38008879fbdc7129e6381e306f83b8948a7af6" - integrity sha512-4HYoWC4q4gSTK+4/SgSIQox4WLuH2uBvJZ/Y8YhEacP54YzkJwT+XhYa+tRR1vhnKXshKTz9JqAaAgea6ouc2Q== +"@omega-edit/server@0.9.75": + version "0.9.75" + resolved "https://registry.yarnpkg.com/@omega-edit/server/-/server-0.9.75.tgz#cb724bfdde21abc3551b55521e21cf0592b9152a" + integrity sha512-790QS7xtJ6gA1KoB3e62ZrMc+jlERla1V/FFTjBv6R3Z/wiP0PGh2vDGyvSIYRN71f+Qnpy+lh59UcmgKYrbZQ== "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" @@ -278,10 +278,10 @@ "@types/minimatch" "^5.1.2" "@types/node" "*" -"@types/google-protobuf@3.15.6": - version "3.15.6" - resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.15.6.tgz#674a69493ef2c849b95eafe69167ea59079eb504" - integrity sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw== +"@types/google-protobuf@3.15.7": + version "3.15.7" + resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.15.7.tgz#882e7351bc8ccf30bb21c507cc4597cf76f8888b" + integrity sha512-pIEMnb04J60c5eExVLUY/R4eWT5QEQ5cC792JOSfDI3kLjaKC4TjdgMp3xIrN1vxbi2Zk8LcscTm0VaNrIdniA== "@types/http-cache-semantics@^4.0.1": version "4.0.1" @@ -317,20 +317,22 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== -"@types/mocha@^10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" - integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== +"@types/mocha@^10.0.3": + version "10.0.3" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.3.tgz#4804fe9cd39da26eb62fa65c15ea77615a187812" + integrity sha512-RsOPImTriV/OE4A9qKjMtk2MnXiuLLbcO3nCXK+kvq4nr0iMfFgpjaX3MPLb6f7+EL1FGSelYvuJMV6REH+ZPQ== "@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0": version "20.5.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.0.tgz#7fc8636d5f1aaa3b21e6245e97d56b7f56702313" integrity sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q== -"@types/node@^20.6.1": - version "20.6.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.1.tgz#8b589bba9b2af0128796461a0979764562687e6f" - integrity sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g== +"@types/node@^20.8.7": + version "20.8.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.7.tgz#ad23827850843de973096edfc5abc9e922492a25" + integrity sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ== + dependencies: + undici-types "~5.25.1" "@types/pug@^2.0.6": version "2.0.6" @@ -344,10 +346,10 @@ dependencies: "@types/ws" "*" -"@types/vscode-webview@^1.57.2": - version "1.57.2" - resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.2.tgz#aa6a8cf02c23ef7ce4e5f2d257f52b15ddd8ec78" - integrity sha512-RpkIso3+FVoi9hFwHj9uBFO+9p8PGym0LnLJ9Yabo9mUJaV39CzOxz6EVtHg8AidA9hAf4cVmG0c+l9pvw6Lbw== +"@types/vscode-webview@^1.57.3": + version "1.57.3" + resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.3.tgz#b57608173f12424b0b650b42a3e6c5b45b604a5f" + integrity sha512-8at2UVGjA/6gcLOay+J8wOars6VsDqAqPxRHYihH0XFUaXt+2AZ+Hd9hSoUbnhjicb6V1xe7rfjb7j4Ri2n1fg== "@types/vscode@^1.67.2": version "1.82.0" @@ -400,17 +402,45 @@ resolved "https://registry.yarnpkg.com/@vscode/debugprotocol/-/debugprotocol-1.63.0.tgz#f6d16c382765d2533e515939ac2857aa1ed7ba35" integrity sha512-7gewwv69pA7gcJUhtJsru5YN7E1AwwnlBrF5mJY4R/NGInOUqOYOWHlqQwG+4AXn0nXWbcn26MHgaGI9Q26SqA== -"@vscode/test-electron@2.3.4": - version "2.3.4" - resolved "https://registry.yarnpkg.com/@vscode/test-electron/-/test-electron-2.3.4.tgz#d0ed1de72d347221cdf71426b0c7e21136f4791f" - integrity sha512-eWzIqXMhvlcoXfEFNWrVu/yYT5w6De+WZXR/bafUQhAp8+8GkQo95Oe14phwiRUPv8L+geAKl/QM2+PoT3YW3g== +"@vscode/test-electron@2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@vscode/test-electron/-/test-electron-2.3.5.tgz#c472c5bdce1329aeb4762b8aa7a2cbe7aa783aac" + integrity sha512-lAW7nQ0HuPqJnGJrtCzEKZCICtRizeP6qNanyCrjmdCOAAWjX3ixiG8RVPwqsYPQBWLPgYuE12qQlwXsOR/2fQ== dependencies: http-proxy-agent "^4.0.1" https-proxy-agent "^5.0.0" jszip "^3.10.1" semver "^7.5.2" -"@vscode/vsce@2.21.0", "@vscode/vsce@^2.20.1": +"@vscode/vsce@2.21.1": + version "2.21.1" + resolved "https://registry.yarnpkg.com/@vscode/vsce/-/vsce-2.21.1.tgz#793c78d992483b428611a3927211a9640041be14" + integrity sha512-f45/aT+HTubfCU2oC7IaWnH9NjOWp668ML002QiFObFRVUCoLtcwepp9mmql/ArFUy+HCHp54Xrq4koTcOD6TA== + dependencies: + azure-devops-node-api "^11.0.1" + chalk "^2.4.2" + cheerio "^1.0.0-rc.9" + commander "^6.2.1" + glob "^7.0.6" + hosted-git-info "^4.0.2" + jsonc-parser "^3.2.0" + leven "^3.1.0" + markdown-it "^12.3.2" + mime "^1.3.4" + minimatch "^3.0.3" + parse-semver "^1.1.1" + read "^1.0.7" + semver "^7.5.2" + tmp "^0.2.1" + typed-rest-client "^1.8.4" + url-join "^4.0.1" + xml2js "^0.5.0" + yauzl "^2.3.1" + yazl "^2.2.2" + optionalDependencies: + keytar "^7.7.0" + +"@vscode/vsce@^2.20.1": version "2.21.0" resolved "https://registry.yarnpkg.com/@vscode/vsce/-/vsce-2.21.0.tgz#572e66db79cff383b9ac39f71710aa62e6392330" integrity sha512-KuxYqScqUY/duJbkj9eE2tN2X/WJoGAy54hHtxT3ZBkM6IzrOg7H7CXGUPBxNlmqku2w/cAjOUSrgIHlzz0mbA== @@ -929,18 +959,18 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001517: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001520.tgz#62e2b7a1c7b35269594cf296a80bdf8cb9565006" integrity sha512-tahF5O9EiiTzwTUqAeFjIZbn4Dnqxzz7ktrgGlMYNLH43Ul26IgTMH/zvL3DG0lZxBYnlT04axvInszUsZULdA== -chai@^4.3.8: - version "4.3.8" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.8.tgz#40c59718ad6928da6629c70496fe990b2bb5b17c" - integrity sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ== +chai@^4.3.10: + version "4.3.10" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" + integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== dependencies: assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^4.1.2" - get-func-name "^2.0.0" - loupe "^2.3.1" + check-error "^1.0.3" + deep-eql "^4.1.3" + get-func-name "^2.0.2" + loupe "^2.3.6" pathval "^1.1.1" - type-detect "^4.0.5" + type-detect "^4.0.8" chainsaw@~0.1.0: version "0.1.0" @@ -966,10 +996,12 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== +check-error@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== + dependencies: + get-func-name "^2.0.2" cheerio-select@^2.1.0: version "2.1.0" @@ -1136,10 +1168,10 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concurrently@^8.2.1: - version "8.2.1" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-8.2.1.tgz#bcab9cacc38c23c503839583151e0fa96fd5b584" - integrity sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ== +concurrently@^8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-8.2.2.tgz#353141985c198cfa5e4a3ef90082c336b5851784" + integrity sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg== dependencies: chalk "^4.1.2" date-fns "^2.30.0" @@ -1331,7 +1363,7 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" -deep-eql@^4.1.2: +deep-eql@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== @@ -1659,7 +1691,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-func-name@^2.0.0: +get-func-name@^2.0.1, get-func-name@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== @@ -2216,12 +2248,12 @@ long@^5.0.0: resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== -loupe@^2.3.1: - version "2.3.6" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" - integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== +loupe@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== dependencies: - get-func-name "^2.0.0" + get-func-name "^2.0.1" lowercase-keys@^3.0.0: version "3.0.0" @@ -2653,10 +2685,10 @@ pino-std-serializers@^6.0.0: resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz#d9a9b5f2b9a402486a5fc4db0a737570a860aab3" integrity sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA== -pino@8.15.1: - version "8.15.1" - resolved "https://registry.yarnpkg.com/pino/-/pino-8.15.1.tgz#04b815ff7aa4e46b1bbab88d8010aaa2b17eaba4" - integrity sha512-Cp4QzUQrvWCRJaQ8Lzv0mJzXVk4z2jlq8JNKMGaixC2Pz5L4l2p95TkuRvYbrEbe85NQsDKrAd4zalf7Ml6WiA== +pino@8.16.0: + version "8.16.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-8.16.0.tgz#2465012a1d11fa2e7a0545032f636e203990ae26" + integrity sha512-UUmvQ/7KTZt/vHjhRrnyS7h+J7qPBQnpG80V56xmIC+o9IqYmQOw/UIny9S9zYDfRBR0ClouCr464EkBMIT7Fw== dependencies: atomic-sleep "^1.0.0" fast-redact "^3.1.1" @@ -2667,7 +2699,7 @@ pino@8.15.1: quick-format-unescaped "^4.0.3" real-require "^0.2.0" safe-stable-stringify "^2.3.1" - sonic-boom "^3.1.0" + sonic-boom "^3.7.0" thread-stream "^2.0.0" pkg-dir@^4.2.0: @@ -3233,10 +3265,10 @@ sanitize-filename@^1.6.3: dependencies: truncate-utf8-bytes "^1.0.0" -sass@^1.67.0: - version "1.67.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.67.0.tgz#fed84d74b9cd708db603b1380d6dc1f71bb24f6f" - integrity sha512-SVrO9ZeX/QQyEGtuZYCVxoeAL5vGlYjJ9p4i4HFuekWl8y/LtJ7tJc10Z+ck1c8xOuoBm2MYzcLfTAffD0pl/A== +sass@^1.69.4: + version "1.69.4" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.4.tgz#10c735f55e3ea0b7742c6efa940bce30e07fbca2" + integrity sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -3363,10 +3395,10 @@ slash@^4.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== -sonic-boom@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.3.0.tgz#cffab6dafee3b2bcb88d08d589394198bee1838c" - integrity sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g== +sonic-boom@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.7.0.tgz#b4b7b8049a912986f4a92c51d4660b721b11f2f2" + integrity sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg== dependencies: atomic-sleep "^1.0.0" @@ -3494,10 +3526,10 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -svelte-check@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-3.5.1.tgz#88265b41623b9374ff35b69802497287073d693d" - integrity sha512-+Zb4iHxAhdUtcUg/WJPRjlS1RJalIsWAe9Mz6G1zyznSs7dDkT7VUBdXc3q7Iwg49O/VrZgyJRvOJkjuBfKjFA== +svelte-check@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-3.5.2.tgz#d6e650996afbe80f5e5b9b02d3fb9489f7d6fb8a" + integrity sha512-5a/YWbiH4c+AqAUP+0VneiV5bP8YOk9JL3jwvN+k2PEPLgpu85bjQc5eE67+eIZBBwUEJzmO3I92OqKcqbp3fw== dependencies: "@jridgewell/trace-mapping" "^0.3.17" chokidar "^3.4.1" @@ -3726,7 +3758,7 @@ tunnel@0.0.6: resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== -type-detect@^4.0.0, type-detect@^4.0.5: +type-detect@^4.0.0, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -3760,6 +3792,11 @@ underscore@^1.12.1: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== +undici-types@~5.25.1: + version "5.25.3" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" + integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== + universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -3850,10 +3887,10 @@ vscode-extension-tester@5.9.1: unzipper "^0.10.14" vscode-extension-tester-locators "^3.7.1" -wait-port@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/wait-port/-/wait-port-1.0.4.tgz#6f9474645ddbf7701ac100ab6762438edf6e5689" - integrity sha512-w8Ftna3h6XSFWWc2JC5gZEgp64nz8bnaTp5cvzbJSZ53j+omktWTDdwXxEF0jM8YveviLgFWvNGrSvRHnkyHyw== +wait-port@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wait-port/-/wait-port-1.1.0.tgz#e5d64ee071118d985e2b658ae7ad32b2ce29b6b5" + integrity sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q== dependencies: chalk "^4.1.2" commander "^9.3.0"