Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion MAINTAINING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ with `cardvision refresh` for the checks and `cardvision cdn` for the host ([cdn
cards against Konami's database in each language before publishing.
6. **Publish.** The new art (`cardvision cdn publish --catalog … --images …`), then the release:
`cardvision cdn publish-release --release <folder> --min-version 0.3.0 --data-file <file> --config
cdn/config.json --set-pointer` (try it with `--dry-run` before). It uploads the release folder, verifies it
cdn/config.json --set-pointer --verdict-r <VERDICT-R.json> --verdict-n <VERDICT-N.json>` (try it with
`--dry-run` before). The two verdicts are step 3's files: each must be a PASS of its own gate, not a
rehearsal, under the same rule, or the tool refuses before anything is fetched or written (cardvision
0.10.0 and later). An update with no new card has no new-card verdict: it takes
`--no-refresh-gate "official renames, no new cards"` in place of both, after the regression
check has still been run and its verdict kept. It uploads the release folder, verifies it
live, publishes the details file, and moves the pointer in `config.json` last. Publish each
language's file with `cardvision cdn publish --data-file <file> --config cdn/config.json` after
setting its `details<Lang>` entry. Commit the changed
Expand Down
10 changes: 8 additions & 2 deletions cdn/SETTINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,14 @@ compressed (the bank and catalog are most of a card-only update).
### Publishing a release

`cardvision cdn publish-release --release <folder named after its id> --min-version 0.3.0 [--data-file F]
[--config cdn/config.json --set-pointer] [--sessions] [--dry-run]`:

[--config cdn/config.json --set-pointer (--verdict-r R --verdict-n N | --no-refresh-gate "REASON")]
[--sessions] [--dry-run]`:

0. **Refresh gate** (with `--config`, cardvision 0.10.0 and later): both refresh verdicts, each a
PASS of its own gate with `rehearsal` false under one rule, or `--no-refresh-gate` with the reason
(a release that is not a gated card update, such as one that renames cards and adds none, or
one with new models). Otherwise the run is refused before anything is fetched or written, a dry run included.
The log names each verdict file with its SHA-256 (MAINTAINING.md, "New cards").
1. **Seal:** the document parses, its id is the folder's name, every pinned file is a flat name
present with its size and SHA-256, and `release-legal/` names this release (`NOTICE`'s first
line, as for a build); then `vendor/cardvision-browser/node/verify-release.mjs`, the vendored runtime's own
Expand Down
2 changes: 1 addition & 1 deletion cdn/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# The publishing tool, `cardvision cdn` (the toolkit's docs/cdn.md), with boto3 for the uploads.
cardvision[cdn]==0.6.0rc2
cardvision[cdn]==0.10.0
4 changes: 3 additions & 1 deletion test/smoke/remote-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ async function hoverPage(tab, url) {
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
await tab.mouse.move(cx, cy);
for (let i = 0; i < 80; i += 1) {
// Up to 2 minutes for the first analysis: a pointer release is downloaded and loaded first, and
// Chrome for Testing under Rosetta took 50-70 s on 2026-11-10 (20 s was too short).
for (let i = 0; i < 480; i += 1) {
await tab.mouse.move(cx + (i % 2 ? 3 : -3), cy, { steps: 2 });
await sleep(250);
const s = await computeState(tab);
Expand Down
4 changes: 2 additions & 2 deletions vendor/cardvision-browser/VENDOR.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"version": "0.1.0",
"license": "Apache-2.0",
"source": "cardvision-browser, the browser runtime of the cardvision toolkit (source published with the toolkit release)",
"commit": "cfb8fb23fb08a88c1edd9f1fa60c8b05fca7e376",
"toolkitRelease": "cardvision 0.6.0rc2",
"commit": "d0584b7f6cf1ddc1938ba654f025483768fce429",
"toolkitRelease": "cardvision 0.10.0",
"onnxruntimeWeb": "1.29.0",
"ortFiles": [
"ort-wasm-simd-threaded.jsep.mjs",
Expand Down
2,058 changes: 1,029 additions & 1,029 deletions vendor/cardvision-browser/cardvision.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion vendor/cardvision-browser/compute-session.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion vendor/cardvision-browser/page-capture.js

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions vendor/cardvision-browser/types/cadence.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { ExecutionProvider } from "./providers.js";
export type AnalysisMode = "pointer" | "always-on";
export type AnalysisMode = "pointer" | "always-on" | "layout";
/** The modes a session runs. */
export type SessionMode = Exclude<AnalysisMode, "layout">;
/** The slow cadence on WebGPU, and before the execution provider is known. */
export declare const DEFAULT_ANALYZE_INTERVAL_MS = 1000;
/** The slow cadence on WebAssembly. */
Expand All @@ -12,7 +14,8 @@ export declare const ACTIVE_WASM_ANALYZE_INTERVAL_MS = 1000;
export declare function analyzeIntervalMs(ep: ExecutionProvider | null): number;
/** The fast interval for the recognizer's execution provider (null: not known yet). */
export declare function activeAnalyzeIntervalMs(ep: ExecutionProvider | null): number;
/** The interval a scheduler is armed with for an execution provider in an analysis mode. */
/** The interval a scheduler is armed with for an execution provider in an analysis mode. In
* "layout" mode this is the pointer's fast cadence; the probe interval is the product's. */
export declare function cadenceMs(ep: ExecutionProvider | null, mode: AnalysisMode): number;
/** Whether this device runs the slower cadences. */
export declare function isSlowDevice(ep: ExecutionProvider | null): boolean;
2 changes: 1 addition & 1 deletion vendor/cardvision-browser/types/compute-session.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { type AnalysisMode, cadenceMs } from "./cadence.js";
export { type AnalysisMode, cadenceMs, type SessionMode } from "./cadence.js";
export { type AnalysisState, FrameScheduler, HOVER_MAX_AGE_MS, replyRejection } from "./frame-scheduler.js";
export { hoverAt } from "./hover-at.js";
export { type ComputeIn, type ComputeOut, type ComputeProtocol, computeProtocol, type FractionBox, MAX_FRAME_SIDE, MAX_OTHER_BOXES, MAX_REASON_LENGTH, MAX_TEXT_LENGTH, type ShownCard, type Tagged, } from "./compute-messages.js";
Expand Down
3 changes: 3 additions & 0 deletions vendor/cardvision-browser/types/detector/detector.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Candidate } from "../boxes.js";
import { type SessionSetup } from "../ort.js";
import type { ExecutionProvider } from "../providers.js";
import { type DecodeSettings } from "./decode.js";
import { type LetterboxSettings } from "./letterbox.js";
Expand Down Expand Up @@ -38,6 +39,8 @@ export declare class Detector implements FrameDetector {
/** The execution provider that initialized. */
readonly ep: ExecutionProvider;
private readonly settings;
/** How long the session took to create and to run once, on `ep`. */
readonly setup: SessionSetup;
lastTimings: {
preprocessMs: number;
inferMs: number;
Expand Down
3 changes: 3 additions & 0 deletions vendor/cardvision-browser/types/embedder.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { type SessionSetup } from "./ort.js";
import type { ExecutionProvider } from "./providers.js";
/**
* Most crops one model run takes. A frame can ask for every proposal at once (up to the
Expand Down Expand Up @@ -30,6 +31,8 @@ export declare class Embedder implements BatchEmbedder {
/** The execution provider that initialized. */
readonly ep: ExecutionProvider;
private readonly settings;
/** How long the session took to create and to run once, on `ep`. */
readonly setup: SessionSetup;
private constructor();
/**
* Create a session on the first of `providers` that initializes and returns embeddings of
Expand Down
23 changes: 19 additions & 4 deletions vendor/cardvision-browser/types/frame-scheduler.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export declare function withinMaxAge(resultSec: number, nowSec: number, maxAgeMs
export declare const HOVER_TRIGGER_MIN_GAP_MS = 250;
/** An analysis with no reply after this long is given up on, so that the next frame can go. */
export declare const ANALYSIS_WATCHDOG_MS = 5000;
/** The watchdog of the looks before a worker's first analysis, once its release has loaded: the
* first analysis warms the models up, and on a slow machine it can take several times longer
* than the ones after it. Given up on at 5 s, it was dropped when it came back and looked again,
* so the first card was late or never came. */
export declare const FIRST_ANALYSIS_WATCHDOG_MS = 15000;
/** After a look comes back with the picture not analyzed, the same picture is due again after
* these delays, one per unanswered look in a row, then the last one each time. */
export declare const LOOK_RETRY_MS: readonly number[];
Expand Down Expand Up @@ -59,7 +64,7 @@ export declare function replyRejection(envelope: FrameEnvelope | undefined, live
/** Does a rejected reply still finish the request in flight? */
export declare function rejectionAnswersInFlight(reason: ReplyRejection): boolean;
/** Which analysis policy applies right now. */
export type AnalysisState = "always-on" | "fast" | "reading" | "idle";
export type AnalysisState = "always-on" | "fast" | "reading" | "idle" | "probe";
export interface StartedInfo {
/** Time of the analyzed picture in the video, in seconds: what staleness is measured from. */
videoTimeSec?: number;
Expand All @@ -71,6 +76,7 @@ export declare class FrameScheduler {
private readonly confirmFrames;
private mode;
private readingIntervalMs;
private probeIntervalMs;
private pending;
private repeatsLeft;
private lastStartedAt;
Expand All @@ -96,14 +102,22 @@ export declare class FrameScheduler {
private lastUnansweredCapture;
/** A look's capture was refused since the picture was last answered, received or replaced. */
private refused;
/** Layout mode: the host also wants pointer-driven analysis. */
private pointerAnalysis;
/**
* @param intervalMs The cadence of the mode: the fast cadence in pointer mode, the slow one
* in always-on mode (cadence.ts `cadenceMs`).
* @param confirmFrames How many times a still picture is analyzed in all.
* @param mode Defaults to "always-on": the cadence alone decides.
* @param readingIntervalMs The slow cadence of the "reading" state. Defaults to `intervalMs`.
* @param probeIntervalMs Layout mode: the probe interval (the product's). Required there.
*/
constructor(intervalMs: number, confirmFrames?: number, mode?: AnalysisMode, readingIntervalMs?: number);
constructor(intervalMs: number, confirmFrames?: number, mode?: AnalysisMode, readingIntervalMs?: number, probeIntervalMs?: number | null);
private checkProbe;
setProbeIntervalMs(ms: number): void;
/** Layout mode: does the host also want pointer-driven analysis (while its display shows the
* recognizer's own cards)? */
setPointerAnalysis(on: boolean): void;
setIntervalMs(ms: number): void;
setReadingIntervalMs(ms: number): void;
/** Is a tooltip showing at the resting pointer? Report it before each evaluation and after
Expand All @@ -120,8 +134,8 @@ export declare class FrameScheduler {
requestLook(): void;
/**
* A look came back with the picture not analyzed: the picture could not be captured, the
* worker was still busy with an earlier picture, or no reply came within
* `ANALYSIS_WATCHDOG_MS`. The still picture's other repeats are dropped, and the same picture
* worker was still busy with an earlier picture, or no reply came within the watchdog's time
* (`ANALYSIS_WATCHDOG_MS`, or `FIRST_ANALYSIS_WATCHDOG_MS` before the first analysis). The still picture's other repeats are dropped, and the same picture
* counts as newly presented again after a back-off, so that a paused video is looked at again
* (with its repeats). This is not `requestLook`, which would also make the picture stale and
* let every pointer move look again at once, past the back-off.
Expand Down Expand Up @@ -171,6 +185,7 @@ export declare class FrameScheduler {
/** Is the grace period of the last pointer activity still running? */
pointerActive(now: number): boolean;
analysisState(now: number): AnalysisState;
private pointerState;
/** May anything be analyzed right now? */
analysisActive(now: number): boolean;
/** The cadence in effect: the slow reading cadence while reading, else the mode's cadence. */
Expand Down
6 changes: 4 additions & 2 deletions vendor/cardvision-browser/types/hover-geometry.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ export interface NormalizedBounds {
* One card of a layer, in fractions of the frame.
*
* `bounds` is the card's axis-aligned box. `localWidth` and `localHeight` are the card's own
* size before any turn, and `rotation` its tilt in degrees, in (-45, 45]. The detector's boxes
* are axis-aligned, so for them the tilt is 0 and the local size equals the box's size.
* size before any turn, and `rotation` its tilt in degrees, in (-45, 45], positive clockwise on
* screen. The detector's boxes are axis-aligned, so for them the tilt is 0 and the local size
* equals the box's size; with rotated outlines a named card takes its outline's (tilt.ts
* `outlineRect`), and `bounds` stays the box.
* `cardId` and `name` are set only for a card that is named; a card that was detected and not
* named carries neither, so nothing can be shown for it by mistake.
*/
Expand Down
4 changes: 3 additions & 1 deletion vendor/cardvision-browser/types/hover-layer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export interface HoverEntry {
proposal: number;
aabb: AABB;
rect: Rect;
/** The card's outline when rotated outlines are on (`ScoredProposal.outline`). */
outline?: Rect;
/** The card id to show, or null: the box takes part and shows nothing. */
identity: string | null;
/** The proposal's score. */
Expand All @@ -26,7 +28,7 @@ export interface HoverEntry {
zIndex: number;
}
type HoverFrame = Pick<ScoredFrame, "kept"> & {
proposals: ReadonlyArray<Pick<ScoredProposal, "aabb" | "rect" | "score" | "detectorScore" | "accepted" | "displayId">>;
proposals: ReadonlyArray<Pick<ScoredProposal, "aabb" | "rect" | "score" | "detectorScore" | "accepted" | "displayId" | "outline">>;
};
/**
* The selection's members as indices into `frame.proposals`, bottom of the stack first (entry
Expand Down
17 changes: 12 additions & 5 deletions vendor/cardvision-browser/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
export { analyzeFrame, type LoadedRelease, type LoadOptions, type LoadProgress, loadRelease, ReleaseError } from "./load.js";
export { analyzeFrame, type LoadedRelease, type LoadOptions, type LoadProgress, type LoadTimings, loadRelease, type ModelLoadTimings, ReleaseError } from "./load.js";
export type { SessionSetup } from "./ort.js";
export { type ClientBox, createSession, type Session, type SessionOptions, type SessionStatus, type Shown } from "./session.js";
export { type BoxResult, type FaceResult, type FrameAnalysis, hoverAt, hoverCardsOf, Pipeline, type PipelineOptions } from "./pipeline.js";
export { type AnalyzeOptions, type BoxResult, type FaceResult, type FrameAnalysis, hoverAt, hoverCardsOf, Pipeline, type PipelineOptions } from "./pipeline.js";
export { type AABB, type Candidate, iou, nonMaxSuppression, type Rect } from "./boxes.js";
export { type EmbeddingBank, parseBank } from "./bank.js";
export { type AnalysisMode, cadenceMs } from "./cadence.js";
export { type AnalysisMode, cadenceMs, type SessionMode } from "./cadence.js";
export { analysisSize, captureFrame, type FrameSource, MAX_ANALYSIS_WIDTH, MIN_ANALYSIS_WIDTH } from "./capture.js";
export { type DecodeSettings, decodeDetections, DEFAULT_DECODE, validBox } from "./detector/decode.js";
export { Detector, type DetectorSettings, type Frame, type FrameDetector } from "./detector/detector.js";
Expand All @@ -12,11 +13,17 @@ export { type BatchEmbedder, Embedder, type EmbedderSettings } from "./embedder.
export { type AnalysisState, FrameScheduler, HOVER_MAX_AGE_MS, replyRejection } from "./frame-scheduler.js";
export { computeCardQuad, type LayerCard, type NormalizedBounds, pointInConvexQuad, resolveHoveredCard } from "./hover-geometry.js";
export { HOVER_SELECTIONS, type HoverOutcome, type HoverSelection, hoverOrder, resolveHover, selectHoverLayer } from "./hover-layer.js";
export { type Box, compatible, correspondences, type Correspondence, fitFrame, fitFrameDetail, type FitParams, type FrameFitOutcome, iou as layoutIoU, type Layout, type LayoutCard, LAYOUT_FIT_DEFAULTS, layoutExtent, type Observation, placementDistance, project, type Region, toRegion, type Transform, } from "./layout-fit.js";
export { classifyAccept, classifyHitbox, coverage, exitLatency, fitError, type Hitbox, type TruthCard } from "./layout-metrics.js";
export { clockUsable, FIDUCIAL_POINTS, type LayoutCandidate, type LayoutRecording, latestOffered, offeredCandidates, type ProbeScheduler, readLayoutRecording, recordingSource, type Replay, replayRecording, sceneAt, timedFrames, truthCandidate, truthUsable, } from "./layout-recording.js";
export { type Display, type FrameInput, type LayoutConfig, layoutConfigError, LayoutRegistration, type LayoutSource, RATIO_POOL_SIZE, type State as LayoutState, suppressedInstances, type Verdict, } from "./layout-state.js";
export { MismatchMonitor, MONITOR_DEFAULTS } from "./mismatch-monitor.js";
export { type IdentityDisplay, type IdentityGroups, IdentityMap, type IdentityRule, parseIdentityGroups } from "./identity.js";
export type { FrameEnvelope, FrameResult, ReleaseProgress, ReleaseStatus, WorkerReply, WorkerRequest } from "./messages.js";
export type { FrameEnvelope, FrameResult, ReleaseProgress, ReleaseStatus, TiltedStatus, WorkerReply, WorkerRequest } from "./messages.js";
export { boxAverageRgb, PREPROCESSING, type PreprocessingContract, rotateTensor90, toContractTensor } from "./preprocess.js";
export { EXECUTION_PROVIDERS, type ExecutionProvider } from "./providers.js";
export { chooseLook, cropRgba, lookAccepted, recognizeFrame, type ScoredFrame, type ScoredProposal } from "./recognition.js";
export { chooseLook, cropRgba, lookAccepted, recognizeFrame, type ScoredFrame, type ScoredProposal, type TiltedEvidence, type TiltedRun, tiltedOrder } from "./recognition.js";
export { DEFAULT_TILTED_RETRY, estimateTilt, OUTLINE_MIN_TILT, outlineFromTilt, outlineRect, rectFromAabb, sampleRect, tiltedRects, type TiltedRetrySettings, } from "./tilt.js";
export { type AcceptRule, DEFAULT_ACCEPT, EmbeddingRecognizer, type ScoredMatch } from "./recognizer.js";
export { type CatalogCard, loadReleaseData, parseRelease, type ReleaseData, type VisionRelease } from "./release.js";
export { resizeBilinearRgb } from "./resize.js";
Expand Down
Loading
Loading