From 9991ec3c284ef1b67fad6aca571037227ac1557a Mon Sep 17 00:00:00 2001 From: SuperMonster003 Date: Tue, 9 Sep 2025 17:24:48 +0800 Subject: [PATCH] =?UTF-8?q?6.7.0=20-=20Alpha4=20-=20=E6=96=B0=E5=A2=9E=20J?= =?UTF-8?q?S=20=E8=84=9A=E6=9C=AC=E5=B7=A5=E5=85=B7=20(run-scrapers.mjs)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changelog/lang_zh-Hans.json | 11 +- .python/generate_markdown.py | 108 +- .readme/README-ar.md | 75 +- .readme/README-en.md | 75 +- .readme/README-es.md | 75 +- .readme/README-fr.md | 75 +- .readme/README-ja.md | 75 +- .readme/README-ko.md | 77 +- .readme/README-ru.md | 75 +- .readme/README-zh-Hans.md | 75 +- .readme/README-zh-Hant-HK.md | 75 +- .readme/README-zh-Hant-TW.md | 75 +- .readme/common.json | 22 +- .readme/lang_ar.json | 2 +- .readme/lang_en.json | 2 +- .readme/lang_es.json | 2 +- .readme/lang_fr.json | 2 +- .readme/lang_ja.json | 2 +- .readme/lang_ko.json | 4 +- .readme/lang_ru.json | 2 +- .readme/lang_zh-Hans.json | 2 +- .readme/lang_zh-Hant-HK.json | 2 +- .readme/lang_zh-Hant-TW.json | 2 +- .readme/template_readme.md | 47 +- .utils/.gitignore | 2 + ...android-studio-agp-compatibility-table.mjs | 48 + ...e-android-studio-latest-stable-version.mjs | 138 ++ ...e-autojs6-merged-pr-commits-statistics.mjs | 373 ++++ .utils/package-lock.json | 1505 +++++++++++++++++ .utils/package.json | 13 + .utils/run-scrapers.bat | 17 + .utils/run-scrapers.mjs | 175 ++ ...d-inject-agp-gradle-compatibility-list.mjs | 47 + .utils/scrape-and-inject-agp-releases.mjs | 32 + ...-inject-android-studio-agp-version-map.mjs | 44 + ...nd-inject-android-studio-codename_maps.mjs | 480 ++++++ ...scrape-and-inject-embedded-kotlin-list.mjs | 98 ++ ...-inject-java-gradle-compatibility-list.mjs | 62 + .utils/scrape-and-inject-ksp-releases.mjs | 224 +++ .../scrape-and-inject-rhino-engine-data.mjs | 80 + ...ate-readme-template-contributors-table.mjs | 46 + .utils/tsconfig.json | 12 + .utils/utils/anchors.mjs | 263 +++ .utils/utils/async.mjs | 9 + .utils/utils/date.mjs | 23 + .utils/utils/fetch.mjs | 100 ++ .utils/utils/format.mjs | 11 + .utils/utils/properties.mjs | 234 +++ .utils/utils/puppeteer-helpers.mjs | 160 ++ .utils/utils/versioning.mjs | 97 ++ README.md | 75 +- app/build.gradle.kts | 23 +- .../main/assets/modules/dayjs/package.json | 84 - gradle/wrapper/gradle-wrapper.properties | 4 +- settings.gradle.kts | 463 ++--- version.properties | 15 +- 56 files changed, 5167 insertions(+), 752 deletions(-) create mode 100644 .utils/.gitignore create mode 100644 .utils/fetch-and-parse-android-studio-agp-compatibility-table.mjs create mode 100644 .utils/fetch-and-parse-android-studio-latest-stable-version.mjs create mode 100644 .utils/fetch-and-parse-autojs6-merged-pr-commits-statistics.mjs create mode 100644 .utils/package-lock.json create mode 100644 .utils/package.json create mode 100644 .utils/run-scrapers.bat create mode 100644 .utils/run-scrapers.mjs create mode 100644 .utils/scrape-and-inject-agp-gradle-compatibility-list.mjs create mode 100644 .utils/scrape-and-inject-agp-releases.mjs create mode 100644 .utils/scrape-and-inject-android-studio-agp-version-map.mjs create mode 100644 .utils/scrape-and-inject-android-studio-codename_maps.mjs create mode 100644 .utils/scrape-and-inject-embedded-kotlin-list.mjs create mode 100644 .utils/scrape-and-inject-java-gradle-compatibility-list.mjs create mode 100644 .utils/scrape-and-inject-ksp-releases.mjs create mode 100644 .utils/scrape-and-inject-rhino-engine-data.mjs create mode 100644 .utils/scrape-and-update-readme-template-contributors-table.mjs create mode 100644 .utils/tsconfig.json create mode 100644 .utils/utils/anchors.mjs create mode 100644 .utils/utils/async.mjs create mode 100644 .utils/utils/date.mjs create mode 100644 .utils/utils/fetch.mjs create mode 100644 .utils/utils/format.mjs create mode 100644 .utils/utils/properties.mjs create mode 100644 .utils/utils/puppeteer-helpers.mjs create mode 100644 .utils/utils/versioning.mjs delete mode 100644 app/src/main/assets/modules/dayjs/package.json diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index ff7d3e24..ed001e56 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -1,12 +1,13 @@ { "$data": { "v6.7.0": { - "released_date": "2025/07/22", + "released_date": "2025/09/09", "feature": [ "zip 模块, 用于文件压缩与解压缩操作 (Ref to [Auto.js Pro](https://g.pro.autojs.org/)) (参阅 项目文档 > [Zip](https://docs.autojs6.com/#/zip))", "mediainfo 模块, 用于查看媒体文件的详细信息 (参阅 项目文档 > [媒体信息](https://docs.autojs6.com/#/mediainfo))", "UiObject#isShifted 方法, 用于检测控件位置变化", - "设置页面支持应用启动器图标设置选项 _[`issue #405`](http://issues.autojs6.com/405)_" + "设置页面支持应用启动器图标设置选项 _[`issue #405`](http://issues.autojs6.com/405)_", + "JS 脚本工具 (run-scrapers.mjs) 用于自动更新 Gradle 构建脚本锚点数据/README 通用数据/README 模板数据" ], "fix": [ "使用 XML 语法将 JavaScript 表达式作为属性值时, this 对象可能出现指向错误的问题", @@ -29,9 +30,9 @@ "应用启动器图标支持自适应图标特性 _[`issue #405`](http://issues.autojs6.com/405)_" ], "dependency": [ - "附加 Androidx Core (KTX) 版本 1.16.0", - "升级 Gradle 版本 8.14 -> 8.14.2", - "升级 Apache Commons 版本 3.16.0 -> 3.17.0", + "附加 Androidx Core (KTX) 版本 1.15.0", + "升级 Gradle 版本 8.14 -> 8.14.3", + "升级 Apache Commons 版本 3.16.0 -> 3.18.0", "升级 Retrofit2 Retrofit 版本 2.11.0 -> 2.12.0", "升级 Retrofit2 Converter Gson 版本 2.11.0 -> 2.12.0", "升级 Retrofit2 RxJava2 版本 2.11.0 -> 2.12.0", diff --git a/.python/generate_markdown.py b/.python/generate_markdown.py index b6157f28..64f6dce9 100644 --- a/.python/generate_markdown.py +++ b/.python/generate_markdown.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- import locale -import sys # 设置语言环境为 UTF-8 locale.setlocale(locale.LC_ALL, '') @@ -8,9 +7,6 @@ encoding = locale.getpreferredencoding() if encoding.lower() != 'utf-8': # 强制使用 UTF-8 编码 locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') - # 如果 locale 无法设置, 使用以下方式 - # sys.stdout.reconfigure(encoding='utf-8') - # sys.stderr.reconfigure(encoding='utf-8') from jinja2 import Environment, FileSystemLoader, StrictUndefined from collections import defaultdict @@ -53,7 +49,101 @@ env = Environment( undefined=StrictUndefined, ) -# 读取模板文件 +# 从 version.properties 读取 JDK 相关限制, 以便注入到 merged_data +def _load_version_properties(props_path: str) -> dict: + props = {} + try: + with open(props_path, 'r', encoding='utf-8') as f: + for raw in f.read().splitlines(): + line = raw.strip() + if not line or line.startswith('#') or line.startswith('!'): + continue + sep = line.find('=') + if sep <= 0: + continue + key = line[:sep].strip() + val = line[sep + 1 :].strip() + props[key] = val + except FileNotFoundError: + print(f'[warn] version.properties not found at {props_path}, skip injecting JDK constraints') + except Exception as e: + print(f'[warn] Failed to read version.properties: {e}') + return props + +_version_props_path = os.path.join(project_root_dir, 'version.properties') +_version_props = _load_version_properties(_version_props_path) + +_jdk_min_supported = _version_props.get('JAVA_VERSION_MIN_SUPPORTED') +_jdk_min_suggested = _version_props.get('JAVA_VERSION_MIN_SUGGESTED') +_jdk_max_supported = _version_props.get('JAVA_VERSION_MAX_SUPPORTED') +_android_studio_min_supported = _version_props.get('MIN_SUPPORTED_ANDROID_STUDIO_IDE_VERSION') +_intellij_idea_min_supported = _version_props.get('MIN_SUPPORTED_INTELLIJ_IDEA_IDE_VERSION') + +# 在加载模板前, 先更新模板中的 Android Studio 与 IntelliJ IDEA Badge 版本 +def update_readme_badge_versions(): + """ + 读取 .readme/template_readme.md, 将 Android Studio 与 IntelliJ IDEA 的徽标版本替换为 + version.properties 中的最小支持版本: + - MIN_SUPPORTED_ANDROID_STUDIO_IDE_VERSION + - MIN_SUPPORTED_INTELLIJ_IDEA_IDE_VERSION + """ + template_path = os.path.join(readme_root_dir, 'template_readme.md') + try: + with open(template_path, 'r', encoding='utf-8') as f: + data = f.read() + except FileNotFoundError: + print(f'[warn] template_readme.md not found at {template_path}, skip badge update') + return + except Exception as e: + print(f'[warn] Failed to read template_readme.md: {e}') + return + + # 与原逻辑等价的正则片段 + prefix = r']*?src="https://img\.shields\.io/badge/' + android_fragment = r'android(?:%20|\s)studio' + idea_fragment = r'intellij(?:%20|\s)idea' + # 捕获 2024.1 或 2024.1.2 这类版本, 末尾带一个 '+' + version_group = r'.*?-([0-9]{4}\.[0-9]+(?:\.[0-9]+)?)\+' + + re_android = re.compile(prefix + android_fragment + version_group, re.IGNORECASE) + re_idea = re.compile(prefix + idea_fragment + version_group, re.IGNORECASE) + + original = data + + if _android_studio_min_supported: + def _repl_android(m): + old = m.group(1) + if old != _android_studio_min_supported: + return m.group(0).replace(old, _android_studio_min_supported) + return m.group(0) + data = re_android.sub(_repl_android, data) + + if _intellij_idea_min_supported: + def _repl_idea(m): + old = m.group(1) + if old != _intellij_idea_min_supported: + return m.group(0).replace(old, _intellij_idea_min_supported) + return m.group(0) + data = re_idea.sub(_repl_idea, data) + + if data == original: + return + + try: + with open(template_path, 'w', encoding='utf-8') as f: + f.write(data) + print(f'Updated badge(s) in {template_path}') + except Exception as e: + print(f'[warn] Failed to write template_readme.md: {e}') + +# 执行模板内徽标版本更新, 并清空 Jinja2 缓存后再获取模板 +update_readme_badge_versions() +try: + env.cache.clear() # 确保重新读取更新后的模板文件 +except Exception: + pass + +# 读取模板文件 (在更新徽标版本之后) template_readme = env.get_template('template_readme.md') template_changelog = env.get_template('template_changelog.md') @@ -111,6 +201,14 @@ def init_languages(): # 合并共用 JSON 数据 merged_data = {**common_data, **processed_data} + # 注入 JDK 版本约束 (来自 version.properties) + if _jdk_min_supported is not None: + merged_data['jdk_min_supported'] = str(_jdk_min_supported) + if _jdk_min_suggested is not None: + merged_data['jdk_min_suggested'] = str(_jdk_min_suggested) + if _jdk_max_supported is not None: + merged_data['jdk_max_supported'] = str(_jdk_max_supported) + # 处理日期转换标记 for key, value in merged_data.items(): if key.startswith('var_date_'): diff --git a/.readme/README-ar.md b/.readme/README-ar.md index 3c0bd085..db408794 100644 --- a/.readme/README-ar.md +++ b/.readme/README-ar.md @@ -8,16 +8,16 @@

أداة أتمتة JavaScript لنظام Android مدعومة بخدمة الوصول

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | التواريخ في الجدول هي تقديرات وقد تختلف عن الواقع. @@ -76,7 +76,7 @@ في الجدول، تشير البيانات في العمود `تاريخ نهاية التطوير` التي تحتوي على أقواس مربعة (`[]`) إلى أن مشروع المصدر المفتوح غير متاح مؤقتًا. -في الجدول، يتم احتساب البيانات في العمود `فترة الصيانة النشطة` التي تحتوي على أقواس زاوية (`<>`) حتى 17 August 2025. +في الجدول، يتم احتساب البيانات في العمود `فترة الصيانة النشطة` التي تحتوي على أقواس زاوية (`<>`) حتى 9 September 2025. ****** @@ -133,7 +133,7 @@ * تكييف ألوان الموضوع [ التجميع / الموقع / البحث / السجل / التكييف التلقائي للسطوع والتباين / ... ] * دعم وضع الليل [ صفحة الإعدادات / صفحة الوثائق / صفحة تحليل التخطيط / النافذة العائمة / ... ] * دعم الاتصال بـ [المكون الإضافي لـ VSCode](http://vscext-project.autojs6.com) بطرق الاتصال عبر الشبكة المحلية (LAN) و ADB -* تم ترقية محرك [Rhino](https://github.com/mozilla/rhino/) من [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) إلى [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* تم ترقية محرك [Rhino](https://github.com/mozilla/rhino/) من [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) إلى [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (تم التحديث في 11 April 2025) * دعم هروب نقطة الرمز Unicode [للأحرف متعددة المستويات](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) ```javascript '\u{1D160}'; /* تمثل "𝅘𝅥𝅮", طريقة تقليدية: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ #### تحضير Android Studio -قم بتنزيل إصدار `Android Studio Narwhal Feature Drop | 2025.1.2` (حدد أحدها حسب الحاجة): +قم بتنزيل إصدار `Android Studio Narwhal 3 Feature Drop | 2025.1.3` (حدد أحدها حسب الحاجة): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> ملاحظة: تاريخ الإصدار بالنسخة المذكورة أعلاه هو 31 July 2025. إذا كنت بحاجة إلى تنزيل إصدار آخر، أو إذا كان الرابط المذكور غير صالح، يمكنك زيارة [أرشيف إصدارات Android Studio](https://developer.android.com/studio/archive?hl=en). +> ملاحظة: تاريخ الإصدار بالنسخة المذكورة أعلاه هو 2 September 2025. إذا كنت بحاجة إلى تنزيل إصدار آخر، أو إذا كان الرابط المذكور غير صالح، يمكنك زيارة [أرشيف إصدارات Android Studio](https://developer.android.com/studio/archive?hl=en). قم بتثبيت أو فك ضغط الملف المذكور سابقًا، ثم قم بتشغيل برنامج Android Studio (مثل `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ File (ملف) | Settings (إعدادات) | Appearance & Behavior (المظهر #### تحضير JDK -يعتمد مشروع AutoJs6 على إصدار `JDK (مجموعة تطوير جافا)` بإصدار لا يقل عن `17`، ولكن يفضل الإصدار الذي لا يقل عن `19`. +يعتمد مشروع AutoJs6 على إصدار `JDK (مجموعة تطوير جافا)` بإصدار لا يقل عن `17`، ولكن يفضل الإصدار الذي لا يقل عن `21`. -اعتبارًا من 17 August 2025، الإصدار الأقصى المدعوم من JDK لمشروع AutoJs6 هو `24`. +اعتبارًا من 9 September 2025، الإصدار الأقصى المدعوم من JDK لمشروع AutoJs6 هو `24`. > ملاحظة: إذا كان نظام الكمبيوتر يحتوي على JDK والإصدار يفي بالمتطلبات المذكورة أعلاه، فيمكنك تخطي هذا القسم. @@ -514,19 +514,19 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk شكرًا لكل من ساهم في تطوير مشروع AutoJs6. -| المساهمون | عدد الإرساليات | أحدث الإرساليات | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| المساهمون | عدد الإرساليات | أحدث الإرساليات | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -تم تحديث البيانات في 27 May 2025. +تم تحديث البيانات في 6 September 2025. تم تصنيف سجلات البيانات بترتيب تنازلي حسب `أحدث الإرساليات`. @@ -547,11 +547,12 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-en.md b/.readme/README-en.md index 9f26d3a4..bd54346c 100644 --- a/.readme/README-en.md +++ b/.readme/README-en.md @@ -8,16 +8,16 @@

JavaScript automation tool supporting accessibility service on the Android platform

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ The table below lists some Auto.js-related projects (sorted by development date) | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | The dates in the table are estimated and may differ from actual dates. @@ -76,7 +76,7 @@ Auto.js Pro 7/8/9 in the table are paid versions, and the rest are free open-sou In the table, data in the `Development End Date` column that contains square brackets (`[]`) indicates that the open-source project is temporarily inaccessible. -In the table, data in the `Active Maintenance` column that contains angle brackets (`<>`) is calculated up to Aug 17, 2025. +In the table, data in the `Active Maintenance` column that contains angle brackets (`<>`) is calculated up to Sep 9, 2025. ****** @@ -133,7 +133,7 @@ Compared to the final open-source version `4.1.1 Alpha2` of Auto.js, the main up * Theme color adaptation [ Grouping / Location / Search / History / Automatic Adaptation of Brightness and Contrast / ... ] * Night mode adaptation [ Settings page / Documentation page / Layout analysis page / Floating window / ... ] * [VSCode plugin](http://vscext-project.autojs6.com) supports both client (LAN) and server (LAN/ADB) connection methods -* [Rhino](https://github.com/mozilla/rhino/) engine upgraded from [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) to [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* [Rhino](https://github.com/mozilla/rhino/) engine upgraded from [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) to [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (Updated on Apr 11, 2025) * Unicode [code point](https://developer.mozilla.org/en-US/docs/Glossary/Code_point) escape support for [supplementary plane](https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane) characters ```javascript '\u{1D160}'; /* stands for "𝅘𝅥𝅮", traditional method: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ This section introduces the compilation and build methods of the AutoJs6 open-so #### Android Studio Preparation -Download `Android Studio Narwhal Feature Drop | 2025.1.2` version (choose one as needed): +Download `Android Studio Narwhal 3 Feature Drop | 2025.1.3` version (choose one as needed): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> Note: The release date for the above version is Jul 31, 2025. To download other versions, or if the above link is invalid, you can visit the [Android Studio release archive](https://developer.android.com/studio/archive?hl=en) page. +> Note: The release date for the above version is Sep 2, 2025. To download other versions, or if the above link is invalid, you can visit the [Android Studio release archive](https://developer.android.com/studio/archive?hl=en) page. Install or extract the above file, then run the Android Studio software (e.g., `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ Check `Show Package Details`, click NDK and CMake respectively to ensure the cor #### JDK Preparation -The `JDK (Java Development Kit)` version required for the AutoJs6 project should be at least `17`, but `19` or higher is recommended. +The `JDK (Java Development Kit)` version required for the AutoJs6 project should be at least `17`, but `21` or higher is recommended. -As of Aug 17, 2025, AutoJs6 supports up to version `24` of the JDK. +As of Sep 9, 2025, AutoJs6 supports up to version `24` of the JDK. > Note: If the JDK is already installed on the computer system and the version meets the above requirements, this section can be skipped. @@ -514,19 +514,19 @@ Existing script development projects can serve as references and inspire creativ Thank you to everyone who contributed to the AutoJs6 project development. -| Contributors | Number of Commits | Recent Submissions | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| Contributors | Number of Commits | Recent Submissions | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -Data updated on May 27, 2025. +Data updated on Sep 6, 2025. Data entries sorted in descending order by `recent submissions`. @@ -547,11 +547,12 @@ Some contributors do not appear correctly in the [GitHub Contributors](https://g - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-es.md b/.readme/README-es.md index 4914dd59..ae8816f5 100644 --- a/.readme/README-es.md +++ b/.readme/README-es.md @@ -8,16 +8,16 @@

Herramienta de automatización JavaScript que soporta servicios de accesibilidad en la plataforma Android

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ La siguiente tabla enumera algunos proyectos relacionados con Auto.js (ordenados | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | Las fechas en la tabla son estimadas y pueden no coincidir con las reales. @@ -76,7 +76,7 @@ En la tabla, Auto.js Pro 7/8/9 son versiones pagas, mientras que las demás son En la tabla, los datos de la columna `Fecha de finalización del desarrollo` que contienen corchetes (`[]`) indican que el proyecto de código abierto no está temporalmente accesible. -En la tabla, los datos de la columna `Mantenimiento activo` que contienen paréntesis angulares (`<>`) se han calculado hasta 17 de August de 2025. +En la tabla, los datos de la columna `Mantenimiento activo` que contienen paréntesis angulares (`<>`) se han calculado hasta 9 de September de 2025. ****** @@ -133,7 +133,7 @@ En comparación con la versión final de Auto.js `4.1.1 Alpha2`, AutoJs6 ha real * Adaptation des couleurs du thème [ Groupement / Localisation / Recherche / Historique / Adaptation automatique de la luminosité et du contraste / ... ] * Soporte para modo nocturno en varias páginas [ página de configuración / página de documentación / página de análisis de diseño / ventana flotante / ... ] * El [complemento de VSCode](http://vscext-project.autojs6.com) soporta conexiones cliente (LAN) y servidor (LAN/ADB) -* El motor [Rhino](https://github.com/mozilla/rhino/) se ha actualizado de [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) a [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* El motor [Rhino](https://github.com/mozilla/rhino/) se ha actualizado de [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) a [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (actualizado el 11 de April de 2025) * Soporte para secuencias de escape de [puntos de código](https://developer.mozilla.org/zh-CN/docs/Glossary/Code_point) Unicode [ plano suplementario](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) ```javascript '\u{1D160}'; /* significa "𝅘𝅥𝅮", método tradicional: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ Esta sección toma como ejemplo Android Studio para presentar los métodos de co #### Preparación de Android Studio -Descarga la versión `Android Studio Narwhal Feature Drop | 2025.1.2` (elige una según tus necesidades): +Descarga la versión `Android Studio Narwhal 3 Feature Drop | 2025.1.3` (elige una según tus necesidades): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> Nota: La fecha de lanzamiento de la versión anterior es el 31 de July de 2025. Para descargar otras versiones, o si los enlaces anteriores ya no funcionan, puedes visitar la página del [Archivo de versiones de Android Studio](https://developer.android.com/studio/archive?hl=en). +> Nota: La fecha de lanzamiento de la versión anterior es el 2 de September de 2025. Para descargar otras versiones, o si los enlaces anteriores ya no funcionan, puedes visitar la página del [Archivo de versiones de Android Studio](https://developer.android.com/studio/archive?hl=en). Instala o descomprime los archivos mencionados anteriormente y ejecuta el software Android Studio (por ejemplo, `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ Marca `Show Package Details (Mostrar detalles del paquete)`, haz clic en NDK y C #### Preparación del JDK -La versión mínima requerida del `JDK (Kit de Desarrollo de Java)` para el proyecto AutoJs6 es `17`, pero se recomienda usar una versión no inferior a `19`. +La versión mínima requerida del `JDK (Kit de Desarrollo de Java)` para el proyecto AutoJs6 es `17`, pero se recomienda usar una versión no inferior a `21`. -Hasta el 17 de August de 2025, AutoJs6 soporta hasta la versión `24` de JDK. +Hasta el 9 de September de 2025, AutoJs6 soporta hasta la versión `24` de JDK. > Nota: Si el sistema ya tiene instalado JDK y cumple con los requisitos anteriores, puedes omitir esta sección. @@ -514,19 +514,19 @@ Los proyectos de desarrollo de scripts existentes pueden servir como referencia Agradecemos a todos los que han contribuido al desarrollo del proyecto AutoJs6. -| Contribuyentes | Número de commits | Últimas presentaciones | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| Contribuyentes | Número de commits | Últimas presentaciones | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -Datos actualizados el 27 de May de 2025. +Datos actualizados el 6 de September de 2025. Las entradas de datos están ordenadas en orden descendente por `últimas presentaciones`. @@ -547,11 +547,12 @@ Algunos contribuyentes no aparecen en [GitHub Contributors](https://github.com/S - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-fr.md b/.readme/README-fr.md index 64797fbc..33c9290d 100644 --- a/.readme/README-fr.md +++ b/.readme/README-fr.md @@ -8,16 +8,16 @@

Outil d'automatisation JavaScript prenant en charge les services d'accessibilité sur la plateforme Android

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ Le tableau suivant énumère certains projets liés à Auto.js (classés par dat | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | Les dates dans le tableau sont des estimations et peuvent différer des dates réelles. @@ -76,7 +76,7 @@ Dans le tableau, Auto.js Pro 7/8/9 sont des versions payantes, les autres sont d Dans le tableau, les données de la colonne `Date de fin de développement` contenant des crochets (`[]`) indiquent que le projet open source est temporairement inaccessible. -Dans le tableau, les données de la colonne `Maintenance active` contenant des chevrons (`<>`) sont calculées jusqu’au 17 August 2025. +Dans le tableau, les données de la colonne `Maintenance active` contenant des chevrons (`<>`) sont calculées jusqu’au 9 September 2025. ****** @@ -133,7 +133,7 @@ Par rapport à la version finale open source de Auto.js `4.1.1 Alpha2`, AutoJs6 * Adaptación del color del tema [ Agrupación / Ubicación / Búsqueda / Historial / Adaptación automática de brillo y contraste / ... ] * Adaptation du mode nuit [ Paramètres / Documentation / Analyse de la disposition / Fenêtre flottante / ... ] * Prise en charge de l'extension [VSCode](http://vscext-project.autojs6.com) pour la connexion client (LAN) et serveur (LAN/ADB) -* Le moteur [Rhino](https://github.com/mozilla/rhino/) a été mis à niveau de [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) à [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* Le moteur [Rhino](https://github.com/mozilla/rhino/) a été mis à niveau de [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) à [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (mis à jour le 11 April 2025) * [Échappements](https://developer.mozilla.org/zh-CN/docs/Glossary/Code_point) pour les points de code Unicode supportent les caractères du [plan complémentaire](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) ```javascript '\u{1D160}'; /* signifie "𝅘𝅥𝅮", méthode traditionnelle: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ Cette section présente la méthode de compilation et de construction du projet #### Préparation de Android Studio -Téléchargez la version `Android Studio Narwhal Feature Drop | 2025.1.2` (choisissez-en une selon vos besoins): +Téléchargez la version `Android Studio Narwhal 3 Feature Drop | 2025.1.3` (choisissez-en une selon vos besoins): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> Note : La version mentionnée ci-dessus a été publiée le 31 July 2025. Pour télécharger d'autres versions ou si le lien ci-dessus n'est plus valide, visitez la page [archive des versions de Android Studio](https://developer.android.com/studio/archive?hl=en). +> Note : La version mentionnée ci-dessus a été publiée le 2 September 2025. Pour télécharger d'autres versions ou si le lien ci-dessus n'est plus valide, visitez la page [archive des versions de Android Studio](https://developer.android.com/studio/archive?hl=en). Installez ou extrayez le fichier ci-dessus, exécutez Android Studio (par exemple `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ Cochez `Show Package Details (afficher les détails du package)`, puis cliquez r #### Préparation du JDK -La version de JDK (Kit de développement Java) requise pour le projet AutoJs6 doit être au moins `17`, mais il est recommandé d'avoir au moins `19`. +La version de JDK (Kit de développement Java) requise pour le projet AutoJs6 doit être au moins `17`, mais il est recommandé d'avoir au moins `21`. -À partir du 17 August 2025, AutoJs6 prend en charge la version maximale de JDK `24`. +À partir du 9 September 2025, AutoJs6 prend en charge la version maximale de JDK `24`. > Note : Si le JDK est déjà installé sur le système informatique et que la version répond aux exigences ci-dessus, vous pouvez ignorer cette section. @@ -514,19 +514,19 @@ Les projets de développement de scripts existants peuvent servir de référence Merci à chaque contributeur participant au développement du projet AutoJs6. -| Contributeurs | Nombre de commits | Soumissions récentes | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| Contributeurs | Nombre de commits | Soumissions récentes | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -Données mises à jour le 27 May 2025. +Données mises à jour le 6 September 2025. Les entrées de données sont triées par `soumissions récentes` en ordre décroissant. @@ -547,11 +547,12 @@ Certains contributeurs ne figurant pas correctement dans [GitHub Contributors](h - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-ja.md b/.readme/README-ja.md index 340cc384..6ec3bc2b 100644 --- a/.readme/README-ja.md +++ b/.readme/README-ja.md @@ -8,16 +8,16 @@

アクセシビリティサービスをサポートする Android プラットフォーム用の JavaScript 自動化ツール

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ AutoJs6 は `2021/12/01` に Auto.js 最終プロジェクトを基に二次開 | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | 表の日付は推定値であり, 実際とは異なる場合があります. @@ -76,7 +76,7 @@ AutoJs6 は `2021/12/01` に Auto.js 最終プロジェクトを基に二次開 表では, `開発終了日` 列に角括弧 (`[]`) を含むデータは, オープンソースプロジェクトが一時的にアクセス不能であることを示します. -表では, `アクティブメンテナンス期間` 列に山括弧 (`<>`) を含むデータは, 統計の締め日が 2025 年 8 月 17 日 であることを示します. +表では, `アクティブメンテナンス期間` 列に山括弧 (`<>`) を含むデータは, 統計の締め日が 2025 年 9 月 9 日 であることを示します. ****** @@ -133,7 +133,7 @@ Auto.js の最終オープンソースバージョン `4.1.1 Alpha2` と比較 * テーマカラーの適応 [ グループ化 / ロケーション / 検索 / 履歴 / 明るさとコントラストの自動適応 / ... ] * ナイトモード対応 [ 設定ページ / ドキュメントページ / レイアウト分析ページ / 浮動ウィンドウ / ... ] * [VSCodeプラグイン](http://vscext-project.autojs6.com)がクライアント (LAN)とサーバ (LAN/ADB)接続方法をサポート -* [Rhino](https://github.com/mozilla/rhino/)エンジンが [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) から [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) にアップグレードされました +* [Rhino](https://github.com/mozilla/rhino/)エンジンが [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) から [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (2025 年 4 月 11 日 更新) にアップグレードされました * Unicode [コードポイント](https://developer.mozilla.org/ja/docs/Glossary/Code_point)エスケープのサポート [補助平面](https://ja.wikipedia.org/wiki/多言語面#補助平面)文字 ```javascript '\u{1D160}'; /* を表します "𝅘𝅥𝅮", 従来の方法: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ AutoJs6 オープンソース プロジェクトのデバッグや開発が必 #### Android Studioの準備 -`Android Studio Narwhal Feature Drop | 2025.1.2` バージョンをダウンロードしてください (いずれかを選択): +`Android Studio Narwhal 3 Feature Drop | 2025.1.3` バージョンをダウンロードしてください (いずれかを選択): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> 注: 上述バージョンのリリース日は 2025 年 7 月 31 日 です. その他のバージョンをダウンロードするか, 上記のリンクが失効している場合は, [Android Studioリリースアーカイブ](https://developer.android.com/studio/archive?hl=en)のページをご覧ください. +> 注: 上述バージョンのリリース日は 2025 年 9 月 2 日 です. その他のバージョンをダウンロードするか, 上記のリンクが失効している場合は, [Android Studioリリースアーカイブ](https://developer.android.com/studio/archive?hl=en)のページをご覧ください. 上記のファイルをインストールまたは解凍し, Android Studio ソフトウェアを実行します (例: `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ File (ファイル) | Settings (設定) | Appearance & Behavior (外観と動作 #### JDKの準備 -AutoJs6プロジェクトが依存する `JDK (Java開発キット)` のリリースバージョンは少なくとも `17` で, それ以下のバージョンは推奨されませんが, 最低でも `19` の使用を推奨します. +AutoJs6プロジェクトが依存する `JDK (Java開発キット)` のリリースバージョンは少なくとも `17` で, それ以下のバージョンは推奨されませんが, 最低でも `21` の使用を推奨します. -2025 年 8 月 17 日 現在, AutoJs6がサポートする最大のJDKバージョンは `24` です. +2025 年 9 月 9 日 現在, AutoJs6がサポートする最大のJDKバージョンは `24` です. > 注: コンピュータシステムに適切なバージョンのJDKがインストールされている場合, この節の内容をスキップできます. @@ -514,19 +514,19 @@ AutoJs6に関するAPIおよび使用方法については, 常にアプリケ AutoJs6 プロジェクト開発に参加したすべての貢献者に感謝します. -| 貢献者 | コミット数 | 最近の提出 | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| 貢献者 | コミット数 | 最近の提出 | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -データは 2025 年 5 月 27 日 に更新されました. +データは 2025 年 9 月 6 日 に更新されました. データ項目は `最近の提出` の降順で並べ替えられます. @@ -547,11 +547,12 @@ AutoJs6 プロジェクト開発に参加したすべての貢献者に感謝し - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-ko.md b/.readme/README-ko.md index b169ccbc..8e6a5d2d 100644 --- a/.readme/README-ko.md +++ b/.readme/README-ko.md @@ -8,16 +8,16 @@

안드로이드 플랫폼에서 접근성 서비스를 지원하는 JavaScript 자동화 도구

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ AutoJs6는 Auto.js 최종 프로젝트를 기반으로 `2021/12/01` 에 다시 | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | 표에 표시된 날짜는 예상 날짜로, 실제 날짜와 다를 수 있습니다. @@ -76,7 +76,7 @@ AutoJs6는 Auto.js 최종 프로젝트를 기반으로 `2021/12/01` 에 다시 표에서 `개발 종료 날짜` 열에 대괄호 (`[]`) 가 포함된 데이터는 오픈 소스 프로젝트가 일시적으로 접근 불가함을 나타냅니다. -표에서 `활성 유지보수 기간` 열에 꺾쇠괄호 (`<>`) 가 포함된 데이터는 통계 기준일이 2025 년 8 월 17 일 임을 나타냅니다. +표에서 `활성 유지보수 기간` 열에 꺾쇠괄호 (`<>`) 가 포함된 데이터는 통계 기준일이 2025 년 9 월 9 일 임을 나타냅니다. ****** @@ -95,7 +95,7 @@ AutoJs6는 Auto.js 최종 프로젝트를 기반으로 `2021/12/01` 에 다시 * 스크립트 파일 또는 프로젝트를 APK 파일로 패키징 지원 * Root 권한을 이용한 기능 확장 지원 (화면 클릭/스크롤/녹화/Shell) * Tasker 플러그인으로 사용 가능 -* VSCode와 연결하여 데스크톱 개발 지원 ( [AutoJs6-VSCode-Extension](http://vscext-project.autojs6.com) 플러그인 필요) +* VSCode와 연결하여 데스크톱 개발 지원 ([AutoJs6-VSCode-Extension](http://vscext-project.autojs6.com) 플러그인 필요) ****** @@ -133,7 +133,7 @@ Auto.js 최종 오픈 소스 버전 `4.1.1 Alpha2` 와 비교하여 AutoJs6는 * 테마 색상 적응 [ 그룹화 / 위치 / 검색 / 기록 / 밝기 및 대비 자동 적응 / ...] * 야경 모드 지원 [ 설정 페이지 / 문서 페이지 / 레이아웃 분석 페이지 / 플로팅 창 / ... ] * [VSCode 플러그인](http://vscext-project.autojs6.com) 지원 클라이언트 (LAN) 및 서버 (LAN/ADB) 연결 방식 -* [Rhino](https://github.com/mozilla/rhino/) 엔진을 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release)에서 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3)로 업그레이드 +* [Rhino](https://github.com/mozilla/rhino/) 엔진을 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 에서 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) 로 업그레이드 (2025 년 4 월 11 일 업데이트됨) * 유니코드 [코드 포인트](https://developer.mozilla.org/zh-CN/docs/Glossary/Code_point) 이스케이프 지원 [보조 평면](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) 문자 ```javascript '\u{1D160}'; /* 의 의미 "𝅘𝅥𝅮", 전통적인 방법: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ AutoJs6 오픈 소스 프로젝트를 디버깅하거나 개발하려면 [Androi #### Android Studio 준비 -`Android Studio Narwhal Feature Drop | 2025.1.2` 버전을 다운로드하십시오 (필요에 따라 선택): +`Android Studio Narwhal 3 Feature Drop | 2025.1.3` 버전을 다운로드하십시오 (필요에 따라 선택): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> 메모: 상기 버전 출시 날짜는 2025 년 7 월 31 일입니다. 다른 버전을 다운로드하거나 상기 링크가 만료되었을 경우, [Android Studio 릴리스 아카이브](https://developer.android.com/studio/archive?hl=en) 페이지를 방문하십시오. +> 메모: 상기 버전 출시 날짜는 2025 년 9 월 2 일입니다. 다른 버전을 다운로드하거나 상기 링크가 만료되었을 경우, [Android Studio 릴리스 아카이브](https://developer.android.com/studio/archive?hl=en) 페이지를 방문하십시오. 위의 파일을 설치하거나 압축을 풀고 Android Studio 소프트웨어를 실행합니다 (예: `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ File (파일) | Settings (설정) | Appearance & Behavior (모양 및 동작) | #### JDK 준비 -AutoJs6 프로젝트는 `JDK (Java 개발 도구 키트)` 버전이 `17` 이상이어야 하지만, `19` 이상을 권장합니다. +AutoJs6 프로젝트는 `JDK (Java 개발 도구 키트)` 버전이 `17` 이상이어야 하지만, `21` 이상을 권장합니다. -2025 년 8 월 17 일 기준으로, AutoJs6이 지원하는 최대 JDK 버전은 `24` 입니다. +2025 년 9 월 9 일 기준으로, AutoJs6이 지원하는 최대 JDK 버전은 `24` 입니다. > 메모: 시스템에 JDK가 설치되어 있고, 버전이 위의 요구 사항을 충족하는 경우, 이 섹션을 건너뛸 수 있습니다. @@ -514,19 +514,19 @@ PC에서 스크립트를 작성하고 디버깅하려면 VSCode 플러그인을 AutoJs6 프로젝트 개발에 참여한 모든 기여자분들께 감사합니다. -| 기여자 | 커밋 수 | 최근 제출 | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| 기여자 | 커밋 수 | 최근 제출 | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -데이터 갱신일: 2025 년 5 월 27 일. +데이터 갱신일: 2025 년 9 월 6 일. 데이터 항목은 `최근 제출` 순으로 내림차순 정렬됩니다. @@ -547,11 +547,12 @@ AutoJs6 프로젝트 개발에 참여한 모든 기여자분들께 감사합니 - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-ru.md b/.readme/README-ru.md index 79fb0aa8..bcf509ad 100644 --- a/.readme/README-ru.md +++ b/.readme/README-ru.md @@ -8,16 +8,16 @@

Инструмент автоматизации на языке JavaScript для платформы Android с поддержкой службы доступности

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ AutoJs6 разработан на основе финальной версии | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | Даты в таблице являются оценочными и могут отличаться от фактических. @@ -76,7 +76,7 @@ AutoJs6 разработан на основе финальной версии В таблице данные в столбце `Дата окончания разработки`, содержащие квадратные скобки (`[]`), означают, что открытый проект временно недоступен. -В таблице данные в столбце `Период активного обслуживания`, содержащие угловые скобки (`<>`), учитываются по состоянию на 17 August 2025 года. +В таблице данные в столбце `Период активного обслуживания`, содержащие угловые скобки (`<>`), учитываются по состоянию на 9 September 2025 года. ****** @@ -133,7 +133,7 @@ AutoJs6 разработан на основе финальной версии * Адаптация темы [ Группировка / Локация / Поиск / История / Автоматическая адаптация яркости и контрастности / ... ] * Поддержка ночного режима [ страница настроек / страница документации / страница анализа макета / плавающее окно / ... ] * Плагин [VSCode](http://vscext-project.autojs6.com) поддерживает варианты подключения клиента (LAN) и сервера (LAN/ADB) -* Движок [Rhino](https://github.com/mozilla/rhino/) обновлен с версии [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) до версии [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* Движок [Rhino](https://github.com/mozilla/rhino/) обновлен с версии [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) до версии [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (обновлено 11 April 2025 года) * Поддержка Unicode для [экранирования кодовых точек](https://developer.mozilla.org/zh-CN/docs/Glossary/Code_point) и символов [в дополнительных плоскостях](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) ```javascript '\u{1D160}'; /* означает "𝅘𝅥𝅮", традиционный метод: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ AutoJs6 разработан на основе финальной версии #### Подготовка Android Studio -Скачайте версию `Android Studio Narwhal Feature Drop | 2025.1.2` (выберите одну из них по необходимости): +Скачайте версию `Android Studio Narwhal 3 Feature Drop | 2025.1.3` (выберите одну из них по необходимости): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> Примечание: Указанная версия была выпущена 31 July 2025 года. Для загрузки других версий или если указанная ссылка недействительна, посетите страницу [архива версий Android Studio](https://developer.android.com/studio/archive?hl=en). +> Примечание: Указанная версия была выпущена 2 September 2025 года. Для загрузки других версий или если указанная ссылка недействительна, посетите страницу [архива версий Android Studio](https://developer.android.com/studio/archive?hl=en). Установите или распакуйте указанные файлы, запустите программное обеспечение Android Studio (например, `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ File (Файл) | Settings (Настройки) | Appearance & Behavior (Вне #### Подготовка JDK -Для проекта AutoJs6 требуется версия `JDK (Java Development Kit)` не ниже `17`, но рекомендуется не ниже `19`. +Для проекта AutoJs6 требуется версия `JDK (Java Development Kit)` не ниже `17`, но рекомендуется не ниже `21`. -По состоянию на 17 August 2025 года AutoJs6 поддерживает JDK максимальной версии `24`. +По состоянию на 9 September 2025 года AutoJs6 поддерживает JDK максимальной версии `24`. > Примечание: Если на компьютере уже установлен JDK и версия соответствует указанным требованиям, этот раздел можно пропустить. @@ -514,19 +514,19 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk Благодарим всех участников проекта AutoJs6 за их вклад. -| Участники | Количество коммитов | Последние коммиты | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| Участники | Количество коммитов | Последние коммиты | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -Данные обновлены на 27 May 2025 года. +Данные обновлены на 6 September 2025 года. Данные отсортированы по `последним отправкам` в порядке убывания. @@ -547,11 +547,12 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-zh-Hans.md b/.readme/README-zh-Hans.md index 6219233b..2c979743 100644 --- a/.readme/README-zh-Hans.md +++ b/.readme/README-zh-Hans.md @@ -8,16 +8,16 @@

Android 平台支持无障碍服务的 JavaScript 自动化工具

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | 表格中的日期为预估值, 实际可能存在出入. @@ -76,7 +76,7 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 表格中 `终止开发日期` 列包含方括号 (`[]`) 的数据, 表示开源项目暂时无法访问. -表格中 `活跃维护期` 列包含尖括号 (`<>`) 的数据, 其统计截止日期为 2025 年 8 月 17 日. +表格中 `活跃维护期` 列包含尖括号 (`<>`) 的数据, 其统计截止日期为 2025 年 9 月 9 日. ****** @@ -133,7 +133,7 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 * 主题色适配 [ 分组 / 定位 / 搜索 / 历史记录 / 亮度及对比度自动适配 / ... ] * 夜间模式适配 [ 设置页面 / 文档页面 / 布局分析页面 / 浮动窗口 / ... ] * [VSCode 插件](http://vscext-project.autojs6.com) 支持客户端 (LAN) 及服务端 (LAN/ADB) 连接方式 -* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升级至 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升级至 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (更新于 2025 年 4 月 11 日) * Unicode [码位](https://developer.mozilla.org/zh-CN/docs/Glossary/Code_point) 转义支持 [辅助平面](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) 字符 ```javascript '\u{1D160}'; /* 表示 "𝅘𝅥𝅮", 传统方式: '\uD834\uDD60'. */ @@ -280,12 +280,12 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 #### Android Studio 准备 -下载 `Android Studio Narwhal Feature Drop | 2025.1.2` 版本 (按需选择其一): +下载 `Android Studio Narwhal 3 Feature Drop | 2025.1.3` 版本 (按需选择其一): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> 注: 上述版本发布时间为 2025 年 7 月 31 日. 如需下载其他版本, 或上述链接已失效, 可访问 [Android Studio 发行版本归档](https://developer.android.com/studio/archive?hl=en) 页面. +> 注: 上述版本发布时间为 2025 年 9 月 2 日. 如需下载其他版本, 或上述链接已失效, 可访问 [Android Studio 发行版本归档](https://developer.android.com/studio/archive?hl=en) 页面. 安装或解压上述文件, 运行 Android Studio 软件 (如 `"D:\android-studio\bin\studio64.exe"`). @@ -334,9 +334,9 @@ File (文件) | Settings (设置) | Appearance & Behavior (外观与行为) | Sy #### JDK 准备 -AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `19`. +AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `21`. -截至 2025 年 8 月 17 日, AutoJs6 可支持 JDK 最高版本为 `24`. +截至 2025 年 9 月 9 日, AutoJs6 可支持 JDK 最高版本为 `24`. > 注: 如果计算机系统已安装 JDK 且版本满足上述要求, 则可跳过此小节内容. @@ -487,19 +487,19 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk 感谢每一位参与 AutoJs6 项目开发的贡献人员. -| 贡献人员 | 提交数 | 最近提交 | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| 贡献人员 | 提交数 | 最近提交 | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -数据更新于 2025 年 5 月 27 日. +数据更新于 2025 年 9 月 6 日. 数据条目按 `最近提交` 降序排序. @@ -520,11 +520,12 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-zh-Hant-HK.md b/.readme/README-zh-Hant-HK.md index 29974d39..62b382f5 100644 --- a/.readme/README-zh-Hant-HK.md +++ b/.readme/README-zh-Hant-HK.md @@ -8,16 +8,16 @@

Android 平台支持無障礙服務的 JavaScript 自動化工具

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ AutoJs6 在 Auto.js 最終項目的基礎上, 於 `2021/12/01` 進行二次開 | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | 表格中的日期為預估值, 與實際可能存在出入. @@ -76,7 +76,7 @@ AutoJs6 在 Auto.js 最終項目的基礎上, 於 `2021/12/01` 進行二次開 表格中 `終止開發日期` 列包含方括號 (`[]`) 的數據, 表示開源項目暫時無法訪問. -表格中 `活躍維護期` 列包含尖括號 (`<>`) 的數據, 其統計截止日期為 2025 年 8 月 17 日. +表格中 `活躍維護期` 列包含尖括號 (`<>`) 的數據, 其統計截止日期為 2025 年 9 月 9 日. ****** @@ -133,7 +133,7 @@ AutoJs6 在 Auto.js 最終項目的基礎上, 於 `2021/12/01` 進行二次開 * 主題色適配 [ 分組 / 定位 / 搜索 / 歷史記錄 / 亮度及對比度自動適配 / ... ] * 夜間模式適配 [ 設置頁面 / 文檔頁面 / 佈局分析頁面 / 浮動窗口 / ... ] * [VSCode 插件](http://vscext-project.autojs6.com) 支持客户端 (LAN) 及服務端 (LAN/ADB) 連接方式 -* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升級至 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升級至 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (更新於 2025 年 4 月 11 日) * Unicode [碼位](https://developer.mozilla.org/zh-CN/docs/Glossary/Code_point) 轉義支持 [輔助平面](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) 字符 ```javascript '\u{1D160}'; /* 表示 "𝅘𝅥𝅮", 傳統方式: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ AutoJs6 在 Auto.js 最終項目的基礎上, 於 `2021/12/01` 進行二次開 #### Android Studio 準備 -下載 `Android Studio Narwhal Feature Drop | 2025.1.2` 版本 (按需選擇其一): +下載 `Android Studio Narwhal 3 Feature Drop | 2025.1.3` 版本 (按需選擇其一): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> 注: 上述版本發佈時間為 2025 年 7 月 31 日. 如需下載其他版本, 或上述鏈接已失效, 可訪問 [Android Studio 發行版本歸檔](https://developer.android.com/studio/archive?hl=en) 頁面. +> 注: 上述版本發佈時間為 2025 年 9 月 2 日. 如需下載其他版本, 或上述鏈接已失效, 可訪問 [Android Studio 發行版本歸檔](https://developer.android.com/studio/archive?hl=en) 頁面. 安裝或解壓上述文件, 運行 Android Studio 軟件 (如 `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ File (文件) | Settings (設置) | Appearance & Behavior (外觀與行為) | Sy #### JDK 準備 -AutoJs6 項目依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `19`. +AutoJs6 項目依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `21`. -截至 2025 年 8 月 17 日, AutoJs6 可支持 JDK 最高版本為 `24`. +截至 2025 年 9 月 9 日, AutoJs6 可支持 JDK 最高版本為 `24`. > 注: 如果計算機系統已安裝 JDK 且版本滿足上述要求, 則可跳過此小節內容. @@ -514,19 +514,19 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk 感謝每一位參與 AutoJs6 項目開發的貢獻人員. -| 貢獻人員 | 提交數 | 最近提交 | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| 貢獻人員 | 提交數 | 最近提交 | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -數據更新於 2025 年 5 月 27 日. +數據更新於 2025 年 9 月 6 日. 數據條目按 `最近提交` 降序排序. @@ -547,11 +547,12 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/README-zh-Hant-TW.md b/.readme/README-zh-Hant-TW.md index 926c49d9..5e1f54c2 100644 --- a/.readme/README-zh-Hant-TW.md +++ b/.readme/README-zh-Hant-TW.md @@ -8,16 +8,16 @@

Android 平臺支援無障礙服務的 JavaScript 自動化工具

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ AutoJs6 在 Auto.js 最終專案的基礎上, 於 `2021/12/01` 進行二次開 | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | 表格中的日期為預估值, 與實際可能存在出入. @@ -76,7 +76,7 @@ AutoJs6 在 Auto.js 最終專案的基礎上, 於 `2021/12/01` 進行二次開 表格中 `終止開發日期` 列包含方括號 (`[]`) 的資料, 表示開源專案暫時無法訪問. -表格中 `活躍維護期` 列包含尖括號 (`<>`) 的資料, 其統計截止日期為 2025 年 8 月 17 日. +表格中 `活躍維護期` 列包含尖括號 (`<>`) 的資料, 其統計截止日期為 2025 年 9 月 9 日. ****** @@ -133,7 +133,7 @@ AutoJs6 在 Auto.js 最終專案的基礎上, 於 `2021/12/01` 進行二次開 * 主題色適配 [ 分組 / 定位 / 搜尋 / 歷史記錄 / 亮度及對比度自動適配 / ... ] * 夜間模式適配 [ 設定頁面 / 文件頁面 / 佈局分析頁面 / 浮動視窗 / ... ] * [VSCode 外掛](http://vscext-project.autojs6.com) 支援客戶端 (LAN) 及服務端 (LAN/ADB) 連線方式 -* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升級至 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升級至 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (更新於 2025 年 4 月 11 日) * Unicode [碼位](https://developer.mozilla.org/zh-CN/docs/Glossary/Code_point) 轉義支援 [輔助平面](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) 字元 ```javascript '\u{1D160}'; /* 表示 "𝅘𝅥𝅮", 傳統方式: '\uD834\uDD60'. */ @@ -307,12 +307,12 @@ AutoJs6 在 Auto.js 最終專案的基礎上, 於 `2021/12/01` 進行二次開 #### Android Studio 準備 -下載 `Android Studio Narwhal Feature Drop | 2025.1.2` 版本 (按需選擇其一): +下載 `Android Studio Narwhal 3 Feature Drop | 2025.1.3` 版本 (按需選擇其一): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> 注: 上述版本釋出時間為 2025 年 7 月 31 日. 如需下載其他版本, 或上述連結已失效, 可訪問 [Android Studio 發行版本歸檔](https://developer.android.com/studio/archive?hl=en) 頁面. +> 注: 上述版本釋出時間為 2025 年 9 月 2 日. 如需下載其他版本, 或上述連結已失效, 可訪問 [Android Studio 發行版本歸檔](https://developer.android.com/studio/archive?hl=en) 頁面. 安裝或解壓上述檔案, 執行 Android Studio 軟體 (如 `"D:\android-studio\bin\studio64.exe"`). @@ -361,9 +361,9 @@ File (文件) | Settings (設置) | Appearance & Behavior (外觀與行為) | Sy #### JDK 準備 -AutoJs6 專案依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `19`. +AutoJs6 專案依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `21`. -截至 2025 年 8 月 17 日, AutoJs6 可支援 JDK 最高版本為 `24`. +截至 2025 年 9 月 9 日, AutoJs6 可支援 JDK 最高版本為 `24`. > 注: 如果計算機系統已安裝 JDK 且版本滿足上述要求, 則可跳過此小節內容. @@ -514,19 +514,19 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk 感謝每一位參與 AutoJs6 專案開發的貢獻人員. -| 貢獻人員 | 提交數 | 最近提交 | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| 貢獻人員 | 提交數 | 最近提交 | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -資料更新於 2025 年 5 月 27 日. +資料更新於 2025 年 9 月 6 日. 資料條目按 `最近提交` 降序排序. @@ -547,11 +547,12 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.readme/common.json b/.readme/common.json index 5596c015..c93e3ff1 100644 --- a/.readme/common.json +++ b/.readme/common.json @@ -1,17 +1,15 @@ { - "android_studio_latest_recommended_version_name": "Android Studio Narwhal Feature Drop | 2025.1.2", - "var_date_android_studio_latest_recommended_version_name": "2025/07/31", - "android_studio_latest_recommended_file_name_of_exe": "android-studio-2025.1.2.11-windows.exe", - "android_studio_latest_recommended_download_address_of_exe": "https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe", - "android_studio_latest_recommended_file_size_of_exe": "1.39 GB", - "android_studio_latest_recommended_file_name_of_zip": "android-studio-2025.1.2.11-windows.zip", - "android_studio_latest_recommended_download_address_of_zip": "https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip", - "android_studio_latest_recommended_file_size_of_zip": "1.40 GB", - "var_date_contribution_table_data_updated": "2025/05/27", + "android_studio_latest_recommended_version_name": "Android Studio Narwhal 3 Feature Drop | 2025.1.3", + "var_date_android_studio_latest_recommended_version_name": "2025/09/02", + "android_studio_latest_recommended_file_name_of_exe": "android-studio-2025.1.3.7-windows.exe", + "android_studio_latest_recommended_download_address_of_exe": "https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe", + "android_studio_latest_recommended_file_size_of_exe": "1.33 GiB", + "android_studio_latest_recommended_file_name_of_zip": "android-studio-2025.1.3.7-windows.zip", + "android_studio_latest_recommended_download_address_of_zip": "https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip", + "android_studio_latest_recommended_file_size_of_zip": "1.34 GiB", + "var_date_contribution_table_data_updated": "2025/09/06", "latest_rhino_engine_name_with_github_lineno_address": "[v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3)", - "jdk_min_supported": 17, - "jdk_min_suggested": 19, - "jdk_max_supported": 24, + "var_date_rhino_engine_latest_committed": "2025/04/11", "var_date_jdk_max_supported": "%CURRENT_DATE%", "var_date_active_maintenance_phase_statistics_since_when": "%CURRENT_DATE%" } \ No newline at end of file diff --git a/.readme/lang_ar.json b/.readme/lang_ar.json index 4c827a60..71bca46a 100644 --- a/.readme/lang_ar.json +++ b/.readme/lang_ar.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "دعم التكيف متعدد اللغات [ الإسبانية / الفرنسية / الروسية / العربية / اليابانية / الكورية / الإنجليزية / الصينية المبسطة / الصينية التقليدية / ... ]", "li_major_changes_new_modules": "وحدات جديدة [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "دعم وضع الليل [ صفحة الإعدادات / صفحة الوثائق / صفحة تحليل التخطيط / النافذة العائمة / ... ]", - "li_major_changes_rhino_engine_upgrade": "تم ترقية محرك [Rhino](https://github.com/mozilla/rhino/) من [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) إلى {{ latest_rhino_engine_name_with_github_lineno_address }}", + "li_major_changes_rhino_engine_upgrade": "تم ترقية محرك [Rhino](https://github.com/mozilla/rhino/) من [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) إلى {{ latest_rhino_engine_name_with_github_lineno_address }} (تم التحديث في {{ var_date_rhino_engine_latest_committed }})", "li_major_changes_shizuku_adb_privileges_support": "دعم امتيازات ADB باستخدام [Shizuku](https://shizuku.rikka.app/introduction/) واستخدام واجهة برمجة التطبيقات للنظام", "li_major_changes_theme_color_support": "تكييف ألوان الموضوع [ التجميع / الموقع / البحث / السجل / التكييف التلقائي للسطوع والتباين / ... ]", "li_major_changes_vscode_plugin_support": "دعم الاتصال بـ [المكون الإضافي لـ VSCode](http://vscext-project.autojs6.com) بطرق الاتصال عبر الشبكة المحلية (LAN) و ADB", diff --git a/.readme/lang_en.json b/.readme/lang_en.json index 66ba600d..054077a4 100644 --- a/.readme/lang_en.json +++ b/.readme/lang_en.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "Multilingual support [ Spanish / French / Russian / Arabic / Japanese / Korean / English / Simplified Chinese / Traditional Chinese / ... ]", "li_major_changes_new_modules": "New modules [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "Night mode adaptation [ Settings page / Documentation page / Layout analysis page / Floating window / ... ]", - "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) engine upgraded from [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) to {{ latest_rhino_engine_name_with_github_lineno_address }}", + "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) engine upgraded from [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) to {{ latest_rhino_engine_name_with_github_lineno_address }} (Updated on {{ var_date_rhino_engine_latest_committed }})", "li_major_changes_shizuku_adb_privileges_support": "Supports obtaining ADB privileges through [Shizuku](https://shizuku.rikka.app/introduction/) and using system API", "li_major_changes_theme_color_support": "Theme color adaptation [ Grouping / Location / Search / History / Automatic Adaptation of Brightness and Contrast / ... ]", "li_major_changes_vscode_plugin_support": "[VSCode plugin](http://vscext-project.autojs6.com) supports both client (LAN) and server (LAN/ADB) connection methods", diff --git a/.readme/lang_es.json b/.readme/lang_es.json index ae79118d..92b63df2 100644 --- a/.readme/lang_es.json +++ b/.readme/lang_es.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "Soporte multilingüe [Español / Francés / Ruso / Árabe / Japonés / Coreano / Inglés / Chino Simplificado / Chino Tradicional / ...]", "li_major_changes_new_modules": "Nuevos módulos [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "Soporte para modo nocturno en varias páginas [ página de configuración / página de documentación / página de análisis de diseño / ventana flotante / ... ]", - "li_major_changes_rhino_engine_upgrade": "El motor [Rhino](https://github.com/mozilla/rhino/) se ha actualizado de [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) a {{ latest_rhino_engine_name_with_github_lineno_address }}", + "li_major_changes_rhino_engine_upgrade": "El motor [Rhino](https://github.com/mozilla/rhino/) se ha actualizado de [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) a {{ latest_rhino_engine_name_with_github_lineno_address }} (actualizado el {{ var_date_rhino_engine_latest_committed }})", "li_major_changes_shizuku_adb_privileges_support": "Soporte para obtener privilegios ADB usando [Shizuku](https://shizuku.rikka.app/introduction/) y usar las API del sistema", "li_major_changes_theme_color_support": "Adaptation des couleurs du thème [ Groupement / Localisation / Recherche / Historique / Adaptation automatique de la luminosité et du contraste / ... ]", "li_major_changes_vscode_plugin_support": "El [complemento de VSCode](http://vscext-project.autojs6.com) soporta conexiones cliente (LAN) y servidor (LAN/ADB)", diff --git a/.readme/lang_fr.json b/.readme/lang_fr.json index 2f5561e5..5cfa54d8 100644 --- a/.readme/lang_fr.json +++ b/.readme/lang_fr.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "Adaptation multilingue [ Espagnol / Français / Russe / Arabe / Japonais / Coréen / Anglais / Chinois Simplifié / Chinois Traditionnel / ... ]", "li_major_changes_new_modules": "Nouveaux modules ajoutés [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "Adaptation du mode nuit [ Paramètres / Documentation / Analyse de la disposition / Fenêtre flottante / ... ]", - "li_major_changes_rhino_engine_upgrade": "Le moteur [Rhino](https://github.com/mozilla/rhino/) a été mis à niveau de [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) à {{ latest_rhino_engine_name_with_github_lineno_address }}", + "li_major_changes_rhino_engine_upgrade": "Le moteur [Rhino](https://github.com/mozilla/rhino/) a été mis à niveau de [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) à {{ latest_rhino_engine_name_with_github_lineno_address }} (mis à jour le {{ var_date_rhino_engine_latest_committed }})", "li_major_changes_shizuku_adb_privileges_support": "Prise en charge des privilèges ADB via [Shizuku](https://shizuku.rikka.app/introduction/) pour utiliser les API système", "li_major_changes_theme_color_support": "Adaptación del color del tema [ Agrupación / Ubicación / Búsqueda / Historial / Adaptación automática de brillo y contraste / ... ]", "li_major_changes_vscode_plugin_support": "Prise en charge de l'extension [VSCode](http://vscext-project.autojs6.com) pour la connexion client (LAN) et serveur (LAN/ADB)", diff --git a/.readme/lang_ja.json b/.readme/lang_ja.json index 288b69db..c510a2db 100644 --- a/.readme/lang_ja.json +++ b/.readme/lang_ja.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "多言語対応 [ 西 / 仏 / 露 / 阿 / 日 / 韓 / 英 / 簡中 / 繁中 / ... ]", "li_major_changes_new_modules": "新モジュール [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "ナイトモード対応 [ 設定ページ / ドキュメントページ / レイアウト分析ページ / 浮動ウィンドウ / ... ]", - "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/)エンジンが [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) から {{ latest_rhino_engine_name_with_github_lineno_address }} にアップグレードされました", + "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/)エンジンが [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) から {{ latest_rhino_engine_name_with_github_lineno_address }} ({{ var_date_rhino_engine_latest_committed }} 更新) にアップグレードされました", "li_major_changes_shizuku_adb_privileges_support": "[Shizuku](https://shizuku.rikka.app/introduction/)経由でADB特権を取得し, システムAPIを使用可能", "li_major_changes_theme_color_support": "テーマカラーの適応 [ グループ化 / ロケーション / 検索 / 履歴 / 明るさとコントラストの自動適応 / ... ]", "li_major_changes_vscode_plugin_support": "[VSCodeプラグイン](http://vscext-project.autojs6.com)がクライアント (LAN)とサーバ (LAN/ADB)接続方法をサポート", diff --git a/.readme/lang_ko.json b/.readme/lang_ko.json index c19ca660..cbbd2a7f 100644 --- a/.readme/lang_ko.json +++ b/.readme/lang_ko.json @@ -62,11 +62,11 @@ "li_function_screenshot_and_image_matching_support": "스크린샷 찍기/스크린샷 저장/이미지 색상 찾기/이미지 매칭 지원", "li_function_selector_api_support": "선택기 API 지원 및 컨트롤 탐색/정보 가져오기/컨트롤 작업 지원 ( [UiAutomator](https://developer.android.com/training/testing/ui-automator)와 유사)", "li_function_tasker_plugin_support": "Tasker 플러그인으로 사용 가능", - "li_function_vscode_integration_support": "VSCode와 연결하여 데스크톱 개발 지원 ( [AutoJs6-VSCode-Extension](http://vscext-project.autojs6.com) 플러그인 필요)", + "li_function_vscode_integration_support": "VSCode와 연결하여 데스크톱 개발 지원 ([AutoJs6-VSCode-Extension](http://vscext-project.autojs6.com) 플러그인 필요)", "li_major_changes_multilingual_support": "다국어 지원 [ 서 / 프 / 러 / 아 / 일 / 한 / 영어 / 중국어 / 번체 중 ... ]", "li_major_changes_new_modules": "새로운 모듈 추가 [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "야경 모드 지원 [ 설정 페이지 / 문서 페이지 / 레이아웃 분석 페이지 / 플로팅 창 / ... ]", - "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) 엔진을 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release)에서 {{ latest_rhino_engine_name_with_github_lineno_address }}로 업그레이드", + "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) 엔진을 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 에서 {{ latest_rhino_engine_name_with_github_lineno_address }} 로 업그레이드 ({{ var_date_rhino_engine_latest_committed }} 업데이트됨)", "li_major_changes_shizuku_adb_privileges_support": "[Shizuku](https://shizuku.rikka.app/introduction/)를 통해 ADB 특권을 얻고 시스템 API 사용 지원", "li_major_changes_theme_color_support": "테마 색상 적응 [ 그룹화 / 위치 / 검색 / 기록 / 밝기 및 대비 자동 적응 / ...]", "li_major_changes_vscode_plugin_support": "[VSCode 플러그인](http://vscext-project.autojs6.com) 지원 클라이언트 (LAN) 및 서버 (LAN/ADB) 연결 방식", diff --git a/.readme/lang_ru.json b/.readme/lang_ru.json index b8cbb461..97bee5e7 100644 --- a/.readme/lang_ru.json +++ b/.readme/lang_ru.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "Поддержка нескольких языков [ испанский / французский / русский / арабский / японский / корейский / английский / упрощенный китайский / традиционный китайский / ... ]", "li_major_changes_new_modules": "Добавлены новые модули [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "Поддержка ночного режима [ страница настроек / страница документации / страница анализа макета / плавающее окно / ... ]", - "li_major_changes_rhino_engine_upgrade": "Движок [Rhino](https://github.com/mozilla/rhino/) обновлен с версии [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) до версии {{ latest_rhino_engine_name_with_github_lineno_address }}", + "li_major_changes_rhino_engine_upgrade": "Движок [Rhino](https://github.com/mozilla/rhino/) обновлен с версии [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) до версии {{ latest_rhino_engine_name_with_github_lineno_address }} (обновлено {{ var_date_rhino_engine_latest_committed }})", "li_major_changes_shizuku_adb_privileges_support": "Поддержка получения привилегий ADB через [Shizuku](https://shizuku.rikka.app/introduction/) и использование системных API", "li_major_changes_theme_color_support": "Адаптация темы [ Группировка / Локация / Поиск / История / Автоматическая адаптация яркости и контрастности / ... ]", "li_major_changes_vscode_plugin_support": "Плагин [VSCode](http://vscext-project.autojs6.com) поддерживает варианты подключения клиента (LAN) и сервера (LAN/ADB)", diff --git a/.readme/lang_zh-Hans.json b/.readme/lang_zh-Hans.json index 7d0dc2fe..76368a34 100644 --- a/.readme/lang_zh-Hans.json +++ b/.readme/lang_zh-Hans.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "多语言适配 [ 西 / 法 / 俄 / 阿 / 日 / 韩 / 英 / 简中 / 繁中 / ... ]", "li_major_changes_new_modules": "新增模块 [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "夜间模式适配 [ 设置页面 / 文档页面 / 布局分析页面 / 浮动窗口 / ... ]", - "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升级至 {{ latest_rhino_engine_name_with_github_lineno_address }}", + "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升级至 {{ latest_rhino_engine_name_with_github_lineno_address }} (更新于 {{ var_date_rhino_engine_latest_committed }})", "li_major_changes_shizuku_adb_privileges_support": "支持通过 [Shizuku](https://shizuku.rikka.app/introduction/) 获得 ADB 特权并使用系统 API", "li_major_changes_theme_color_support": "主题色适配 [ 分组 / 定位 / 搜索 / 历史记录 / 亮度及对比度自动适配 / ... ]", "li_major_changes_vscode_plugin_support": "[VSCode 插件](http://vscext-project.autojs6.com) 支持客户端 (LAN) 及服务端 (LAN/ADB) 连接方式", diff --git a/.readme/lang_zh-Hant-HK.json b/.readme/lang_zh-Hant-HK.json index 3e293282..fb71a812 100644 --- a/.readme/lang_zh-Hant-HK.json +++ b/.readme/lang_zh-Hant-HK.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "多語言適配 [ 西 / 法 / 俄 / 阿 / 日 / 韓 / 英 / 簡中 / 繁中 / ... ]", "li_major_changes_new_modules": "新增模塊 [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "夜間模式適配 [ 設置頁面 / 文檔頁面 / 佈局分析頁面 / 浮動窗口 / ... ]", - "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升級至 {{ latest_rhino_engine_name_with_github_lineno_address }}", + "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升級至 {{ latest_rhino_engine_name_with_github_lineno_address }} (更新於 {{ var_date_rhino_engine_latest_committed }})", "li_major_changes_shizuku_adb_privileges_support": "支持通過 [Shizuku](https://shizuku.rikka.app/introduction/) 獲得 ADB 特權並使用系統 API", "li_major_changes_theme_color_support": "主題色適配 [ 分組 / 定位 / 搜索 / 歷史記錄 / 亮度及對比度自動適配 / ... ]", "li_major_changes_vscode_plugin_support": "[VSCode 插件](http://vscext-project.autojs6.com) 支持客户端 (LAN) 及服務端 (LAN/ADB) 連接方式", diff --git a/.readme/lang_zh-Hant-TW.json b/.readme/lang_zh-Hant-TW.json index 60173a8d..6bfed449 100644 --- a/.readme/lang_zh-Hant-TW.json +++ b/.readme/lang_zh-Hant-TW.json @@ -66,7 +66,7 @@ "li_major_changes_multilingual_support": "多語言適配 [ 西 / 法 / 俄 / 阿 / 日 / 韓 / 英 / 簡中 / 繁中 / ... ]", "li_major_changes_new_modules": "新增模組 [ [base64](https://docs.autojs6.com/#/base64) / [crypto](https://docs.autojs6.com/#/crypto) / [sqlite](https://docs.autojs6.com/#/sqlite) / [i18n](https://docs.autojs6.com/#/i18n) / [notice](https://docs.autojs6.com/#/notice) / [ocr](https://docs.autojs6.com/#/ocr) / [opencc](https://docs.autojs6.com/#/opencc) / [qrcode](https://docs.autojs6.com/#/qrcode) / [shizuku](https://docs.autojs6.com/#/shizuku) / ... ]", "li_major_changes_night_mode_support": "夜間模式適配 [ 設定頁面 / 文件頁面 / 佈局分析頁面 / 浮動視窗 / ... ]", - "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升級至 {{ latest_rhino_engine_name_with_github_lineno_address }}", + "li_major_changes_rhino_engine_upgrade": "[Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升級至 {{ latest_rhino_engine_name_with_github_lineno_address }} (更新於 {{ var_date_rhino_engine_latest_committed }})", "li_major_changes_shizuku_adb_privileges_support": "支援透過 [Shizuku](https://shizuku.rikka.app/introduction/) 獲得 ADB 特權並使用系統 API", "li_major_changes_theme_color_support": "主題色適配 [ 分組 / 定位 / 搜尋 / 歷史記錄 / 亮度及對比度自動適配 / ... ]", "li_major_changes_vscode_plugin_support": "[VSCode 外掛](http://vscext-project.autojs6.com) 支援客戶端 (LAN) 及服務端 (LAN/ADB) 連線方式", diff --git a/.readme/template_readme.md b/.readme/template_readme.md index f4b1bce7..187e3ade 100644 --- a/.readme/template_readme.md +++ b/.readme/template_readme.md @@ -8,16 +8,16 @@

{{ text_autojs6_synopsis }}

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -379,17 +379,17 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk {{ p_contribution_table_thank_all_contributors }}. -| {{ table_header_contribution_contributors }} | {{ table_header_contribution_number_of_commits }} | {{ table_header_contribution_recent_submissions }} | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| {{ table_header_contribution_contributors }} | {{ table_header_contribution_number_of_commits }} | {{ table_header_contribution_recent_submissions }} | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | {{ p_contribution_table_data_updated_on }}. @@ -412,11 +412,12 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/.utils/.gitignore b/.utils/.gitignore new file mode 100644 index 00000000..7af7f047 --- /dev/null +++ b/.utils/.gitignore @@ -0,0 +1,2 @@ +/node_modules +.env \ No newline at end of file diff --git a/.utils/fetch-and-parse-android-studio-agp-compatibility-table.mjs b/.utils/fetch-and-parse-android-studio-agp-compatibility-table.mjs new file mode 100644 index 00000000..f199d60a --- /dev/null +++ b/.utils/fetch-and-parse-android-studio-agp-compatibility-table.mjs @@ -0,0 +1,48 @@ +// fetch-and-parse-android-studio-agp-compatibility-table.mjs + +import fetch from 'node-fetch'; +import { load } from 'cheerio'; +import { fileURLToPath } from 'node:url'; + +const URL = 'https://developer.android.com/studio/releases#android_gradle_plugin_and_android_studio_compatibility'; + +/** + * @return {Promise>} + */ +export async function fetchStudioAgpTable() { + const html = await fetch(URL).then(r => r.text()); + const $ = load(html); + + const targetTable = $('table').filter((_, el) => { + let text = $(el).find('th').first().text(); + return /Android Studio version/i.test(text); + }); + + if (!targetTable.length) { + throw new Error('未找到目标表格, 页面结构可能已变更'); + } + + const rows = []; + targetTable.find('tbody tr').each((_, tr) => { + const cells = $(tr).find('td').map((_, td) => { + return $(td).text().trim().replace(/\s+/g, ' '); + }).get(); + if (cells.length < 2) return; + const [ studioVersion, agpRange ] = cells; + rows.push({ studioVersion, agpRange }); + }); + + return rows; +} + +async function main() { + console.table(await fetchStudioAgpTable()); +} + +// 判断是否为直接执行该文件 +if (fileURLToPath(import.meta.url) === process.argv[1]) { + main().catch(err => { + console.error(err); + process.exitCode = 1; + }); +} \ No newline at end of file diff --git a/.utils/fetch-and-parse-android-studio-latest-stable-version.mjs b/.utils/fetch-and-parse-android-studio-latest-stable-version.mjs new file mode 100644 index 00000000..429ce05e --- /dev/null +++ b/.utils/fetch-and-parse-android-studio-latest-stable-version.mjs @@ -0,0 +1,138 @@ +// fetch-and-parse-android-studio-latest-stable-version.mjs + +import { load } from 'cheerio'; +import { fileURLToPath } from 'node:url'; + +const URL = 'https://developer.android.com/studio?hl=en'; + +/** + * @param {string} s + * @return {string} + */ +function norm(s) { + return (s ?? '').replace(/\s+/g, ' ').trim(); +} + +/** + * @param {string} filename + * @return {string | null} + */ +function buildDownloadUrlFromFilename(filename) { + // 例: android-studio-2025.1.2.13-windows.exe + const m = /android-studio-([\d.]+)-/.exec(filename); + if (!m) return null; + const version = m[1]; + return `https://redirector.gvt1.com/edgedl/android/studio/install/${version}/${filename}`; +} + +/** + * @param {string} url + * @return {Promise} + */ +async function fetchHtml(url) { + const res = await fetch(url, { + headers: { + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124 Safari/537.36', + 'accept-language': 'en', + }, + }); + if (!res.ok) throw new Error(`HTTP ${res.status} for ${url}`); + return await res.text(); +} + +/** + * @typedef {'exe' | 'zip' | 'other'} RowKind + */ + +/** + * @typedef {Object} Row + * @property {string} platform + * @property {string} filename + * @property {string} size + * @property {string} sha256 + * @property {string | null} url + * @property {RowKind} kind + */ +/** + * @param {string} html + * @return {Row[]} + */ +function parseWindowsRowsFromHtml(html) { + const $ = load(html); + const rows = []; + + /** @type {import('cheerio').Cheerio} */ + const tableRows = $('table.download tbody tr'); + tableRows.each((_, tr) => { + const tds = $(tr).find('td'); + if (tds.length !== 4) return; + + const platform = norm($(tds[0]).text()); + if (!/windows/i.test(platform)) return; + + const btn = $(tds[1]).find('button.devsite-dialog-button').first(); + const filename = norm(btn.text()); + if (!filename || !filename.includes('android-studio')) return; + + const size = norm($(tds[2]).text()); + const sha256 = norm($(tds[3]).text()); + const url = buildDownloadUrlFromFilename(filename); + + rows.push({ + platform, + filename, + size, + sha256, + url, + kind: filename.endsWith('.exe') + ? 'exe' + : filename.endsWith('.zip') + ? 'zip' + : 'other', + }); + }); + + return rows + .filter(r => r.kind === 'exe' || r.kind === 'zip') + .sort((a) => a.kind === 'exe' ? -1 : 1); +} + +/** + * 导出: 获取最新稳定版 Windows 的下载信息 (exe 与 zip) + * 返回形如: + * [ + * { platform, filename, size, sha256, url, kind: 'exe' }, + * { platform, filename, size, sha256, url, kind: 'zip' } + * ] + * + * @param {string} [sourceUrl=URL] + * @returns {Promise} + */ +export async function getLatestStableWindows(sourceUrl = URL) { + const html = await fetchHtml(sourceUrl); + const rows = parseWindowsRowsFromHtml(html); + if (!rows.length) { + throw new Error('未在页面中找到 Windows 稳定版下载条目'); + } + return rows; +} + +// CLI 模式: 直接运行则打印结果; 被 import 时不执行 +async function main() { + const rows = await getLatestStableWindows(URL); + for (const r of rows) { + console.log(`${r.kind.toUpperCase()}:`); + console.log(` filename : ${r.filename}`); + console.log(` size : ${r.size}`); + console.log(` sha256 : ${r.sha256}`); + console.log(` url : ${r.url}`); + } +} + +// 判断是否为直接执行该文件 +if (fileURLToPath(import.meta.url) === process.argv[1]) { + main().catch(err => { + console.error(err); + process.exitCode = 1; + }); +} diff --git a/.utils/fetch-and-parse-autojs6-merged-pr-commits-statistics.mjs b/.utils/fetch-and-parse-autojs6-merged-pr-commits-statistics.mjs new file mode 100644 index 00000000..5add5cfb --- /dev/null +++ b/.utils/fetch-and-parse-autojs6-merged-pr-commits-statistics.mjs @@ -0,0 +1,373 @@ +// fetch-and-parse-autojs6-merged-pr-commits-statistics.mjs + +/** @typedef {import('@octokit/types').Endpoints['GET /repos/{owner}/{repo}/pulls']['response']['data']} PullsData */ +/** @typedef {import('@octokit/types').Endpoints['GET /repos/{owner}/{repo}/pulls/{pull_number}/commits']['response']['data']} PullCommitsData */ + +import fetch from 'node-fetch'; +import * as dotenv from 'dotenv'; +import { fileURLToPath } from 'node:url'; +import { toYYYYMMDD } from './utils/date.mjs'; + +dotenv.config({ path: '.env', quiet: true }); + +const REPO = 'AutoJs6'; +const OWNER = 'SuperMonster003'; +const BASE = `https://api.github.com/repos/${OWNER}/${REPO}`; +const GITHUB_TOKEN = process.env.GITHUB_TOKEN || ''; + +// 调试: 设置为某个作者的登录名 (login) 以打印该作者的匹配细节 +const DEBUG_LOGIN = process.env.DEBUG_LOGIN || ''; +const DEBUG_VERBOSE = process.env.DEBUG_VERBOSE === '1'; + +// 可排除的登录名列表 (默认排除仓库维护者); 可用 EXCLUDED_LOGINS 环境变量覆盖, 逗号分隔 +const EXCLUDED_LOGINS = (process.env.EXCLUDED_LOGINS || OWNER) + .split(',') + .map(s => s.trim()) + .filter(Boolean); + +/** + * @return {import('node-fetch').HeadersInit} + */ +function headers() { + return { + accept: 'application/vnd.github+json', + ...(GITHUB_TOKEN ? { authorization: `Bearer ${GITHUB_TOKEN}` } : {}), + 'user-agent': 'pr-commit-contributions', + }; +} + +/** + * @typedef {Object} UserProfile + * @property {string} login + * @property {string | null} name + */ +/** + * 简单内存缓存, 避免重复请求. + * + * @type {Map} + */ +const userProfileCache = new Map(); + +/** + * @param {string} login + * @return {Promise} + */ +async function getUserProfile(login) { + if (userProfileCache.has(login)) return userProfileCache.get(login); + const url = `https://api.github.com/users/${login}`; + const res = await fetch(url, { headers: headers() }); + if (!res.ok) { + userProfileCache.set(login, { login, name: null }); + return { login, name: null }; + } + const data = await res.json(); + const profile = { + login: data?.['login'] || login, + name: data?.['name'] || null, + }; + userProfileCache.set(login, profile); + return profile; +} + +/** + * @return {Promise} + */ +async function fetchAllMergedPRs() { + const perPage = 100; + let page = 1; + const merged = []; + + while (true) { + const url = `${BASE}/pulls?state=closed&per_page=${perPage}&page=${page}&sort=created&direction=asc`; + const res = await fetch(url, { headers: headers() }); + if (!res.ok) { + const text = await res.text(); + throw new Error(`获取 PR 列表失败: ${res.status} ${res.statusText} - ${text}`); + } + const prs = /** @type {PullsData} */ await res.json(); + if (!Array.isArray(prs) || prs.length === 0) break; + + for (const pr of prs) { + if (pr.merged_at) merged.push(pr); + } + + if (prs.length < perPage) break; + page += 1; + } + + return merged; +} + +/** + * @param {string} a + * @param {string} b + * @return {boolean} + */ +function equalsIgnoreCase(a, b) { + return typeof a === 'string' + && typeof b === 'string' + && a.toLowerCase() === b.toLowerCase(); +} + +/** + * @param {PullCommitsData[number]} c + * @return {string | null} + */ +function commitTimeFrom(c) { + return c.commit?.committer?.date + || c.commit?.author?.date + || null; +} + +/** + * 规则: 排除 EXCLUDED_LOGINS (author.login 或 committer.login 命中即排除); 其余一律计入. + * + * @param {PullCommitsData[number]} c + * @return {boolean} + */ +function isCommitBelongsToLogin(c) { + const authorLogin = c.author?.login || null; + const committerLogin = c.committer?.login || null; + + return !(authorLogin && EXCLUDED_LOGINS.some(x => equalsIgnoreCase(x, authorLogin))) + && !(committerLogin && EXCLUDED_LOGINS.some(x => equalsIgnoreCase(x, committerLogin))); +} + +/** + * @typedef {Object} DebugRecord + * @property {string} sha + * @property {boolean} belongs + * @property {string | null} author_login + * @property {string | null} committer_login + * @property {string | null} author_name + * @property {string | null} author_email + * @property {string | null} time + */ +/** + * @param {PullsData[number]} pr + * @return {Promise<{count: number, latestCommitAt: string | null}>} - 该 PR 中属于 PR 作者本人的提交计数与最新提交时间. + */ +async function getPRCommitStatsByAuthor(pr) { + const perPage = 100; + let page = 1; + let total = 0; + let latestCommitAt = null; + + const login = pr.user?.login; + if (!login) return { count: 0, latestCommitAt: null }; + + // 仅在调试该作者时收集详细信息 + /** @type {DebugRecord[]} */ + const debugRecords = []; + + while (true) { + const url = `${BASE}/pulls/${pr.number}/commits?per_page=${perPage}&page=${page}`; + const res = await fetch(url, { headers: headers() }); + if (!res.ok) { + const text = await res.text(); + throw new Error(`获取 PR #${pr.number} 的 commits 失败: ${res.status} ${res.statusText} - ${text}`); + } + const commits = /** @type {PullCommitsData} */ await res.json(); + if (!Array.isArray(commits) || commits.length === 0) break; + + for (const c of commits) { + const included = isCommitBelongsToLogin(c); + if (included) { + total += 1; + const t = commitTimeFrom(c); + if (t && (!latestCommitAt || new Date(t) > new Date(latestCommitAt))) { + latestCommitAt = t; + } + } + if (DEBUG_LOGIN && equalsIgnoreCase(login, DEBUG_LOGIN)) { + debugRecords.push({ + sha: c.sha, + belongs: included, + author_login: c.author?.login || null, + committer_login: c.committer?.login || null, + author_name: c.commit?.author?.name || null, + author_email: c.commit?.author?.email || null, + time: c.commit?.committer?.date || c.commit?.author?.date || null, + }); + } + } + + if (commits.length < perPage) break; + page += 1; + } + + // 打印调试: 仅针对目标作者; 默认仅在该 PR 统计结果为 0 时打印, 或开启 DEBUG_VERBOSE 时总是打印 + if (DEBUG_LOGIN && equalsIgnoreCase(login, DEBUG_LOGIN) && (DEBUG_VERBOSE || total === 0)) { + const matched = debugRecords.filter(r => r.belongs).length; + const unmatched = debugRecords.length - matched; + console.log(`\n[DEBUG] PR #${pr.number} by ${login}: commits=${debugRecords.length}, included=${matched}, excluded=${unmatched}`); + for (const r of debugRecords) { + if (DEBUG_VERBOSE || !r.belongs) { + console.log(`[DEBUG] ${r.sha} | included=${r.belongs} | author_login=${r.author_login} | committer_login=${r.committer_login} | author_name=${r.author_name} | author_email=${r.author_email} | time=${r.time}`); + } + } + } + + return { count: total, latestCommitAt }; +} + +/** + * @template Item + * @template MapperResult + * @param {Item[]} items + * @param {number} limit + * @param {(item: Item, idx: number) => Promise} mapper + * @return {Promise} + */ +async function mapWithLimit(items, limit, mapper) { + const results = new Array(items.length); + let i = 0; + const workers = Array.from({ length: Math.min(limit, items.length) }, async () => { + while (true) { + const idx = i++; + if (idx >= items.length) break; + results[idx] = await mapper(items[idx], idx); + } + }); + await Promise.all(workers); + return results; +} + +/** + * 批量获取作者资料 (并发受限), 返回 Map. + * + * @param {string[]} logins + * @param {number} [concurrency=6] + * @return {Promise>} + */ +async function fetchProfilesForLogins(logins, concurrency = 6) { + const unique = Array.from(new Set(logins)).filter(Boolean); + const profiles = await mapWithLimit(unique, concurrency, async (login) => { + return await getUserProfile(login); + }); + const map = new Map(); + for (const p of profiles) { + map.set(p.login, p); + } + return map; +} + +/** + * @return {Promise} + */ +export async function fetchStatistics() { + const mergedPRs = await fetchAllMergedPRs(); + const CONCURRENCY = 6; + const prWithStats = await mapWithLimit(mergedPRs, CONCURRENCY, async (pr) => { + const { count, latestCommitAt } = await getPRCommitStatsByAuthor(pr); + return { pr, count, latestCommitAt }; + }); + + // 先收集所有作者, 再批量获取资料 (并发受限 + 内存缓存) + const allLogins = prWithStats + .map(({ pr }) => pr.user?.login) + .filter(Boolean); + const profileMap = await fetchProfilesForLogins(allLogins, 6); + + // 按 PR 发起者聚合 + const byAuthor = new Map(); + for (const { pr, count, latestCommitAt } of prWithStats) { + const user = pr.user; + if (!user?.login) continue; + + const entry = byAuthor.get(user.login) || { + login: user.login, + name: profileMap.get(user.login)?.name || null, + html_url: `https://github.com/${user.login}`, + totalCommitsInMergedPRs: 0, + latestCommitAt: null, + }; + + entry.totalCommitsInMergedPRs += count; + + if (latestCommitAt && (!entry.latestCommitAt || new Date(latestCommitAt) > new Date(entry.latestCommitAt))) { + entry.latestCommitAt = latestCommitAt; + } + + byAuthor.set(user.login, entry); + } + + // 按最近提交倒序 + const rows = Array.from(byAuthor.values()).sort((a, b) => { + const da = a.latestCommitAt ? new Date(a.latestCommitAt).getTime() : 0; + const db = b.latestCommitAt ? new Date(b.latestCommitAt).getTime() : 0; + return db - da; + }); + + return rows.map(r => new Statistics(r)); +} + +async function main() { + return await fetchStatistics(); +} + +class Statistics { + /** + * @param row {{ + * login: string, + * name: string | null, + * html_url: string, + * totalCommitsInMergedPRs: number, + * latestCommitAt: string | null, + * prListLink: string, + * }} + */ + constructor(row) { + this.login = row.login; + this.name = row.name; + this.html_url = row.html_url; + this.totalCommitsInMergedPRs = row.totalCommitsInMergedPRs; + this.latestCommitAt = row.latestCommitAt; + this.prListLink = `https://github.com/${OWNER}/${REPO}/pulls?q=` + + 'is' + '%3A' + 'pr' + '+' + + 'is' + '%3A' + 'merged' + '+' + + 'author' + '%3A' + encodeURIComponent(row.login); + } + + /** + * @param {string} text + * @param {string} [style='word-break:keep-all;white-space:nowrap'] + * @returns {string} + */ + #wrapInSpan(text, style = 'word-break:keep-all;white-space:nowrap') { + return `${text}`; + } + + get contributorMarkdown() { + let markdownName = `[${this.login.replace(/-/g, '‑')}](${this.html_url})`; + if (this.name && this.name !== this.login) { + markdownName += ` \`(${this.name})\``; + } + return this.#wrapInSpan(markdownName); + } + + get commitsCountMarkdown() { + return this.#wrapInSpan(`[${this.totalCommitsInMergedPRs}](${this.prListLink})`); + } + + get latestCommitMarkdown() { + if (!this.latestCommitAt) { + return this.#wrapInSpan('`N/A`'); + } + return this.#wrapInSpan(`\`${toYYYYMMDD(this.latestCommitAt)}\``); + } +} + +// 判断是否为直接执行该文件 +if (fileURLToPath(import.meta.url) === process.argv[1]) { + main().then((dataList) => { + console.table(dataList.map(r => ({ + contributor: r.name && r.name !== r.login ? `${r.login} (${r.name})` : r.login, + commits: r.totalCommitsInMergedPRs, + recent: r.latestCommitAt ? toYYYYMMDD(r.latestCommitAt) : 'N/A', + }))); + }).catch(err => { + console.error(err); + process.exit(1); + }); +} \ No newline at end of file diff --git a/.utils/package-lock.json b/.utils/package-lock.json new file mode 100644 index 00000000..a7738a38 --- /dev/null +++ b/.utils/package-lock.json @@ -0,0 +1,1505 @@ +{ + "name": ".utils", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "cheerio": "^1.1.2", + "domhandler": "^5.0.3", + "dotenv": "^17.2.2", + "node-fetch": "^3.3.2", + "puppeteer": "^24.17.1" + }, + "devDependencies": { + "@octokit/types": "^14.1.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.10.8", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.8.tgz", + "integrity": "sha512-f02QYEnBDE0p8cteNoPYHHjbDuwyfbe4cCIVlNi8/MRicIxFW4w4CfgU0LNgWEID6s06P+hRJ1qjpBLMhPRCiQ==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.1", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.2", + "tar-fs": "^3.1.0", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "license": "MIT", + "optional": true, + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "license": "Apache-2.0" + }, + "node_modules/bare-events": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.1.tgz", + "integrity": "sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-fs": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.2.1.tgz", + "integrity": "sha512-mELROzV0IhqilFgsl1gyp48pnZsaV9xhQapHLDsvn4d4ZTfbFhcghQezl7FTEDNBcGqLUnNI3lUlm6ecrLWdFA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cheerio": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz", + "integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.0.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.12.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chromium-bidi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-8.0.0.tgz", + "integrity": "sha512-d1VmE0FD7lxZQHzcDUCKZSNRtRwISXDsdg4HjdTR5+Ll5nQ/vzU12JeNmupD6VWffrPSlrnGhEWlLESKH3VO+g==", + "license": "Apache-2.0", + "dependencies": { + "mitt": "^3.0.1", + "zod": "^3.24.1" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1475386", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1475386.tgz", + "integrity": "sha512-RQ809ykTfJ+dgj9bftdeL2vRVxASAuGU+I9LEx9Ij5TXU5HrgAQVmzi72VA+mkzscE12uzlRv5/tWWv9R9J1SA==", + "license": "BSD-3-Clause" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz", + "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-fetch/node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/puppeteer": { + "version": "24.17.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.17.1.tgz", + "integrity": "sha512-KIuX0w+0um4TUbm55yFl2WIsbgjya2BHIgW9ylTuhavtwjXCOM7lMo9oLR1jQnCxrFvm9h/Yeb+zfs4nlgntPg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "2.10.8", + "chromium-bidi": "8.0.0", + "cosmiconfig": "^9.0.0", + "devtools-protocol": "0.0.1475386", + "puppeteer-core": "24.17.1", + "typed-query-selector": "^2.12.0" + }, + "bin": { + "puppeteer": "lib/cjs/puppeteer/node/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core": { + "version": "24.17.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.17.1.tgz", + "integrity": "sha512-Msh/kf9k1XFN0wuKiT4/npMmMWOT7kPBEUw01gWvRoKOOoz3It9TEmWjnt4Gl4eO+p73VMrvR+wfa0dm9rfxjw==", + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "2.10.8", + "chromium-bidi": "8.0.0", + "debug": "^4.4.1", + "devtools-protocol": "0.0.1475386", + "typed-query-selector": "^2.12.0", + "ws": "^8.18.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamx": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", + "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar-fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", + "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.15.0.tgz", + "integrity": "sha512-7oZJCPvvMvTd0OlqWsIxTuItTpJBpU1tcbVl24FMn3xt3+VSunwUasmfPJRE57oNO1KsZ4PgA1xTdAX4hq8NyQ==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "license": "MIT", + "optional": true + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/.utils/package.json b/.utils/package.json new file mode 100644 index 00000000..307853e6 --- /dev/null +++ b/.utils/package.json @@ -0,0 +1,13 @@ +{ + "type": "module", + "dependencies": { + "cheerio": "^1.1.2", + "node-fetch": "^3.3.2", + "puppeteer": "^24.17.1", + "domhandler": "^5.0.3", + "dotenv": "^17.2.2" + }, + "devDependencies": { + "@octokit/types": "^14.1.0" + } +} diff --git a/.utils/run-scrapers.bat b/.utils/run-scrapers.bat new file mode 100644 index 00000000..a08b2b8d --- /dev/null +++ b/.utils/run-scrapers.bat @@ -0,0 +1,17 @@ +@ECHO OFF +:RUN +node "run-scrapers.mjs" +ECHO. + +REM 显示提示并等待单键 (无需按回车) +ECHO Press [R] to rerun the scrapers, or [ESC]/[Enter]/[Space] to exit... +powershell -NoLogo -NoProfile -Command "$ErrorActionPreference='Stop'; while($true){ $k=$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); if($k.VirtualKeyCode -eq 27 -or $k.VirtualKeyCode -eq 13 -or $k.Character -eq ' '){ exit 1 } elseif($k.Character -match '^[Rr]$'){ exit 0 } }" + +IF ERRORLEVEL 1 GOTO EXIT + +ECHO. +GOTO RUN + +:EXIT +ECHO. +EXIT /B \ No newline at end of file diff --git a/.utils/run-scrapers.mjs b/.utils/run-scrapers.mjs new file mode 100644 index 00000000..f5351aad --- /dev/null +++ b/.utils/run-scrapers.mjs @@ -0,0 +1,175 @@ +// run-scrapers.mjs + +import { spawn } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import * as path from 'node:path'; +import * as fs from 'node:fs/promises'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// 待执行脚本 (顺序可按需调整) +const SCRIPT_LIST = [ + 'scrape-and-inject-agp-releases.mjs', + 'scrape-and-inject-android-studio-agp-version-map.mjs', + 'scrape-and-inject-android-studio-codename_maps.mjs', + 'scrape-and-inject-embedded-kotlin-list.mjs', + 'scrape-and-inject-ksp-releases.mjs', + 'scrape-and-inject-agp-gradle-compatibility-list.mjs', + 'scrape-and-inject-java-gradle-compatibility-list.mjs', + 'scrape-and-inject-rhino-engine-data.mjs', + 'scrape-and-update-readme-template-contributors-table.mjs', +]; + +/** + * 解析 CLI 参数. + * + * @param {string[]} [argv=process.argv.slice(2)] + * @return {{ continueOnError: boolean, dryRun: boolean, nodePath: string, filters: string[] }} + */ +function parseArgs(argv = process.argv.slice(2)) { + const opts = { + continueOnError: false, + dryRun: false, + nodePath: process.execPath, // 使用当前 Node 可执行文件, 避免 PATH 问题 + filters: [], + }; + for (let i = 0; i < argv.length; i++) { + const a = argv[i]; + if (a === '--continue-on-error') opts.continueOnError = true; + else if (a === '--dry-run') opts.dryRun = true; + else if (a === '--node') opts.nodePath = argv[++i]; + else if (a === '--filter') opts.filters.push(argv[++i]); + else if (a.startsWith('--filter=')) opts.filters.push(a.split('=').slice(1).join('=')); + else if (a.startsWith('--node=')) opts.nodePath = a.split('=').slice(1).join('='); + } + return opts; +} + +/** + * @param {number} ms + * @return {string} + */ +function formatDuration(ms) { + const sec = Math.floor(ms / 1000); + const msPart = ms % 1000; + return `${sec}.${String(msPart).padStart(3, '0')}s`; +} + +/** + * @param {import("fs").PathLike} filePath + * @return {Promise} + */ +async function ensureExists(filePath) { + try { + await fs.access(filePath); + return true; + } catch { + return false; + } +} + +/** + * @param {Object} options + * @param {string} options.nodePath + * @param {string} options.scriptPath + * @param {string | URL | undefined} options.cwd + * @return {Promise<{ code: number, signal: NodeJS.Signals | null, ms: number, error?: Error }>} + */ +async function runOne({ nodePath, scriptPath, cwd }) { + return new Promise((resolve) => { + const start = Date.now(); + const child = spawn(nodePath, [ scriptPath ], { + cwd, + stdio: 'inherit', // 直接把子进程的输出打到当前控制台 + env: process.env, + }); + child.on('close', (code, signal) => { + const end = Date.now(); + resolve({ + code: code ?? 0, + signal: signal ?? null, + ms: end - start, + }); + }); + child.on('error', (err) => { + const end = Date.now(); + resolve({ code: 1, signal: null, ms: end - start, error: err }); + }); + }); +} + +async function main() { + const opts = parseArgs(); + + const utilsDir = __dirname; // 运行器位于 .utils + const scripts = SCRIPT_LIST + .map(name => ({ name, abs: path.resolve(utilsDir, name) })) + .filter(s => opts.filters.length === 0 || opts.filters.some(f => s.name.includes(f))); + + console.log('\n============================================================'); + console.log(' Running scrapers in sequence (Node ESM)'); + console.log(` UTILS_DIR = ${utilsDir}`); + console.log(` NODE_EXE = ${opts.nodePath}`); + if (opts.filters.length) console.log(` FILTERS = ${opts.filters.join(', ')}`); + console.log('============================================================\n'); + + if (scripts.length === 0) { + console.log('No scripts to run after filtering.'); + return process.exit(0); + } + + // 检查存在性 + const finalScripts = []; + for (const s of scripts) { + if (await ensureExists(s.abs)) { + finalScripts.push(s); + } else { + console.log(`File not found: ${s.name}`); + } + } + if (finalScripts.length === 0) { + console.log('No existing scripts to run.'); + return process.exit(0); + } + + if (opts.dryRun) { + console.log('The following scripts would run in order:'); + finalScripts.forEach((s, i) => console.log(` (${i + 1}/${finalScripts.length}) ${s.name}`)); + return process.exit(0); + } + + const results = []; + for (let i = 0; i < finalScripts.length; i++) { + const s = finalScripts[i]; + console.log(`[${i + 1}/${finalScripts.length}] ${s.name}`); + const res = await runOne({ nodePath: opts.nodePath, scriptPath: s.abs, cwd: utilsDir }); + if (res.code === 0) { + console.log(`[Duration] ${formatDuration(res.ms)}\n`); + } else { + console.log(`[Duration] ${formatDuration(res.ms)} | [Exit Code] ${res.code}\n`); + results.push({ ...res, name: s.name }); + if (!opts.continueOnError) break; + continue; + } + results.push({ ...res, name: s.name }); + } + + const failed = results.filter(r => r.code !== 0); + console.log('============================================================'); + if (failed.length === 0) { + console.log(' All tasks completed successfully.'); + console.log('============================================================\n'); + process.exit(0); + } else { + console.log(` ${failed.length} task(s) failed:`); + failed.forEach(r => console.log(` - ${r.name} (code ${r.code}, ${formatDuration(r.ms)})`)); + console.log('============================================================\n'); + process.exit(1); + } +} + +main().catch(err => { + console.error(err); + process.exit(1); +}); \ No newline at end of file diff --git a/.utils/scrape-and-inject-agp-gradle-compatibility-list.mjs b/.utils/scrape-and-inject-agp-gradle-compatibility-list.mjs new file mode 100644 index 00000000..5ae9764b --- /dev/null +++ b/.utils/scrape-and-inject-agp-gradle-compatibility-list.mjs @@ -0,0 +1,47 @@ +// scrape-and-inject-agp-gradle-compatibility-list.mjs + +import { getMinSupportedAgpVersion, getMinSupportedGradleVersion } from './utils/properties.mjs'; +import { compareVersionStrings } from './utils/versioning.mjs'; +import { updateAnchoredListInFile } from './utils/anchors.mjs'; +import { findTargetRows } from './utils/puppeteer-helpers.mjs'; + +const URL = 'https://developer.android.com/build/releases/gradle-plugin#updating-gradle'; + +(async function main() { + const rows = await findTargetRows({ + url: URL, + tableSelector: '.devsite-table-wrapper table', + tableFilter: { + 'tr th': [ + `:RegExp:i:${/Plugin version/.source}`, + `:RegExp:i:${/Minimum required Gradle version/.source}`, + ], + }, + tableRowSelector: 'tbody tr', + tableDataSelector: 'td', + tableDataStructure: [ + 'pluginVersion', + 'gradleVersion', + ], + }); + const minSupportedAgpVersion = getMinSupportedAgpVersion(); + const minSupportedGradleVersion = getMinSupportedGradleVersion(); + const map = {}; + for (const { pluginVersion, gradleVersion } of rows) { + if (compareVersionStrings(pluginVersion, minSupportedAgpVersion) < 0) continue; + if (compareVersionStrings(gradleVersion, minSupportedGradleVersion) < 0) continue; + map[pluginVersion] = gradleVersion; + } + + await updateAnchoredListInFile('../settings.gradle.kts', { + anchorTag: 'AGP_GRADLE_COMPATIBILITY_LIST', + listName: 'agpGradleCompatibility', + lines: Object.entries(map) + .sort((a, b) => compareVersionStrings(b[0], a[0])) + .map(([ pluginVersion, gradleVersion ]) => `"${pluginVersion}" to "${gradleVersion}",`), + updatedLabel: 'AGP 与 Gradle 兼容性映射', + }); +})().catch(err => { + console.error(err); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/.utils/scrape-and-inject-agp-releases.mjs b/.utils/scrape-and-inject-agp-releases.mjs new file mode 100644 index 00000000..ce15dfe0 --- /dev/null +++ b/.utils/scrape-and-inject-agp-releases.mjs @@ -0,0 +1,32 @@ +// scrape-and-inject-agp-releases.mjs + +import * as cheerio from 'cheerio'; +import { getMinSupportedAgpVersion } from './utils/properties.mjs'; +import { compareVersionStrings, compareVersionStringsDescending } from './utils/versioning.mjs'; +import { updateAnchoredListInFile } from './utils/anchors.mjs'; + +const URL = 'https://developer.android.com/reference/tools/gradle-api'; + +(async function main() { + const res = await fetch(URL); + const $ = cheerio.load(await res.text()); + const results = new Set(); + $('table').find('a').each((_, el) => { + const a = $(el); + const href = a.attr('href'); + if (href.includes('reference/tools/gradle-api')) { + results.add(a.text()); + } + }); + const minSupportedVersion = getMinSupportedAgpVersion(); + const agpList = Array.from(results).filter(v => compareVersionStrings(v, minSupportedVersion) >= 0).sort(compareVersionStringsDescending); + await updateAnchoredListInFile('../settings.gradle.kts', { + anchorTag: 'ANDROID_GRADLE_PLUGIN_RELEASES_LIST', + listName: 'agpReleases', + lines: agpList.map(v => `"${v}",`), + updatedLabel: 'AGP 发行版本数据', + }); +})().catch((e) => { + console.error('Failed to fetch AGP releases:', e) + process.exit(1); +}) \ No newline at end of file diff --git a/.utils/scrape-and-inject-android-studio-agp-version-map.mjs b/.utils/scrape-and-inject-android-studio-agp-version-map.mjs new file mode 100644 index 00000000..dbdf0344 --- /dev/null +++ b/.utils/scrape-and-inject-android-studio-agp-version-map.mjs @@ -0,0 +1,44 @@ +// scrape-android-studio-agp_version_maps.mjs + +import { fetchStudioAgpTable } from './fetch-and-parse-android-studio-agp-compatibility-table.mjs'; +import { readPropertiesSync } from './utils/properties.mjs'; +import { compareVersionStrings } from './utils/versioning.mjs'; +import { updateAnchoredMapInFile } from './utils/anchors.mjs'; + +const props = readPropertiesSync(); + +const version = { + MIN_IDE: props['MIN_SUPPORTED_ANDROID_STUDIO_IDE_VERSION'], + MIN_AGP: props['MIN_SUPPORTED_ANDROID_STUDIO_AGP_VERSION'], +}; + +(async function main() { + const agpTable = await fetchStudioAgpTable(); + /** @type {{ [targetStudioVersion: string]: string }} */ + const agpMap = {}; + + for (const { studioVersion, agpRange } of agpTable) { + const [ _, targetAgpVersion ] = agpRange.split('-'); + const targetStudioVersion = studioVersion.match(/\d{2,}\.\d+\.\d/)?.[0]; + if (!targetStudioVersion) continue; + if (targetStudioVersion in agpMap) { + if (compareVersionStrings(targetAgpVersion, agpMap[targetStudioVersion]) < 0) { + agpMap[targetStudioVersion] = targetAgpVersion; + } + } else { + agpMap[targetStudioVersion] = targetAgpVersion; + } + if (compareVersionStrings(targetStudioVersion, version.MIN_IDE) <= 0) break; + if (compareVersionStrings(targetAgpVersion, version.MIN_AGP) <= 0) break; + } + + await updateAnchoredMapInFile('../settings.gradle.kts', { + anchorTag: 'ANDROID_STUDIO_AGP_VERSION_MAP', + mapName: 'agpVersionMap', + lines: Object.entries(agpMap).map(([ studioVer, agpVer ]) => `"${studioVer}" to "${agpVer}",`), + updatedLabel: 'AGP 版本映射', + }); +})().catch(err => { + console.error(err); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/.utils/scrape-and-inject-android-studio-codename_maps.mjs b/.utils/scrape-and-inject-android-studio-codename_maps.mjs new file mode 100644 index 00000000..0b09e901 --- /dev/null +++ b/.utils/scrape-and-inject-android-studio-codename_maps.mjs @@ -0,0 +1,480 @@ +// scrape-and-inject-android-studio-codename_maps.mjs + +/** @typedef {import('puppeteer').Page} Page */ +/** @typedef {import('puppeteer').Frame} Frame */ +/** + * @template {Node} T + * @typedef {import('puppeteer').ElementHandle} ElementHandle + */ + +import puppeteer from 'puppeteer'; +import { getLatestStableWindows } from './fetch-and-parse-android-studio-latest-stable-version.mjs'; +import { batchUpdateAnchoredBlocks } from './utils/anchors.mjs'; +import { compareVersionStrings } from './utils/versioning.mjs'; +import { toUpdatedStamp, toYYYYMMDD } from './utils/date.mjs'; +import { sleep } from './utils/async.mjs'; +import { bytes2GiB } from './utils/format.mjs'; +import { getRemoteFileSizeBytes } from './utils/fetch.mjs'; + +const URL = 'https://developer.android.com/studio/archive?hl=en'; + +/** + * 在所有 frame (含主文档) 中查找 "同意" 按钮. + * + * @param {Page} page + * @param {number} [timeoutMs=30000] + * @returns {Promise<{handle: ElementHandle, frame: Frame}>} + */ +async function waitAndFindAgreeButton(page, timeoutMs = 30000) { + const deadline = Date.now() + timeoutMs; + const selector = 'button.button-primary'; + + while (Date.now() < deadline) { + + // 1) 先尝试主文档 + + const mainBtn = await page.$$(selector); + for (const h of mainBtn) { + const txt = await page.evaluate(el => (el.textContent || '').trim().toLowerCase(), h); + if (txt.includes('agree')) return { handle: h, frame: page.mainFrame() }; + } + + // 2) 再查所有子 frame + + const frames = page.frames(); + for (const f of frames) { + /** @type {ElementHandle} */ + const btn = await f.$(selector); + if (!btn) continue; + const txt = await f.evaluate(el => (el.textContent || '').trim().toLowerCase(), btn); + if (txt.includes('i agree') || txt.includes('agree to the terms') || txt === 'agree') { + return { handle: btn, frame: f }; + } + } + + // 3) 触发懒加载: 轻微滚动几次 + + await page.evaluate(() => window.scrollBy(0, 600)); + await sleep(250); + } + throw new Error('未在任何文档中找到 "同意" 按钮 (超时)'); +} + +/** + * 在所有 frame 中等待某个选择器出现, 并返回该 frame. + * + * @param {Page} page + * @param {string} selector + * @param [timeoutMs=30000] + * @returns {Promise} + */ +async function waitForFrameWithSelector(page, selector, timeoutMs = 30000) { + const deadline = Date.now() + timeoutMs; + while (Date.now() < deadline) { + for (const f of page.frames()) { + const el = await f.$(selector); + if (el) return f; + } + await sleep(250); + } + throw new Error(` 未在任何 frame 中找到选择器: ${selector}`); +} + +async function main() { + const browser = await puppeteer.launch({ + headless: true, + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + ], + }); + + const page = await browser.newPage(); + await page.setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36'); + await page.goto(URL, { waitUntil: 'networkidle2', timeout: 60000 }); + + // 滚动到下载区域, 促发懒加载 (有助于注入承载 "同意" 按钮的 iframe) + await page.evaluate(() => { + const anchor = document.querySelector('#downloads') + || Array.from(document.querySelectorAll('h2, h3')) + .find(h => /download|archive/i.test(h.textContent || '')); + if (anchor) anchor.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await sleep(500); + + // 等待并点击 "同意" 按钮 + try { + const { handle, frame } = await waitAndFindAgreeButton(page, 30000); + await frame.waitForSelector('button.button-primary', { visible: true, timeout: 15000 }).catch(() => { + }); + await handle.click(); + } catch (e) { + console.log('未检测到协议或已同意, 继续解析...'); + } + + // 同意后不要在主文档等待; 改为在包含内容的 frame 里等待 devsite-expandable + // 若首次未出现, 尝试轻微滚动以触发懒加载, 再次检查 + /** @type {Frame} */ + let contentFrame; + try { + contentFrame = await waitForFrameWithSelector(page, 'devsite-expandable', 20000); + } catch { + // 尝试滚动触发 + for (let i = 0; i < 8; i++) { + await page.evaluate(() => window.scrollBy(0, 800)); + await sleep(250); + } + // 再次寻找 + contentFrame = await waitForFrameWithSelector(page, 'devsite-expandable', 20000); + } + + /** + * @typedef {Object} ArchiveItem + * @property {string} title + * @property {string} date + * @property {string | null} version + * @property {{ text: string, href: string }[]} links + * @property {{ [filename: string]: string }} checksums + */ + /** + * @type {ArchiveItem[]} + */ + const archives = await contentFrame.$$eval('devsite-expandable', nodes => { + + // 从内容 frame 中直接抽取 devsite-expandable 数据 + + /** + * @param {Node | null} el + * @returns {string} + */ + const pickText = el => (el?.textContent || '').trim(); + + return nodes.map(n => { + /** @type {Node} */ + const titleEl = n.querySelector('.expand-control'); + const title = pickText(titleEl?.childNodes?.[0]); // 不含日期的主标题 + const date = pickText(n.querySelector('.expand-control span')); // 例如 "April 1, 2025" + /** @type {Element[]} */ + const linkEls = Array.from(n.querySelectorAll('.downloads a[href]')); + const links = linkEls.map(a => ({ + text: pickText(a), + href: a.getAttribute('href') || '', + })); + + // 收集 checksums (在 .downloads 文本中) + /** @type {HTMLElement} */ + const downloadsElement = n.querySelector('.downloads'); + const bodyText = (downloadsElement?.innerText || '').trim(); + /** @type {{[filename: string]: string}} */ + const checksums = {}; + // 行格式: + bodyText.split('\n').forEach(line => { + const m = /^\s*([a-f0-9]{64})\s+(.+?)\s*$/.exec(line); + if (m) { + const [ _, sha256, filename ] = m; + checksums[filename] = sha256; + } + }); + + // 解析版本号 (2025.1.2 等), 优先从标题中提取 + let version = null; + const vm = title.match(/\d{2,}\.\d+(?:\.\d+)?/); + if (vm) version = vm[0]; + + return { title, date, version, links, checksums }; + }); + }); + + // 1) 用 "最新稳定版" 的校验和/文件名, 在归档中定位条目, 补全并更新 common.json + + const latestRows = await getLatestStableWindows(); // [{kind, filename, sha256, url, size, ...}] + const latestExe = latestRows.find(x => x.kind === 'exe'); + const latestZip = latestRows.find(x => x.kind === 'zip'); + if (!latestExe || !latestZip) { + throw new Error('最新稳定版条目缺少 Windows EXE 或 ZIP'); + } + + /** + * 在归档中查找: 优先用 sha256 命中, 其次用文件名. + * + * @param {ArchiveItem[]} rows + * @param {import('./fetch-and-parse-android-studio-latest-stable-version.mjs').Row} target + * @return {ArchiveItem | null} + */ + const matchArchive = (rows, target) => { + for (const arc of rows) { + const bySha = target.sha256 && arc.checksums[target.filename] === target.sha256; + const byName = arc.links.some(l => l.text === target.filename); + if (bySha || byName) return arc; + } + return null; + }; + const matchedArc = matchArchive(archives, latestExe) || matchArchive(archives, latestZip); + if (!matchedArc) { + throw new Error('未能在归档中定位到与最新版本对应的条目 (按 sha256/文件名均未命中)'); + } + + /** + * 从匹配到的 expandable 中抽取 Windows EXE/ZIP 的链接/文件名. + * + * @param {string} suffix + * @return {{ filename: string, url: string, sizeGiB?: string | null } | null} + */ + const pickWinItem = suffix => { + // suffix: "-windows.exe" | "-windows.zip" + const link = matchedArc.links.find(l => l.text.endsWith(suffix)); + if (!link) return null; + return { + filename: link.text, + url: link.href, + }; + }; + const exeItem = pickWinItem('-windows.exe'); + const zipItem = pickWinItem('-windows.zip'); + + // 查询真实文件大小 (并发获取), 格式化为 GiB + const [ exeBytes, zipBytes ] = await Promise.all([ + exeItem ? getRemoteFileSizeBytes(exeItem.url) : Promise.resolve(null), + zipItem ? getRemoteFileSizeBytes(zipItem.url) : Promise.resolve(null), + ]); + if (exeItem) exeItem.sizeGiB = bytes2GiB(exeBytes); + if (zipItem) zipItem.sizeGiB = bytes2GiB(zipBytes); + + // 准备写回 common.json 所需字段 + const latestVersionName = matchedArc.title.trim(); // 例: "Android Studio Narwhal Feature Drop | 2025.1.2" + const latestVersionDate = toYYYYMMDD(matchedArc.date) || ''; // 例: "2025/07/31" + + if (!exeItem || !zipItem) { + throw new Error('匹配到的归档条目缺少 Windows EXE 或 ZIP 下载信息'); + } + + // 读取并更新 common.json (仅更新带有 "android_studio_latest_" 片段的键与版本名日期键) + const fs = await import('node:fs/promises'); + const path = await import('node:path'); + + const commonJsonPath = path.resolve(process.cwd(), '../.readme/common.json'); + const commonRaw = await fs.readFile(commonJsonPath, 'utf8'); + const commonObj = JSON.parse(commonRaw); + + const updatedCommon = { + ...commonObj, + android_studio_latest_recommended_version_name: latestVersionName, + var_date_android_studio_latest_recommended_version_name: latestVersionDate, + android_studio_latest_recommended_file_name_of_exe: exeItem.filename, + android_studio_latest_recommended_download_address_of_exe: exeItem.url, + android_studio_latest_recommended_file_size_of_exe: exeItem.sizeGiB ?? commonObj.android_studio_latest_recommended_file_size_of_exe, + android_studio_latest_recommended_file_name_of_zip: zipItem.filename, + android_studio_latest_recommended_download_address_of_zip: zipItem.url, + android_studio_latest_recommended_file_size_of_zip: zipItem.sizeGiB ?? commonObj.android_studio_latest_recommended_file_size_of_zip, + }; + + if (JSON.stringify(updatedCommon) !== JSON.stringify(commonObj)) { + await fs.writeFile(commonJsonPath, JSON.stringify(updatedCommon, null, 2), 'utf8'); + console.log('[common.json] 已更新 (Android Studio 数据)'); + console.log(`-- '${commonObj.android_studio_latest_recommended_version_name}'`); + console.log(`-> '${updatedCommon.android_studio_latest_recommended_version_name}'`); + } else { + // console.log('[common.json] 无需更新 (Android Studio 数据)'); + } + + // 2) 汇总代号 - 版本映射与代号首发日期, 更新 settings.gradle.kts 两个锚点块 + // 2.1 从标题中解析 "代号与版本号" + // 标题模式示例: "Android Studio Meerkat Feature Drop | 2024.3.2 RC 1" + /** + * @param {string} t + * @return {string | null} + */ + const codenameFromTitle = t => { + // 捕获 "Android Studio [Feature Drop] |" + const m = /Android Studio\s+(.+?)\s*(?:(\s+\d+\s+)?Feature Drop)?\s*\|/i.exec(t); + return m ? m[1].trim() : null; + }; + + // 用户手动覆盖映射 (可按需填写或从外部读取) + /** @type {Object} */ + const manualCodenameOverrides = { + /* e.g. 'Meerkat': 'Mkt' */ + }; + + // 生成唯一代码: 按顺序, 出现冲突则对冲突组统一递增长度; 覆盖项优先生效且不可被自动改动 + /** + * @param {string[]} names 原始代号 (保留大小写与空格, 顺序与站点一致) + * @param {Object} overrides 手动覆盖映射 + * @returns {Map} name -> code + */ + function buildUniquePrefixes(names, overrides) { + // 代码不包含空格; 按名称去空格后逐字符递增长度 + const entries = names.map(n => ({ + name: n, + base: n.replace(/\s+/g, ''), // 去空格用于截取 + len: Math.max(1, overrides[n] ? overrides[n].replace(/\s+/g, '').length : 1), + code: overrides[n] ? overrides[n].replace(/\s+/g, '') : null, + locked: !!overrides[n], + })); + + // 先赋初值 + for (const e of entries) { + if (!e.code) e.code = e.base.slice(0, e.len); + } + + // 检测并解决冲突 + const maxLenByName = new Map(entries.map(e => [ e.name, e.base.length ])); + // 循环上限保护, 防止极端情况下死循环 + for (let step = 0; step < 1024; step++) { + // 统计冲突组: code -> indices + /** @type {Map} */ + const bucket = new Map(); + entries.forEach((e, idx) => { + const key = e.code; + if (!bucket.has(key)) bucket.set(key, []); + bucket.get(key).push(idx); + }); + + // 找到有冲突的组 (size >= 2) + const conflicts = Array.from(bucket.entries()).filter(([ , indices ]) => indices.length >= 2); + if (conflicts.length === 0) break; // 已无冲突 + + // 逐组处理 + for (const [ code, indices ] of conflicts) { + // 若组内存在 >=2 个锁定项且 code 相同 -> 直接报错 + const lockedIndices = indices.filter(i => entries[i].locked); + if (lockedIndices.length >= 2) { + const letter = code[0]?.toUpperCase() || '?'; + const groupNames = indices.map(i => entries[i].name); + throw new Error(`[CodenameMap] 手动覆盖映射发生冲突: "${code}" -> ${groupNames.join(', ')}. 请调整覆盖映射. 冲突首字母组: ${letter}*`); + } + + // 让组内所有 "未锁定项" 统一递增长度 + for (const i of indices) { + const e = entries[i]; + if (e.locked) continue; // 覆盖项不改 + const maxLen = maxLenByName.get(e.name); + if (e.len >= maxLen) { + // 已经用到全长仍冲突 -> 无法自动消解 + const letter = e.base[0]?.toUpperCase() || '?'; + const groupNames = indices.map(ii => entries[ii].name); + throw new Error(`[CodenameMap] 无法自动消解冲突 ("${e.name}" 与同组名称完全相同或为彼此前缀到尽头). 请为该首字母组手动指定覆盖映射.\n- 组首字母: ${letter}\n- 组成员: ${groupNames.join(', ')}`); + } + e.len += 1; + e.code = e.base.slice(0, e.len); + } + } + } + + return new Map(entries.map(e => [ e.name, e.code ])); + } + + // 提取按页面顺序的代号列表 (去重, 保留第一次出现顺序) + const codenamesOrdered = []; + const seen = new Set(); + for (const arc of archives) { + const cname = codenameFromTitle(arc.title); + if (!cname) continue; + if (!seen.has(cname)) { + seen.add(cname); + codenamesOrdered.push(cname); + } + } + + // 构建 name->code 映射 (按规则自动消解冲突; 支持手动覆盖) + const nameToCode = buildUniquePrefixes(codenamesOrdered, manualCodenameOverrides); + + // 收集每版本 (yyyy.m.patch) 对应的代号集合, 以及每个代号的首发日期 + /** @type {Map>} */ + const versionToLetters = new Map(); + /** @type {Map} */ + const letterBorn = new Map(); + + for (const arc of archives) { + if (!arc.version) continue; // 版本号 (yyyy.m.patch) + const cname = codenameFromTitle(arc.title); + if (!cname) continue; + + const code = nameToCode.get(cname); + if (!code) continue; + + // 映射 version -> codes + if (!versionToLetters.has(arc.version)) versionToLetters.set(arc.version, new Set()); + versionToLetters.get(arc.version).add(code); + + // 记录代号首次出现日期 + const d = new Date(arc.date); + const existed = letterBorn.get(code); + if (!existed || d < existed.born) { + letterBorn.set(code, { name: cname, born: d }); + } + } + + // 生成 codenameVersionMap 文本 (按版本倒序排列, 值用 "A|B" 连接) + const sortedVersions = Array.from(versionToLetters.keys()).sort((a, b) => { + const [ ay, am, ap ] = a.split('.').map(Number); + const [ by, bm, bp ] = b.split('.').map(Number); + return by - ay || bm - am || bp - ap; + }); + + const versionLettersList = sortedVersions.map(v => [ v, Array.from(versionToLetters.get(v)).sort().join('|') ]); + + /* e.g. { "2023.3": {1: "J", 2: "J|K"} }. */ + /** @type {Object} */ + const rawVersionLettersMap = {}; + for (let i = 0; i < versionLettersList.length; i++) { + const [ v, letters ] = versionLettersList[i]; + const matched = v.match(/(^\d+\.\d+)(?:\.(\d+))?/); + if (!matched) continue; + const [ , major, patch ] = matched; + if (major in rawVersionLettersMap) { + rawVersionLettersMap[major][patch] = letters; + } else { + rawVersionLettersMap[major] = { [patch]: letters }; + } + } + + /* e.g. { "2024.3": "M", "2024.1.2": "K" }. */ + const combinedVersionLettersMap = {}; + + Object.entries(rawVersionLettersMap).forEach(([ major, patchToLetters ]) => { + const letterValues = Object.values(patchToLetters); + if (new Set(letterValues).size === 1) { + combinedVersionLettersMap[major] = letterValues[0]; + } else { + Object.entries(patchToLetters).forEach(([ patch, letters ]) => { + combinedVersionLettersMap[`${major}.${patch}`] = letters; + }); + } + }); + + const versionMapLines = Object.entries(combinedVersionLettersMap) + .sort((a, b) => compareVersionStrings(b[0], a[0])) + .map(([ v, letters ]) => `"${v}" to "${letters}",`); + + // 生成 codenameMap 文本 (按 born 日期倒序; 注释: Born on Mon d, yyyy.) + // 这里 key 为自动生成的 code (可能为一到多字符), value 为完整代号 + const sortedLetters = Array.from(letterBorn.entries()) + .sort((a, b) => b[1].born.getTime() - a[1].born.getTime()); + + const codenameMapLines = sortedLetters.map(([ code, { name, born } ]) => { + const bornStr = toUpdatedStamp(born); + return `"${code}" to "${name}", /* Born on ${bornStr}. */`; + }); + + await batchUpdateAnchoredBlocks('../settings.gradle.kts', [ { + type: 'map', + anchorTag: 'ANDROID_STUDIO_CODENAME_VERSION_MAP', + mapName: 'codenameVersionMap', + lines: versionMapLines, + updatedLabel: 'Android Studio 代号版本映射', + }, { + type: 'map', + anchorTag: 'ANDROID_STUDIO_CODENAME_MAP', + mapName: 'codenameMap', + lines: codenameMapLines, + updatedLabel: 'Android Studio 代号名称映射', + } ]); + + await browser.close(); +} + +main().catch(err => { + console.error(err); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/.utils/scrape-and-inject-embedded-kotlin-list.mjs b/.utils/scrape-and-inject-embedded-kotlin-list.mjs new file mode 100644 index 00000000..f6853fd4 --- /dev/null +++ b/.utils/scrape-and-inject-embedded-kotlin-list.mjs @@ -0,0 +1,98 @@ +// scrape-and-inject-embedded-kotlin-list.mjs + +/** @typedef {import('puppeteer').Page} Page */ + +import puppeteer from 'puppeteer'; +import { getMinSupportedGradleVersion } from './utils/properties.mjs'; +import { updateAnchoredListInFile } from './utils/anchors.mjs'; +import { compareVersionStrings } from './utils/versioning.mjs'; +import { autoScroll } from './utils/puppeteer-helpers.mjs'; +import { sleep } from './utils/async.mjs'; + +const URL = 'https://docs.gradle.org/current/userguide/compatibility.html#kotlin'; + +const unofficialKotlinCompatibilityList = { + '8.14': '2.1.10', + '8.13': '2.1.10', +}; + +/** + * @param {Page} page + * @return {Promise} + */ +async function findTargetRows(page) { + return await page.evaluate(() => { + /** @type {HTMLTableElement[]} */ + const targets = Array.from(document.querySelectorAll('table.tableblock')); + const target = targets.find(t => { + const tableHeadList = t.querySelectorAll('th'); + return Array.from(tableHeadList).some(th => /Embedded Kotlin version|Minimum Gradle version|Kotlin Language version/i.test(th.textContent)); + }); + if (!target) return null; + + return Array.from(target.querySelectorAll('tbody tr')) + .map(tr => { + const tds = tr.querySelectorAll('td'); + if (tds.length < 3) return null; + const kotlin = tds[0]?.querySelector('p')?.textContent?.trim(); + const gradle = tds[1]?.querySelector('p')?.textContent?.trim(); + const ktLanguage = tds[2]?.querySelector('p')?.textContent?.trim(); + return kotlin && gradle && ktLanguage ? [ kotlin, gradle, ktLanguage ] : null; + }) + .filter(Boolean); + }); +} + +(async function main() { + const browser = await puppeteer.launch({ headless: true }); + const page = await browser.newPage(); + try { + await page.goto(URL, { waitUntil: 'networkidle0', timeout: 120000 }); + + // 页面为懒加载: 滚动并多次尝试, 直到目标表格出现或超时 + let rows = null; + const deadline = Date.now() + 30000; // 30s 总超时 + while (Date.now() < deadline) { + rows = await findTargetRows(page); + if (rows && rows.length) break; + await autoScroll(page); + await sleep(300); + } + if (!rows || !rows.length) { + throw new Error('Unable to locate target table rows (lazy-loaded content not found in time)'); + } + + /** + * @type {{ [gradle: string]: { kotlin: string, isUnofficial: boolean } }} + */ + const map = {}; + const minSupportedGradleVersion = getMinSupportedGradleVersion(); + + for (const [ kotlin, gradle ] of rows) { + if (compareVersionStrings(gradle, minSupportedGradleVersion) < 0) continue; + map[gradle] = { kotlin, isUnofficial: false }; + } + + Object.entries(unofficialKotlinCompatibilityList).forEach(([ gradle, kotlin ]) => { + if (!(gradle in map)) map[gradle] = { kotlin, isUnofficial: true }; + }); + + await updateAnchoredListInFile('../settings.gradle.kts', { + anchorTag: 'EMBEDDED_KOTLIN_LIST', + listName: 'embeddedKotlin', + lines: Object.entries(map) + .sort((a, b) => compareVersionStrings(b[1]['kotlin'], a[1]['kotlin'])) + .map(([ gradle, { kotlin, isUnofficial } ]) => { + return isUnofficial + ? `"${gradle}" to "${kotlin}", /* Unofficial. */` + : `"${gradle}" to "${kotlin}",`; + }), + updatedLabel: 'Java 与 Gradle 兼容性映射', + }); + } finally { + await browser.close(); + } +})().catch(err => { + console.error(err); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/.utils/scrape-and-inject-java-gradle-compatibility-list.mjs b/.utils/scrape-and-inject-java-gradle-compatibility-list.mjs new file mode 100644 index 00000000..c4fb4463 --- /dev/null +++ b/.utils/scrape-and-inject-java-gradle-compatibility-list.mjs @@ -0,0 +1,62 @@ +// scrape-and-inject-java-gradle-compatibility-list.mjs + +import { getMinSupportedJavaVersionInt } from './utils/properties.mjs'; +import { updateAnchoredListInFile } from './utils/anchors.mjs'; +import { findTargetRows } from './utils/puppeteer-helpers.mjs'; + +const URL = 'https://docs.gradle.org/current/userguide/compatibility.html#java_runtime'; + +const unofficialGradleCompatibilityList = { + 25: '9.0', +}; + +(async function main() { + const rows = await findTargetRows({ + url: URL, + tableSelector: 'table.tableblock', + tableFilter: { + 'caption': `:RegExp:i:${/java compatibility/.source}`, + }, + tableRowSelector: 'tbody tr', + tableDataSelector: 'td', + tableDataStructure: [ + { 'java': `:RegExp:${/^\d+$/.source}` }, + { 'toolchain': `:RegExp:${/^N\/A$|\d+\.\d+/.source}` }, + { 'gradle': `:RegExp:${/^N\/A$|\d+\.\d+/.source}` }, + ], + }); + /** + * @type {{ [javaInt: string]: string }} + */ + const map = {}; + const minSupportedJavaVersionInt = getMinSupportedJavaVersionInt(); + for (const { java, gradle } of rows) { + const javaInt = parseInt(java); + if (Number.isNaN(javaInt)) { + throw Error(`Invalid java version int: ${java}`); + } + if (javaInt >= minSupportedJavaVersionInt) { + map[javaInt] = gradle; + } + } + + await updateAnchoredListInFile('../settings.gradle.kts', { + anchorTag: 'JAVA_GRADLE_COMPATIBILITY_LIST', + listName: 'javaGradleCompatibility', + lines: Object.entries(map) + .sort((a, b) => Number(b[0]) - Number(a[0])) + .map(([ java, gradle ]) => { + if (gradle === 'N/A') { + const unofficialGradleVersion = unofficialGradleCompatibilityList[java]; + if (unofficialGradleVersion) { + return `${java} to "${unofficialGradleVersion}", /* Unofficial. */`; + } + } + return `${java} to "${gradle}",`; + }), + updatedLabel: 'Java 与 Gradle 兼容性映射', + }); +})().catch(err => { + console.error(err); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/.utils/scrape-and-inject-ksp-releases.mjs b/.utils/scrape-and-inject-ksp-releases.mjs new file mode 100644 index 00000000..d1b4e206 --- /dev/null +++ b/.utils/scrape-and-inject-ksp-releases.mjs @@ -0,0 +1,224 @@ +// scrape-and-inject-ksp-releases.mjs + +/** @typedef {import('@octokit/types').Endpoints['GET /repos/{owner}/{repo}/releases']['response']['data']} ReleasesData */ + +import * as https from 'https'; +import { updateAnchoredMapInFile } from './utils/anchors.mjs'; +import { toUpdatedStamp } from './utils/date.mjs'; + +/** + * @param {string} url + * @param {Object} [options={}] + * @param {import("http").OutgoingHttpHeaders} [options.headers={}] + * @param {number} [options.timeout=15000] + * @return {Promise} + */ +function httpsGetJson(url, options = {}) { + return new Promise((resolve, reject) => { + const req = https.request( + url, + { + method: 'GET', + headers: { + 'User-Agent': 'node', + 'Accept': 'application/vnd.github+json', + ...(options.headers || {}), + }, + timeout: options.timeout || 15000, + }, + (res) => { + const { statusCode } = res; + const chunks = []; + + res.on('data', (d) => chunks.push(d)); + res.on('end', () => { + const body = Buffer.concat(chunks).toString('utf8'); + + if (statusCode < 200 || statusCode >= 300) { + return reject( + new Error(`HTTP ${statusCode}: ${body.slice(0, 200)}`), + ); + } + + try { + const json = /** @type {ReleasesData} */ JSON.parse(body); + resolve(json); + } catch (e) { + reject(new Error(`JSON parse error: ${e.message}`)); + } + }); + }, + ); + + req.on('error', reject); + req.on('timeout', () => { + req.destroy(new Error('Request timed out')); + }); + req.end(); + }); +} + +/** + * @typedef {Object} KspRelease + * @property {string} version + * @property {string} name + * @property {string} publishedAt + */ +/** + * @return {Promise} + */ +async function fetchKspReleases() { + const base = 'https://api.github.com/repos/google/ksp/releases'; + const perPage = 100; + let page = 1; + let reached = false; + const out = []; + + /** @type {import("http").OutgoingHttpHeaders} */ + const headers = {}; + if (process.env.GITHUB_TOKEN) { + headers.authorization = `Bearer ${process.env.GITHUB_TOKEN}`; + } + + while (!reached) { + const url = `${base}?per_page=${perPage}&page=${page}`; + const releases = await httpsGetJson(url, { headers }); + if (!Array.isArray(releases) || releases.length === 0) break; + + for (const release of releases) { + const tag = String(release.tag_name || '').trim(); + // 记录 + out.push({ + version: tag, + name: release.name, + publishedAt: release.published_at, + }); + + // 判断是否已到达目标最旧版本(含) + const parts = tag.split('-'); + if (parts.length >= 2) { + const kspVer = parts.slice(0, -1).join('-'); + if (kspVer === '1.8.0-RC2') { + reached = true; + break; + } + } + } + + if (reached) break; + page += 1; + } + + return out; +} + +/** + * @param {KspRelease[]} releases + * @return {string[]} + */ +function parseReleases(releases) { + if (!Array.isArray(releases)) return []; + + // 先根据 KSP 版本去重,保留发布时间最新的一条 + /** @type {Map} */ + const latestByKsp = new Map(); // kspVer -> { kotlinVer, date } + for (const r of releases) { + const rawVer = String(r.version || '').trim(); + const parts = rawVer.split('-'); + if (parts.length < 2) continue; // 跳过无效项 + + const kotlinVer = parts.pop(); + const kspVer = parts.join('-'); + + const d = new Date(r.publishedAt); + if (Number.isNaN(d.getTime())) continue; + + const prev = latestByKsp.get(kspVer); + if (!prev || d > prev.date) { + latestByKsp.set(kspVer, { kotlinVer, date: d }); + } + } + + /** + * 解析 KSP 版本用于排序. + * + * @param {string} ksp + * @return {{ baseNums: number[], rank: number, qName: string, qNum: number }} + */ + function parseKspVer(ksp) { + const [ base, qualifierRaw = '' ] = ksp.split('-', 2); + const baseNums = base.split('.').map((n) => parseInt(String(n), 10) || 0); + + let qName = ''; + let qNum = 0; + if (qualifierRaw) { + const m = /^([A-Za-z]+)(\d+)?$/i.exec(qualifierRaw.trim()); + if (m) { + qName = m[1].toUpperCase(); + qNum = m[2] ? parseInt(m[2], 10) : 0; + } else { + qName = qualifierRaw.toUpperCase(); + } + } + + // 等级:稳定版 > RC > Beta > 其他 + const rankMap = { '': 3, RC: 2, BETA: 1 }; + const rank = Object.prototype.hasOwnProperty.call(rankMap, qName) ? rankMap[qName] : 0; + + return { baseNums, rank, qName, qNum }; + } + + /** + * @param {number[]} aNums + * @param {number[]} bNums + * @return {number} + */ + function cmpBaseDesc(aNums, bNums) { + const len = Math.max(aNums.length, bNums.length); + for (let i = 0; i < len; i++) { + const av = aNums[i] ?? 0; + const bv = bNums[i] ?? 0; + if (av !== bv) return bv - av; // 降序 + } + return 0; + } + + // 转为数组并按 KSP 版本降序排列 + /** + * @type {Array<{ kspVer: string, kotlinVer: string, date: Date, parsed: { baseNums: number[], rank: number, qName: string, qNum: number } }>} + */ + const items = Array.from(latestByKsp.entries()) + .map(([ kspVer, v ]) => { + const parsed = parseKspVer(kspVer); + return { kspVer, kotlinVer: v.kotlinVer, date: v.date, parsed }; + }) + .sort((a, b) => { + // 1) 基础版本号降序 + let c = cmpBaseDesc(a.parsed.baseNums, b.parsed.baseNums); + if (c !== 0) return c; + // 2) 级别降序(稳定版 > RC > Beta > 其他) + if (a.parsed.rank !== b.parsed.rank) return b.parsed.rank - a.parsed.rank; + // 3) 同级别数字降序(RC2 > RC1;Beta2 > Beta1;无数字视为 0) + if (a.parsed.qNum !== b.parsed.qNum) return b.parsed.qNum - a.parsed.qNum; + // 4) 兜底,限定词字典序降序(稳定排序用) + if (a.parsed.qName !== b.parsed.qName) return a.parsed.qName < b.parsed.qName ? 1 : -1; + // 5) 仍然相同则按日期降序(保险) + return b.date.getTime() - a.date.getTime(); + }); + + return items.map(({ kspVer, kotlinVer, date }) => { + const dateStr = toUpdatedStamp(date); + return `"${kspVer}" to "${kotlinVer}", /* ${dateStr}. */`; + }); +} + +fetchKspReleases() + .then(async (releases) => { + await updateAnchoredMapInFile('../settings.gradle.kts', { + anchorTag: 'KSP_VERSION_MAP', + mapName: 'kspVersionMap', + lines: parseReleases(releases).map(l => `${l}`), + updatedLabel: 'KSP 发行版本映射', + }); + }) + .catch((error) => console.error('Failed to fetch KSP releases:', error)); \ No newline at end of file diff --git a/.utils/scrape-and-inject-rhino-engine-data.mjs b/.utils/scrape-and-inject-rhino-engine-data.mjs new file mode 100644 index 00000000..e1583bf2 --- /dev/null +++ b/.utils/scrape-and-inject-rhino-engine-data.mjs @@ -0,0 +1,80 @@ +// scrape-and-inject-rhino-engine-data.mjs + +import { getLatestCommitDate } from './utils/fetch.mjs'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; + +const URL = 'https://raw.githubusercontent.com/SuperMonster003/Rhino-For-AutoJs6/refs/heads/master/gradle.properties'; + +/** + * @param {string} latestVersion + * @return {Promise} + */ +async function updateTemplateReadmeRhinoBadge(latestVersion) { + const templateReadmePath = path.resolve(process.cwd(), '../.readme/template_readme.md'); + const fileContent = fs.readFileSync(templateReadmePath, 'utf8'); + const rhinoBadgeRegex = /(href=.*?https:\/\/github\.com\/mozilla\/rhino.+?img\.shields\.io\/badge\/Rhino-)(.+)(-[a-f\d]{6}\b)/; + const matched = fileContent.match(rhinoBadgeRegex); + const oldVersion = matched[2].replaceAll('--', '-'); + if (oldVersion !== latestVersion) { + const updatedFileContent = fileContent.replace(rhinoBadgeRegex, `$1${latestVersion.replaceAll('-', '--')}$3`); + fs.writeFileSync(templateReadmePath, updatedFileContent, 'utf8'); + console.log('[template_readme.md] 已更新 (Rhino 徽标版本)'); + console.log(`-- ${oldVersion}`); + console.log(`-> ${latestVersion}`); + } else { + // console.log('[template_readme.md] 无需更新 (Rhino 徽标版本)'); + } +} + +/** + * @param {string} latestVersion + * @param {number} linenoOfLatestVersion + * @return {Promise} + */ +async function updateCommonJsonWithRhinoData(latestVersion, linenoOfLatestVersion) { + const commonJsonPath = path.resolve(process.cwd(), '../.readme/common.json'); + const commonRaw = fs.readFileSync(commonJsonPath, 'utf8'); + const commonObj = JSON.parse(commonRaw); + + const addressPrefix = 'http://rhino.autojs6.com/blob/master/gradle.properties'; + const addressSuffix = linenoOfLatestVersion > 0 ? `#L${linenoOfLatestVersion}` : ''; + const addressJsonValue = `[v${latestVersion}](${addressPrefix}${addressSuffix})`; + const latestCommitValue = await getLatestCommitDate('SuperMonster003', 'Rhino-For-AutoJs6'); + + const updatedCommon = { + ...commonObj, + latest_rhino_engine_name_with_github_lineno_address: addressJsonValue, + var_date_rhino_engine_latest_committed: latestCommitValue, + }; + + if (JSON.stringify(updatedCommon) !== JSON.stringify(commonObj)) { + fs.writeFileSync(commonJsonPath, JSON.stringify(updatedCommon, null, 2), 'utf8'); + console.log('[common.json] 已更新 (Rhino 数据)'); + [ 'latest_rhino_engine_name_with_github_lineno_address', 'var_date_rhino_engine_latest_committed' ].forEach(key => { + if (key in updatedCommon && key in commonObj && updatedCommon[key] !== commonObj[key]) { + console.log(`## ${key}`); + console.log(`-- ${commonObj[key]}`); + console.log(`-> ${updatedCommon[key]}`); + } + }); + } else { + // console.log('[common.json] 无需更新 (Rhino 数据)'); + } +} + +async function main() { + const response = await fetch(URL); + const text = await response.text(); + const lines = text.split('\n'); + const latestVersion = lines.find(line => line.startsWith('version=')).split('=')[1]; + const linenoOfLatestVersion = lines.findIndex(line => line.startsWith('version=')) + 1; + + await updateTemplateReadmeRhinoBadge(latestVersion); + await updateCommonJsonWithRhinoData(latestVersion, linenoOfLatestVersion); +} + +main().catch(err => { + console.error(err); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/.utils/scrape-and-update-readme-template-contributors-table.mjs b/.utils/scrape-and-update-readme-template-contributors-table.mjs new file mode 100644 index 00000000..65d6c75f --- /dev/null +++ b/.utils/scrape-and-update-readme-template-contributors-table.mjs @@ -0,0 +1,46 @@ +// scrape-and-update-readme-template-contributors-table.mjs + +import { fetchStatistics } from './fetch-and-parse-autojs6-merged-pr-commits-statistics.mjs'; +import * as fs from 'node:fs'; +import { toYYYYMMDD } from './utils/date.mjs'; +import * as path from 'node:path'; + +function updateCommonJsonFile() { + const commonJsonPath = path.resolve(process.cwd(), '../.readme/common.json'); + const commonRaw = fs.readFileSync(commonJsonPath, 'utf8'); + const commonObj = JSON.parse(commonRaw); + + const updatedCommon = { + ...commonObj, + var_date_contribution_table_data_updated: toYYYYMMDD(), + }; + + if (JSON.stringify(updatedCommon) !== JSON.stringify(commonObj)) { + fs.writeFileSync(commonJsonPath, JSON.stringify(updatedCommon, null, 2), 'utf8'); + console.log('[common.json] 已更新 (贡献参与数据统计日期)'); + } +} + +(async function main() { + const path = '../.readme/template_readme.md'; + + const stats = await fetchStatistics(); + const newMarkdown = stats.map(stat => `| ${stat.contributorMarkdown} | ${stat.commitsCountMarkdown} | ${stat.latestCommitMarkdown} |`).join('\n'); + + const text = fs.readFileSync(path, { encoding: 'utf-8' }); + const newText = text.replace(/((?:table_header_contribution_contributors|table_header_contribution_number_of_commits|table_header_contribution_recent_submissions).+\r?\n)([\s|:\-]+\r?\n)(\|\s* { + console.error(err); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/.utils/tsconfig.json b/.utils/tsconfig.json new file mode 100644 index 00000000..596d5a2e --- /dev/null +++ b/.utils/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "module": "ESNext", + "moduleResolution": "Node", + "target": "ES2022", + "lib": ["ES2022", "DOM"], + "types": ["node"], + }, + "include": ["**/*.js", "**/*.mjs", "**/*.ts"] +} diff --git a/.utils/utils/anchors.mjs b/.utils/utils/anchors.mjs new file mode 100644 index 00000000..1273e275 --- /dev/null +++ b/.utils/utils/anchors.mjs @@ -0,0 +1,263 @@ +// utils/anchors.mjs + +import * as fsp from 'node:fs/promises'; +import * as path from 'node:path'; +import { toUpdatedStamp } from './date.mjs'; + +/** + * @param {string} s + * @returns {string} + */ +const normalize = s => String(s).replace(/\s+/g, ''); + +/** + * 在指定 Anchor 块中, 用给定的替换函数生成新块内容. + * + * @param {string} src + * @param {string} anchorTag + * @param {(block: string) => { newBlock: string, changed: boolean }} replaceBlockFn + * @returns {{ src: string, changed: boolean }} - 返回 { src: 新源码, changed: 是否发生变更 }. 若找不到锚点, 原样返回. + */ +export function replaceInAnchoredBlock(src, anchorTag, replaceBlockFn) { + const beginTag = `// @AnchorBegin ${anchorTag}`; + const endTag = `// @AnchorEnd ${anchorTag}`; + + const beginIdx = src.indexOf(beginTag); + if (beginIdx === -1) return { src, changed: false }; + + const endIdx = src.indexOf(endTag, beginIdx + beginTag.length); + if (endIdx === -1) return { src, changed: false }; + + const before = src.slice(0, beginIdx); + const block = src.slice(beginIdx, endIdx); // 不包含 endTag + const after = src.slice(endIdx); + + const { newBlock, changed } = replaceBlockFn(block) || {}; + if (!changed || !newBlock) return { src, changed: false }; + + return { src: before + newBlock + after, changed }; +} + +/** + * 替换锚点块中的某个 map 声明 (如 mapOf(...)), 并在变更时自动刷新 @Updated 日期. + * + * @param {string} src + * @param {Object} options + * @param {string} options.anchorTag - 块的锚点名 + * @param {string} options.mapName - 变量名, 如 agpVersionMap + * @param {string[]} options.lines - map 体内的每行 (不含缩进, 由函数自动缩进) + * @param {number} [options.linesIndent=4] + * @param {(date?: Date) => string} [options.toUpdatedStamp=toUpdatedStamp] - 自定义时间戳函数 (可选) + * @returns {{ src: string, changed: boolean }}} + */ +export function replaceAnchoredMapBlock(src, { + anchorTag, + mapName, + lines, + linesIndent = 4, + toUpdatedStamp: toStamp = toUpdatedStamp, +}) { + return replaceInAnchoredBlock(src, anchorTag, (block) => { + let changed = false; + + const re = new RegExp(`([\\t\\x20]*)(va[lr]\\s+)?${mapName}\\s*=\\s*mapOf\\([\\s\\S]*?\\)(,?)`, 'm'); + let updatedBlock = block.replace(re, (/** @type {string} */ original, /** @type {string} */ indent, /** @type {string} */ keyword, /** @type {string} */ comma) => { + const kw = keyword ?? ''; + const body = lines.map(l => `${' '.repeat(linesIndent)}${indent}${l}`).join('\n'); + const next = `${indent}${kw}${mapName} = mapOf(\n${body}\n${indent})${comma}`; + if (normalize(original) !== normalize(next)) changed = true; + return next; + }); + if (changed) { + updatedBlock = updatedBlock.replace( + /(@Updated[^\n]*?\son\s)([A-Z][a-z]{2}\s\d{1,2},\s\d{4})(\.?)/, + (_, p1, _old, p3) => `${p1}${(toStamp())}${p3}`, + ); + } + + return { newBlock: updatedBlock, changed }; + }); +} + +/** + * 替换锚点块中的某个 list 声明 (如 listOf(...)), 并在变更时自动刷新 @Updated 日期. + * + * @param {string} src + * @param {Object} options + * @param {string} options.anchorTag - 块的锚点名 + * @param {string} options.listName - 变量名, 如 modules 或 libs + * @param {string[]} options.lines - list 体内的每行 (不含缩进, 由函数自动缩进) + * @param {number} [options.linesIndent=4] + * @param {(date?: Date) => string} [options.toUpdatedStamp=toUpdatedStamp] - 自定义时间戳函数 (可选) + * @returns {{ src: string, changed: boolean }}} + */ +export function replaceAnchoredListBlock(src, { + anchorTag, + listName, + lines, + linesIndent = 4, + toUpdatedStamp: toStamp = toUpdatedStamp, +}) { + return replaceInAnchoredBlock(src, anchorTag, (block) => { + let changed = false; + + const re = new RegExp(`([\\t\\x20]*)(va[lr]\\s+)?${listName}\\s*=\\s*listOf\\([\\s\\S]*?\\)(,?)`, 'm'); + let updatedBlock = block.replace(re, (original, indent, keyword, comma) => { + const kw = keyword ?? ''; + const body = lines.map(l => `${' '.repeat(linesIndent)}${indent}${l}`).join('\n'); + const next = `${indent}${kw}${listName} = listOf(\n${body}\n${indent})${comma}`; + if (normalize(original) !== normalize(next)) changed = true; + return next; + }); + if (changed) { + updatedBlock = updatedBlock.replace( + /(@Updated[^\n]*?\son\s)([A-Z][a-z]{2}\s\d{1,2},\s\d{4})(\.?)/, + (_, p1, _old, p3) => `${p1}${(toStamp())}${p3}`, + ); + } + + return { newBlock: updatedBlock, changed }; + }); +} + +/** + * 高层封装: 读取文件 -> 替换锚点 map -> 若有变更则写回 -> 打印日志. + * + * @param {string} filePath + * @param {Object} options + * @param {string} options.anchorTag - 块的锚点名 + * @param {string} options.mapName - 变量名, 如 agpVersionMap + * @param {string[]} options.lines - map 体内的每行 (不含缩进, 由函数自动缩进) + * @param {number} [options.linesIndent=4] + * @param {string} [options.updatedLabel=''] + * @param {(date?: Date) => string} [options.toUpdatedStamp=toUpdatedStamp] - 自定义时间戳函数 (可选) + * @param {Console} [options.logger=console] + * @returns {Promise<{ changed: boolean, content: string }>} + */ +export async function updateAnchoredMapInFile(filePath, { + anchorTag, + mapName, + lines, + linesIndent = 4, + updatedLabel = '', + toUpdatedStamp: toStamp = toUpdatedStamp, + logger = console, +}) { + const filename = path.basename(filePath); + const raw = await fsp.readFile(filePath, 'utf8'); + const { src: updated, changed } = replaceAnchoredMapBlock(raw, { anchorTag, mapName, lines, linesIndent, toUpdatedStamp: toStamp }); + + if (changed) { + await fsp.writeFile(filePath, updated, 'utf8'); + logger.log(`[${filename}] 已更新` + (updatedLabel ? ` (${updatedLabel})` : '')); + } else { + // logger.log(`[${filename}] 无需更新` + (updatedLabel ? ` (${updatedLabel})` : '')); + } + return { changed, content: updated }; +} + +/** + * 高层封装: 读取文件 -> 替换锚点 list -> 若有变更则写回 -> 打印日志. + * + * @param {string} filePath + * @param {Object} options + * @param {string} options.anchorTag - 块的锚点名 + * @param {string} options.listName - 变量名, 如 modules 或 libs + * @param {string[]} options.lines - list 体内的每行 (不含缩进, 由函数自动缩进) + * @param {number} [options.linesIndent=4] + * @param {string} [options.updatedLabel=''] + * @param {(date?: Date) => string} [options.toUpdatedStamp=toUpdatedStamp] - 自定义时间戳函数 (可选) + * @param {Console} [options.logger=console] + * @returns {Promise<{ changed: boolean, content: string }>} + */ +export async function updateAnchoredListInFile(filePath, { + anchorTag, + listName, + lines, + linesIndent = 4, + updatedLabel = '', + toUpdatedStamp: toStamp = toUpdatedStamp, + logger = console, +}) { + const filename = path.basename(filePath); + const raw = await fsp.readFile(filePath, 'utf8'); + const { src: updated, changed } = replaceAnchoredListBlock(raw, { anchorTag, listName, lines, linesIndent, toUpdatedStamp: toStamp }); + + if (changed) { + await fsp.writeFile(filePath, updated, 'utf8'); + logger.log(`[${filename}] 已更新` + (updatedLabel ? ` (${updatedLabel})` : '')); + } else { + // logger.log(`[${filename}] 无需更新` + (updatedLabel ? ` (${updatedLabel})` : '')); + } + return { changed, content: updated }; +} + +/** + * @typedef {Object} AnchoredBlockUpdateOption + * @property {'map' | 'list' | 'custom'} type + * @property {string} anchorTag + * @property {string} [mapName] + * @property {string} [listName] + * @property {string[]} lines + * @property {number} [linesIndent=4] + * @property {string} [updatedLabel] + * @property {(srcInBlock: string, options: { toUpdatedStamp?: (date?: Date) => string }) => { newBlock: string, changed: boolean }} [replacer] + */ +/** + * 批量在同一文件内进行多锚点替换 (map 与 list 都支持, 读一次/写一次). + * + * @param {string} filePath + * @param {AnchoredBlockUpdateOption[]} optionList + * @param {Object} [extraOptions={}] + * @param {(date?: Date) => string} [extraOptions.toUpdatedStamp=toUpdatedStamp] - 自定义时间戳函数 (可选) + * @param {Console} [extraOptions.logger=console] + * @returns {Promise<{ changed: boolean, content: string }>} + */ +export async function batchUpdateAnchoredBlocks(filePath, optionList, { + toUpdatedStamp: toStamp = toUpdatedStamp, + logger = console, +} = {}) { + const filename = path.basename(filePath); + let raw = await fsp.readFile(filePath, 'utf8'); + let changedAny = false; + + for (const op of optionList) { + let res = { src: raw, changed: false }; + + if (op.type === 'map') { + res = replaceAnchoredMapBlock(raw, { + anchorTag: op.anchorTag, + mapName: op.mapName, + lines: op.lines, + linesIndent: op.linesIndent, + toUpdatedStamp: toStamp, + }); + } else if (op.type === 'list') { + res = replaceAnchoredListBlock(raw, { + anchorTag: op.anchorTag, + listName: op.listName, + lines: op.lines, + linesIndent: op.linesIndent, + toUpdatedStamp: toStamp, + }); + } else if (op.type === 'custom' && typeof op.replacer === 'function') { + res = replaceInAnchoredBlock(raw, op.anchorTag, (block) => op.replacer(block, { toUpdatedStamp: toStamp })); + } else { + logger.warn(`[${filename}] 未知操作类型或缺少参数:`, op); + continue; + } + + if (res.changed) { + changedAny = true; + raw = res.src; + logger.log(`[${filename}] 已更新 (${op['updatedLabel'] ?? op.anchorTag})`); + } else { + // logger.log(`[${filename}] 无需更新 (${op['updatedLabel'] ?? op.anchorTag})`); + } + } + + if (changedAny) { + await fsp.writeFile(filePath, raw, 'utf8'); + } + return { changed: changedAny, content: raw }; +} diff --git a/.utils/utils/async.mjs b/.utils/utils/async.mjs new file mode 100644 index 00000000..37f8d8bc --- /dev/null +++ b/.utils/utils/async.mjs @@ -0,0 +1,9 @@ +// utils/async.mjs + +/** + * @param {number} ms + * @returns {Promise} + */ +export async function sleep(ms) { + return new Promise(r => setTimeout(r, ms)); +} diff --git a/.utils/utils/date.mjs b/.utils/utils/date.mjs new file mode 100644 index 00000000..ffd0b192 --- /dev/null +++ b/.utils/utils/date.mjs @@ -0,0 +1,23 @@ +// utils/date.mjs + +/** + * @param {Date} [date=new Date()] + * @returns {string} + */ +export function toUpdatedStamp(date = new Date()) { + /* e.g. "Aug 23, 2025". */ + return date.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }); +} + +/** + * @param {string} [dateText=''] + * @returns {string | null} + */ +export function toYYYYMMDD(dateText = '') { + const d = dateText ? new Date(dateText) : new Date(); + if (Number.isNaN(d.getTime())) return null; + const y = d.getFullYear(); + const m = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + return `${y}/${m}/${day}`; +} \ No newline at end of file diff --git a/.utils/utils/fetch.mjs b/.utils/utils/fetch.mjs new file mode 100644 index 00000000..da2e6850 --- /dev/null +++ b/.utils/utils/fetch.mjs @@ -0,0 +1,100 @@ +// utils/fetch.mjs + +/** @typedef {import('@octokit/types').Endpoints['GET /repos/{owner}/{repo}/commits']['response']['data']} CommitsData */ + +import fetch from 'node-fetch'; +import * as dotenv from 'dotenv'; +import { toYYYYMMDD } from './date.mjs'; + +dotenv.config({ path: '../.env', quiet: true }); + +/** + * 获取远程文件真实大小. + * + * @param {string} url + * @param {{timeout?: number}} [options] + * @returns {Promise} + */ +export async function getRemoteFileSizeBytes(url, { timeout = 30000 } = {}) { + const headers = { + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124 Safari/537.36', + 'accept': '*/*', + }; + + // 1) 尝试 HEAD + + try { + const res = await fetch(url, { + method: 'HEAD', + redirect: 'follow', + headers, + }); + if (res.ok) { + const len = res.headers.get('content-length'); + if (len && /^\d+$/.test(len)) return Number(len); + } + } catch (_) { + /* Ignored. */ + } + + // 2) 尝试 Range GET (bytes=0-0), 从 Content-Range 解析总长度 + + try { + const ac = new AbortController(); + const t = setTimeout(() => ac.abort(), timeout); + const res = await fetch(url, { + method: 'GET', + redirect: 'follow', + headers: { ...headers, range: 'bytes=0-0' }, + signal: ac.signal, + }).finally(() => clearTimeout(t)); + + if (res.ok || res.status === 206) { + // Content-Range: bytes 0-0/123456789 + const cr = res.headers.get('content-range'); + if (cr) { + const m = /bytes\s+\d+-\d+\/(\d+)/i.exec(cr); + if (m) return Number(m[1]); + } + // 退化: 仍然尝试 content-length + const len = res.headers.get('content-length'); + if (len && /^\d+$/.test(len)) return Number(len); + } + } catch (_) { + /* Ignored. */ + } + + return null; +} + +/** + * @param {string} owner + * @param {string} repo + * @return {Promise} + */ +export async function getLatestCommitDate(owner, repo) { + const token = process.env.GITHUB_TOKEN; // 可选:避免频繁请求受限 + const url = `https://api.github.com/repos/${owner}/${repo}/commits?per_page=1`; + + /** @type {import('node-fetch').HeadersInit} */ + const headers = { + accept: 'application/vnd.github+json', + 'user-agent': 'repo-last-commit-script', + ...(token ? { authorization: `Bearer ${token}` } : {}), + }; + const res = await fetch(url, { headers }); + + if (!res.ok) { + throw new Error(`GitHub API 请求失败: ${res.status} ${res.statusText}`); + } + + const data = /** @type {CommitsData} */ await res.json(); + const latest = Array.isArray(data) ? data[0] : null; + if (!latest?.commit) throw new Error('未获取到最新提交'); + + // 优先使用 committer 的提交时间,fallback 到 author + const iso = latest.commit.committer?.date ?? latest.commit.author?.date; + if (!iso) throw new Error('提交对象缺少日期字段'); + + return toYYYYMMDD(iso); +} diff --git a/.utils/utils/format.mjs b/.utils/utils/format.mjs new file mode 100644 index 00000000..99adac25 --- /dev/null +++ b/.utils/utils/format.mjs @@ -0,0 +1,11 @@ +// utils/format.mjs + +/** + * @param {number | null} bytes + * @param {number} [fractionDigits=2] + */ +export function bytes2GiB(bytes, fractionDigits = 2) { + if (bytes == null) return null; + const gib = bytes / 1024 ** 3; + return `${gib.toFixed(fractionDigits)} GiB`; +} \ No newline at end of file diff --git a/.utils/utils/properties.mjs b/.utils/utils/properties.mjs new file mode 100644 index 00000000..92bad626 --- /dev/null +++ b/.utils/utils/properties.mjs @@ -0,0 +1,234 @@ +// utils/properties.mjs + +import * as fs from 'node:fs'; +import * as fsp from 'node:fs/promises'; +import { compareVersionStrings } from './versioning.mjs'; + +/** + * @param {string} str + * @returns {string} + */ +function unescapeProperty(str) { + let i = 0, out = ''; + while (i < str.length) { + const ch = str[i++]; + if (ch !== '\\') { + out += ch; + continue; + } + const next = str[i++]; + switch (next) { + case 't': + out += '\t'; + break; + case 'n': + out += '\n'; + break; + case 'r': + out += '\r'; + break; + case 'f': + out += '\f'; + break; + case 'u': { + const hex = str.slice(i, i + 4); + if (/^[0-9a-fA-F] {4}$/.test(hex)) { + out += String.fromCharCode(parseInt(hex, 16)); + i += 4; + } else { + // 非法 \u 序列, 按字面量保留 + out += '\\u'; + } + break; + } + case ':': + case '=': + case ' ': + case '\\': + out += next; + break; + default: + // 未知转义, 保留第二个字符 + out += next; + } + } + return out; +} + +/** + * @param {string} text + * @returns {Object} + */ +export function parseProperties(text) { + const props = Object.create(null); + if (!text) return props; + + const lines = []; + const rawLines = text.split(/\r?\n/); + + // 合并续行 (以反斜杠结尾且反斜杠未被转义) + for (let i = 0; i < rawLines.length; i++) { + let line = rawLines[i]; + if (line == null) continue; + + // 去除行尾 CR (兼容 \r\n 已 split 的情况, 一般无需此步) + line = line.replace(/\r$/, ''); + + // 合并续行 + while (true) { + // 统计结尾连续反斜杠数量, 奇数表示续行 + let backslashes = 0; + for (let j = line.length - 1; j >= 0 && line[j] === '\\'; j--) backslashes++; + const isContinuation = backslashes % 2 === 1; + + if (!isContinuation) break; + const next = rawLines[++i]; + if (next == null) break; + // 去掉一个续行用的反斜杠, 再拼接后续行, 续行处按规范会吞掉换行 + line = line.slice(0, -1) + next; + } + lines.push(line); + } + + for (const raw of lines) { + const line = raw.trim(); + if (!line || line.startsWith('#') || line.startsWith('!')) continue; + + // 键值分隔: 第一个 =/: 或未转义空白 + let key = ''; + let value = ''; + let sepIdx = -1; + + // 逐字符扫描, 识别未转义的分隔符 + let escaped = false; + for (let i = 0; i < line.length; i++) { + const ch = line[i]; + if (!escaped && (ch === '=' || ch === ':')) { + sepIdx = i; + break; + } + if (!escaped && /\s/.test(ch)) { + sepIdx = i; + break; + } + escaped = ch === '\\' && !escaped; + if (!escaped && ch !== '\\') escaped = false; + } + + if (sepIdx === -1) { + key = line; + value = ''; + } else { + key = line.slice(0, sepIdx); + value = line.slice(sepIdx + 1); + // 如果分隔符是空白, value 应该从第一个非空白处开始 + if (/^\s$/.test(line[sepIdx])) { + value = value.replace(/^\s+/, ''); + } + } + + key = key.replace(/\s+$/, ''); // 规范里 key 前部空白可作为分隔符, 末尾空白需要去掉 + const k = unescapeProperty(key); + const v = unescapeProperty(value.trim()); + + if (k) props[k] = v; + } + return props; +} + +/** + * @param {string} [filePath='../version.properties'] + * @param {Object} options + * @param {BufferEncoding} [options.encoding='utf8'] + * @returns {Promise>} + */ +export async function readProperties(filePath = '../version.properties', { encoding = 'utf8' } = {}) { + const text = await fsp.readFile(filePath, { encoding }); + return parseProperties(text); +} + +/** + * @param {string} [filePath='../version.properties'] + * @param {Object} options + * @param {BufferEncoding} [options.encoding='utf8'] + * @returns {Object} + */ +export function readPropertiesSync(filePath = '../version.properties', { encoding = 'utf8' } = {}) { + const text = fs.readFileSync(filePath, { encoding }); + return parseProperties(text); +} + +/** + * @param {string} [filePath='../version.properties'] + * @param {Object} options + * @param {BufferEncoding} [options.encoding='utf8'] + * @returns {string} + */ +export function getMinSupportedAgpVersion(filePath = '../version.properties', { encoding = 'utf8' } = {}) { + let minSupportedVersion = null; + Object.entries(readPropertiesSync(filePath, { encoding })).forEach(([ key, value ]) => { + if (!/agp.version.*min.supported|min.supported.*agp.version/i.test(key)) return; + if (minSupportedVersion === null || compareVersionStrings(value, minSupportedVersion) < 0) { + minSupportedVersion = value; + } + }); + return minSupportedVersion ?? '8.0'; +} + +/** + * @param {string} [filePath='../version.properties'] + * @param {Object} options + * @param {BufferEncoding} [options.encoding='utf8'] + * @returns {string} + */ +export function getMinSupportedGradleVersion(filePath = '../version.properties', { encoding = 'utf8' } = {}) { + let minSupportedVersion = null; + Object.entries(readPropertiesSync(filePath, { encoding })).forEach(([ key, value ]) => { + if (!/gradle.version.*min.supported|min.supported.*gradle.version/i.test(key)) return; + if (minSupportedVersion === null || compareVersionStrings(value, minSupportedVersion) < 0) { + minSupportedVersion = value; + } + }); + return minSupportedVersion ?? '8.0'; +} + +/** + * @param {string} [filePath='../version.properties'] + * @param {Object} options + * @param {BufferEncoding} [options.encoding='utf8'] + * @returns {number} + */ +export function getMinSupportedJavaVersionInt(filePath = '../version.properties', { encoding = 'utf8' } = {}) { + return getJavaVersionInfo(filePath, { encoding }).minSupportedJavaVersionInt; +} + +/** + * @param {string} [filePath='../version.properties'] + * @param {Object} options + * @param {BufferEncoding} [options.encoding='utf8'] + * @returns {{ currentJavaVersionInt: number, minSupportedJavaVersionInt: number, minSuggestedJavaVersionInt: number, maxSupportedJavaVersionInt: number }} + */ +export function getJavaVersionInfo(filePath = '../version.properties', { encoding = 'utf8' } = {}) { + let currentVersion = 0; + let minSuggestedVersion = 19; + let minSupportedVersion = 17; + let maxSupportedVersion = 0; + Object.entries(readPropertiesSync(filePath, { encoding })).forEach(([ key, value ]) => { + const versionNumber = parseInt(value, 10); + if (/^java.version$/i.test(key)) { + currentVersion = Math.max(currentVersion, versionNumber); + } else if (/java.version.*min.suggested|min.suggested.*java.version/i.test(key)) { + minSuggestedVersion = Math.min(minSuggestedVersion, versionNumber); + } else if (/java.version.*min.supported|min.supported.*java.version/i.test(key)) { + minSupportedVersion = Math.min(minSupportedVersion, versionNumber); + } else if (/java.version.*max.supported|max.supported.*java.version/i.test(key)) { + maxSupportedVersion = Math.max(maxSupportedVersion, versionNumber); + } + }); + return { + currentJavaVersionInt: currentVersion, + minSuggestedJavaVersionInt: minSuggestedVersion, + minSupportedJavaVersionInt: minSupportedVersion, + maxSupportedJavaVersionInt: maxSupportedVersion, + }; +} \ No newline at end of file diff --git a/.utils/utils/puppeteer-helpers.mjs b/.utils/utils/puppeteer-helpers.mjs new file mode 100644 index 00000000..b1213368 --- /dev/null +++ b/.utils/utils/puppeteer-helpers.mjs @@ -0,0 +1,160 @@ +// utils/puppeteer-helpers.mjs + +/** @typedef {import('puppeteer').Page} Page */ + +import puppeteer from 'puppeteer'; +import { sleep } from './async.mjs'; + +/** + * @param {Page} page + * @returns {Promise} + */ +export async function autoScroll(page) { + await page.evaluate(async () => { + await new Promise(resolve => { + let total = 0; + const step = 400; + const timer = setInterval(() => { + window.scrollBy(0, step); + total += step; + if (total >= document.body.scrollHeight) { + clearInterval(timer); + resolve(); + } + }, 100); + }); + }); +} + +/** + * @typedef {object} FindTargetRowsOptions + * @property {string} [tableSelector='table'] + * @property {{ [selector: string]: string | string[] }}[tableFilter={}] + * @property {string} [tableRowSelector='tbody tr'] + * @property {string} [tableDataSelector='td'] + * @property {Array<{ [dataItemName: string]: string } | string>} [tableDataStructure=[]] + */ +/** + * @param {Page} page + * @param {FindTargetRowsOptions} [options={}] + * @returns {Promise>} + */ +async function findTargetRowsWithPage(page, options = {}) { + return await page.evaluate((options) => { + const targets = Array.from(document.querySelectorAll(options.tableSelector ?? 'table')); + const target = targets.find(t => { + for (const [ selector, filter ] of Object.entries(options.tableFilter ?? {})) { + const elements = Array.from(t.querySelectorAll(selector)); + if (Array.isArray(filter)) { + if (!filter.some(f => elements.some(e => { + if (typeof f === 'string') { + if (!f.startsWith(':RegExp:')) { + return e.textContent.trim() === f; + } + const [ _, flags, pattern ] = f.match(/:RegExp:(?:(\w+):)?(.+)/); + const re = new RegExp(pattern, flags); + return re.test(e.textContent.trim()); + } + throw TypeError(`Unknown type of filter (${f})`); + }))) { + return false; + } + } else { + if (!elements.some(e => { + if (typeof filter === 'string') { + if (!filter.startsWith(':RegExp:')) { + return e.textContent.trim() === filter; + } + const [ _, flags, pattern ] = filter.match(/:RegExp:(?:(\w+):)?(.+)/); + const re = new RegExp(pattern, flags); + return re.test(e.textContent.trim()); + } + throw TypeError(`Unknown type of filter (${filter})`); + })) { + return false; + } + } + } + return true; + }); + if (!target) { + throw Error('No target table found'); + } + + const tableRows = Array.from(target.querySelectorAll(options.tableRowSelector ?? 'tbody tr')); + const tableDataList = []; + tableRows.forEach((tr) => { + const tableData = {}; + const tds = Array.from(tr.querySelectorAll(options.tableDataSelector ?? 'td')); + const tableDataStructure = options.tableDataStructure ?? []; + if (tds.length === 0 || tableDataStructure.length === 0) return null; + if (options.tableDataStructure.length > tds.length) { + throw Error(`Table data size (${tds.length}) is less than table data structure (${options.tableDataStructure.length})`); + } + for (let i = 0; i < options.tableDataStructure.length; i++) { + const o = options.tableDataStructure[i]; + let dataItemName = null; + let dataItemFilter = null; + if (typeof o === 'string') { + dataItemName = o; + } else if (typeof o === 'object' && o !== null) { + if (Object.keys(o).length !== 1) { + throw Error(`Table data structure (${options.tableDataStructure}) must be a string or an object with only one key`); + } + dataItemName = Object.keys(o)[0]; + dataItemFilter = o[dataItemName]; + } else { + throw Error(`Unknown type of table data structure (${options.tableDataStructure})`); + } + const dataItemValueRaw = tds[i].textContent.trim(); + if (dataItemFilter == null) { + tableData[dataItemName] = dataItemValueRaw; + } else if (typeof dataItemFilter === 'string') { + if (!dataItemFilter.startsWith(':RegExp:')) { + tableData[dataItemName] = dataItemValueRaw === dataItemFilter ? dataItemValueRaw : null; + } else { + const [ _, flags, pattern ] = dataItemFilter.match(/:RegExp:(?:(\w+):)?(.+)/); + const re = new RegExp(pattern, flags); + tableData[dataItemName] = dataItemValueRaw.match(re)?.[0] ?? null; + } + } + } + tableDataList.push(tableData); + }); + return tableDataList; + }, options); +} + +/** + * @typedef {object} PuppeteerOptions + * @property {string} url + * @property {number} [pageGoToTimeout=120000] + * @property {number} [findTargetRowsTimeout=30000] + */ +/** + * @param {FindTargetRowsOptions & PuppeteerOptions} options + * @returns {Promise>} + */ +export async function findTargetRows(options) { + const browser = await puppeteer.launch({ headless: true }); + const page = await browser.newPage(); + try { + await page.goto(options.url, { waitUntil: 'networkidle0', timeout: options.pageGoToTimeout ?? 120000 }); + + // 页面为懒加载: 滚动并多次尝试, 直到目标表格出现或超时 + let rows = null; + const deadline = Date.now() + (options.findTargetRowsTimeout ?? 30000); + while (Date.now() < deadline) { + rows = await findTargetRowsWithPage(page, options); + if (rows && rows.length) break; + await autoScroll(page); + await sleep(300); + } + if (rows && rows.length > 0) { + return rows; + } + throw new Error('Unable to locate target table rows (lazy-loaded content not found in time)'); + } finally { + await browser.close(); + } +} \ No newline at end of file diff --git a/.utils/utils/versioning.mjs b/.utils/utils/versioning.mjs new file mode 100644 index 00000000..5c0d896c --- /dev/null +++ b/.utils/utils/versioning.mjs @@ -0,0 +1,97 @@ +// utils/versioning.mjs + +const SUFFIX_PRIORITY = { '': 10, 'alpha': 1, 'beta': 2, 'canary': 3, 'rc': 5 }; + +/** + * @param {string} version + * @return { [number[], [string, number]]} + */ +export function toVersionParts(version) { + const parts = version.split(/[\s+-]/); + const numberParts = parts[0].split('.').map(part => { + const num = parseInt(String(part), 10); + if (Number.isNaN(num)) { + throw new Error(`Invalid version part: '${part}' in version: '${version}'`); + } + return num; + }); + + // 解析后缀, 如 Alpha2 / Beta / RC1 等; 默认数字为 1 + const suffixPattern = /([A-Za-z]+)\s*(\d*)|([A-Za-z]*)\s*(\d+)/; + const suffixStr = parts[1] || ''; + const m = suffixStr.match(suffixPattern); + if (!m) return [ numberParts, [ '', 0 ] ]; + + const suffixName = m[1] || ''; + const suffixNumber = parseInt(m[2] || '1', 10); + return [ numberParts, [ suffixName, Number.isNaN(suffixNumber) ? 1 : suffixNumber ] ]; +} + +/** + * @param {number[]} a + * @param {number[]} b + * @return {number} + */ +export function compareVersionParts(a, b) { + const max = Math.max(a.length, b.length); + for (let i = 0; i < max; i++) { + const x = a[i] ?? 0; + const y = b[i] ?? 0; + if (x !== y) return x > y ? 1 : -1; + } + return 0; +} + +/** + * @param {[string, number]} s1 + * @param {[string, number]} s2 + * @return {number} + */ +export function compareVersionSuffix(s1, s2) { + const [ name1Raw, num1 ] = s1; + const [ name2Raw, num2 ] = s2; + const name1 = name1Raw.toLowerCase(); + const name2 = name2Raw.toLowerCase(); + const p1 = SUFFIX_PRIORITY[name1] ?? Number.MAX_SAFE_INTEGER; + const p2 = SUFFIX_PRIORITY[name2] ?? Number.MAX_SAFE_INTEGER; + if (p1 !== p2) return p1 > p2 ? 1 : -1; + if (num1 !== num2) return num1 > num2 ? 1 : -1; + return 0; +} + +/** + * @param {string} v1 + * @param {string} v2 + * @return {number} + */ +export function compareVersionStrings(v1, v2) { + const [ n1, s1 ] = toVersionParts(v1); + const [ n2, s2 ] = toVersionParts(v2); + const cmp = compareVersionParts(n1, n2); + return cmp !== 0 ? cmp : compareVersionSuffix(s1, s2); +} + +/** + * @param {string} v1 + * @param {string} v2 + * @return {number} + */ +export function compareVersionStringsDescending(v1, v2) { + const [ n1, s1 ] = toVersionParts(v1); + const [ n2, s2 ] = toVersionParts(v2); + const cmp = compareVersionParts(n2, n1); + return cmp !== 0 ? cmp : compareVersionSuffix(s2, s1); +} + +/** + * @param {string} v + * @param {Object} options + * @param {string} [options.min] + * @param {string} [options.max] + * @return {boolean} + */ +export function isVersionInRange(v, { min, max } = {}) { + return (min !== null && compareVersionStrings(v, min) >= 0) + && (max !== null && compareVersionStrings(v, max) <= 0); + +} \ No newline at end of file diff --git a/README.md b/README.md index 6219233b..2c979743 100644 --- a/README.md +++ b/README.md @@ -8,16 +8,16 @@

Android 平台支持无障碍服务的 JavaScript 自动化工具

- GitHub release (latest by date) - GitHub closed issues - Created + GitHub release (latest by date) + GitHub closed issues + Created
- Rhino - Android Studio + Android Studio + IntelliJ IDEA
- CodeFactor Grade - JetBrains supporter - GitHub License + Rhino + JetBrains supporter + GitHub License

@@ -59,16 +59,16 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 | [Auto.js](https://github.com/hyb1996/Auto.js) | [Auto.js](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [hyb1996](https://github.com/hyb1996) | `2017/01/27` | `2020/03/13` | 3.13 | | Auto.js Pro 7 | Auto.js | [hyb1996](https://github.com/hyb1996) | `2019/03/13` | `2019/07/08` | 0.32 | | Auto.js Pro 8 | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2019/10/13` | `2021/07/24` | 1.78 | -| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.74 > | +| [Auto.js](https://github.com/TonyJiangWJ/Auto.js) | [Auto.js M](https://github.com/TonyJiangWJ/Auto.js/commit/268ec8895bbfa28fc7715154eb15b1c1eaaefd14#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [TonyJiangWJ](https://github.com/TonyJiangWJ) | `2019/11/21` | - | < 5.81 > | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js](https://github.com/kkevsekk1/AutoX/commit/8143e4ed893d4af05d22aa791b83a962f9959873#diff-5e01f7d37a66e4ca03deefc205d8e7008661cdd0284a05aaba1858e6b7bf9103R2) | [kkevsekk1](https://github.com/kkevsekk1) | `2020/07/24` | [ `2025/01/07` ] | 4.46 | | [Auto.js Pro 9](https://pro.autojs.org/) | AutoJsPro | [hyb1996](https://github.com/hyb1996) | `2021/03/28` | `2023/02/09` | 1.87 | -| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.71 > | +| [AutoJs6](https://github.com/SuperMonster003/AutoJs6) | [AutoJs6](https://github.com/SuperMonster003/AutoJs6/commit/a8ce1b9acb541e9736c33134be3194c3148a15a3#diff-833a46a97033e77558372a2dce103fd6fee29aaaa899f610022a7aece592ee7bR27) | [SuperMonster003](https://github.com/SuperMonster003) | `2021/12/01` | - | < 3.78 > | | [autojs4](https://github.com/blackcd318/autojs4) | Auto.js | [blackcd318](https://github.com/blackcd318) | `2021/12/15` | `2023/07/31` | 1.62 | | [AutoX](https://github.com/kkevsekk1/AutoX) | [Autox.js v6](https://github.com/kkevsekk1/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [wilinz](https://github.com/wilinz) / [aiselp](https://github.com/aiselp) | `2022/05/26` | [ `2025/01/07` ] | 2.62 | | [openautojs](https://github.com/openautojs/openautojs) | [OpenAuto.js](https://github.com/openautojs/openautojs/commit/a11feaad025154de9b453ba70b49e94a6ca8b48a#diff-7d757295fcec3b37c258337e048644c258233d79259152e77baa6d36bb0ec418R2) | [openautojs](https://github.com/openautojs) | `2023/02/17` | `2023/04/16` | 0.16 | -| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.32 > | -| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.88 > | -| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.38 > | +| [AutoX](https://github.com/aiselp/AutoX) | [Autox.js v7](https://github.com/aiselp/AutoX/commit/484491fd5fe12b8203d0b09c181eb0f471c0ea9f#diff-8cff73265af19c059547b76aca8882cbaa3209291406f52df1dafbbc78e80c46R120) | [aiselp](https://github.com/aiselp) | `2024/04/21` | - | < 1.39 > | +| [Autoxjs_v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi) | [Autox.js v6_ozobi](https://github.com/ozobiozobi/Autoxjs_v6_ozobi/blob/a651d02246e09cfbbfa87e6eaccf900fab/app/build.gradle.kts#L143) | [ozobiozobi](https://github.com/ozobiozobi) | `2024/10/01` | - | < 0.94 > | +| [AutoX](https://github.com/autox-community/AutoX) | [Autox.js v6](https://github.com/autox-community/AutoX/commit/8b6776cff8b0fca4be4a52719b7d7d07c0a058f3#diff-51a0b488f963eb0be6c6599bf5df497313877cf5bdff3950807373912ac1cdc9R130) | [autox-community](https://github.com/autox-community) | `2025/03/30` | - | < 0.45 > | 表格中的日期为预估值, 实际可能存在出入. @@ -76,7 +76,7 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 表格中 `终止开发日期` 列包含方括号 (`[]`) 的数据, 表示开源项目暂时无法访问. -表格中 `活跃维护期` 列包含尖括号 (`<>`) 的数据, 其统计截止日期为 2025 年 8 月 17 日. +表格中 `活跃维护期` 列包含尖括号 (`<>`) 的数据, 其统计截止日期为 2025 年 9 月 9 日. ****** @@ -133,7 +133,7 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 * 主题色适配 [ 分组 / 定位 / 搜索 / 历史记录 / 亮度及对比度自动适配 / ... ] * 夜间模式适配 [ 设置页面 / 文档页面 / 布局分析页面 / 浮动窗口 / ... ] * [VSCode 插件](http://vscext-project.autojs6.com) 支持客户端 (LAN) 及服务端 (LAN/ADB) 连接方式 -* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升级至 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) +* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升级至 [v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3) (更新于 2025 年 4 月 11 日) * Unicode [码位](https://developer.mozilla.org/zh-CN/docs/Glossary/Code_point) 转义支持 [辅助平面](https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#%E7%AC%AC%E4%B8%80%E8%BC%94%E5%8A%A9%E5%B9%B3%E9%9D%A2) 字符 ```javascript '\u{1D160}'; /* 表示 "𝅘𝅥𝅮", 传统方式: '\uD834\uDD60'. */ @@ -280,12 +280,12 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 #### Android Studio 准备 -下载 `Android Studio Narwhal Feature Drop | 2025.1.2` 版本 (按需选择其一): +下载 `Android Studio Narwhal 3 Feature Drop | 2025.1.3` 版本 (按需选择其一): -- [android-studio-2025.1.2.11-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.2.11/android-studio-2025.1.2.11-windows.exe) (1.39 GB) -- [android-studio-2025.1.2.11-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.2.11/android-studio-2025.1.2.11-windows.zip) (1.40 GB) +- [android-studio-2025.1.3.7-windows.exe](https://redirector.gvt1.com/edgedl/android/studio/install/2025.1.3.7/android-studio-2025.1.3.7-windows.exe) (1.33 GiB) +- [android-studio-2025.1.3.7-windows.zip](https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2025.1.3.7/android-studio-2025.1.3.7-windows.zip) (1.34 GiB) -> 注: 上述版本发布时间为 2025 年 7 月 31 日. 如需下载其他版本, 或上述链接已失效, 可访问 [Android Studio 发行版本归档](https://developer.android.com/studio/archive?hl=en) 页面. +> 注: 上述版本发布时间为 2025 年 9 月 2 日. 如需下载其他版本, 或上述链接已失效, 可访问 [Android Studio 发行版本归档](https://developer.android.com/studio/archive?hl=en) 页面. 安装或解压上述文件, 运行 Android Studio 软件 (如 `"D:\android-studio\bin\studio64.exe"`). @@ -334,9 +334,9 @@ File (文件) | Settings (设置) | Appearance & Behavior (外观与行为) | Sy #### JDK 准备 -AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `19`. +AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `21`. -截至 2025 年 8 月 17 日, AutoJs6 可支持 JDK 最高版本为 `24`. +截至 2025 年 9 月 9 日, AutoJs6 可支持 JDK 最高版本为 `24`. > 注: 如果计算机系统已安装 JDK 且版本满足上述要求, 则可跳过此小节内容. @@ -487,19 +487,19 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk 感谢每一位参与 AutoJs6 项目开发的贡献人员. -| 贡献人员 | 提交数 | 最近提交 | -|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| -| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=wirsnow) | `2025/05/19` | -| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [5](https://github.com/SuperMonster003/AutoJs6/commits?author=TonyJiangWJ) | `2025/04/24` | -| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/commits?author=luckyloogn) | `2025/01/01` | -| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/commits?author=kvii) | `2024/10/16` | -| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Achenguangming) | `2024/05/14` | -| [LZX284](https://github.com/LZX284) `(AI)` | [17](https://github.com/SuperMonster003/AutoJs6/commits?author=LZX284) | `2023/11/19` | -| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/commits?author=little-alei) | `2023/07/12` | -| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+author%3Aaiselp) | `2023/06/14` | -| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/commits?author=LYS86) | `2023/06/03` | +| 贡献人员 | 提交数 | 最近提交 | +|:-------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------:| +| [wirsnow](https://github.com/wirsnow) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Awirsnow) | `2025/05/19` | +| [TonyJiangWJ](https://github.com/TonyJiangWJ) | [4](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ATonyJiangWJ) | `2025/04/24` | +| [luckyloogn](https://github.com/luckyloogn) | [3](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aluckyloogn) | `2024/12/31` | +| [kvii](https://github.com/kvii) | [1](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Akvii) | `2024/10/16` | +| [chenguangming](https://github.com/chenguangming) `(Tom)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Achenguangming) | `2024/05/14` | +| [LZX284](https://github.com/LZX284) `(AI)` | [7](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALZX284) | `2023/11/15` | +| [little‑alei](https://github.com/little-alei) `(抠脚本人)` | [12](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Alittle-alei) | `2023/07/12` | +| [aiselp](https://github.com/aiselp) | [6](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3Aaiselp) | `2023/06/14` | +| [LYS86](https://github.com/LYS86) `(Lin)` | [2](https://github.com/SuperMonster003/AutoJs6/pulls?q=is%3Apr+is%3Amerged+author%3ALYS86) | `2023/06/03` | -数据更新于 2025 年 5 月 27 日. +数据更新于 2025 年 9 月 6 日. 数据条目按 `最近提交` 降序排序. @@ -520,11 +520,12 @@ autojs6-v6.6.2-arm64-v8a-0f2a9d74.apk - Translate into other languages - Update TypeScript declarations according to section `dependency` if needed - $projectDir/.readme/template_readme.md - - Update badges like [ android studio / rhino / ... ] - - Update contribution section: [ h3_contribution ] + - Update Rhino badge + - Update Android Studio and IntelliJ IDEA badges [ link: aj6mdgen ] + - Update contribution section: [ h3_contribution ] [ link: aj6scrapers ] - $projectDir/.readme/common.json - - Update android studio download links and version names - - Update contribution section: var_date_contribution_table_data_updated + - Update android studio download links and version names [ link: aj6scrapers ] + - Update contribution section: var_date_contribution_table_data_updated [ link: aj6scrapers ] - $projectDir/.python/generate_markdown.py - Re-generate markdown by running the python script [ link: aj6mdgen ] - Others diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a1a66ae5..62c78738 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -43,7 +43,13 @@ dependencies /* Unclassified */ { implementation(kotlin("reflect")) // Androidx Core - implementation("androidx.core:core-ktx:1.16.0") + implementation("androidx.core:core-ktx") { + because("Compatibility for Android Gradle plugin 8.2.2") + version { + strictly("1.15.0") + because("Exception on newer versions: Dependency 'androidx.core:core:1.16.0' requires Android Gradle plugin 8.6.0 or higher") + } + } // LeakCanary debugImplementation("com.squareup.leakcanary:leakcanary-android:2.14") @@ -74,7 +80,7 @@ dependencies /* Unclassified */ { implementation("de.psdev.licensesdialog:licensesdialog:2.2.0") // Apache Commons - implementation("org.apache.commons:commons-lang3:3.17.0") + implementation("org.apache.commons:commons-lang3:3.18.0") // Retrofit implementation("com.squareup.retrofit2:retrofit:2.12.0") @@ -657,6 +663,7 @@ android { } } + @Suppress("DEPRECATION") kotlinOptions { jvmTarget = versions.javaVersion.toString() // freeCompilerArgs = listOf("-Xjvm-default=all-compatibility") @@ -857,7 +864,7 @@ class Versions(filePath: String) { } } private val javaVersionMinSuggested: Int = properties["JAVA_VERSION_MIN_SUGGESTED"].let { it as String }.toInt() - private val javaVersionMinRadical: Int = properties["JAVA_VERSION_MIN_RADICAL"].let { it as String }.toInt() + private val javaVersionMaxSupported: Int = properties["JAVA_VERSION_MAX_SUPPORTED"].let { it as String }.toInt() private val javaVersionRaw = properties["JAVA_VERSION"] as String private var javaVersionInfoSuffix = "" @@ -920,15 +927,15 @@ class Versions(filePath: String) { if (currentVersionInt < javaVersionMinSuggested) { logger.error( "It is recommended to upgrade current Gradle JDK version ${JavaVersion.current()} to $javaVersionMinSuggested or higher${ - if (javaVersionMinRadical > 0) " (but lower than $javaVersionMinRadical)" else "" + if (javaVersionMaxSupported > 0) " (but not higher than $javaVersionMaxSupported)" else "" }." ) } - if (javaVersionMinRadical in 1..currentVersionInt) { + if (currentVersionInt > javaVersionMaxSupported) { logger.error( "It is recommended to downgrade current Gradle JDK version $currentVersionInt " + - "to ${javaVersionMinRadical - 1}${if (javaVersionMinRadical - 1 > javaVersionMinSuggested) " or lower (but not lower than $javaVersionMinSuggested)" else ""}, " + - "as Gradle may be not compatible with JDK $javaVersionMinRadical${if (currentVersionInt > javaVersionMinRadical) " (and above)" else ""} for now." + "to $javaVersionMaxSupported${if (javaVersionMaxSupported > javaVersionMinSuggested) " or lower (but not lower than $javaVersionMinSuggested)" else ""}, " + + "as Gradle may be not compatible with JDK $currentVersionInt for now." ) } } @@ -939,7 +946,7 @@ class Versions(filePath: String) { val infoVerName = "Version name: $appVersionName" val infoVerCode = "Version code: ${if (isBuildNumberAutoIncremented) "${appVersionCode + 1} [auto-incremented]" else appVersionCode}" val infoVerSdk = "SDK versions: min [$sdkVersionMin] / target [$sdkVersionTarget] / compile [$sdkVersionCompile]" - val infoVerJava = "Java version: $javaVersion$javaVersionInfoSuffix" + val infoVerJava = "Java version: $javaVersion${if (gradle.extra.has("isHideConsoleInfoHintSuffix") && gradle.extra.get("isHideConsoleInfoHintSuffix") == true) "" else javaVersionInfoSuffix}" val maxLength = arrayOf(title, infoVerName, infoVerCode, infoVerSdk, infoVerJava).maxOf { it.length } diff --git a/app/src/main/assets/modules/dayjs/package.json b/app/src/main/assets/modules/dayjs/package.json deleted file mode 100644 index 417c30b9..00000000 --- a/app/src/main/assets/modules/dayjs/package.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "dayjs", - "version": "1.11.10", - "description": "2KB immutable date time library alternative to Moment.js with the same modern API ", - "main": "dayjs.min.js", - "types": "index.d.ts", - "scripts": { - "test": "TZ=Pacific/Auckland npm run test-tz && TZ=Europe/London npm run test-tz && TZ=America/Whitehorse npm run test-tz && npm run test-tz && jest", - "test-tz": "date && jest test/timezone.test --coverage=false", - "lint": "./node_modules/.bin/eslint src/* test/* build/*", - "prettier": "prettier --write \"docs/**/*.md\"", - "babel": "cross-env BABEL_ENV=build babel src --out-dir esm --copy-files && node build/esm", - "build": "cross-env BABEL_ENV=build node build && npm run size", - "sauce": "npx karma start karma.sauce.conf.js", - "test:sauce": "npm run sauce -- 0 && npm run sauce -- 1 && npm run sauce -- 2 && npm run sauce -- 3", - "size": "size-limit && gzip-size dayjs.min.js" - }, - "pre-commit": [ - "lint" - ], - "size-limit": [ - { - "limit": "2.99 KB", - "path": "dayjs.min.js" - } - ], - "jest": { - "roots": [ - "test" - ], - "testRegex": "test/(.*?/)?.*test.js$", - "testURL": "http://localhost", - "coverageDirectory": "./coverage/", - "collectCoverage": true, - "collectCoverageFrom": [ - "src/**/*" - ] - }, - "keywords": [ - "dayjs", - "date", - "time", - "immutable", - "moment" - ], - "author": "iamkun", - "license": "MIT", - "homepage": "https://day.js.org", - "repository": { - "type": "git", - "url": "https://github.com/iamkun/dayjs.git" - }, - "devDependencies": { - "@babel/cli": "^7.0.0-beta.44", - "@babel/core": "^7.0.0-beta.44", - "@babel/node": "^7.0.0-beta.44", - "@babel/preset-env": "^7.0.0-beta.44", - "babel-core": "^7.0.0-bridge.0", - "babel-jest": "^22.4.3", - "babel-plugin-external-helpers": "^6.22.0", - "cross-env": "^5.1.6", - "eslint": "^4.19.1", - "eslint-config-airbnb-base": "^12.1.0", - "eslint-plugin-import": "^2.10.0", - "eslint-plugin-jest": "^21.15.0", - "gzip-size-cli": "^2.1.0", - "jasmine-core": "^2.99.1", - "jest": "^22.4.3", - "karma": "^2.0.2", - "karma-jasmine": "^1.1.2", - "karma-sauce-launcher": "^1.1.0", - "mockdate": "^2.0.2", - "moment": "2.29.2", - "moment-timezone": "0.5.31", - "ncp": "^2.0.0", - "pre-commit": "^1.2.2", - "prettier": "^1.16.1", - "rollup": "^2.45.1", - "rollup-plugin-babel": "^4.4.0", - "rollup-plugin-terser": "^7.0.2", - "size-limit": "^0.18.0", - "typescript": "^2.8.3" - } -} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b7204511..5bdde407 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 06 00:45:56 CST 2025 +#Thu Aug 28 12:05:55 CST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index 8828a14a..1bda8c47 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -58,11 +58,17 @@ pluginManagement { // ! plugin("com.google.devtools.ksp") val overriddenKspVersion: String? = null + val versionProperties = java.util.Properties().apply { + load(java.io.FileInputStream("$rootDir/version.properties")) + } + + // @AnchorBegin EMBEDDED_KOTLIN_LIST + // @Script /.utils/scrape-and-inject-embedded-kotlin-list.mjs // @Signature Pair // @Reference gradle--src.zip\gradle\dependency-management\kotlin-version.properties // @Reference https://docs.gradle.org/current/userguide/compatibility.html#kotlin // @Updated by SuperMonster003 on Aug 9, 2025. - val embeddedKotlin: List> = listOf( + val embeddedKotlin = listOf( "9.0" to "2.2.0", "8.14" to "2.1.10", /* Unofficial. */ "8.13" to "2.1.10", /* Unofficial. */ @@ -75,9 +81,11 @@ pluginManagement { "8.4" to "1.9.10", "8.3" to "1.9.0", "8.2" to "1.8.20", - "8.0" to "1.8.10", ) + // @AnchorEnd EMBEDDED_KOTLIN_LIST + // @AnchorBegin JAVA_GRADLE_COMPATIBILITY_LIST + // @Script /.utils/scrape-java-gradle-compatibility-map.mjs // @Signature Pair // @Reference https://docs.gradle.org/current/userguide/compatibility.html#java_runtime // @Updated by SuperMonster003 on May 12, 2025. @@ -92,11 +100,15 @@ pluginManagement { 18 to "7.5", 17 to "7.3", ) + // @AnchorEnd JAVA_GRADLE_COMPATIBILITY_LIST + // @AnchorBegin AGP_GRADLE_COMPATIBILITY_LIST + // @Script /.utils/scrape-and-inject-agp-gradle-compatibility-list.mjs // @Signature Pair // @Reference https://developer.android.com/build/releases/gradle-plugin#updating-gradle - // @Updated by SuperMonster003 on Aug 9, 2025. - val agpGradleCompatibility: List> = listOf( + // @Updated by SuperMonster003 on Sep 3, 2025. + val agpGradleCompatibility = listOf( + "8.13" to "8.13", "8.12" to "8.13", "8.11" to "8.13", "8.10" to "8.11.1", @@ -108,20 +120,20 @@ pluginManagement { "8.4" to "8.6", "8.3" to "8.4", "8.2" to "8.2", - "8.1" to "8.0", - "8.0" to "8.0", - "7.4" to "7.5", - "7.3" to "7.4", ) + // @AnchorEnd AGP_GRADLE_COMPATIBILITY_LIST + // @AnchorBegin ANDROID_GRADLE_PLUGIN_RELEASES_LIST + // @Script /.utils/scrape-and-inject-agp-releases.mjs // @Reference https://developer.android.com/reference/tools/gradle-api - // @Updated by SuperMonster003 on Aug 9, 2025. - val agpReleases: List = listOf( - "8.13.0-alpha04", /* Aug 9, 2025. */ - "8.12.0", /* Aug 9, 2025. */ - "8.11.1", /* Aug 9, 2025. */ - "8.10.1", /* Jun 7, 2025. */ - "8.9.3", /* May 17, 2025. */ + // @Updated by SuperMonster003 on Sep 5, 2025. + val agpReleases = listOf( + "9.0.0-alpha04", + "8.13.0", + "8.12.2", + "8.11.1", + "8.10.1", + "8.9.3", "8.8.2", "8.7.3", "8.6.1", @@ -129,10 +141,8 @@ pluginManagement { "8.4.2", "8.3.2", "8.2.2", - "8.1.4", - "8.0.2", - "7.4.2", ) + // @AnchorEnd ANDROID_GRADLE_PLUGIN_RELEASES_LIST val consts = object { val DEFAULT_VERSION = "0" @@ -146,37 +156,41 @@ pluginManagement { val vendorName: String? = System.getProperty("idea.vendor.name") ?: System.getProperty("java.vendor") ?: System.getProperty("java.vm.vendor") - val concerns: List by lazy { - val concernedKeyWords = setOf("name", "vendor", "version", "platform", "paths", "os") - val unconcernedKeyWords = setOf("url", "user", "runtime", "specification", "date") - val unconcernedKeys = setOf( - "java.class.version", - "java.vm.name", - "java.vm.version", - "java.version", - "platform.random.idempotence.check.rate", - "sun.os.patch.level", - ) - System.getProperties().filterKeys { key -> - return@filterKeys key is String - && key !in unconcernedKeys - && key.split(Regex("\\W")).any { it in concernedKeyWords } - && key.split(Regex("\\W")).none { it in unconcernedKeyWords } - }.map { (key, value) -> "[ $key: $value ]" } - } - var isConcernsAlreadyPrinted = false + } + + var isConcernedPropertiesAlreadyPrinted = false + + val concernedProperties: List by lazy { + val concernedKeyWords = setOf("name", "vendor", "version", "platform", "paths", "os") + val unconcernedKeyWords = setOf("url", "user", "runtime", "specification", "date") + val unconcernedKeys = setOf( + "java.class.version", + "java.vm.name", + "java.vm.version", + "java.version", + "platform.random.idempotence.check.rate", + "sun.os.patch.level", + ) + System.getProperties().apply { + putAll(gradle.startParameter.projectProperties) + }.filterKeys { key -> + return@filterKeys key is String + && key !in unconcernedKeys + && key.split(Regex("\\W")).any { it in concernedKeyWords } + && key.split(Regex("\\W")).none { it in unconcernedKeyWords } + }.map { (key, value) -> "[ $key: $value ]" } } data class Classpath(val id: String, val version: String) data class Plugin(val id: String, val version: String, val isApply: Boolean = false) - class Formatted(title: String, private val contents: Collection = emptyList(), subtitle: String? = null) { + class Formatted(title: String, private val contents: Collection = emptyList(), subtitle: String? = null, footers: Collection = emptyList()) { private val formattedOutput = run { val elements = mutableListOf() subtitle?.let { elements.add(it) } elements.addAll(contents) - val maxLength = elements.plus(title).maxOf { it.length } + val maxLength = elements.plus(title).plus(footers).maxOf { it.length } listOfNotNull( "=".repeat(maxLength), @@ -184,6 +198,8 @@ pluginManagement { subtitle, "-".repeat(maxLength).takeUnless { contents.isEmpty() }, *contents.toTypedArray(), + "-".repeat(maxLength).takeUnless { footers.isEmpty() }, + *footers.toTypedArray(), "=".repeat(maxLength), "", ) @@ -194,59 +210,145 @@ pluginManagement { fun throwException(): Unit = throw Exception(formattedOutput.joinToString("\n")) } + val utils = object { + fun compareVersionStrings(v1: String, v2: String): Int { + val (ver1Numbers, ver1Suffix) = toVersionParts(v1) + val (ver2Numbers, ver2Suffix) = toVersionParts(v2) + return compareVersionParts(ver1Numbers, ver2Numbers) + .takeIf { it != 0 } + ?: compareVersionSuffix(ver1Suffix, ver2Suffix) + } + + fun compareVersionParts(parts1: List, parts2: List): Int { + for (i in 0 until maxOf(parts1.size, parts2.size)) { + val part1 = parts1.getOrElse(i) { 0 } + val part2 = parts2.getOrElse(i) { 0 } + if (part1 != part2) return part1.compareTo(part2) + } + return 0 + } + + fun compareVersionSuffix(suffix1: Pair, suffix2: Pair): Int { + val suffixPriority = mapOf("" to 10, "Alpha" to 1, "Beta" to 2, "RC" to 5) + val (suffixName1, suffixNumber1) = suffix1 + val (suffixName2, suffixNumber2) = suffix2 + val priority1 = suffixPriority[suffixName1] ?: Int.MAX_VALUE + val priority2 = suffixPriority[suffixName2] ?: Int.MAX_VALUE + return priority1.compareTo(priority2).takeIf { it != 0 } ?: suffixNumber1.compareTo(suffixNumber2) + } + + fun toVersionParts(version: String): Pair, Pair> { + val parts = version.split(Regex("[+-]")) + val numberParts = parts[0].split('.').map { + it.toIntOrNull() ?: throw IllegalArgumentException("Invalid version part: '$it' in version: '$version'") + } + + val suffixPattern = Regex("([A-Za-z]+)(\\d*)|([A-Za-z]*)(\\d+)") + val suffixMatch = suffixPattern.matchEntire(parts.getOrElse(1) { "" }) ?: return numberParts to ("" to 0) + + val suffixName = suffixMatch.groupValues[1] // "Alpha", "Beta", "RC" or empty string + val suffixNumber = suffixMatch.groupValues[2].toIntOrNull() ?: 1 // Default to 1 for suffixes like "Alpha", "Beta", "RC" + + return numberParts to (suffixName to suffixNumber) + } + + fun parseAndroidStudioBuildToVersion(): String? { + // e.g. "251.26094.121.2513.13991806". + val build = providers.gradleProperty("android.studio.version") + .orElse(providers.systemProperty("android.studio.version")) + .orNull ?: return null + val parts = build.split('.') + val baseStr = parts.getOrNull(0) ?: return null + val base = baseStr.toIntOrNull() ?: return null + val year = 2000 + base / 10 + val minor = base % 10 + + // Look for strings starting with base and having longer length in the remaining fragments. + // e.g. "2513" means patch version is "3". + // zh-CN: + // 在其余片段里找以 base 开头且长度更长的字段. + // 如 "2513" 意味着补丁版本为 "3". + val patch = parts.drop(1).firstNotNullOfOrNull { seg -> + if (seg.startsWith(baseStr) && seg.length > baseStr.length) { + seg.substring(baseStr.length).toIntOrNull() + } else null + } + + return if (patch != null && patch > 0) "$year.$minor.$patch" else "$year.$minor" + } + } + val config = object { - /* Print concerned info by `System.getProperties()`. */ - val isShowConcernedSystemProperties = true + /* Hide concerned properties by `System.getProperties()` and `gradle.startParameter.projectProperties`. */ + val isHideConcernedProperties = false + + /* Hide hint suffix like `[auto-specified]`, `[nearest-lower-matched]`, etc. in console. */ + val isHideConsoleInfoHintSuffix = false val isCleanupPaddleOcr = false val isCleanupRapidOcr = false - val fallbackAgpVersion = "7.4.2" - val fallbackKotlinVersion = "1.7.10" + val fallbackAgpVersion = "8.2.2" + val fallbackKotlinVersion = "1.8.10" @Suppress("unused") val platforms = object { val androidStudio = object : Platform( name = "AndroidStudio", vendor = "Google", + // @AnchorBegin ANDROID_STUDIO_AGP_VERSION_MAP + // @Script /.utils/scrape-android-studio-agp_version_maps.mjs // @Reference https://developer.android.com/studio/releases#android_gradle_plugin_and_android_studio_compatibility - // @Updated by SuperMonster003 on Aug 9, 2025. + // @Updated by SuperMonster003 on Sep 5, 2025. agpVersionMap = mapOf( - "2025.1" to "8.11", /* Jun 7, 2025. */ - "2024.3" to "8.9", /* May 17, 2025. */ - "2024.2" to "8.7", /* Jan 13, 2025. */ - "2024.1" to "8.5", /* Aug 30, 2024. */ - "2023.3" to "8.4", /* Mar 28, 2024. */ - "2023.2" to "8.3", /* Feb 14, 2024. */ - "2023.1" to "8.2", /* Feb 6, 2024. */ - "2022.3" to "8.1", /* Mar 31, 2024. */ - "2022.2" to "8.0", /* May 26, 2023. */ - "2022.1" to "7.4", /* Mar 25, 2023. */ - ), - // @Updated by SuperMonster003 on May 13, 2025. - kotlinVersionMap = mapOf( - "2024.3" to "2.1.21", /* May 17, 2025. */ - "2024.2" to "2.1.0", /* Nov 29, 2024. */ - "2024.1" to "2.0.0", /* Aug 13, 2024. */ + "2025.1.3" to "8.13", + "2025.1.2" to "8.12", + "2025.1.1" to "8.11", + "2024.3.2" to "8.10", + "2024.3.1" to "8.9", + "2024.2.2" to "8.8", + "2024.2.1" to "8.7", + "2024.1.2" to "8.6", + "2024.1.1" to "8.5", + "2023.3.1" to "8.4", ), + // @AnchorEnd ANDROID_STUDIO_AGP_VERSION_MAP + + // @AnchorBegin ANDROID_STUDIO_CODENAME_VERSION_MAP + // @Script /.utils/scrape-and-inject-android-studio-codename_maps.mjs + // @Reference https://developer.android.com/studio/archive?hl=en + // @Updated by SuperMonster003 on Sep 5, 2025. codenameVersionMap = mapOf( - "2025.1" to "N", /* Apr 11, 2025. */ - "2024.3" to "M", /* Nov 29, 2024. */ - "2024.2" to "L", /* Aug 13, 2024. */ - "2024.1" to "K|L", /* May 14, 2024. */ - "2023.3" to "J|K", /* Jan 21, 2024. */ - "2023.2" to "I", /* Aug 25, 2023. */ - "2023.1" to "H", /* May 13, 2023. */ - "2022.3" to "G", /* May 3, 2023. */ - "2022.2" to "F", /* May 3, 2023. */ - "2022.1" to "E", /* May 3, 2023. */ + "2025.1" to "N", + "2024.3" to "M", + "2024.2" to "L", + "2024.1.3" to "L", + "2024.1.2" to "K", + "2024.1.1" to "K", + "2023.3.2" to "J|K", + "2023.3.1" to "J", + "2023.2" to "I", + "2023.1" to "H", + "2022.3" to "G", + "2022.2" to "F", + "2022.1" to "E", + "2021.3" to "D", + "2021.2" to "C", + "2021.1" to "B", + "2020.3" to "A", ), + // @AnchorEnd ANDROID_STUDIO_CODENAME_VERSION_MAP + + // @AnchorBegin ANDROID_STUDIO_CODENAME_MAP + // @Script /.utils/scrape-and-inject-android-studio-codename_maps.mjs + // @Reference https://developer.android.com/studio/archive?hl=en + // @Updated by SuperMonster003 on Apr 11, 2025. codenameMap = mapOf( "N" to "Narwhal", /* Born on Mar 19, 2025. */ "M" to "Meerkat", /* Born on Nov 12, 2024. */ "L" to "Ladybug", /* Born on Jul 15, 2024. */ - "K" to "Koala", /* Born on Mar 19, 2024. */ + "K" to "Koala", /* Born on Mar 22, 2024. */ "J" to "Jellyfish", /* Born on Dec 28, 2023. */ "I" to "Iguana", /* Born on Aug 25, 2023. */ "H" to "Hedgehog", /* Born on Apr 25, 2023. */ @@ -258,59 +360,53 @@ pluginManagement { "B" to "Bumblebee", /* Born on May 18, 2021. */ "A" to "Arctic Fox", /* Born on Jan 26, 2021. */ ), + // @AnchorEnd ANDROID_STUDIO_CODENAME_MAP ) { override val weight = Int.MAX_VALUE override val gradleSettingsName = "Gradle JDK" override val fullName by lazy { - val suffix = codenameVersionMap?.get(version) - ?.split("|") - ?.joinToString(" / ", prefix = " ") { key -> - codenameMap?.get(key.trim()) ?: key - } ?: "" + val suffix = codenameVersionMap?.let { map -> + val letters = map[version] + ?: map[version.split(".").take(2).joinToString(".")] + ?: return@let null + letters + .split("|") + .joinToString(" / ", prefix = " ") { key -> + codenameMap?.get(key.trim()) ?: key + } + } ?: "" return@lazy "Android Studio$suffix" } + override val minSupportedVersion = versionProperties["MIN_SUPPORTED_ANDROID_STUDIO_IDE_VERSION"] as String } val intelliJIdea = object : Platform( name = "IntelliJIdea", vendor = "Jetbrains", // @Reference AGP Upgrade Assistant integrated within JetBrains IntelliJ IDEA. - // @Updated by SuperMonster003 on Aug 10, 2025. + // @Updated by SuperMonster003 on Aug 10, 2025. (Manual) agpVersionMap = mapOf( - "2025.2" to "8.11.0", /* Aug 10, 2025. */ - "2025.1" to "8.10.1", /* Jun 7, 2025. */ - "2024.3.1" to "8.7.3", /* Dec 10, 2024. */ - "2024.3" to "8.7.0-rc01", /* Nov 15, 2024. */ - "2024.2" to "8.5.2", /* Aug 13, 2024. */ - "2024.1" to "8.2.2", /* Apr 6, 2024. */ - "2023.3" to "8.2.2", /* Jan 19, 2024. */ - "2023.1" to "7.4.2", /* May 26, 2023. */ - "2022.3" to "7.4.0-beta02", /* Mar 25, 2023. */ - ), - // @Updated by SuperMonster003 on Apr 23, 2025. - kotlinVersionMap = mapOf( - "2025.1" to "2.1.21", /* May 17, 2025. */ - "2024.3.4" to "2.1.10", /* Feb 28, 2025. */ - "2024.2.3" to "2.0.21", /* Oct 17, 2024. */ - "2024.2" to "2.0.21-RC", /* Sep 27, 2024. */ - "2024.1" to "1.9.24", /* Dec 3, 2024. */ - "2023.3" to "1.9.23", /* Mar 29, 2024. */ + "2025.2" to "8.11.1", + "2025.1" to "8.10.1", + "2024.3" to "8.7.3", + "2024.2" to "8.5.2", + "2024.1" to "8.2.2", + "2023.3" to "8.2.2", /* Settings: Enable sync with future AGP version. */ ), ) { override val weight = 10 override val gradleSettingsName = "Gradle JVM" override val fullName = "IntelliJ IDEA" + override val minSupportedVersion = versionProperties["MIN_SUPPORTED_INTELLIJ_IDEA_IDE_VERSION"] as String } val temurin = object : Platform( - name = "Temurin", vendor = "temurin", /* More common as "Eclipse Adoptium". */ + name = "Temurin", vendor = "temurin", + /* More common as "Eclipse Adoptium". */ + // @Updated by SuperMonster003 on Apr 16, 2025. (Manual) agpVersionMap = mapOf( "21.0.6+7" to "8.7.3", /* Apr 16, 2025. */ "20.0.2+9" to "8.2.2", /* Dec 2, 2024. */ ), - kotlinVersionMap = mapOf( - "21.0.6+7" to "2.1.10", /* Apr 16, 2025. */ - "20.0.2+9" to "1.9.24", /* Dec 2, 2024. */ - ), ) { override val weight = 5 override val shouldPrintProgress = false @@ -323,9 +419,9 @@ pluginManagement { println("Unexpected platform: $it") } ?: Formatted( "Current platform is unknown", - systemProperties.concerns, + concernedProperties, "However, here are some props may be useful for determining platform info", - ).print().also { systemProperties.isConcernsAlreadyPrinted = true } + ).print().also { isConcernedPropertiesAlreadyPrinted = true } } fun determine(): Platform { @@ -336,6 +432,16 @@ pluginManagement { }?.let { tmpPlatform as? Platform } } } + + fun parseVersion(platform: Platform) = systemProperties.version ?: when { + platform != unknown && systemProperties.platform != null -> { + systemProperties.platform.substring(platform.name.length) + .replace(Regex("^\\W*"), "") + .replace(Regex("^Preview", RegexOption.IGNORE_CASE), "") + } + else -> consts.DEFAULT_VERSION + } + return when { candidates.isEmpty() -> when (val osName = System.getProperty("os.name")) { is String -> unknown.also { it.name = osName } @@ -344,13 +450,13 @@ pluginManagement { candidates.size > 1 -> candidates.maxBy { it.weight } else -> candidates.first() }.also { - it.version = systemProperties.version ?: when { - it != unknown && systemProperties.platform != null -> { - systemProperties.platform.substring(it.name.length) - .replace(Regex("^\\W*"), "") - .replace(Regex("^Preview", RegexOption.IGNORE_CASE), "") + when (it) { + androidStudio -> { + it.version = utils.parseAndroidStudioBuildToVersion() ?: parseVersion(it) + } + else -> { + it.version = parseVersion(it) } - else -> consts.DEFAULT_VERSION } } } @@ -363,11 +469,16 @@ pluginManagement { Plugin(id = "com.google.devtools.ksp", version = overriddenKspVersion ?: "auto:ksp"), ) + // @AnchorBegin KSP_VERSION_MAP + // @Script /.utils/scrape-and-inject-ksp-releases.mjs // @Reference https://github.com/google/ksp/releases - // @Updated by SuperMonster003 on Aug 9, 2025. + // @Updated by SuperMonster003 on Sep 4, 2025. val kspVersionMap = mapOf( + "2.2.20-RC2" to "2.0.2", /* Sep 4, 2025. */ + "2.2.20-RC" to "2.0.2", /* Aug 20, 2025. */ "2.2.20-Beta2" to "2.0.2", /* Aug 1, 2025. */ "2.2.20-Beta1" to "2.0.2", /* Jul 11, 2025. */ + "2.2.10" to "2.0.2", /* Aug 15, 2025. */ "2.2.10-RC2" to "2.0.2", /* Aug 7, 2025. */ "2.2.10-RC" to "2.0.2", /* Jul 25, 2025. */ "2.2.0" to "2.0.2", /* Jun 25, 2025. */ @@ -436,12 +547,12 @@ pluginManagement { "1.8.0" to "1.0.9", /* Jan 26, 2023. */ "1.8.0-RC2" to "1.0.8", /* Dec 21, 2022. */ ) + // @AnchorEnd KSP_VERSION_MAP abstract inner class Platform( var name: String, val vendor: String, val agpVersionMap: Map = emptyMap(), - val kotlinVersionMap: Map = emptyMap(), val codenameVersionMap: Map? = null, val codenameMap: Map? = null, ) { @@ -449,6 +560,7 @@ pluginManagement { open val gradleSettingsName: String? = null open val weight: Int = -Int.MAX_VALUE open var version: String = consts.DEFAULT_VERSION + open val minSupportedVersion: String = consts.DEFAULT_VERSION @Suppress("unused") open val shouldPrintProgress: Boolean = true @@ -460,9 +572,7 @@ pluginManagement { || systemProperties.vendorName?.contains(vendor, true) == true fun ensureMinimalGradleJdkVersion() { - val minVer = java.util.Properties().apply { - load(java.io.FileInputStream("$rootDir/version.properties")) - }["JAVA_VERSION_MIN_SUPPORTED"].let { it as String }.toInt() + val minVer = versionProperties["JAVA_VERSION_MIN_SUPPORTED"].let { it as String }.toInt() if (JavaVersion.current().majorVersion.toInt() < minVer) { Formatted( @@ -476,6 +586,12 @@ pluginManagement { } } + fun ensureMinimalIdeVersion() { + if (minSupportedVersion == consts.DEFAULT_VERSION) return + if (utils.compareVersionStrings(version, minSupportedVersion) >= 0) return + throw Exception("Current IDE (${this.fullName}) version $version does not meet the minimum requirement which $minSupportedVersion is needed") + } + fun prependConsoleInformation(consoleInfo: MutableList) { val versionSuffix = when (this.version.isNotEmpty() && this.version != consts.DEFAULT_VERSION) { true -> " | ${this.version}" @@ -527,18 +643,20 @@ pluginManagement { var versionInfo = mutableListOf() - fun printConcernedSystemPropertiesIfNeeded() { - if (config.isShowConcernedSystemProperties && !systemProperties.isConcernsAlreadyPrinted) { - Formatted("Information for concerned system properties", systemProperties.concerns).print(true) + fun printConcernedPropertiesIfNeeded() { + if (!config.isHideConcernedProperties && !isConcernedPropertiesAlreadyPrinted) { + Formatted("Information for concerned properties", concernedProperties).print(true) } } fun printVersionsOfIdeAndGradlePlugins() { - Formatted("Version information for IDE platform and Gradle plugins", versionInfo).print() + val footers = listOf("Gradle version: ${gradle.gradleVersion}") + Formatted("Version information for IDE platform and Gradle plugins", versionInfo, footers = footers).print() } } + platform.ensureMinimalIdeVersion() platform.ensureMinimalGradleJdkVersion() platform.prependConsoleInformation(console.versionInfo) @@ -551,35 +669,37 @@ pluginManagement { override fun refinedBestMatchingValue(bestMatchingValue: String?): String? { val currentGradleVersion = gradle.gradleVersion.toGradleVersion() val sorted = agpGradleCompatibility.sortedByDescending { it.second.toGradleVersion() } - var maxSupporedAgpVersionPrefix: String? = null + var maxSupportedAgpVersionPrefix: String? = null for (pair in sorted) { - maxSupporedAgpVersionPrefix = pair.first + maxSupportedAgpVersionPrefix = pair.first if (currentGradleVersion >= pair.second.toGradleVersion()) { break } } - val maxSupporedAgpVersion = maxSupporedAgpVersionPrefix?.let { getAgpReleasedVersion(it) } - return when { - maxSupporedAgpVersion == null -> bestMatchingValue - bestMatchingValue == null -> { - bestMatchingOperationHintSuffix = identifier.autoSpecifiedSuffix - maxSupporedAgpVersion - } - compareVersionStrings(bestMatchingValue, maxSupporedAgpVersion) > 0 -> { - bestMatchingOperationHintSuffix = identifier.downgradedSuffix - maxSupporedAgpVersion - } - else -> bestMatchingValue + val maxSupporedAgpVersion = maxSupportedAgpVersionPrefix?.let { getAgpReleasedVersion(it) } + maxSupporedAgpVersion ?: return bestMatchingValue + bestMatchingValue ?: return maxSupporedAgpVersion.also { + bestMatchingOperationHintSuffix += identifier.autoSpecifiedSuffix } + if (!bestMatchingValue.contains("\\d+\\.\\d+\\.\\d+".toRegex())) { + bestMatchingOperationHintSuffix += identifier.autoSpecifiedSuffix + return getAgpReleasedVersion(bestMatchingValue) ?: "$bestMatchingValue.0" + } + if (utils.compareVersionStrings(bestMatchingValue, maxSupporedAgpVersion) > 0) { + bestMatchingOperationHintSuffix += identifier.downgradedSuffix + return maxSupporedAgpVersion + } + return bestMatchingValue } private fun getAgpReleasedVersion(referenceAgpVersion: String): String? { - return agpReleases.find { it.startsWith(referenceAgpVersion) && !it.contains("-") } + val sortedAgpReleases = agpReleases.sortByVersionName(isDescend = true) + return sortedAgpReleases.find { it.startsWith(referenceAgpVersion) && !it.contains("-") } } } - val kotlin = object : Version(platform.kotlinVersionMap, platform.version, config.fallbackKotlinVersion) { + val kotlin = object : Version(emptyMap(), platform.version, config.fallbackKotlinVersion) { override fun refinedBestMatchingValue(bestMatchingValue: String?): String? { val currentGradleVersion = gradle.gradleVersion.toGradleVersion() @@ -590,15 +710,15 @@ pluginManagement { return when { embeddedMin == null -> bestMatchingValue bestMatchingValue == null -> { - bestMatchingOperationHintSuffix = identifier.autoSpecifiedSuffix + bestMatchingOperationHintSuffix += identifier.autoSpecifiedSuffix embeddedMin } bestMatchingValue.toGradleVersion() < embeddedMin.toGradleVersion() -> { - bestMatchingOperationHintSuffix = identifier.upgradedSuffix + bestMatchingOperationHintSuffix += identifier.upgradedSuffix embeddedMin } bestMatchingValue.toGradleVersion() > embeddedMin.toGradleVersion() -> { - bestMatchingOperationHintSuffix = identifier.downgradedSuffix + bestMatchingOperationHintSuffix += identifier.downgradedSuffix embeddedMin } else -> bestMatchingValue @@ -630,7 +750,7 @@ pluginManagement { val ver = Version(config.kspVersionMap, kt) val key = ver.bestMatchingKey ?: return@let null val value = ver.bestMatchingValue ?: return@let null - ver.bestMatchingOperationHintSuffix?.let { suffix += it } + suffix += ver.bestMatchingOperationHintSuffix "$key-$value" } @@ -649,7 +769,7 @@ pluginManagement { else -> throw Exception("Unknown version ${lib.version} for classpath ${lib.id}") } ver.bestMatchingValue?.also { - ver.bestMatchingOperationHintSuffix?.let { s -> suffix += s } + suffix += ver.bestMatchingOperationHintSuffix } ?: ver.fallbackVersion?.also { suffix += identifier.fallbackSuffix } ?: consts.DEFAULT_VERSION @@ -663,7 +783,7 @@ pluginManagement { gradle.extra.set("javaVersionOverriddenByUser", overriddenJavaVersion) } "${lib.id}:$version".also { notation -> - console.versionInfo += "Classpath: \"$notation\"$suffix" + console.versionInfo += "Classpath: \"$notation\"${if (config.isHideConsoleInfoHintSuffix) "" else suffix}" } } @@ -681,7 +801,7 @@ pluginManagement { lib.version } } - console.versionInfo += "Plugin: \"${lib.id}:$version\"$suffix" + console.versionInfo += "Plugin: \"${lib.id}:$version\"${if (config.isHideConsoleInfoHintSuffix) "" else suffix}" mapOf("id" to lib.id, "version" to version, "isApply" to lib.isApply) } @@ -689,8 +809,9 @@ pluginManagement { val bestMatchingKey: String? = findBestMatchingMapKey(platformVersion) - var bestMatchingOperationHintSuffix: String? = identifier.nearestLowerMatchedSuffix.takeIf { - bestMatchingKey != null && bestMatchingKey != platformVersion + var bestMatchingOperationHintSuffix: String = when (bestMatchingKey != null && bestMatchingKey != platformVersion) { + true -> identifier.nearestLowerMatchedSuffix + else -> "" } val bestMatchingValue: String? = refinedBestMatchingValue(bestMatchingKey?.let { map[it] }) @@ -698,60 +819,23 @@ pluginManagement { open fun refinedBestMatchingValue(bestMatchingValue: String?) = bestMatchingValue fun findBestMatchingMapKey(platformVersion: String): String? { - val (platformVersionNumbers, platformVersionSuffix) = toVersionParts(platformVersion) - val sortedVersions = map.keys.filter { it != identifier.fallback }.sortedWith(::compareVersionStrings).reversed() + val (platformVersionNumbers, platformVersionSuffix) = utils.toVersionParts(platformVersion) + val sortedVersions = map.keys.filter { it != identifier.fallback }.sortedWith(utils::compareVersionStrings).reversed() for (version in sortedVersions) { - val (versionNumbers, versionSuffix) = toVersionParts(version) - val versionComparisonScore = compareVersionParts(versionNumbers, platformVersionNumbers) + val (versionNumbers, versionSuffix) = utils.toVersionParts(version) + val versionComparisonScore = utils.compareVersionParts(versionNumbers, platformVersionNumbers) if (versionComparisonScore < 0) { return version } - if (versionComparisonScore == 0 && compareSuffix(versionSuffix, platformVersionSuffix) <= 0) { + if (versionComparisonScore == 0 && utils.compareVersionSuffix(versionSuffix, platformVersionSuffix) <= 0) { return version } } return null } - fun compareVersionStrings(v1: String, v2: String): Int { - val (ver1Numbers, ver1Suffix) = toVersionParts(v1) - val (ver2Numbers, ver2Suffix) = toVersionParts(v2) - return compareVersionParts(ver1Numbers, ver2Numbers) - .takeIf { it != 0 } - ?: compareSuffix(ver1Suffix, ver2Suffix) - } - - private fun compareVersionParts(parts1: List, parts2: List): Int { - for (i in 0 until maxOf(parts1.size, parts2.size)) { - val part1 = parts1.getOrElse(i) { 0 } - val part2 = parts2.getOrElse(i) { 0 } - if (part1 != part2) return part1.compareTo(part2) - } - return 0 - } - - private fun compareSuffix(suffix1: Pair, suffix2: Pair): Int { - val suffixPriority = mapOf("" to 10, "Alpha" to 1, "Beta" to 2, "RC" to 5) - val (suffixName1, suffixNumber1) = suffix1 - val (suffixName2, suffixNumber2) = suffix2 - val priority1 = suffixPriority[suffixName1] ?: Int.MAX_VALUE - val priority2 = suffixPriority[suffixName2] ?: Int.MAX_VALUE - return priority1.compareTo(priority2).takeIf { it != 0 } ?: suffixNumber1.compareTo(suffixNumber2) - } - - private fun toVersionParts(version: String): Pair, Pair> { - val parts = version.split(Regex("[+-]")) - val numberParts = parts[0].split('.').map { - it.toIntOrNull() ?: throw IllegalArgumentException("Invalid version part: '$it' in version: '$version'") - } - - val suffixPattern = Regex("([A-Za-z]+)(\\d*)|([A-Za-z]*)(\\d+)") - val suffixMatch = suffixPattern.matchEntire(parts.getOrElse(1) { "" }) ?: return numberParts to ("" to 0) - - val suffixName = suffixMatch.groupValues[1] // "Alpha", "Beta", "RC" or empty string - val suffixNumber = suffixMatch.groupValues[2].toIntOrNull() ?: 1 // Default to 1 for suffixes like "Alpha", "Beta", "RC" - - return numberParts to (suffixName to suffixNumber) + fun List.sortByVersionName(isDescend: Boolean = false): List { + return sortedWith { v1, v2 -> utils.compareVersionStrings(v1, v2) * if (isDescend) -1 else 1 } } } @@ -803,8 +887,8 @@ pluginManagement { notations.classpath.forEach { classpath(it) } } dependencies /* Apache Compress for utils.build.gradle module. */ { - classpath("org.apache.commons:commons-compress:1.27.1") - classpath("org.tukaani:xz:1.9") + classpath("org.apache.commons:commons-compress:1.28.0") + classpath("org.tukaani:xz:1.10") } } @@ -816,7 +900,7 @@ pluginManagement { gradle.taskGraph.whenReady { if (allTasks.none { it.name == "clean" }) { - console.printConcernedSystemPropertiesIfNeeded() + console.printConcernedPropertiesIfNeeded() console.printVersionsOfIdeAndGradlePlugins() } } @@ -824,6 +908,7 @@ pluginManagement { gradle.extra.apply { set("isCleanupPaddleOcr", config.isCleanupPaddleOcr) set("isCleanupRapidOcr", config.isCleanupRapidOcr) + set("isHideConsoleInfoHintSuffix", config.isHideConsoleInfoHintSuffix) } gradle.beforeProject { diff --git a/version.properties b/version.properties index edbc28a8..bec3cdd1 100644 --- a/version.properties +++ b/version.properties @@ -1,13 +1,18 @@ -#Sun Aug 10 14:25:33 CST 2025 -BUILD_TIME=1754807133222 +#Fri Sep 05 15:31:16 CST 2025 +BUILD_TIME=1757057476985 COMPILE_SDK_VERSION=35 IMAGE_QUANT_CMAKE_VERSION=3.22.1 IMAGE_QUANT_NDK_VERSION=26.1.10909125 JAVA_VERSION=24 -JAVA_VERSION_MIN_RADICAL=0 -JAVA_VERSION_MIN_SUGGESTED=19 +JAVA_VERSION_MAX_SUPPORTED=24 +JAVA_VERSION_MIN_SUGGESTED=21 JAVA_VERSION_MIN_SUPPORTED=17 MIN_SDK_VERSION=24 +MIN_SUPPORTED_ANDROID_STUDIO_AGP_VERSION=8.4 +MIN_SUPPORTED_ANDROID_STUDIO_IDE_VERSION=2023.3 +MIN_SUPPORTED_GRADLE_VERSION=8.2 +MIN_SUPPORTED_INTELLIJ_IDEA_AGP_VERSION=8.2 +MIN_SUPPORTED_INTELLIJ_IDEA_IDE_VERSION=2023.3 PADDLE_OCR_CMAKE_VERSION=3.10.2 PADDLE_OCR_NDK_VERSION=21.1.6352462 PADDLE_OCR_OPENCV_VERSION=4.8.0 @@ -19,6 +24,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 TARGET_SDK_VERSION=35 TARGET_SDK_VERSION_INRT=29 -VERSION_BUILD=3341 +VERSION_BUILD=3355 VERSION_NAME=6.7.0 Alpha4 VSCODE_EXT_REQUIRED_VERSION=1.0.8