@adatechnology/game-test-room 0.20.0 → 0.22.0
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.
- package/dist/index.d.ts +83 -14
- package/dist/index.global.js +7391 -1050
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +962 -161
- package/dist/index.js.map +1 -1
- package/package.json +18 -14
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
import { LightBudget } from '@adatechnology/game-render-three';
|
|
1
2
|
import * as THREE_NS from 'three';
|
|
2
3
|
import { AudioEngine } from '@adatechnology/game-audio';
|
|
3
4
|
import { Vec3 as Vec3$1, DestructionWorld, BlastOptions, DestructibleSpec, DestructionOptions, DestructionEvent } from '@adatechnology/game-destruction';
|
|
4
5
|
export { DestructionEvent, Vec3 } from '@adatechnology/game-destruction';
|
|
5
6
|
import { DoorUsePhase, FurniturePushPhase, FurniturePushBlock, FurniturePushRules, DoorUseRules } from '@adatechnology/game-player';
|
|
6
|
-
import { BusySink, ItemSeat, Vec3, HandTargets, ModuleControl, ControlValue, ModuleLayer, EnvironmentBus, BusyTask, BusyOptions, TestableModule, ModuleItemSeal, DestructibleImpl, AnimationClipSpec, GroundLayout, BlastShoveOptions } from '@adatechnology/game-contracts';
|
|
7
|
+
import { BusySink, ItemSeat, Vec3, HandTargets, ModuleControl, ControlValue, ModuleLayer, EnvironmentBus, Knock, BusyTask, BusyOptions, TestableModule, ModuleItemSeal, DestructibleImpl, AnimationClipSpec, ItemSounds, GroundLayout, BlastShoveOptions } from '@adatechnology/game-contracts';
|
|
7
8
|
export { AnimationClipSpec, DestructibleImpl, ItemAnimationContract, ModuleScenario, TestableItem, TestableModule } from '@adatechnology/game-contracts';
|
|
8
|
-
import { DestructionRenderer, SpecFromObjectOptions, Quality, FragmentLifeRule } from '@adatechnology/game-destruction-three';
|
|
9
|
-
import {
|
|
9
|
+
import { DestructionRenderer, SpecFromObjectOptions, Quality, SoundDetail, FragmentLifeRule } from '@adatechnology/game-destruction-three';
|
|
10
|
+
import { StorageLike, GraphicsController } from '@adatechnology/game-graphics';
|
|
11
|
+
import { GraphicsScreen } from '@adatechnology/game-graphics/screen';
|
|
12
|
+
import { Arsenal, WeaponState, TriggerResult, WeaponDef } from '@adatechnology/game-weapons';
|
|
10
13
|
import { VfxWorld, SpriteKindDef } from '@adatechnology/game-vfx';
|
|
11
14
|
import { Terrain, TerrainBudget } from '@adatechnology/game-terrain';
|
|
15
|
+
import { SchedulerStats } from '@adatechnology/game-runtime';
|
|
12
16
|
import { FilmBridge, FluidRenderer } from '@adatechnology/game-fluids-three';
|
|
13
17
|
import { FluidWorld, ContainerSpec, LiquidDef, ItemUseDef, SurfaceSpec } from '@adatechnology/game-fluids';
|
|
14
18
|
|
|
@@ -101,6 +105,21 @@ interface LoadingOptions {
|
|
|
101
105
|
declare const nextPaint: () => Promise<void>;
|
|
102
106
|
declare function createLoading(options: LoadingOptions): RoomLoading;
|
|
103
107
|
|
|
108
|
+
/** The room's graphics settings (`TestRoomOptions.graphics`). */
|
|
109
|
+
interface RoomGraphicsOptions {
|
|
110
|
+
/** Where the player's choice is kept (default `localStorage`; null keeps it in memory). */
|
|
111
|
+
readonly storage?: StorageLike | null;
|
|
112
|
+
/** The key it is kept under (default `adatechnology.graphics`). */
|
|
113
|
+
readonly key?: string;
|
|
114
|
+
/** The short test of the first load, seconds (default 3; 0 skips it and starts the automatic mode at Alta). */
|
|
115
|
+
readonly calibrationSeconds?: number;
|
|
116
|
+
/**
|
|
117
|
+
* When the calibration of a first run starts: `idle` (default) after a few drawn frames with nothing on the loading indicator, or `manual`, where the page calls
|
|
118
|
+
* `room.graphics.calibrateIfNeeded()` once its content is in (a page that loads its content before it shows the room).
|
|
119
|
+
*/
|
|
120
|
+
readonly calibrate?: 'idle' | 'manual';
|
|
121
|
+
}
|
|
122
|
+
|
|
104
123
|
/**
|
|
105
124
|
* The room's seats: puts the player on a seat an item brings (`TestRoomItem.seats`, the shape of a `game-interactables` seat) and back on its feet at the seat's exit.
|
|
106
125
|
* Seated, the keys do not walk and the view stays within reach of the seat's facing; a walk key or a jump gets up, and so does losing the seat (the item is gone).
|
|
@@ -452,6 +471,11 @@ interface RoomAvatar {
|
|
|
452
471
|
leg?: 'left' | 'right';
|
|
453
472
|
hand?: 'left' | 'right';
|
|
454
473
|
}): number | null;
|
|
474
|
+
/**
|
|
475
|
+
* The foot the body put down since the last call (its walk cycle reached a heel strike), or null. The room asks after each `update` and sends the footfall to the
|
|
476
|
+
* modules (`HostEvent` `footfall`), so the step is heard on the frame the foot is seen on the ground. Without it the room counts strides by distance.
|
|
477
|
+
*/
|
|
478
|
+
footfall?(): 'left' | 'right' | null;
|
|
455
479
|
/**
|
|
456
480
|
* Brings the body's hands to the tool in them (`HandTargets`, world space: the module's). The room calls it in both views every frame, after the modules have placed the tool and
|
|
457
481
|
* before the render, with `view` (the eye's camera, and `contact` to keep the hands out of walls) in both views. An avatar without it keeps the hands where its own pose puts them.
|
|
@@ -572,6 +596,8 @@ interface TestRoomItem {
|
|
|
572
596
|
animations?: AnimationClipSpec[];
|
|
573
597
|
/** Where the player can sit or lie on it (see `TestRoom.sit`). */
|
|
574
598
|
seats?: readonly ItemSeat[];
|
|
599
|
+
/** What it sounds like in the hand and the sound set of its doors and lids (`TestableItem.sounds`). */
|
|
600
|
+
sounds?: ItemSounds;
|
|
575
601
|
/** Picture for the catalogue, the search results and the aimed-item label: an image URL or inline `<svg…>` markup (see `TestableItem.thumbnail`). */
|
|
576
602
|
thumbnail?: string;
|
|
577
603
|
/** Author and licence of the thumbnail, shown as the tooltip of the picture in the inspector. */
|
|
@@ -677,6 +703,12 @@ interface TestRoomOptions {
|
|
|
677
703
|
world?: DestructionWorld;
|
|
678
704
|
worldOptions?: DestructionOptions;
|
|
679
705
|
quality?: Quality;
|
|
706
|
+
/**
|
|
707
|
+
* The player's graphics settings (`game-graphics`): a Gráficos button opens the screen (presets Automático, Baixa, Média, Alta, Ultra and each option), the
|
|
708
|
+
* choice is kept in the browser, the first load runs a short calibration on the loading indicator and the automatic mode moves what is left on auto. Only on a
|
|
709
|
+
* renderer the room makes. Default off (the fixed look of `quality`).
|
|
710
|
+
*/
|
|
711
|
+
graphics?: boolean | RoomGraphicsOptions;
|
|
680
712
|
/** What the floor is made of until an area lays its own (`TestableModule.ground`). Default a concrete slab. */
|
|
681
713
|
ground?: GroundLayout;
|
|
682
714
|
/** Limits of the floor's marks, thrown pieces and redraws per frame. */
|
|
@@ -708,12 +740,15 @@ interface TestRoomOptions {
|
|
|
708
740
|
area?: string;
|
|
709
741
|
/** Called for every destruction event (to log, play sounds, sync over LAN). Fluid events reach the log too. */
|
|
710
742
|
onEvent?: (event: DestructionEvent) => void;
|
|
711
|
-
|
|
743
|
+
/** Every sound key the room plays, with its detail: the more specific keys of an impact, the named explosion, a leak's seconds (`SoundDetail` of game-destruction-three). */
|
|
744
|
+
onSound?: (key: string, point: Vec3$1, volume: number, detail?: SoundDetail) => void;
|
|
712
745
|
/**
|
|
713
746
|
* The sound engine of the room (@adatechnology/game-audio): the destruction renderer's sound keys play on it, and modules get it as `host.audio`.
|
|
714
747
|
* Default: a new engine of the room's own (it makes no AudioContext until the first sound); `false` for a silent room.
|
|
715
748
|
*/
|
|
716
749
|
audio?: AudioEngine | false;
|
|
750
|
+
/** Where the kit's recorded sound files (game-audio `assets/sfx/`) are served, for the room's engine (default `./sfx/`); `null` plays the recipes only. */
|
|
751
|
+
samplesBaseUrl?: string | null;
|
|
717
752
|
/** The environment store modules get as `host.environment` (the weather module writes it, the others read it). Default: a new one with a calm dry day. */
|
|
718
753
|
environment?: EnvironmentBus;
|
|
719
754
|
/** Show the built-in HUD and panels (default true). */
|
|
@@ -754,6 +789,11 @@ interface TestRoomOptions {
|
|
|
754
789
|
handStances?: Readonly<Record<string, string>>;
|
|
755
790
|
/** The over-the-shoulder view of the `third` mode: distance, shoulder, height, wall probes. Defaults are the team game's. */
|
|
756
791
|
thirdPerson?: ThirdPersonOptions;
|
|
792
|
+
/**
|
|
793
|
+
* Milliseconds of every frame the deferred queues (sound voices, destruction events, breach paint, vehicle crease) share. Default 8, the biggest budget the loose
|
|
794
|
+
* queues had; 4 is the library default of `@adatechnology/game-runtime`, for a room whose `maxFramesWaiting` stays under 15 (see `frameStats()`).
|
|
795
|
+
*/
|
|
796
|
+
frameBudgetMs?: number;
|
|
757
797
|
/** Room counters the bench panel shows and `TestRoom.metrics()` returns (default all); `false` for none. */
|
|
758
798
|
metrics?: readonly RoomMetricId[] | false;
|
|
759
799
|
/**
|
|
@@ -762,12 +802,21 @@ interface TestRoomOptions {
|
|
|
762
802
|
* sprites (dust, smoke, chips, sparks...) by kind, e.g. `{ dust: { life: [10, 30] } }` (seconds, min and max). Loose pieces (what breaks off whole: a door, a leg,
|
|
763
803
|
* a slab) stay as part of the map, with collision.
|
|
764
804
|
*/
|
|
805
|
+
/** Slots of the room's light budget (default 16 point and 4 spot). Each light is paid per pixel, lit or not, so a weak GPU gets fewer; changing them recompiles every lit program, so they are fixed at load. */
|
|
806
|
+
lightSizes?: {
|
|
807
|
+
readonly point?: number;
|
|
808
|
+
readonly spot?: number;
|
|
809
|
+
};
|
|
810
|
+
/** Drawn frames the GPU may be behind before the room holds a draw back (`createFramePacer`, default 2). */
|
|
811
|
+
framesInFlight?: number;
|
|
765
812
|
debris?: {
|
|
766
813
|
fragmentLife?: number | FragmentLifeRule;
|
|
767
814
|
maxFragments?: number;
|
|
768
815
|
particles?: Readonly<Record<string, Partial<SpriteKindDef> | null>>;
|
|
769
816
|
/** Milliseconds of destruction events the renderer applies per frame; the rest wait for the next frames (default 8). `Infinity` applies every event in the frame it happens, which a test comparing counts needs. */
|
|
770
817
|
eventBudgetMs?: number;
|
|
818
|
+
/** The most loose bodies (ejected casings, dropped magazines) modules may keep alive at once, lent as `ModuleHost.particleLimit` (default 900). */
|
|
819
|
+
particleLimit?: number;
|
|
771
820
|
};
|
|
772
821
|
/** Blast options every explosion of the room starts with (`shelter`, `fragmentHits`, `confinement`; default all off). The HUD toggles them and `TestRoom.setBlast` changes them. */
|
|
773
822
|
blast?: BlastOptions;
|
|
@@ -776,6 +825,8 @@ interface TestRoomOptions {
|
|
|
776
825
|
* Default: the SDK's (`DEFAULT_BLAST_SHOVE` of game-contracts: 2 % of the energy becomes speed, 20 m/s at most, falloff `(1 - d / r)^2`).
|
|
777
826
|
*/
|
|
778
827
|
blastShove?: BlastShoveOptions;
|
|
828
|
+
/** Mass of the player's body in kg: how far a blast throws it and whether it knocks it down (default 70, the `bodyMass` of 1.75 m). */
|
|
829
|
+
playerMass?: number;
|
|
779
830
|
/**
|
|
780
831
|
* Module bench state. `state` maps a module id to its encoded state, restored when that module is first loaded (a module reloaded
|
|
781
832
|
* keeps its live state instead) before its first changes are sent; ids are per module, so two modules may share a control id.
|
|
@@ -794,7 +845,9 @@ interface TestRoomOptions {
|
|
|
794
845
|
/** Counters the room measures itself. `fps` and `frame_ms` use the real frame time, so slow motion does not change them. */
|
|
795
846
|
type RoomMetricId = 'fps' | 'frame_ms' | 'draw_calls' | 'triangles' | 'objects' | 'fragments' | 'particles' | 'decals'
|
|
796
847
|
/** Of the last blast, once the room's blast options are on: the share that reached the most sheltered target (%), the pressure multiplier, the fragment hits. */
|
|
797
|
-
| 'blast_shelter' | 'blast_confinement' | 'blast_fragments'
|
|
848
|
+
| 'blast_shelter' | 'blast_confinement' | 'blast_fragments'
|
|
849
|
+
/** Memory: geometries and textures alive on the GPU (three's `renderer.info.memory`), the JS heap in MB where the browser tells it. */
|
|
850
|
+
| 'geometries' | 'textures' | 'heap_mb';
|
|
798
851
|
/** A module control as the room holds it: the declaration with the module's patches applied, and its value (none for an action). */
|
|
799
852
|
type BenchControl = ModuleControl & {
|
|
800
853
|
readonly disabled: boolean;
|
|
@@ -831,6 +884,10 @@ interface TestRoom {
|
|
|
831
884
|
readonly renderer: DestructionRenderer;
|
|
832
885
|
readonly scene: THREE_NS.Scene;
|
|
833
886
|
readonly camera: THREE_NS.PerspectiveCamera;
|
|
887
|
+
/** The room's light budget (what `host.lights` lends): the one owner of its point and spot lights. */
|
|
888
|
+
readonly lights?: LightBudget;
|
|
889
|
+
/** The WebGL renderer the room draws with, for tools that read what the GPU got (the `light_slots` phase of `perf.mjs` reads the uniforms of a lit material). */
|
|
890
|
+
readonly webgl?: THREE_NS.WebGLRenderer;
|
|
834
891
|
/** The test table: lays the catalogue on the `test_table` piece a page at a time and runs the trials (shot, punch, knife, fire, blast) on one item. */
|
|
835
892
|
readonly testTable: TestTable;
|
|
836
893
|
/** Spawn a catalogue item at a world position (default in front of the player). */
|
|
@@ -850,10 +907,16 @@ interface TestRoom {
|
|
|
850
907
|
readonly tool: WeaponState;
|
|
851
908
|
/** Play an item use on the held item (`drink`, `pour`...). Returns false when nothing is held or the use does not apply. */
|
|
852
909
|
useItem(useId: string): boolean;
|
|
853
|
-
/**
|
|
854
|
-
|
|
910
|
+
/**
|
|
911
|
+
* Use the current tool once from the camera (tests and scripted demos), as the click does: bare hands punch (or let go of what they hold). `hold` seconds for continuous tools.
|
|
912
|
+
* Answers what the trigger said: `ok` when the tool did something; `drawing` when the draw is not over for the trigger yet (the frame that ends the draw is the trigger's
|
|
913
|
+
* too, so `tool.phase` turns null one frame before the first pull can go: a script waits a frame and pulls again), `cooldown`, `empty`, `reloading`... otherwise.
|
|
914
|
+
*/
|
|
915
|
+
use(hold?: number): UseStatus;
|
|
855
916
|
/** Where the player's feet are. */
|
|
856
917
|
readonly playerPosition: Vec3$1;
|
|
918
|
+
/** The knock of a blast on the player while it lasts (thrown, down, getting up), or null on its feet. */
|
|
919
|
+
readonly playerKnock: Readonly<Knock> | null;
|
|
857
920
|
/** Grab what the camera looks at (or drop what is held). */
|
|
858
921
|
grab(): boolean;
|
|
859
922
|
/**
|
|
@@ -888,11 +951,12 @@ interface TestRoom {
|
|
|
888
951
|
/** Everything the inspector panel shows for the aimed part (state, joints and the tools that undo them), or null. */
|
|
889
952
|
inspectInfo(): InspectInfo | null;
|
|
890
953
|
spawned(): SpawnedObject[];
|
|
891
|
-
/** Advance one frame
|
|
954
|
+
/** Advance one frame, and throw what a system threw in it. The host that owns the loop must call it every frame: the deferred queues lent to the room's budget (sound voices, destruction events) drain only inside a frame. */
|
|
892
955
|
update(dt: number): void;
|
|
893
956
|
/** Advance frames until the tool in hand has no phase left (the draw `setTool` plays, a reload, a cycle) or `maxSeconds` pass; plus one frame so the next pull is not inside the phase; returns the seconds waited. */
|
|
894
957
|
waitUntilReady(maxSeconds?: number): number;
|
|
895
|
-
|
|
958
|
+
/** `footfall`: a foot of the player's body touched the ground (`{ foot, gait, time }`), the moment its footstep sounds. */
|
|
959
|
+
on(type: 'spawn' | 'tool' | 'grab' | 'throw' | 'event' | 'camera' | 'footfall', fn: (data: unknown) => void): () => void;
|
|
896
960
|
/** Tilt the held item by `rad` radians around its own x axis (hold Z in the room). Pouring and spilling follow from the tilt. */
|
|
897
961
|
tilt(rad: number): void;
|
|
898
962
|
/** Open or close the tap over the table (default: toggle). Returns whether it is open. */
|
|
@@ -939,6 +1003,10 @@ interface TestRoom {
|
|
|
939
1003
|
openAreaAsync(group: string): Promise<SpawnedObject[]>;
|
|
940
1004
|
/** The loading indicator of the room: `begin`, `busy`, `state`, `on` (see `RoomLoading`); modules get it as `ModuleHost.loading`. */
|
|
941
1005
|
readonly loading: RoomLoading;
|
|
1006
|
+
/** The player's graphics settings (`options.graphics`): presets, options, the automatic mode, the calibration; null without them. */
|
|
1007
|
+
readonly graphics: GraphicsController | null;
|
|
1008
|
+
/** The graphics screen (open, close, toggle); null without settings or without the panels. */
|
|
1009
|
+
readonly graphicsScreen: GraphicsScreen | null;
|
|
942
1010
|
/** `loading.busy`: shows the indicator, waits for it to be painted, runs `work` and takes it down. The way to run a slow, synchronous job. */
|
|
943
1011
|
busy<T>(label: string, work: (task: BusyTask) => T | Promise<T>, options?: BusyOptions): Promise<T>;
|
|
944
1012
|
/** The scenarios the panel offers: the built-in `SCENARIOS` in the room locale plus `TestRoomOptions.scenarios`. */
|
|
@@ -1024,6 +1092,8 @@ interface TestRoom {
|
|
|
1024
1092
|
room: Partial<Record<RoomMetricId, number>>;
|
|
1025
1093
|
module: Record<string, number | string>;
|
|
1026
1094
|
};
|
|
1095
|
+
/** What the frame scheduler measured: ms per phase of the last frame, substeps, and per deferred queue the work waiting, run, forced and the most frames anything waited. */
|
|
1096
|
+
frameStats?(): SchedulerStats;
|
|
1027
1097
|
dispose(): void;
|
|
1028
1098
|
}
|
|
1029
1099
|
/** What `TestRoom.loadModule` did. */
|
|
@@ -1141,10 +1211,9 @@ interface ScenarioReport {
|
|
|
1141
1211
|
}>;
|
|
1142
1212
|
}
|
|
1143
1213
|
|
|
1144
|
-
/**
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
*/
|
|
1214
|
+
/** What the trigger answered to `TestRoom.use`: the status of the weapons package's trigger. */
|
|
1215
|
+
type UseStatus = TriggerResult['status'];
|
|
1216
|
+
|
|
1148
1217
|
declare function createTestRoom(options: TestRoomOptions): TestRoom;
|
|
1149
1218
|
|
|
1150
1219
|
/** Spec of the brick target wall: `cols` x `rows` brick panels, the bottom row anchored, mortar joints between neighbours. */
|
|
@@ -1187,4 +1256,4 @@ declare function encodeBenchState(controls: readonly BenchControl[], layers: rea
|
|
|
1187
1256
|
/** Reads an encoded state as hostile input: unknown ids, NaN, options not offered and malformed pairs are dropped; numbers are clamped. */
|
|
1188
1257
|
declare function decodeBenchState(encoded: string, controls: readonly ModuleControl[], layers: readonly ModuleLayer[]): Map<string, ControlValue>;
|
|
1189
1258
|
|
|
1190
|
-
export { type AnimationInfo, type BenchControl, type BenchHandle, type BenchLayer, type BuildFromSpecOptions, type CameraMode, DEFAULT_HAND_STANCES, DEFAULT_STRIKE_CLIPS, DEFAULT_TRIALS, type HudState, type InspectInfo, type KickLeg, LOADING_CLASS, LOADING_CSS, type LoadingOptions, type LoadingState, type LogEntry, MATERIAL_COLORS, type ModuleReport, type NewEntry, type NewLogEntry, type ProjectileModel, type ProjectileQuery, type PunchHand, type RoomAvatar, type RoomAvatarState, type RoomDoorEvent, type RoomDoorState, type RoomFirstPersonState, type RoomLoading, type RoomMetricId, type RoomPushEvent, type RoomPushState, type RoomReachView, type RoomSeat, type RoomStrings, type ScenarioContext, type ScenarioReport, type SceneryObject, type SceneryTap, type SpawnedObject, type StrikeComboOption, TRIAL_KINDS, type TestRoom, type TestRoomItem, type TestRoomLocale, type TestRoomLog, type TestRoomOptions, type TestRoomScenario, type TestTable, type TestTableContext, type TestTableObject, type TestTableOptions, type TestTablePage, type ThirdPersonOptions, type ThreeNamespace, type TrialKind, type TrialTool, type WritableLog, brickWallSpec, buildFromSpec, createLoading, createLog, createTestRoom, createTestTable, decodeBenchState, encodeBenchState, fitRow, loadingMarkup, locales, nextPaint, resolveStrings, rowCentres, trialView };
|
|
1259
|
+
export { type AnimationInfo, type BenchControl, type BenchHandle, type BenchLayer, type BuildFromSpecOptions, type CameraMode, DEFAULT_HAND_STANCES, DEFAULT_STRIKE_CLIPS, DEFAULT_TRIALS, type HudState, type InspectInfo, type KickLeg, LOADING_CLASS, LOADING_CSS, type LoadingOptions, type LoadingState, type LogEntry, MATERIAL_COLORS, type ModuleReport, type NewEntry, type NewLogEntry, type ProjectileModel, type ProjectileQuery, type PunchHand, type RoomAvatar, type RoomAvatarState, type RoomDoorEvent, type RoomDoorState, type RoomFirstPersonState, type RoomGraphicsOptions, type RoomLoading, type RoomMetricId, type RoomPushEvent, type RoomPushState, type RoomReachView, type RoomSeat, type RoomStrings, type ScenarioContext, type ScenarioReport, type SceneryObject, type SceneryTap, type SpawnedObject, type StrikeComboOption, TRIAL_KINDS, type TestRoom, type TestRoomItem, type TestRoomLocale, type TestRoomLog, type TestRoomOptions, type TestRoomScenario, type TestTable, type TestTableContext, type TestTableObject, type TestTableOptions, type TestTablePage, type ThirdPersonOptions, type ThreeNamespace, type TrialKind, type TrialTool, type UseStatus, type WritableLog, brickWallSpec, buildFromSpec, createLoading, createLog, createTestRoom, createTestTable, decodeBenchState, encodeBenchState, fitRow, loadingMarkup, locales, nextPaint, resolveStrings, rowCentres, trialView };
|