@poe-platform/safe-bash 0.1.842 → 0.1.843
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1292,6 +1292,24 @@ function applyStreamDispositions(tracks, dispositions) {
|
|
|
1292
1292
|
}
|
|
1293
1293
|
return tracks;
|
|
1294
1294
|
}
|
|
1295
|
+
function selectAutomaticAudio(documents) {
|
|
1296
|
+
let selected;
|
|
1297
|
+
let bestScore = -1;
|
|
1298
|
+
for (const document of documents) {
|
|
1299
|
+
for (const track of document.tracks) {
|
|
1300
|
+
if (track.type !== "audio") continue;
|
|
1301
|
+
const score = (track.enabled ? 1 << 22 : 0) + (track.decodedAudio?.channels ?? track.codecDescriptions[0]?.channels ?? 0);
|
|
1302
|
+
if (score > bestScore) {
|
|
1303
|
+
selected = track;
|
|
1304
|
+
bestScore = score;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
return documents.map((document) => ({
|
|
1309
|
+
...document,
|
|
1310
|
+
tracks: document.tracks.filter((track) => track.type !== "audio" || track === selected)
|
|
1311
|
+
}));
|
|
1312
|
+
}
|
|
1295
1313
|
function evalSyncFfmpeg(inBytesOrArgs, maybeArgs, readFileSync, writeFileSync) {
|
|
1296
1314
|
const inBytes = Array.isArray(inBytesOrArgs) ? void 0 : inBytesOrArgs;
|
|
1297
1315
|
const args = Array.isArray(inBytesOrArgs) ? inBytesOrArgs : maybeArgs ?? [];
|
|
@@ -1441,6 +1459,7 @@ function evalSyncFfmpeg(inBytesOrArgs, maybeArgs, readFileSync, writeFileSync) {
|
|
|
1441
1459
|
else outputTarget = arg;
|
|
1442
1460
|
}
|
|
1443
1461
|
if (inputs.length === 0 || !outputTarget) return void 0;
|
|
1462
|
+
if (outputDuration === void 0 && outputTo !== void 0 && outputTo <= (outputSs ?? 0)) return void 0;
|
|
1444
1463
|
const isNullMux = outputFormat === "null" || outputTarget === "/dev/null";
|
|
1445
1464
|
if (!isNullMux && !writeFileSync) return void 0;
|
|
1446
1465
|
if (noOverwrite && !isNullMux && (!readFileSync || readFileSync(outputTarget))) return void 0;
|
|
@@ -1467,9 +1486,9 @@ function evalSyncFfmpeg(inBytesOrArgs, maybeArgs, readFileSync, writeFileSync) {
|
|
|
1467
1486
|
}
|
|
1468
1487
|
loadedDocs.push(doc);
|
|
1469
1488
|
}
|
|
1470
|
-
let workingDoc = muxMp4(loadedDocs, { stripAudio, stripVideo, stripSubtitles, shortest, rotation });
|
|
1489
|
+
let workingDoc = muxMp4(selectAutomaticAudio(loadedDocs), { stripAudio, stripVideo, stripSubtitles, shortest, rotation });
|
|
1471
1490
|
if (outputSs !== void 0 || outputTo !== void 0 || outputDuration !== void 0) {
|
|
1472
|
-
workingDoc = sliceMp4(workingDoc, { startSeconds: outputSs, endSeconds: outputTo, durationSeconds: outputDuration });
|
|
1491
|
+
workingDoc = sliceMp4(workingDoc, { startSeconds: outputSs, endSeconds: outputDuration === void 0 ? outputTo : void 0, durationSeconds: outputDuration });
|
|
1473
1492
|
}
|
|
1474
1493
|
if (outputSize && videoCodec !== "copy") {
|
|
1475
1494
|
const [w, h] = outputSize.toLowerCase().split("x");
|
|
@@ -1823,6 +1842,10 @@ function createFfmpegCommand(options = {}) {
|
|
|
1823
1842
|
);
|
|
1824
1843
|
return { exitCode: 1 };
|
|
1825
1844
|
}
|
|
1845
|
+
if (outputDuration === void 0 && outputTo !== void 0 && outputTo <= (outputSs ?? 0)) {
|
|
1846
|
+
await writeBytes(context.stderr, encodeUtf8("ffmpeg: -to value smaller than -ss; aborting.\n"), context.signal);
|
|
1847
|
+
return { exitCode: 1 };
|
|
1848
|
+
}
|
|
1826
1849
|
try {
|
|
1827
1850
|
if (!overwrite && !isStdout(outputTarget) && outputFormat !== "null") {
|
|
1828
1851
|
const outFull = resolvePath(context.cwd, outputTarget);
|
|
@@ -2248,7 +2271,11 @@ function createFfmpegCommand(options = {}) {
|
|
|
2248
2271
|
const [input, selector, ordinal] = clean.split(":");
|
|
2249
2272
|
const inputIdx = Number(input);
|
|
2250
2273
|
const srcDoc = loadedDocs[inputIdx];
|
|
2251
|
-
if (!srcDoc)
|
|
2274
|
+
if (!srcDoc) {
|
|
2275
|
+
await writeBytes(context.stderr, encodeUtf8(`ffmpeg: Invalid input file index: ${inputIdx}.
|
|
2276
|
+
`), context.signal);
|
|
2277
|
+
return { exitCode: 234 };
|
|
2278
|
+
}
|
|
2252
2279
|
const type = selector === "v" ? "video" : selector === "a" ? "audio" : selector === "s" ? "subtitle" : void 0;
|
|
2253
2280
|
let matches = type ? srcDoc.tracks.filter((t) => t.type === type) : srcDoc.tracks;
|
|
2254
2281
|
const index = type ? ordinal : selector;
|
|
@@ -2268,7 +2295,7 @@ To ignore this, add a trailing '?' to the map.
|
|
|
2268
2295
|
}
|
|
2269
2296
|
const filteredTracks = selectedTracks.map((entry) => entry.track);
|
|
2270
2297
|
if (!mapped) {
|
|
2271
|
-
const tracks = loadedDocs.flatMap((doc) => doc.tracks);
|
|
2298
|
+
const tracks = selectAutomaticAudio(loadedDocs).flatMap((doc) => doc.tracks);
|
|
2272
2299
|
for (const type of ["video", "audio"]) {
|
|
2273
2300
|
const track = tracks.find((track2) => track2.type === type);
|
|
2274
2301
|
if (track) filteredTracks.push(track);
|
|
@@ -2280,7 +2307,7 @@ To ignore this, add a trailing '?' to the map.
|
|
|
2280
2307
|
context.signal
|
|
2281
2308
|
);
|
|
2282
2309
|
} else {
|
|
2283
|
-
workingDoc = await muxMp4Cooperatively(loadedDocs, {
|
|
2310
|
+
workingDoc = await muxMp4Cooperatively(selectAutomaticAudio(loadedDocs), {
|
|
2284
2311
|
stripAudio,
|
|
2285
2312
|
stripVideo,
|
|
2286
2313
|
stripSubtitles,
|
|
@@ -2291,7 +2318,7 @@ To ignore this, add a trailing '?' to the map.
|
|
|
2291
2318
|
if (outputSs !== void 0 || outputTo !== void 0 || outputDuration !== void 0) {
|
|
2292
2319
|
workingDoc = sliceMp4(workingDoc, {
|
|
2293
2320
|
startSeconds: outputSs,
|
|
2294
|
-
endSeconds: outputTo,
|
|
2321
|
+
endSeconds: outputDuration === void 0 ? outputTo : void 0,
|
|
2295
2322
|
durationSeconds: outputDuration
|
|
2296
2323
|
});
|
|
2297
2324
|
}
|
|
@@ -3651,7 +3651,7 @@ import {
|
|
|
3651
3651
|
} from "../safe-bash-contracts/command.js";
|
|
3652
3652
|
import { readBytes as readBytes2, writeBytes as writeBytes2 } from "../safe-bash-contracts/io.js";
|
|
3653
3653
|
import { createOutputOperation } from "../safe-bash-contracts/output.js";
|
|
3654
|
-
import { readImageMetadataFromSource as readImageMetadataFromSource3, decodeImageToStorage as decodeImageToStorage2, transformStoredImage as transformStoredImage2, UnsupportedStoredResource as UnsupportedStoredResource4, decodeImage as decodeImage3, decodePngToCanvas, FONT_5X7, encodeImage, readImageMetadata as readImageMetadata3, parseColor as baseParseColor, applyExifOrientationSteps, compositeImageSteps, computeImageStatsSteps as computeImageStatsSteps2, ensureAlphaImageSteps, extendImageSteps, extractChannelImageSteps, extractImageSteps as extractImageSteps2,
|
|
3654
|
+
import { readImageMetadataFromSource as readImageMetadataFromSource3, decodeImageToStorage as decodeImageToStorage2, transformStoredImage as transformStoredImage2, UnsupportedStoredResource as UnsupportedStoredResource4, decodeImage as decodeImage3, decodePngToCanvas, FONT_5X7, encodeImage, readImageMetadata as readImageMetadata3, parseColor as baseParseColor, applyExifOrientationSteps, compositeImageSteps, computeImageStatsSteps as computeImageStatsSteps2, ensureAlphaImageSteps, extendImageSteps, extractChannelImageSteps, extractImageSteps as extractImageSteps2, flipImageSteps, flopImageSteps, grayscaleImageSteps, resizeImageSteps, rotateImageSteps, thresholdImageSteps } from "../image-ast/portable.js";
|
|
3655
3655
|
var X11_NAMED_COLORS = {
|
|
3656
3656
|
aliceblue: [240, 248, 255, 255],
|
|
3657
3657
|
antiquewhite: [250, 235, 215, 255],
|
|
@@ -4805,11 +4805,10 @@ function* applyMagickSpliceSteps(img, geomStr, bg, gravity = "northwest", signal
|
|
|
4805
4805
|
const g = parseMagickGeometry(geomStr);
|
|
4806
4806
|
const sw = Math.max(0, Math.round(g.width ?? 0));
|
|
4807
4807
|
const sh = Math.max(0, Math.round(g.height ?? 0));
|
|
4808
|
-
const
|
|
4809
|
-
const
|
|
4810
|
-
const
|
|
4811
|
-
const
|
|
4812
|
-
const sy = Math.max(0, Math.min(img.height, Math.round(base.top + (isSouth ? -g.y : g.y))));
|
|
4808
|
+
const box = gravityAdjustBox(img.width, img.height, sw, sh, g.x, g.y, gravity);
|
|
4809
|
+
const anchor = resolveGravityOffset(sw, sh, gravity);
|
|
4810
|
+
const sx = Math.max(0, Math.min(img.width, box.x + anchor.left));
|
|
4811
|
+
const sy = Math.max(0, Math.min(img.height, box.y + anchor.top));
|
|
4813
4812
|
const outW = img.width + sw;
|
|
4814
4813
|
const outH = img.height + sh;
|
|
4815
4814
|
const out = new Uint8Array(new ArrayBuffer(outW * outH * 4 + outH), 0, outW * outH * 4);
|
|
@@ -8061,7 +8060,7 @@ function parseMagickPixelOperation(tokens, settings, start, signal) {
|
|
|
8061
8060
|
return { ...metadata, data: out, space: "b-w", channels: image.hasAlpha ? 2 : 1 };
|
|
8062
8061
|
};
|
|
8063
8062
|
} else if (token === "-gamma") {
|
|
8064
|
-
const gamma = Math.max(0.1,
|
|
8063
|
+
const gamma = Math.max(0.1, parseFloat(tokens[++i] ?? "1"));
|
|
8065
8064
|
const channels = state.channelExplicit ? state.channels : { r: true, g: true, b: true, a: true };
|
|
8066
8065
|
const lookup = [channels.r, channels.g, channels.b, channels.a].map((active) => Uint8Array.from({ length: 256 }, (_, value) => active ? clampByteVal(255 * Math.pow(value / 255, 1 / gamma)) : value));
|
|
8067
8066
|
apply = (image) => applyMagickLookup(image, lookup);
|
|
@@ -8069,7 +8068,19 @@ function parseMagickPixelOperation(tokens, settings, start, signal) {
|
|
|
8069
8068
|
const mode = (tokens[++i] ?? "on").toLowerCase();
|
|
8070
8069
|
if (mode === "remove") {
|
|
8071
8070
|
apply = function* (im) {
|
|
8072
|
-
|
|
8071
|
+
const out = new Uint8Array(im.data.length);
|
|
8072
|
+
const background = [state.background.r, state.background.g, state.background.b];
|
|
8073
|
+
for (let idx = 0; idx < out.length; idx += 4) {
|
|
8074
|
+
if (idx % 65536 === 0) yield;
|
|
8075
|
+
const alpha = im.data[idx + 3] / 255;
|
|
8076
|
+
for (let channel = 0; channel < 3; channel++) {
|
|
8077
|
+
const bg = background[im.channels === 2 ? 0 : channel];
|
|
8078
|
+
out[idx + channel] = clampByteVal(im.data[idx + channel] * alpha + bg * (1 - alpha));
|
|
8079
|
+
}
|
|
8080
|
+
out[idx + 3] = 255;
|
|
8081
|
+
}
|
|
8082
|
+
const { data16: ignored, ...metadata } = im;
|
|
8083
|
+
return { ...metadata, data: out, hasAlpha: false, channels: im.channels === 4 ? 3 : im.channels === 2 ? 1 : im.channels };
|
|
8073
8084
|
};
|
|
8074
8085
|
} else if (mode === "associate" || mode === "disassociate") {
|
|
8075
8086
|
apply = function* (im) {
|
|
@@ -9267,6 +9278,8 @@ function* evaluatePipelineTokensSteps(tokens, files, state, parentStack = [], st
|
|
|
9267
9278
|
if (composed !== overlay) detachRgbaBuffer(overlay.data);
|
|
9268
9279
|
}
|
|
9269
9280
|
stack = [composed, ...stack.slice(2)];
|
|
9281
|
+
} else {
|
|
9282
|
+
throw new Error("image sequence is required '-composite'");
|
|
9270
9283
|
}
|
|
9271
9284
|
} else {
|
|
9272
9285
|
if (t.startsWith("-") && t !== "-" || t.startsWith("+")) throw new Error(`unrecognized option '${t}'`);
|
|
@@ -9513,11 +9526,10 @@ async function transformStoredMagickCoordinates(image, backend, token, geometry,
|
|
|
9513
9526
|
ys = [{ source: h - dy, target: 0, length: dy }, { source: 0, target: dy, length: h - dy }];
|
|
9514
9527
|
} else if (token === "-splice") {
|
|
9515
9528
|
const sw = Math.max(0, Math.round(g.width ?? 0)), sh = Math.max(0, Math.round(g.height ?? 0));
|
|
9516
|
-
const
|
|
9517
|
-
const
|
|
9518
|
-
const
|
|
9519
|
-
const
|
|
9520
|
-
const y = Math.max(0, Math.min(h, Math.round(base.top + (south ? -g.y : g.y))));
|
|
9529
|
+
const box = gravityAdjustBox(w, h, sw, sh, g.x, g.y, state.gravity);
|
|
9530
|
+
const anchor = resolveGravityOffset(sw, sh, state.gravity);
|
|
9531
|
+
const x = Math.max(0, Math.min(w, box.x + anchor.left));
|
|
9532
|
+
const y = Math.max(0, Math.min(h, box.y + anchor.top));
|
|
9521
9533
|
width += sw;
|
|
9522
9534
|
height += sh;
|
|
9523
9535
|
xs = [{ source: 0, target: 0, length: x }, { source: x, target: x + sw, length: w - x }];
|
|
@@ -9888,7 +9900,8 @@ async function tryConvertFilesResult(argv, input, stdinBytes, signal, analysis)
|
|
|
9888
9900
|
if (token === "-layers") i++;
|
|
9889
9901
|
const settings = { ...state };
|
|
9890
9902
|
stackStep(async (stack, backend) => {
|
|
9891
|
-
if (
|
|
9903
|
+
if (token === "-composite" && stack.length < 2) throw new Error("image sequence is required '-composite'");
|
|
9904
|
+
if (!stack.length) return stack;
|
|
9892
9905
|
let result;
|
|
9893
9906
|
if (token === "-composite") {
|
|
9894
9907
|
const base = await stack.get(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poe-platform/safe-bash",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.843",
|
|
4
4
|
"description": "Extensible virtual shell with pluggable filesystems and streaming commands",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -1415,7 +1415,7 @@
|
|
|
1415
1415
|
"access": "public"
|
|
1416
1416
|
},
|
|
1417
1417
|
"dependencies": {
|
|
1418
|
-
"@poe-platform/safe-fs": "0.1.
|
|
1418
|
+
"@poe-platform/safe-fs": "0.1.843",
|
|
1419
1419
|
"pdf-lib": "1.17.1",
|
|
1420
1420
|
"@types/node": "^25.2.2",
|
|
1421
1421
|
"@formatjs/intl-numberformat": "9.4.0",
|