plainbook 0.0.8__py3-none-any.whl → 0.0.10__py3-none-any.whl
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.
- plainbook/css/main.css +1 -1
- plainbook/gemini.py +38 -16
- plainbook/js/CellInsertionZone.js +2 -2
- plainbook/js/CodeCell.js +2 -2
- plainbook/js/ExplanationEditor.js +14 -8
- plainbook/js/InfoModal.js +1 -1
- plainbook/js/InputFile.js +164 -0
- plainbook/js/NotebookCell.js +16 -3
- plainbook/js/UiError.js +10 -0
- plainbook/js/nb.js +23 -10
- plainbook/main.py +41 -0
- plainbook/plainbook.py +81 -15
- plainbook/views/index.html +89 -81
- {plainbook-0.0.8.dist-info → plainbook-0.0.10.dist-info}/METADATA +1 -1
- {plainbook-0.0.8.dist-info → plainbook-0.0.10.dist-info}/RECORD +19 -17
- {plainbook-0.0.8.dist-info → plainbook-0.0.10.dist-info}/WHEEL +0 -0
- {plainbook-0.0.8.dist-info → plainbook-0.0.10.dist-info}/entry_points.txt +0 -0
- {plainbook-0.0.8.dist-info → plainbook-0.0.10.dist-info}/licenses/LICENSE.md +0 -0
- {plainbook-0.0.8.dist-info → plainbook-0.0.10.dist-info}/top_level.txt +0 -0
plainbook/plainbook.py
CHANGED
|
@@ -16,6 +16,22 @@ class ExecutionError(Exception):
|
|
|
16
16
|
"""Custom exception for execution errors in Plainbook."""
|
|
17
17
|
pass
|
|
18
18
|
|
|
19
|
+
def getlist(value):
|
|
20
|
+
"""Utility to ensure a value is a list."""
|
|
21
|
+
if isinstance(value, list):
|
|
22
|
+
return value
|
|
23
|
+
else:
|
|
24
|
+
return [value]
|
|
25
|
+
|
|
26
|
+
def tostring(value):
|
|
27
|
+
"""Utility to ensure a value is a string."""
|
|
28
|
+
if isinstance(value, str):
|
|
29
|
+
return value
|
|
30
|
+
elif isinstance(value, list):
|
|
31
|
+
return "".join(value)
|
|
32
|
+
else:
|
|
33
|
+
return str(value)
|
|
34
|
+
|
|
19
35
|
class Plainbook(object):
|
|
20
36
|
"""This class implements an Plainbook and its operations."""
|
|
21
37
|
|
|
@@ -26,7 +42,9 @@ class Plainbook(object):
|
|
|
26
42
|
self.nb = None
|
|
27
43
|
self._lock = threading.Lock()
|
|
28
44
|
self.last_executed_cell = -1
|
|
29
|
-
self.
|
|
45
|
+
self._load_notebook()
|
|
46
|
+
# Context for notebook processing.
|
|
47
|
+
self.input_files = []
|
|
30
48
|
# Starts the kernel.
|
|
31
49
|
self.km = KernelManager()
|
|
32
50
|
self.km.start_kernel()
|
|
@@ -41,11 +59,20 @@ class Plainbook(object):
|
|
|
41
59
|
# Register the cleanup function
|
|
42
60
|
atexit.register(self._shutdown)
|
|
43
61
|
|
|
44
|
-
def
|
|
62
|
+
def _load_notebook(self):
|
|
45
63
|
"""Loads the notebook from the specified path. If the file is missing, create an empty notebook."""
|
|
46
64
|
try:
|
|
47
65
|
with open(self.path) as f:
|
|
48
66
|
self.nb = nbformat.read(f, as_version=4)
|
|
67
|
+
for cell in self.nb.cells:
|
|
68
|
+
cell.source = tostring(cell.source)
|
|
69
|
+
if cell.cell_type == 'code':
|
|
70
|
+
if 'explanation' not in cell.metadata:
|
|
71
|
+
cell.metadata['explanation'] = ""
|
|
72
|
+
else:
|
|
73
|
+
cell.metadata['explanation'] = tostring(cell.metadata['explanation'])
|
|
74
|
+
if 'codegen' not in cell.metadata:
|
|
75
|
+
cell.metadata['codegen'] = False
|
|
49
76
|
except (FileNotFoundError, OSError):
|
|
50
77
|
# Ensure parent directory exists
|
|
51
78
|
parent = os.path.dirname(self.path) or "."
|
|
@@ -245,6 +272,7 @@ class Plainbook(object):
|
|
|
245
272
|
else:
|
|
246
273
|
new_cell = nbformat.v4.new_code_cell(source="", execution_count=None, outputs=[])
|
|
247
274
|
new_cell.metadata['explanation'] = []
|
|
275
|
+
new_cell.metadata['codegen'] = False
|
|
248
276
|
self.nb.cells.insert(index, new_cell)
|
|
249
277
|
# Inserting code cells before the last executed cell requires resetting the kernel.
|
|
250
278
|
if cell_type == 'code' and index <= self.last_executed_cell:
|
|
@@ -296,10 +324,12 @@ class Plainbook(object):
|
|
|
296
324
|
"""Sets the source code of a cell at the given index."""
|
|
297
325
|
with self._lock:
|
|
298
326
|
assert 0 <= index < len(self.nb.cells)
|
|
299
|
-
self.nb.cells[index]
|
|
300
|
-
|
|
327
|
+
cell = self.nb.cells[index]
|
|
328
|
+
cell.source = source
|
|
329
|
+
if cell.cell_type == 'code':
|
|
330
|
+
cell.metadata['codegen'] = False
|
|
301
331
|
# Reset outputs and execution count on code cell edit
|
|
302
|
-
|
|
332
|
+
cell.outputs = []
|
|
303
333
|
if index <= self.last_executed_cell:
|
|
304
334
|
# We need to restart.
|
|
305
335
|
self._reset_kernel()
|
|
@@ -312,6 +342,7 @@ class Plainbook(object):
|
|
|
312
342
|
cell = self.nb.cells[index]
|
|
313
343
|
assert cell.cell_type == 'code'
|
|
314
344
|
cell.metadata['explanation'] = explanation
|
|
345
|
+
cell.metadata['codegen'] = False
|
|
315
346
|
self._write()
|
|
316
347
|
|
|
317
348
|
# Methods to support AI
|
|
@@ -321,15 +352,16 @@ class Plainbook(object):
|
|
|
321
352
|
Needs to be called with the lock held."""
|
|
322
353
|
cell = self.nb.cells[index]
|
|
323
354
|
if cell.cell_type == 'code':
|
|
324
|
-
explanation = cell.metadata.get('explanation',
|
|
325
|
-
explanation = ["# " + line for line in explanation]
|
|
326
|
-
explanation_text = "
|
|
327
|
-
|
|
328
|
-
return explanation_text +
|
|
355
|
+
explanation = cell.metadata.get('explanation', "")
|
|
356
|
+
explanation = ["# " + line for line in explanation.splitlines(keepends=True)]
|
|
357
|
+
explanation_text = "".join(explanation) + "\n"
|
|
358
|
+
source_code = cell.source + "\n"
|
|
359
|
+
return explanation_text + source_code
|
|
329
360
|
elif cell.cell_type == 'markdown':
|
|
330
|
-
|
|
361
|
+
commented_lines = ["# " + line for line in cell.source.splitlines(keepends=True)]
|
|
362
|
+
return "".join(commented_lines) + "\n"
|
|
331
363
|
else:
|
|
332
|
-
return ""
|
|
364
|
+
return "\n"
|
|
333
365
|
|
|
334
366
|
def _get_code_for_ai(self, index):
|
|
335
367
|
"""Returns the concatenated source code of all previous code cells for context."""
|
|
@@ -346,21 +378,26 @@ class Plainbook(object):
|
|
|
346
378
|
cell = self.nb.cells[index]
|
|
347
379
|
assert cell.cell_type == 'code'
|
|
348
380
|
instructions = cell.metadata.get('explanation')
|
|
381
|
+
files_context = self._get_files_context()
|
|
382
|
+
error_context = self._get_error_context(index)
|
|
349
383
|
previous_code = self._get_code_for_ai(index)
|
|
350
384
|
# Mark that an AI request is pending
|
|
351
385
|
try:
|
|
352
|
-
new_code = gemini_generate_code(
|
|
386
|
+
new_code = gemini_generate_code(
|
|
387
|
+
api_key, previous_code=previous_code, instructions=instructions,
|
|
388
|
+
file_context=files_context, error_context=error_context)
|
|
353
389
|
# If we are still in a request, update the cell.
|
|
354
390
|
if self.ai_request_pending:
|
|
355
391
|
cell.source = new_code
|
|
392
|
+
cell.metadata['codegen'] = True
|
|
356
393
|
# Reset outputs and execution count
|
|
357
394
|
cell.outputs = []
|
|
358
395
|
if index <= self.last_executed_cell:
|
|
359
396
|
self._reset_kernel()
|
|
360
397
|
self._write()
|
|
361
|
-
return new_code
|
|
398
|
+
return new_code, True
|
|
362
399
|
else:
|
|
363
|
-
return None
|
|
400
|
+
return None, False
|
|
364
401
|
finally:
|
|
365
402
|
self.ai_request_pending = False
|
|
366
403
|
|
|
@@ -400,3 +437,32 @@ class Plainbook(object):
|
|
|
400
437
|
cell.metadata['validation'] = {}
|
|
401
438
|
cell.metadata['validation']['is_hidden'] = is_hidden
|
|
402
439
|
self._write()
|
|
440
|
+
|
|
441
|
+
def set_input_files(self, files):
|
|
442
|
+
"""Sets the input files for the notebook."""
|
|
443
|
+
self.input_files = files
|
|
444
|
+
|
|
445
|
+
def _get_files_context(self):
|
|
446
|
+
"""Builds the AI context including input files."""
|
|
447
|
+
context_parts = [
|
|
448
|
+
"Here is a list of file names and paths. "
|
|
449
|
+
"The user may mention input files; to access them, the full path should be used."
|
|
450
|
+
]
|
|
451
|
+
for file in self.input_files:
|
|
452
|
+
context_parts.append(f"* File name: {file['name']} path: {file['path']}\n")
|
|
453
|
+
return "\n".join(context_parts) + "\n"
|
|
454
|
+
|
|
455
|
+
def _get_error_context(self, cell_index):
|
|
456
|
+
"""If the cell has an error, include its traceback as context."""
|
|
457
|
+
context_parts = [
|
|
458
|
+
"The previous attempt to run this cell resulted in this error traceback:"
|
|
459
|
+
]
|
|
460
|
+
cell = self.nb.cells[cell_index]
|
|
461
|
+
if cell.cell_type != 'code':
|
|
462
|
+
return None
|
|
463
|
+
for output in reversed(getlist(cell.get('outputs', []))):
|
|
464
|
+
if output.output_type == 'error':
|
|
465
|
+
traceback = context_parts + getlist(output.get('traceback', []))
|
|
466
|
+
return "\n".join(traceback)
|
|
467
|
+
return None
|
|
468
|
+
|
plainbook/views/index.html
CHANGED
|
@@ -29,100 +29,108 @@
|
|
|
29
29
|
</style>
|
|
30
30
|
</head>
|
|
31
31
|
<body class="has-navbar-fixed-top">
|
|
32
|
+
|
|
33
|
+
<div id="app"></div>
|
|
32
34
|
|
|
33
35
|
<script type="text/x-template" id="app-template">
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
37
|
+
<app-navbar
|
|
38
|
+
:is-locked="isLocked"
|
|
39
|
+
:running="running"
|
|
40
|
+
:has-notebook="!!notebook"
|
|
41
|
+
:last-run-index="lastRunIndex"
|
|
42
|
+
:cell-count="notebook ? notebook.cells.length : 0"
|
|
43
|
+
:has-api-key="!!geminiApiKey"
|
|
44
|
+
@lock="lockNotebook"
|
|
45
|
+
@refresh="reloadNotebook"
|
|
46
|
+
@interrupt="interruptKernel"
|
|
47
|
+
@regenerate-all="regenerateAllCode"
|
|
48
|
+
@reset-run-all="resetAndRunAllCells"
|
|
49
|
+
@open-info="showInfo = true"
|
|
50
|
+
@open-settings="showSettings = true"
|
|
51
|
+
/>
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
<input-file
|
|
54
|
+
:auth-token="authToken"
|
|
55
|
+
/>
|
|
56
|
+
|
|
57
|
+
<ui-error
|
|
58
|
+
:error="uiError"
|
|
59
|
+
@close="closeUiError"
|
|
60
|
+
/>
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
<div class="section notebook-area">
|
|
63
|
+
<h1 class="title">
|
|
64
|
+
{{ notebook_name }}
|
|
65
|
+
</h1>
|
|
66
|
+
<div class="notebook-container px-2 py-2">
|
|
67
|
+
<div v-if="loading" class="has-text-centered py-6">
|
|
68
|
+
<button class="button is-loading is-ghost is-large">Loading</button>
|
|
69
|
+
<p class="has-text-grey">Fetching notebook data...</p>
|
|
70
|
+
</div>
|
|
71
|
+
<div v-else-if="error" class="notification is-danger is-light">
|
|
72
|
+
<button class="delete" @click="error = null"></button>
|
|
73
|
+
<strong>Error:</strong> {{ error }}
|
|
74
|
+
</div>
|
|
75
|
+
<div v-else="notebook">
|
|
76
|
+
|
|
77
|
+
<template v-for="(cell, index) in notebook.cells" :key="index">
|
|
71
78
|
|
|
72
79
|
<cell-insertion-zone v-if="!isLocked"
|
|
73
|
-
|
|
80
|
+
:is-last="false"
|
|
81
|
+
@insert="(celltype) => insertCell(index, celltype)"
|
|
82
|
+
/>
|
|
83
|
+
|
|
84
|
+
<notebook-cell
|
|
85
|
+
:cell="cell"
|
|
86
|
+
:is-active="activeIndex === index"
|
|
87
|
+
:needs-running="index > lastRunIndex"
|
|
88
|
+
:is-locked="isLocked"
|
|
89
|
+
:last-run-index="lastRunIndex"
|
|
90
|
+
:as-read="asRead"
|
|
91
|
+
:markdown-edit-key="markdownEditKey[index]"
|
|
92
|
+
:explanation-edit-key="explanationEditKey[index]"
|
|
93
|
+
@click="setActiveCell(index)"
|
|
94
|
+
|
|
95
|
+
@save-markdown="(content) => sendMarkdownToServer(content, index)"
|
|
96
|
+
@save-explanation="(content) => sendExplanationToServer(content, index)"
|
|
97
|
+
@save-code="(content) => sendCodeToServer(content, index)"
|
|
98
|
+
@save-and-run="(content) => saveExplanationAndRun(content, index)"
|
|
99
|
+
|
|
100
|
+
@run-cell="runCell(index)"
|
|
101
|
+
@generate-code="generateCode(index)"
|
|
102
|
+
@validate-code="validateCode(index)"
|
|
103
|
+
@dismiss-validation="dismissValidation(index)"
|
|
104
|
+
|
|
105
|
+
@delete="deleteCell(index)"
|
|
106
|
+
@move-up="moveCell(index, -1)"
|
|
107
|
+
@move-down="moveCell(index, 1)"
|
|
74
108
|
/>
|
|
75
109
|
|
|
76
|
-
<template v-for="(cell, index) in notebook.cells" :key="index">
|
|
77
|
-
|
|
78
|
-
<notebook-cell
|
|
79
|
-
:cell="cell"
|
|
80
|
-
:is-active="activeIndex === index"
|
|
81
|
-
:needs-running="index > lastRunIndex"
|
|
82
|
-
:is-locked="isLocked"
|
|
83
|
-
:last-run-index="lastRunIndex"
|
|
84
|
-
:as-read="asRead"
|
|
85
|
-
:markdown-edit-key="markdownEditKey[index]"
|
|
86
|
-
:explanation-edit-key="explanationEditKey[index]"
|
|
87
|
-
@click="setActiveCell(index)"
|
|
88
|
-
|
|
89
|
-
@save-markdown="(content) => sendMarkdownToServer(content, index)"
|
|
90
|
-
@save-explanation="(content) => sendExplanationToServer(content, index)"
|
|
91
|
-
@save-code="(content) => sendCodeToServer(content, index)"
|
|
92
|
-
@save-and-run="(content) => saveExplanationAndRun(content, index)"
|
|
93
|
-
|
|
94
|
-
@run-cell="runCell(index)"
|
|
95
|
-
@generate-code="generateCode(index)"
|
|
96
|
-
@validate-code="validateCode(index)"
|
|
97
|
-
@dismiss-validation="dismissValidation(index)"
|
|
98
|
-
|
|
99
|
-
@delete="deleteCell(index)"
|
|
100
|
-
@move-up="moveCell(index, -1)"
|
|
101
|
-
@move-down="moveCell(index, 1)"
|
|
102
|
-
/>
|
|
103
|
-
|
|
104
|
-
<cell-insertion-zone v-if="!isLocked"
|
|
105
|
-
@insert="(celltype) => insertCell(index + 1, celltype)"
|
|
106
|
-
/>
|
|
107
|
-
|
|
108
|
-
</template>
|
|
109
110
|
|
|
110
|
-
</
|
|
111
|
+
</template>
|
|
112
|
+
|
|
113
|
+
<cell-insertion-zone v-if="!isLocked"
|
|
114
|
+
:is-last="true"
|
|
115
|
+
@insert="(celltype) => insertCell(notebook.cells.length, celltype)"
|
|
116
|
+
/>
|
|
117
|
+
|
|
111
118
|
</div>
|
|
112
119
|
</div>
|
|
120
|
+
</div>
|
|
113
121
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
<!-- Settings Modal -->
|
|
123
|
+
<settings-modal
|
|
124
|
+
:is-active="showSettings"
|
|
125
|
+
:api-key="geminiApiKey"
|
|
126
|
+
@close="showSettings = false"
|
|
127
|
+
@save="(newKey) => {showSettings = false; saveSettings(newKey); }"
|
|
128
|
+
/>
|
|
129
|
+
<!-- Info Modal -->
|
|
130
|
+
<info-modal
|
|
131
|
+
:is-active="showInfo"
|
|
132
|
+
@close="showInfo = false"
|
|
133
|
+
/>
|
|
126
134
|
|
|
127
135
|
</script>
|
|
128
136
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
plainbook/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
2
|
-
plainbook/gemini.py,sha256=
|
|
3
|
-
plainbook/main.py,sha256=
|
|
4
|
-
plainbook/plainbook.py,sha256=
|
|
2
|
+
plainbook/gemini.py,sha256=v0jCIE8MFQ7Fnctah9pV9YAkGHZ7E2vUAnKAPUQw_VA,3175
|
|
3
|
+
plainbook/main.py,sha256=52rfzj-ZwnJu0ozadBDa7bINqvEK71M2OduiIf5LhIc,11693
|
|
4
|
+
plainbook/plainbook.py,sha256=2PmEyfpShY1Gn_3-pApNyhXL-NidgyjH081AtPbmwjk,19808
|
|
5
5
|
plainbook/css/font-awesome.css,sha256=NuCn4IvuZXdBaFKJOAcsU2Q3ZpwbdFisd5dux4jkQ5w,37414
|
|
6
6
|
plainbook/css/font-awesome.min.css,sha256=eZrrJcwDc_3uDhsdt61sL2oOBY362qM3lon1gyExkL0,31000
|
|
7
|
-
plainbook/css/main.css,sha256=
|
|
7
|
+
plainbook/css/main.css,sha256=sWH9Nanyr0pZwVQRkqV8-zQjrK602PrxNHgW0_15lU4,692344
|
|
8
8
|
plainbook/css/prism.min.css,sha256=ko4j5rn874LF8dHwW29_xabhh8YBleWfvxb8nQce4Fc,1789
|
|
9
9
|
plainbook/fonts/FontAwesome.otf,sha256=RE3UNmYV_8ShbQErL6kBNwZdPMtBD6b9Xk3de15P_NU,134808
|
|
10
10
|
plainbook/fonts/fontawesome-webfont.eot,sha256=e_yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk,165742
|
|
@@ -13,24 +13,26 @@ plainbook/fonts/fontawesome-webfont.ttf,sha256=qljzPyOaD7AvXHpsRcBD16msmgkzNYBml
|
|
|
13
13
|
plainbook/fonts/fontawesome-webfont.woff,sha256=ugxZ3rVFD1y0Gz-TYJ7i0NmVQVh33foiPoqKdTNHTwc,98024
|
|
14
14
|
plainbook/fonts/fontawesome-webfont.woff2,sha256=Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8_4,77160
|
|
15
15
|
plainbook/js/AppNavbar.js,sha256=nEX2CXdI0136Usj-YVts6QXV4xd_vbsXh9-mPvgbi5E,3968
|
|
16
|
-
plainbook/js/CellInsertionZone.js,sha256=
|
|
17
|
-
plainbook/js/CodeCell.js,sha256=
|
|
18
|
-
plainbook/js/ExplanationEditor.js,sha256=
|
|
19
|
-
plainbook/js/InfoModal.js,sha256=
|
|
16
|
+
plainbook/js/CellInsertionZone.js,sha256=En2hItfUGdV5s2_vk41ovCkM8XLpIlLQ8wRNNmQAyzU,728
|
|
17
|
+
plainbook/js/CodeCell.js,sha256=Xi7M0-0ew3_UJvPoJDJBsaf9PZ3MBKKdZ4nkMVODp-o,6959
|
|
18
|
+
plainbook/js/ExplanationEditor.js,sha256=gPwe3fLKBy8dnprKloeCHYDgBh2znse6clacGWq0g-I,7444
|
|
19
|
+
plainbook/js/InfoModal.js,sha256=t1Rjz658gfuoszoE0chfi2qFqJwmCgjlaYIeIATe_Nk,1436
|
|
20
|
+
plainbook/js/InputFile.js,sha256=l93wGretLdu9iqcTdatTI3LQxEo-sTTi9phKPQC6zF0,7928
|
|
20
21
|
plainbook/js/MarkdownCell.js,sha256=SxU_LO4TGcxOEy6sKognF_gHUXwmqR6BDsv4z0tlgVQ,5292
|
|
21
|
-
plainbook/js/NotebookCell.js,sha256
|
|
22
|
+
plainbook/js/NotebookCell.js,sha256=-HMSZlf287IEZJQSRCKv6u-9Yd2Wvq0DB4mEvWD5Jts,3677
|
|
22
23
|
plainbook/js/OutputRenderer.js,sha256=KXECI2xd0Sk_TnZnAfqfhL0dEIT9pjZZTXo6Qdiw0o4,2981
|
|
23
24
|
plainbook/js/SettingsModal.js,sha256=HpU2gKj26zZHhilcfp3hghEsW-sxsgq1HBlcsIBDGCI,1689
|
|
25
|
+
plainbook/js/UiError.js,sha256=F3tQ3I66-3kbAsGlD9OVWWrRu9LNJ3QCSkr0tWX-R5w,439
|
|
24
26
|
plainbook/js/ValidationCell.js,sha256=4XdlBNELTpeARiNVh55_7ay24CEY-aUNJy1knX8I9MU,1595
|
|
25
27
|
plainbook/js/markdown-it.min.js,sha256=hNyljag6giCsjv_yKmxK8_VeHzvMDvc5u8AzmRvm1BI,103012
|
|
26
|
-
plainbook/js/nb.js,sha256=
|
|
28
|
+
plainbook/js/nb.js,sha256=xLQb5IDMe1Smpa1HsH2qgNnRCG9Cl51mRdyC8AoV5_k,23464
|
|
27
29
|
plainbook/js/prism-python.min.js,sha256=7UOFaFvPLUk1yNu6tL3hZgPaEyngktK_NsPa3WfpqFw,2113
|
|
28
30
|
plainbook/js/prism.min.js,sha256=57iL3cbHV7L8jLET4kaYAasUp47BqPraTWOR41c_X58,18997
|
|
29
31
|
plainbook/js/vue.esm-browser.js,sha256=75FuLhUTPk19sncwNIrm0BGEL0_Qw298-_v01fPWYoI,542872
|
|
30
|
-
plainbook/views/index.html,sha256=
|
|
31
|
-
plainbook-0.0.
|
|
32
|
-
plainbook-0.0.
|
|
33
|
-
plainbook-0.0.
|
|
34
|
-
plainbook-0.0.
|
|
35
|
-
plainbook-0.0.
|
|
36
|
-
plainbook-0.0.
|
|
32
|
+
plainbook/views/index.html,sha256=hBuTsAh86BGUQxjyIQG1ZWTAsrOI3Rh6NNbppqze6Hc,5188
|
|
33
|
+
plainbook-0.0.10.dist-info/licenses/LICENSE.md,sha256=JW6Hp9mBeCkRkCSeiT2KmIU3XA5mJorjcIlM2cOOxyU,1462
|
|
34
|
+
plainbook-0.0.10.dist-info/METADATA,sha256=4lblvcP571gixqk-P7chUSKy-37nyUgMSWQotiPutDc,3024
|
|
35
|
+
plainbook-0.0.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
36
|
+
plainbook-0.0.10.dist-info/entry_points.txt,sha256=fktud-zRh9ZZ4rXv5w6kW-78u44lSYklXY1ttMTB9k8,50
|
|
37
|
+
plainbook-0.0.10.dist-info/top_level.txt,sha256=Y3jOV2n79dczNw9tJ7acufz3y3ns2pWw8b06sIN4ltc,10
|
|
38
|
+
plainbook-0.0.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|