diff --git a/custom_tfjs/custom_tfjs.js b/custom_tfjs/custom_tfjs.js new file mode 100644 index 00000000..5d8d0080 --- /dev/null +++ b/custom_tfjs/custom_tfjs.js @@ -0,0 +1,178 @@ +/** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + * ============================================================================= + */ + +// This file is autogenerated. + + +import {registerKernel} from '@tensorflow/tfjs-core/dist/base'; +import '@tensorflow/tfjs-core/dist/base_side_effects'; +export * from '@tensorflow/tfjs-core/dist/base'; +export * from '@tensorflow/tfjs-converter'; + +//backend = cpu +export * from '@tensorflow/tfjs-backend-cpu/dist/base'; +import {splitVConfig as SplitV_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/SplitV'; +registerKernel(SplitV_cpu); +import {maxConfig as Max_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Max'; +registerKernel(Max_cpu); +import {minConfig as Min_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Min'; +registerKernel(Min_cpu); +import {subConfig as Sub_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Sub'; +registerKernel(Sub_cpu); +import {realDivConfig as RealDiv_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/RealDiv'; +registerKernel(RealDiv_cpu); +import {multiplyConfig as Multiply_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Multiply'; +registerKernel(Multiply_cpu); +import {sliceConfig as Slice_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Slice'; +registerKernel(Slice_cpu); +import {concatConfig as Concat_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Concat'; +registerKernel(Concat_cpu); +import {reshapeConfig as Reshape_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Reshape'; +registerKernel(Reshape_cpu); +import {zerosLikeConfig as ZerosLike_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/ZerosLike'; +registerKernel(ZerosLike_cpu); +import {complexConfig as Complex_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Complex'; +registerKernel(Complex_cpu); +import {fFTConfig as FFT_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/FFT'; +registerKernel(FFT_cpu); +import {realConfig as Real_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Real'; +registerKernel(Real_cpu); +import {imagConfig as Imag_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Imag'; +registerKernel(Imag_cpu); +import {complexAbsConfig as ComplexAbs_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/ComplexAbs'; +registerKernel(ComplexAbs_cpu); +import {packConfig as Pack_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Pack'; +registerKernel(Pack_cpu); +import {transposeConfig as Transpose_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Transpose'; +registerKernel(Transpose_cpu); +import {reverseConfig as Reverse_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Reverse'; +registerKernel(Reverse_cpu); +import {expandDimsConfig as ExpandDims_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/ExpandDims'; +registerKernel(ExpandDims_cpu); +import {resizeBilinearConfig as ResizeBilinear_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/ResizeBilinear'; +registerKernel(ResizeBilinear_cpu); +import {castConfig as Cast_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Cast'; +registerKernel(Cast_cpu); +import {conv2DConfig as Conv2D_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Conv2D'; +registerKernel(Conv2D_cpu); +import {addConfig as Add_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Add'; +registerKernel(Add_cpu); +import {sigmoidConfig as Sigmoid_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Sigmoid'; +registerKernel(Sigmoid_cpu); +import {fusedDepthwiseConv2DConfig as FusedDepthwiseConv2D_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/FusedDepthwiseConv2D'; +registerKernel(FusedDepthwiseConv2D_cpu); +import {meanConfig as Mean_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Mean'; +registerKernel(Mean_cpu); +import {stridedSliceConfig as StridedSlice_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/StridedSlice'; +registerKernel(StridedSlice_cpu); +import {batchMatMulConfig as BatchMatMul_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/BatchMatMul'; +registerKernel(BatchMatMul_cpu); +import {_fusedMatMulConfig as _FusedMatMul_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/_FusedMatMul'; +registerKernel(_FusedMatMul_cpu); +import {identityConfig as Identity_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Identity'; +registerKernel(Identity_cpu); +import {maximumConfig as Maximum_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Maximum'; +registerKernel(Maximum_cpu); +import {greaterConfig as Greater_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Greater'; +registerKernel(Greater_cpu); +import {tileConfig as Tile_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Tile'; +registerKernel(Tile_cpu); +import {selectConfig as Select_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Select'; +registerKernel(Select_cpu); +import {topKConfig as TopK_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/TopK'; +registerKernel(TopK_cpu); +import {squareConfig as Square_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/Square'; +registerKernel(Square_cpu); +import {greaterEqualConfig as GreaterEqual_cpu} from '@tensorflow/tfjs-backend-cpu/dist/kernels/GreaterEqual'; +registerKernel(GreaterEqual_cpu); + +//backend = webgl +export * from '@tensorflow/tfjs-backend-webgl/dist/base'; +import {splitVConfig as SplitV_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/SplitV'; +registerKernel(SplitV_webgl); +import {maxConfig as Max_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Max'; +registerKernel(Max_webgl); +import {minConfig as Min_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Min'; +registerKernel(Min_webgl); +import {subConfig as Sub_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Sub'; +registerKernel(Sub_webgl); +import {realDivConfig as RealDiv_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/RealDiv'; +registerKernel(RealDiv_webgl); +import {multiplyConfig as Multiply_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Multiply'; +registerKernel(Multiply_webgl); +import {sliceConfig as Slice_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Slice'; +registerKernel(Slice_webgl); +import {concatConfig as Concat_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Concat'; +registerKernel(Concat_webgl); +import {reshapeConfig as Reshape_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Reshape'; +registerKernel(Reshape_webgl); +import {zerosLikeConfig as ZerosLike_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/ZerosLike'; +registerKernel(ZerosLike_webgl); +import {complexConfig as Complex_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Complex'; +registerKernel(Complex_webgl); +import {fFTConfig as FFT_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/FFT'; +registerKernel(FFT_webgl); +import {realConfig as Real_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Real'; +registerKernel(Real_webgl); +import {imagConfig as Imag_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Imag'; +registerKernel(Imag_webgl); +import {complexAbsConfig as ComplexAbs_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/ComplexAbs'; +registerKernel(ComplexAbs_webgl); +import {packConfig as Pack_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Pack'; +registerKernel(Pack_webgl); +import {transposeConfig as Transpose_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Transpose'; +registerKernel(Transpose_webgl); +import {reverseConfig as Reverse_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Reverse'; +registerKernel(Reverse_webgl); +import {expandDimsConfig as ExpandDims_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/ExpandDims'; +registerKernel(ExpandDims_webgl); +import {resizeBilinearConfig as ResizeBilinear_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/ResizeBilinear'; +registerKernel(ResizeBilinear_webgl); +import {castConfig as Cast_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Cast'; +registerKernel(Cast_webgl); +import {conv2DConfig as Conv2D_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Conv2D'; +registerKernel(Conv2D_webgl); +import {addConfig as Add_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Add'; +registerKernel(Add_webgl); +import {sigmoidConfig as Sigmoid_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Sigmoid'; +registerKernel(Sigmoid_webgl); +import {fusedDepthwiseConv2DConfig as FusedDepthwiseConv2D_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/FusedDepthwiseConv2D'; +registerKernel(FusedDepthwiseConv2D_webgl); +import {meanConfig as Mean_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Mean'; +registerKernel(Mean_webgl); +import {stridedSliceConfig as StridedSlice_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/StridedSlice'; +registerKernel(StridedSlice_webgl); +import {batchMatMulConfig as BatchMatMul_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/BatchMatMul'; +registerKernel(BatchMatMul_webgl); +import {_fusedMatMulConfig as _FusedMatMul_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/_FusedMatMul'; +registerKernel(_FusedMatMul_webgl); +import {identityConfig as Identity_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Identity'; +registerKernel(Identity_webgl); +import {maximumConfig as Maximum_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Maximum'; +registerKernel(Maximum_webgl); +import {greaterConfig as Greater_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Greater'; +registerKernel(Greater_webgl); +import {tileConfig as Tile_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Tile'; +registerKernel(Tile_webgl); +import {selectConfig as Select_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Select'; +registerKernel(Select_webgl); +import {topKConfig as TopK_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/TopK'; +registerKernel(TopK_webgl); +import {squareConfig as Square_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/Square'; +registerKernel(Square_webgl); +import {greaterEqualConfig as GreaterEqual_webgl} from '@tensorflow/tfjs-backend-webgl/dist/kernels/GreaterEqual'; +registerKernel(GreaterEqual_webgl); \ No newline at end of file diff --git a/custom_tfjs/custom_tfjs_core.js b/custom_tfjs/custom_tfjs_core.js new file mode 100644 index 00000000..330b919d --- /dev/null +++ b/custom_tfjs/custom_tfjs_core.js @@ -0,0 +1,23 @@ +/** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + * ============================================================================= + */ + +// This file is autogenerated. + + +import {registerKernel} from '@tensorflow/tfjs-core/dist/base'; +import '@tensorflow/tfjs-core/dist/base_side_effects'; +export * from '@tensorflow/tfjs-core/dist/base'; \ No newline at end of file diff --git a/custom_tfjs_config.json b/custom_tfjs_config.json new file mode 100644 index 00000000..85b16465 --- /dev/null +++ b/custom_tfjs_config.json @@ -0,0 +1,11 @@ +{ + "kernels": ["SplitV", "Max", "Min", "Sub", "RealDiv", "Multiply", "Slice", "Concat", "Reshape", "ZerosLike", "Complex", "FFT", "Real", "Imag", "ComplexAbs", "Pack", "Transpose", "Reverse", "ExpandDims", "ResizeBilinear", "Cast", "Conv2D", "Add", "Sigmoid", "FusedDepthwiseConv2D", "fusedDepthwiseConv2d__op", "Mean", "StridedSlice", "BatchMatMul", "_FusedMatMul", "fusedMatMul__op", "Identity", "Maximum", "Greater", "Tile", "Select", "TopK", "Square", "GreaterEqual"], + "backends": [ + "cpu", "webgl" + ], + "models": [ + "./model/model.json" + ], + "outputPath": "./custom_tfjs", + "forwardModeOnly": true + } \ No newline at end of file diff --git a/js/audio_normalizer.js b/js/audio_normalizer.js deleted file mode 100644 index 4f1ac965..00000000 --- a/js/audio_normalizer.js +++ /dev/null @@ -1,64 +0,0 @@ -// audio-normalizer.js -class AudioNormlizer extends AudioWorkletProcessor { - process(inputs, outputs, parameters) { - const output = outputs[0]; - output.forEach((channel) => { - const channelMax = Math.max(...channel); - for (let i = 0; i < channel.length; i++) { - channel[i] = channel[i] / channelMax; - } - }); - return true; - } - } - - -// class AudioNormlizer extends AudioWorkletProcessor { -// constructor() { -// super(); -// this.maxLevel = 0.5; -// this.minLevel = 0.05; -// this.level = 0; -// } - -// static get parameterDescriptors() { -// return [ -// { name: 'cutoff', defaultValue: 100 }, -// { name: 'maxLevel', defaultValue: 0.5 }, -// { name: 'minLevel', defaultValue: 0.05 }, -// ]; -// } - -// process(inputs, outputs, parameters) { -// const input = inputs[0]; -// const output = outputs[0]; - -// // Apply a highpass filter to the input signal -// const frequency = parameters.cutoff[0]; -// const highpass = this.context.createBiquadFilter(); -// highpass.type = 'highpass'; -// highpass.frequency.value = frequency; - -// const gain = this.context.createGain(); - -// // Analyze the audio levels in real-time -// const max = Math.max(...input); -// const level = max.toFixed(2); // Round the level to two decimal places -// this.level = level >= this.maxLevel ? 1 : (level <= this.minLevel ? 0 : (level - this.minLevel) / (this.maxLevel - this.minLevel)); - -// // Connect the nodes -// const source = this.context.createBufferSource(); -// source.buffer = input; -// source.connect(highpass).connect(gain); -// gain.gain.value = this.level; - -// // Copy the output -// for (let i = 0; i < output.length; i++) { -// output[i].set(input[i]); -// } - -// return true; -// } -// } - -registerProcessor("audio-normalizer", AudioNormlizer); diff --git a/js/ui.js b/js/ui.js index c4086d6e..a42df479 100644 --- a/js/ui.js +++ b/js/ui.js @@ -496,7 +496,7 @@ const filename = document.getElementById('filename'); filename.addEventListener('click', openFileInList); filename.addEventListener('contextmenu', buildFileMenu); -function renderFilnamePanel() { +function renderFilenamePanel() { if (!currentFile) return; const openfile = currentFile; const files = fileList; @@ -939,7 +939,7 @@ function hideAll() { const save2dbLink = document.getElementById('save2db'); save2dbLink.addEventListener('click', async () => { worker.postMessage({ action: 'save2db', file: currentFile }) - renderFilnamePanel(); + renderFilenamePanel(); }); const export2audio = document.getElementById('export2audio'); @@ -1465,13 +1465,6 @@ const setUpWorkerMessaging = () => { case 'diskDB-has-records': chartsLink.classList.remove('disabled'); exploreLink.classList.remove('disabled'); - if (currentFile) { - worker.postMessage({ - action: 'filter', - species: isSpeciesViewFiltered(true), - active: getActiveRowID(), - }); // no re-prepare - } break; case 'file-location-id': onFileLocationID(args); @@ -1481,7 +1474,7 @@ const setUpWorkerMessaging = () => { break; case 'generate-alert': if (args.render) { - renderFilnamePanel(); + renderFilenamePanel(); window.electron.unsavedRecords(false); document.getElementById('unsaved-icon').classList.add('d-none'); } @@ -1489,7 +1482,16 @@ const setUpWorkerMessaging = () => { let message = args.message; message += '\nWould you like to remove the file from the Archive?'; if (confirm(message)) deleteFile(args.file) - } else { alert(args.message) } + } else { + if (args.savedToDB){ + worker.postMessage({ + action: 'filter', + species: isSpeciesViewFiltered(true), + active: getActiveRowID(), + }); // no re-prepare + } + alert(args.message) + } break; case 'location-list': LOCATIONS = args.locations; @@ -1501,7 +1503,7 @@ const setUpWorkerMessaging = () => { case 'mode-changed': STATE.mode = args.mode; // Update the current file name in the UI - renderFilnamePanel(); + renderFilenamePanel(); console.log('Mode changed to: ' + args.mode); break; case 'no-detections-remain': @@ -2475,7 +2477,7 @@ async function onWorkerLoadedAudio({ NEXT_BUFFER = undefined; if (currentFile !== file) { currentFile = file; - renderFilnamePanel(); + renderFilenamePanel(); fileStart = start; fileEnd = new Date(fileStart + (currentFileDuration * 1000)); } @@ -3906,7 +3908,7 @@ function deleteFile(file) { fileName: file }) } - renderFilnamePanel() + renderFilenamePanel() } } // Utility functions to wait for file to load diff --git a/js/worker.js b/js/worker.js index c4475290..31bfd9ed 100644 --- a/js/worker.js +++ b/js/worker.js @@ -267,7 +267,8 @@ async function handleMessage(e) { if (STATE.mode !== 'explore' && !args.batch && args.toDisk) { UI.postMessage({ event: 'generate-alert', - message: `${count} ${args.cname} record has been saved to the archive.` + message: `${count} ${args.cname} record has been saved to the archive.`, + savedToDB: true }) } break; @@ -1651,7 +1652,7 @@ async function batchInsertRecords(cname, label, toDisk, files, originalCname) { } await db.runAsync('END'); console.log(`Batch record update took ${(Date.now() - t0) / 1000} seconds`) - if (STATE.mode !== 'explore' && toDisk) UI.postMessage({ event: 'generate-alert', message: `${count} ${cname} records have been saved to the archive.` }) + if (STATE.mode !== 'explore' && toDisk) UI.postMessage({ event: 'generate-alert', message: `${count} ${cname} records have been saved to the archive.`, savedToDB: true }) } const onInsertManualRecord = async ({ cname, start, end, comment, count, file, label, toDisk, batch, originalCname }) => { diff --git a/kernels.txt b/kernels.txt new file mode 100644 index 00000000..931f88db --- /dev/null +++ b/kernels.txt @@ -0,0 +1,16 @@ + + + +['SplitV', 'Max', 'Min', 'Sub', 'RealDiv', 'Multiply', 'Slice', 'Concat', 'Reshape', 'ZerosLike', 'Complex', 'FFT', 'Real', 'Imag', 'ComplexAbs', 'Pack', 'Transpose', 'Reverse', 'ExpandDims', 'ResizeBilinear', 'Cast', 'Conv2D', 'Add', 'Sigmoid', 'FusedDepthwiseConv2D', 'fusedDepthwiseConv2d__op', 'Mean', 'StridedSlice', 'BatchMatMul', '_FusedMatMul', 'fusedMatMul__op', 'Identity', 'Maximum', 'Greater', 'Tile', 'Select', 'TopK', 'Square', 'GreaterEqual'] + +{ + "kernels": ['SplitV', 'Max', 'Min', 'Sub', 'RealDiv', 'Multiply', 'Slice', 'Concat', 'Reshape', 'ZerosLike', 'Complex', 'FFT', 'Real', 'Imag', 'ComplexAbs', 'Pack', 'Transpose', 'Reverse', 'ExpandDims', 'ResizeBilinear', 'Cast', 'Conv2D', 'Add', 'Sigmoid', 'FusedDepthwiseConv2D', 'fusedDepthwiseConv2d__op', 'Mean', 'StridedSlice', 'BatchMatMul', '_FusedMatMul', 'fusedMatMul__op', 'Identity', 'Maximum', 'Greater', 'Tile', 'Select', 'TopK', 'Square', 'GreaterEqual'], + "backends": [ + "tensorflow", "webgl" + ], + "models": [ + "./model/model.json" + ], + "outputPath": "./custom_tfjs", + "forwardModeOnly": true +} \ No newline at end of file diff --git a/minify.js b/minify.js new file mode 100644 index 00000000..231798ed --- /dev/null +++ b/minify.js @@ -0,0 +1,65 @@ +const terser = require('terser'); +const fs = require('fs'); +const path = require('path'); + +const minifyOptions = { + parse: { + // parse options + }, + compress: { + // compress options + }, + mangle: { + // mangle options + toplevel: true, + properties: { + // mangle property options + } + }, + format: { + // format options (can also use `output` for backwards compatibility) + }, + sourceMap: { + // source map options + }, + ecma: 2016, // specify one of: 5, 2015, 2016, etc. + enclose: false, // or specify true, or "args:values" + keep_classnames: false, + keep_fnames: false, + ie8: false, + module: false, + nameCache: null, // or specify a name cache object + safari10: false, + toplevel: true +} +// Directory containing your JavaScript files +const directory = process.cwd(); + +// Function to recursively minify JavaScript files +function minifyFiles(dir) { + const files = fs.readdirSync(dir); + files.forEach(async file => { + const filePath = path.join(dir, file); + + if (fs.statSync(filePath).isDirectory() && ! filePath.endsWith('node_modules')) { + // If it's a directory, recursively process its contents + minifyFiles(filePath); + } else if (filePath.endsWith('.js') && !fs.existsSync(filePath + '.map') && !filePath.endsWith('min.js')) { + // If it's a JavaScript file, minify it and rename to *.min.js + const inputCode = fs.readFileSync(filePath, 'utf8'); + const minifiedCode = await terser.minify(inputCode); + if (minifiedCode.error) { + console.error('Error minifying JavaScript:', minifiedCode.error); + } else { + // Rename the file to *.min.js + const minifiedFilePath = filePath.replace(/\.js$/, '.min.js'); + console.log(filePath, minifiedFilePath) + fs.writeFileSync(minifiedFilePath, minifiedCode.code, 'utf8'); + console.log(`Minified and renamed: ${minifiedFilePath}`); + } + } + }); +} + +// Start minification from the root directory +minifyFiles(directory); diff --git a/package.json b/package.json index 627913f7..b566bae0 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "main": "main.js", "scripts": { "start": "electron .", + "minify": "node minify.js", "export": "electron-builder build -w --x64", "publish": "electron-builder --win -p always" }, @@ -23,6 +24,12 @@ "files": [ "**/*", "!test*${/*}", + "!custom*{/*}", + "!.vscode${*/}", + "!.idea{*/}", + "!kernels.txt", + "!minify.js", + "!playwright.*", "!dist${/*}", "!BirdNet${/*}", "!*fixed_roll*${/*}", @@ -34,10 +41,8 @@ "!poetry.lock*", "!pyproject.toml", "!README.md", - "!.idea", "!saved_model$(/*)", "!**/*.js.map", - "model_config.json", "node_modules/ffmpeg-static-electron/bin/${os}/${arch}/ffmpeg", "node_modules/ffmpeg-static-electron/index.js", "node_modules/ffmpeg-static-electron/package.json", @@ -175,7 +180,8 @@ "electron-builder": "24.6.4", "electron-playwright-helpers": "^1.6.0", "playwright": "^1.39.0", - "jimp": "0.22.10" + "jimp": "0.22.10", + "terser": "5.22.0" }, "dependencies": { "@popperjs/core": "^2.9.2",