pysfi 0.1.10__py3-none-any.whl → 0.1.11__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.
Files changed (47) hide show
  1. {pysfi-0.1.10.dist-info → pysfi-0.1.11.dist-info}/METADATA +7 -7
  2. pysfi-0.1.11.dist-info/RECORD +60 -0
  3. {pysfi-0.1.10.dist-info → pysfi-0.1.11.dist-info}/entry_points.txt +12 -2
  4. sfi/__init__.py +1 -1
  5. sfi/alarmclock/alarmclock.py +40 -40
  6. sfi/bumpversion/__init__.py +1 -1
  7. sfi/cleanbuild/cleanbuild.py +155 -0
  8. sfi/condasetup/condasetup.py +116 -0
  9. sfi/docscan/__init__.py +1 -1
  10. sfi/docscan/docscan_gui.py +1 -1
  11. sfi/docscan/lang/eng.py +152 -152
  12. sfi/docscan/lang/zhcn.py +170 -170
  13. sfi/filedate/filedate.py +185 -112
  14. sfi/gittool/__init__.py +2 -0
  15. sfi/gittool/gittool.py +401 -0
  16. sfi/llmclient/llmclient.py +592 -0
  17. sfi/llmquantize/llmquantize.py +480 -0
  18. sfi/llmserver/llmserver.py +335 -0
  19. sfi/makepython/makepython.py +2 -2
  20. sfi/pdfsplit/pdfsplit.py +4 -4
  21. sfi/pyarchive/pyarchive.py +418 -0
  22. sfi/pyembedinstall/pyembedinstall.py +629 -0
  23. sfi/pylibpack/pylibpack.py +813 -269
  24. sfi/pylibpack/rules/numpy.json +22 -0
  25. sfi/pylibpack/rules/pymupdf.json +10 -0
  26. sfi/pylibpack/rules/pyqt5.json +19 -0
  27. sfi/pylibpack/rules/pyside2.json +23 -0
  28. sfi/pylibpack/rules/scipy.json +23 -0
  29. sfi/pylibpack/rules/shiboken2.json +24 -0
  30. sfi/pyloadergen/pyloadergen.py +271 -572
  31. sfi/pypack/pypack.py +822 -471
  32. sfi/pyprojectparse/__init__.py +0 -0
  33. sfi/pyprojectparse/pyprojectparse.py +500 -0
  34. sfi/pysourcepack/pysourcepack.py +308 -369
  35. sfi/quizbase/__init__.py +0 -0
  36. sfi/quizbase/quizbase.py +828 -0
  37. sfi/quizbase/quizbase_gui.py +987 -0
  38. sfi/regexvalidate/__init__.py +0 -0
  39. sfi/regexvalidate/regex_help.html +284 -0
  40. sfi/regexvalidate/regexvalidate.py +468 -0
  41. sfi/taskkill/taskkill.py +0 -2
  42. pysfi-0.1.10.dist-info/RECORD +0 -39
  43. sfi/embedinstall/embedinstall.py +0 -478
  44. sfi/projectparse/projectparse.py +0 -152
  45. {pysfi-0.1.10.dist-info → pysfi-0.1.11.dist-info}/WHEEL +0 -0
  46. /sfi/{embedinstall → llmquantize}/__init__.py +0 -0
  47. /sfi/{projectparse → pyembedinstall}/__init__.py +0 -0
@@ -0,0 +1,468 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ import re
6
+ import sys
7
+ from datetime import datetime
8
+ from pathlib import Path
9
+
10
+ import PySide2
11
+ from PySide2.QtCore import Qt, QTimer
12
+ from PySide2.QtGui import QFont
13
+ from PySide2.QtWidgets import (
14
+ QApplication,
15
+ QCheckBox,
16
+ QComboBox,
17
+ QDialog,
18
+ QGroupBox,
19
+ QHBoxLayout,
20
+ QLabel,
21
+ QLineEdit,
22
+ QMainWindow,
23
+ QPushButton,
24
+ QSplitter,
25
+ QTextBrowser,
26
+ QTextEdit,
27
+ QVBoxLayout,
28
+ QWidget,
29
+ )
30
+
31
+ qt_dir = Path(PySide2.__file__).parent
32
+ plugin_path = str(qt_dir / "plugins" / "platforms")
33
+ os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = plugin_path
34
+
35
+ # History file path
36
+ HISTORY_FILE = Path.home() / ".pysfi" / "regexvalidate" / ".regex_validator_history.json"
37
+ HISTORY_FILE.parent.mkdir(parents=True, exist_ok=True)
38
+ MAX_HISTORY_ITEMS = 20
39
+
40
+
41
+ class RegexValidatorGUI(QMainWindow):
42
+ def __init__(self) -> None:
43
+ super().__init__()
44
+ self.setWindowTitle("Regex Validator Tool")
45
+ self.setGeometry(100, 100, 800, 600)
46
+
47
+ # Load history
48
+ self.history = self.load_history()
49
+ self.history_items = [] # Current list of history display items
50
+
51
+ # Timer for delayed history update to avoid focus loss
52
+ self.history_timer = QTimer()
53
+ self.history_timer.setSingleShot(True)
54
+ self.history_timer.setInterval(1000) # Wait 1 second after typing stops
55
+ self.history_timer.timeout.connect(self.add_to_history)
56
+
57
+ # Central widget
58
+ central_widget = QWidget()
59
+ self.setCentralWidget(central_widget)
60
+
61
+ # Main layout
62
+ main_layout = QVBoxLayout(central_widget)
63
+
64
+ # Title and help button
65
+ title_layout = QHBoxLayout()
66
+ title_label = QLabel("Regex Validator Tool")
67
+ title_label.setAlignment(Qt.AlignCenter)
68
+ title_label.setStyleSheet("font-size: 18px; font-weight: bold; margin: 10px;")
69
+ title_layout.addWidget(title_label)
70
+
71
+ help_button = QPushButton("Help")
72
+ help_button.setMaximumWidth(80)
73
+ help_button.clicked.connect(self.show_help)
74
+ title_layout.addWidget(help_button)
75
+ main_layout.addLayout(title_layout)
76
+
77
+ # Create splitter for flexible layout
78
+ splitter = QSplitter(Qt.Vertical)
79
+ main_layout.addWidget(splitter)
80
+
81
+ # Top group: Input settings
82
+ top_group = QGroupBox("Input Settings")
83
+ top_layout = QVBoxLayout(top_group)
84
+
85
+ # Regular expression input
86
+ regex_layout = QHBoxLayout()
87
+ regex_label = QLabel("Regular Expression:")
88
+ self.regex_input = QLineEdit()
89
+ self.regex_input.setPlaceholderText("Enter your regular expression...")
90
+ regex_layout.addWidget(regex_label)
91
+ regex_layout.addWidget(self.regex_input)
92
+ top_layout.addLayout(regex_layout)
93
+
94
+ # History selector
95
+ history_layout = QHBoxLayout()
96
+ history_label = QLabel("History:")
97
+ self.history_combo = QComboBox()
98
+ self.history_combo.setMinimumWidth(400)
99
+ self.update_history_combo()
100
+ self.history_combo.currentIndexChanged.connect(self.on_history_selected)
101
+ history_layout.addWidget(history_label)
102
+ history_layout.addWidget(self.history_combo)
103
+ top_layout.addLayout(history_layout)
104
+
105
+ # Raw mode checkbox
106
+ self.raw_mode_checkbox = QCheckBox("Raw Mode (Disable Escape Sequence Processing)")
107
+ self.raw_mode_checkbox.setChecked(True)
108
+ top_layout.addWidget(self.raw_mode_checkbox)
109
+
110
+ # Test string input
111
+ test_string_label = QLabel("Test String:")
112
+ top_layout.addWidget(test_string_label)
113
+
114
+ self.test_string_input = QTextEdit()
115
+ self.test_string_input.setMaximumHeight(100)
116
+ self.test_string_input.setPlaceholderText("Enter the string to test against the regular expression...")
117
+ top_layout.addWidget(self.test_string_input)
118
+
119
+ splitter.addWidget(top_group)
120
+
121
+ # Bottom group: Results and options
122
+ bottom_group = QGroupBox("Results & Options")
123
+ bottom_layout = QVBoxLayout(bottom_group)
124
+
125
+ # Options
126
+ options_layout = QHBoxLayout()
127
+
128
+ self.case_insensitive_checkbox = QCheckBox("Case Insensitive (re.IGNORECASE)")
129
+ self.multiline_checkbox = QCheckBox("Multiline (re.MULTILINE)")
130
+ self.dotall_checkbox = QCheckBox("Dotall (re.DOTALL)")
131
+
132
+ options_layout.addWidget(self.case_insensitive_checkbox)
133
+ options_layout.addWidget(self.multiline_checkbox)
134
+ options_layout.addWidget(self.dotall_checkbox)
135
+ bottom_layout.addLayout(options_layout)
136
+
137
+ # Results label with status indicator
138
+ self.results_label = QLabel("Validation Results: ")
139
+ self.results_label.setStyleSheet("font-size: 14px; font-weight: bold;")
140
+ bottom_layout.addWidget(self.results_label)
141
+
142
+ self.results_output = QTextEdit()
143
+ self.results_output.setReadOnly(True)
144
+ bottom_layout.addWidget(self.results_output)
145
+
146
+ splitter.addWidget(bottom_group)
147
+
148
+ # Set initial sizes for splitter
149
+ splitter.setSizes([200, 400])
150
+
151
+ # Connect text changes to auto-validate function
152
+ self.regex_input.textChanged.connect(self.on_text_changed)
153
+ self.test_string_input.textChanged.connect(self.on_text_changed)
154
+
155
+ def on_text_changed(self) -> None:
156
+ """Handle text changes and auto-validate."""
157
+ self.validate_regex()
158
+ # Restart the timer to delay history update
159
+ self.history_timer.stop()
160
+ self.history_timer.start()
161
+
162
+ def load_history(self) -> list:
163
+ """Load history from file."""
164
+ if HISTORY_FILE.exists():
165
+ try:
166
+ with open(HISTORY_FILE, encoding="utf-8") as f:
167
+ return json.load(f)
168
+ except Exception as e:
169
+ print(f"Failed to load history: {e}")
170
+ return []
171
+
172
+ def save_history(self) -> None:
173
+ """Save history to file."""
174
+ try:
175
+ with open(HISTORY_FILE, "w", encoding="utf-8") as f:
176
+ json.dump(self.history, f, indent=2, ensure_ascii=False)
177
+ except Exception as e:
178
+ print(f"Failed to save history: {e}")
179
+
180
+ def update_history_combo(self) -> None:
181
+ """Update the history combo box with current history."""
182
+ # Store current selection
183
+ current_index = self.history_combo.currentIndex()
184
+ self.history_combo.itemData(current_index) if current_index > 0 else None
185
+
186
+ # Block signals to prevent triggering selection changes
187
+ self.history_combo.blockSignals(True)
188
+
189
+ self.history_combo.clear()
190
+ self.history_combo.addItem("-- Select History --")
191
+
192
+ # Add history items with display format
193
+ for i, item in enumerate(self.history):
194
+ display_text = f"{i + 1}. {item['pattern'][:50]}{'...' if len(item['pattern']) > 50 else ''}"
195
+ self.history_combo.addItem(display_text, i)
196
+
197
+ # Restore selection to first item (placeholder) to avoid focus stealing
198
+ self.history_combo.setCurrentIndex(0)
199
+
200
+ # Unblock signals
201
+ self.history_combo.blockSignals(False)
202
+
203
+ def on_history_selected(self, index: int) -> None:
204
+ """Handle history item selection."""
205
+ if index <= 0: # First item is placeholder
206
+ return
207
+
208
+ data_index = self.history_combo.itemData(index)
209
+ if data_index is not None and 0 <= data_index < len(self.history):
210
+ item = self.history[data_index]
211
+
212
+ # Block signals to prevent auto-validation during restoration
213
+ self.regex_input.blockSignals(True)
214
+ self.test_string_input.blockSignals(True)
215
+
216
+ # Restore values
217
+ self.regex_input.setText(item["pattern"])
218
+ self.test_string_input.setPlainText(item["test_string"])
219
+ self.raw_mode_checkbox.setChecked(item.get("raw_mode", True))
220
+ self.case_insensitive_checkbox.setChecked(item.get("case_insensitive", False))
221
+ self.multiline_checkbox.setChecked(item.get("multiline", False))
222
+ self.dotall_checkbox.setChecked(item.get("dotall", False))
223
+
224
+ # Unblock signals and validate
225
+ self.regex_input.blockSignals(False)
226
+ self.test_string_input.blockSignals(False)
227
+ self.validate_regex()
228
+
229
+ def add_to_history(self) -> None:
230
+ """Add current settings to history if they are different."""
231
+ current_pattern = self.regex_input.text()
232
+ current_test_string = self.test_string_input.toPlainText()
233
+
234
+ if not current_pattern:
235
+ return
236
+
237
+ # Create current item
238
+ current_item = {
239
+ "pattern": current_pattern,
240
+ "test_string": current_test_string,
241
+ "raw_mode": self.raw_mode_checkbox.isChecked(),
242
+ "case_insensitive": self.case_insensitive_checkbox.isChecked(),
243
+ "multiline": self.multiline_checkbox.isChecked(),
244
+ "dotall": self.dotall_checkbox.isChecked(),
245
+ "timestamp": str(datetime.now()) if "datetime" in globals() else None,
246
+ }
247
+
248
+ # Check if this item already exists in history
249
+ for item in self.history:
250
+ if (
251
+ item["pattern"] == current_pattern
252
+ and item["test_string"] == current_test_string
253
+ and item.get("raw_mode", True) == current_item["raw_mode"]
254
+ ):
255
+ # Item already exists, move it to front
256
+ self.history.remove(item)
257
+ self.history.insert(0, current_item)
258
+ self.save_history()
259
+ return
260
+
261
+ # Add new item to front
262
+ self.history.insert(0, current_item)
263
+
264
+ # Limit history size
265
+ if len(self.history) > MAX_HISTORY_ITEMS:
266
+ self.history = self.history[:MAX_HISTORY_ITEMS]
267
+
268
+ self.save_history()
269
+ self.update_history_combo()
270
+
271
+ def validate_regex(self) -> None:
272
+ """Validate the regex against the test string."""
273
+ regex_pattern = self.regex_input.text()
274
+ test_string = self.test_string_input.toPlainText()
275
+
276
+ if not regex_pattern:
277
+ self.results_output.setText("Error: Regular expression is empty.")
278
+ self.results_output.setStyleSheet("background-color: #ffcccc;")
279
+ self.results_label.setText("Validation Results: ✗")
280
+ self.results_label.setStyleSheet("font-size: 14px; font-weight: bold; color: red;")
281
+ return
282
+
283
+ if not test_string:
284
+ self.results_output.setText("Warning: Test string is empty, but regex is being tested anyway.")
285
+ self.results_output.setStyleSheet("background-color: #ffffcc;")
286
+ self.results_label.setText("Validation Results: ")
287
+ self.results_label.setStyleSheet("font-size: 14px; font-weight: bold; color: orange;")
288
+
289
+ # Build flags based on checkboxes
290
+ flags = 0
291
+ if self.case_insensitive_checkbox.isChecked():
292
+ flags |= re.IGNORECASE
293
+ if self.multiline_checkbox.isChecked():
294
+ flags |= re.MULTILINE
295
+ if self.dotall_checkbox.isChecked():
296
+ flags |= re.DOTALL
297
+
298
+ try:
299
+ # Handle raw mode
300
+ if self.raw_mode_checkbox.isChecked():
301
+ # In raw mode, treat the regex as-is without processing escape sequences
302
+ compiled_regex = re.compile(regex_pattern, flags)
303
+ else:
304
+ # In non-raw mode, process escape sequences in the pattern
305
+ compiled_regex = re.compile(regex_pattern, flags)
306
+
307
+ # Perform various regex operations
308
+ match_result = compiled_regex.search(test_string)
309
+ findall_result = compiled_regex.findall(test_string)
310
+ finditer_result = list(compiled_regex.finditer(test_string))
311
+ fullmatch_result = compiled_regex.fullmatch(test_string) if test_string else None
312
+
313
+ # Prepare results
314
+ results = []
315
+ results.append("=" * 50)
316
+ results.append("REGEX VALIDATION RESULTS")
317
+ results.append("=" * 50)
318
+ results.append(f"Pattern: {regex_pattern}")
319
+ results.append(f"Test String: {test_string!r}")
320
+ results.append(f"Raw Mode: {'Enabled' if self.raw_mode_checkbox.isChecked() else 'Disabled'}")
321
+ results.append(f"Flags: {flags}")
322
+ results.append("-" * 50)
323
+
324
+ # Match result
325
+ if match_result:
326
+ results.append("MATCH FOUND:")
327
+ results.append(f" Match: {match_result.group()!r}")
328
+ results.append(f" Span: {match_result.span()}")
329
+ results.append(f" Start: {match_result.start()}")
330
+ results.append(f" End: {match_result.end()}")
331
+
332
+ # Show groups if any
333
+ if match_result.groups():
334
+ results.append(f" Groups: {match_result.groups()}")
335
+
336
+ if match_result.groupdict():
337
+ results.append(f" Named Groups: {match_result.groupdict()}")
338
+ else:
339
+ results.append("NO MATCH FOUND")
340
+
341
+ # Full match result
342
+ results.append("\nFULL MATCH:")
343
+ if fullmatch_result:
344
+ results.append(f" Full Match: {fullmatch_result.group()!r}")
345
+ results.append(f" Full Match Groups: {fullmatch_result.groups()}")
346
+ else:
347
+ results.append(" No full match")
348
+
349
+ # Findall result
350
+ results.append(f"\nFINDALL RESULT ({len(findall_result)} items):")
351
+ if findall_result:
352
+ for i, item in enumerate(findall_result):
353
+ results.append(f" [{i}]: {item!r}")
354
+ else:
355
+ results.append(" No matches found")
356
+
357
+ # Finditer result
358
+ results.append(f"\nFINDITER RESULT ({len(finditer_result)} matches):")
359
+ if finditer_result:
360
+ for i, match in enumerate(finditer_result):
361
+ results.append(f" Match {i + 1}: {match.group()!r} at {match.span()}")
362
+ if match.groups():
363
+ results.append(f" Groups: {match.groups()}")
364
+ else:
365
+ results.append(" No matches found")
366
+
367
+ # Check for special regex features
368
+ results.append("\nREGEX ANALYSIS:")
369
+ if "(" in regex_pattern and ")" in regex_pattern:
370
+ results.append(" Contains capturing groups")
371
+ if "(?:" in regex_pattern:
372
+ results.append(" Contains non-capturing groups")
373
+ if "(?P<" in regex_pattern:
374
+ results.append(" Contains named groups")
375
+ if "?" in regex_pattern:
376
+ results.append(" Contains quantifier modifiers")
377
+ if "\\" in regex_pattern:
378
+ results.append(" Contains escape sequences")
379
+
380
+ self.results_output.setText("\n".join(results))
381
+
382
+ # Set background color based on match result
383
+ if match_result:
384
+ self.results_output.setStyleSheet("background-color: #ccffcc;")
385
+ self.results_label.setText("Validation Results: ✓")
386
+ self.results_label.setStyleSheet("font-size: 14px; font-weight: bold; color: green;")
387
+ else:
388
+ self.results_output.setStyleSheet("background-color: #ffcccc;")
389
+ self.results_label.setText("Validation Results: ✗")
390
+ self.results_label.setStyleSheet("font-size: 14px; font-weight: bold; color: red;")
391
+
392
+ except re.error as e:
393
+ error_msg = f"Regex Error: {e!s}"
394
+ self.results_output.setText(error_msg)
395
+ self.results_output.setStyleSheet("background-color: #ffcccc;")
396
+ self.results_label.setText("Validation Results: ✗")
397
+ self.results_label.setStyleSheet("font-size: 14px; font-weight: bold; color: red;")
398
+ except Exception as e:
399
+ error_msg = f"Unexpected Error: {e!s}"
400
+ self.results_output.setText(error_msg)
401
+ self.results_output.setStyleSheet("background-color: #ffcccc;")
402
+ self.results_label.setText("Validation Results: ✗")
403
+ self.results_label.setStyleSheet("font-size: 14px; font-weight: bold; color: red;")
404
+
405
+ def show_help(self) -> None:
406
+ """Show regex help dialog."""
407
+ dialog = RegexHelpDialog(self)
408
+ dialog.exec_()
409
+
410
+
411
+ class RegexHelpDialog(QDialog):
412
+ """Dialog showing regex syntax help from HTML file."""
413
+
414
+ def __init__(self, parent: QWidget | None = None) -> None:
415
+ super().__init__(parent)
416
+ self.setWindowTitle("Regex Syntax Help")
417
+ self.setMinimumSize(700, 500)
418
+ self.resize(750, 600)
419
+
420
+ layout = QVBoxLayout(self)
421
+
422
+ # Load HTML content from file
423
+ help_html_path = Path(__file__).parent / "regex_help.html"
424
+
425
+ if help_html_path.exists():
426
+ with open(help_html_path, encoding="utf-8") as f:
427
+ html_content = f.read()
428
+ else:
429
+ html_content = """
430
+ <html><body>
431
+ <h2>Help File Not Found</h2>
432
+ <p>Cannot find help file: <code>regex_help.html</code></p>
433
+ <p>Please ensure the file is located in the same directory as <code>regexvalidate.py</code>.</p>
434
+ </body></html>
435
+ """
436
+
437
+ # Create text browser to display HTML
438
+ text_browser = QTextBrowser()
439
+ text_browser.setHtml(html_content)
440
+ text_browser.setOpenExternalLinks(False) # Prevent opening external links
441
+
442
+ layout.addWidget(text_browser)
443
+
444
+ # Close button
445
+ close_button = QPushButton("Close")
446
+ close_button.setMaximumWidth(100)
447
+ close_button.clicked.connect(self.accept)
448
+ button_layout = QHBoxLayout()
449
+ button_layout.addStretch()
450
+ button_layout.addWidget(close_button)
451
+ layout.addLayout(button_layout)
452
+
453
+
454
+ def main() -> None:
455
+ app = QApplication(sys.argv)
456
+
457
+ # Set application font
458
+ font = QFont("Arial", 9)
459
+ app.setFont(font)
460
+
461
+ window = RegexValidatorGUI()
462
+ window.show()
463
+
464
+ sys.exit(app.exec_())
465
+
466
+
467
+ if __name__ == "__main__":
468
+ main()
sfi/taskkill/taskkill.py CHANGED
@@ -232,5 +232,3 @@ def main() -> None:
232
232
 
233
233
  # Restore original threshold
234
234
  _max_match_threshold = original_threshold
235
-
236
- return
@@ -1,39 +0,0 @@
1
- sfi/__init__.py,sha256=8bMY8NhWD1vYgwgWs9iUPIBAypGLtUPLEYaDIUaFXN4,75
2
- sfi/cli.py,sha256=bUUTOg18sJQbSKSfsVANhlMgSj9yzO2txIzFAd9B2Ok,296
3
- sfi/alarmclock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- sfi/alarmclock/alarmclock.py,sha256=65G8OyTGpe4oQ2SFerQG1N9PVJ4KxO7WzgsTxpGm4O0,12509
5
- sfi/bumpversion/__init__.py,sha256=K9BMEwc9KPoYJnm_FPKjKRrRrq9lNbSqGe96zOOuG6Q,86
6
- sfi/bumpversion/bumpversion.py,sha256=HOyHLaE0sZajrlcVZ8hsim8mPjz77qwQVSo6aIzjMXE,20735
7
- sfi/docscan/__init__.py,sha256=PZio8kjN0cGQ0CF-YjS3NK7MHTL7yPA5YsnAYtCt1Z8,121
8
- sfi/docscan/docscan.py,sha256=rk8mjEI2SKNIliV-Yb41pfUmYBQ1tUhk5LHUNEjkszI,41890
9
- sfi/docscan/docscan_gui.py,sha256=2WzvxMf-rsAJnEYXTCfRhTvojZFNp46LKt_Xke67D_s,50657
10
- sfi/docscan/lang/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- sfi/docscan/lang/eng.py,sha256=_43KW9WfX64dS3Rjg4fbtvavP9MBWhNEKeIt1HKYktU,8377
12
- sfi/docscan/lang/zhcn.py,sha256=n4QGTv5SwgBqICNZHiTF1kmaDcQA6wG7gvRc0OWIfe4,8715
13
- sfi/embedinstall/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- sfi/embedinstall/embedinstall.py,sha256=Go0nmi22KVYpZPuW_-ORoVE5oHgQNbMw7Fbn0AZ9D8s,17507
15
- sfi/filedate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- sfi/filedate/filedate.py,sha256=DpVp26lumE_Lz_4TgqUEX8IxtK3Y6yHSEFV8qJyegyk,3645
17
- sfi/makepython/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- sfi/makepython/makepython.py,sha256=nKuklEW3yIm0VIol0Ly9Cm9RCyqdY9Fs-i5obvbO0kI,11423
19
- sfi/pdfsplit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- sfi/pdfsplit/pdfsplit.py,sha256=1fntwckU8yy4-_A4h5eOrODs6-Cl_wMzaIvHGmMzCco,6177
21
- sfi/projectparse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- sfi/projectparse/projectparse.py,sha256=Ojg-z4lZEtjEBpJYWyznTgL307N45AxlQKnRkEH0P70,5525
23
- sfi/pylibpack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- sfi/pylibpack/pylibpack.py,sha256=BDcgtGZ1S0u9a0rrHZ-ZJCvmNs8D0YxM2b5aONxPkXc,31398
25
- sfi/pyloadergen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- sfi/pyloadergen/pyloadergen.py,sha256=-8-uLFQOie1wgUhV18CFcfRF2uNkxm8AZuJQHYGTzng,51386
27
- sfi/pypack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- sfi/pypack/pypack.py,sha256=up1Z6thEPuvo-naNnDGSA3S7YZGYAruxyN3Z2agkr8Q,31137
29
- sfi/pysourcepack/pysourcepack.py,sha256=VwrKqYeHm2YU6J-Fdhze1mDTVDM4Or7DsJQ4vWL23tw,11725
30
- sfi/taskkill/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- sfi/taskkill/taskkill.py,sha256=6Aw4afmgfLZcQnvgG_38A1VrwazDrnNdOmY1l4kr0lc,7758
32
- sfi/which/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- sfi/which/which.py,sha256=zVIAwZA-pGGngxkkwZ6IxDX3ozVHg7cLSYwYO9FjaIc,2439
34
- sfi/workflowengine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- sfi/workflowengine/workflowengine.py,sha256=ck5PjyyjtWtbjN4ePEKsTWV6QR-BUlrfwrY6jih52jQ,17055
36
- pysfi-0.1.10.dist-info/METADATA,sha256=bhtOFk62jPKXMqrVA3icmNKpI7U2hJjPkxLwBB4glQc,4031
37
- pysfi-0.1.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
38
- pysfi-0.1.10.dist-info/entry_points.txt,sha256=_QEugTtofmViUWxD_LtMc6gzX8VfOaLmd2Vco0LZam0,678
39
- pysfi-0.1.10.dist-info/RECORD,,