diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61442e7..5fcf36c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,6 @@ jobs: toolchain: ${{ env.RUST_TOOLCHAIN }} profile: minimal override: true - - uses: swatinem/rust-cache@v2 - name: Build (Makefile linux-arm64) run: make ubuntu-arm64 - name: Run tests diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 60a1e1e..6746936 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -79,8 +79,6 @@ jobs: profile: minimal override: true - - uses: swatinem/rust-cache@v2 - - name: Install packaging tools run: cargo install cargo-deb cargo-generate-rpm diff --git a/README.md b/README.md index 2f44dbc..c176216 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,10 @@ Explore Kingfisher’s built-in report viewer and its `--access-map`, which can kingfisher scan /path/to/scan --access-map --view-report ``` -![alt text](docs/kingfisher-usage-access-map.gif) +![alt text](docs/kingfisher-usage-access-map-01.gif) + +**Click to view video** +[![Demo](docs/demos/findings-thumbnail.png)](docs/kingfisher-usage-access-map-02.mp4) # Table of Contents diff --git a/docs/demos/.gitignore b/docs/demos/.gitignore index 8d7839d..d8d07cb 100644 --- a/docs/demos/.gitignore +++ b/docs/demos/.gitignore @@ -137,3 +137,6 @@ dist # SvelteKit build / generate output .svelte-kit + + +pw-out/* diff --git a/docs/demos/findings-thumbnail.png b/docs/demos/findings-thumbnail.png new file mode 100644 index 0000000..574f04a Binary files /dev/null and b/docs/demos/findings-thumbnail.png differ diff --git a/docs/demos/merge.sh b/docs/demos/merge.sh deleted file mode 100755 index d230858..0000000 --- a/docs/demos/merge.sh +++ /dev/null @@ -1,28 +0,0 @@ -GIF_IN="../kingfisher-usage-access-map-01.gif" -WEBM_IN="pw-out/066d10b5ae5d3603dacd69417a8227c6.webm" -OUT_GIF="../kingfisher-usage-access-map-01+accessmap.gif" - -# 1) Normalize GIF -> MP4 (H.264, fixed fps/size) -ffmpeg -y -i "$GIF_IN" \ - -vf "fps=12,scale=960:-2:flags=lanczos" \ - -an -c:v libx264 -pix_fmt yuv420p -crf 18 -preset veryfast \ - gif_part.mp4 - -# 2) Normalize WEBM -> MP4 (same settings) -ffmpeg -y -i "$WEBM_IN" \ - -vf "fps=12,scale=960:-2:flags=lanczos" \ - -an -c:v libx264 -pix_fmt yuv420p -crf 18 -preset veryfast \ - webm_part.mp4 - -# 3) Concatenate via filter (video-only; reliable) -ffmpeg -y -i gif_part.mp4 -i webm_part.mp4 \ - -filter_complex "[0:v][1:v]concat=n=2:v=1:a=0[v]" \ - -map "[v]" -c:v libx264 -pix_fmt yuv420p -crf 18 -preset veryfast \ - combined.mp4 - -# 4) Convert combined MP4 -> GIF (single palette across whole thing) -ffmpeg -y -i combined.mp4 \ - -vf "fps=12,scale=960:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=256[p];[s1][p]paletteuse=dither=bayer" \ - "$OUT_GIF" - -echo "Wrote: $OUT_GIF" diff --git a/docs/demos/record.mjs b/docs/demos/record.mjs index 30ab60a..5defc84 100644 --- a/docs/demos/record.mjs +++ b/docs/demos/record.mjs @@ -6,24 +6,142 @@ fs.mkdirSync(outDir, { recursive: true }); const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); +const cursorOverlayScript = ` +(() => { + const style = document.createElement('style'); + style.textContent = \` + #__pw_cursor { + position: fixed; + top: 0; left: 0; + width: 18px; height: 18px; + transform: translate(-100px, -100px); + z-index: 2147483647; + pointer-events: none; + } + #__pw_cursor svg { width: 18px; height: 18px; } + #__pw_cursor .dot { + fill: rgba(255,255,255,0.9); + stroke: rgba(0,0,0,0.85); + stroke-width: 2; + } + #__pw_click { + position: fixed; + width: 8px; height: 8px; + border-radius: 50%; + transform: translate(-100px, -100px); + z-index: 2147483646; + pointer-events: none; + opacity: 0; + border: 2px solid rgba(0,0,0,0.6); + } + \`; + document.documentElement.appendChild(style); + + const cursor = document.createElement('div'); + cursor.id = '__pw_cursor'; + cursor.innerHTML = \` + + \`; + document.documentElement.appendChild(cursor); + + const click = document.createElement('div'); + click.id = '__pw_click'; + document.documentElement.appendChild(click); + + let x = -100, y = -100; + const move = (nx, ny) => { + x = nx; y = ny; + cursor.style.transform = \`translate(\${x}px, \${y}px)\`; + click.style.transform = \`translate(\${x}px, \${y}px)\`; + }; + + window.addEventListener('pointermove', (e) => move(e.clientX, e.clientY), { passive: true }); + window.addEventListener('mousemove', (e) => move(e.clientX, e.clientY), { passive: true }); + + window.addEventListener('pointerdown', () => { + click.style.transition = 'none'; + click.style.opacity = '0.9'; + click.style.width = '8px'; + click.style.height = '8px'; + requestAnimationFrame(() => { + click.style.transition = 'all 250ms ease-out'; + click.style.opacity = '0'; + click.style.width = '28px'; + click.style.height = '28px'; + }); + }, { passive: true }); +})(); +`; + +// Converts native