@davmash/bygone 0.8.14 → 0.9.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davmash/bygone",
3
- "version": "0.8.14",
3
+ "version": "0.9.2",
4
4
  "description": "See how change happened. Visual diff and file history.",
5
5
  "author": "David Mashburn",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  "electron"
41
41
  ],
42
42
  "dependencies": {
43
- "electron": "^43.1.1",
43
+ "electron": "^43.7.6",
44
44
  "electron-updater": "^6.8.9",
45
45
  "js-yaml": "^4.3.0"
46
46
  }
@@ -7,7 +7,7 @@
7
7
  "additionalProperties": false,
8
8
  "required": ["version", "anchors", "connections", "chapters"],
9
9
  "properties": {
10
- "version": { "const": 1 },
10
+ "version": { "enum": [1, 2, 3] },
11
11
  "title": { "$ref": "#/$defs/nonEmptyString" },
12
12
  "windowTitle": {
13
13
  "$ref": "#/$defs/nonEmptyString",
@@ -34,6 +34,7 @@
34
34
  }
35
35
  }
36
36
  },
37
+ "review": { "$ref": "#/$defs/review" },
37
38
  "anchors": {
38
39
  "type": "object",
39
40
  "propertyNames": { "minLength": 1 },
@@ -56,10 +57,77 @@
56
57
  "type": "array",
57
58
  "minItems": 1,
58
59
  "items": { "$ref": "#/$defs/chapter" }
60
+ },
61
+ "tours": {
62
+ "type": "object",
63
+ "additionalProperties": false,
64
+ "minProperties": 1,
65
+ "properties": {
66
+ "historical": { "$ref": "#/$defs/historicalTour" },
67
+ "deconstructed": { "$ref": "#/$defs/deconstructedTour" }
68
+ }
59
69
  }
60
70
  },
