ok-script 0.0.77__tar.gz → 0.0.79__tar.gz
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.
- {ok-script-0.0.77 → ok-script-0.0.79}/PKG-INFO +1 -1
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/OK.py +19 -11
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/platform_windows.py +2 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/DeviceManager.py +7 -4
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/FeatureSet.py +2 -1
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/FindFeature.py +1 -1
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/App.py +6 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/MainWindow.py +2 -5
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/MessageWindow.py +2 -1
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/DebugTab.py +5 -5
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/start/StartTab.py +2 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/BaseTask.py +12 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/ExecutorOperation.py +7 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/TaskExecutor.py +1 -2
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/update/GithubMultiDownloader.py +8 -1
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/Handler.py +23 -43
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/exit_event.py +1 -1
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/win32_process.py +2 -2
- {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/PKG-INFO +1 -1
- {ok-script-0.0.77 → ok-script-0.0.79}/setup.py +1 -1
- {ok-script-0.0.77 → ok-script-0.0.79}/README.md +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/emulator_base.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/emulator_windows.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/platform_base.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/utils.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/BaseCaptureMethod.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/HwndWindow.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/ADBCaptureMethod.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/bin/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/image/ImageCaptureMethod.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/image/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/BitBltCaptureMethod.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/d3d11.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/dump.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/utils.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/window.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/color/Color.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/color/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/config/Config.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/config/InfoDict.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/config/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/Box.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/Feature.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/firebase/Analytics.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/firebase/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/Communicate.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/StartController.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/TabTitles.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/about/AboutTab.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/about/HttpTextEdit.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/about/VersionCard.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/about/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/common/OKIcon.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/common/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/common/config.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/common/style_sheet.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/AspectRatioWidget.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/FrameWidget.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/InfoWidget.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/LoggerWidget.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/Screenshot.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/i18n/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/i18n/path.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/i18n/update.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/icon/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/icon/icon.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/overlay/OverlayWindow.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/overlay/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/qss/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/resources.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/settings/SettingTab.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/settings/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/start/SelectCaptureListView.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/start/StartCard.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/start/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/ConfigItemFactory.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndDropDown.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndList.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndWidget.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/ModifyListDialog.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/ModifyListItem.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/StartButton.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/TaskCard.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/TaskOpButton.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/TooltipTableWidget.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/TriggerTaskTab.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/util/Alert.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/util/InitWorker.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/util/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/Card.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/EmptyCard.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/FramelessDialog.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/ListTableWidgetItem.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/StartLoadingDialog.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/StatusBar.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/Tab.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/TabWidget.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/YesNonWidgetItem.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/ADBInteraction.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/BaseInteraction.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/DoNothingInteraction.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/Win32Interaction.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/logging/Logger.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/logging/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/ocr/OCR.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/ocr/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Media/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Security/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Storage/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/delegate.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/export.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/idldsl.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/inspectable.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/roapi.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/types.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/winstring.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/BlackBarProcessor.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/PostProcessor.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/SaveByInterval.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/SaveByKeyPress.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/SaveMethodBase.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/scene/FeatureScene.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/scene/Scene.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/scene/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/stats/StreamStats.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/stats/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/OneTimeTask.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/TriggerTask.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/update/Updater.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/update/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/update/gen_md5.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/json.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/list.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/path.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/thread.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/yaml.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/SOURCES.txt +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/dependency_links.txt +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/requires.txt +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/top_level.txt +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/setup.cfg +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/tests/__init__.py +0 -0
- {ok-script-0.0.77 → ok-script-0.0.79}/tests/test_updater.py +0 -0
|
@@ -11,7 +11,6 @@ from ok.util.exit_event import ExitEvent
|
|
|
11
11
|
from ok.util.path import install_path_isascii
|
|
12
12
|
from ok.util.win32_process import check_mutex
|
|
13
13
|
|
|
14
|
-
check_mutex()
|
|
15
14
|
logger = get_logger(__name__)
|
|
16
15
|
|
|
17
16
|
|
|
@@ -27,6 +26,7 @@ class OK:
|
|
|
27
26
|
app = None
|
|
28
27
|
screenshot = None
|
|
29
28
|
exit_event = ExitEvent()
|
|
29
|
+
init_error = None
|
|
30
30
|
|
|
31
31
|
def __init__(self, config: Dict[str, Any]):
|
|
32
32
|
print(f"AutoHelper init, config: {config}")
|
|
@@ -57,7 +57,8 @@ class OK:
|
|
|
57
57
|
def start(self):
|
|
58
58
|
try:
|
|
59
59
|
if self.config.get("use_gui"):
|
|
60
|
-
self.
|
|
60
|
+
if not self.init_error:
|
|
61
|
+
self.app.show_main_window()
|
|
61
62
|
self.app.exec()
|
|
62
63
|
else:
|
|
63
64
|
self.task_executor.start()
|
|
@@ -91,14 +92,6 @@ class OK:
|
|
|
91
92
|
|
|
92
93
|
def do_init(self):
|
|
93
94
|
logger.info(f"initializing {self.__class__.__name__}, config: {self.config}")
|
|
94
|
-
if self.config.get('ocr'):
|
|
95
|
-
isascii, path = install_path_isascii()
|
|
96
|
-
if not isascii:
|
|
97
|
-
self.app.show_path_ascii_error(path)
|
|
98
|
-
return False
|
|
99
|
-
from rapidocr_openvino import RapidOCR
|
|
100
|
-
inference_num_threads = self.config.get('ocr').get('inference_num_threads', -1)
|
|
101
|
-
self.ocr = RapidOCR(inference_num_threads=inference_num_threads)
|
|
102
95
|
|
|
103
96
|
template_matching = self.config.get('template_matching')
|
|
104
97
|
if template_matching is not None:
|
|
@@ -117,10 +110,25 @@ class OK:
|
|
|
117
110
|
trigger_tasks=self.config.get('trigger_tasks', []),
|
|
118
111
|
scenes=self.config['scenes'],
|
|
119
112
|
feature_set=self.feature_set,
|
|
120
|
-
|
|
113
|
+
config_folder=self.config.get("config_folder"))
|
|
121
114
|
|
|
122
115
|
ok.gui.executor = self.task_executor
|
|
123
116
|
|
|
117
|
+
if self.config.get('ocr'):
|
|
118
|
+
isascii, path = install_path_isascii()
|
|
119
|
+
if not isascii:
|
|
120
|
+
self.app.show_path_ascii_error(path)
|
|
121
|
+
self.init_error = True
|
|
122
|
+
return False
|
|
123
|
+
from rapidocr_openvino import RapidOCR
|
|
124
|
+
inference_num_threads = self.config.get('ocr').get('inference_num_threads', -1)
|
|
125
|
+
self.ocr = RapidOCR(inference_num_threads=inference_num_threads)
|
|
126
|
+
self.task_executor.ocr = self.ocr
|
|
127
|
+
|
|
128
|
+
if not check_mutex():
|
|
129
|
+
self.init_error = True
|
|
130
|
+
self.app.show_already_running_error()
|
|
131
|
+
|
|
124
132
|
return True
|
|
125
133
|
|
|
126
134
|
def wait_task(self):
|
|
@@ -44,6 +44,8 @@ def get_emulator_exe(instance: EmulatorInstance):
|
|
|
44
44
|
elif instance == Emulator.BlueStacks4:
|
|
45
45
|
# BlueStacks\Client\Bluestacks.exe -vmname Android_1
|
|
46
46
|
return f'"{exe}" -vmname {instance.name}'
|
|
47
|
+
elif instance == Emulator.LDPlayerFamily:
|
|
48
|
+
return f'"{exe}" -name {instance.name}'
|
|
47
49
|
else:
|
|
48
50
|
raise EmulatorUnknown(f'Cannot start an unknown emulator instance: {instance}')
|
|
49
51
|
|
|
@@ -55,6 +55,9 @@ class DeviceManager:
|
|
|
55
55
|
def adb_connect(self, addr):
|
|
56
56
|
try:
|
|
57
57
|
for info in self.adb.list():
|
|
58
|
+
if self.exit_event.is_set():
|
|
59
|
+
logger.error(f"adb_connect exit_event is set")
|
|
60
|
+
return None
|
|
58
61
|
if info.serial == addr:
|
|
59
62
|
if info.state == 'offline':
|
|
60
63
|
logger.debug(f'adb_connect offline disconnect first {addr}')
|
|
@@ -185,7 +188,7 @@ class DeviceManager:
|
|
|
185
188
|
if self.config.get("preferred") != imei:
|
|
186
189
|
logger.info(f'preferred device did change {imei}')
|
|
187
190
|
self.config["preferred"] = imei
|
|
188
|
-
self.
|
|
191
|
+
self.start()
|
|
189
192
|
logger.debug(f'preferred device: {preferred}')
|
|
190
193
|
|
|
191
194
|
def adb_get_imei(self, device):
|
|
@@ -215,7 +218,7 @@ class DeviceManager:
|
|
|
215
218
|
def set_capture(self, capture):
|
|
216
219
|
if self.config.get("capture") != capture:
|
|
217
220
|
self.config['capture'] = capture
|
|
218
|
-
self.
|
|
221
|
+
self.start()
|
|
219
222
|
|
|
220
223
|
def get_hwnd_name(self):
|
|
221
224
|
preferred = self.get_preferred_device()
|
|
@@ -280,7 +283,7 @@ class DeviceManager:
|
|
|
280
283
|
communicate.adb_devices.emit(True)
|
|
281
284
|
|
|
282
285
|
def update_resolution_for_hwnd(self):
|
|
283
|
-
if self.hwnd is not None and self.hwnd.frame_aspect_ratio == 0:
|
|
286
|
+
if self.hwnd is not None and self.hwnd.frame_aspect_ratio == 0 and self.adb_capture_config:
|
|
284
287
|
width, height = self.get_resolution()
|
|
285
288
|
logger.debug(f'update resolution for {self.hwnd} {width}x{height}')
|
|
286
289
|
self.hwnd.update_frame_size(width, height)
|
|
@@ -372,7 +375,7 @@ class DeviceManager:
|
|
|
372
375
|
packages = [packages]
|
|
373
376
|
for package in packages:
|
|
374
377
|
if package == front.package:
|
|
375
|
-
return
|
|
378
|
+
return True
|
|
376
379
|
|
|
377
380
|
def adb_start_package(self, package):
|
|
378
381
|
self.shell(f'monkey -p {package} -c android.intent.category.LAUNCHER 1')
|
|
@@ -105,7 +105,8 @@ class FeatureSet:
|
|
|
105
105
|
self.feature_dict[category_name] = Feature(image, x, y, w, h)
|
|
106
106
|
self.box_dict[category_name] = Box(x, y, w, h, name=category_name)
|
|
107
107
|
|
|
108
|
-
def get_box_by_name(self, category_name: str) -> Box:
|
|
108
|
+
def get_box_by_name(self, mat, category_name: str) -> Box:
|
|
109
|
+
self.check_size(mat)
|
|
109
110
|
if category_name in self.box_dict:
|
|
110
111
|
return self.box_dict[category_name]
|
|
111
112
|
else:
|
|
@@ -18,7 +18,7 @@ class FindFeature:
|
|
|
18
18
|
threshold, use_gray_scale, x, y, to_x, to_y, width, height)
|
|
19
19
|
|
|
20
20
|
def get_box_by_name(self, name):
|
|
21
|
-
return self.feature_set.get_box_by_name(name)
|
|
21
|
+
return self.feature_set.get_box_by_name(self.executor.frame, name)
|
|
22
22
|
|
|
23
23
|
def find_feature_and_set(self, features, horizontal_variance=0, vertical_variance=0, threshold=0):
|
|
24
24
|
ret = True
|
|
@@ -79,6 +79,12 @@ class App:
|
|
|
79
79
|
message_window = MessageWindow(self.icon, title, message, exit_event=self.exit_event)
|
|
80
80
|
message_window.show()
|
|
81
81
|
|
|
82
|
+
def show_already_running_error(self):
|
|
83
|
+
title = QCoreApplication.translate("app", 'Error')
|
|
84
|
+
content = QCoreApplication.translate("app",
|
|
85
|
+
"Another instance is already running")
|
|
86
|
+
self.show_message_window(title, content)
|
|
87
|
+
|
|
82
88
|
def show_path_ascii_error(self, path):
|
|
83
89
|
title = QCoreApplication.translate("app", 'Error')
|
|
84
90
|
content = QCoreApplication.translate("app",
|
|
@@ -2,12 +2,10 @@ import os
|
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
4
|
from PySide6.QtCore import QObject, Signal, Qt
|
|
5
|
-
from PySide6.QtGui import QKeySequence, QShortcut
|
|
6
5
|
from PySide6.QtWidgets import QMenu, QSystemTrayIcon
|
|
7
6
|
from qfluentwidgets import FluentIcon, NavigationItemPosition, MSFluentWindow, InfoBar, InfoBarPosition, MessageBox
|
|
8
7
|
|
|
9
8
|
import ok.gui
|
|
10
|
-
from ok.capture.windows.dump import dump_threads
|
|
11
9
|
from ok.gui.Communicate import communicate
|
|
12
10
|
from ok.gui.about.AboutTab import AboutTab
|
|
13
11
|
from ok.gui.debug.DebugTab import DebugTab
|
|
@@ -68,8 +66,6 @@ class MainWindow(MSFluentWindow):
|
|
|
68
66
|
communicate.executor_paused.connect(self.executor_paused)
|
|
69
67
|
communicate.tab.connect(self.navigate_tab)
|
|
70
68
|
|
|
71
|
-
|
|
72
|
-
|
|
73
69
|
# Create a context menu for the tray
|
|
74
70
|
menu = QMenu()
|
|
75
71
|
exit_action = menu.addAction(self.tr("Exit"))
|
|
@@ -167,10 +163,11 @@ class MainWindow(MSFluentWindow):
|
|
|
167
163
|
def closeEvent(self, event):
|
|
168
164
|
# Create a message box that asks the user if they really want to close the window
|
|
169
165
|
if sys.platform == 'win32' and 'shutdown' in os.environ.get('SESSIONNAME', '').lower():
|
|
166
|
+
logger.info("system shutting down")
|
|
167
|
+
ok.gui.ok.quit()
|
|
170
168
|
event.accept()
|
|
171
169
|
return
|
|
172
170
|
|
|
173
|
-
# Your existing code for the message box
|
|
174
171
|
if ok.gui.ok.exit_event.is_set():
|
|
175
172
|
event.accept()
|
|
176
173
|
return
|
|
@@ -27,8 +27,9 @@ class MessageWindow(FramelessWindow):
|
|
|
27
27
|
self.message_label = BodyLabel(message)
|
|
28
28
|
self.message_label.setWordWrap(True)
|
|
29
29
|
self.vBoxLayout = QVBoxLayout(self)
|
|
30
|
+
self.vBoxLayout.setAlignment(Qt.AlignCenter)
|
|
30
31
|
self.setLayout(self.vBoxLayout)
|
|
31
|
-
self.vBoxLayout.addWidget(self.message_label,
|
|
32
|
+
self.vBoxLayout.addWidget(self.message_label, 1, Qt.AlignVCenter)
|
|
32
33
|
self.confirm_button = PushButton(self.tr('Confirm'))
|
|
33
34
|
self.vBoxLayout.addWidget(self.confirm_button, 0, Qt.AlignCenter)
|
|
34
35
|
self.confirm_button.clicked.connect(self.quit)
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import subprocess
|
|
2
2
|
from ctypes import windll, wintypes
|
|
3
3
|
|
|
4
|
-
from PySide6.QtCore import Qt, Signal
|
|
5
|
-
from PySide6.
|
|
6
|
-
from PySide6.QtWidgets import QWidget, QFileDialog, QCompleter, QVBoxLayout, QHBoxLayout, QMessageBox
|
|
4
|
+
from PySide6.QtCore import Qt, Signal
|
|
5
|
+
from PySide6.QtWidgets import QWidget, QFileDialog, QCompleter, QVBoxLayout, QHBoxLayout
|
|
7
6
|
from _ctypes import byref
|
|
8
7
|
from qfluentwidgets import PushButton, FlowLayout, ComboBox, SearchLineEdit, TextEdit
|
|
9
8
|
|
|
@@ -110,6 +109,7 @@ class DebugTab(Tab):
|
|
|
110
109
|
if msg.message == 0x0312: # WM_HOTKEY
|
|
111
110
|
logger.debug(f'hotkey pressed {msg}')
|
|
112
111
|
if msg.wParam == 1:
|
|
112
|
+
logger.debug('dumping threads')
|
|
113
113
|
dump_threads()
|
|
114
114
|
elif msg.wParam == 2:
|
|
115
115
|
self.handler.post(self.capture)
|
|
@@ -124,9 +124,9 @@ class DebugTab(Tab):
|
|
|
124
124
|
VK_S = 0x53
|
|
125
125
|
|
|
126
126
|
if not windll.user32.RegisterHotKey(None, 1, MOD_ALT | MOD_CONTROL, VK_D):
|
|
127
|
-
|
|
127
|
+
logger.debug("Failed to register hotkey for Alt+Ctrl+D")
|
|
128
128
|
if not windll.user32.RegisterHotKey(None, 2, MOD_ALT | MOD_CONTROL, VK_S):
|
|
129
|
-
|
|
129
|
+
logger.debug("Failed to register hotkey for Alt+Ctrl+S")
|
|
130
130
|
logger.debug('bind_hot_keys')
|
|
131
131
|
|
|
132
132
|
def __del__(self):
|
|
@@ -82,6 +82,8 @@ class StartTab(Tab):
|
|
|
82
82
|
preferred = ok.gui.device_manager.config.get("preferred")
|
|
83
83
|
selected = self.device_list_row
|
|
84
84
|
|
|
85
|
+
logger.debug('update_capture')
|
|
86
|
+
|
|
85
87
|
# Update the existing items in the device_list and ok.gui.device_manager.get_devices()
|
|
86
88
|
for row, device in enumerate(devices):
|
|
87
89
|
if device["imei"] == preferred:
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
|
|
1
3
|
from ok.config.Config import Config
|
|
2
4
|
from ok.config.InfoDict import InfoDict
|
|
3
5
|
from ok.gui.Communicate import communicate
|
|
4
6
|
from ok.logging.Logger import get_logger
|
|
5
7
|
from ok.task.ExecutorOperation import ExecutorOperation
|
|
8
|
+
from ok.util.Handler import Handler
|
|
6
9
|
|
|
7
10
|
logger = get_logger(__name__)
|
|
8
11
|
|
|
@@ -22,6 +25,15 @@ class BaseTask(ExecutorOperation):
|
|
|
22
25
|
self.config_description = {}
|
|
23
26
|
self.config_type = {}
|
|
24
27
|
self._paused = False
|
|
28
|
+
self.lock = threading.Lock()
|
|
29
|
+
self._handler = None
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def handler(self) -> Handler:
|
|
33
|
+
with self.lock:
|
|
34
|
+
if self._handler is None:
|
|
35
|
+
self._handler = Handler(self.executor.exit_event, __name__)
|
|
36
|
+
return self._handler
|
|
25
37
|
|
|
26
38
|
def pause(self):
|
|
27
39
|
self.executor.pause(self)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import queue
|
|
2
2
|
from typing import List
|
|
3
3
|
|
|
4
|
+
from ok.color.Color import calculate_color_percentage
|
|
4
5
|
from ok.feature.Box import Box, find_box_by_name, relative_box
|
|
5
6
|
from ok.gui.Communicate import communicate
|
|
6
7
|
|
|
@@ -163,5 +164,11 @@ class ExecutorOperation:
|
|
|
163
164
|
def draw_boxes(feature_name=None, boxes=None, color="red"):
|
|
164
165
|
communicate.emit_draw_box(feature_name, boxes, color)
|
|
165
166
|
|
|
167
|
+
def calculate_color_percentage(self, color, box: Box):
|
|
168
|
+
percentage = calculate_color_percentage(self.frame, color, box)
|
|
169
|
+
box.confidence = percentage
|
|
170
|
+
self.draw_boxes(box.name, box)
|
|
171
|
+
return percentage
|
|
172
|
+
|
|
166
173
|
def adb_shell(self, *args, **kwargs):
|
|
167
174
|
return self.executor.device_manager.shell(*args, **kwargs)
|
|
@@ -10,7 +10,6 @@ from ok.scene.Scene import Scene
|
|
|
10
10
|
from ok.stats.StreamStats import StreamStats
|
|
11
11
|
from ok.task.OneTimeTask import OneTimeTask
|
|
12
12
|
from ok.task.TriggerTask import TriggerTask
|
|
13
|
-
from ok.util.exit_event import ExitEvent
|
|
14
13
|
|
|
15
14
|
logger = get_logger(__name__)
|
|
16
15
|
|
|
@@ -35,7 +34,7 @@ class TaskExecutor:
|
|
|
35
34
|
|
|
36
35
|
def __init__(self, device_manager: DeviceManager,
|
|
37
36
|
wait_until_timeout=10, wait_until_before_delay=1, wait_until_check_delay=1,
|
|
38
|
-
exit_event=
|
|
37
|
+
exit_event=None, trigger_tasks=[], onetime_tasks=[], scenes=[], feature_set=None,
|
|
39
38
|
ocr=None,
|
|
40
39
|
config_folder=None):
|
|
41
40
|
self.device_manager = device_manager
|
|
@@ -55,13 +55,14 @@ class GithubMultiDownloader:
|
|
|
55
55
|
downloaded = os.path.getsize(file)
|
|
56
56
|
if downloaded == part_size:
|
|
57
57
|
logger.info(f'File {file} already downloaded')
|
|
58
|
+
self.downloaded += part_size
|
|
58
59
|
return
|
|
59
60
|
elif downloaded > part_size:
|
|
60
61
|
logger.warning(f'File size error {file} {downloaded} > {part_size}')
|
|
61
62
|
os.remove(file)
|
|
62
63
|
else:
|
|
63
64
|
part_start += downloaded
|
|
64
|
-
|
|
65
|
+
self.downloaded += downloaded
|
|
65
66
|
|
|
66
67
|
target_size = end - part_start + 1
|
|
67
68
|
|
|
@@ -117,6 +118,12 @@ class GithubMultiDownloader:
|
|
|
117
118
|
response.close()
|
|
118
119
|
logger.debug('switch to fast proxy')
|
|
119
120
|
break
|
|
121
|
+
if part_downloaded == target_size:
|
|
122
|
+
logger.debug("download_part finished")
|
|
123
|
+
return
|
|
124
|
+
else:
|
|
125
|
+
logger.warning(f'download_part size failed {part_downloaded} {target_size}')
|
|
126
|
+
return True
|
|
120
127
|
except Exception as e:
|
|
121
128
|
with self.lock:
|
|
122
129
|
if proxy in self.proxys:
|
|
@@ -31,33 +31,40 @@ class Handler:
|
|
|
31
31
|
while not self.task_queue:
|
|
32
32
|
self.condition.wait()
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
34
|
+
now = time.time()
|
|
35
|
+
self.condition.acquire()
|
|
36
|
+
if self.task_queue and self.task_queue[0].execute_at <= now:
|
|
37
|
+
scheduled_task = heapq.heappop(self.task_queue)
|
|
38
|
+
self.condition.release()
|
|
39
|
+
if scheduled_task.task is None:
|
|
40
|
+
logger.debug(f'stopping handler {self.thread.name}')
|
|
41
|
+
return
|
|
42
|
+
self.executing = scheduled_task.task
|
|
43
|
+
try:
|
|
44
|
+
scheduled_task.task()
|
|
45
|
+
except Exception as e:
|
|
46
|
+
logger.error(f'handler {self.thread.name} raised exception', e)
|
|
47
|
+
self.executing = None
|
|
48
|
+
else:
|
|
47
49
|
if self.task_queue:
|
|
48
50
|
next_time = self.task_queue[0].execute_at
|
|
49
51
|
timeout = next_time - now
|
|
50
52
|
if timeout > 0:
|
|
51
53
|
self.condition.wait(timeout=timeout)
|
|
54
|
+
self.condition.release()
|
|
52
55
|
|
|
53
56
|
def post(self, task, delay=0, remove_existing=False, skip_if_running=False):
|
|
54
57
|
with self.condition:
|
|
58
|
+
if self.exit_event.is_set():
|
|
59
|
+
logger.error(f'post handler {self.thread.name} already exits')
|
|
60
|
+
self.condition.notify_all()
|
|
61
|
+
return
|
|
55
62
|
if remove_existing and len(self.task_queue) > 0:
|
|
56
63
|
for obj in self.task_queue.copy():
|
|
57
64
|
if obj.task == task:
|
|
58
65
|
self.task_queue.remove(obj)
|
|
59
66
|
logger.debug(f'removing duplicate task {task}')
|
|
60
|
-
if
|
|
67
|
+
if skip_if_running and self.executing == task:
|
|
61
68
|
logger.debug(f'skipping duplicate task {task}')
|
|
62
69
|
return
|
|
63
70
|
if delay > 0:
|
|
@@ -65,36 +72,9 @@ class Handler:
|
|
|
65
72
|
else:
|
|
66
73
|
scheduled_task = ScheduledTask(0, task)
|
|
67
74
|
heapq.heappush(self.task_queue, scheduled_task)
|
|
68
|
-
self.condition.
|
|
75
|
+
self.condition.notify_all()
|
|
69
76
|
|
|
70
77
|
def stop(self):
|
|
71
|
-
heapq.heappush(self.task_queue, ScheduledTask(0, None))
|
|
72
78
|
with self.condition:
|
|
79
|
+
heapq.heappush(self.task_queue, ScheduledTask(0, None))
|
|
73
80
|
self.condition.notify_all()
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
# Example usage
|
|
77
|
-
if __name__ == "__main__":
|
|
78
|
-
def print_message(message):
|
|
79
|
-
from datetime import datetime
|
|
80
|
-
print(f"{message} at {datetime.now().time()}")
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
exit_event = ExitEvent()
|
|
84
|
-
handler = Handler(event=ExitEvent(), name="MyHandlerThread")
|
|
85
|
-
|
|
86
|
-
# Post a task to run immediately
|
|
87
|
-
handler.post(lambda: print_message("Immediate task"))
|
|
88
|
-
|
|
89
|
-
# Post a task to run after a delay (e.g., 2 seconds)
|
|
90
|
-
handler.post_delayed(lambda: print_message("Delayed task"), 2)
|
|
91
|
-
|
|
92
|
-
# Post a function to run immediately
|
|
93
|
-
handler.post(lambda: print_message("Immediate function"))
|
|
94
|
-
|
|
95
|
-
# Post a function to run after a delay (e.g., 3 seconds)
|
|
96
|
-
handler.post_delayed(lambda: print_message("Delayed function"), 3)
|
|
97
|
-
|
|
98
|
-
# Let the handler run for a while to process the tasks
|
|
99
|
-
time.sleep(5)
|
|
100
|
-
exit_event.set()
|
|
@@ -17,7 +17,7 @@ class ExitEvent(threading.Event):
|
|
|
17
17
|
|
|
18
18
|
def set(self):
|
|
19
19
|
super(ExitEvent, self).set()
|
|
20
|
-
logger.debug(f"ExitEvent set event empty queues")
|
|
20
|
+
logger.debug(f"ExitEvent set event empty queues {self.queues} to_stops: {self.to_stops}")
|
|
21
21
|
for queue in self.queues:
|
|
22
22
|
queue.put(None)
|
|
23
23
|
|
|
@@ -4,7 +4,6 @@ import ctypes
|
|
|
4
4
|
import hashlib
|
|
5
5
|
import msvcrt
|
|
6
6
|
import os
|
|
7
|
-
import sys
|
|
8
7
|
from ctypes import wintypes
|
|
9
8
|
from typing import Union
|
|
10
9
|
|
|
@@ -34,7 +33,8 @@ def check_mutex():
|
|
|
34
33
|
# Check if the mutex already exists
|
|
35
34
|
if GetLastError() == ERROR_ALREADY_EXISTS:
|
|
36
35
|
print(f"Another instance of this application is already running. {path}")
|
|
37
|
-
|
|
36
|
+
return False
|
|
37
|
+
return True
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def all_pids() -> list[int]:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|