diff --git a/src/StaticConfiguration.ts b/src/StaticConfiguration.ts index e3d51f474..d347cd5a1 100644 --- a/src/StaticConfiguration.ts +++ b/src/StaticConfiguration.ts @@ -8,9 +8,9 @@ * Static configuration values. These values are not expected to change, while the application is running. */ import { MBSpecs } from 'microbyte'; -import { PinTurnOnState } from './lib/PinTurnOnState'; -import { type LayersModelTrainingSettings as NeuralNetworkModelTrainerSettings } from './lib/mlmodels/LayersModelTrainer'; +import { PinTurnOnState } from './core/entities/PinTurnOnState'; import { HexOrigin } from './lib/microbit-interfacing/HexOrigin'; +import type { LayersModelTrainingSettings } from './core/entities/classifier/models/LayersModelTrainer'; class StaticConfiguration { // in milliseconds, how long should be wait for reconnect before determining something catestrophic happened during the process? @@ -122,14 +122,13 @@ class StaticConfiguration { /** * The neural network training settings */ - public static readonly defaultNeuralNetworkSettings: NeuralNetworkModelTrainerSettings = - { - noOfEpochs: 80, - batchSize: 16, - learningRate: 0.1, - validationSplit: 0.1, - noOfUnits: 16, // size of hidden layer - }; + public static readonly defaultNeuralNetworkSettings: LayersModelTrainingSettings = { + noOfEpochs: 80, + batchSize: 16, + learningRate: 0.1, + validationSplit: 0.1, + noOfUnits: 16, // size of hidden layer + }; /** * How many samples should the KNN model use for prediction? i.e the k-value. diff --git a/src/__tests__/csv/csv.test.ts b/src/__tests__/csv/csv.test.ts index f8a522047..119aeed1c 100644 --- a/src/__tests__/csv/csv.test.ts +++ b/src/__tests__/csv/csv.test.ts @@ -9,8 +9,8 @@ import { writable } from 'svelte/store'; import { locale } from 'svelte-i18n'; -import type { RecordingData } from '../../lib/domain/RecordingData'; -import Gesture from '../../lib/domain/stores/gesture/Gesture'; +import type { RecordingData } from '../../core/entities/RecordingData'; +import GestureState from '../../lib/domain/stores/gesture/GestureState'; import type { PersistedGestureData } from '../../lib/domain/stores/gesture/Gestures'; import type GestureConfidence from '../../lib/domain/stores/gesture/GestureConfidence'; import { @@ -41,7 +41,7 @@ describe('CSV Test', () => { name: 'Test;Gesture', } as PersistedGestureData); const confidence = writable({}) as unknown as GestureConfidence; - const gesture: Gesture = new Gesture(data, confidence, () => void 0); + const gesture: GestureState = new GestureState(data, confidence, () => void 0); const result = serializeGestureRecordingsToCSV([gesture]); expect(result).toBe( 'gesture;sample;x;y;z\nTest\\;Gesture;0;1;2;3\nTest\\;Gesture;1;4;5;6\nTest\\;Gesture;2;7;8;9', @@ -82,8 +82,8 @@ describe('CSV Test', () => { name: 'Gesture2', } as PersistedGestureData); const confidence = writable({}) as unknown as GestureConfidence; - const gesture1: Gesture = new Gesture(data1, confidence, () => void 0); - const gesture2: Gesture = new Gesture(data2, confidence, () => void 0); + const gesture1: GestureState = new GestureState(data1, confidence, () => void 0); + const gesture2: GestureState = new GestureState(data2, confidence, () => void 0); const result = serializeGestureRecordingsToCSV([gesture1, gesture2]); expect(result).toBe( 'gesture;sample;x;y;z\n' + @@ -133,13 +133,13 @@ describe('CSV Test', () => { ], }); - const createTestGestureWithDecimals = (name: string): Gesture => { + const createTestGestureWithDecimals = (name: string): GestureState => { const data = writable({ recordings: [createTestRecordingWithDecimals()], name, } as PersistedGestureData); const confidence = writable({}) as unknown as GestureConfidence; - return new Gesture(data, confidence, () => void 0); + return new GestureState(data, confidence, () => void 0); }; test('English locale uses period as decimal separator', () => { diff --git a/src/__tests__/ml/classifier.test.ts b/src/__tests__/ml/classifier.test.ts index 0ebae98e8..84935a890 100644 --- a/src/__tests__/ml/classifier.test.ts +++ b/src/__tests__/ml/classifier.test.ts @@ -8,21 +8,21 @@ */ import { get, writable } from 'svelte/store'; -import BaseLiveDataVector from '../../lib/domain/BaseLiveDataVector'; +import BaseLiveDataVector from '../../core/entities/vector/BaseLiveDataVector'; import { ClassifierInput } from '../../lib/domain/ClassifierInput'; import Filters from '../../lib/domain/Filters'; import { stores } from '../../lib/stores/Stores'; import TestMLModelTrainer from '../mocks/mlmodel/TestMLModelTrainer'; -import type { Filter } from '../../lib/domain/Filter'; -import FilterTypes, { FilterType } from '../../lib/domain/FilterTypes'; import ClassifierFactory from '../../lib/domain/ClassifierFactory'; -import LayersModelTrainer from '../../lib/mlmodels/LayersModelTrainer'; import StaticConfiguration from '../../StaticConfiguration'; import TestTrainingDataRepository from '../mocks/TestTrainingDataRepository'; import TestGestureRepository from '../mocks/TestGestureRepository'; import Confidences from '../../lib/domain/stores/Confidences'; -import BaseVector from '../../lib/domain/BaseVector'; +import BaseVector from '../../core/entities/vector/BaseVector'; import Snackbar from '../../lib/stores/Snackbar'; +import { FilterType, type Filter } from '../../core/entities/filter/Filter'; +import { createFilter } from '../../core/entities/filter/FilterUtils'; +import LayersModelTrainer from '../../core/entities/classifier/models/LayersModelTrainer'; describe('Classifier tests', () => { test('Changing matrix does not mark model as untrained', async () => { @@ -62,9 +62,9 @@ describe('Classifier tests', () => { new BaseLiveDataVector(new BaseVector([3, 3, 3]), ['x', 'y', 'z']), ]; const input = new ClassifierInput(vectors); - const filterMax: Filter = FilterTypes.createFilter(FilterType.MAX); - const filterMean: Filter = FilterTypes.createFilter(FilterType.MEAN); - const filterMin: Filter = FilterTypes.createFilter(FilterType.MIN); + const filterMax: Filter = createFilter(FilterType.MAX); + const filterMean: Filter = createFilter(FilterType.MEAN); + const filterMin: Filter = createFilter(FilterType.MIN); const filters: Filters = new Filters(writable([filterMax, filterMean, filterMin])); expect(input.getInput(filters).length).toBe(3 * 3); }); @@ -75,7 +75,7 @@ describe('Classifier tests', () => { new BaseLiveDataVector(new BaseVector([4, 5, 6]), ['x', 'y', 'z']), ]; const input = new ClassifierInput(vectors); - const filterMax: Filter = FilterTypes.createFilter(FilterType.MAX); + const filterMax: Filter = createFilter(FilterType.MAX); const filters: Filters = new Filters(writable([filterMax])); expect(input.getInput(filters)).toStrictEqual([4, 5, 6]); }); @@ -87,9 +87,9 @@ describe('Classifier tests', () => { new BaseLiveDataVector(new BaseVector([10]), ['x']), ]; const input = new ClassifierInput(vectors); - const filterMax: Filter = FilterTypes.createFilter(FilterType.MAX); - const filterMean: Filter = FilterTypes.createFilter(FilterType.MEAN); - const filterMin: Filter = FilterTypes.createFilter(FilterType.MIN); + const filterMax: Filter = createFilter(FilterType.MAX); + const filterMean: Filter = createFilter(FilterType.MEAN); + const filterMin: Filter = createFilter(FilterType.MIN); const filters: Filters = new Filters(writable([filterMax, filterMean, filterMin])); expect(input.getInput(filters).length).toBe(3); expect(input.getInput(filters)).toStrictEqual([10, 5, 1]); @@ -102,8 +102,8 @@ describe('Classifier tests', () => { new BaseLiveDataVector(new BaseVector([10, 20]), ['x', 'y']), ]; const input = new ClassifierInput(vectors); - const filterMax: Filter = FilterTypes.createFilter(FilterType.MAX); - const filterMin: Filter = FilterTypes.createFilter(FilterType.MIN); + const filterMax: Filter = createFilter(FilterType.MAX); + const filterMin: Filter = createFilter(FilterType.MIN); const filters: Filters = new Filters(writable([filterMax, filterMin])); expect(input.getInput(filters)).toStrictEqual([ // x value max/min @@ -120,9 +120,9 @@ describe('Classifier tests', () => { new BaseLiveDataVector(new BaseVector([10, 20, 40]), ['x', 'y', 'z']), ]; const classifierInput = new ClassifierInput(vectors); - const filterMax: Filter = FilterTypes.createFilter(FilterType.MAX); - const filterMean: Filter = FilterTypes.createFilter(FilterType.MEAN); - const filterMin: Filter = FilterTypes.createFilter(FilterType.MIN); + const filterMax: Filter = createFilter(FilterType.MAX); + const filterMean: Filter = createFilter(FilterType.MEAN); + const filterMin: Filter = createFilter(FilterType.MIN); const filters: Filters = new Filters(writable([filterMax, filterMean, filterMin])); let iterations = 0; @@ -177,9 +177,9 @@ describe('Classifier tests', () => { new BaseLiveDataVector(new BaseVector([10, 20, 40]), ['x', 'y', 'z']), ]; const classifierInput = new ClassifierInput(vectors); - const filterMax: Filter = FilterTypes.createFilter(FilterType.MAX); - const filterMean: Filter = FilterTypes.createFilter(FilterType.MEAN); - const filterMin: Filter = FilterTypes.createFilter(FilterType.MIN); + const filterMax: Filter = createFilter(FilterType.MAX); + const filterMean: Filter = createFilter(FilterType.MEAN); + const filterMin: Filter = createFilter(FilterType.MIN); const filters: Filters = new Filters(writable([filterMax, filterMean, filterMin])); let iterations = 0; @@ -239,9 +239,9 @@ describe('Classifier tests', () => { new BaseLiveDataVector(new BaseVector([10, 20, 40]), ['x', 'y', 'z']), ]; const classifierInput = new ClassifierInput(vectors); - const filterMax: Filter = FilterTypes.createFilter(FilterType.MAX); - const filterMean: Filter = FilterTypes.createFilter(FilterType.MEAN); - const filterMin: Filter = FilterTypes.createFilter(FilterType.MIN); + const filterMax: Filter = createFilter(FilterType.MAX); + const filterMean: Filter = createFilter(FilterType.MEAN); + const filterMin: Filter = createFilter(FilterType.MIN); const filters: Filters = new Filters(writable([filterMax, filterMean, filterMin])); let iterations = 0; diff --git a/src/__tests__/ml/data-representation.test.ts b/src/__tests__/ml/data-representation.test.ts index 6c3f9895e..0678b8b59 100644 --- a/src/__tests__/ml/data-representation.test.ts +++ b/src/__tests__/ml/data-representation.test.ts @@ -7,13 +7,13 @@ * SPDX-License-Identifier: MIT */ -import LiveDataBuffer from '../../lib/domain/LiveDataBuffer'; +import LiveDataBuffer from '../../core/LiveDataBuffer'; import MicrobitAccelerometerLiveData, { MicrobitAccelerometerDataVector, } from '../../lib/livedata/MicrobitAccelerometerData'; import { repeat } from '../testUtils'; import { get } from 'svelte/store'; -import { type LiveDataVector } from '../../lib/domain/stores/LiveDataVector'; +import { type LiveDataVector } from '../../core/entities/vector/LiveDataVector'; import SmoothedLiveData from '../../lib/livedata/SmoothedLiveData'; import { smoothNewValue } from '../../lib/utils/graphUtils'; import type { LiveData } from '../../lib/domain/stores/LiveData'; diff --git a/src/__tests__/ml/engine.test.ts b/src/__tests__/ml/engine.test.ts index 2dd49afdc..adb46ac9f 100644 --- a/src/__tests__/ml/engine.test.ts +++ b/src/__tests__/ml/engine.test.ts @@ -8,7 +8,7 @@ */ import { get } from 'svelte/store'; -import LiveDataBuffer from '../../lib/domain/LiveDataBuffer'; +import LiveDataBuffer from '../../core/LiveDataBuffer'; import MicrobitAccelerometerLiveData from '../../lib/livedata/MicrobitAccelerometerData'; import { stores } from '../../lib/stores/Stores'; diff --git a/src/__tests__/ml/model.test.ts b/src/__tests__/ml/model.test.ts index a824b1b46..7eb1620c0 100644 --- a/src/__tests__/ml/model.test.ts +++ b/src/__tests__/ml/model.test.ts @@ -7,10 +7,10 @@ * SPDX-License-Identifier: MIT */ import TestTrainingDataRepository from '../mocks/TestTrainingDataRepository'; -import LayersModelTrainer from '../../lib/mlmodels/LayersModelTrainer'; import StaticConfiguration from '../../StaticConfiguration'; -import KNNNonNormalizedModelTrainer from '../../lib/mlmodels/KNNNonNormalizedModelTrainer'; -import BaseVector from '../../lib/domain/BaseVector'; +import BaseVector from '../../core/entities/vector/BaseVector'; +import LayersModelTrainer from '../../core/entities/classifier/models/LayersModelTrainer'; +import KNNNonNormalizedModelTrainer from '../../core/entities/classifier/models/KNNNonNormalizedModelTrainer'; describe('ML Model tests', async () => { describe('Layers Model', async () => { diff --git a/src/__tests__/mocks/TestGestureRepository.ts b/src/__tests__/mocks/TestGestureRepository.ts index 0867b7b6f..598621961 100644 --- a/src/__tests__/mocks/TestGestureRepository.ts +++ b/src/__tests__/mocks/TestGestureRepository.ts @@ -12,14 +12,14 @@ import { get, } from 'svelte/store'; import type { GestureRepository } from '../../lib/domain/GestureRepository'; -import Gesture from '../../lib/domain/stores/gesture/Gesture'; +import GestureState from '../../lib/domain/stores/gesture/GestureState'; import type { PersistedGestureData } from '../../lib/domain/stores/gesture/Gestures'; import GestureConfidence from '../../lib/domain/stores/gesture/GestureConfidence'; class TestGestureRepository implements GestureRepository { - private gestures = writable([]); + private gestures = writable([]); - getGesture(gestureId: number): Gesture { + getGesture(gestureId: number): GestureState { const foundGesture = get(this.gestures).find(g => g.getId() === gestureId); if (!foundGesture) { throw new Error('Could not find gesture with id ' + gestureId); @@ -31,8 +31,8 @@ class TestGestureRepository implements GestureRepository { this.gestures.set([]); } - addGesture(gestureData: PersistedGestureData): Gesture { - const gesture = new Gesture( + addGesture(gestureData: PersistedGestureData): GestureState { + const gesture = new GestureState( writable(gestureData), new GestureConfidence(0.5, writable(0)), () => void 0, @@ -50,8 +50,8 @@ class TestGestureRepository implements GestureRepository { } subscribe( - run: Subscriber, - invalidate?: Invalidator | undefined, + run: Subscriber, + invalidate?: Invalidator | undefined, ): Unsubscriber { return this.gestures.subscribe(run, invalidate); } diff --git a/src/__tests__/mocks/TestTrainingDataRepository.ts b/src/__tests__/mocks/TestTrainingDataRepository.ts index 32c045157..c69e64f5f 100644 --- a/src/__tests__/mocks/TestTrainingDataRepository.ts +++ b/src/__tests__/mocks/TestTrainingDataRepository.ts @@ -4,10 +4,10 @@ * SPDX-License-Identifier: MIT */ -import BaseVector from '../../lib/domain/BaseVector'; -import type { TrainingData } from '../../lib/domain/ModelTrainer'; -import type { TrainingDataRepository } from '../../lib/domain/TrainingDataRepository'; -import type { Vector } from '../../lib/domain/Vector'; +import BaseVector from '../../core/entities/vector/BaseVector'; +import type { TrainingData } from '../../core/entities/classifier/models/ModelTrainer'; +import type { TrainingDataRepository } from '../../core/repository/TrainingDataRepository'; +import type { Vector } from '../../core/entities/vector/Vector'; class TestTrainingDataRepository implements TrainingDataRepository { getTrainingDataMean(): Vector { diff --git a/src/__tests__/mocks/mlmodel/TestMLModel.ts b/src/__tests__/mocks/mlmodel/TestMLModel.ts index ada7b4b3d..05e8ce5a5 100644 --- a/src/__tests__/mocks/mlmodel/TestMLModel.ts +++ b/src/__tests__/mocks/mlmodel/TestMLModel.ts @@ -4,8 +4,8 @@ * SPDX-License-Identifier: MIT */ -import type { MLModel } from '../../../lib/domain/MLModel'; -import type { Vector } from '../../../lib/domain/Vector'; +import type { MLModel } from '../../../core/entities/classifier/models/MLModel'; +import type { Vector } from '../../../core/entities/vector/Vector'; class TestMLModel implements MLModel { constructor(private numberOfGestures: number) {} diff --git a/src/__tests__/mocks/mlmodel/TestMLModelTrainer.ts b/src/__tests__/mocks/mlmodel/TestMLModelTrainer.ts index faffbf0a0..9a9e96a5f 100644 --- a/src/__tests__/mocks/mlmodel/TestMLModelTrainer.ts +++ b/src/__tests__/mocks/mlmodel/TestMLModelTrainer.ts @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: MIT */ -import type { ModelInfo } from '../../../lib/domain/ModelRegistry'; -import ModelRegistry from '../../../lib/domain/ModelRegistry'; -import type { ModelTrainer } from '../../../lib/domain/ModelTrainer'; -import type { TrainingDataRepository } from '../../../lib/domain/TrainingDataRepository'; +import type { ModelInfo } from '../../../core/entities/classifier/models/ModelRegistry'; +import ModelRegistry from '../../../core/entities/classifier/models/ModelRegistry'; +import type { ModelTrainer } from '../../../core/entities/classifier/models/ModelTrainer'; +import type { TrainingDataRepository } from '../../../core/repository/TrainingDataRepository'; import TestMLModel from './TestMLModel'; class TestMLModelTrainer implements ModelTrainer { diff --git a/src/assets/messages/ui.da.json b/src/assets/messages/ui.da.json index e565f45c6..844f09f9c 100644 --- a/src/assets/messages/ui.da.json +++ b/src/assets/messages/ui.da.json @@ -30,8 +30,12 @@ "content.index.MLExplainer3": "Data repræsentationerne af eksemplerne vises til et neuralt netværk. Det neurale netværk “lærer” fra disse eksempler ved at finde mønstre i og imellem eksemplerne.", "content.index.MLExplainer4": "Denne træningsprocess resulterer i et trænet neuralt netværk (vi kalder det også en machine learning model), der kan gætte/forudsige, hvordan micro:bit’en bevæges, når de samme egenskaber (standardafvigelse, samlet acceleration, den maximale værdi m.m.) beregnes fra det live accelerometer data.", "content.data.classPlaceholderNewClass": "Klik for at ændre navnet", + "content.data.print": "Print", + "content.data.delete": "Slet", "content.data.record": "Optag", "content.data.addData": "Tilføj data", + "content.data.select": "Vælg", + "content.data.csv": "Download som csv", "content.data.classHelpHeader": "Klasse", "content.data.classHelpBody": "En klasse beskriver en type af bevægelse. Vi kan optage eksempler af en bestemt type bevægelse og putte eksemplerne i samme klasse. Træneren kan finde mønstre i eksemplerne/dataet og bruge disse mønstre til at træne en model, der kan genkende denne type bevægelse. Flere eksmpler vil typisk reulstere i en bedre model, men overvej på hvor mange forskellige måder en bevægelse kan laves.", "content.data.classification": "Klasser", diff --git a/src/assets/messages/ui.de.json b/src/assets/messages/ui.de.json index ed21fab57..3a5656d7f 100644 --- a/src/assets/messages/ui.de.json +++ b/src/assets/messages/ui.de.json @@ -30,8 +30,12 @@ "content.index.MLExplainer3": "Die Datendarstellungen der Datenbeispiele werden einem neuronalen Netz gezeigt. Das neuronale Netz \"lernt\" aus diesen Beispielen, indem es Muster in und zwischen den Beispielen findet.", "content.index.MLExplainer4": "Das Ergebnis dieses Trainingsprozesses ist ein trainiertes neuronales Netzwerk (wir nennen es auch ein maschinelles Lernmodell), das erraten/vorhersagen kann, wie der micro:bit bewegt wird, wenn dieselben Eigenschaften (Standardabweichung, kumulierte Beschleunigung, Maximalwert usw.) aus den Live-Beschleunigungsdaten berechnet werden.", "content.data.classPlaceholderNewClass": "Drücke hier, um den Namen zu ändern", + "content.data.print": "Drucken", + "content.data.delete": "Löschen", "content.data.record": "Aufnehmen", "content.data.addData": "Daten hinzufügen", + "content.data.select": "Auswählen", + "content.data.csv": "Als CSV herunterladen", "content.data.classHelpHeader": "Klasse", "content.data.classHelpBody": "Eine Klasse beschreibt eine Art von Geste. Wir können Beispiele für eine bestimmte Art von Geste aufzeichnen und die Beispiele in dieselbe Klasse einordnen. Das Training kann Muster in den Beispielen/Daten finden und diese Muster verwenden, um ein Modell zu 'trainieren', das diese Klasse von Gesten erkennen kann. Mehrere Beispiele führen in der Regel zu einem besseren Modell, wobei zu berücksichtigen ist, auf wie viele verschiedene Arten eine Geste ausgeführt werden kann.", "content.data.classification": "Klassen", diff --git a/src/assets/messages/ui.en.json b/src/assets/messages/ui.en.json index 8be5c56a3..ef951bc6e 100644 --- a/src/assets/messages/ui.en.json +++ b/src/assets/messages/ui.en.json @@ -30,8 +30,12 @@ "content.index.MLExplainer3": "The data representations of the data samples are shown to a neural network. The neural network “learns” from these examples by finding patterns in and between the samples.", "content.index.MLExplainer4": "This training process results in a trained neural network (we also call it a machine learning model) that can guess/predict how the micro:bit is moved when the same properties (standard deviation, cumulated acceleration, maximum value, etc.) are calculated from the live accelerometer data.", "content.data.classPlaceholderNewClass": "Press here to change name", + "content.data.print": "Print", + "content.data.delete": "Delete", "content.data.record": "Record", "content.data.addData": "Add Data", + "content.data.select": "Select", + "content.data.csv": "Download as csv", "content.data.classHelpHeader": "Class", "content.data.classHelpBody": "A class describes a type of gesture. We can record examples of a certain type of gesture and put the examples in the same class. The trainer can find patterns in the examples/data and use these patterns to 'train' a model that can recognize this class of gestures. Multiple examples will typically result in a better model, and consider how many different ways a gesture can be performed.", "content.data.classification": "Classes", diff --git a/src/components/features/GoToPlaygroundButton.svelte b/src/components/features/GoToPlaygroundButton.svelte deleted file mode 100644 index e85053d7b..000000000 --- a/src/components/features/GoToPlaygroundButton.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - - - { - navigate(Paths.PLAYGROUND); - }}> - Go to playground - diff --git a/src/components/features/bottom/BottomPanelLiveDataValues.svelte b/src/components/features/bottom/BottomPanelLiveDataValues.svelte index 89473befa..322a85f2a 100644 --- a/src/components/features/bottom/BottomPanelLiveDataValues.svelte +++ b/src/components/features/bottom/BottomPanelLiveDataValues.svelte @@ -8,9 +8,9 @@ import { derived } from 'svelte/store'; import { stores } from '../../../lib/stores/Stores'; import StaticConfiguration from '../../../StaticConfiguration'; - import type { Axis } from '../../../lib/domain/Axis'; import FixedNumber from '../../ui/FixedNumber.svelte'; import SmoothedLiveData from '../../../lib/livedata/SmoothedLiveData'; + import type { Axis } from '../../../core/entities/Axis'; const highlightedAxes = stores.getHighlightedAxes(); const availableAxes = stores.getAvailableAxes(); diff --git a/src/components/features/datacollection/Gesture.svelte b/src/components/features/datacollection/Gesture.svelte index e2505b50f..1418f9f3d 100644 --- a/src/components/features/datacollection/Gesture.svelte +++ b/src/components/features/datacollection/Gesture.svelte @@ -19,23 +19,25 @@ import ImageSkeleton from '../../ui/skeletonloading/ImageSkeleton.svelte'; import GestureCard from '../../ui/Card.svelte'; import StaticConfiguration from '../../../StaticConfiguration'; - import Gesture from '../../../lib/domain/stores/gesture/Gesture'; import { stores } from '../../../lib/stores/Stores'; - import type { RecordingData } from '../../../lib/domain/RecordingData'; + import type { RecordingData } from '../../../core/entities/RecordingData'; import { startRecording } from '../../../lib/utils/Recording'; import GestureDot from '../../ui/GestureDot.svelte'; import StandardButton from '../../ui/buttons/StandardButton.svelte'; + import IconButton from '../../ui/buttons/IconButton.svelte'; import { Feature, getFeature, hasFeature } from '../../../lib/FeatureToggles'; import { printRecordings } from '../../../lib/utils/printRecordings'; + import type GestureState from '../../../lib/domain/stores/gesture/GestureState'; export let onNoMicrobitSelect: () => void; - export let gesture: Gesture; + export let gesture: GestureState; const devices = stores.getDevices(); const gestures = stores.getGestures(); const defaultNewName = $t('content.data.classPlaceholderNewClass'); const recordingDuration = getFeature(Feature.RECORDING_DURATION); const enableFingerprint = stores.getEnableFingerprint(); + const highlightedAxes = stores.getHighlightedAxes(); let isThisRecording = false; @@ -51,7 +53,7 @@ function handlePrintRecordings(): void { const recordings = gesture.getRecordings() ?? []; if (!recordings || recordings.length === 0) return; - printRecordings(gesture.getName(), recordings); + printRecordings(gesture.getName(), recordings, $highlightedAxes); } function removeClicked(): void { @@ -179,46 +181,67 @@ {#if hasFeature(Feature.PRINTABLE_RECORDINGS)} - handlePrintRecordings()}> - Print - + + + {/if}
+ font-semibold transition ease + rounded-xl border border-gray-300 + border-solid hover:bg-gray-100">

- + aria-hidden="true" /> +
{#if $chosenGesture !== gesture} -
-
- -
+
+ +