Commit Graph
73 Commits
Author SHA1 Message Date
aiongg bf0386bf76 Merge integration track sys 2026-10-31 02:17:26 +00:00
aiongg 70eafa58cb Merge PR #3683: platform: macOS test fixes (boxed MediaClip, HEVC probe test in its own binary) 2026-10-31 02:12:27 +00:00
aiongg 19db881b0c Merge PR #3255: platform: VideoToolbox export takes the RGBA pictures and converts them itself (#3030) 2026-10-31 02:12:01 +00:00
aiongg 8498607d0d Merge PR #2386: #2375: the NVENC SDR sample entry test expects the BT.709 colr since #2142 2026-10-31 02:10:03 +00:00
Patrik LermonandClaude Opus 5.5 749030694d platform: give the macOS HEVC probe test its own binary again
It must be the first in its process to ask `hevc_available()`, but #2860 moved it into the shared
`it` binary next to `hardware_encode`, which asks too. Under `cargo test` (xtask's fallback without
nextest) the two raced and it failed with "nothing has asked yet". Same layout as its Windows twin
`nvenc_hevc_warm.rs`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:43:04 +01:00
Patrik LermonandClaude Opus 5.5 660fd64739 platform: box the media clip in the macOS hardware encode test
`ItemKind::Media` holds a `Box<MediaClip>` now. The test is macOS-only, so Linux CI never compiled
it and clippy on macOS failed on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:43:04 +01:00
Jason LukerandClaude Fable 5.1 f98c6e20bb platform: VideoToolbox export takes the RGBA pictures and converts them itself (#3030)
Export > Hardware encoding on macOS was CPU-bound by its own colour conversion: the
encode thread converted every RGBA frame to NV12 (rgba_to_yuv420_8) while the rayon
pool rendered the next batch, so the serial conversion took 20-27 ms a 1080p frame
and the media engine waited (perf.stats: convertMs 29.6 s of a 33.7 s export). The
VideoToolbox session now takes the export's RGBA pictures as 32BGRA buffers tagged
BT.709 and converts them itself, as NVENC has since #486; the encode thread copies
8 MB a frame (0.3-0.4 ms). A VideoToolbox that refuses RGB input on the first picture
gets the planar session and the CPU conversion back, so nothing depends on it.

Apple M2 Max, A/B interleaved, median of 3: hardware-encode export of a 60 s 1080p
timeline 35.8 s -> 29.4 s (now render-bound, waitMs 18-25 s), with GPU rendering
22.2 s -> 18.7 s at 277 % -> 219 % CPU; the software-encoder export is byte-identical.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-29 22:53:44 -07:00
dotCooCoo aab42961b7 Tests: split the NVENC error test so clippy's complexity limit passes on Windows
what_nvenc_cannot_do_is_an_error_that_says_why had a cognitive complexity
of 34, over the workspace limit of 30, so
`cargo clippy -p filmcraft-platform --all-targets -- -D warnings` failed on
Windows. The file is Windows-only, so Ubuntu CI does not lint it.

The test keeps the declined-configuration cases. The HDR cases, the
interlaced and no-encoder cases, the export size limits and the factory
cases move to four tests of their own, with the same assertions.
2026-10-28 17:35:23 -07:00
dotCooCoo 4539b67ef7 Tests: Windows platform tests build ItemKind::Media with a boxed MediaClip
ItemKind::Media now holds a Box<MediaClip>, but the NVENC HEVC export tests
still passed a bare MediaClip, so filmcraft-platform's Windows-only test
targets failed to compile with E0308. Wrap the MediaClip in Box::new in the
three project() helpers.
2026-10-28 16:59:38 -07:00
Dylan M. Taylor 3ffd0ebdf9 Refactor platform for strict Clippy checks 2026-10-28 04:36:48 +00:00
aiongg 81db9bd3c2 refactor(platform): convert mod.rs files to <module>.rs 2026-10-26 18:15:17 +00:00
skylar taylor-barrickandDylan M. Taylor 320cae243d Migrate FilmCraft to egui 0.37 with current editing changes preserved (#3249)
* egui 0.37: migrate FilmCraft input and rendering integration

* egui-037: fix capture failures, UTF-8 input and hidden timing

* Fix screenshot crop scale for fitted native surfaces

* egui037: simplify UI helpers and preserve pointer IME cancellation

* Translate graphics and effect control accessibility labels

* egui037: Document capture and IME lifecycle contracts

* egui-037: document UI and input integration contracts

---------

Co-authored-by: Dylan M. Taylor <dylan@dylanmtaylor.com>
2026-10-25 14:45:04 -04:00
Earl Co ee871ca06c security(h264): enforce long-term DPB limits (#2894) 2026-10-24 04:50:30 -04:00
aiongg 0a881266c8 CI: xtask ci in the dev profile, one test binary per crate, nextest (#2860)
* Tests: one integration-test binary per crate

Each crate with several tests/*.rs files keeps them as modules of tests/it/,
so cargo links one test executable per crate instead of one per file. Files
that change process-wide state or time a workload stay binaries of their own.

* Profiles: line tables for workspace crates, no debug info for dependencies

* Windows ARM64: nightly and on release pushes instead of every push to main

* xtask ci: clippy and tests in the dev profile

The release profile's thin LTO and single codegen unit made linking the test
binaries take most of the gate. The codec and audio crates stay at opt-level 3
in the dev profile, so their tests run at release speed.

* xtask ci: nextest, doctests, no examples, one wasm check

Tests run with cargo nextest when it is installed (cargo test otherwise) and
build with --lib --bins --tests, so examples aren't linked; doctests run
separately. The wasm check keeps going past the first failing crate. VP8
fixture generation locks across processes, since nextest runs each test in
its own.

* VP9 synthetic fixtures: write aside and rename

A test in another process could read a fixture ffmpeg was still writing.

* Fuzz tests: a third of each sweep by default, all of it with FILMCRAFT_FUZZ_ITERS

Every seed, mutation kind and thread count still runs. Header bytes each get
one overwrite value and two bit flips in rotation, so every value and bit
index still occurs across the region. FILMCRAFT_FUZZ_ITERS=N runs the whole
sweep plus N random rounds per seed, as before.

* Platform fallback tests: one failure point per hybrid path

The failure-anywhere test injected a failure at four points around every
restart point; the hybrid's paths differ only in the first GOP, around the
second and last restart points, at the end and never. The replay test needs
the first two GOPs.

* Export tests: shorter ranges with the same checks

The bitrate test measures 0.5–1.5 s, where each preset reaches its own
target (on 0–3 s the simple demo left two presets at the same rate). The
every-preset test exports three frames per preset.

* Audio tests: effects in parallel, a table-driven FFT for the Opus quality metric

The extreme-settings test keeps both settings and the 40 s tail for every
effect, one thread each. The Opus quality metric's FFT builds its twiddles
once and allocates nothing per transform (same algorithm and summation order).

* CI: dev-profile gate with nextest

xtask ci no longer builds with --release, so the release-profile overrides
go; nextest is installed for the test step.

* CI: apt packages through the cached install-apt-packages action

* Review fixes: fuzz tests with a panic hook in their own binaries, loud fixture lock

The fuzz tests of av1, h264, hevc, mpeg2v, vp8 and vp9 count panics through
a process-wide hook, so a panic in another test of the same process would
fail them; they are binaries of their own again. The VP8 fixture lock fails
the test instead of skipping it silently, and the full-sweep doc comments say
how many truncation points the full run samples.

* Fuzz tests: rotate the default subset per run (FILMCRAFT_FUZZ_SEED replays one)

* platform tests: decode-switch tests in their own binaries, one NVENC lock
2026-10-23 13:34:16 -04:00
Earl Co 16d93a8c3d security(videotoolbox): bound reorder buffering (#2908) 2026-10-23 10:53:57 -04:00
Earl Co ccb80b2e9d security(platform): bound hybrid replay output (#2938) 2026-10-23 10:52:08 -04:00
irgendwasmitfelixandClaude Opus 5.5 3413825016 #2375: the NVENC SDR sample entry test expects the BT.709 colr since #2142
The SDR (Main) HEVC encoder's sample entry carries an nclx BT.709 colr since
678fe732 tagged every SDR export. Assert what "nothing HDR" means now (a
BT.709 limited-range colr, no mdcv / clli) and fix the outdated comment.

Fixes #2375

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 19:50:20 +02:00
Marco Arnulfo c1b1e86046 fix(codecs): in-band parameter sets compare without trailing zero bytes (fixes #1483)
ffmpeg keeps a trailing zero byte after the hvcC PPS that the in-band PPS lacks, so the byte-for-byte comparison read it as a parameter-set change and sent the stream to the software decoder from its first sample. A NAL unit never ends with 0x00 (H.264 7.4.1, H.265 7.4.2): those bytes are trailing_zero_8bits, so both sides are compared without them. The platform fallback test used a trailing zero byte as its changed SPS; it now changes nal_ref_idc.
2026-10-13 01:16:52 +02:00
MarekSpodBiedry d702608eaf Count VideoToolbox sessions, frames and declined requests in perf.stats (#981) 2026-10-11 11:35:18 +02:00
skylar taylor-barrick 1996723225 UI.6: refresh shared UI integration against current main 2026-10-10 18:51:04 -06:00
Brandon ThomasandClaude Opus 5.5 f114b5f10c Revert #783 (Linux H.265 through NVENC): intermittent heap corruption in the CLI
With NVENC registered on Linux, `filmcraft-cli --test cli` aborts in 2 of 45 runs on an RTX 3090
(`malloc(): mismatching next->prev_size`, `malloc(): unaligned fastbin chunk detected`) right
after an export finishes; 0 of 30 runs fail with this reverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:01:15 -04:00
SilentYetiandClaude Opus 5.5 c635d9af9e Linux: H.265 export through NVENC
The NVENC HEVC encoder (Main 8-bit SDR and Main 10 HDR PQ / HLG) was gated to
Windows. It now also runs on 64-bit Linux, on the CUDA device the H.264 encoder
already uses: the H.265 format and HDR probes are registered there and the
HEVC tests run on both systems.

NVENC registration on Linux now happens after the VA-API probe. Started beside
it, the background HEVC probe's first cuInit could deadlock with
libva-nvidia-driver, which calls cuInit from its library constructor under the
loader lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:41:04 -07:00
Brandon Thomas 23ac344798 Merge pull request #673 from abdelkabirouadoukou/fix-monterey-constant-bitrate
platform: look up kVTCompressionPropertyKey_ConstantBitRate at run time
2026-10-10 14:54:16 -04:00
Abdelkabir Ouadoukou 0f08798af0 platform: look up kVTCompressionPropertyKey_ConstantBitRate at run time 2026-10-10 15:54:00 +00:00
JordyUSAandClaude Opus 5.5 360183e273 Merge main into feat/export-crf
Conflict in crates/engine/src/export_tools.rs: both sides added an
import (BitrateMode for CRF, GpuRendering from main); both kept.
main's new Chinese catalog requires every tl! string: added zh-CN for
"Quality (CRF)" and "CRF (constant quality)".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:45:31 +07:00
Brandon Thomas b638f94d7a Merge pull request #442 from cshapiro/fix/windows-upstream-validation
WINCI: Repair HEVC timing and CRLF translation validation
2026-10-10 08:10:03 -04:00
Brandon ThomasandClaude Opus 5.5 1bf590c73c Timeline file drops: merge origin/main; document the platform cursor exception and mixed-DPI limit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:11:18 -04:00
Brandon ThomasandClaude Opus 5.5 0414a1d346 #549: NVDEC callback state from Box::into_raw, freed in Drop; setting test accepts NVDEC or VA-API
Session kept the parser's user data in a Box and later wrote through that Box,
which invalidates the raw pointer the callbacks use (Stacked/Tree Borrows).
Rust code now reaches the state only through the same into_raw pointer, never
across the parse call, and Drop frees it after the parser is destroyed.
The setting test accepts either Linux backend's decoder when NVDEC registered,
and the README notes perf.stats names NVDEC for streams VA-API decodes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:32:00 -04:00
JordyUSAandClaude Opus 5.5 3a46156861 Export: CRF (constant quality) bitrate encoding for H.264
Adds BitrateMode::Crf with ExportSettings::crf (0-51, default 23) and
maps it to the built-in encoder's RateControl::Crf, which export never
used. The Export panel offers "CRF (constant quality)" with a Quality
(CRF) slider in place of the bitrate fields; file.exportMedia takes
`crf` and `bitrateMode: "crf"`. H.265 (hardware only) rejects it, and
VideoToolbox / NVENC decline it so the built-in encoder runs. Settings
saved before this read as CRF 23.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 17:09:05 +07:00
Brandon ThomasandClaude Opus 5.5 2ff51268f1 Merge origin/main into #442; pin HEVC VUI offsets, drop the CRLF i18n hunk
The i18n CRLF normalisation already landed with #488, so main's version is kept.
abi_tests now asserts the HEVC VUI field offsets (inside the VUI and within
NV_ENC_CONFIG_HEVC) to rule out a binding mismatch behind the reversed timing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:04:44 -04:00
SilentYetiandClaude Opus 5.5 3df0b9bb36 Merge remote-tracking branch 'origin/main' into nvdec-linux
tests/setting.rs: keep the check against the backend register() reported
(main's fix expects VA-API on Linux, which NVDEC now sits in front of).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:30:22 -07:00
SilentYetiandClaude Opus 5.5 b3d68fe0ae NVDEC: reject pictures without valid bitstream data before the driver call
The parser's picture parameters were passed to cuvidDecodePicture unread.
Their shared head is now checked first: a null data pointer, zero length, no
slices, or a slice offset past the end of the data is an error, so the
session fails over to the software decoder and the driver never sees the
picture.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:17:16 -07:00
Brandon Thomas 11f8ac9718 Merge pull request #486 from MasakatsuFunaki/nvenc-rgba-input
M-HW: NVENC takes the export's RGBA and converts it on the GPU (#30)
2026-10-10 05:03:06 -04:00
Brandon Thomas 606c355644 Merge pull request #475 from MrCloudy2/fix/vaapi-shared-display
#474: VA-API decoders share one display (no 0.3 s open / 70 ms close per decoder on NVIDIA)
2026-10-10 05:03:00 -04:00
Brandon Thomas 2ded373cdb Merge pull request #453 from MrCloudy2/fix/hybrid-replay-keeps-pictures
#447: HybridDecoder fallback replay goes on past samples the software decoder rejects
2026-10-10 05:00:48 -04:00
Brandon Thomas 629d554e0d Merge pull request #467 from sanyamsingh001/codex/audio-stream-essence
Keep selected audio streams distinct in AAF/OMF exports
2026-10-10 05:00:30 -04:00
SilentYetiandClaude Opus 5.5 03a840d28b Linux: NVDEC hardware decoding for H.264 and HEVC
Adds a second Linux decoder backend, crates/platform/src/nvdec, that talks to
NVIDIA's driver directly (libnvcuvid + the CUDA driver, both loaded at run
time). It is registered in front of VA-API: what NVDEC declines still reaches
VA-API, then the software decoders. H.264 8-bit and HEVC 8/10-bit, 4:2:0
progressive.

NVIDIA's parser takes Annex B access units, so there is no host-side DPB.
Pictures are read back as NV12 / P016 through the existing biplanar path and
are bit-exact with the software decoders. The CUDA context is the one
nvenc::device already retains; it gains push/pop and copy-to-host. A seek
recreates the parser and keeps the decoder.

Also fixes tests/setting.rs, which expected the Media Foundation backend name
on Linux, and updates the Hardware decoding tooltip and its Spanish row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:17:11 -07:00
MitchandClaude Sonnet 5.5 b630643ec9 #171: read the OS cursor for drops from the file manager
winit on Windows sends no cursor events while files are dragged in, so the
pointer was stale and the drop was never placed on the timeline. The desktop
app now passes a host hook that reads the cursor from the OS (GetCursorPos),
which the UI maps into window points.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 14:21:49 +11:00
MasakatsuFunakiandClaude 5001d6bf29 M-HW: NVENC takes the export's RGBA and converts it on the GPU (#30)
8-bit NVENC sessions (H.265 Main, hardware H.264) now take the export's RGBA
frames as ABGR input buffers and NVENC converts them to BT.709 limited 4:2:0
on the GPU, with the same codes as rgba_to_yuv420_8. The CPU conversion ran
on the encode thread, where it competed with the render of the next frames
for the thread pool (about 13 ms per 1080p frame instead of 1.5 ms) and held
NVENC back. A driver that refuses RGB input falls back to the CPU conversion
into NV12. HEVC Main 10 is unchanged.

60 s of a 1080p30 project as H.265 in the app: 18.7 s -> 15.0 s (96 -> 120
fps); headless 30.3 s -> 16.8 s.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-09 23:49:24 +02:00
MrCloudy2andClaude Opus 5.5 30ff11e669 #474: VA-API decoders share one display instead of opening one each
Every VA-API session opened its own display and terminated it when dropped. With NVIDIA's driver
that is a CUDA context each: 0.2-0.3 s to open, 60-70 ms to terminate and about 100 MB of video
memory, on the thread creating or dropping the decoder (a frame worker at every clip change, the
UI thread when media is removed: a ~0.6 s freeze deleting five played clips, and dropped frames at
clip changes).

Sessions now take the process's shared display (the startup probe's, kept for the life of the
process like the libraries) and make only their own configuration, context and surfaces. Display
is Sync on the strength of libva's Multithreading Guide (va.h): its functions and drivers are
thread-safe, and every session uses only its own VA objects. A session that cannot be made on the
shared display is tried once on a new display, which is shared from then on if it works (a GPU
reset).

On NVIDIA (RTX 3060): deleting five played clips 650-690 ms -> 132-198 ms, dropped frames in 20 s
of playback 2-3 -> 0, peak video memory 1281 -> 1010 MiB. Intel and software unchanged.

Test: tests/vaapi_displays.rs (decoders one after another and six at once on six threads open no
display; pictures bit-exact). The VA-API hardware suite passes on NVIDIA and Intel, and the
concurrency tests 20 times each.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:58:47 +02:00
sanyamsingh001andCodex dd121aeb9c AUDIO.STREAM_ESSENCE: Preserve selected audio streams in AAF/OMF exports
Co-authored-by: Codex <codex@openai.com>
2026-10-10 05:53:14 +10:00
MrCloudy2andClaude Opus 5.5 c724bc5566 #447: HybridDecoder fallback replay goes on past samples the software decoder rejects
After a hardware decoder failed, the replay of the run through the software decoder stopped at the
first sample the software decoder rejected (`?` in the replay loop): the pictures it had already
output were dropped, the rest of the run was never fed, the error was returned for the failed
sample even when the software decoder accepted it, and the replay log was not restored. That
happens when the GPU tolerated a damaged sample our decoder rejects and then fails later in the
same run; one picture went missing on a damaged HEVC file through VA-API (Intel).

The replay now behaves like software decoding from the restart point: a rejected sample is skipped
(logged when the hardware had already decoded it); if the failed sample itself is rejected its
error is this call's, and the pictures replayed before it are kept in `carry` for the next output.

Regression test (every platform, no GPU): a stand-in hardware decoder that decodes one damaged
sample the software decoder rejects and fails at that sample or later; every software picture
comes out once and in order, errors are reported where the software decoder reports them, and the
pictures from the next restart point are the software decoder's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:36:54 +02:00
Cathy Shapiro 626df5ac86 WINCI: Repair upstream HEVC timing and CRLF translation validation
Delegate HEVC VUI timing to NVENC's configured frame rate instead of the
explicit timing pair reversed by the affected driver. Preserve existing
stream quality/timing assertions and cover integer and fractional rates.
Normalize line endings in the translation test's source scanner so it
excludes test modules in Windows checkouts as well as LF checkouts.

Assisted-by: Codex
2026-10-09 10:59:56 -05:00
Brandon ThomasandClaude Opus 5.5 f267a941fb Merge origin/main into feat/nvenc-export
main gained NVENC H.265 Main / Main 10 (#328, #360), export stage timings
(#370) and VA-API decoding (#358). Resolution: main's NVENC session, FFI and
export factory, with this PR's changes ported onto them:
- ffi: the portable Guid (now also for the HEVC GUIDs), NV_ENC_DEVICE_TYPE_CUDA;
- session: device.rs (Direct3D 11 / retained CUDA primary context), the
  Linux libnvidia-encode.so.1 loader, Device::KIND;
- export: factory_with and its tests, the even-size check, the saturating
  max bitrate; H.265 through NVENC stays Windows-only (the factory declines
  it on Linux, where nothing probed or tested it);
- Cargo.toml: main's Linux libloading dependency covers both users;
- docs: README / ROADMAP / architecture now say NVENC H.264 runs on Windows
  and Linux; ADR and platform README keep both addenda / test rows;
- abi_tests: note why the MSVC-generated expectations hold on LP64 Linux.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:12:46 -04:00
Brandon ThomasandClaude Opus 5.5 285e81b5da Merge origin/main into m8/export-stage-timings
NVENC export: keep main's Main 10 / Main dispatch and time both colour
conversions (rgbf_to_yuv420_10, rgba_to_yuv420_8) as Stage::Convert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:08:35 -04:00
Brandon ThomasandClaude Opus 5.5 afd5a6b347 M3: NVENC Main 10 review fixes: saturating plane sizes, as_chunks for clippy
encode / encode_10 compute the plane sizes they check with saturating_mul;
fill_p010, rgbf_to_yuv420_10 and the HDR export test use as_chunks instead of
chunks_exact with a constant size (clippy::chunks_exact_to_as_chunks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:01:08 -04:00
Brandon Thomas 6ebc21f093 Merge remote-tracking branch 'origin/main' into fix-360
# Conflicts:
#	README.md
#	ROADMAP.md
#	crates/platform/README.md
2026-10-09 09:46:48 -04:00
Brandon Thomas 570d06d5bd Merge remote-tracking branch 'origin/main' into fix-328
# Conflicts:
#	Cargo.lock
#	README.md
#	ROADMAP.md
#	crates/platform/Cargo.toml
#	crates/platform/README.md
#	docs/architecture.md
2026-10-09 09:34:12 -04:00
Brandon Thomas 0bae537ad0 Merge pull request #300 from dcarnelutti/platform/warm-hevc-probe
platform: ask for the hardware HEVC encoder in the background at startup
2026-10-09 09:25:32 -04:00
Davi AndreiandClaude Opus 5.5 1996f319c3 Export: stage wall times in perf.stats (export.stages)
filmcraft_export::Stage, stage_times(), note_stage() and timed(): the wall
time of setup, loudness, render, encode (and its RGB->YUV convert part),
audio, mux and finish, summed per process like export.hardware. Converters
in the H.264 / ProRes / NVENC / VideoToolbox encoders are timed as Convert.
Two clock reads per stage per batch; the exported file does not change
(determinism tests). Test: an export grows every stage counter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 01:26:09 -03:00