71
+ "allOf": [
72
+ {
73
+ "if": { "properties": { "version": { "enum": [1, 2] } }, "required": ["version"] },
74
+ "then": {
75
+ "not": { "anyOf": [{ "required": ["tours"] }, { "required": ["review"] }] },
76
+ "properties": {
77
+ "chapters": {
78
+ "items": {
79
+ "properties": {
80
+ "scenes": {
81
+ "items": { "not": { "required": ["overview"] } }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ },
89
+ {
90
+ "if": { "properties": { "version": { "const": 1 } }, "required": ["version"] },
91
+ "then": {
92
+ "properties": {
93
+ "chapters": {
94
+ "items": {
95
+ "properties": {
96
+ "scenes": {
97
+ "items": {
98
+ "if": { "properties": { "kind": { "const": "stacked-diff" } }, "required": ["kind"] },
99
+ "then": { "properties": { "stack": { "minItems": 3 } } }
100
+ }
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ },
108
+ {
109
+ "if": { "properties": { "version": { "enum": [2, 3] } }, "required": ["version"] },
110
+ "then": {
111
+ "properties": {
112
+ "chapters": {
113
+ "items": {
114
+ "properties": {
115
+ "scenes": {
116
+ "items": {
117
+ "if": { "properties": { "kind": { "const": "deconstructed-diff" } }, "required": ["kind"] },
118
+ "then": { "required": ["stack", "steps"] }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+ ],
61
128
  "$defs": {
62
129
  "nonEmptyString": { "type": "string", "minLength": 1 },
130
+ "reviewString": { "type": "string", "minLength": 1, "pattern": "\\S" },
63
131
  "stringArray": {
64
132
  "type": "array",
65
133
  "items": { "type": "string" }
@@ -106,6 +174,97 @@
106
174
  "takeaway": { "$ref": "#/$defs/nonEmptyString" }
107
175
  }
108
176
  },
177
+ "sceneOverview": {
178
+ "type": "object",
179
+ "additionalProperties": false,
180
+ "required": ["kind"],
181
+ "properties": {
182
+ "kind": { "const": "directory-diff" },
183
+ "comparison": {
184
+ "type": "object",
185
+ "additionalProperties": false,
186
+ "required": ["from", "to"],
187
+ "properties": {
188
+ "from": { "$ref": "#/$defs/nonEmptyString" },
189
+ "to": { "$ref": "#/$defs/nonEmptyString" }
190
+ }
191
+ },
192
+ "path": {
193
+ "type": "string",
194
+ "minLength": 1,
195
+ "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.(?:/|$)).*$"
196
+ }
197
+ }
198
+ },
199
+ "requirement": {
200
+ "type": "object",
201
+ "additionalProperties": false,
202
+ "required": ["id", "text"],
203
+ "properties": {
204
+ "id": { "$ref": "#/$defs/nonEmptyString" },
205
+ "text": { "$ref": "#/$defs/nonEmptyString" },
206
+ "status": { "enum": ["fulfilled", "gap"] },
207
+ "source": { "$ref": "#/$defs/nonEmptyString" },
208
+ "confidence": { "enum": ["high", "medium", "low"] }
209
+ }
210
+ },
211
+ "review": {
212
+ "type": "object",
213
+ "additionalProperties": false,
214
+ "required": ["baseOid", "headOid", "items"],
215
+ "properties": {
216
+ "baseOid": { "$ref": "#/$defs/fullGitOid" },
217
+ "headOid": { "$ref": "#/$defs/fullGitOid" },
218
+ "items": {
219
+ "type": "array",
220
+ "minItems": 1,
221
+ "items": { "$ref": "#/$defs/reviewItem" }
222
+ }
223
+ }
224
+ },
225
+ "fullGitOid": {
226
+ "type": "string",
227
+ "pattern": "^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$"
228
+ },
229
+ "reviewItem": {
230
+ "type": "object",
231
+ "additionalProperties": false,
232
+ "required": ["id", "kind", "title", "body", "evidence"],
233
+ "properties": {
234
+ "id": { "$ref": "#/$defs/reviewString" },
235
+ "kind": { "enum": ["concept", "boundary", "tradeoff", "question"] },
236
+ "title": { "$ref": "#/$defs/reviewString" },
237
+ "body": { "$ref": "#/$defs/reviewString" },
238
+ "evidence": {
239
+ "type": "array",
240
+ "items": { "$ref": "#/$defs/reviewEvidence" }
241
+ },
242
+ "nextCheck": { "$ref": "#/$defs/reviewString" }
243
+ },
244
+ "allOf": [
245
+ {
246
+ "if": {
247
+ "properties": { "kind": { "const": "question" } },
248
+ "required": ["kind"]
249
+ },
250
+ "then": { "required": ["nextCheck"] },
251
+ "else": {
252
+ "properties": {
253
+ "evidence": { "minItems": 1 }
254
+ }
255
+ }
256
+ }
257
+ ]
258
+ },
259
+ "reviewEvidence": {
260
+ "type": "object",
261
+ "additionalProperties": false,
262
+ "required": ["sceneId", "stepId"],
263
+ "properties": {
264
+ "sceneId": { "$ref": "#/$defs/reviewString" },
265
+ "stepId": { "$ref": "#/$defs/reviewString" }
266
+ }
267
+ },
109
268
  "step": {
110
269
  "type": "object",
111
270
  "additionalProperties": false,
@@ -116,7 +275,8 @@
116
275
  "body": { "$ref": "#/$defs/nonEmptyString" },
117
276
  "focus": { "$ref": "#/$defs/nonEmptyString" },
118
277
  "connection": { "$ref": "#/$defs/nonEmptyString" },
119
- "depth": { "enum": ["mentioned", "explained", "contextualized"] }
278
+ "depth": { "enum": ["mentioned", "explained", "contextualized"] },
279
+ "requirement": { "$ref": "#/$defs/requirement" }
120
280
  }
121
281
  },
122
282
  "coverageExclusion": {
@@ -138,11 +298,13 @@
138
298
  "required": ["id", "title", "summary", "bullets", "tags", "takeaway", "steps"],
139
299
  "properties": {
140
300
  "id": { "$ref": "#/$defs/nonEmptyString" },
301
+ "kind": { "const": "walkthrough" },
141
302
  "title": { "$ref": "#/$defs/nonEmptyString" },
142
303
  "summary": { "$ref": "#/$defs/nonEmptyString" },
143
304
  "bullets": { "$ref": "#/$defs/stringArray" },
144
305
  "tags": { "$ref": "#/$defs/stringArray" },
145
306
  "takeaway": { "$ref": "#/$defs/nonEmptyString" },
307
+ "overview": { "allOf": [{ "$ref": "#/$defs/sceneOverview" }, { "not": { "required": ["comparison"] } }] },
146
308
  "steps": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/step" } }
147
309
  }
148
310
  }
@@ -194,7 +356,8 @@
194
356
  "bullets": { "$ref": "#/$defs/stringArray" },
195
357
  "tags": { "$ref": "#/$defs/stringArray" },
196
358
  "takeaway": { "$ref": "#/$defs/nonEmptyString" },
197
- "stack": { "type": "array", "minItems": 3, "maxItems": 6, "items": { "$ref": "#/$defs/stackEntry" } },
359
+ "overview": { "$ref": "#/$defs/sceneOverview" },
360
+ "stack": { "type": "array", "minItems": 2, "maxItems": 6, "items": { "$ref": "#/$defs/stackEntry" } },
198
361
  "files": { "$ref": "#/$defs/stringArray" },
199
362
  "steps": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/stackStep" } }
200
363
  }
@@ -253,8 +416,11 @@
253
416
  "bullets": { "$ref": "#/$defs/stringArray" },
254
417
  "tags": { "$ref": "#/$defs/stringArray" },
255
418
  "takeaway": { "$ref": "#/$defs/nonEmptyString" },
419
+ "overview": { "$ref": "#/$defs/sceneOverview" },
256
420
  "base": { "$ref": "#/$defs/nonEmptyString" },
257
421
  "target": { "$ref": "#/$defs/nonEmptyString" },
422
+ "stack": { "type": "array", "minItems": 2, "maxItems": 6, "items": { "$ref": "#/$defs/stackEntry" } },
423
+ "steps": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/step" } },
258
424
  "stages": {
259
425
  "type": "array",
260
426
  "minItems": 1,
@@ -286,6 +452,59 @@
286
452
  }
287
453
  }
288
454
  }
455
+ },
456
+ "historicalTour": {
457
+ "type": "object",
458
+ "additionalProperties": false,
459
+ "required": ["chapters"],
460
+ "properties": {
461
+ "chapters": {
462
+ "type": "array",
463
+ "minItems": 1,
464
+ "items": { "$ref": "#/$defs/historicalChapter" }
465
+ }
466
+ }
467
+ },
468
+ "historicalChapter": {
469
+ "type": "object",
470
+ "additionalProperties": false,
471
+ "required": ["id", "title", "scenes"],
472
+ "properties": {
473
+ "id": { "$ref": "#/$defs/nonEmptyString" },
474
+ "title": { "$ref": "#/$defs/nonEmptyString" },
475
+ "scenes": {
476
+ "type": "array",
477
+ "minItems": 1,
478
+ "items": {
479
+ "oneOf": [
480
+ { "$ref": "#/$defs/scene" },
481
+ { "$ref": "#/$defs/stackedScene" }
482
+ ]
483
+ }
484
+ }
485
+ }
486
+ },
487
+ "deconstructedTour": {
488
+ "type": "object",
489
+ "additionalProperties": false,
490
+ "required": ["chapters"],
491
+ "properties": {
492
+ "chapters": {
493
+ "type": "array",
494
+ "minItems": 1,
495
+ "items": { "$ref": "#/$defs/chapter" },
496
+ "contains": {
497
+ "type": "object",
498
+ "required": ["scenes"],
499
+ "properties": {
500
+ "scenes": {
501
+ "type": "array",
502
+ "contains": { "$ref": "#/$defs/deconstructedScene" }
503
+ }
504
+ }
505
+ }
506
+ }
507
+ }
289
508
  }
290
509
  }
291
510
  }
@@ -98,6 +98,10 @@ Do not rebuild, commit, push, publish, or open a browser unless the user request
98
98
 
99
99
  Determine the intended head and base from the request and repository state. Prefer an explicit base; do not guess when different bases would materially change the explanation.
100
100
 
101
+ Treat workspace paths named by the request as the explicit scope. The context
102
+ does not provide a path filter, so do not silently narrow or broaden that scope
103
+ based on which files seem easiest to explain; surface any scope ambiguity.
104
+
101
105
  For a hosted review, resolve both immutable endpoint OIDs from provider metadata. Never assume the current checkout is the requested review head. For GitHub:
102
106
 
103
107
  ```sh
@@ -109,9 +113,16 @@ test -n "$HEAD_OID" && test "$HEAD_OID" != null
109
113
  bygone tour context "$HEAD_OID" --base "$BASE_OID" --output /tmp/change-context.json
110
114
  ```
111
115
 
112
- Use the equivalent API or CLI fields for other providers. If you are not reviewing a hosted change, compute the merge-base against the intended integration branch and pass that exact base OID or ref. Keep the existing preference for explicit endpoints and do not guess.
116
+ Use the equivalent API or CLI fields for other providers. If the requested
117
+ endpoints are unresolved, reversed, divergent, or have multiple candidates,
118
+ stop and report the ambiguity. Never silently invent an endpoint, choose among
119
+ candidates, or substitute a merge-base. If you are not reviewing a hosted
120
+ change, compute the merge-base only when the intended integration branch is
121
+ explicit, and pass that exact base OID or ref.
113
122
 
114
- Use immutable commit IDs in the eventual tour. Dirty working-tree changes are reported but excluded from committed-range context.
123
+ Use immutable commit IDs in the eventual tour. Dirty working-tree changes and
124
+ unsaved buffers are reported separately but excluded from committed-range
125
+ context, authored evidence, and compiled source.
115
126
 
116
127
  Inspect progressively instead of loading every patch immediately:
117
128
 
@@ -164,18 +175,52 @@ Retrieve the current contract:
164
175
  bygone tour schema > /tmp/change-tour-source.schema.json
165
176
  ```
166
177
 
167
- Write a `.bygone` file. The legacy `.bygone.yaml` spelling remains valid when
168
- generic YAML tooling requires it. Treat either authored source as Git-backed,
169
- not portable: pin `range.base` and `range.head` to the exact OIDs from the
170
- context, and keep the file within the corresponding repository so Bygone can
171
- resolve those objects. Use a compiled `.tour.json` only when a portable
172
- snapshot is required.
178
+ Write a version 3 `.bygone` file for new tours. The legacy `.bygone.yaml`
179
+ spelling remains valid when generic YAML tooling requires it. Treat the
180
+ authored source and its compiled `.tour.json` as Git-backed, non-portable
181
+ artifacts: pin `range.base` and `range.head` to the exact OIDs from the
182
+ context, and keep them with the corresponding repository so Bygone can resolve
183
+ those objects and live history. Versions 1 and 2 remain readable for legacy
184
+ inputs; v3 is the format for independent authored modes, directory overviews,
185
+ and review notes.
173
186
 
174
187
  Set optional `windowTitle` when the tour should appear in the native window
175
188
  title — for example a pull request number (`PR-1234`) so multiple open tours
176
189
  stay distinguishable. When omitted, the presenter falls back to `title`.
177
190
 
178
- For every step:
191
+ ### Choose the authored modes
192
+
193
+ The root `chapters` is required and is the compatibility tour. It shares the
194
+ top-level `range`, `anchors`, and `connections` with any independent modes.
195
+ When the source supplies them, `tours.historical.chapters` and
196
+ `tours.deconstructed.chapters` are separate authored tours; keep their chapter,
197
+ scene, and step order independent rather than expecting Bygone to match content
198
+ across modes.
199
+
200
+ - **Historical** explains real revision states. Its scenes may be walkthroughs
201
+ or `stacked-diff` scenes, never `deconstructed-diff` scenes. Every stacked
202
+ panel must resolve to a real Git revision; an explicitly authored Historical
203
+ stack may contain two to six revisions, but its first and last panels must be
204
+ the resolved review base and head.
205
+ - **Deconstructed** explains the change through synthetic cumulative stages. It
206
+ must contain at least one `deconstructed-diff` scene and may include
207
+ walkthrough scenes for context or proof. A mode-specific deconstructed scene
208
+ may omit `stack` and endpoint `steps`: its stages, not Git history, define the
209
+ explanation panels.
210
+ - If a mode is omitted, v3 derives it from the root chapters by scene identity
211
+ and order. Root walkthroughs and real stacks supply Historical; root
212
+ deconstructed scenes supply Deconstructed. A root deconstructed scene enters
213
+ Historical only when it also has explicit endpoint walkthrough `steps`; a
214
+ real revision `stack` by itself is not that walkthrough. No cross-mode
215
+ correspondence is inferred from filenames or narrative text.
216
+
217
+ For a root v3 `deconstructed-diff` scene, provide both an explicit real
218
+ revision `stack` and regular endpoint `steps`. The stack is used for the real
219
+ Historical/Final fallback and must have the same base and final endpoints as
220
+ the source range; the synthetic stages remain separate. A
221
+ mode-specific Deconstructed scene may omit those fields as described above.
222
+
223
+ For every walkthrough step:
179
224
 
180
225
  - make one concise explanatory claim;
181
226
  - focus an anchor in `base` or `head` evidence;
@@ -184,6 +229,49 @@ For every step:
184
229
  - connect behavior to tests, error handling, or other concrete proof;
185
230
  - add a connection only when the relationship between two locations materially improves understanding.
186
231
 
232
+ For every `stacked-diff` step, use a real changed file and a `pair` of adjacent
233
+ stack entry IDs; use `side` or `lines` only to refine the focus. For every
234
+ deconstructed stage, assign concrete change-unit (hunk) IDs through `changes`
235
+ and build a cumulative teaching order. Assign each changed hunk exactly once,
236
+ or exclude it explicitly with a reason; unsupported, binary, and rename-path
237
+ changes generally need whole-file exclusions. Do not infer a real stack from
238
+ the synthetic stages or describe an explanation panel as a commit.
239
+
240
+ Keep deconstructed-tour coordinates distinct:
241
+
242
+ - A **stage** is an authored synthetic phase and cumulative comparison state;
243
+ it is not a Git revision.
244
+ - The presenter derives one or more navigable Deconstructed tour steps from a
245
+ stage's introduced changes. A root deconstructed scene's endpoint `steps`
246
+ are ordinary anchor-based walkthrough items for the real range, not those
247
+ synthetic stage steps.
248
+ - Do not refer to either by an unqualified ordinal such as "Stage 2" or "Step 11" in authored titles, summaries, narration, or takeaways. Prefer the stable descriptive title so the reference survives edits.
249
+ - When an ordinal is necessary, qualify the coordinate: "stage 2 of 4" versus "tour step 11 of 46."
250
+ - Treat presenter-generated labels as UI context; do not repeat them in authored prose unless the distinction itself needs explanation.
251
+
252
+ Version 3 scenes may include a directory Overview:
253
+
254
+ ```yaml
255
+ overview:
256
+ kind: directory-diff
257
+ path: web
258
+ ```
259
+
260
+ Keep `path` relative and POSIX-style; omit it or use `.` for the repository
261
+ root. Stacked and Deconstructed scenes may set `overview.comparison` to two
262
+ distinct stack-entry IDs or to `explanation-baseline` and
263
+ `explanation-stage-<stage-id>`. Walkthrough overviews always use the review's
264
+ base-to-head comparison and reject an explicit comparison.
265
+
266
+ Use the optional v3 top-level `review` block for evidence-linked concepts,
267
+ boundaries, tradeoffs, and unresolved questions instead of presenting open
268
+ questions as settled scene narration. Pin `review.baseOid` and `review.headOid`
269
+ to the resolved range. `concept`, `boundary`, and `tradeoff` items need at
270
+ least one link to a root authored walkthrough scene and step; a `question` may
271
+ have empty evidence but must provide `nextCheck`. Do not add an ad hoc `notes`
272
+ key. See `examples/bygone-history.bygone` for review notes and
273
+ `examples/navigation-lab.bygone.yaml` for independently authored v3 modes.
274
+
187
275
  Never emit generated line numbers or hunk indexes. Verify candidate snippets against the pinned object when uncertain:
188
276
 
189
277
  ```sh
@@ -212,6 +300,16 @@ Treat this as a required self-audit, not a claim the validator can prove. For ea
212
300
  - tests are connected to the behavior they prove;
213
301
  - connections express causal, contractual, data-flow, ordering, or proof relationships;
214
302
  - binary files and omitted patches are surfaced explicitly;
303
+ - every Historical tour excludes synthetic deconstructed scenes, and every
304
+ Deconstructed tour contains at least one deconstructed scene;
305
+ - deconstructed stages cover every included change unit exactly once or record
306
+ an explicit exclusion, contain no unqualified "Stage N" or "Step N"
307
+ references, and keep comparison stages distinct from navigable tour steps;
308
+ - root deconstructed scenes have the required real stack and endpoint
309
+ walkthrough evidence, while mode-specific synthetic scenes do not claim
310
+ that evidence exists;
311
+ - v3 review-note OIDs match the resolved range and evidence links resolve to
312
+ authored root walkthrough steps;
215
313
  - the final step supplies proof or a clear reviewer conclusion.
216
314
 
217
315
  ## Always print the open command
@@ -236,7 +334,7 @@ Tour tooling that does not open the app (`tour context`, `tour validate`, `tour
236
334
 
237
335
  ## Compile or present
238
336
 
239
- Compile a portable manifest when the user needs an artifact:
337
+ Compile a repository-bound manifest when the user needs an artifact:
240
338
 
241
339
  ```sh
242
340
  bygone tour compile review.bygone --output review.tour.json
@@ -259,7 +357,9 @@ Report:
259
357
  - the exact base and head OIDs;
260
358
  - the **open command** for the primary artifact (`bygone present --tour …`, `bygone review …`, `bygone --git-diff …`, etc.);
261
359
  - the source and compiled artifact paths;
262
- - authored chapter, scene, and step counts, plus compiled counts when the generated complete-change appendix changes them;
360
+ - authored root and Historical/Deconstructed chapter, scene, step, and stage
361
+ counts, plus compiled counts when generated complete-change or per-mode
362
+ scenes change them;
263
363
  - omitted or unread evidence;
264
364
  - validation and visual verification performed;
265
365
  - whether generated files are temporary, uncommitted, committed, or pushed.
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta http-equiv="Content-Security-Policy" content="default-src 'self'; base-uri 'none'; object-src 'none'; frame-src 'none'; form-action 'none'; img-src 'self' data:; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; worker-src 'self' blob:;">
6
+ <meta http-equiv="Content-Security-Policy" content="default-src 'self'; base-uri 'none'; object-src 'none'; frame-src http://127.0.0.1:*; form-action 'none'; img-src 'self' data:; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; worker-src 'self' blob:;">
7
7
  <title>Bygone</title>
8
8
  <link href="../media/webview.css" rel="stylesheet">
9
9
  </head>
@@ -168,6 +168,11 @@
168
168
  </div>
169
169
  </div>
170
170
  <div id="directory-diff" class="dir-view hidden">
171
+ <div id="directory-view-tabs" class="directory-view-tabs" hidden>
172
+ <button id="directory-overview-tab" type="button" title="Show change overview" aria-pressed="true">Overview</button>
173
+ <button id="directory-files-tab" type="button" title="Show all changed files" aria-pressed="false">Files</button>
174
+ </div>
175
+ <section id="directory-overview" class="directory-overview" aria-label="Change overview" hidden></section>
171
176
  <div class="dir-headers">
172
177
  <div class="dir-col-header" id="dir-left-header">Left</div>
173
178
  <div class="dir-header-gutter" aria-hidden="true"></div>