kopia lustrzana https://github.com/mifi/lossless-cut
commit
476ab11f63
|
@ -35,12 +35,6 @@ For Windows, you may have to install [7z](https://www.7-zip.org/download.html),
|
|||
npm start
|
||||
```
|
||||
|
||||
### Building for production
|
||||
|
||||
See:
|
||||
- https://www.electron.build/
|
||||
- https://github.com/mifi/lossless-cut/blob/master/.github/workflows/build.yml
|
||||
|
||||
## Building mas-dev (Mac App Store) build locally
|
||||
|
||||
This will sign using the development provisioning profile:
|
||||
|
@ -62,7 +56,7 @@ NOTE: when MAS (dev) build, Application Support will instead be here:
|
|||
rm -rf ~/Library/Containers/no.mifi.losslesscut-mac
|
||||
```
|
||||
|
||||
## Windows Store
|
||||
## Windows Store notes
|
||||
|
||||
Windows store version is built as a Desktop Bridge app (with `runFullTrust` capability). This means the app has access to essentially everything the user has access to, and even `internetClient` is redundant.
|
||||
|
||||
|
@ -76,13 +70,21 @@ For per-platform build/signing setup, see [this article](https://mifi.no/blog/au
|
|||
|
||||
### Release new version
|
||||
|
||||
- Commit changes
|
||||
- If Mac App Store / Windows Store
|
||||
- Checkout branch `stores`
|
||||
- Merge `master` into `stores`
|
||||
- `npm version ...`
|
||||
- `git push --follow-tags`
|
||||
- Wait for build and draft in Github actions
|
||||
- Open draft in github and add Release notes
|
||||
- For files `LosslessCut-mac-universal.pkg` and `LosslessCut-win-x64.appx` add prefix `-DO-NOT-DOWNLOAD`
|
||||
- Release the draft
|
||||
- If intended as Github, release the draft
|
||||
- If store-only release, release the draft as **pre-release**
|
||||
|
||||
### After release
|
||||
|
||||
- If Mac App Store / Windows Store
|
||||
- Merge `stores` into `master`
|
||||
- Bump [snap version](https://snapcraft.io/losslesscut/listing)
|
||||
- `npm run scan-i18n` to get the newest English strings and push so weblate gets them
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<url type="bugtracker">https://github.com/mifi/lossless-cut/issues</url>
|
||||
<url type="donation">https://paypal.me/mifino/usd</url>
|
||||
<releases>
|
||||
<release version="3.60.0" date="2024-01-05"/>
|
||||
<release version="3.59.1" date="2023-12-22"/>
|
||||
<release version="3.59.0" date="2023-12-22"/>
|
||||
<release version="3.58.0" date="2023-10-16"/>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"productName": "LosslessCut",
|
||||
"description": "The swiss army knife of lossless video/audio editing",
|
||||
"copyright": "Copyright © 2021 ${author}",
|
||||
"version": "3.59.1",
|
||||
"version": "3.60.0",
|
||||
"main": "public/electron.js",
|
||||
"homepage": "./",
|
||||
"scripts": {
|
||||
|
@ -13,7 +13,7 @@
|
|||
"icon-gen": "mkdirp icon-build build-resources/appx && node script/icon-gen.mjs",
|
||||
"download-ffmpeg-darwin-x64": "mkdirp ffmpeg/darwin-x64 && cd ffmpeg/darwin-x64 && wget https://github.com/mifi/ffmpeg-build-script/releases/download/6.0/ffmpeg -O ffmpeg && wget https://github.com/mifi/ffmpeg-build-script/releases/download/6.0/ffprobe -O ffprobe && chmod +x ffmpeg && chmod +x ffprobe",
|
||||
"download-ffmpeg-darwin-arm64": "mkdirp ffmpeg/darwin-arm64 && cd ffmpeg/darwin-arm64 && wget https://github.com/mifi/ffmpeg-builds/releases/download/6.0/ffmpeg-darwin-arm64-v6.0 -O ffmpeg && wget https://github.com/mifi/ffmpeg-builds/releases/download/6.0/ffprobe-darwin-arm64-v6.0 -O ffprobe && chmod +x ffmpeg && chmod +x ffprobe",
|
||||
"download-ffmpeg-linux-x64": "mkdirp ffmpeg/linux-x64 && cd ffmpeg/linux-x64 && wget https://github.com/mifi/ffmpeg-builds/releases/download/6.0/ffmpeg-n6.0-12-ga6dc92968a-linux64-gpl-shared-6.0.tar.xz -O ffmpeg-ffprobe.xz && tar -xv -f ffmpeg-ffprobe.xz && mv ffmpeg-n6.0-12-ga6dc92968a-linux64-gpl-shared-6.0 extracted && mkdirp lib && mv extracted/bin/{ffmpeg,ffprobe} extracted/lib/lib*.so* lib",
|
||||
"download-ffmpeg-linux-x64": "mkdirp ffmpeg/linux-x64 && cd ffmpeg/linux-x64 && wget https://github.com/mifi/ffmpeg-builds/releases/download/6.0/ffmpeg-n6.0-12-ga6dc92968a-linux64-gpl-shared-6.0.tar.xz -O ffmpeg-ffprobe.xz && tar -xv -f ffmpeg-ffprobe.xz && mv ffmpeg-n6.0-12-ga6dc92968a-linux64-gpl-shared-6.0 extracted && mkdirp lib && mv extracted/bin/ffmpeg extracted/bin/ffprobe extracted/lib/lib*.so* lib",
|
||||
"download-ffmpeg-win32-x64": "mkdirp ffmpeg/win32-x64 && cd ffmpeg/win32-x64 && npx download-cli https://github.com/mifi/ffmpeg-builds/releases/download/6.0/ffmpeg-n6.0-12-ga6dc92968a-win64-gpl-shared-6.0.zip --out . --filename ffmpeg-ffprobe.zip && 7z x ffmpeg-ffprobe.zip && mkdirp lib && cd ffmpeg-n6.0-12-ga6dc92968a-win64-gpl-shared-6.0/bin && npx shx mv ffmpeg.exe ffprobe.exe *.dll ../../lib",
|
||||
"build": "yarn icon-gen && vite build --outDir vite-dist",
|
||||
"tsc": "tsc --build",
|
||||
|
@ -99,7 +99,7 @@
|
|||
"use-debounce": "^5.1.0",
|
||||
"use-trace-update": "^1.3.0",
|
||||
"uuid": "^8.3.2",
|
||||
"vite": "^4.1.5",
|
||||
"vite": "^4.5.2",
|
||||
"vitest": "^0.28.5",
|
||||
"wait-on": "^7.0.1"
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@ const { stat } = require('fs/promises');
|
|||
const logger = require('./logger');
|
||||
const menu = require('./menu');
|
||||
const configStore = require('./configStore');
|
||||
const { frontendBuildDir } = require('./util');
|
||||
const { frontendBuildDir, isLinux, isWindows } = require('./util');
|
||||
const attachContextMenu = require('./contextMenu');
|
||||
const HttpServer = require('./httpServer');
|
||||
|
||||
|
@ -33,6 +33,9 @@ unhandled({
|
|||
});
|
||||
|
||||
const appName = 'LosslessCut';
|
||||
const copyrightYear = 2024;
|
||||
|
||||
const appVersion = app.getVersion();
|
||||
|
||||
app.name = appName;
|
||||
|
||||
|
@ -40,11 +43,21 @@ const isStoreBuild = process.windowsStore || process.mas;
|
|||
|
||||
const showVersion = !isStoreBuild;
|
||||
|
||||
const aboutPanelOptions = { applicationName: appName };
|
||||
/** @type import('electron').AboutPanelOptionsOptions */
|
||||
const aboutPanelOptions = {
|
||||
applicationName: appName,
|
||||
copyright: `Copyright © ${copyrightYear} Mikael Finstad ❤️ 🇳🇴`,
|
||||
version: '', // not very useful (MacOS only, and same as applicationVersion)
|
||||
};
|
||||
|
||||
// https://github.com/electron/electron/issues/18918
|
||||
// https://github.com/mifi/lossless-cut/issues/1537
|
||||
if (isLinux) {
|
||||
aboutPanelOptions.version = appVersion;
|
||||
}
|
||||
if (!showVersion) {
|
||||
// version will be wrong in Store builds
|
||||
aboutPanelOptions.applicationVersion = '';
|
||||
aboutPanelOptions.version = '';
|
||||
// https://github.com/mifi/lossless-cut/issues/1882
|
||||
aboutPanelOptions.applicationVersion = `${process.windowsStore ? 'Microsoft Store' : 'App Store'} edition, based on GitHub v${appVersion}`;
|
||||
}
|
||||
|
||||
// https://www.electronjs.org/docs/latest/api/app#appsetaboutpaneloptionsoptions
|
||||
|
@ -121,13 +134,13 @@ function createWindow() {
|
|||
webSecurity: !isDev,
|
||||
},
|
||||
backgroundColor: darkMode ? '#333' : '#fff',
|
||||
autoHideMenuBar: isWindows, // https://github.com/mifi/lossless-cut/issues/543#issuecomment-1872945955
|
||||
});
|
||||
|
||||
remote.enable(mainWindow.webContents);
|
||||
|
||||
attachContextMenu(mainWindow);
|
||||
|
||||
|
||||
if (isDev) mainWindow.loadURL('http://localhost:3001');
|
||||
// Need to useloadFile for special characters https://github.com/mifi/lossless-cut/issues/40
|
||||
else mainWindow.loadFile(`${frontendBuildDir}/index.html`);
|
||||
|
|
49
src/App.jsx
49
src/App.jsx
|
@ -68,7 +68,7 @@ import {
|
|||
getOutPath, getSuffixedOutPath, handleError, getOutDir,
|
||||
isStoreBuild, dragPreventer,
|
||||
havePermissionToReadFile, resolvePathIfNeeded, getPathReadAccessError, html5ifiedPrefix, html5dummySuffix, findExistingHtml5FriendlyFile,
|
||||
deleteFiles, isOutOfSpaceError, isExecaFailure, readFileSize, readFileSizes, checkFileSizes, setDocumentTitle, getOutFileExtension, getSuffixedFileName, mustDisallowVob, readVideoTs, getImportProjectType,
|
||||
deleteFiles, isOutOfSpaceError, isExecaFailure, readFileSize, readFileSizes, checkFileSizes, setDocumentTitle, getOutFileExtension, getSuffixedFileName, mustDisallowVob, readVideoTs, readDirRecursively, getImportProjectType,
|
||||
calcShouldShowWaveform, calcShouldShowKeyframes, mediaSourceQualities,
|
||||
} from './util';
|
||||
import { toast, errorToast } from './swal';
|
||||
|
@ -88,6 +88,7 @@ import isDev from './isDev';
|
|||
|
||||
const electron = window.require('electron');
|
||||
const { exists } = window.require('fs-extra');
|
||||
const { lstat } = window.require('fs/promises');
|
||||
const filePathToUrl = window.require('file-url');
|
||||
const { parse: parsePath, join: pathJoin, basename, dirname } = window.require('path');
|
||||
|
||||
|
@ -1178,8 +1179,8 @@ function App() {
|
|||
|
||||
console.log('outSegTemplateOrDefault', outSegTemplateOrDefault);
|
||||
|
||||
const { outSegFileNames, outSegError } = generateOutSegFileNames({ segments: segmentsToExport, template: outSegTemplateOrDefault });
|
||||
if (outSegError != null) {
|
||||
const { outSegFileNames, outSegProblems } = generateOutSegFileNames({ segments: segmentsToExport, template: outSegTemplateOrDefault });
|
||||
if (outSegProblems.error != null) {
|
||||
console.warn('Output segments file name invalid, using default instead', outSegFileNames);
|
||||
}
|
||||
|
||||
|
@ -1296,6 +1297,7 @@ function App() {
|
|||
await onExportConfirm();
|
||||
} else {
|
||||
setExportConfirmVisible(true);
|
||||
setStreamsSelectorShown(false);
|
||||
}
|
||||
}, [filePath, exportConfirmEnabled, exportConfirmVisible, onExportConfirm]);
|
||||
|
||||
|
@ -1649,7 +1651,6 @@ function App() {
|
|||
|
||||
const handleShowStreamsSelectorClick = useCallback(() => {
|
||||
setStreamsSelectorShown(true);
|
||||
setExportConfirmVisible(false);
|
||||
}, []);
|
||||
|
||||
const extractAllStreams = useCallback(async () => {
|
||||
|
@ -1800,12 +1801,28 @@ function App() {
|
|||
|
||||
[lastOpenedPathRef.current] = filePaths;
|
||||
|
||||
// https://en.wikibooks.org/wiki/Inside_DVD-Video/Directory_Structure
|
||||
if (filePaths.length === 1 && /^VIDEO_TS$/i.test(basename(filePaths[0]))) {
|
||||
if (mustDisallowVob()) return;
|
||||
filePaths = await readVideoTs(filePaths[0]);
|
||||
// first check if it is a single directory, and if so, read it recursively
|
||||
if (filePaths.length === 1) {
|
||||
const firstFilePath = filePaths[0];
|
||||
const firstFileStat = await lstat(firstFilePath);
|
||||
if (firstFileStat.isDirectory()) {
|
||||
console.log('Reading directory...');
|
||||
filePaths = await readDirRecursively(firstFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
// Only allow opening regular files
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const path of filePaths) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const fileStat = await lstat(path);
|
||||
|
||||
if (!fileStat.isFile()) {
|
||||
errorToast(i18n.t('Cannot open anything else than regular files'));
|
||||
console.warn('Not a file:', path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (filePaths.length > 1) {
|
||||
if (alwaysConcatMultipleFiles) {
|
||||
|
@ -1820,6 +1837,12 @@ function App() {
|
|||
// filePaths.length is now 1
|
||||
const firstFilePath = filePaths[0];
|
||||
|
||||
// https://en.wikibooks.org/wiki/Inside_DVD-Video/Directory_Structure
|
||||
if (/^VIDEO_TS$/i.test(basename(firstFilePath))) {
|
||||
if (mustDisallowVob()) return;
|
||||
filePaths = await readVideoTs(firstFilePath);
|
||||
}
|
||||
|
||||
if (workingRef.current) return;
|
||||
try {
|
||||
setWorking({ text: i18n.t('Loading file') });
|
||||
|
@ -1900,7 +1923,7 @@ function App() {
|
|||
}, [alwaysConcatMultipleFiles, batchLoadPaths, setWorking, isFileOpened, batchFiles.length, userOpenSingleFile, checkFileOpened, loadEdlFile, enableAskForFileOpenAction, addStreamSourceFile, filePath]);
|
||||
|
||||
const openFilesDialog = useCallback(async () => {
|
||||
const { canceled, filePaths } = await showOpenDialog({ properties: ['openFile', 'multiSelections'], defaultPath: lastOpenedPathRef.current });
|
||||
const { canceled, filePaths } = await showOpenDialog({ properties: ['openFile', 'openDirectory', 'multiSelections'], defaultPath: lastOpenedPathRef.current });
|
||||
if (canceled) return;
|
||||
userOpenFiles(filePaths);
|
||||
}, [userOpenFiles]);
|
||||
|
@ -2578,7 +2601,9 @@ function App() {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<Sheet visible={streamsSelectorShown} onClosePress={() => setStreamsSelectorShown(false)} style={{ padding: '1em 0' }}>
|
||||
<ExportConfirm filePath={filePath} areWeCutting={areWeCutting} nonFilteredSegmentsOrInverse={nonFilteredSegmentsOrInverse} selectedSegments={selectedSegmentsOrInverse} segmentsToExport={segmentsToExport} willMerge={willMerge} visible={exportConfirmVisible} onClosePress={closeExportConfirm} onExportConfirm={onExportConfirm} renderOutFmt={renderOutFmt} outputDir={outputDir} numStreamsTotal={numStreamsTotal} numStreamsToCopy={numStreamsToCopy} onShowStreamsSelectorClick={handleShowStreamsSelectorClick} outFormat={fileFormat} setOutSegTemplate={setOutSegTemplate} outSegTemplate={outSegTemplateOrDefault} generateOutSegFileNames={generateOutSegFileNames} currentSegIndexSafe={currentSegIndexSafe} mainCopiedThumbnailStreams={mainCopiedThumbnailStreams} needSmartCut={needSmartCut} mergedOutFileName={mergedOutFileName} setMergedOutFileName={setMergedOutFileName} />
|
||||
|
||||
<Sheet visible={streamsSelectorShown} onClosePress={() => setStreamsSelectorShown(false)} maxWidth={1000}>
|
||||
{mainStreams && (
|
||||
<StreamsSelector
|
||||
mainFilePath={filePath}
|
||||
|
@ -2606,15 +2631,13 @@ function App() {
|
|||
)}
|
||||
</Sheet>
|
||||
|
||||
<ExportConfirm filePath={filePath} areWeCutting={areWeCutting} nonFilteredSegmentsOrInverse={nonFilteredSegmentsOrInverse} selectedSegments={selectedSegmentsOrInverse} segmentsToExport={segmentsToExport} willMerge={willMerge} visible={exportConfirmVisible} onClosePress={closeExportConfirm} onExportConfirm={onExportConfirm} renderOutFmt={renderOutFmt} outputDir={outputDir} numStreamsTotal={numStreamsTotal} numStreamsToCopy={numStreamsToCopy} onShowStreamsSelectorClick={handleShowStreamsSelectorClick} outFormat={fileFormat} setOutSegTemplate={setOutSegTemplate} outSegTemplate={outSegTemplateOrDefault} generateOutSegFileNames={generateOutSegFileNames} currentSegIndexSafe={currentSegIndexSafe} mainCopiedThumbnailStreams={mainCopiedThumbnailStreams} needSmartCut={needSmartCut} mergedOutFileName={mergedOutFileName} setMergedOutFileName={setMergedOutFileName} />
|
||||
|
||||
<LastCommandsSheet
|
||||
visible={lastCommandsVisible}
|
||||
onTogglePress={toggleLastCommands}
|
||||
ffmpegCommandLog={ffmpegCommandLog}
|
||||
/>
|
||||
|
||||
<Sheet visible={settingsVisible} onClosePress={toggleSettings} style={{ padding: '1em 0' }}>
|
||||
<Sheet visible={settingsVisible} onClosePress={toggleSettings}>
|
||||
<Settings
|
||||
onTunerRequested={onTunerRequested}
|
||||
onKeyboardShortcutsDialogRequested={toggleKeyboardShortcuts}
|
||||
|
|
|
@ -8,7 +8,7 @@ const LastCommandsSheet = memo(({ visible, onTogglePress, ffmpegCommandLog }) =>
|
|||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Sheet visible={visible} onClosePress={onTogglePress} style={{ paddingTop: '2em' }}>
|
||||
<Sheet visible={visible} onClosePress={onTogglePress} style={{ padding: '0 1em' }}>
|
||||
<h2>{t('Last ffmpeg commands')}</h2>
|
||||
|
||||
{ffmpegCommandLog.length > 0 ? (
|
||||
|
|
|
@ -42,7 +42,7 @@ const Waveforms = memo(({ calculateTimelinePercent, durationSafe, waveforms, zoo
|
|||
|
||||
const CommandedTime = memo(({ commandedTimePercent }) => {
|
||||
const color = 'var(--gray12)';
|
||||
const commonStyle = { left: commandedTimePercent, position: 'absolute', zIndex: 4, pointerEvents: 'none' };
|
||||
const commonStyle = { left: commandedTimePercent, position: 'absolute', pointerEvents: 'none' };
|
||||
return (
|
||||
<>
|
||||
<FaCaretDown style={{ ...commonStyle, top: 0, color, fontSize: 14, marginLeft: -7, marginTop: -6 }} />
|
||||
|
@ -275,7 +275,7 @@ const Timeline = memo(({
|
|||
const nextThumbTime = nextThumbnail ? nextThumbnail.time : durationSafe;
|
||||
const maxWidthPercent = ((nextThumbTime - thumbnail.time) / durationSafe) * 100 * 0.9;
|
||||
return (
|
||||
<img key={thumbnail.url} src={thumbnail.url} alt="" style={{ position: 'absolute', left: `${leftPercent}%`, height: '100%', boxSizing: 'border-box', zIndex: 1, maxWidth: `${maxWidthPercent}%`, objectFit: 'cover', border: '1px solid rgba(255, 255, 255, 0.5)', borderBottomRightRadius: 15, borderTopLeftRadius: 15, borderTopRightRadius: 15, pointerEvents: 'none' }} />
|
||||
<img key={thumbnail.url} src={thumbnail.url} alt="" style={{ position: 'absolute', left: `${leftPercent}%`, height: '100%', boxSizing: 'border-box', maxWidth: `${maxWidthPercent}%`, objectFit: 'cover', border: '1px solid rgba(255, 255, 255, 0.5)', borderBottomRightRadius: 15, borderTopLeftRadius: 15, borderTopRightRadius: 15, pointerEvents: 'none' }} />
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
@ -285,13 +285,6 @@ const Timeline = memo(({
|
|||
style={{ height: timelineHeight, width: `${zoom * 100}%`, position: 'relative', backgroundColor: timelineBackground, transition: darkModeTransition }}
|
||||
ref={timelineWrapperRef}
|
||||
>
|
||||
{currentTimePercent !== undefined && (
|
||||
<motion.div transition={{ type: 'spring', damping: 70, stiffness: 800 }} animate={{ left: currentTimePercent }} style={{ position: 'absolute', bottom: 0, top: 0, zIndex: 3, backgroundColor: 'var(--gray12)', width: currentTimeWidth, pointerEvents: 'none' }} />
|
||||
)}
|
||||
{commandedTimePercent !== undefined && (
|
||||
<CommandedTime commandedTimePercent={commandedTimePercent} />
|
||||
)}
|
||||
|
||||
{apparentCutSegments.map((seg, i) => {
|
||||
if (seg.start === 0 && seg.end === 0) return null; // No video loaded
|
||||
|
||||
|
@ -325,10 +318,17 @@ const Timeline = memo(({
|
|||
{shouldShowKeyframes && !areKeyframesTooClose && neighbouringKeyFrames.map((f) => (
|
||||
<div key={f.time} style={{ position: 'absolute', top: 0, bottom: 0, left: `${(f.time / durationSafe) * 100}%`, marginLeft: -1, width: 1, background: 'var(--gray11)', pointerEvents: 'none' }} />
|
||||
))}
|
||||
|
||||
{currentTimePercent !== undefined && (
|
||||
<motion.div transition={{ type: 'spring', damping: 70, stiffness: 800 }} animate={{ left: currentTimePercent }} style={{ position: 'absolute', bottom: 0, top: 0, backgroundColor: 'var(--gray12)', width: currentTimeWidth, pointerEvents: 'none' }} />
|
||||
)}
|
||||
{commandedTimePercent !== undefined && (
|
||||
<CommandedTime commandedTimePercent={commandedTimePercent} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ position: 'absolute', height: timelineHeight, left: 0, right: 0, bottom: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', pointerEvents: 'none', zIndex: 2 }}>
|
||||
<div style={{ position: 'absolute', height: timelineHeight, left: 0, right: 0, bottom: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', pointerEvents: 'none' }}>
|
||||
<div style={{ background: 'rgba(0,0,0,0.4)', borderRadius: 3, padding: '2px 4px', color: 'rgba(255, 255, 255, 0.8)' }}>
|
||||
{formatTimeAndFrames(displayTime)}{isZoomed ? ` ${displayTimePercent}` : ''}
|
||||
</div>
|
||||
|
|
|
@ -356,29 +356,44 @@ const ExportConfirm = memo(({
|
|||
</>
|
||||
)}
|
||||
|
||||
{!needSmartCut && (
|
||||
<tr>
|
||||
<td>
|
||||
"avoid_negative_ts"
|
||||
{!['make_zero', 'auto'].includes(avoidNegativeTs) && <div style={warningStyle}>{t('It\'s generally recommended to set this to one of: {{values}}', { values: '"auto", "make_zero"' })}</div>}
|
||||
</td>
|
||||
<td>
|
||||
<Select value={avoidNegativeTs} onChange={(e) => setAvoidNegativeTs(e.target.value)} style={{ height: 20, marginLeft: 5 }}>
|
||||
<option value="auto">auto</option>
|
||||
<option value="make_zero">make_zero</option>
|
||||
<option value="make_non_negative">make_non_negative</option>
|
||||
<option value="disabled">disabled</option>
|
||||
</Select>
|
||||
</td>
|
||||
<td>
|
||||
{!['make_zero', 'auto'].includes(avoidNegativeTs) ? (
|
||||
<WarningSignIcon verticalAlign="middle" color="warning" />
|
||||
) : (
|
||||
<HelpIcon onClick={onAvoidNegativeTsHelpPress} />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!needSmartCut && (() => {
|
||||
const avoidNegativeTsWarn = (() => {
|
||||
if (willMerge) {
|
||||
if (avoidNegativeTs !== 'make_non_negative') {
|
||||
return t('When merging, it\'s generally recommended to set this to "make_non_negative"');
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
if (!['make_zero', 'auto'].includes(avoidNegativeTs)) {
|
||||
return t('It\'s generally recommended to set this to one of: {{values}}', { values: '"auto", "make_zero"' });
|
||||
}
|
||||
return undefined;
|
||||
})();
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
{`"${'avoid_negative_ts'}"`}
|
||||
{avoidNegativeTsWarn != null && <div style={warningStyle}>{avoidNegativeTsWarn}</div>}
|
||||
</td>
|
||||
<td>
|
||||
<Select value={avoidNegativeTs} onChange={(e) => setAvoidNegativeTs(e.target.value)} style={{ height: 20, marginLeft: 5 }}>
|
||||
<option value="auto">auto</option>
|
||||
<option value="make_zero">make_zero</option>
|
||||
<option value="make_non_negative">make_non_negative</option>
|
||||
<option value="disabled">disabled</option>
|
||||
</Select>
|
||||
</td>
|
||||
<td>
|
||||
{avoidNegativeTsWarn != null ? (
|
||||
<WarningSignIcon verticalAlign="middle" color="warning" />
|
||||
) : (
|
||||
<HelpIcon onClick={onAvoidNegativeTsHelpPress} />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})()}
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
@ -397,7 +412,7 @@ const ExportConfirm = memo(({
|
|||
</div>
|
||||
</motion.div>
|
||||
|
||||
<div style={{ zIndex: 11, position: 'fixed', right: 0, bottom: 0, display: 'flex', alignItems: 'center', margin: 5 }}>
|
||||
<div style={{ position: 'fixed', right: 0, bottom: 0, display: 'flex', alignItems: 'center', margin: 5 }}>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, translateX: 50 }}
|
||||
animate={{ opacity: 1, translateX: 0 }}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
background: var(--whiteA11);
|
||||
color: var(--gray12);
|
||||
backdrop-filter: blur(30px);
|
||||
|
|
|
@ -7,9 +7,11 @@ import groupBy from 'lodash/groupBy';
|
|||
import orderBy from 'lodash/orderBy';
|
||||
import uniq from 'lodash/uniq';
|
||||
|
||||
import useUserSettings from '../hooks/useUserSettings';
|
||||
import Swal from '../swal';
|
||||
import SetCutpointButton from './SetCutpointButton';
|
||||
import SegmentCutpointButton from './SegmentCutpointButton';
|
||||
import { getModifier } from '../hooks/useTimelineScroll';
|
||||
|
||||
|
||||
const renderKeys = (keys) => keys.map((key, i) => (
|
||||
|
@ -105,13 +107,15 @@ const CreateBinding = memo(({
|
|||
);
|
||||
});
|
||||
|
||||
const rowStyle = { display: 'flex', alignItems: 'center', margin: '6px 0' };
|
||||
const rowStyle = { display: 'flex', alignItems: 'center', margin: '.2em 0', borderBottom: '1px solid rgba(0,0,0,0.1)', paddingBottom: '.5em' };
|
||||
|
||||
const KeyboardShortcuts = memo(({
|
||||
keyBindings, setKeyBindings, resetKeyBindings, currentCutSeg, mainActions,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { mouseWheelZoomModifierKey } = useUserSettings();
|
||||
|
||||
const { actionsMap, extraLinesPerCategory } = useMemo(() => {
|
||||
const playbackCategory = t('Playback');
|
||||
const selectivePlaybackCategory = t('Playback/preview segments only');
|
||||
|
@ -136,8 +140,9 @@ const KeyboardShortcuts = memo(({
|
|||
<div key="2" style={{ ...rowStyle, alignItems: 'center' }}>
|
||||
<Text>{t('Pan timeline')}</Text>
|
||||
<div style={{ flexGrow: 1 }} />
|
||||
{getModifier(mouseWheelZoomModifierKey).map((v) => <kbd key={v} style={{ marginRight: '.7em' }}>{v}</kbd>)}
|
||||
<FaMouse style={{ marginRight: 3 }} />
|
||||
<Text>{t('Mouse scroll/wheel left/right')}</Text>
|
||||
<Text>{t('Mouse scroll/wheel up/down')}</Text>
|
||||
</div>,
|
||||
],
|
||||
},
|
||||
|
@ -649,7 +654,7 @@ const KeyboardShortcuts = memo(({
|
|||
|
||||
return (
|
||||
<>
|
||||
<div style={{ color: 'black' }}>
|
||||
<div style={{ color: 'black', marginBottom: '1em' }}>
|
||||
<div>
|
||||
<SearchInput value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} placeholder="Search" width="100%" />
|
||||
</div>
|
||||
|
@ -691,7 +696,7 @@ const KeyboardShortcuts = memo(({
|
|||
);
|
||||
})}
|
||||
|
||||
{extraLinesPerCategory[category]}
|
||||
{extraLinesPerCategory[category] && <div style={{ marginTop: '.8em' }}>{extraLinesPerCategory[category]}</div>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -23,13 +23,13 @@ const formatVariable = (variable) => `\${${variable}}`;
|
|||
|
||||
const extVar = formatVariable('EXT');
|
||||
|
||||
const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generateOutSegFileNames, currentSegIndexSafe, getOutSegError }) => {
|
||||
const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generateOutSegFileNames, currentSegIndexSafe }) => {
|
||||
const { safeOutputFileName, toggleSafeOutputFileName, outputFileNameMinZeroPadding, setOutputFileNameMinZeroPadding } = useUserSettings();
|
||||
|
||||
const [text, setText] = useState(outSegTemplate);
|
||||
const [debouncedText] = useDebounce(text, 500);
|
||||
const [validText, setValidText] = useState();
|
||||
const [error, setError] = useState();
|
||||
const [outSegProblems, setOutSegProblems] = useState({ error: undefined, sameAsInputFileNameWarning: false });
|
||||
const [outSegFileNames, setOutSegFileNames] = useState();
|
||||
const [shown, setShown] = useState();
|
||||
const inputRef = useRef();
|
||||
|
@ -42,22 +42,16 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate
|
|||
if (debouncedText == null) return;
|
||||
|
||||
try {
|
||||
const { outSegFileNames: newOutSegFileNames, outSegError } = generateOutSegFileNames({ template: debouncedText });
|
||||
setOutSegFileNames(newOutSegFileNames);
|
||||
if (outSegError) {
|
||||
setError(outSegError);
|
||||
setValidText();
|
||||
return;
|
||||
}
|
||||
|
||||
setValidText(debouncedText);
|
||||
setError();
|
||||
const outSegs = generateOutSegFileNames({ template: debouncedText });
|
||||
setOutSegFileNames(outSegs.outSegFileNames);
|
||||
setOutSegProblems(outSegs.outSegProblems);
|
||||
setValidText(outSegs.outSegProblems.error == null ? debouncedText : undefined);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setValidText();
|
||||
setError(err.message);
|
||||
setOutSegProblems({ error: err.message });
|
||||
}
|
||||
}, [debouncedText, generateOutSegFileNames, getOutSegError, t]);
|
||||
}, [debouncedText, generateOutSegFileNames, t]);
|
||||
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
const isMissingExtension = validText != null && !validText.endsWith(extVar);
|
||||
|
@ -80,8 +74,8 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate
|
|||
}, [setOutSegTemplate]);
|
||||
|
||||
const onHideClick = useCallback(() => {
|
||||
if (error == null) setShown(false);
|
||||
}, [error]);
|
||||
if (outSegProblems.error == null) setShown(false);
|
||||
}, [outSegProblems.error]);
|
||||
|
||||
const onShowClick = useCallback(() => {
|
||||
if (!shown) setShown(true);
|
||||
|
@ -89,7 +83,7 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate
|
|||
|
||||
const onTextChange = useCallback((e) => setText(e.target.value), []);
|
||||
|
||||
const needToShow = shown || error != null;
|
||||
const needToShow = shown || outSegProblems.error != null || outSegProblems.sameAsInputFileNameWarning;
|
||||
|
||||
const onVariableClick = useCallback((variable) => {
|
||||
const input = inputRef.current;
|
||||
|
@ -132,7 +126,18 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate
|
|||
))}
|
||||
</div>
|
||||
|
||||
{error != null && <div style={{ marginBottom: '1em' }}><ErrorIcon color="var(--red9)" size={14} verticalAlign="baseline" /> {error}</div>}
|
||||
{outSegProblems.error != null && (
|
||||
<div style={{ marginBottom: '1em' }}>
|
||||
<ErrorIcon color="var(--red9)" size={14} verticalAlign="baseline" /> {outSegProblems.error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{outSegProblems.error == null && outSegProblems.sameAsInputFileNameWarning && (
|
||||
<div style={{ marginBottom: '1em' }}>
|
||||
<WarningSignIcon verticalAlign="middle" color="var(--amber9)" />{' '}
|
||||
{i18n.t('Output file name is the same as the source file name. This increases the risk of accidentally overwriting or deleting source files!')}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isMissingExtension && (
|
||||
<div style={{ marginBottom: '1em' }}>
|
||||
|
|
|
@ -78,11 +78,11 @@ const Settings = memo(({
|
|||
|
||||
return (
|
||||
<>
|
||||
<div style={{ margin: '0 2em' }}>
|
||||
<div style={{ padding: '1.5em 2em' }}>
|
||||
<div>{t('Hover mouse over buttons in the main interface to see which function they have')}</div>
|
||||
</div>
|
||||
|
||||
<table style={{ marginTop: 20 }} className={styles.settings}>
|
||||
<table className={styles.settings}>
|
||||
<thead>
|
||||
<tr className={styles.header}>
|
||||
<th>{t('Settings')}</th>
|
||||
|
@ -321,8 +321,8 @@ const Settings = memo(({
|
|||
<KeyCell>{t('Mouse wheel zoom modifier key')}</KeyCell>
|
||||
<td>
|
||||
<Select value={mouseWheelZoomModifierKey} onChange={(e) => setMouseWheelZoomModifierKey(e.target.value)}>
|
||||
{Object.entries(getModifierKeyNames()).map(([key, value]) => (
|
||||
<option key={key} value={key}>{value}</option>
|
||||
{Object.entries(getModifierKeyNames()).map(([key, values]) => (
|
||||
<option key={key} value={key}>{values.join(' / ')}</option>
|
||||
))}
|
||||
</Select>
|
||||
</td>
|
||||
|
|
|
@ -1,27 +1,33 @@
|
|||
import React, { memo } from 'react';
|
||||
import { IoIosCloseCircleOutline } from 'react-icons/io';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import styles from './Sheet.module.css';
|
||||
|
||||
const Sheet = memo(({ visible, onClosePress, style, children }) => (
|
||||
<AnimatePresence>
|
||||
{visible && (
|
||||
<motion.div
|
||||
initial={{ scale: 0, opacity: 0.5 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
exit={{ scale: 0, opacity: 0 }}
|
||||
style={style}
|
||||
className={styles.sheet}
|
||||
>
|
||||
<IoIosCloseCircleOutline role="button" onClick={onClosePress} size={30} style={{ position: 'fixed', right: 0, top: 0, padding: 20, zIndex: 1, cursor: 'pointer' }} />
|
||||
const Sheet = memo(({ visible, onClosePress, children, maxWidth = 800, style }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
<div style={{ overflowY: 'scroll', height: '100%' }}>
|
||||
{children}
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
));
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{visible && (
|
||||
<motion.div
|
||||
initial={{ scale: 0, opacity: 0.5 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
exit={{ scale: 0, opacity: 0 }}
|
||||
className={styles.sheet}
|
||||
>
|
||||
<div style={{ margin: 'auto', maxWidth, height: '100%', position: 'relative' }}>
|
||||
<div style={{ overflowY: 'scroll', height: '100%', ...style }}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
<IoIosCloseCircleOutline role="button" onClick={onClosePress} title={t('Close')} size={30} style={{ position: 'absolute', padding: '1em', right: 0, top: 0, cursor: 'pointer' }} />
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
});
|
||||
|
||||
export default Sheet;
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
.sheet {
|
||||
padding: 1em 2em;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
background: var(--whiteA11);
|
||||
color: var(--gray12);
|
||||
backdrop-filter: blur(30px);
|
||||
|
|
|
@ -1,27 +1,49 @@
|
|||
import React, { memo } from 'react';
|
||||
import React, { memo, useState, useCallback } from 'react';
|
||||
import { Button } from 'evergreen-ui';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ValueTuner = memo(({ style, title, value, setValue, onFinished, resolution = 1000, min = 0, max = 1, resetToDefault }) => {
|
||||
import Switch from './Switch';
|
||||
|
||||
|
||||
const ValueTuner = memo(({ style, title, value, setValue, onFinished, resolution = 1000, min: minIn = 0, max: maxIn = 1, resetToDefault }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [min, setMin] = useState(minIn);
|
||||
const [max, setMax] = useState(maxIn);
|
||||
|
||||
function onChange(e) {
|
||||
e.target.blur();
|
||||
setValue(Math.min(Math.max(min, ((e.target.value / resolution) * (max - min)) + min)), max);
|
||||
}
|
||||
|
||||
const isZoomed = !(min === minIn && max === maxIn);
|
||||
|
||||
const toggleZoom = useCallback(() => {
|
||||
if (isZoomed) {
|
||||
setMin(minIn);
|
||||
setMax(maxIn);
|
||||
} else {
|
||||
const zoomWindow = (maxIn - minIn) / 100;
|
||||
setMin(Math.max(minIn, value - zoomWindow));
|
||||
setMax(Math.min(maxIn, value + zoomWindow));
|
||||
}
|
||||
}, [isZoomed, maxIn, minIn, value]);
|
||||
|
||||
return (
|
||||
<div style={{ background: 'var(--gray1)', color: 'var(--gray12)', position: 'absolute', bottom: 0, zIndex: 10, padding: 10, margin: 10, borderRadius: 10, ...style }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', flexBasis: 400 }}>
|
||||
<div style={{ marginBottom: '.5em' }}>{title}</div>
|
||||
<div style={{ marginLeft: 10, fontWeight: 'bold' }}>{value.toFixed(2)}</div>
|
||||
<div style={{ flexGrow: 1, flexBasis: 10 }} />
|
||||
<Button height={20} onClick={resetToDefault}>{t('Default')}</Button>
|
||||
<Button height={20} intent="success" onClick={onFinished}>{t('Done')}</Button>
|
||||
<div style={{ background: 'var(--gray1)', color: 'var(--gray12)', position: 'absolute', bottom: 0, padding: 10, margin: 10, borderRadius: 10, ...style }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', flexBasis: 400, marginBottom: '.2em' }}>
|
||||
<div>{title}</div>
|
||||
<div style={{ marginLeft: '.5em', fontWeight: 'bold', marginRight: '.5em', textDecoration: 'underline' }}>{value.toFixed(4)}</div>
|
||||
<Switch checked={isZoomed} onCheckedChange={toggleZoom} style={{ flexShrink: 0 }} /><span style={{ marginLeft: '.3em' }}>{t('Precise')}</span>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex' }}>
|
||||
<input style={{ flexGrow: 1 }} type="range" min="0" max="1000" step="1" value={((value - min) / (max - min)) * resolution} onChange={onChange} />
|
||||
<div style={{ marginBottom: '.3em' }}>
|
||||
<input style={{ width: '100%' }} type="range" min="0" max="1000" step="1" value={((value - min) / (max - min)) * resolution} onChange={onChange} />
|
||||
</div>
|
||||
|
||||
<div style={{ textAlign: 'right' }}>
|
||||
<Button height={20} onClick={resetToDefault}>{t('Default')}</Button>
|
||||
<Button height={20} intent="success" onClick={onFinished}>{t('Done')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -14,6 +14,8 @@ const ValueTuners = memo(({ type, onFinished }) => {
|
|||
title: t('Timeline trackpad/wheel sensitivity'),
|
||||
value: wheelSensitivity,
|
||||
setValue: setWheelSensitivity,
|
||||
min: 0,
|
||||
max: 4,
|
||||
default: 0.2,
|
||||
},
|
||||
keyboardNormalSeekSpeed: {
|
||||
|
|
|
@ -9,7 +9,7 @@ import loadingLottie from '../7077-magic-flow.json';
|
|||
|
||||
|
||||
const Working = memo(({ text, cutProgress, onAbortClick }) => (
|
||||
<div style={{ position: 'absolute', zIndex: 1, bottom: 0, top: 0, left: 0, right: 0, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||
<div style={{ position: 'absolute', bottom: 0, top: 0, left: 0, right: 0, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||
<motion.div
|
||||
style={{ background: primaryColor, boxShadow: `${primaryColor} 0px 0px 20px 25px`, borderRadius: 60, paddingBottom: 5, color: 'white', fontSize: 14, display: 'flex', flexDirection: 'column', alignItems: 'center' }}
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
|
|
|
@ -11,12 +11,14 @@ export const keyMap = {
|
|||
};
|
||||
|
||||
export const getModifierKeyNames = () => ({
|
||||
ctrl: t('Ctrl'),
|
||||
shift: t('Shift'),
|
||||
alt: t('Alt'),
|
||||
meta: t('⌘ Cmd / ⊞ Win'),
|
||||
ctrl: [t('Ctrl')],
|
||||
shift: [t('Shift')],
|
||||
alt: [t('Alt')],
|
||||
meta: [t('⌘ Cmd'), t('⊞ Win')],
|
||||
});
|
||||
|
||||
export const getModifier = (key) => getModifierKeyNames()[key];
|
||||
|
||||
function useTimelineScroll({ wheelSensitivity, mouseWheelZoomModifierKey, invertTimelineScroll, zoomRel, seekRel }) {
|
||||
const onWheel = useCallback((e) => {
|
||||
const { pixelX, pixelY } = normalizeWheel(e);
|
||||
|
|
20
src/util.js
20
src/util.js
|
@ -11,7 +11,7 @@ import { ffmpegExtractWindow } from './util/constants';
|
|||
|
||||
const { dirname, parse: parsePath, join, extname, isAbsolute, resolve, basename } = window.require('path');
|
||||
const fsExtra = window.require('fs-extra');
|
||||
const { stat, readdir, utimes, unlink } = window.require('fs/promises');
|
||||
const { stat, lstat, readdir, utimes, unlink } = window.require('fs/promises');
|
||||
const os = window.require('os');
|
||||
const { ipcRenderer } = window.require('electron');
|
||||
const remote = window.require('@electron/remote');
|
||||
|
@ -90,7 +90,7 @@ export async function getPathReadAccessError(pathIn) {
|
|||
}
|
||||
|
||||
export async function dirExists(dirPath) {
|
||||
return (await pathExists(dirPath)) && (await fsExtra.lstat(dirPath)).isDirectory();
|
||||
return (await pathExists(dirPath)) && (await lstat(dirPath)).isDirectory();
|
||||
}
|
||||
|
||||
// const testFailFsOperation = isDev;
|
||||
|
@ -402,6 +402,22 @@ export async function readVideoTs(videoTsPath) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
export async function readDirRecursively(dirPath) {
|
||||
const files = await readdir(dirPath, { recursive: true });
|
||||
const ret = (await pMap(files, async (path) => {
|
||||
if (['.DS_Store'].includes(basename(path))) return [];
|
||||
|
||||
const absPath = join(dirPath, path);
|
||||
const fileStat = await lstat(absPath); // readdir also returns directories...
|
||||
if (!fileStat.isFile()) return [];
|
||||
|
||||
return [absPath];
|
||||
}, { concurrency: 5 })).flat();
|
||||
|
||||
if (ret.length === 0) throw new Error('No files found in folder');
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function getImportProjectType(filePath) {
|
||||
if (filePath.endsWith('Summary.txt')) return 'dv-analyzer-summary-txt';
|
||||
const edlFormatForExtension = { csv: 'csv', pbf: 'pbf', edl: 'mplayer', cue: 'cue', xml: 'xmeml', fcpxml: 'fcpxml' };
|
||||
|
|
|
@ -9,10 +9,11 @@ import { getSegmentTags, formatSegNum } from '../segments';
|
|||
export const segNumVariable = 'SEG_NUM';
|
||||
export const segSuffixVariable = 'SEG_SUFFIX';
|
||||
|
||||
const { parse: parsePath, sep: pathSep, join: pathJoin, normalize: pathNormalize } = window.require('path');
|
||||
const { parse: parsePath, sep: pathSep, join: pathJoin, normalize: pathNormalize, basename } = window.require('path');
|
||||
|
||||
function getOutSegError({ fileNames, filePath, outputDir, safeOutputFileName }) {
|
||||
function getOutSegProblems({ fileNames, filePath, outputDir, safeOutputFileName }) {
|
||||
let error;
|
||||
let sameAsInputFileNameWarning = false;
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fileName of fileNames) {
|
||||
|
@ -49,6 +50,10 @@ function getOutSegError({ fileNames, filePath, outputDir, safeOutputFileName })
|
|||
const shouldCheckPathLength = isWindows || isDev;
|
||||
const shouldCheckFileEnd = isWindows || isDev;
|
||||
|
||||
if (basename(filePath) === fileName) {
|
||||
sameAsInputFileNameWarning = true; // just an extra warning in case sameAsInputPath doesn't work
|
||||
}
|
||||
|
||||
if (fileName.length === 0) {
|
||||
error = i18n.t('At least one resulting file name has no length');
|
||||
break;
|
||||
|
@ -73,11 +78,14 @@ function getOutSegError({ fileNames, filePath, outputDir, safeOutputFileName })
|
|||
}
|
||||
}
|
||||
|
||||
if (error != null) return error;
|
||||
if (error == null && hasDuplicates(fileNames)) {
|
||||
error = i18n.t('Output file name template results in duplicate file names (you are trying to export multiple files with the same name). You can fix this for example by adding the "{{segNumVariable}}" variable.', { segNumVariable });
|
||||
}
|
||||
|
||||
if (hasDuplicates(fileNames)) return i18n.t('Output file name template results in duplicate file names (you are trying to export multiple files with the same name). You can fix this for example by adding the "{{segNumVariable}}" variable.', { segNumVariable });
|
||||
|
||||
return undefined;
|
||||
return {
|
||||
error,
|
||||
sameAsInputFileNameWarning,
|
||||
};
|
||||
}
|
||||
|
||||
// This is used as a fallback and so it has to always generate unique file names
|
||||
|
@ -155,10 +163,10 @@ export function generateOutSegFileNames({ segments, template: desiredTemplate, f
|
|||
|
||||
let outSegFileNames = generate({ template: desiredTemplate, forceSafeOutputFileName: false });
|
||||
|
||||
const outSegError = getOutSegError({ fileNames: outSegFileNames, filePath, outputDir, safeOutputFileName });
|
||||
if (outSegError != null) {
|
||||
const outSegProblems = getOutSegProblems({ fileNames: outSegFileNames, filePath, outputDir, safeOutputFileName });
|
||||
if (outSegProblems.error != null) {
|
||||
outSegFileNames = generate({ template: defaultOutSegTemplate, forceSafeOutputFileName: true });
|
||||
}
|
||||
|
||||
return { outSegFileNames, outSegError };
|
||||
return { outSegFileNames, outSegProblems };
|
||||
}
|
||||
|
|
|
@ -8,5 +8,6 @@ export default defineConfig({
|
|||
base: '',
|
||||
build: {
|
||||
chunkSizeWarningLimit: 3e6,
|
||||
sourcemap: true,
|
||||
},
|
||||
});
|
||||
|
|
383
yarn.lock
383
yarn.lock
|
@ -569,16 +569,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-arm64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/android-arm64@npm:0.17.19"
|
||||
"@esbuild/android-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/android-arm64@npm:0.17.8"
|
||||
conditions: os=android & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/android-arm64@npm:0.17.8"
|
||||
"@esbuild/android-arm64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/android-arm64@npm:0.18.20"
|
||||
conditions: os=android & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -590,16 +590,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-arm@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/android-arm@npm:0.17.19"
|
||||
"@esbuild/android-arm@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/android-arm@npm:0.17.8"
|
||||
conditions: os=android & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-arm@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/android-arm@npm:0.17.8"
|
||||
"@esbuild/android-arm@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/android-arm@npm:0.18.20"
|
||||
conditions: os=android & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -611,16 +611,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-x64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/android-x64@npm:0.17.19"
|
||||
"@esbuild/android-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/android-x64@npm:0.17.8"
|
||||
conditions: os=android & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/android-x64@npm:0.17.8"
|
||||
"@esbuild/android-x64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/android-x64@npm:0.18.20"
|
||||
conditions: os=android & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -632,16 +632,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/darwin-arm64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/darwin-arm64@npm:0.17.19"
|
||||
"@esbuild/darwin-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/darwin-arm64@npm:0.17.8"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/darwin-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/darwin-arm64@npm:0.17.8"
|
||||
"@esbuild/darwin-arm64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/darwin-arm64@npm:0.18.20"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -653,16 +653,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/darwin-x64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/darwin-x64@npm:0.17.19"
|
||||
"@esbuild/darwin-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/darwin-x64@npm:0.17.8"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/darwin-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/darwin-x64@npm:0.17.8"
|
||||
"@esbuild/darwin-x64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/darwin-x64@npm:0.18.20"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -674,16 +674,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/freebsd-arm64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/freebsd-arm64@npm:0.17.19"
|
||||
"@esbuild/freebsd-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/freebsd-arm64@npm:0.17.8"
|
||||
conditions: os=freebsd & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/freebsd-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/freebsd-arm64@npm:0.17.8"
|
||||
"@esbuild/freebsd-arm64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/freebsd-arm64@npm:0.18.20"
|
||||
conditions: os=freebsd & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -695,16 +695,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/freebsd-x64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/freebsd-x64@npm:0.17.19"
|
||||
"@esbuild/freebsd-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/freebsd-x64@npm:0.17.8"
|
||||
conditions: os=freebsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/freebsd-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/freebsd-x64@npm:0.17.8"
|
||||
"@esbuild/freebsd-x64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/freebsd-x64@npm:0.18.20"
|
||||
conditions: os=freebsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -716,16 +716,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-arm64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-arm64@npm:0.17.19"
|
||||
"@esbuild/linux-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-arm64@npm:0.17.8"
|
||||
conditions: os=linux & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-arm64@npm:0.17.8"
|
||||
"@esbuild/linux-arm64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-arm64@npm:0.18.20"
|
||||
conditions: os=linux & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -737,16 +737,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-arm@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-arm@npm:0.17.19"
|
||||
"@esbuild/linux-arm@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-arm@npm:0.17.8"
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-arm@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-arm@npm:0.17.8"
|
||||
"@esbuild/linux-arm@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-arm@npm:0.18.20"
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -758,16 +758,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-ia32@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-ia32@npm:0.17.19"
|
||||
"@esbuild/linux-ia32@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-ia32@npm:0.17.8"
|
||||
conditions: os=linux & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-ia32@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-ia32@npm:0.17.8"
|
||||
"@esbuild/linux-ia32@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-ia32@npm:0.18.20"
|
||||
conditions: os=linux & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -779,16 +779,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-loong64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-loong64@npm:0.17.19"
|
||||
"@esbuild/linux-loong64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-loong64@npm:0.17.8"
|
||||
conditions: os=linux & cpu=loong64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-loong64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-loong64@npm:0.17.8"
|
||||
"@esbuild/linux-loong64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-loong64@npm:0.18.20"
|
||||
conditions: os=linux & cpu=loong64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -800,16 +800,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-mips64el@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-mips64el@npm:0.17.19"
|
||||
"@esbuild/linux-mips64el@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-mips64el@npm:0.17.8"
|
||||
conditions: os=linux & cpu=mips64el
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-mips64el@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-mips64el@npm:0.17.8"
|
||||
"@esbuild/linux-mips64el@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-mips64el@npm:0.18.20"
|
||||
conditions: os=linux & cpu=mips64el
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -821,16 +821,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-ppc64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-ppc64@npm:0.17.19"
|
||||
"@esbuild/linux-ppc64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-ppc64@npm:0.17.8"
|
||||
conditions: os=linux & cpu=ppc64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-ppc64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-ppc64@npm:0.17.8"
|
||||
"@esbuild/linux-ppc64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-ppc64@npm:0.18.20"
|
||||
conditions: os=linux & cpu=ppc64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -842,16 +842,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-riscv64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-riscv64@npm:0.17.19"
|
||||
"@esbuild/linux-riscv64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-riscv64@npm:0.17.8"
|
||||
conditions: os=linux & cpu=riscv64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-riscv64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-riscv64@npm:0.17.8"
|
||||
"@esbuild/linux-riscv64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-riscv64@npm:0.18.20"
|
||||
conditions: os=linux & cpu=riscv64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -863,16 +863,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-s390x@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-s390x@npm:0.17.19"
|
||||
"@esbuild/linux-s390x@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-s390x@npm:0.17.8"
|
||||
conditions: os=linux & cpu=s390x
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-s390x@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-s390x@npm:0.17.8"
|
||||
"@esbuild/linux-s390x@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-s390x@npm:0.18.20"
|
||||
conditions: os=linux & cpu=s390x
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -884,16 +884,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-x64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/linux-x64@npm:0.17.19"
|
||||
"@esbuild/linux-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-x64@npm:0.17.8"
|
||||
conditions: os=linux & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/linux-x64@npm:0.17.8"
|
||||
"@esbuild/linux-x64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/linux-x64@npm:0.18.20"
|
||||
conditions: os=linux & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -905,16 +905,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/netbsd-x64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/netbsd-x64@npm:0.17.19"
|
||||
"@esbuild/netbsd-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/netbsd-x64@npm:0.17.8"
|
||||
conditions: os=netbsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/netbsd-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/netbsd-x64@npm:0.17.8"
|
||||
"@esbuild/netbsd-x64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/netbsd-x64@npm:0.18.20"
|
||||
conditions: os=netbsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -926,16 +926,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/openbsd-x64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/openbsd-x64@npm:0.17.19"
|
||||
"@esbuild/openbsd-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/openbsd-x64@npm:0.17.8"
|
||||
conditions: os=openbsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/openbsd-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/openbsd-x64@npm:0.17.8"
|
||||
"@esbuild/openbsd-x64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/openbsd-x64@npm:0.18.20"
|
||||
conditions: os=openbsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -947,16 +947,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/sunos-x64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/sunos-x64@npm:0.17.19"
|
||||
"@esbuild/sunos-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/sunos-x64@npm:0.17.8"
|
||||
conditions: os=sunos & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/sunos-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/sunos-x64@npm:0.17.8"
|
||||
"@esbuild/sunos-x64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/sunos-x64@npm:0.18.20"
|
||||
conditions: os=sunos & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -968,16 +968,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-arm64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/win32-arm64@npm:0.17.19"
|
||||
"@esbuild/win32-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/win32-arm64@npm:0.17.8"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-arm64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/win32-arm64@npm:0.17.8"
|
||||
"@esbuild/win32-arm64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/win32-arm64@npm:0.18.20"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -989,16 +989,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-ia32@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/win32-ia32@npm:0.17.19"
|
||||
"@esbuild/win32-ia32@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/win32-ia32@npm:0.17.8"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-ia32@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/win32-ia32@npm:0.17.8"
|
||||
"@esbuild/win32-ia32@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/win32-ia32@npm:0.18.20"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -1010,16 +1010,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-x64@npm:0.17.19":
|
||||
version: 0.17.19
|
||||
resolution: "@esbuild/win32-x64@npm:0.17.19"
|
||||
"@esbuild/win32-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/win32-x64@npm:0.17.8"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-x64@npm:0.17.8":
|
||||
version: 0.17.8
|
||||
resolution: "@esbuild/win32-x64@npm:0.17.8"
|
||||
"@esbuild/win32-x64@npm:0.18.20":
|
||||
version: 0.18.20
|
||||
resolution: "@esbuild/win32-x64@npm:0.18.20"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
@ -4232,32 +4232,32 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"esbuild@npm:^0.17.5":
|
||||
version: 0.17.19
|
||||
resolution: "esbuild@npm:0.17.19"
|
||||
"esbuild@npm:^0.18.10":
|
||||
version: 0.18.20
|
||||
resolution: "esbuild@npm:0.18.20"
|
||||
dependencies:
|
||||
"@esbuild/android-arm": "npm:0.17.19"
|
||||
"@esbuild/android-arm64": "npm:0.17.19"
|
||||
"@esbuild/android-x64": "npm:0.17.19"
|
||||
"@esbuild/darwin-arm64": "npm:0.17.19"
|
||||
"@esbuild/darwin-x64": "npm:0.17.19"
|
||||
"@esbuild/freebsd-arm64": "npm:0.17.19"
|
||||
"@esbuild/freebsd-x64": "npm:0.17.19"
|
||||
"@esbuild/linux-arm": "npm:0.17.19"
|
||||
"@esbuild/linux-arm64": "npm:0.17.19"
|
||||
"@esbuild/linux-ia32": "npm:0.17.19"
|
||||
"@esbuild/linux-loong64": "npm:0.17.19"
|
||||
"@esbuild/linux-mips64el": "npm:0.17.19"
|
||||
"@esbuild/linux-ppc64": "npm:0.17.19"
|
||||
"@esbuild/linux-riscv64": "npm:0.17.19"
|
||||
"@esbuild/linux-s390x": "npm:0.17.19"
|
||||
"@esbuild/linux-x64": "npm:0.17.19"
|
||||
"@esbuild/netbsd-x64": "npm:0.17.19"
|
||||
"@esbuild/openbsd-x64": "npm:0.17.19"
|
||||
"@esbuild/sunos-x64": "npm:0.17.19"
|
||||
"@esbuild/win32-arm64": "npm:0.17.19"
|
||||
"@esbuild/win32-ia32": "npm:0.17.19"
|
||||
"@esbuild/win32-x64": "npm:0.17.19"
|
||||
"@esbuild/android-arm": "npm:0.18.20"
|
||||
"@esbuild/android-arm64": "npm:0.18.20"
|
||||
"@esbuild/android-x64": "npm:0.18.20"
|
||||
"@esbuild/darwin-arm64": "npm:0.18.20"
|
||||
"@esbuild/darwin-x64": "npm:0.18.20"
|
||||
"@esbuild/freebsd-arm64": "npm:0.18.20"
|
||||
"@esbuild/freebsd-x64": "npm:0.18.20"
|
||||
"@esbuild/linux-arm": "npm:0.18.20"
|
||||
"@esbuild/linux-arm64": "npm:0.18.20"
|
||||
"@esbuild/linux-ia32": "npm:0.18.20"
|
||||
"@esbuild/linux-loong64": "npm:0.18.20"
|
||||
"@esbuild/linux-mips64el": "npm:0.18.20"
|
||||
"@esbuild/linux-ppc64": "npm:0.18.20"
|
||||
"@esbuild/linux-riscv64": "npm:0.18.20"
|
||||
"@esbuild/linux-s390x": "npm:0.18.20"
|
||||
"@esbuild/linux-x64": "npm:0.18.20"
|
||||
"@esbuild/netbsd-x64": "npm:0.18.20"
|
||||
"@esbuild/openbsd-x64": "npm:0.18.20"
|
||||
"@esbuild/sunos-x64": "npm:0.18.20"
|
||||
"@esbuild/win32-arm64": "npm:0.18.20"
|
||||
"@esbuild/win32-ia32": "npm:0.18.20"
|
||||
"@esbuild/win32-x64": "npm:0.18.20"
|
||||
dependenciesMeta:
|
||||
"@esbuild/android-arm":
|
||||
optional: true
|
||||
|
@ -4305,7 +4305,7 @@ __metadata:
|
|||
optional: true
|
||||
bin:
|
||||
esbuild: bin/esbuild
|
||||
checksum: 86ada7cad6d37a3445858fee31ca39fc6c0436c7c00b2e07b9ce308235be67f36aefe0dda25da9ab08653fde496d1e759d6ad891ce9479f9e1fb4964c8f2a0fa
|
||||
checksum: 1f723ec71c3aa196473bf3298316eedc3f62d523924652dfeb60701b609792f918fc60db84b420d1d8ba9bfa7d69de2fc1d3157ba47c028bdae5d507a26a3c64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -5010,23 +5010,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"follow-redirects@npm:^1.14.0":
|
||||
version: 1.14.8
|
||||
resolution: "follow-redirects@npm:1.14.8"
|
||||
"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.14.9":
|
||||
version: 1.15.4
|
||||
resolution: "follow-redirects@npm:1.15.4"
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
checksum: 94b8cca8123c719273788174728fea5789267ab077784eae095e41fba0b5944b9fabda6b98164d15f0166914489b4d3896e3e181dd2d67b9f1b3969eb14f7c0f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"follow-redirects@npm:^1.14.9":
|
||||
version: 1.15.2
|
||||
resolution: "follow-redirects@npm:1.15.2"
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
checksum: 8be0d39919770054812537d376850ccde0b4762b0501c440bd08724971a078123b55f57704f2984e0664fecc0c86adea85add63295804d9dce401cd9604c91d3
|
||||
checksum: 2e8f5f259a6b02dfa8dc199e08431848a7c3beed32eb4c19945966164a52c89f07b86c3afcc32ebe4279cf0a960520e45a63013d6350309c5ec90133c5d9351a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -6885,7 +6875,7 @@ __metadata:
|
|||
use-debounce: "npm:^5.1.0"
|
||||
use-trace-update: "npm:^1.3.0"
|
||||
uuid: "npm:^8.3.2"
|
||||
vite: "npm:^4.1.5"
|
||||
vite: "npm:^4.5.2"
|
||||
vitest: "npm:^0.28.5"
|
||||
wait-on: "npm:^7.0.1"
|
||||
winston: "npm:^3.8.1"
|
||||
|
@ -7400,6 +7390,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nanoid@npm:^3.3.7":
|
||||
version: 3.3.7
|
||||
resolution: "nanoid@npm:3.3.7"
|
||||
bin:
|
||||
nanoid: bin/nanoid.cjs
|
||||
checksum: ac1eb60f615b272bccb0e2b9cd933720dad30bf9708424f691b8113826bb91aca7e9d14ef5d9415a6ba15c266b37817256f58d8ce980c82b0ba3185352565679
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"napi-build-utils@npm:^1.0.1":
|
||||
version: 1.0.2
|
||||
resolution: "napi-build-utils@npm:1.0.2"
|
||||
|
@ -8059,7 +8058,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"postcss@npm:^8.4.21, postcss@npm:^8.4.23":
|
||||
"postcss@npm:^8.4.21":
|
||||
version: 8.4.31
|
||||
resolution: "postcss@npm:8.4.31"
|
||||
dependencies:
|
||||
|
@ -8070,6 +8069,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"postcss@npm:^8.4.27":
|
||||
version: 8.4.33
|
||||
resolution: "postcss@npm:8.4.33"
|
||||
dependencies:
|
||||
nanoid: "npm:^3.3.7"
|
||||
picocolors: "npm:^1.0.0"
|
||||
source-map-js: "npm:^1.0.2"
|
||||
checksum: e22a4594c255f26117f38419fb494d7ecab0f596cd409f7aadc8a6173abf180ed7ea970cd13fd366ab12b5840be901d2a09b25197700c2ebcb5a8077326bf519
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prebuild-install@npm:^7.0.0":
|
||||
version: 7.1.0
|
||||
resolution: "prebuild-install@npm:7.1.0"
|
||||
|
@ -8841,9 +8851,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rollup@npm:^3.21.0":
|
||||
version: 3.23.1
|
||||
resolution: "rollup@npm:3.23.1"
|
||||
"rollup@npm:^3.27.1":
|
||||
version: 3.29.4
|
||||
resolution: "rollup@npm:3.29.4"
|
||||
dependencies:
|
||||
fsevents: "npm:~2.3.2"
|
||||
dependenciesMeta:
|
||||
|
@ -8851,7 +8861,7 @@ __metadata:
|
|||
optional: true
|
||||
bin:
|
||||
rollup: dist/bin/rollup
|
||||
checksum: 242fb599cfdf0ddb76279ddfd543243b86ce6b71652031ac52e4b6c3141e437384b12cb2c82dc69185133da2defab10c5980d3d147e4e154977455404b11d17a
|
||||
checksum: 9e39d54e23731a4c4067e9c02910cdf7479a0f9a7584796e2dc6efaa34bb1e5e015c062c87d1e64d96038baca76cefd47681ff22604fae5827147f54123dc6d0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -10536,17 +10546,18 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite@npm:^4.1.5":
|
||||
version: 4.3.9
|
||||
resolution: "vite@npm:4.3.9"
|
||||
"vite@npm:^4.5.2":
|
||||
version: 4.5.2
|
||||
resolution: "vite@npm:4.5.2"
|
||||
dependencies:
|
||||
esbuild: "npm:^0.17.5"
|
||||
esbuild: "npm:^0.18.10"
|
||||
fsevents: "npm:~2.3.2"
|
||||
postcss: "npm:^8.4.23"
|
||||
rollup: "npm:^3.21.0"
|
||||
postcss: "npm:^8.4.27"
|
||||
rollup: "npm:^3.27.1"
|
||||
peerDependencies:
|
||||
"@types/node": ">= 14"
|
||||
less: "*"
|
||||
lightningcss: ^1.21.0
|
||||
sass: "*"
|
||||
stylus: "*"
|
||||
sugarss: "*"
|
||||
|
@ -10559,6 +10570,8 @@ __metadata:
|
|||
optional: true
|
||||
less:
|
||||
optional: true
|
||||
lightningcss:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
stylus:
|
||||
|
@ -10569,7 +10582,7 @@ __metadata:
|
|||
optional: true
|
||||
bin:
|
||||
vite: bin/vite.js
|
||||
checksum: c2f0b392a253318a1d3ffc6873885d4a03c6bda6f717682bd0c82b7a431a67fb1ba08de6e1bf7f3f31bde1615015c5ef4be264f20c6e34c590d8a7c9516e94f4
|
||||
checksum: 3feb39f8da038fb2b1ad074c19a9579c263c1d7a872c5c6e0269b82d67805bb8c93cf9fc393e852807483ae9a918b1ac2861c72f73ee92fb3935ea68333a2cf7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue