466 lines
22 KiB
Markdown
466 lines
22 KiB
Markdown
# SLICE 10 — Separate child-notebook kanban and matrix views
|
||
|
||
> **State-saving rule:** update this file and `TASKS.md` after every completed
|
||
> task and whenever work pauses. Automated checks and manual Joplin acceptance
|
||
> must be recorded separately.
|
||
|
||
## Status
|
||
|
||
**IN PROGRESS.** Phases 1–6 and Phase 8 manual acceptance are complete. Phase 7
|
||
(documentation) is the only remaining phase.
|
||
|
||
## Goal
|
||
|
||
When a kanban or matrix block uses `scope: children` with `group: notebook`,
|
||
render a separate complete view for the root notebook and each descendant notebook that owns eligible
|
||
cards. This keeps large notebook trees browsable without nesting subsections
|
||
inside one board or matrix.
|
||
|
||
## Confirmed behavior
|
||
|
||
- Multi-view rendering requires both the literal `scope: children` keyword and
|
||
`group: notebook`.
|
||
- `scope: children` without `group: notebook` retains the current aggregated
|
||
single view.
|
||
- `this-folder`, numeric depths (including very large values), and `scope: all`
|
||
keep their current single aggregated view.
|
||
- The root notebook gets its own view for cards it owns directly.
|
||
- Every descendant notebook gets its own view for cards it owns directly.
|
||
- Cards are not rolled up into ancestor views; each card appears exactly once.
|
||
- Empty notebook views are omitted.
|
||
- If every notebook is empty, show the existing overall empty board/matrix once.
|
||
- Each view heading uses a full notebook path so duplicate titles are clear.
|
||
- Views use deterministic depth-first tree order: root first, then descendants;
|
||
siblings sort case-insensitively by title with folder ID as a stable tie-breaker.
|
||
- Each generated view contains the normal three kanban columns or four matrix
|
||
quadrants, rather than notebook subsections inside those buckets.
|
||
- Each bucket receives independent SLICE8 visible-count state and the configured
|
||
`page-size`.
|
||
- SLICE9 normal-note cards group by `parent_id` exactly like to-do cards.
|
||
- Overall scan statistics count folders and notes once. Card totals equal the sum
|
||
of all non-empty notebook groups.
|
||
|
||
## Example
|
||
|
||
```text
|
||
Projects <- root view (direct cards only)
|
||
├── Home <- separate Home view
|
||
│ ├── Repairs <- separate Repairs view
|
||
│ └── Garden <- separate Garden view
|
||
└── Work <- separate Work view
|
||
└── Release <- separate Release view
|
||
```
|
||
|
||
If `Home` has no eligible cards, its view is omitted; `Repairs` and `Garden`
|
||
still appear if they have cards.
|
||
|
||
## Architecture and data flow
|
||
|
||
```text
|
||
parse scope
|
||
children + group: notebook -> scopeDepth: Infinity + groupByNotebook: true
|
||
all other combinations -> existing depth + groupByNotebook: false
|
||
|
|
||
v
|
||
resolve root notebook + ordered scoped folder metadata
|
||
|
|
||
v
|
||
collector scans each folder once
|
||
single mode -> existing aggregate board/matrix
|
||
grouped mode -> one exact-owner board/matrix per folder
|
||
|
|
||
v
|
||
plugin payload: discriminated single or notebook-grouped result
|
||
|
|
||
v
|
||
webview
|
||
single -> current component
|
||
grouped -> repeat complete component per non-empty notebook group
|
||
(each component owns independent SLICE8 state)
|
||
```
|
||
|
||
## Data-contract decision
|
||
|
||
Use a discriminated view layout instead of returning both aggregate and grouped
|
||
copies of every card:
|
||
|
||
```ts
|
||
type KanbanLayout =
|
||
| { kind: "single"; board: KanbanBoard }
|
||
| { kind: "notebooks"; groups: NotebookKanbanGroup[] };
|
||
|
||
type MatrixLayout =
|
||
| { kind: "single"; board: MatrixBoard }
|
||
| { kind: "notebooks"; groups: NotebookMatrixGroup[] };
|
||
```
|
||
|
||
Each group carries `folderId`, `notebookPath`, its board/matrix, `cardCount`, and
|
||
item-level warnings for that notebook. Config warnings, notebook-resolution
|
||
warnings, and profile-wide soft-cap warnings remain at the overall block level.
|
||
The empty grouped case carries `groups: []` and renders one existing empty state.
|
||
|
||
## Implementation plan
|
||
|
||
### Phase 1 — Preserve the explicit grouping intent
|
||
|
||
- [x] Add `groupByNotebook: boolean` to `KanbanConfig` and `MatrixConfig`
|
||
in `src/Gtd/types.ts`.
|
||
- [x] Recognize `group: notebook` in both parsers.
|
||
- [x] Set `scopeDepth = Infinity` for literal `scope: children`, preserving
|
||
its existing recursion behavior.
|
||
- [x] Set `groupByNotebook = true` only when literal `scope: children` and
|
||
`group: notebook` appear together.
|
||
- [x] Default `groupByNotebook` to false, including `scope: children` without
|
||
the grouping option.
|
||
- [x] Keep `this-folder`, numeric depth, invalid-value fallback, and
|
||
`scope: all` parsing unchanged.
|
||
- [x] Warn and remain non-grouped when `group: notebook` is combined with
|
||
another scope, or when `group:` has an unsupported value.
|
||
- [x] Add parser tests covering the grouped combination and every non-grouped
|
||
scope form.
|
||
|
||
A boolean is deliberately preferred over a broad scope-enum refactor: existing
|
||
collectors still need `scopeDepth` and `scopeAll`, while this slice needs only
|
||
one additional rendering decision.
|
||
|
||
### Phase 1 completion record
|
||
|
||
- Kanban and matrix configs now preserve explicit notebook-grouping intent
|
||
independently of recursive scope depth.
|
||
- Existing `scope: children` dashboards remain aggregated unless they opt in
|
||
with `group: notebook`.
|
||
- Focused validation: 4 suites and 104 tests passed.
|
||
- Full validation: 14 suites and 205 tests passed.
|
||
- TypeScript, whitespace, and prohibited-reference checks passed.
|
||
- No manual Joplin test is required for this parser-only phase.
|
||
|
||
### Phase 2 — Ordered notebook metadata helper
|
||
|
||
- [x] Extend `folderScope.ts` or add a focused `folderTree.ts` helper that returns
|
||
scoped folder metadata rather than only IDs when grouping is requested.
|
||
- [x] Include `id`, `parentId`, display title, and full path for the resolved root
|
||
and every descendant.
|
||
- [x] Build paths from the actual notebook tree, including ancestors above a
|
||
`notebook:`-selected root so headings remain unambiguous.
|
||
- [x] Order root first, then perform depth-first traversal with siblings sorted
|
||
by case-insensitive title and folder ID tie-breaker.
|
||
- [x] Handle missing/empty titles with a stable documented fallback such as
|
||
`Untitled notebook` while retaining the folder ID tie-breaker.
|
||
- [x] Defend against malformed folder data (orphan parent references and cycles)
|
||
without hanging; keep every reachable scoped folder at most once.
|
||
- [x] Leave `resolveScopedFolderIds` behavior intact for calendars, Gantt, and
|
||
non-grouped views.
|
||
|
||
### Phase 2 completion record
|
||
|
||
- Added `folderTree.ts` with typed scoped-folder metadata: folder ID, parent ID,
|
||
display title, and full notebook path.
|
||
- Ordering is deterministic root-first depth-first; siblings sort by
|
||
case-insensitive display title and then folder ID.
|
||
- Notebook-selected roots retain real ancestor paths above the selected root.
|
||
- Blank titles use `Untitled notebook`.
|
||
- Missing roots return no metadata; orphan roots remain usable; visited guards
|
||
prevent cycles and duplicate traversal.
|
||
- The legacy `resolveScopedFolderIds` implementation and output remain unchanged.
|
||
- Focused validation: 4 suites and 52 tests passed.
|
||
- Full validation: 15 suites and 214 tests passed.
|
||
- TypeScript, whitespace, and prohibited-reference checks passed.
|
||
- No manual Joplin test is required for this pure metadata phase.
|
||
|
||
### Phase 3 — Grouped collector contracts
|
||
|
||
- [x] Add shared notebook-view metadata types plus `KanbanLayout` and
|
||
`MatrixLayout` discriminated unions in `src/Gtd/types.ts` or collector-local
|
||
result types where appropriate.
|
||
- [x] Refactor kanban collection so each eligible card is appended to the board
|
||
associated with the current scanned `folderId` when grouping is enabled.
|
||
- [x] Apply done-window filtering and sort each kanban group's columns using the
|
||
existing logic.
|
||
- [x] Refactor matrix collection equivalently and sort each group's quadrants.
|
||
- [x] Attach malformed-block/item warnings to the owning notebook group.
|
||
- [x] Omit groups whose final `cardCount` is zero, including groups emptied by
|
||
done-window or eligibility filtering.
|
||
- [x] Retain the current aggregate path and result behavior when grouping is off.
|
||
- [x] Compute overall `scannedFolders`, `scannedNotes`, and `cardCount` once,
|
||
without summing repeated scans or duplicating cards.
|
||
- [x] Ensure the host view note is excluded before group counts are finalized.
|
||
|
||
### Phase 3 completion record
|
||
|
||
- Added shared notebook-view metadata plus discriminated single/notebook layouts
|
||
for kanban and matrix results. The existing top-level board remains a temporary
|
||
empty alias in grouped mode so later payload consumers could migrate cleanly
|
||
without duplicating cards. The alias was removed after the Phase 5 webview
|
||
migration.
|
||
- Grouped collectors scan every scoped folder once, bucket cards by the folder
|
||
currently being scanned, apply existing filtering and sorting per group, and
|
||
preserve the aggregate collector path when grouping is disabled.
|
||
- Empty groups are omitted after filtering. Item warnings remain with their
|
||
owning non-empty group; overall folder, note, and card totals count unique
|
||
scans/cards once.
|
||
- Added exact-owner coverage for root/child/grandchild cards, mixed notes and
|
||
to-dos, host-note exclusion, empty groups, done-window removal, group-local
|
||
warnings, ordering, sorting, both matrix modes, and single-layout regressions.
|
||
- Focused validation: 4 suites and 110 tests passed.
|
||
- Full validation: 15 suites and 219 tests passed.
|
||
- Production TypeScript/webpack build and `git diff --check` passed; the package
|
||
was created at `publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl`.
|
||
- No manual Joplin test is required for this collector-contract phase; grouped
|
||
payload and visual acceptance remain in Phases 4–8.
|
||
|
||
### Phase 4 — Plugin payloads and warning ownership
|
||
|
||
- [x] Update `handleGetKanban` and `handleGetMatrix` in `src/index.ts` to return
|
||
the discriminated layout plus SLICE8 `pageSize`.
|
||
- [x] Keep config warnings, notebook-resolution warnings, config parse errors,
|
||
and `scope: all` soft-cap warnings at the overall block level.
|
||
- [x] Send item-level warnings inside their notebook group in grouped mode.
|
||
- [x] Preserve the current top-level warning array in single mode.
|
||
- [x] Return a structurally valid empty layout when the source note cannot be
|
||
resolved.
|
||
- [x] Keep overall statistics visible once per source block; optionally show a
|
||
compact per-notebook card count in each generated heading, but do not add
|
||
separate scan totals that could imply folders were scanned repeatedly.
|
||
|
||
### Phase 4 completion record
|
||
|
||
- Kanban and matrix handlers now send the collector's discriminated `layout`
|
||
together with normalized `pageSize`, one overall statistics object, and the
|
||
existing global configuration fields.
|
||
- Missing-source responses use the requested single/notebook discriminator and
|
||
return a structurally valid empty layout, including matrix labels and scope
|
||
metadata.
|
||
- Configuration, YAML parse, notebook-resolution, and soft-cap warnings remain
|
||
overall. Single-mode item warnings retain the top-level warning path; grouped
|
||
item warnings remain inside their exact-owner notebook group.
|
||
- A temporary legacy `board` alias kept the single-view webview working during
|
||
this phase. It was removed in Phase 5 after the webview migrated to `layout`;
|
||
grouped mode never duplicated cards into an aggregate payload.
|
||
- Added pure payload-boundary helpers and tests for all missing-source layouts
|
||
and the no-aggregate compatibility behavior.
|
||
- Focused validation: 3 suites and 83 tests passed.
|
||
- Full validation: 16 suites and 221 tests passed.
|
||
- TypeScript with `--skipLibCheck`, `git diff --check`, and the production
|
||
webpack/JPL build passed. The current artifact is
|
||
`publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl`.
|
||
- No manual Joplin test is required for this payload-only phase; rendering and
|
||
manual acceptance remain in Phases 5–8.
|
||
|
||
### Phase 5 — Webview component reuse
|
||
|
||
- [x] Separate the existing kanban wrapper concerns (overall title, errors,
|
||
global warnings, stats) from rendering one kanban board component.
|
||
- [x] Do the same for one matrix component.
|
||
- [x] In single mode, render exactly one component with current markup and visual
|
||
behavior.
|
||
- [x] In grouped mode, iterate groups in payload order and render one full
|
||
component per group beneath a notebook-path heading.
|
||
- [x] Render each group's item warnings adjacent to that group.
|
||
- [x] Reuse the SLICE8 incremental-list helper inside every component; closure
|
||
state must not be shared between groups or buckets.
|
||
- [x] When `groups` is empty, render the existing empty board/matrix once rather
|
||
than showing a blank block.
|
||
- [x] Add only the spacing/heading CSS required to distinguish notebook views;
|
||
preserve column and matrix layout styles.
|
||
|
||
### Phase 5 completion record
|
||
|
||
- Split kanban and matrix rendering into overall wrappers plus reusable
|
||
one-board/one-matrix component functions. Single layouts retain the existing
|
||
component markup and visual behavior.
|
||
- Notebook layouts render every non-empty group in collector order beneath its
|
||
full notebook path, with item warnings adjacent to the owning view.
|
||
- Every generated component calls the existing SLICE8 incremental-list helper
|
||
separately for each column/quadrant, giving every bucket independent closure
|
||
state and the configured `pageSize`.
|
||
- Empty notebook layouts render one ordinary empty board or matrix, preserving
|
||
the established overall empty presentation.
|
||
- Removed the temporary top-level `board` payload alias. The webview consumes
|
||
`layout` directly, retaining only a defensive fallback for stale payloads.
|
||
- Added only shared notebook-view spacing and heading styles; existing board,
|
||
matrix, card, and batching styles remain unchanged.
|
||
- Full validation: JavaScript syntax, TypeScript with `--skipLibCheck`,
|
||
`git diff --check`, 16 suites/220 tests, and the production webpack/JPL build
|
||
all passed. The current artifact is
|
||
`publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl`.
|
||
- Browser-only interaction testing remains deliberately manual because the
|
||
repository has no DOM harness; Phase 6 records that boundary explicitly.
|
||
|
||
### Phase 6 — Automated tests
|
||
|
||
#### Scope/parser tests
|
||
|
||
- [x] `children` sets infinite depth plus grouping.
|
||
- [x] Numeric depth remains non-grouped, including a numeric string.
|
||
- [x] `this-folder`, invalid scope, and omitted scope remain non-grouped.
|
||
- [x] `scope: all` remains non-grouped and retains notebook-conflict warnings.
|
||
|
||
#### Folder-tree tests
|
||
|
||
- [x] Root plus multiple children and grandchildren.
|
||
- [x] Deterministic depth-first order regardless of input folder order.
|
||
- [x] Case-insensitive sibling ordering and folder-ID tie-breaker.
|
||
- [x] Duplicate titles represented by unambiguous full paths.
|
||
- [x] A `notebook:`-selected child root with its ancestor path retained.
|
||
- [x] Empty titles, orphan parents, and cycle protection.
|
||
|
||
#### Kanban collector tests
|
||
|
||
- [x] Root-owned and descendant-owned cards appear in separate exact-owner groups.
|
||
- [x] Every card appears once with no ancestor rollup.
|
||
- [x] Empty groups are omitted while non-empty grandchildren remain.
|
||
- [x] Done-window filtering can remove an otherwise non-empty group.
|
||
- [x] Per-group sorting and warnings are correct.
|
||
- [x] SLICE9 note and to-do cards group identically.
|
||
- [x] Aggregate stats and card totals are not double-counted.
|
||
- [x] Non-grouped scope results remain unchanged.
|
||
|
||
#### Matrix collector tests
|
||
|
||
- [x] Repeat exact-owner, omission, sorting, warning, mixed-card, and total-count
|
||
coverage for Skeleton and Eisenhower modes.
|
||
- [x] Confirm all four quadrants remain local to their owning notebook group.
|
||
- [x] Confirm non-grouped scope results remain unchanged.
|
||
|
||
#### Payload/rendering contracts
|
||
|
||
- [x] Test single and grouped payload construction at the thinnest practical
|
||
boundary without adding a new browser-test dependency solely for this slice.
|
||
- [x] If SLICE8 introduced reusable DOM tests, extend them to prove independent
|
||
visible counts across notebook components; otherwise cover this manually.
|
||
- [x] Run focused parser, folder-tree, kanban, and matrix tests.
|
||
- [x] Run the complete Jest suite and record suite/test totals.
|
||
- [x] Run `npm run dist` and record the produced `.jpl` path.
|
||
- [x] Run `git diff --check` and the prohibited-reference audit.
|
||
|
||
### Phase 6 completion record
|
||
|
||
- Parser coverage now explicitly locks literal `children` grouping, numeric and
|
||
default non-grouped scopes, invalid fallbacks, and `scope: all` notebook
|
||
conflict warnings for both kanban and matrix.
|
||
- Existing folder-tree coverage proves root/descendant traversal, deterministic
|
||
ordering, duplicate and blank titles, selected-root ancestor paths, orphans,
|
||
cycles, and unchanged legacy ID-only scope behavior.
|
||
- Collector coverage now includes exact ownership, no rollups, empty-group and
|
||
done-window omission, local sorting/warnings, mixed cards, unique totals, all
|
||
four local quadrants in both matrix modes, and single-layout regressions for
|
||
`this-folder`, numeric depth, recursive children, and `scope: all`.
|
||
- Pure layout helpers cover valid empty single/grouped payload construction.
|
||
The repository still has no DOM harness, so independent click-state remains
|
||
an explicit Phase 8 manual acceptance check rather than a test-only browser
|
||
abstraction.
|
||
- Focused validation: 5 suites and 121 tests passed.
|
||
- Full validation: 16 suites and 230 tests passed.
|
||
- JavaScript syntax, TypeScript with `--skipLibCheck`, `git diff --check`, and
|
||
the prohibited-reference audit passed.
|
||
- `npm run dist` produced
|
||
`publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl` (163,328 bytes,
|
||
SHA-256 `cc5eddd2dcd74453e5ebd2c2fd4635cb34eb5996bf736efd54441931f2a54930`).
|
||
The five-file tar archive was inspected and contains the grouped notebook-view
|
||
runtime markers.
|
||
- No manual Joplin acceptance was performed; that remains Phase 8.
|
||
|
||
### Phase 7 — Documentation
|
||
|
||
- [ ] Update README.md to state that `scope: children` plus `group: notebook`
|
||
produces separate notebook views for kanban and matrix blocks.
|
||
- [ ] Add a parent/child/grandchild example showing root ownership, omitted empty
|
||
notebooks, full-path headings, and no rollups.
|
||
- [ ] State that ungrouped `children`, numeric depth, and `scope: all` remain
|
||
aggregated.
|
||
- [ ] Explain that every generated bucket has independent SLICE8 expansion state.
|
||
- [ ] Explain that SLICE9 notes group by their owning notebook.
|
||
- [ ] Update SPEC.md scope parsing, folder traversal, layout payloads, warning
|
||
ownership, statistics, and rendering flow.
|
||
- [ ] Add an unreleased SLICE10 entry to CHANGELOG.md without changing the
|
||
package version until release scope is decided.
|
||
|
||
### Phase 8 — Manual Joplin acceptance
|
||
|
||
Create a root notebook containing direct cards, multiple children, grandchildren,
|
||
duplicate child titles under different parents, empty notebooks, and more than
|
||
one SLICE8 batch in at least two generated views. Include SLICE9 notes and to-dos.
|
||
|
||
- [x] Confirm root-owned cards render only in the root view.
|
||
- [x] Confirm every descendant card renders only in its owning notebook view.
|
||
- [x] Confirm empty notebooks are omitted but non-empty descendants still appear.
|
||
- [x] Confirm full paths distinguish duplicate titles.
|
||
- [x] Confirm view ordering is stable and matches the documented traversal.
|
||
- [x] Confirm both matrix modes create separate complete matrices.
|
||
- [x] Confirm per-group warnings appear with the correct notebook.
|
||
- [x] Confirm overall statistics equal the unique scanned/card totals.
|
||
- [x] Confirm independent `page-size` limits and "List more" state across groups,
|
||
buckets, and multiple source blocks.
|
||
- [x] Confirm reload resets all expanded buckets.
|
||
- [x] Confirm `this-folder`, numeric depths, and `scope: all` still render one
|
||
aggregated view.
|
||
- [x] Confirm notebook targeting plus `scope: children` roots grouping at the
|
||
resolved target and uses correct full paths.
|
||
- [x] Confirm sorting, styling, navigation, completion, recurrence, and note-card
|
||
behavior do not regress.
|
||
- [x] Record user sign-off here; do not mark manual acceptance complete before
|
||
confirmation.
|
||
|
||
### Phase 8 acceptance record
|
||
|
||
- **PASSED — USER SIGN-OFF RECEIVED 2026-07-28.** The user confirmed that all
|
||
Phase 8 manual tests passed against the current production JPL.
|
||
- Accepted workflows include exact root/descendant ownership, no rollups or
|
||
duplication, empty-group handling, full-path headings, deterministic order,
|
||
both matrix modes, warning/statistics ownership, independent batching across
|
||
groups and blocks, reload reset, notebook targeting, and all non-grouped scope
|
||
regressions.
|
||
- Sorting, styling, navigation, completion, recurrence, mixed note/to-do cards,
|
||
hover/focus controls, and configured page sizes were also manually accepted.
|
||
- This manual acceptance is recorded separately from Phase 6 automated
|
||
validation. Phase 7 documentation remains pending.
|
||
|
||
## Acceptance criteria
|
||
|
||
SLICE10 is complete only when:
|
||
|
||
- Literal `scope: children` renders separate root/descendant views with every
|
||
eligible card present exactly once in its owning notebook.
|
||
- Empty groups are omitted, headings are unambiguous, and ordering is stable.
|
||
- SLICE8 state is independent per bucket and SLICE9 cards group correctly.
|
||
- Warnings and statistics are correctly owned and never double-counted.
|
||
- Every other scope form retains its prior single-view behavior.
|
||
- Focused tests, the full suite, and the production package build pass.
|
||
- Manual Joplin acceptance is explicitly confirmed.
|
||
|
||
## Files expected to change
|
||
|
||
- `src/Gtd/types.ts`
|
||
- `src/Gtd/parseKanbanConfig.ts`
|
||
- `src/Gtd/parseMatrixConfig.ts`
|
||
- `src/Gtd/folderScope.ts` and/or a new `src/Gtd/folderTree.ts`
|
||
- `src/Gtd/collectKanban.ts`
|
||
- `src/Gtd/collectMatrix.ts`
|
||
- `src/index.ts`
|
||
- `src/gtd-calendar-webview.js`
|
||
- `src/event-calendar.css`
|
||
- `src/tests/Gtd/kanban.test.ts`
|
||
- `src/tests/Gtd/matrix.test.ts`
|
||
- `src/tests/Gtd/resolveNotebook.test.ts` and/or a new folder-tree test file
|
||
- `README.md`
|
||
- `SPEC.md`
|
||
- `CHANGELOG.md`
|
||
- `SLICE10.md`
|
||
- `TASKS.md`
|
||
|
||
## Out of scope
|
||
|
||
- Grouping numeric-depth or `scope: all` results.
|
||
- Ancestor rollups or duplicated cards across parent/child views.
|
||
- Nested notebook subsections inside a single kanban or matrix.
|
||
- Persisting expanded/collapsed notebook-view state.
|
||
- Notebook-level filtering controls or user-selectable grouping modes.
|
||
- Applying notebook grouping to calendar or Gantt views.
|
||
|
||
## Dependencies and resume point
|
||
|
||
Implement after SLICE8 and SLICE9 are complete. Start by preserving
|
||
`groupByNotebook` in parser tests, then build and test ordered folder metadata.
|
||
Introduce discriminated collector layouts before changing the webview. Complete
|
||
single-view regression tests before grouped manual acceptance.
|