chore: 更新学生档案数据
This commit is contained in:
1
.claude/memory/MEMORY.md
Normal file
1
.claude/memory/MEMORY.md
Normal file
@@ -0,0 +1 @@
|
||||
- [CSP03周六1400第18课总复习完成](csp03-sat1400-lesson18-review.md) — OJ数据获取踩坑 + 补课学生处理 + 知识点从录音提取
|
||||
@@ -0,0 +1,23 @@
|
||||
# 班级总结 — AICODE03橙子周五1700(一对一)
|
||||
|
||||
**日期**: 2026-07-03 | **课程**: 《漫画-角色三视图》
|
||||
|
||||
---
|
||||
|
||||
## 本节课知识点
|
||||
1. 理解角色三视图的概念:正面视图、侧面视图、背面视图
|
||||
2. 学习AI生图提示词的设计方法(角色外观描述 + 视图角度)
|
||||
3. 掌握角色外观设计要素:发型、服装、配色、表情
|
||||
4. 通过迭代优化提示词来提升AI生成效果
|
||||
5. 培养审美判断力和创意表达能力
|
||||
|
||||
## 学生表现总结
|
||||
|
||||
**李梓宁**:本节课表现积极,创作投入度高。主动分享自己小说中的角色设定,对角色设计有自己的审美判断。能自主发现AI生成图片的问题(如"太黑了"、"头太大了")并调整提示词优化,具备了良好的"发现问题→调整→再试"的迭代意识。对角色外观(头发颜色、服装风格等)有明确主见。
|
||||
|
||||
**亮点**:审美判断力敏锐,不满足于AI的初始输出,追求品质
|
||||
|
||||
**建议关注**:可以引导梓宁养成记录提示词修改的习惯,帮助她更系统地掌握提示词优化技巧
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:《漫画-角色三视图》
|
||||
|
||||
**授课日期**: 2026-07-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
梓宁家长好,本周学习的内容是《漫画-角色三视图》:
|
||||
1. 理解角色三视图的概念:正面视图、侧面视图、背面视图
|
||||
2. 学习AI生图提示词的设计方法(角色外观描述 + 视图角度)
|
||||
3. 掌握角色外观设计要素:发型、服装、配色、表情
|
||||
4. 通过迭代优化提示词来提升AI生成效果
|
||||
5. 培养审美判断力和创意表达能力
|
||||
|
||||
梓宁今天表现特别棒~主动和老师分享自己小说中的角色设定,对角色名字和形象都有自己的想法,创作投入度非常高!🌸
|
||||
|
||||
对AI生成的图片有敏锐的审美判断,能自己发现"太黑了"、"头太大了"这些问题,然后主动调整提示词来优化效果~这种"发现问题→调整→再试"的迭代意识特别好,说明梓宁已经具备了AI时代很重要的批判性思维和问题解决能力💡
|
||||
|
||||
对角色设计很有主见,从头发颜色到服装风格都有自己的想法,不满足于AI随便生成的结果,这种追求品质的态度值得鼓励~
|
||||
|
||||
要是可以在调整提示词的时候,把每次修改的地方简单记下来,下次就能更快找到最优的描述方式啦😊
|
||||
|
||||
老师会继续关注梓宁的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -1,7 +1,7 @@
|
||||
# 学生画像 — 李梓宁
|
||||
|
||||
> 创建日期:2026-03-27
|
||||
> 最后更新:2026-05-20
|
||||
> 最后更新:2026-07-04
|
||||
> 班级:周五下午1700AI03班
|
||||
> 备注:一对一上课
|
||||
|
||||
@@ -174,6 +174,12 @@
|
||||
- **画像更新**:近期(4-5月集训阶段)已明显偏离初始"兴趣缺乏型"评估,呈现出主动创作、精益求精的特质;一对一陪伴 + 创作类任务能很好激发她的内驱力
|
||||
- **下阶段重点**:在作品细节打磨与专业度上提供更具体的指引(构图、文字与画面搭配)
|
||||
|
||||
### 2026-07-03(《漫画-角色三视图》)
|
||||
- **课堂表现**:创作投入度非常高,主动分享小说角色设定;审美判断敏锐,能自主发现AI生图问题并调整提示词优化;对角色设计(发型、服装、配色)有明确主见
|
||||
- **亮点**:具备了"发现问题→调整→再试"的迭代意识,批判性思维和问题解决能力在提升;不满足于AI初始输出,追求品质
|
||||
- **画像更新**:创作潜力持续释放,一对一环境下的专注度和主动性表现稳定;审美判断力是突出优势
|
||||
- **下阶段重点**:可引导养成记录提示词修改的习惯,帮助更系统地掌握优化技巧
|
||||
|
||||
### 2026-06-05(AICODE03第14课《魔幻俄罗斯方块(下)》)
|
||||
- **课堂表现**:主动提出虎鲸主题海报创意,设计思路清晰,审美判断能力突出;但在项目打基础环节(增量文档、测试脚本)缺乏主动性
|
||||
- **亮点**:对设计风格有明确偏好(写实摄影、水中透视构图、海洋背景+海底景色),能主动与老师讨论设计细节
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
# AICODE03橙子周六1900 · 第18课《PK总结》班级反馈
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
---
|
||||
|
||||
## 📚 本节课内容
|
||||
|
||||
1. 项目整合与文件管理——整理散乱的项目文件,按功能分类存放到独立文件夹
|
||||
2. 导航主页制作——用AI生成包含所有子项目入口链接的导航主页
|
||||
3. 需求文档回顾与讲解——回顾每个子项目的需求文档和增量文档,口头复述开发流程
|
||||
4. 项目路演录制——录制视频介绍各项目功能、开发流程和学到的知识
|
||||
5. 学期项目成果整理——梳理涂鸦PK系列全部学习成果,形成完整项目展示
|
||||
|
||||
---
|
||||
|
||||
## 📊 出勤情况
|
||||
|
||||
| 学生 | 状态 | 备注 |
|
||||
|------|------|------|
|
||||
| 王子墨 | ✅ 正常上课 | 课堂演示表现突出 |
|
||||
| 谭俊研 | ✅ 正常上课 | 安静踏实完成 |
|
||||
| 黄彦棋 | ✅ 正常上课 | 有聊天分心现象 |
|
||||
| 李承泽 | ✅ 正常上课 | 代码结构最规范 |
|
||||
| 陈嘉博 | ⚠️ 请假 | 请假仍完成作品 |
|
||||
| 黄浩 | 🔄 补课 | 文档数量全班最多 |
|
||||
| 钟嘉鑫 | 🔄 补课 | 增量文档三维度覆盖 |
|
||||
|
||||
---
|
||||
|
||||
## 🌟 本节课亮点
|
||||
|
||||
1. **王子墨的课堂演示** - 唯一被老师点名做现场演示的学生,主动上台介绍三个项目,讲解条理清晰,展现了对AI辅助调试的实用理解
|
||||
|
||||
2. **谭俊研的导航主页** - 班上唯一单独创建了主页.html做导航入口的学生,5个子项目整理得井井有条
|
||||
|
||||
3. **李承泽的代码规范** - 特效生成器采用HTML/CSS/JS分离的专业代码结构,有test-character.html测试页面
|
||||
|
||||
4. **黄浩的文档数量** - 7份文档全班最多,包含PRD、技术架构文档,展现了对项目结构的深入理解
|
||||
|
||||
5. **钟嘉鑫的增量覆盖** - 增量需求文档覆盖三个维度(玩家对战、冒险模式、设置与角色系统),结构最完整
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 需要关注的问题
|
||||
|
||||
### 黄彦棋的专注度问题
|
||||
- 课堂上有聊天分心现象,被提醒了几次
|
||||
- 之前第13课曾因聊游戏、说"很无聊"、不想上课,已与家长沟通过
|
||||
- 建议:继续关注,肯定阳光开朗优点的同时温和引导专注
|
||||
|
||||
### 陈嘉博的出勤
|
||||
- 这节课请假,但完成了作品和162MB视频
|
||||
- 建议:了解请假原因,确保学习状态稳定
|
||||
|
||||
---
|
||||
|
||||
## 📈 学期总结
|
||||
|
||||
涂鸦PK系列四课主线回顾:
|
||||
- **第12课**:需求文档 → 画图工具
|
||||
- **第13课**:需求文档 → 战斗系统 + 测试验证
|
||||
- **第14课**:增量需求 → 动画 + 音效
|
||||
- **第15课**:数据驱动 → 角色系统 + 锦标赛
|
||||
|
||||
学生学到的核心能力:
|
||||
1. 需求文档让你在动手之前想清楚
|
||||
2. 测试验证让你知道自己做的对不对
|
||||
3. 增量需求让你在已有基础上扩展,而不是推倒重来
|
||||
4. 数据驱动让你的系统可以无限成长,不被代码本身限制
|
||||
|
||||
---
|
||||
|
||||
## 🎯 下节课建议
|
||||
|
||||
1. **项目路演分享** - 让每位学生展示自己的项目,练习路演表达
|
||||
2. **视频录制技巧** - 分享如何录制更清晰、更有条理的演示视频
|
||||
3. **代码结构规范** - 以李承泽的HTML/CSS/JS分离为范例,推广代码规范意识
|
||||
4. **持续关注黄彦棋** - 与家长保持沟通,引导专注度提升
|
||||
|
||||
---
|
||||
|
||||
*班级反馈生成时间:2026-07-05*
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:《PK总结》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
承泽家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目整合与文件管理——整理散乱的项目文件,按功能分类存放到独立文件夹
|
||||
2. 导航主页制作——用AI生成包含所有子项目入口链接的导航主页
|
||||
3. 需求文档回顾与讲解——回顾每个子项目的需求文档和增量文档,口头复述开发流程
|
||||
4. 项目路演录制——录制视频介绍各项目功能、开发流程和学到的知识
|
||||
5. 学期项目成果整理——梳理涂鸦PK系列全部学习成果,形成完整项目展示
|
||||
|
||||
承泽今天完成得很棒~项目完整,代码结构在班上是最规范的!🌟
|
||||
|
||||
特效生成器采用了HTML/CSS/JS分离的专业代码结构,还有test-character.html测试页面,展现了测试验证意识。36.6MB的视频也正常完成。比之前的作品完成度有明显进步,值得肯定💪
|
||||
|
||||
从涂鸦PK第一课到现在,承泽的进步肉眼可见——从之前作品完成度不高到现在能独立完成全套项目整理,专注度在持续提升。需求文档也写了好几份,说明"先设计再编码"的习惯在慢慢养成💡
|
||||
|
||||
继续保持这种认真的状态,老师期待看到你下一个更棒的作品!
|
||||
|
||||
老师会继续关注承泽的表现,期待看到更多惊喜!✨💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -137,6 +137,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04 第18课观察
|
||||
- 特效生成器采用HTML/CSS/JS分离的专业代码结构,有test-character.html测试页面
|
||||
- 36.6MB视频正常完成,项目完整度在班上是最规范的
|
||||
- 比之前作品完成度有明显进步,专注度在持续提升
|
||||
- 需求文档也写了好几份,"先设计再编码"的习惯在慢慢养成
|
||||
|
||||
### 2026-06-20 第16课观察
|
||||
- 比之前更专注,能独立完成玩家对战模式的增量需求文档
|
||||
- 中间有想偷懒跳过审核步骤,但最终跟着流程完整走完
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:《PK总结》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
子墨家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目整合与文件管理——整理散乱的项目文件,按功能分类存放到独立文件夹
|
||||
2. 导航主页制作——用AI生成包含所有子项目入口链接的导航主页
|
||||
3. 需求文档回顾与讲解——回顾每个子项目的需求文档和增量文档,口头复述开发流程
|
||||
4. 项目路演录制——录制视频介绍各项目功能、开发流程和学到的知识
|
||||
5. 学期项目成果整理——梳理涂鸦PK系列全部学习成果,形成完整项目展示
|
||||
|
||||
子墨今天表现超棒~是班上唯一被老师点名做现场演示的学生!🌟
|
||||
|
||||
自己主动上台介绍了像素画图工具、对战模拟器、特效生成器三个项目,讲解条理清晰,从画图工具的功能演示到文档介绍再到AI辅助解决问题,结构完整。还提到"遇到问题可以截图发给AI让它帮忙解决",展现了对AI辅助调试的实用理解💡
|
||||
|
||||
作品方面,子墨是班上项目最完整的——5份需求/增量文档覆盖像素画图工具、回合制对战、玩家对战、设置与角色等多维度,50点属性分配系统代替20分制增加了能量值属性,设计更有创意。83.5MB的演示视频内容非常丰富!
|
||||
|
||||
要是可以在讲解的时候语速再慢一点,让观众跟上就更好啦~
|
||||
|
||||
老师会继续关注子墨的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -138,6 +138,19 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04 第18课观察
|
||||
- 唯一被老师点名做现场演示的学生,主动上台介绍三个项目,讲解条理清晰
|
||||
- 提到"遇到问题可以截图发给AI让它帮忙解决",展现对AI辅助调试的实用理解
|
||||
- 项目最完整:5份需求/增量文档覆盖多维度,50点属性分配系统有创意
|
||||
- 83.5MB演示视频内容非常丰富,展现了认真细致的态度
|
||||
|
||||
### 2026-07-04 第18课观察
|
||||
- 唯一被老师点名做现场演示的学生,主动上台介绍三个项目,讲解条理清晰
|
||||
- 提到"遇到问题可以截图发给AI让它帮忙解决",展现对AI辅助调试的实用理解
|
||||
- 项目最完整:5份需求/增量文档覆盖多维度,50点属性分配系统有创意
|
||||
- 83.5MB演示视频内容非常丰富,展现了认真细致的态度
|
||||
- 打字速度持续进步,从1分提升到3分,愿意主动表达
|
||||
|
||||
### 2026-06-27 第17课观察
|
||||
- 课堂参与度高,对金币获取途径和装备特殊效果理解快,思维活跃
|
||||
- 讨论环节积极分享想法,愿意表达
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# 课程名称:《PK总结》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**出勤状态**: 补课
|
||||
|
||||
**课评内容**:
|
||||
|
||||
嘉鑫家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目整合与文件管理——整理散乱的项目文件,按功能分类存放到独立文件夹
|
||||
2. 导航主页制作——用AI生成包含所有子项目入口链接的导航主页
|
||||
3. 需求文档回顾与讲解——回顾每个子项目的需求文档和增量文档,口头复述开发流程
|
||||
4. 项目路演录制——录制视频介绍各项目功能、开发流程和学到的知识
|
||||
5. 学期项目成果整理——梳理涂鸦PK系列全部学习成果,形成完整项目展示
|
||||
|
||||
嘉鑫今天来补课,表现超棒~增量需求文档覆盖三个维度,结构最完整!🌟
|
||||
|
||||
玩家对战、冒险模式、设置与角色系统——三个维度的增量文档都有,约束条件写得很清楚,考虑了重复挑战金币衰减、失败后状态重置等边缘情况,思考非常周全💡
|
||||
|
||||
游戏本体与文档分离清晰,52.1MB的视频也正常完成。从上次补课做玩家对战到这次做项目总结,对增量文档的理解持续进步,工程意识越来越强💪
|
||||
|
||||
继续保持这种认真细致的态度,老师相信你会做出更棒的作品!
|
||||
|
||||
老师会继续关注嘉鑫的表现,期待看到更多惊喜!✨💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -19,6 +19,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04 第18课观察(补课)
|
||||
- 增量需求文档覆盖三个维度(玩家对战、冒险模式、设置与角色系统),结构最完整
|
||||
- 约束条件写得很清楚,考虑了边缘情况,思考非常周全
|
||||
- 游戏本体与文档分离清晰,52.1MB视频正常完成
|
||||
- 从上次补课做玩家对战到这次做项目总结,对增量文档的理解持续进步,工程意识越来越强
|
||||
|
||||
### 2026-06-27 第17课观察(补课)
|
||||
- 完成冒险模式增量文档超过180行,内容充实
|
||||
- 约束条件写得很清楚,有"不破坏原有系统"的工程意识
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# 课程名称:《PK总结》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**出勤状态**: 补课
|
||||
|
||||
**课评内容**:
|
||||
|
||||
黄浩家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目整合与文件管理——整理散乱的项目文件,按功能分类存放到独立文件夹
|
||||
2. 导航主页制作——用AI生成包含所有子项目入口链接的导航主页
|
||||
3. 需求文档回顾与讲解——回顾每个子项目的需求文档和增量文档,口头复述开发流程
|
||||
4. 项目路演录制——录制视频介绍各项目功能、开发流程和学到的知识
|
||||
5. 学期项目成果整理——梳理涂鸦PK系列全部学习成果,形成完整项目展示
|
||||
|
||||
黄浩今天来补课,表现不错~项目整理得很完整🌟
|
||||
|
||||
最让老师惊喜的是文档数量全班最多——7份文档,包含PRD、技术架构文档、需求文档、玩家对战功能需求文档、新功能增量需求文档、冒险模式增量文档等,还有src/目录结构意识,展现了对项目结构的深入理解💡
|
||||
|
||||
从上次补课做玩家对战到这次做项目总结,黄浩一直在进步。能理解增量文档的核心思路:不修改原代码,通过新增独立模块扩展功能。视频11.7MB虽然偏小,但基础框架已经搭好💪
|
||||
|
||||
继续加油,期待看到你更完整的作品展示!
|
||||
|
||||
老师会继续关注黄浩的表现,期待看到更多进步!🌟💪
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -19,6 +19,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04 第18课观察(补课)
|
||||
- 文档数量全班最多(7份),包含PRD、技术架构文档、需求文档等
|
||||
- 有src/目录结构意识,展现了对项目结构的深入理解
|
||||
- 视频11.7MB偏小,但基础框架已经搭好
|
||||
- 从上次补课做玩家对战到这次做项目总结,一直在进步
|
||||
|
||||
### 2026-06-27 第17课观察(补课)
|
||||
- 能理解增量文档的核心思路:不修改原代码,通过新增独立模块扩展功能
|
||||
- 对关卡设计和装备系统概念有一定认识
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:《PK总结》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
俊研家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目整合与文件管理——整理散乱的项目文件,按功能分类存放到独立文件夹
|
||||
2. 导航主页制作——用AI生成包含所有子项目入口链接的导航主页
|
||||
3. 需求文档回顾与讲解——回顾每个子项目的需求文档和增量文档,口头复述开发流程
|
||||
4. 项目路演录制——录制视频介绍各项目功能、开发流程和学到的知识
|
||||
5. 学期项目成果整理——梳理涂鸦PK系列全部学习成果,形成完整项目展示
|
||||
|
||||
俊研一如既往地安静踏实~这节课认真完成了所有项目整理和视频录制💪
|
||||
|
||||
最让老师惊喜的是,俊研是班上唯一单独创建了主页.html做导航入口的学生!5个子项目全部整理得井井有条,文档分类清晰,37.6MB的视频也正常完成。这种踏实的执行力真的很珍贵🌟
|
||||
|
||||
从涂鸦PK系列第一课到现在,俊研的进步有目共睹——需求文档从几行到现在271行结构清晰的增量文档,"用数据说话"的习惯越来越稳固,工程化思维在持续进步。虽然打字速度还是有些慢,但每次都能耐心完成,这份坚持比速度更重要💡
|
||||
|
||||
继续保持这种认真的学习态度,老师相信你会越来越棒!
|
||||
|
||||
老师会继续关注俊研的表现,期待看到更多进步!🌸😊
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -137,6 +137,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04 第18课观察
|
||||
- 班上唯一单独创建了主页.html做导航入口的学生,执行力强
|
||||
- 5个子项目全部整理得井井有条,文档分类清晰
|
||||
- 37.6MB视频正常完成,保持踏实认真的风格
|
||||
- 从涂鸦PK系列第一课到现在,需求文档从几行到271行,进步明显
|
||||
|
||||
### 2026-06-27 第17课观察
|
||||
- 271行增量文档结构清晰,九大章节,保持踏实细致的风格
|
||||
- 数值平衡分析细致,做出装备前后属性对比表格和Boss AI概率调整对比表
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# 课程名称:《PK总结》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**出勤状态**: 请假
|
||||
|
||||
**课评内容**:
|
||||
|
||||
嘉博家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目整合与文件管理——整理散乱的项目文件,按功能分类存放到独立文件夹
|
||||
2. 导航主页制作——用AI生成包含所有子项目入口链接的导航主页
|
||||
3. 需求文档回顾与讲解——回顾每个子项目的需求文档和增量文档,口头复述开发流程
|
||||
4. 项目路演录制——录制视频介绍各项目功能、开发流程和学到的知识
|
||||
5. 学期项目成果整理——梳理涂鸦PK系列全部学习成果,形成完整项目展示
|
||||
|
||||
嘉博这节课请假了,但老师要特别表扬——请假也没落下作业!🌟
|
||||
|
||||
作品文件夹里4个子项目全部整理完成,视频文件162MB是全班最大的,说明录制内容非常详尽。一如既往地保持认真踏实的态度,这种对学习的责任心真的很珍贵💪
|
||||
|
||||
从整个涂鸦PK系列来看,嘉博一直是班上的标杆——617行的增量需求文档全班最详细,从核心决策到模块设计、代码示例到验收标准,结构非常完整。还画了ASCII界面设计图,工程化思维突出💡
|
||||
|
||||
下次如果能来上课,一起参加班级活动会更有趣哦!
|
||||
|
||||
老师会继续关注嘉博的表现,期待看到更多精彩!🌸😊
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -138,6 +138,19 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-05 第18课观察(补课)
|
||||
- 在周日下午AICODE03班补课,认真整理项目作品
|
||||
- 4个子项目全部整理完成,视频文件162MB全班最大
|
||||
- 录制介绍视频声音清晰,讲解详细
|
||||
- 保持认真踏实的态度,对学习的责任心很珍贵
|
||||
- 一直是班上的标杆,617行增量需求文档全班最详细
|
||||
|
||||
### 2026-07-04 第18课观察
|
||||
- 请假但完成作品提交,4个子项目全部整理完成
|
||||
- 视频文件162MB是全班最大的,说明录制内容非常详尽
|
||||
- 保持认真踏实的态度,对学习的责任心很珍贵
|
||||
- 一直是班上的标杆,617行增量需求文档全班最详细
|
||||
|
||||
### 2026-06-27 第17课观察
|
||||
- 完成617行增量需求文档,全班最详细,工程化思维突出
|
||||
- 从核心决策到模块设计、代码示例到验收标准,结构非常完整
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:《PK总结》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
彦棋家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目整合与文件管理——整理散乱的项目文件,按功能分类存放到独立文件夹
|
||||
2. 导航主页制作——用AI生成包含所有子项目入口链接的导航主页
|
||||
3. 需求文档回顾与讲解——回顾每个子项目的需求文档和增量文档,口头复述开发流程
|
||||
4. 项目路演录制——录制视频介绍各项目功能、开发流程和学到的知识
|
||||
5. 学期项目成果整理——梳理涂鸦PK系列全部学习成果,形成完整项目展示
|
||||
|
||||
彦棋今天完成了所有项目整理和视频录制,整体表现不错~🌟
|
||||
|
||||
文档分类特别规整,专门建了一个需求文档文件夹把4份文档集中存放,结构很清晰。对战项目还用自己名字命名("对战黄彦棋"),有个人品牌意识,挺有创意的!49.3MB的视频也顺利完成💪
|
||||
|
||||
不过老师发现课堂上有聊天分心的现象,被提醒了几次。彦棋的阳光开朗是最大的优点,和同学们相处融洽,但如果能把聊天的精力多用在作品打磨上,一定会做出更棒的成果💡
|
||||
|
||||
从涂鸦PK系列开始到现在,彦棋对增量需求文档的理解越来越到位,上次写的玩家对战文档也比较完整。继续保持,老师相信你下次会更专注!
|
||||
|
||||
老师会继续关注彦棋的表现,期待看到更多进步!🌟💪
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -138,6 +138,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04 第18课观察
|
||||
- 完成所有项目整理和视频录制,文档分类规整(专门的需求文档文件夹)
|
||||
- 对战项目用自己名字命名("对战黄彦棋"),有个人品牌意识
|
||||
- 49.3MB视频顺利完成,整体表现不错
|
||||
- 课堂上仍有聊天分心现象,被提醒了几次,专注度仍需持续关注
|
||||
|
||||
### 2026-06-20 第16课观察
|
||||
- 完成玩家对战作品90KB,内容很丰富,增量需求文档写得比较完整
|
||||
- 对玩家对战概念理解快,能说出"一个人选时另一个人不能看"的公平性设计细节
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# AICODE03橙子周日0845班 第18课《PK总结》班级反馈
|
||||
|
||||
**授课日期**:2026-07-05
|
||||
**出勤情况**:3人到课,1人请假(杨翊弘)
|
||||
|
||||
---
|
||||
|
||||
## 📚 本节课内容
|
||||
|
||||
1. 项目文件整理与分类管理
|
||||
2. 作品展示与课堂展示技巧
|
||||
3. 项目说明文档与改进记录的回顾
|
||||
4. 项目介绍的表达能力
|
||||
5. 学期项目总结与反思
|
||||
|
||||
---
|
||||
|
||||
## 🌟 整体表现
|
||||
|
||||
这节课是学期总结课,同学们轮流展示自己这学期做的项目作品。整体表现很棒,大部分同学都能把自己的作品介绍清楚,文件整理意识也有明显提升。
|
||||
|
||||
---
|
||||
|
||||
## ✨ 亮点学生
|
||||
|
||||
| 学生 | 亮点表现 |
|
||||
|------|----------|
|
||||
| **黄俊博** | 说明文档写得极其详细(超250行),数值规范严谨,改进版作品完成度高 |
|
||||
| **朱浩铭** | 主动上台展示,表达能力进步明显,从学期初紧张到现在能完整介绍项目 |
|
||||
| **卢皓霖** | 技能树系统设计有创意(4大分支),文件分类清晰,系统化思维有提升 |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 共性问题
|
||||
|
||||
- 部分同学课堂展示时偏害羞,可以多练习表达
|
||||
- 技术细节介绍可以更丰富
|
||||
|
||||
---
|
||||
|
||||
## 📢 下节课预告
|
||||
|
||||
下学期继续加油!期待看到同学们更多创意作品~🌟
|
||||
|
||||
---
|
||||
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,22 @@
|
||||
# 课程名称:PK总结
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
皓霖家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目文件整理与分类管理
|
||||
2. 作品展示与课堂展示技巧
|
||||
3. 项目说明文档与改进记录的回顾
|
||||
4. 项目介绍的表达能力
|
||||
5. 学期项目总结与反思
|
||||
|
||||
皓霖这节课表现很棒~从学期初文件比较散乱,到现在能把像素对战模拟器、画图工具、特效生成器分类得井井有条,文件管理意识进步很明显~🌟
|
||||
|
||||
最让老师惊喜的是皓霖设计的技能树系统,分成了攻击系、防御系、辅助系、敏捷系四大分支,还有终极技能的设计,说明皓霖对游戏系统有很深的理解,这种系统化思维在以后的学习中会越来越有价值~💡
|
||||
|
||||
课堂展示的时候虽然有点害羞,但还是把自己的作品介绍清楚了,这种勇气值得表扬!要是能在介绍的时候再多说说自己的设计思路就更好啦~😊
|
||||
|
||||
老师会继续关注皓霖的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -141,6 +141,13 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-05 第18课观察
|
||||
- **学期总结课**:展示了整个学期的项目作品,文件分类井井有条(像素对战模拟器、画图工具、特效生成器)
|
||||
- **突出表现**:设计的技能树系统分攻击系、防御系、辅助系、敏捷系四大分支,还有终极技能设计,系统化思维有明显提升
|
||||
- **课堂展示**:虽然有点害羞,但能完整介绍自己的作品,勇气可嘉
|
||||
- **成长对比**:从学期初文件比较散乱,到现在能分类得井井有条,文件管理意识进步明显
|
||||
- **待关注**:课堂展示时可以多分享设计思路,增强表达的丰富性
|
||||
|
||||
### 2026-06-28 第17课观察
|
||||
- **请假回归**:第16课请假后回归课堂,状态积极,一上来就主动参与银色背景色讨论
|
||||
- **积极表现**:主动观察同学作品的鲨鱼技能并发表看法,对游戏机制的探索兴趣浓厚
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# 课程名称:PK总结
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
浩铭家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目文件整理与分类管理
|
||||
2. 作品展示与课堂展示技巧
|
||||
3. 项目说明文档与改进记录的回顾
|
||||
4. 项目介绍的表达能力
|
||||
5. 学期项目总结与反思
|
||||
|
||||
浩铭这节课表现让老师很惊喜~主动上台展示自己的项目,面对大家介绍像素画图工具和像素对战模拟器,声音洪亮、条理清晰,比学期初进步了很多,那时候还会紧张得说不出话,现在已经能完整介绍整个项目了!🌟
|
||||
|
||||
这学期浩铭做了不少作品,每个项目都有完整的说明文档和改进记录,还单独建了"像素回合制PK游戏"文件夹,说明学习越来越系统化了~💡
|
||||
|
||||
浩铭的表达能力一直在持续进步,建议下学期多参加类似的展示机会,把这个优势巩固起来!老师会继续关注浩铭的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -141,6 +141,13 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-05 第18课观察
|
||||
- **学期总结课**:主动上台展示项目,介绍像素画图工具和像素对战模拟器,声音洪亮、条理清晰
|
||||
- **重大进步**:比学期初进步了很多,从紧张得说不出话,到现在能完整介绍整个项目,表达能力提升明显
|
||||
- **学习系统化**:每个项目都有完整的说明文档和改进记录,还单独建了"像素回合制PK游戏"文件夹,学习越来越系统化
|
||||
- **成长对比**:学期初上台会紧张,现在能自信地展示作品,公众表达能力持续进步
|
||||
- **建议**:下学期多参加类似的展示机会,巩固表达优势
|
||||
|
||||
### 2026-06-28 第17课观察
|
||||
- **延续突破**:延续了第16课游戏平衡思维的突破势头,全程跟随老师节奏完成增量文档编写
|
||||
- **精力转化**:精力充沛但有效转化为学习投入,给角色起名"自行车小Q",想象力丰富
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# 课程名称:PK总结
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
翊弘家长好,本周翊弘请假,希望翊弘好好休息,期待下节课回归课堂!💪
|
||||
|
||||
翊弘这学期在像素对战模拟器项目上投入了很多心思,做得很用心~建议翊弘有空的时候可以回顾一下自己这学期最满意的作品,下节课我们可以聊聊这学期的收获和下学期的期待~🌟
|
||||
|
||||
老师会继续关注翊弘的表现,期待下节课见面!🌸😊
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,22 @@
|
||||
# 课程名称:PK总结
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
俊博家长好,本周学习的内容是《PK总结》:
|
||||
1. 项目文件整理与分类管理
|
||||
2. 作品展示与课堂展示技巧
|
||||
3. 项目说明文档与改进记录的回顾
|
||||
4. 项目介绍的表达能力
|
||||
5. 学期项目总结与反思
|
||||
|
||||
俊博这节课表现特别棒~项目文件夹里内容超级丰富,光是项目说明文档就有两份,还做了改进版的对战模拟器,学习态度非常认真!🌟
|
||||
|
||||
最让老师印象深刻的是俊博的像素回合制PK游戏说明文档,超过250行,把属性系统、伤害计算、特技效果、闪避规则都写得清清楚楚,连数值精度要求都想到了,这种严谨细致的态度在编程学习中太珍贵了!💡
|
||||
|
||||
还有中国修仙剑修像素画也迭代了好几个版本,说明俊博对自己的作品要求很高。课堂展示的时候要是能多分享一下文档里的设计思路就更好啦~😊
|
||||
|
||||
老师会继续关注俊博的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -134,6 +134,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-05 第18课观察
|
||||
- **学期总结课**:项目文件夹内容超级丰富,光是说明文档就有两份,还有改进版对战模拟器
|
||||
- **突出表现**:像素回合制PK游戏说明文档超过250行,属性系统、伤害计算、特技效果、闪避规则都写得清清楚楚,连数值精度要求都想到了,严谨细致的态度非常珍贵
|
||||
- **作品迭代**:中国修仙剑修像素画迭代了好几个版本,对自己作品要求很高
|
||||
- **待关注**:课堂展示时可以多分享文档里的设计思路
|
||||
|
||||
### 2026-06-28 第17课观察
|
||||
- **请假回归**:第16课请假后回归课堂,一上课就积极参与功能讨论,提出黄色背景色偏好
|
||||
- **突出表现**:数值计算规范做得极为详细,所有乘除法统一向下取整,严谨细致的习惯在编程学习中非常珍贵
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# AICODE03橙子周日1400班 第18课《涂鸦PK(四)— 班级锦标赛》班级反馈
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
**课程主题**: 涂鸦PK(四)— 班级锦标赛
|
||||
**授课老师**: 橙子
|
||||
|
||||
---
|
||||
|
||||
## 📚 本节课内容
|
||||
|
||||
1. 完成班级对战系统整合
|
||||
2. 举办班级锦标赛
|
||||
3. 项目总结与路演
|
||||
4. 学期总结与回顾
|
||||
5. 作品展示与分享
|
||||
|
||||
---
|
||||
|
||||
## 👥 出勤情况
|
||||
|
||||
| 学生 | 出勤状态 | 备注 |
|
||||
|------|----------|------|
|
||||
| 余浩宸 | ✅ 正常上课 | |
|
||||
| 贺楚悦 | ✅ 正常上课 | |
|
||||
| 吴浩睿 | ❌ 请假 | |
|
||||
| 林俊宇 | ✅ 正常上课 | |
|
||||
| 陈嘉博 | ✅ 补课 | 从周六晚上1900班补课 |
|
||||
|
||||
**出勤率**: 4/5 (80%)
|
||||
|
||||
---
|
||||
|
||||
## 🌟 课堂整体表现
|
||||
|
||||
本节课是涂鸦PK系列的最后一节课,主要完成项目整合、录制介绍视频和学期总结。
|
||||
|
||||
**整体表现**:
|
||||
- 学生们积极整理自己的项目作品,把之前学过的像素画图工具、特效生成器和对战模拟器都整合到了一起
|
||||
- 课堂氛围活跃,学生们认真录制介绍视频,展示自己的作品创意
|
||||
- 大部分学生能完成项目整合和视频录制,作品质量较高
|
||||
|
||||
**亮点学生**:
|
||||
- **贺楚悦**:作品质量获得全班最高认可,增量文档9章节28592字符全班最长,画笔特技设计独特
|
||||
- **林俊宇**:设计了888关冒险模式全班最多,"美人计"特技持续打磨升级至v1.3
|
||||
- **陈嘉博**:虽然是补课,但认真完成所有任务,视频文件162MB全班最大
|
||||
|
||||
**共性问题**:
|
||||
- 部分学生录制视频时声音较小,需要鼓励大胆表达
|
||||
- 个别学生课堂专注力仍需加强
|
||||
|
||||
---
|
||||
|
||||
## 📊 学生表现详情
|
||||
|
||||
### 余浩宸
|
||||
- 积极整理项目作品,整合像素画图工具、特效生成器和对战模拟器
|
||||
- 设计了"不死图腾"复活机制,创意很棒
|
||||
- 录制视频时有点紧张,但勇敢完成
|
||||
- 建议:录制视频时声音再大一点
|
||||
|
||||
### 贺楚悦
|
||||
- 认真整理项目作品,完美整合所有子系统
|
||||
- 增量文档9章节28592字符全班最长,版本管理v1.4规范
|
||||
- 画笔特技"书写任意扣血量"设计独特,逻辑严密
|
||||
- 作品质量获得全班最高认可
|
||||
|
||||
### 吴浩睿
|
||||
- 本周请假,期待下次课继续表现
|
||||
|
||||
### 林俊宇
|
||||
- 安静专注地整理项目作品
|
||||
- 设计了888关冒险模式全班最多,宏大设计超越课堂要求
|
||||
- "美人计"特技持续打磨升级至v1.3,状态冲突处理细致
|
||||
- 建议:课堂上多分享创意想法
|
||||
|
||||
### 陈嘉博(补课)
|
||||
- 认真整理项目作品,4个子项目全部完成
|
||||
- 视频文件162MB全班最大,录制内容详尽
|
||||
- 保持认真踏实的态度,对学习的责任心很珍贵
|
||||
|
||||
---
|
||||
|
||||
## 🎯 课后建议
|
||||
|
||||
1. **复习巩固**:回顾本学期学过的所有知识点,整理自己的作品集
|
||||
2. **创意拓展**:尝试给自己的作品添加更多创意元素
|
||||
3. **分享展示**:把自己的作品分享给家人和朋友,展示学习成果
|
||||
|
||||
---
|
||||
|
||||
## 📝 下节课预告
|
||||
|
||||
下节课将进行学期总结和作品展示,学生们可以分享自己的学习心得和创作体会。
|
||||
|
||||
---
|
||||
|
||||
*班级反馈生成时间:2026年7月5日*
|
||||
*授课老师:橙子*
|
||||
@@ -0,0 +1,18 @@
|
||||
# 课程名称:涂鸦PK(四)— 班级锦标赛
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
浩宸家长好,本周学习的内容是《涂鸦PK(四)— 班级锦标赛》:
|
||||
1. 完成班级对战系统整合
|
||||
2. 举办班级锦标赛
|
||||
3. 项目总结与路演
|
||||
4. 学期总结与回顾
|
||||
5. 作品展示与分享
|
||||
|
||||
浩宸今天表现特别棒~课堂上积极整理自己的项目作品,把之前学过的像素画图工具、特效生成器和对战模拟器都整合到了一起~记得浩宸刚开始学习时,还在摸索像素画的用法,现在已经能独立完成整个对战系统的整合,进步真的很大~自己动手录制介绍视频,虽然有点紧张但还是勇敢地完成了,老师看到了你的成长和勇气~作品创意很棒,设计了"不死图腾"复活机制,被击败后自动复活,最多持有3个,特别有游戏设计感~🎮✨
|
||||
|
||||
看着浩宸从第一节课到现在,一步步掌握了像素画、特效生成、对战系统,老师真的很为你骄傲~要是可以在家练习对着镜子介绍自己的作品,声音再大一点就更好啦~这学期的项目已经完成得很棒啦,如果对游戏设计感兴趣,下学期可以继续探索更复杂的玩法机制,老师期待看到你的新作品!老师会继续关注浩宸的学习旅程,期待在下学期看到更多精彩的作品和创意!加油呀~💪🌟
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -143,6 +143,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-05 第18课观察
|
||||
- 课堂上积极整理项目作品,把像素画图工具、特效生成器和对战模拟器整合到一起
|
||||
- 设计了"不死图腾"复活机制(被击败后自动复活,最多持有3个),创意具有游戏设计感
|
||||
- 自己动手录制介绍视频,虽然有点紧张但勇敢完成
|
||||
- 待改进:录制视频时声音可以再大一点
|
||||
|
||||
### 2026-06-28 第17课观察
|
||||
- 课堂初期分心被提醒后,后半段明显调整进入写作状态,完成了完整增量文档(覆盖7大系统)
|
||||
- "不死图腾"特技延续上节课创意持续打磨(被动复活、最多3个、50%HP恢复),边界情况考虑细致
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# 课程名称:涂鸦PK(四)— 班级锦标赛
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**请假记录**:
|
||||
浩睿家长好,本周学习的内容是《涂鸦PK(四)— 班级锦标赛》:
|
||||
1. 完成班级对战系统整合
|
||||
2. 举办班级锦标赛
|
||||
3. 项目总结与路演
|
||||
4. 学期总结与回顾
|
||||
5. 作品展示与分享
|
||||
|
||||
浩睿本周请假,期待下次课能继续看到他积极好学的表现~
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,18 @@
|
||||
# 课程名称:涂鸦PK(四)— 班级锦标赛
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
俊宇家长好,本周学习的内容是《涂鸦PK(四)— 班级锦标赛》:
|
||||
1. 完成班级对战系统整合
|
||||
2. 举办班级锦标赛
|
||||
3. 项目总结与路演
|
||||
4. 学期总结与回顾
|
||||
5. 作品展示与分享
|
||||
|
||||
俊宇今天表现特别棒~课堂上安静专注地整理自己的项目作品,把像素画图工具、特效生成器和对战模拟器都整合到了一起~自己动手录制介绍视频,声音清晰,讲解详细~作品创意很棒,设计了888关冒险模式——全班最多,分前期1-27关、中期28-500关、后期501-888关三阶段,宏大设计超越课堂要求~"美人计"特技持续打磨升级至v1.3,状态冲突处理细致(冰冻>迷恋>雷电/燃烧优先级链),版本管理规范~
|
||||
|
||||
要是可以在课堂上多分享创意想法就更好啦~老师会继续关注俊宇的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -111,6 +111,13 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-05 第18课观察
|
||||
- 课堂上安静专注地整理项目作品,把像素画图工具、特效生成器和对战模拟器整合到一起
|
||||
- 设计了888关冒险模式全班最多,宏大设计超越课堂要求
|
||||
- "美人计"特技持续打磨升级至v1.3,状态冲突处理细致(冰冻>迷恋>雷电/燃烧优先级链)
|
||||
- 自己动手录制介绍视频,声音清晰,讲解详细
|
||||
- 建议:课堂上多分享创意想法
|
||||
|
||||
### 2026-06-28 第17课观察
|
||||
- 设计了888关冒险模式——全班最多,分前期1-27关、中期28-500关、后期501-888关三阶段,宏大设计超越课堂要求
|
||||
- "美人计"特技持续打磨升级至v1.3,状态冲突处理细致(冰冻>迷恋>雷电/燃烧优先级链),版本管理规范
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# 课程名称:涂鸦PK(四)— 班级锦标赛
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
嘉博家长好,本周学习的内容是《涂鸦PK(四)— 班级锦标赛》:
|
||||
1. 完成班级对战系统整合
|
||||
2. 举办班级锦标赛
|
||||
3. 项目总结与路演
|
||||
4. 学期总结与回顾
|
||||
5. 作品展示与分享
|
||||
|
||||
嘉博今天表现特别棒~虽然是补课,但课堂上认真整理自己的项目作品,把像素画图工具、特效生成器和对战模拟器都完美整合~自己动手录制介绍视频,声音清晰,讲解详细~作品质量很高,4个子项目全部整理完成,视频文件162MB是全班最大的,说明录制内容非常详尽~一直保持认真踏实的态度,对学习的责任心很珍贵~
|
||||
|
||||
老师会继续关注嘉博的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,18 @@
|
||||
# 课程名称:涂鸦PK(四)— 班级锦标赛
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
楚悦家长好,本周学习的内容是《涂鸦PK(四)— 班级锦标赛》:
|
||||
1. 完成班级对战系统整合
|
||||
2. 举办班级锦标赛
|
||||
3. 项目总结与路演
|
||||
4. 学期总结与回顾
|
||||
5. 作品展示与分享
|
||||
|
||||
楚悦今天表现特别棒~课堂上认真整理自己的项目作品,把像素画图工具、特效生成器和对战模拟器都完美整合~自己动手录制介绍视频,声音清晰,讲解详细~作品质量获得全班最高认可,增量文档9章节28592字符全班最长,难度分4阶段、版本管理v1.4规范~画笔特技"书写任意扣血量"设计独特,有输入校验和动画效果,逻辑严密~
|
||||
|
||||
老师会继续关注楚悦的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -144,6 +144,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-05 第18课观察
|
||||
- 课堂上认真整理项目作品,把像素画图工具、特效生成器和对战模拟器完美整合
|
||||
- 作品质量获得全班最高认可,增量文档9章节28592字符全班最长
|
||||
- 画笔特技"书写任意扣血量"设计独特,有输入校验和动画效果,逻辑严密
|
||||
- 自己动手录制介绍视频,声音清晰,讲解详细
|
||||
|
||||
### 2026-06-28 第17课观察
|
||||
- 对战设计被老师用作课堂讨论基准案例,作品质量获得全班最高认可
|
||||
- 主动展示了用AI将小说改编成漫画的跨领域创作作品,课外创作热情高
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# CSP03周六0830班 第18课《总复习——GESP三级真题训练》班级总结
|
||||
|
||||
**授课日期**:2026-07-04
|
||||
**到课**:杨林轩、欧俊宇、谢明泓(3人)
|
||||
**请假**:汪子杰(身体不适)
|
||||
|
||||
---
|
||||
|
||||
## 📚 本节课内容
|
||||
|
||||
1. 掌握双指针算法的核心思想——左右指针向中间推进判断平衡序列
|
||||
2. 学会比较左右总和决定移动哪边指针,判断是否找到平衡点
|
||||
3. 掌握字符串截取(substr)的参数含义——起始位置与截取长度
|
||||
4. 综合应用——拆分字符串并判断两个子串是否均为回文串
|
||||
5. 培养代码调试能力——通过输出中间结果定位逻辑错误
|
||||
|
||||
---
|
||||
|
||||
## 🎯 OJ完成情况
|
||||
|
||||
| 学生 | 平衡序列 | 回文拼接 | 总提交 | 通过率 |
|
||||
|------|----------|----------|--------|--------|
|
||||
| 杨林轩 | ✅ AC(1次) | ✅ AC(1次) | 2次 | 100% |
|
||||
| 欧俊宇 | ✅ AC | ✅ AC | 5次 | 100% |
|
||||
| 谢明泓 | ✅ AC | ✅ AC | 6次 | 100% |
|
||||
| 汪子杰 | — | — | — | 请假 |
|
||||
|
||||
**全班通过率**:3/3 = 100% 🎉
|
||||
|
||||
---
|
||||
|
||||
## 🌟 课堂亮点
|
||||
|
||||
- **杨林轩**:两道题全部一次AC,一气呵成!双指针基本功扎实,课堂互动积极。需要注意在老师讲解时先听完再动手,避免错过关键细节。
|
||||
- **欧俊宇**:一如既往地优秀,理解力强,能主动帮助同学排查代码问题。有调试改进过程,独立排查能力在持续提升。
|
||||
- **谢明泓**:基础扎实,substr参数细节掌握得很清楚。虽然调试次数稍多,但展现了不放弃、反复尝试直到通过的韧劲。
|
||||
- **汪子杰**:请假,后续需补做OJ作业。
|
||||
|
||||
---
|
||||
|
||||
## 📝 共性问题
|
||||
|
||||
- substr第二个参数是"截取长度"而非"结束位置",部分同学容易混淆
|
||||
- 回文串判断中"布尔变量未初始化"和"for循环放错位置"是常见的调试坑点
|
||||
- 拆分回文串时要注意遍历范围:从第二个字符到倒数第二个字符,保证每个子串至少有一个字符
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,32 @@
|
||||
# 课程名称:《总复习——GESP三级真题训练》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
林轩家长好,本周学习的内容是《总复习——GESP三级真题训练》:
|
||||
1. 掌握双指针算法的核心思想——左右指针向中间推进判断平衡序列
|
||||
2. 学会比较左右总和决定移动哪边指针,判断是否找到平衡点
|
||||
3. 掌握字符串截取(substr)的参数含义——起始位置与截取长度
|
||||
4. 综合应用——拆分字符串并判断两个子串是否均为回文串
|
||||
5. 培养代码调试能力——通过输出中间结果定位逻辑错误
|
||||
|
||||
林轩这节课状态在线,课堂互动很积极~老师讲解双指针判断平衡序列时,能跟上思路,对"左边总和小于等于右边就加左边"的核心逻辑理解得不错~
|
||||
|
||||
在拆分回文串这道题上,林轩主动尝试写代码,遇到substr参数拿不准的地方会回头翻看之前的内容找答案,这种主动探索的精神很棒!不过老师发现你在老师还没讲完时就自己往前翻了,有些细节容易错过哦~
|
||||
|
||||
## 【OJ做题数据】
|
||||
|
||||
**A包(课堂练习)完成情况**: 2/2 (共2次提交)
|
||||
|
||||
| 题目 | 类型 | 状态 | 提交次数 | 思考模式 |
|
||||
|------|------|------|----------|----------|
|
||||
| GESP202409C3T3 平衡序列 | GESP三级真题 | ✅ 通过 | 1 | 一气呵成 |
|
||||
| GESP202409C3T4 回文拼接 | GESP三级真题 | ✅ 通过 | 1 | 一气呵成 |
|
||||
|
||||
**📊 分析**: 两道GESP三级真题全部一次AC,非常漂亮!双指针和字符串处理的基本功很扎实。继续保持这种状态,做题前先想清楚思路再落笔,效率会更高~
|
||||
|
||||
希望后续做题时先把老师讲解的思路完整听完再动手,加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -144,6 +144,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04(第18课 总复习——GESP三级真题训练)
|
||||
- **表现**:两道GESP三级真题全部一次AC(共2次提交),双指针和字符串基本功扎实!
|
||||
- **OJ数据**:2/2题全部通过 | 2次提交 | 平衡序列1次AC,回文拼接1次AC
|
||||
- **亮点**:一气呵成型,思路清晰落笔准确;课堂互动积极,遇到不确定的会主动翻看之前内容
|
||||
- **关注点**:老师讲解时偶尔自己往前翻代码,容易错过关键细节;建议先听完再动手
|
||||
|
||||
### 2026-06-27(第17课 GESP真题训练2)
|
||||
- **表现**:满分250分全部通过!编程题「二进制回文串」一次AC,编程功底稳步提升
|
||||
- **OJ数据**:4/4题全部通过 | 总分250/250 | 15次提交(编程题3+1次,选择题9次→30分,判断题2次→20分)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# 课程名称:《总复习——GESP三级真题训练》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
俊宇家长好,本周学习的内容是《总复习——GESP三级真题训练》:
|
||||
1. 掌握双指针算法的核心思想——左右指针向中间推进判断平衡序列
|
||||
2. 学会比较左右总和决定移动哪边指针,判断是否找到平衡点
|
||||
3. 掌握字符串截取(substr)的参数含义——起始位置与截取长度
|
||||
4. 综合应用——拆分字符串并判断两个子串是否均为回文串
|
||||
5. 培养代码调试能力——通过输出中间结果定位逻辑错误
|
||||
|
||||
俊宇今天表现一如既往的优秀~对双指针算法的理解很到位,平衡序列能快速理清核心逻辑,代码编写效率很高~在拆分回文串的练习中,俊宇能主动帮助旁边的同学排查代码问题,互助精神一如既往地棒!
|
||||
|
||||
调试环节中老师带着大家一步步排查"布尔变量未初始化""for循环放错位置"等问题时,俊宇能跟着思路快速定位自己的错误并修复~
|
||||
|
||||
## 【OJ做题数据】
|
||||
|
||||
**A包(课堂练习)完成情况**: 2/2 (共5次提交)
|
||||
|
||||
| 题目 | 类型 | 状态 | 提交次数 | 思考模式 |
|
||||
|------|------|------|----------|----------|
|
||||
| GESP202409C3T3 平衡序列 | GESP三级真题 | ✅ 通过 | — | — |
|
||||
| GESP202409C3T4 回文拼接 | GESP三级真题 | ✅ 通过 | — | 调试改进 |
|
||||
|
||||
**📊 分析**: 两道题全部AC,共5次提交。有一定的调试过程,说明遇到小问题能自己排查改进,调试能力在持续提升!
|
||||
|
||||
以你的能力,如果愿意的话,写完代码可以先自己快速检查一遍再提交,能进一步减少调试次数~加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -143,6 +143,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04(第18课 总复习——GESP三级真题训练)
|
||||
- **表现**:两道GESP三级真题全部AC(共5次提交),有调试改进过程,独立排查能力持续提升
|
||||
- **OJ数据**:2/2题全部通过 | 5次提交 | 调试改进型
|
||||
- **亮点**:双指针算法理解到位,代码效率高;主动帮助同学排查代码问题,互助精神一如既往
|
||||
- **建议**:写完代码先快速自检一遍再提交,可进一步减少调试次数
|
||||
|
||||
### 2026-06-27(第17课 GESP真题训练2)
|
||||
- **表现**:满分250分全部通过!位运算推导(X^X=0、X^0=X、~X=-X-1)理解到位,老师提问时快速给出正确回答
|
||||
- **OJ数据**:4/4题全部通过 | 总分250/250 | 14次提交(编程题1+3次,选择题8次→30分,判断题2次→20分)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# 课程名称:《总复习——GESP三级真题训练》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
**状态**: 请假(身体不适)
|
||||
|
||||
**本节课内容**:
|
||||
1. 双指针算法判断平衡序列(GESP202409C3T3)
|
||||
2. 字符串拆分与回文串判断(GESP202409C3T4)
|
||||
|
||||
两道都是GESP三级真题,恢复后可在OJ上补做(作业ID:6a3e1a6be17a0e56c3901363)。
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -194,3 +194,9 @@
|
||||
---
|
||||
|
||||
*持续更新,见证成长*
|
||||
|
||||
### 2026-07-05(第18课 总复习·补课)
|
||||
- **表现**:来周日1030班补课,学习主动性值得表扬,全程专注听讲
|
||||
- **OJ数据**:2/2 AC(8次提交),遇到CE和RE没有放弃,调试改进型
|
||||
- **亮点**:提交次数虽多但不放弃、反复调试直到通过的态度特别好
|
||||
- **提升方向**:提交前先检查语法细节(分号、括号),减少CE类低级错误
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# 课程名称:《总复习——GESP三级真题训练》
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
明泓家长好,本周学习的内容是《总复习——GESP三级真题训练》:
|
||||
1. 掌握双指针算法的核心思想——左右指针向中间推进判断平衡序列
|
||||
2. 学会比较左右总和决定移动哪边指针,判断是否找到平衡点
|
||||
3. 掌握字符串截取(substr)的参数含义——起始位置与截取长度
|
||||
4. 综合应用——拆分字符串并判断两个子串是否均为回文串
|
||||
5. 培养代码调试能力——通过输出中间结果定位逻辑错误
|
||||
|
||||
明泓这节课学习态度非常认真,基础知识掌握扎实的优势在复习课中体现得很明显~平衡序列的双指针算法一听就懂,代码写得又快又稳,之前的积累都在发挥作用~
|
||||
|
||||
拆分回文串这道题上,明泓对substr的用法掌握得很好,知道第二个参数是截取长度而不是结束下标——这个细节很多同学容易混淆,明泓理解得很清楚!跟着老师调试时能主动复盘,这种学习习惯值得保持~
|
||||
|
||||
## 【OJ做题数据】
|
||||
|
||||
**A包(课堂练习)完成情况**: 2/2 (共6次提交)
|
||||
|
||||
| 题目 | 类型 | 状态 | 提交次数 | 思考模式 |
|
||||
|------|------|------|----------|----------|
|
||||
| GESP202409C3T3 平衡序列 | GESP三级真题 | ✅ 通过 | — | — |
|
||||
| GESP202409C3T4 回文拼接 | GESP三级真题 | ✅ 通过 | — | 耐心调试 |
|
||||
|
||||
**📊 分析**: 两道题全部AC,共6次提交。虽然调试次数稍多,但展现了不放弃、反复尝试直到通过的韧劲!建议写完代码后先在本地检查一遍逻辑再提交OJ,能减少不必要的提交次数~
|
||||
|
||||
继续保持踏实认真的学习态度,把每节课的易错点记在本子上,基础会越来越扎实~加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -130,6 +130,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-04(第18课 总复习——GESP三级真题训练)
|
||||
- **表现**:两道GESP三级真题全部AC(共6次提交),展现了不放弃反复调试的韧劲
|
||||
- **OJ数据**:2/2题全部通过 | 6次提交 | 耐心调试型
|
||||
- **亮点**:基础扎实,substr参数细节理解到位(截取长度 vs 结束下标);跟着老师思路主动复盘,学习习惯好
|
||||
- **建议**:尝试写完代码先在本地检查一遍逻辑再提交OJ,减少不必要的提交次数
|
||||
|
||||
### 2026-06-27(第17课 GESP真题训练2)
|
||||
- **表现**:满分250分全部通过!提交次数仅7次,全班最高效🏆
|
||||
- **OJ数据**:4/4题全部通过 | 总分250/250 | 7次提交(编程题1+3次,选择题2次→30分,判断题1次→20分)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# CSP03橙子周六1400 · 第18课《总复习》班级反馈
|
||||
|
||||
**授课日期**:2026-07-04
|
||||
**授课时间**:14:00-15:30
|
||||
**出勤**:到场4人(含补课1人),请假2人
|
||||
|
||||
---
|
||||
|
||||
## 📋 本节课内容
|
||||
|
||||
本节课为期末总复习课,通过两道OJ综合题串联本学期核心知识点:
|
||||
|
||||
1. 平衡序列的判断——枚举法实现
|
||||
2. 双指针法解决平衡序列问题:O(n²)优化到O(n)
|
||||
3. 算法时间复杂度优化与调试:TLE→AC的优化过程
|
||||
4. 回文拼接的判断:substr()+回文判断
|
||||
5. 综合复习:数组遍历、字符串截取、枚举思想、双指针
|
||||
|
||||
---
|
||||
|
||||
## 📊 OJ数据总览
|
||||
|
||||
作业包:`6a3e1a6be17a0e56c3901363`
|
||||
题目:GESP202409C3T3 平衡序列 + GESP202409C3T4 回文拼接
|
||||
|
||||
| 学生 | T3 平衡序列 | 提交次数 | T4 回文拼接 |
|
||||
|------|------------|----------|------------|
|
||||
| 魏铭轩 | ✅ AC(100) | 2次 (TLE→AC) | 未提交 |
|
||||
| 苏俊宇 | ✅ AC(100) | 1次 | 未提交 |
|
||||
| 卢华琛 | ✅ AC(100) | 3次 (WA→WA→AC) | 未提交 |
|
||||
| 潘沐辰(补) | ✅ AC(100) | 1次 | 未提交 |
|
||||
| 郑子煜 | 请假 | — | — |
|
||||
| 张雨禾 | 请假 | — | — |
|
||||
|
||||
---
|
||||
|
||||
## 🌟 课堂亮点
|
||||
|
||||
- **潘沐辰**(补课):主动提出枚举解法被老师采用为教学示范,思维活跃,课堂参与度最高
|
||||
- **苏俊宇**:提出"为什么R等于N"的好问题,体现深度思考
|
||||
- **魏铭轩**:经历了TLE→AC的优化过程,从枚举法超时到双指针通过,进步明显
|
||||
|
||||
## ⚠️ 共性问题
|
||||
|
||||
- T4回文拼接无人提交,课堂时间有限,建议学生课后补做
|
||||
- 从"理解思路"到"独立写出代码"之间仍有距离,需要多动手练习
|
||||
- 卢华琛中途有走神现象,需关注专注力
|
||||
|
||||
---
|
||||
|
||||
*穹狼科创 · CSP03班 · 橙子老师*
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
华琛家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断——枚举法实现:枚举每个分界点I,分别计算左边总和与右边总和,判断是否相等
|
||||
2. 双指针法解决平衡序列问题:使用左指针L和右指针R,轻的一端加元素向中间逼近,将时间复杂度从O(n²)优化到O(n)
|
||||
3. 算法时间复杂度优化与调试:从枚举法超时(TLE)到双指针法AC的优化过程
|
||||
4. 回文拼接的判断:使用substr()截取左右子串,分别判断两个子串是否为回文串
|
||||
5. 综合复习:数组遍历、字符串截取、枚举思想、双指针等本学期知识的综合运用
|
||||
|
||||
华琛能安静坐住,态度平和,在新班级中逐渐适应了节奏~对字符遍历和字符串截取的基础概念掌握得不错,老师提问的时候也能跟着回答,说明听讲状态基本在线😊
|
||||
|
||||
不过这节复习课内容密度比较大,老师注意到华琛中途有几次走神,需要提醒才能重新集中注意力。复习课的节奏快、知识点串联多,一走神就容易跟不上后面的内容。
|
||||
|
||||
📊 OJ做题情况:
|
||||
- T3 平衡序列:✅ AC(3次提交:WA→WA→AC),虽然前两次答案有误,但没有放弃,第三次调试成功,这份坚持值得肯定!
|
||||
- T4 回文拼接:未提交(课堂时间有限,建议课后补做)
|
||||
|
||||
希望华琛下节课能主动往前排坐,减少外界干扰,上课专注力再好一点~老师相信随着慢慢适应新班级,华琛会越来越好的!加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -163,6 +163,12 @@
|
||||
- **状态评估**:新班级适应良好,有耐心调代码不轻易放弃
|
||||
- **建议**:家长多鼓励课上有不懂就举手问,课后每天花10分钟翻看笔记
|
||||
|
||||
### 2026-07-04(第18课 总复习)
|
||||
- **课堂表现**:在新班级逐渐适应,能安静坐住、态度平和,对字符遍历和字符串截取基础概念掌握不错
|
||||
- **需关注**:复习课内容密度大,中途有几次走神需要老师提醒才能集中注意力
|
||||
- **OJ表现**:T3平衡序列 AC(3次:WA→WA→AC),虽然前两次答案有误但没有放弃,调试后成功通过,坚持值得肯定!T4未提交
|
||||
- **建议**:主动往前排坐减少干扰,课后补做T4回文拼接
|
||||
|
||||
---
|
||||
|
||||
*持续更新,见证成长*
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**状态**:请假
|
||||
|
||||
雨禾家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断——枚举法实现
|
||||
2. 双指针法解决平衡序列问题:O(n²)优化到O(n)
|
||||
3. 算法时间复杂度优化与调试
|
||||
4. 回文拼接的判断:substr()+回文判断
|
||||
5. 综合复习:数组、字符串、枚举、双指针等知识
|
||||
|
||||
雨禾本周请假,未能参加第18课《总复习》的学习。本节课通过两道OJ综合题(平衡序列 + 回文拼接)串联了本学期多个核心知识点,是期末复习的重要一课。
|
||||
|
||||
雨禾的基础比较扎实,建议在家抽空在OJ上补做这两道题,特别是双指针优化和字符串substr()的使用,巩固一下本学期的重点内容。期待雨禾下周回归课堂!😊
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -220,3 +220,9 @@
|
||||
---
|
||||
|
||||
*持续更新,见证成长*
|
||||
|
||||
### 2026-07-05(第18课 总复习·补课)
|
||||
- **表现**:来周日1030班补课,执行力一如既往地强,全程专注不分心
|
||||
- **OJ数据**:2/2 AC(6次提交),遇到CE能自己排查修改,调试能力在线
|
||||
- **亮点**:比同班补课同学少2次提交,吸收效率更高
|
||||
- **提升方向**:课后记得花10-15分钟翻笔记巩固,一周不复习容易忘
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
俊宇家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断——枚举法实现:枚举每个分界点I,分别计算左边总和与右边总和,判断是否相等
|
||||
2. 双指针法解决平衡序列问题:使用左指针L和右指针R,轻的一端加元素向中间逼近,将时间复杂度从O(n²)优化到O(n)
|
||||
3. 算法时间复杂度优化与调试:从枚举法超时(TLE)到双指针法AC的优化过程
|
||||
4. 回文拼接的判断:使用substr()截取左右子串,分别判断两个子串是否为回文串
|
||||
5. 综合复习:数组遍历、字符串截取、枚举思想、双指针等本学期知识的综合运用
|
||||
|
||||
俊宇上课认真专注,紧跟老师节奏,态度非常积极👍还主动提出了一个好问题——"为什么R等于N",说明在认真思考双指针的初始值设定,这种刨根问底的精神很可贵💡
|
||||
|
||||
俊宇的数学基础好,在理解算法逻辑时有明显优势,枚举法和双指针的核心思路都能跟上。但目前最大的瓶颈是"知道思路但写不出来"——理解了不代表能实现,代码实现能力是必须通过大量动手练习才能提升的。
|
||||
|
||||
📊 OJ做题情况:
|
||||
- T3 平衡序列:✅ AC(1次提交,一气呵成!),思路清晰,一次就写对了,说明理解力很强
|
||||
- T4 回文拼接:未提交(课堂时间有限,建议课后补做)
|
||||
|
||||
希望俊宇课后多花时间动手敲代码,每道题至少独立写2-3遍,把"想得通"变成"写得顺",这样才能真正把知识内化成自己的能力!加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -214,6 +214,12 @@
|
||||
- **状态评估**:概念理解在稳步加深,下一步重点是代码实现——「能独立写出来才是真正的掌握」
|
||||
- **建议**:本周完成1道编程题,把"想到了"变成"写出来了"
|
||||
|
||||
### 2026-07-04(第18课 总复习)
|
||||
- **课堂表现**:上课认真专注,紧跟老师节奏,态度积极;提出好问题"为什么R等于N",对双指针初始值有深入思考
|
||||
- **OJ表现**:T3平衡序列 AC(1次提交,一气呵成),数学基础和逻辑思维在算法题中继续发挥优势,T4未提交
|
||||
- **提升方向**:代码实现能力仍是瓶颈——"会想但写得慢",课后需要多动手把"想得通"变成"写得顺"
|
||||
- **建议**:课后补做T4回文拼接,每道题至少独立写2-3遍
|
||||
|
||||
---
|
||||
|
||||
*持续更新,见证成长*
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**备注**:补课(来自其他老师班级)
|
||||
|
||||
**课评内容**:
|
||||
|
||||
沐辰家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断——枚举法实现:枚举每个分界点I,分别计算左边总和与右边总和,判断是否相等
|
||||
2. 双指针法解决平衡序列问题:使用左指针L和右指针R,轻的一端加元素向中间逼近,将时间复杂度从O(n²)优化到O(n)
|
||||
3. 算法时间复杂度优化与调试:从枚举法超时(TLE)到双指针法AC的优化过程
|
||||
4. 回文拼接的判断:使用substr()截取左右子串,分别判断两个子串是否为回文串
|
||||
5. 综合复习:数组遍历、字符串截取、枚举思想、双指针等本学期知识的综合运用
|
||||
|
||||
沐辰这节课是来我们班补课的,但课堂表现特别亮眼——主动提出了平衡序列问题的枚举解法,老师采用了沐辰的思路作为教学示范,给全班同学展示了一遍枚举法的完整实现过程🌟虽然枚举法最终因为时间复杂度O(n²)导致了超时,但思路完全正确,老师借这个机会引出了双指针优化的方法,沐辰的贡献成了本节课最精彩的教学切入点!
|
||||
|
||||
沐辰的逻辑思维很强,敢于表达自己的想法,这种主动思考的习惯非常珍贵💡老师一个学期都未必能遇到几个这么积极动脑的学生。
|
||||
|
||||
📊 OJ做题情况:
|
||||
- T3 平衡序列:✅ AC(1次提交,一气呵成!),思路清晰代码也写得漂亮
|
||||
- T4 回文拼接:未提交(课堂时间有限,建议课后补做)
|
||||
|
||||
希望沐辰继续保持这种主动思考和表达的劲头,多练习代码实现让想法落地得更快!加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,19 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**状态**:请假
|
||||
|
||||
子煜家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断——枚举法实现
|
||||
2. 双指针法解决平衡序列问题:O(n²)优化到O(n)
|
||||
3. 算法时间复杂度优化与调试
|
||||
4. 回文拼接的判断:substr()+回文判断
|
||||
5. 综合复习:数组、字符串、枚举、双指针等知识
|
||||
|
||||
子煜本周请假,未能参加第18课《总复习》的学习。本节课通过两道OJ综合题(平衡序列 + 回文拼接)串联了本学期多个核心知识点,是期末复习的重要一课。
|
||||
|
||||
建议子煜在家抽时间回顾一下枚举法和双指针法的基本思路,可以在OJ上补做这两道题,为后续学习做好准备。期待子煜下周回归课堂!😊
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
铭轩家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断——枚举法实现:枚举每个分界点I,分别计算左边总和与右边总和,判断是否相等
|
||||
2. 双指针法解决平衡序列问题:使用左指针L和右指针R,轻的一端加元素向中间逼近,将时间复杂度从O(n²)优化到O(n)
|
||||
3. 算法时间复杂度优化与调试:从枚举法超时(TLE)到双指针法AC的优化过程
|
||||
4. 回文拼接的判断:使用substr()截取左右子串,分别判断两个子串是否为回文串
|
||||
5. 综合复习:数组遍历、字符串截取、枚举思想、双指针等本学期知识的综合运用
|
||||
|
||||
铭轩这节课状态在线,是班里互动最活跃的同学~对双指针法和枚举法的理解都不错,能主动提问循环条件和边界处理等细节问题,说明听课的时候在认真思考💡
|
||||
|
||||
这学期铭轩的进步非常大,从之前的基础薄弱到现在能跟上复习课的节奏,老师看在眼里很欣慰✨不过课堂上话有点多,有时会聊到和编程无关的话题,老师也提醒过不要直接抄代码,要自己先动手尝试。
|
||||
|
||||
📊 OJ做题情况:
|
||||
- T3 平衡序列:✅ AC(2次提交:TLE→AC),第一次用枚举法超时了,第二次优化后通过,经历了从"超时"到"AC"的完整优化过程,这种TLE→AC的进步比一次过更有价值!
|
||||
- T4 回文拼接:未提交(课堂时间有限,建议课后补做)
|
||||
|
||||
希望铭轩在保持这份学习热情的同时,把更多精力放在独立思考上——先自己想、自己写,实在卡住了再参考代码,这样进步会更快!加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -213,6 +213,13 @@
|
||||
- **状态评估**:聪明头脑是优势,需要把聪明更聚焦在课堂内容上,少谈论游戏
|
||||
- **建议**:编程第二题《小松找玩具》课后抽20分钟独立完成
|
||||
|
||||
### 2026-07-04(第18课 总复习)
|
||||
- **课堂表现**:依旧是班里互动最活跃的同学,对双指针法和枚举法的理解不错,主动提问循环条件和边界处理细节
|
||||
- **需关注**:话多的问题延续,聊到和编程无关话题(游戏),老师提醒不要直接抄代码
|
||||
- **OJ表现**:T3平衡序列 AC(2次:TLE→AC),经历了从枚举法超时到双指针优化的完整过程,T4未提交
|
||||
- **亮点**:TLE→AC的优化过程体现了一定的调试和改进意识,比一次AC更有价值
|
||||
- **建议**:课后补做T4回文拼接,独立思考后再参考代码
|
||||
|
||||
---
|
||||
|
||||
*持续更新,见证成长*
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# CSP03橙子周日1030班 · 第18课《总复习》班级反馈
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
**课程名称**: 总复习
|
||||
**出勤人数**: 2人(王佳琳、唐钎宸)
|
||||
|
||||
---
|
||||
|
||||
## 📚 本节课知识点
|
||||
|
||||
1. 平衡序列的判断:使用双指针法,左边总和与右边总和比较,向中间靠拢
|
||||
2. 前缀和的灵活运用:通过累加左右两边的和来逐步逼近平衡点
|
||||
3. 字符串回文串的判断:使用双指针验证字符串是否正反读相同
|
||||
4. 回文串拼接问题的分析:寻找分界点,前后两段分别验证回文
|
||||
5. 综合问题拆解能力:先读题理解输入输出格式,再选择合适算法
|
||||
|
||||
---
|
||||
|
||||
## 📊 整体表现
|
||||
|
||||
本节课是GESP三级考前总复习,重点讲解了两道真题:平衡序列(双指针+前缀和)和回文串拼接判断。
|
||||
|
||||
**OJ完成情况**:2人全部2/2 AC通过,复习效果很好!
|
||||
|
||||
**课堂亮点**:
|
||||
- 王佳琳:专注力一如既往地好,安静听讲认真跟课,调试能力有进步
|
||||
- 唐钎宸:课堂互动非常积极,对双指针思路理解快,参与感越来越强
|
||||
|
||||
**待改进**:
|
||||
- 佳琳需要更勇敢地举手提问,培养主动表达的习惯
|
||||
- 钎宸后半段注意力需要更集中,把活跃的思考力用在代码优化上
|
||||
|
||||
---
|
||||
|
||||
## 🏠 家长配合建议
|
||||
|
||||
1. 让孩子用生活中的例子(如天平称重)讲解双指针法,巩固知识点
|
||||
2. 鼓励孩子遇到不懂的问题先尝试自己调试5分钟,再提问
|
||||
|
||||
---
|
||||
|
||||
*橙子老师 · 2026-07-05*
|
||||
@@ -0,0 +1,25 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
|
||||
钎宸家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断:使用双指针法,左边总和与右边总和比较,向中间靠拢
|
||||
2. 前缀和的灵活运用:通过累加左右两边的和来逐步逼近平衡点
|
||||
3. 字符串回文串的判断:使用双指针验证字符串是否正反读相同
|
||||
4. 回文串拼接问题的分析:寻找分界点,前后两段分别验证回文
|
||||
5. 综合问题拆解能力:先读题理解输入输出格式,再选择合适算法
|
||||
|
||||
钎宸这节课课堂互动特别积极!对左右指针往中间走、谁小加谁的算法逻辑理解得很快,也能跟着老师的思路分析回文串拼接的分界点位置,参与感越来越强~
|
||||
|
||||
✅ **本次OJ做题:2道题全部通过**,做题能力在线!和上节课相比,钎宸最大的变化就是越来越敢表达了,这是非常珍贵的进步~
|
||||
|
||||
后半段钎宸的思路有些发散,这说明他在思考更多东西。如果能把这份活跃的思考力用在代码优化上,相信你能做出更棒的成绩!
|
||||
|
||||
**🏠 家长配合建议**:回家后可以让孩子用生活中的例子(比如天平称重)给您解释双指针法,既能巩固也能锻炼逻辑表达。
|
||||
|
||||
老师会继续陪着钎宸一起进步,期待下次看到你不仅能回答问题,还能主动提出自己的解法!加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -186,3 +186,10 @@
|
||||
---
|
||||
|
||||
*持续更新,见证成长*
|
||||
|
||||
### 2026-07-05(第18课 总复习)
|
||||
- **表现**:课堂互动非常积极,对双指针谁小加谁的算法逻辑理解很快,参与感越来越强
|
||||
- **OJ数据**:2/2 AC(4次提交),两道GESP三级真题全部通过
|
||||
- **亮点**:和上节课相比越来越敢表达,这是非常珍贵的进步
|
||||
- **问题**:后半段思路有些发散,注意力需要更集中
|
||||
- **提升方向**:把活跃的思考力用在代码优化上,争取不仅能回答问题还能主动提出解法
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
|
||||
佳琳家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断:使用双指针法,左边总和与右边总和比较,向中间靠拢
|
||||
2. 前缀和的灵活运用:通过累加左右两边的和来逐步逼近平衡点
|
||||
3. 字符串回文串的判断:使用双指针验证字符串是否正反读相同
|
||||
4. 回文串拼接问题的分析:寻找分界点,前后两段分别验证回文
|
||||
5. 综合问题拆解能力:先读题理解输入输出格式,再选择合适算法
|
||||
|
||||
佳琳这节课专注力一如既往地好,全程安静听讲,在老师讲解平衡序列的双指针思路时能够认真跟上~这个概念比较抽象,佳琳通过老师的例子逐步理解了过来,掌握得很扎实!
|
||||
|
||||
✅ **本次OJ做题:2道题全部通过**,完成质量很好!佳琳不是一次就写对的,而是发现错误后能自己调整改进,这种调试能力比直接做对更珍贵~
|
||||
|
||||
**🏠 家长配合建议**:回家后可以让孩子给您讲讲双指针谁小加谁的思路,既能巩固知识点,也能锻炼表达能力。
|
||||
|
||||
老师会继续关注佳琳的表现,希望能看到你更勇敢地举手提问!加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -174,3 +174,10 @@
|
||||
---
|
||||
|
||||
*持续更新,见证成长*
|
||||
|
||||
### 2026-07-05(第18课 总复习)
|
||||
- **表现**:专注力一如既往地好,全程安静听讲,在老师讲解平衡序列的双指针思路时能够认真跟上
|
||||
- **知识点掌握**:对数组下标从1开始存储的概念通过例子逐步理解,掌握扎实
|
||||
- **OJ数据**:2/2 AC(4次提交),两道GESP三级真题全部通过,调试改进型
|
||||
- **亮点**:不是一次写对而是发现错误后能自己调整改进,调试能力有进步
|
||||
- **提升方向**:需要更勇敢地举手提问,培养主动表达的习惯
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
**补课来源**: CSP03橙子周六1400班
|
||||
|
||||
**课评内容**:
|
||||
|
||||
雨禾家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断:使用双指针法,左边总和与右边总和比较,向中间靠拢
|
||||
2. 前缀和的灵活运用:通过累加左右两边的和来逐步逼近平衡点
|
||||
3. 字符串回文串的判断:使用双指针验证字符串是否正反读相同
|
||||
4. 回文串拼接问题的分析:寻找分界点,前后两段分别验证回文
|
||||
5. 综合问题拆解能力:先读题理解输入输出格式,再选择合适算法
|
||||
|
||||
雨禾专门从周六班来补这节总复习课,执行力一如既往地强!上课全程专注不分心,对双指针法的思路理解得很快,在老师讲解平衡序列时能跟上节奏~
|
||||
|
||||
✅ **本次OJ做题:2道题全部通过**,共6次提交,遇到编译错误能自己排查修改,调试能力在线!比子杰少了2次提交,说明对知识点的吸收效率更高一些~
|
||||
|
||||
**🏠 家长配合建议**:回家后记得花10-15分钟翻一下今天的笔记,把双指针和回文串判断的代码模板记牢,一周不复习容易忘哦。
|
||||
|
||||
雨禾的认真态度和执行力一直都很棒,继续保持!加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,24 @@
|
||||
# 课程名称:总复习
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
**补课来源**: CSP03橙子周六0830班
|
||||
|
||||
**课评内容**:
|
||||
|
||||
子杰家长好,本周学习的内容是《总复习》:
|
||||
1. 平衡序列的判断:使用双指针法,左边总和与右边总和比较,向中间靠拢
|
||||
2. 前缀和的灵活运用:通过累加左右两边的和来逐步逼近平衡点
|
||||
3. 字符串回文串的判断:使用双指针验证字符串是否正反读相同
|
||||
4. 回文串拼接问题的分析:寻找分界点,前后两段分别验证回文
|
||||
5. 综合问题拆解能力:先读题理解输入输出格式,再选择合适算法
|
||||
|
||||
子杰专门从周六班来补这节总复习课,学习主动性值得表扬!上课全程专注听讲,对双指针谁小加谁的算法逻辑能够跟上老师的讲解节奏~本学期态度转变非常大,从之前的傲气到现在的虚心求学,这份成长比什么都珍贵!
|
||||
|
||||
✅ **本次OJ做题:2道题全部通过**,共8次提交,遇到编译错误和运行错误没有放弃,调试改进能力有明显进步!虽然提交次数多一些,但遇到问题不放弃、反复调试直到通过的态度特别好,这正是编程学习中最宝贵的品质~
|
||||
|
||||
**🏠 家长配合建议**:回家后可以让孩子把双指针的思路用纸笔画一画,左边指针和右边指针分别怎么走,画清楚了代码就容易写了。
|
||||
|
||||
以子杰现在的态度和专注,老师相信你会越来越好!加油呀!💪✨
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,52 @@
|
||||
# K4橙子周五1900 · 第18课《期末测试》班级反馈
|
||||
|
||||
**日期**:2026年7月3日 19:00-20:30
|
||||
**出勤**:4/4人(全部到齐)
|
||||
|
||||
---
|
||||
|
||||
## 📊 测试成绩概览
|
||||
|
||||
| 学生 | 等级 | 亮点 | 改进方向 |
|
||||
|------|------|------|----------|
|
||||
| 郭艺嘉 | A+ | 全班最高分,各知识点掌握扎实 | 列表题粗心失分 |
|
||||
| 彭煜腾 | A | 独立完成,考试心态沉稳 | 列表题审题粗心 |
|
||||
| 陈圆振 | B+ | 全程独立完成,基础扎实 | 检查习惯需培养 |
|
||||
| 王晨语 | B+ | 操作题全对,克服畏难情绪 | 自信心需增强 |
|
||||
|
||||
---
|
||||
|
||||
## 📚 测试内容覆盖
|
||||
|
||||
1. 列表的基本操作:添加、删除、查询元素及列表长度
|
||||
2. 条件判断与分支嵌套结构
|
||||
3. 循环结构与变量组合
|
||||
4. 字符串操作:字符位置获取、拼接
|
||||
5. 综合项目分析与独立完成
|
||||
|
||||
---
|
||||
|
||||
## 🌟 整体情况
|
||||
|
||||
本节课是期末测试,4位同学全部到课。考试分为选择题、填空题和操作题三部分,覆盖了本学期列表、条件判断、循环结构、字符串操作等核心知识点。
|
||||
|
||||
**整体表现**:全班同学都能独立完成试卷,知识掌握情况良好。共性问题是在列表相关题目上的粗心失分,3位同学在列表题上有因审题不仔细导致的失误,后续需加强细节检查和审题习惯的培养。
|
||||
|
||||
**特别表扬**:
|
||||
- 艺嘉取得A+全班最高分,展现了扎实的综合能力
|
||||
- 晨语从"不愿做"到"操作题全对",课堂转变令人惊喜
|
||||
- 煜腾考试心态比之前沉稳很多,进步明显
|
||||
- 圆振基础扎实,理解力不错
|
||||
|
||||
---
|
||||
|
||||
## 🏠 假期建议
|
||||
|
||||
本学期Kitten课程已结束,建议同学们假期可以:
|
||||
1. 用自己的创意做一个小作品,保持编程手感
|
||||
2. 遇到有趣的编程项目可以自己尝试复现
|
||||
3. 期待下学期见到更棒的你们!
|
||||
|
||||
---
|
||||
|
||||
*K4橙子周五1900班 · 橙子老师*
|
||||
@@ -0,0 +1,23 @@
|
||||
# 课程名称:期末测试
|
||||
|
||||
**授课日期**: 2026-07-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
煜腾家长好,本周学习的内容是《期末测试》:
|
||||
1. 列表的基本操作:添加、删除、查询元素及列表长度的综合运用
|
||||
2. 条件判断与分支嵌套结构:if-else嵌套、多条件判断的逻辑设计
|
||||
3. 循环结构与变量组合:重复执行、变量增减在动画和计时场景中的应用
|
||||
4. 字符串操作:字符位置获取、字符串拼接与处理
|
||||
5. 综合项目分析与独立完成:审题、拆解、调试的全流程能力考核
|
||||
|
||||
煜腾在期末测试中取得了A等的优异成绩!凭借扎实的逻辑思维和独立完成能力,整张试卷完成得又快又好,展现了这学期积累的深厚功底👍
|
||||
|
||||
唯一失分的地方是一道关于列表的选择题,不是因为不会,而是审题时稍微急了一点,粗心导致选错了~以你的能力这道题完全在掌握范围内,有点可惜😊
|
||||
|
||||
整体来看,煜腾这学期的进步非常明显!不仅知识点掌握扎实,考试心态也比之前沉稳了很多,不再像之前那样急躁~老师特别为你感到骄傲!继续保持这份认真,你会越来越棒!🌟💪
|
||||
|
||||
**等级**:A
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -144,6 +144,12 @@
|
||||
|
||||
## 📈 成长记录
|
||||
|
||||
### 2026-07-03(第18课·期末测试)
|
||||
- **测试等级**:A
|
||||
- **表现**:独立快速完成试卷,逻辑思维和学习能力突出。仅错一道列表选择题,原因是审题粗心而非不会。考试心态比之前沉稳很多,不再急躁。
|
||||
- **关键观察**:本学期耐心方面进步明显,从"追求速度"到"沉稳完成"。粗心丢分是小问题,能力完全没问题。
|
||||
- **评语风格**:鼓励型
|
||||
|
||||
### 2026-05-20(评语风格调整)
|
||||
- **风格调整**:从"激励型为主"调整为"鼓励型为主",用真诚肯定和温和引导代替"挑战耐心、追求极致"式表述,保护学习兴趣和热情
|
||||
- **核心不变**:继续肯定聪明和独立能力,温和引导耐心
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# 课程名称:期末测试
|
||||
|
||||
**授课日期**: 2026-07-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
晨语家长好,本周学习的内容是《期末测试》:
|
||||
1. 列表的基本操作:添加、删除、查询元素及列表长度的综合运用
|
||||
2. 条件判断与分支嵌套结构:if-else嵌套、多条件判断的逻辑设计
|
||||
3. 循环结构与变量组合:重复执行、变量增减在动画和计时场景中的应用
|
||||
4. 字符串操作:字符位置获取、字符串拼接与处理
|
||||
5. 综合项目分析与独立完成:审题、拆解、调试的全流程能力考核
|
||||
|
||||
晨语在期末测试中给了老师一个很大的惊喜!一开始他说不愿意做试卷,但在老师的鼓励和奖励激励下,他不仅把整张试卷做完了,而且操作题完成得相当出色,全部做对了👍🎉
|
||||
|
||||
这说明晨语的动手能力和编程思维是完全没有问题的~只要他愿意静下心来做,完全有能力独立完成!操作题全对这个成绩,证明这学期学到的知识点他其实都掌握了~
|
||||
|
||||
老师特别想表扬的是,晨语从"不想做"到"做完了还全对"这个转变,说明他内心是有能力的,只是有时候需要一点动力和信心~相信下学期你会更有自信,从一开始就展现出真正的实力!继续加油!🌈💪
|
||||
|
||||
**等级**:B+
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -93,6 +93,12 @@
|
||||
|
||||
## 📝 成长记录
|
||||
|
||||
### 2026-07-03(第18课·期末测试)
|
||||
- **测试等级**:B+
|
||||
- **表现**:课堂转变令人惊喜——一开始说不想做,在老师鼓励和奖励激励下,不仅做完试卷,操作题还全部做对!动手能力和编程思维完全没问题。
|
||||
- **关键观察**:能力是有的,只是需要动力和信心。这次"从不愿做到全对"的转变说明他内心有实力,自信心增强后表现会更好。独立完成能力比之前有提升。
|
||||
- **评语风格**:鼓励型
|
||||
|
||||
### 2026-03-28
|
||||
- **记录**:本周学习《源码精灵之战》,想法特别多,做了一个"地龙大战雷电猴"的作品,非常有创意!把两种不同的元素组合在一起,形成精彩的对抗场景。思维活跃,创意无限。
|
||||
- **评语风格**:鼓励型
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# 课程名称:期末测试
|
||||
|
||||
**授课日期**: 2026-07-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
艺嘉家长好,本周学习的内容是《期末测试》:
|
||||
1. 列表的基本操作:添加、删除、查询元素及列表长度的综合运用
|
||||
2. 条件判断与分支嵌套结构:if-else嵌套、多条件判断的逻辑设计
|
||||
3. 循环结构与变量组合:重复执行、变量增减在动画和计时场景中的应用
|
||||
4. 字符串操作:字符位置获取、字符串拼接与处理
|
||||
5. 综合项目分析与独立完成:审题、拆解、调试的全流程能力考核
|
||||
|
||||
艺嘉在期末测试中表现非常出色,取得了A+的优异成绩,是全班最高分!整张试卷完成质量很高,对各个知识点都有扎实的掌握👏🎉
|
||||
|
||||
唯一失分的是一道关于列表的选择题,同样是粗心导致的小失误~但整体来看,无论是选择题的判断力还是操作题的动手能力,艺嘉都展现了这学期最好的状态!
|
||||
|
||||
不过老师还是要提醒一下,测试过程中偶尔会沉浸在屏幕里忘记听讲题节奏~如果能把这个小习惯调整过来,凭你的思维能力和学习热情,下学期的表现会更加惊艳!老师非常看好你!🚀✨
|
||||
|
||||
**等级**:A+(全班最高分)
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -94,6 +94,12 @@
|
||||
|
||||
## 📝 成长记录
|
||||
|
||||
### 2026-07-03(第18课·期末测试)
|
||||
- **测试等级**:A+(全班最高分)
|
||||
- **表现**:整张试卷完成质量很高,选择题判断力和操作题动手能力都很出色,各知识点掌握扎实。仅错一道列表选择题,属粗心失误。
|
||||
- **关键观察**:综合能力是全班最强的,思维活跃学得快。测试中仍有沉浸在屏幕里忘记听讲题节奏的情况,后续需继续调整。
|
||||
- **评语风格**:鼓励型
|
||||
|
||||
### 2026-03-28
|
||||
- **记录**:本周学习《源码精灵之战》,在说到格斗运动时主动和老师分享和哥哥练习飞毛腿的故事,说得眉飞色辩很开心。对单分支嵌套知识点掌握不错。坐姿不太好,提醒后能坐好。
|
||||
- **评语风格**:鼓励型
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# 课程名称:期末测试
|
||||
|
||||
**授课日期**: 2026-07-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
圆振家长好,本周学习的内容是《期末测试》:
|
||||
1. 列表的基本操作:添加、删除、查询元素及列表长度的综合运用
|
||||
2. 条件判断与分支嵌套结构:if-else嵌套、多条件判断的逻辑设计
|
||||
3. 循环结构与变量组合:重复执行、变量增减在动画和计时场景中的应用
|
||||
4. 字符串操作:字符位置获取、字符串拼接与处理
|
||||
5. 综合项目分析与独立完成:审题、拆解、调试的全流程能力考核
|
||||
|
||||
圆振在期末测试中整体表现不错,全程独立完成了试卷~选择题部分掌握得比较好,讲题环节被老师点名回答列表长度问题时也能准确答出👍
|
||||
|
||||
不过老师发现,失分的地方大多不是因为不会,而是粗心导致的~一道填空题把列表的第几项写成了中文数字,本来会的题因为格式问题丢了分;还有循环结构的题目,没有仔细数清楚循环次数就下了判断,有点可惜😅
|
||||
|
||||
圆振的底子是很扎实的,理解能力也不错,接下来需要重点培养的是做完题后检查的习惯,把粗心丢的分捡回来,成绩还能再上一个台阶!继续加油哦!💪✨
|
||||
|
||||
**等级**:B+
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -92,6 +92,12 @@
|
||||
|
||||
## 📝 成长记录
|
||||
|
||||
### 2026-07-03(第18课·期末测试)
|
||||
- **测试等级**:B+
|
||||
- **表现**:全程独立完成试卷,选择题部分掌握较好。失分主要在粗心:填空题把列表第几项写成中文数字导致失分;循环结构题目没仔细数循环次数就下判断。
|
||||
- **关键观察**:底子扎实,理解力不错,问题在于做完后不检查。后续需重点培养检查习惯。
|
||||
- **评语风格**:鼓励型
|
||||
|
||||
### 2026-03-28
|
||||
- **记录**:本周学习《源码精灵之战》,前面有一点点发呆,感觉不太在状态,后来慢慢调整过来了,后面状态好转很多,最后顺利把任务完成。每个人都有自己的节奏,重要的是能坚持到最后。
|
||||
- **评语风格**:鼓励型
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# K4橙子周日1900班 · 第18课班级反馈
|
||||
|
||||
**课程名称**: 期末考试
|
||||
**授课日期**: 2026-07-05
|
||||
**出勤情况**: 梁境城(到课)、钟嘉逸(请假)
|
||||
|
||||
---
|
||||
|
||||
## 📚 本节课内容
|
||||
|
||||
1. 列表的基本操作:添加元素到末尾、插入元素到指定位置
|
||||
2. 随机数的生成:从指定范围中选择随机整数
|
||||
3. 字符串包含判断:使用"包含"积木判断关键词
|
||||
4. 变量的运算与循环:重复执行中变量的变化规律
|
||||
5. 函数的调用与理解:分析函数执行流程
|
||||
|
||||
---
|
||||
|
||||
## 📊 课堂整体表现
|
||||
|
||||
### 亮点
|
||||
- 境城上课认真听讲,能够跟着老师的思路逐步理解题目
|
||||
- 对列表操作(添加、插入)有了更清晰的认识
|
||||
- 理解了变量在循环中的变化规律
|
||||
|
||||
### 需要巩固的知识点
|
||||
- 随机数生成的参数设置(从第几项到第几项)
|
||||
- 字符串包含判断的应用场景
|
||||
|
||||
---
|
||||
|
||||
## 📝 学生个人表现
|
||||
|
||||
### 梁境城 ✅ 到课
|
||||
- 课堂表现积极,专注听讲
|
||||
- 能回答老师的问题,对列表索引概念掌握不错
|
||||
- 课后建议练习列表操作,巩固知识
|
||||
|
||||
### 钟嘉逸 ❌ 请假
|
||||
- 本次课请假,未能参加期末考试讲解
|
||||
- 建议了解考试内容,做好补考准备
|
||||
|
||||
---
|
||||
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,26 @@
|
||||
# 课程名称:期末考试
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**课评内容**:
|
||||
境城家长好,本周学习的内容是《期末考试》:
|
||||
1. 列表的基本操作:添加元素到末尾、插入元素到指定位置
|
||||
2. 随机数的生成:从指定范围中选择随机整数
|
||||
3. 字符串包含判断:使用"包含"积木判断关键词
|
||||
4. 变量的运算与循环:重复执行中变量的变化规律
|
||||
5. 函数的调用与理解:分析函数执行流程
|
||||
|
||||
境城今天上课很积极哦~在讲解期末考试题目时,能够认真听老师分析每道题的解题思路,特别专注!🎨
|
||||
|
||||
当老师问到"从香蕉到葡萄间选一个随机整数"时,境城能跟着老师的思路思考,虽然一开始有些困惑,但通过老师的引导,逐渐理解了如何用"获取第几项"来实现随机选择,这种逐步理解的过程很棒!🌟
|
||||
|
||||
在列表操作题中,境城对"添加到末尾"和"插入到指定位置"的区别有了更清晰的认识,能够说出"第一项是香蕉、第五项是葡萄",说明对列表的索引概念掌握得不错~💡
|
||||
|
||||
老师讲解变量递减题时,境城能理解"每次减少2,永远不会大于20"的逻辑,思维很清晰!
|
||||
|
||||
课后可以试着用Kitten做一个小作品,练习列表的添加和查找功能,巩固这学期学到的知识哦~
|
||||
|
||||
继续加油哦!相信你会越来越棒的!🚀
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
@@ -0,0 +1,11 @@
|
||||
# 课程名称:期末考试
|
||||
|
||||
**授课日期**: 2026-07-05
|
||||
|
||||
**请假记录**:
|
||||
嘉逸家长好,本周《期末考试》课程请假,未能参加本次期末考试讲解。
|
||||
|
||||
如有需要,可以联系老师了解考试内容和补考安排。
|
||||
|
||||
---
|
||||
**老师签名:橙子**
|
||||
43
.claude/memory/csp03-sat1400-lesson18-review.md
Normal file
43
.claude/memory/csp03-sat1400-lesson18-review.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: csp03-sat1400-lesson18-review
|
||||
description: CSP03周六1400第18课《总复习》完成记录,含OJ数据获取踩坑和补课学生处理
|
||||
metadata:
|
||||
type: project
|
||||
date: 2026-07-04
|
||||
class: CSP03橙子周六1400
|
||||
---
|
||||
|
||||
# CSP03周六1400 · 第18课《总复习》完成
|
||||
|
||||
**日期**: 2026-07-04
|
||||
**出勤**: 到场4人(含补课1人),请假2人(郑子煜、张雨禾)
|
||||
|
||||
## 学生完成情况
|
||||
|
||||
| 学生 | 状态 | OJ-T3 | OJ-T4 |
|
||||
|------|------|-------|-------|
|
||||
| 魏铭轩 | 正常 | AC (TLE→AC, 2次) | 未提交 |
|
||||
| 苏俊宇 | 正常 | AC (1次) | 未提交 |
|
||||
| 卢华琛 | 正常 | AC (WA→WA→AC, 3次) | 未提交 |
|
||||
| 潘沐辰 | 补课 | AC (1次) | 未提交 |
|
||||
|
||||
## 踩坑记录
|
||||
|
||||
### 1. hw_dict.json中的OJ作业包ID可能过时
|
||||
- hw_dict.json中CSP03-18A的ID为`69acffad27e54d3ad7ef501b`,实际只有1道环境测试题且无提交记录
|
||||
- 橙子提供了正确的作业包ID `6a3e1a6be17a0e56c3901363`,包含2道GESP真题(T3平衡序列 + T4回文拼接)
|
||||
- **教训**: 当hw_dict.json中的作业ID返回空数据时,主动向橙子确认正确的OJ作业ID
|
||||
|
||||
### 2. OJ数据——HTML直接解析比正则可靠
|
||||
- 终端中文乱码问题:用python-docx同样的思路,先把HTML保存为文件再Read
|
||||
- Hydro OJ的提交记录页面结构清晰,直接从`<tr>`标签中提取分数、状态、题目、学生名
|
||||
|
||||
### 3. 补课学生潘沐辰无profile.md
|
||||
- 来自其他老师班级,项目中无档案,不需要创建profile
|
||||
- 课评保存在 `补课/潘沐辰/feedback/` 目录下正常生成
|
||||
|
||||
### 4. 课程计划只有15课,第18课不在计划中
|
||||
- 第18课是期末总复习,知识点从录音中提取(两道OJ题串联枚举法+双指针+字符串操作)
|
||||
|
||||
**Why**: 记录本次课评生成过程中的问题和解决方案,供后续课评参考。
|
||||
**How to apply**: 下次遇到hw_dict.json数据异常时直接向橙子确认作业ID;跨班级补课学生无profile也能正常生成课评。
|
||||
@@ -47,9 +47,9 @@
|
||||
- 适当使用表情符号(🌟💡🌸😊💪🌟)
|
||||
- 描述具体行为,不笼统表扬
|
||||
|
||||
**开头固定格式**(与 CSP03 一致,家长信格式):
|
||||
**开头固定格式**(与 CSP03 一致,家长信格式,开头加学生称呼如"梓宁家长好"):
|
||||
```
|
||||
家长好,本周学习的内容是《【课程名称】》:
|
||||
【学生名】家长好,本周学习的内容是《【课程名称】》:
|
||||
1. 【知识点1】
|
||||
2. 【知识点2】
|
||||
3. 【知识点3】
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
- 固定结尾:"老师会继续关注XX的表现,期待看到更多精彩!🌟💡"
|
||||
|
||||
**CSP03班(家长信·要求型):**
|
||||
- 固定开头:"家长好,本周学习的内容是《...》" + 5个知识点
|
||||
- 固定开头:"【学生名】家长好,本周学习的内容是《...》" + 5个知识点(如"子煜家长好")
|
||||
- 表扬积极:"状态在线"、"早早到校等候超积极"
|
||||
- 期望要求:"希望多思考"、"理解为什么这么写,不只是抄完就好"
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
|
||||
**开头固定格式**:
|
||||
```
|
||||
家长好,本周学习的内容是《【课程名称】》:
|
||||
【学生名】家长好,本周学习的内容是《【课程名称】》:
|
||||
1. 【知识点1】
|
||||
2. 【知识点2】
|
||||
3. 【知识点3】
|
||||
@@ -178,7 +178,7 @@
|
||||
4. 避免"但是" - 用"同时"、"下一步"等过渡词
|
||||
|
||||
**CSP03班风格(家长信·要求型)**:
|
||||
1. 固定开头 - "家长好,本周学习的内容是《...》" + 5个知识点
|
||||
1. 固定开头 - "【学生名】家长好,本周学习的内容是《...》" + 5个知识点(如"子煜家长好")
|
||||
2. 表扬积极 - "状态在线"、"早早到校等候超积极"
|
||||
3. 期望要求 - "希望多思考"、"理解为什么这么写,不只是抄完就好"
|
||||
4. 鼓励结尾 - "加油呀!💪✨"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
**开头固定格式**:
|
||||
```
|
||||
家长好,本周学习的内容是《【课程名称】》:
|
||||
【学生名】家长好,本周学习的内容是《【课程名称】》:
|
||||
1. 【知识点1】
|
||||
2. 【知识点2】
|
||||
3. 【知识点3】
|
||||
@@ -119,7 +119,7 @@
|
||||
4. 避免"但是" - 用"同时"、"下一步"等过渡词
|
||||
|
||||
**K4班风格(家长信格式)**:
|
||||
1. 固定开头 - "家长好,本周学习的内容是《...》" + 5个知识点
|
||||
1. 固定开头 - "【学生名】家长好,本周学习的内容是《...》" + 5个知识点(如"境城家长好")
|
||||
2. 具体创意 - "使用自己的名字作为聊天室的名称"
|
||||
3. 温和建议 - 用"不过老师发现"柔和指出问题
|
||||
4. 鼓励结尾 - "继续加油哦"、"相信你会把程序做得更完整"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
**开头固定格式**:
|
||||
```
|
||||
家长好,今天体验的是《【课程名称】》课程:
|
||||
【学生名】家长好,今天体验的是《【课程名称】》课程:
|
||||
|
||||
📚 本节课内容:
|
||||
1. 【知识点1】
|
||||
|
||||
@@ -146,7 +146,9 @@
|
||||
"Bash(sed -i 's|<span class=\"oj-summary-num\">1/4</span>|<span class=\"oj-summary-num\">1/5</span>|g' \"第16周周日早上CSP03课评.html\")",
|
||||
"Bash(python -c ' *)",
|
||||
"Bash(git add *)",
|
||||
"Bash(git commit *)"
|
||||
"Bash(git commit *)",
|
||||
"WebFetch(domain:1d81565c7394457a8fddd3f23c958a9f.app.codebuddy.work)",
|
||||
"Bash(curl -s -L \"https://1d81565c7394457a8fddd3f23c958a9f.app.codebuddy.work\")"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,51 +11,45 @@ type: skill
|
||||
|
||||
✅ 支持四大课程:C++/AICODE/Kitten/体验课
|
||||
✅ 自动匹配班级专属风格:AICODE03温暖鼓励型/K4温和鼓励型/CSP03要求型/体验课转化型
|
||||
✅ **CSP班级必须查询OJ做题数据**(自动调用API获取A包答题情况)
|
||||
✅ **CSP班级必须查询OJ做题数据**(用户提供token后自动获取A包答题情况)
|
||||
|
||||
## 💡 使用方式
|
||||
|
||||
### 方式一:交互式问答(推荐)
|
||||
### 交互式问答(推荐)
|
||||
|
||||
输入 `/课评生成`,我会使用**选择题**的方式问你所有问题:
|
||||
输入 `/课评生成`,我会按顺序问你以下信息:
|
||||
|
||||
```
|
||||
📝 问题1:课堂录音文件路径是什么?(.docx格式)
|
||||
- [ ] 稍后提供
|
||||
- [ ] 还没有录音
|
||||
📝 问题1:这次是什么类型的班?
|
||||
- [ ] AICODE(AI创意编程)
|
||||
- [ ] CSP(C++信息奥赛)
|
||||
- [ ] K4(编程猫Kitten)
|
||||
- [ ] 体验课
|
||||
|
||||
📝 问题2:这是哪个班级的课?
|
||||
- [ ] AICODE03橙子周六1900(需要作品文件夹)
|
||||
- [ ] AICODE03橙子周日0845
|
||||
- [ ] AICODE03橙子周日1400
|
||||
- [ ] CSP03橙子周六0830(需要OJ数据)
|
||||
- [ ] CSP03橙子周六1400
|
||||
- [ ] CSP03橙子周日1030
|
||||
- [ ] K4橙子周五1900
|
||||
- [ ] K4橙子周日1900
|
||||
📝 问题2:课堂录音文件路径是什么?(.docx格式)
|
||||
|
||||
📝 问题3:这是第几课?题目是什么?
|
||||
- [ ] 稍后提供
|
||||
- [ ] 还不确定
|
||||
📝 问题3:这是第几周的课?课程名称是什么?
|
||||
|
||||
📝 问题4:作品文件夹路径?(仅AICODE班需要)
|
||||
- [ ] 稍后提供
|
||||
- [ ] 不需要(CSP/K4班)
|
||||
📝 问题4:具体是哪个班次?(根据你选的班型显示对应选项)
|
||||
AICODE班选项:
|
||||
- [ ] AICODE03橙子周六1900
|
||||
- [ ] AICODE03橙子周日0845
|
||||
- [ ] AICODE03橙子周日1400
|
||||
CSP班选项:
|
||||
- [ ] CSP03橙子周六0830
|
||||
- [ ] CSP03橙子周六1400
|
||||
- [ ] CSP03橙子周日1030
|
||||
K4班选项:
|
||||
- [ ] K4橙子周五1900
|
||||
- [ ] K4橙子周日1900
|
||||
|
||||
📝 问题5(AICODE班):作品文件夹路径是什么?
|
||||
📝 问题5(CSP班):OJ题目的token是什么?
|
||||
|
||||
📝 问题6:本节课出勤情况如何?(来了哪些学生,谁请假)
|
||||
```
|
||||
|
||||
你选择或填写完所有问题,我就会自动完成整个课评生成流程!
|
||||
|
||||
### 方式二:直接提供信息
|
||||
|
||||
如果你已经知道所有信息,可以直接告诉我:
|
||||
```
|
||||
课堂录音文件:第11课录音转写.docx
|
||||
班级:AICODE03橙子周六1900
|
||||
课次:第11课
|
||||
题目:《AI训练师》
|
||||
出勤:来了陈嘉博、王子墨,请假谭俊研
|
||||
作品文件夹:D:\作品\第11课
|
||||
```
|
||||
你回答完所有问题,我就会自动完成整个课评生成流程!
|
||||
|
||||
---
|
||||
|
||||
@@ -64,13 +58,12 @@ type: skill
|
||||
你提供信息后,我会自动完成:
|
||||
|
||||
### 第1阶段:课评准备
|
||||
1. 获取API出勤数据
|
||||
2. 使用python-docx读取录音转写文件
|
||||
3. AI分析录音文本,识别"发言人1,2,3"对应的学生
|
||||
4. **AICODE班**:查看作品文件夹,分析每个学生作品的创意和亮点
|
||||
5. 读取课程计划,获取5个知识点
|
||||
6. 读取每个学生的画像
|
||||
7. **CSP班**:调用OJ API查询A包做题数据
|
||||
1. 使用python-docx读取录音转写文件
|
||||
2. AI分析录音文本,识别"发言人1,2,3"对应的学生
|
||||
3. **AICODE班**:查看作品文件夹,分析每个学生作品的创意和亮点
|
||||
4. 读取课程计划,获取5个知识点
|
||||
5. 读取每个学生的画像
|
||||
6. **CSP班**:使用token查询OJ做题数据
|
||||
|
||||
### 第2阶段:课评生成
|
||||
1. 读取班级风格指南
|
||||
@@ -96,18 +89,20 @@ type: skill
|
||||
|
||||
### 🤖 交互式问答流程
|
||||
|
||||
当橙子输入 `/课评生成` 时,使用 **AskUserQuestion** 工具一次性问完所有问题:
|
||||
当橙子输入 `/课评生成` 时,使用 **AskUserQuestion** 工具按顺序询问:
|
||||
|
||||
**第1轮:收集基本信息**
|
||||
- 问题1:录音文件路径(文本输入)
|
||||
- 问题2:班级(单选:AICODE03/CSP03/K4的各个时间段)
|
||||
- 问题3:课次和题目(文本输入)
|
||||
- 问题4:出勤情况(单选:全部到齐/有人请假)
|
||||
**第1轮:基本信息**
|
||||
- 问题1:班型(单选:AICODE/CSP/K4/体验课)
|
||||
- 问题2:录音文件路径(文本输入)
|
||||
- 问题3:第几周 + 课程名称(文本输入)
|
||||
|
||||
**第2轮:根据班级类型追问**
|
||||
- 如果是AICODE班:追问作品文件夹路径
|
||||
- 如果是CSP班:无需追问(OJ数据自动获取)
|
||||
- 如果是K4班:无需追问
|
||||
**第2轮:确认班次**
|
||||
- 问题4:具体班次(根据班型显示对应选项)
|
||||
|
||||
**第3轮:补充材料**
|
||||
- 问题5(AICODE班):作品文件夹路径
|
||||
- 问题5(CSP班):OJ题目的token
|
||||
- 问题6:出勤情况(文本输入,说明谁来了、谁请假)
|
||||
|
||||
**收集完成后**,自动调用三个阶段的agent完成课评生成。
|
||||
|
||||
@@ -123,7 +118,7 @@ type: skill
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
收集所有数据 生成课评内容 质检+保存+归档
|
||||
• API授课数据 • 读取风格指南 • 课评质检
|
||||
• 确认班型班次 • 读取风格指南 • 课评质检
|
||||
• 录音解析(AI分析) • 读取课评模板 • 保存课评
|
||||
• 课程计划匹配 • 生成个人课评 • 保存班级总结
|
||||
• 学生画像读取 • 生成班级总结 • 更新学生画像
|
||||
@@ -165,119 +160,56 @@ type: skill
|
||||
|
||||
### 工作流程
|
||||
```
|
||||
获取API授课数据 → 读取录音转写(docx) → AI分析识别发言人 → 获取课程知识点 → 读取学生画像 → 润色生成 → 确认修改 → 课评质检 → 保存
|
||||
确认班型班次 → 读取录音转写(docx) → AI分析识别发言人 → 获取课程知识点 → 读取学生画像 → 润色生成 → 确认修改 → 课评质检 → 保存
|
||||
```
|
||||
|
||||
### 0. 获取API授课数据(必须第一步执行)
|
||||
|
||||
**⚠️ 这是强制步骤,必须在读取笔记之前执行!**
|
||||
|
||||
在开始处理任何课评之前,**必须先调用公司API获取橙子老师近期的授课数据**,用于:
|
||||
1. 确认橙子老师实际带了哪些班级
|
||||
2. 获取每个班级的**真实授课日期**(`teaching_date`),用于课评文件名
|
||||
|
||||
**执行命令**(Python):
|
||||
```python
|
||||
import urllib.request
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
API_BASE_URL = "https://api.qonnwolf.com/api/v1"
|
||||
AUTHORIZATION = "Bearer <从.env文件读取>"
|
||||
|
||||
# 计算最近7天的日期范围
|
||||
end_date = datetime.now()
|
||||
start_date = end_date - timedelta(days=7)
|
||||
|
||||
# 查询橙子老师的出勤数据
|
||||
dates_to_query = []
|
||||
current = start_date
|
||||
while current <= end_date:
|
||||
dates_to_query.append(current.strftime('%Y-%m-%d'))
|
||||
current += timedelta(days=1)
|
||||
|
||||
results = []
|
||||
for date in dates_to_query:
|
||||
url = f"{API_BASE_URL}/reports/teaching-schedule?teaching_date={date}"
|
||||
req = urllib.request.Request(url)
|
||||
req.add_header('Authorization', AUTHORIZATION)
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
data = json.loads(response.read().decode('utf-8'))
|
||||
for item in data['data']['items']:
|
||||
teacher = item.get('teacher_name', '')
|
||||
if '橙子' in teacher or '程城' in teacher:
|
||||
results.append({
|
||||
'teaching_date': item['teaching_date'], # API返回的真实授课日期
|
||||
'class_name': item['class_name'],
|
||||
'time': item['teaching_time_period'],
|
||||
'lesson': item['lesson_name'],
|
||||
'student_count': item['student_count'],
|
||||
'attendance': item['attendance'],
|
||||
'students': item.get('student_names', [])
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"查询 {date} 失败: {e}")
|
||||
|
||||
# 输出结果
|
||||
for r in results:
|
||||
print(f"日期:{r['teaching_date']} 班级:{r['class_name']} 时间:{r['time']} 课程:{r['lesson']}")
|
||||
```
|
||||
|
||||
**返回数据说明**:
|
||||
| 字段 | 说明 | 用途 |
|
||||
|------|------|------|
|
||||
| `teaching_date` | API返回的真实授课日期 | **必须用此日期作为课评文件名中的YYYYMMDD** |
|
||||
| `class_name` | 班级名称 | 用于确认班级目录名 |
|
||||
| `time` | 上课时间段 | 用于确认班级(如19:00-20:30对应晚上班) |
|
||||
| `lesson_name` | 课程名称 | 用于匹配课程计划 |
|
||||
| `student_count` | 学生数 | 用于确认班级人数 |
|
||||
| `attendance` | 出勤统计 | 到课/请假/缺课人数 |
|
||||
| `students` | 学生名单 | 用于确认学生 |
|
||||
|
||||
**日期规则(重要)**:
|
||||
- ✅ **必须使用API返回的 `teaching_date`** 作为课评文件名中的日期
|
||||
- ✅ 如果笔记中的日期与API返回的 `teaching_date` 不一致,**以API为准**
|
||||
- ✅ 文件名格式:`{API返回的teaching_date}_课程编号-课次.md`
|
||||
|
||||
**班级匹配规则**:
|
||||
根据API返回的 `class_name` 和 `time` 匹配笔记中的班级:
|
||||
| API返回的class_name | 对应班级目录 | 识别依据 |
|
||||
|---------------------|-------------|----------|
|
||||
| AICODE03... | AICODE03橙子周六1900 / AICODE03橙子周日0845 / AICODE03橙子周日1400 | class_name含"AICODE03" + time判断 |
|
||||
| CSP03... | CSP03橙子周六0830 / CSP03橙子周六1400 / CSP03橙子周日1030 | class_name含"CSP03" + time判断 |
|
||||
| KITTEN04... | K4橙子周五1900 / K4橙子周日1900 | class_name含"KITTEN04" + time判断 |
|
||||
|
||||
### 1. 读取课堂录音转写文件
|
||||
解析用户提供的课堂录音转写文件(`.docx` 格式):
|
||||
|
||||
**使用python-docx库读取**:
|
||||
**⚠️ 关键:docx 中文在终端显示会乱码,必须分两步读取!**
|
||||
|
||||
**第一步:用 python-docx 提取文本并保存为 UTF-8 txt 文件**
|
||||
```python
|
||||
from docx import Document
|
||||
|
||||
def read_recording_docx(file_path):
|
||||
"""读取课堂录音转写的docx文件"""
|
||||
doc = Document(file_path)
|
||||
content = []
|
||||
for para in doc.paragraphs:
|
||||
text = para.text.strip()
|
||||
if text:
|
||||
content.append(text)
|
||||
return '\n'.join(content)
|
||||
def extract_docx_to_txt(docx_path):
|
||||
"""从docx提取文本,保存为UTF-8 txt文件(避免终端乱码)"""
|
||||
doc = Document(docx_path)
|
||||
# 提取所有段落文本
|
||||
text = '\n'.join([p.text for p in doc.paragraphs if p.text.strip()])
|
||||
# 保存为UTF-8 txt
|
||||
txt_path = docx_path.replace('.docx', '_提取.txt')
|
||||
with open(txt_path, 'w', encoding='utf-8') as f:
|
||||
f.write(text)
|
||||
return txt_path
|
||||
|
||||
# 使用示例
|
||||
file_path = r"课堂录音转写文件路径" # 例如:第15课录音转写.docx
|
||||
recording_text = read_recording_docx(file_path)
|
||||
# 对每个录音文件执行
|
||||
for fpath in [r'input/录音1.docx', r'input/录音2.docx']:
|
||||
txt_path = extract_docx_to_txt(fpath)
|
||||
print(f'已提取: {txt_path}')
|
||||
```
|
||||
|
||||
**第二步:用 Read 工具读取 txt 文件**
|
||||
```
|
||||
Read 工具直接读取 _提取.txt 文件,中文显示完全正常
|
||||
```
|
||||
|
||||
> **为什么这样做?** python-docx 底层 XML 是 UTF-8 编码,能正确读取中文。但 bash 终端渲染 UTF-8 中文时会产生乱码。保存为 txt 后,用 Read 工具读取即可正常显示。
|
||||
>
|
||||
> **清理**:课评保存完成后,删除 `_提取.txt` 临时文件。
|
||||
|
||||
**录音文本特点**:
|
||||
- 整节课的完整录音转写,包含老师和学生的对话
|
||||
- 可能包含时间戳(如"[00:05:30]")
|
||||
- 可能包含说话人标识(如"老师:"、"学生:")
|
||||
- 内容为自由文本,不是结构化的表格
|
||||
- 语音转文字质量参差不齐,常见同音字、模糊识别
|
||||
- 整节课的完整转写,包含老师和学生的对话
|
||||
- 带时间戳(如"发言人 00:04")
|
||||
- 可能有"发言人1"、"发言人2"等编号(老师通常是发言人1)
|
||||
- 学生姓名可能被转写为同音字(如"圆振"→"原证"、"艺嘉"→"YGX")
|
||||
|
||||
**AI分析提取学生表现**:
|
||||
由于录音是自由文本格式,需要使用AI分析提取每个学生的表现信息:
|
||||
直接读取 `_提取.txt` 文件内容,分析时注意:
|
||||
- 结合学生姓名和可能的同音字变体来定位个体表现
|
||||
- 语音识别误差大的段落需结合上下文推断
|
||||
- 关注:被点名回答、主动提问、完成进度、老师评语等关键事件
|
||||
|
||||
```python
|
||||
# 分析提示词
|
||||
@@ -285,6 +217,7 @@ analysis_prompt = f"""
|
||||
分析以下课堂录音转写文本,提取每个学生的表现信息。
|
||||
|
||||
班级学生名单:{student_list}
|
||||
注意:语音转文字可能存在同音字,请结合上下文推断学生身份(如"原证"可能是"圆振")。
|
||||
|
||||
请为每个学生提供:
|
||||
1. 出勤状况:正常上课 / 请假 / 未到
|
||||
@@ -301,7 +234,7 @@ analysis_prompt = f"""
|
||||
"""
|
||||
```
|
||||
|
||||
> **日期规则**:批量流程中,所有日期(文件名 `YYYYMMDD`、授课日期)**统一以API返回的teaching_date为准**,不使用录音文件中的日期。
|
||||
> **日期规则**:根据用户提供的周次信息推算具体日期,或在交互式问答时直接询问用户确认授课日期。
|
||||
|
||||
### 2. 匹配课程计划
|
||||
根据班级标题中的关键词匹配对应课程计划:
|
||||
@@ -350,7 +283,7 @@ python scripts/get_student_oj.py \
|
||||
|
||||
**输出示例**:
|
||||
```markdown
|
||||
家长好,本周学习的内容是《魔幻俄罗斯方块(下)》:
|
||||
嘉博家长好,本周学习的内容是《魔幻俄罗斯方块(下)》:
|
||||
1. 理解"自动化测试"的概念
|
||||
2. 理解"测试覆盖":每条规则都应有对应测试
|
||||
3. 功能扩展的增量思维
|
||||
@@ -556,7 +489,7 @@ CSP课评必须使用 `.claude/agents/` 目录下的质检Agent系统进行质
|
||||
|
||||
## ⚙️ 核心生成逻辑(自动完成,你不需要操作)
|
||||
```
|
||||
1. 读取参考资料 → 2. AICODE班分析作品/CSP班拉取OJ数据 → 3. 生成个性化课评 → 4. 橙子确认修改 → 5. 自动质检 → 6. 自动保存
|
||||
1. 确认班型和班次 → 2. 读取参考资料 → 3. AICODE班分析作品/CSP班拉取OJ数据 → 4. 生成个性化课评 → 5. 橙子确认修改 → 6. 自动质检 → 7. 自动保存
|
||||
```
|
||||
|
||||
### 1. 自动读取参考资料
|
||||
@@ -698,7 +631,7 @@ python scripts/get_student_oj.py \
|
||||
|
||||
## 🎨 各班级风格规范(自动匹配)
|
||||
### AICODE03班 - 家长信格式·温暖鼓励型
|
||||
- 固定开头:"家长好,本周学习的内容是《...》" + 5个知识点(与 CSP03 一致)
|
||||
- 固定开头:"【学生名】家长好,本周学习的内容是《...》" + 5个知识点(开头加学生称呼,如"梓宁家长好",与 CSP03 一致)
|
||||
- 课程目标后空一行,再写"课评反馈:"正文
|
||||
- 多用"很棒"、"特别棒"、"超棒"和波浪号"~"
|
||||
- 描述具体行为:"一字一字打字"、"和AI聊了一节课"
|
||||
@@ -730,7 +663,7 @@ python scripts/get_student_oj.py \
|
||||
```
|
||||
|
||||
### K4班 - 家长信格式·温和鼓励型
|
||||
- 固定开头:"家长好,本周学习的内容是《...》" + 5个知识点
|
||||
- 固定开头:"【学生名】家长好,本周学习的内容是《...》" + 5个知识点(开头加学生称呼,如"圆振家长好")
|
||||
- 肯定创意:"能够有自己的创意"
|
||||
- 温和指出:"不过老师发现...专注力有些下降"
|
||||
- **表情包使用**:K4班学生年龄小,多用可爱活泼的表情增加亲和力
|
||||
@@ -740,7 +673,7 @@ python scripts/get_student_oj.py \
|
||||
- 结尾可用:"继续加油哦!🌟"、"相信你会把程序做得更完整!🚀"
|
||||
|
||||
### CSP03班 - 家长信格式·要求型
|
||||
- 固定开头:"家长好,本周学习的内容是《...》" + 5个知识点
|
||||
- 固定开头:"【学生名】家长好,本周学习的内容是《...》" + 5个知识点(开头加学生称呼,如"圆振家长好")
|
||||
- 表扬积极:"状态在线"、"早早到校等候超积极"
|
||||
- 期望要求:"希望多思考"、"理解为什么这么写,不只是抄完就好~"
|
||||
- **表情包使用**:CSP班学生偏大,表情偏励志和认可风格
|
||||
@@ -790,7 +723,7 @@ python scripts/get_student_oj.py \
|
||||
- ✅ 对A包中未完成的题目,给出具体的知识点建议,帮助孩子针对性提高
|
||||
|
||||
### 体验课 - 家长信格式·转化导向型
|
||||
- 固定开头:"家长好,今天体验的是《...》课程" + 课程价值介绍
|
||||
- 固定开头:"【学生名】家长好,今天体验的是《...》课程" + 课程价值介绍(开头加学生称呼,如"小明家长好")
|
||||
- 突出"第一次":强调新体验,降低焦虑,突出潜力
|
||||
- 建立愿景:描述继续学习后孩子能达到的水平
|
||||
- 自然引导报课:用期待和相信引导,不硬推销
|
||||
@@ -808,7 +741,7 @@ python scripts/get_student_oj.py \
|
||||
### 📌 命名规范(必须严格遵守)
|
||||
- **课程编号规则**:C++竞赛班统一用`CSP`,AI编程班统一用`AICODE`,不得使用`AI`、`C++`等缩写
|
||||
- **文件名规则**:`YYYYMMDD_课程编号-课次.md`(如`20260418_CSP05-07.md`、`20260330_AICODE03-02.md`)
|
||||
- **日期要求**:文件名中的`YYYYMMDD`必须与校宝`teaching_date`完全一致,不得使用编写/提交日期
|
||||
- **日期要求**:根据用户提供的周次信息推算具体日期,或询问用户确认
|
||||
- **特殊状态文件**:
|
||||
- 请假:`YYYYMMDD_课程编号-课次(请假).md`
|
||||
- 未上课:`YYYYMMDD_课程编号-课次(未到).md`
|
||||
@@ -873,7 +806,7 @@ python scripts/get_student_oj.py \
|
||||
**判断逻辑**:
|
||||
1. 计算本节课所属的教学周次(第X周)
|
||||
2. 构造文件名:`第{X}周{星期时间}{课程编号}课评.html`
|
||||
- 星期时间从API数据中提取(如"周日下午"、"周六早上")
|
||||
- 星期时间从用户提供的班次信息中提取(如"周日下午"、"周六早上")
|
||||
- 课程编号如 `AICODE03`、`CSP03`、`K4`
|
||||
- 示例:`第14周周日下午AICODE03课评.html`
|
||||
3. 检查 `output/课评汇总/` 目录下是否已存在该文件
|
||||
@@ -887,10 +820,10 @@ python scripts/get_student_oj.py \
|
||||
| 模板位置 | 替换内容 | 数据来源 |
|
||||
|---------|---------|---------|
|
||||
| `<title>`、顶部标题 | 第X周 · [课程编号]班课评 | 周次 + 课程编号 |
|
||||
| 顶部副标题、封面日期 | YYYY年M月D日 · 《课程名称》 · 橙子老师 | API的teaching_date + 课程计划 |
|
||||
| 顶部副标题、封面日期 | YYYY年M月D日 · 《课程名称》 · 橙子老师 | 用户提供的日期 + 课程计划 |
|
||||
| 封面大标题 | 《课程名称》 | 课程计划 |
|
||||
| 封面副标题 | 课程领域 · 第X课 | 课程计划 |
|
||||
| 封面信息区 | 📅日期、⏰时间、👩🏫老师 | API数据 |
|
||||
| 封面信息区 | 📅日期、⏰时间、👩🏫老师 | 用户提供的数据 |
|
||||
| 知识点列表 | 5条知识点 | 课程计划中的教学目标 |
|
||||
| 学生卡片 | 每张卡片一个学生 | 本节课所有学生的课评 |
|
||||
| 状态标签 | 正常上课/补课/请假/未到 | 出勤记录 |
|
||||
@@ -950,7 +883,7 @@ output/课评汇总/第{X}周{星期时间}{课程编号}课评.html
|
||||
> 李明今天虽然是第一次接触AI绘画,但我看到了你眼里的好奇,这就是最好的开始。你的描述很有画面感,"想要一个会眨眼的可爱猫咪",这就是好的Prompt。虽然操作还有点生疏,但老师注意到你一直在尝试,这份坚持比做对题目更珍贵。下次可以把想法先写在便签纸上,分点列出,跟AI沟通会更顺畅。记住,编程最大的门槛不是英文或数学,是敢于尝试的勇气,你已经有了。继续和你的"AI搭档"对话吧,它会越来越懂你的。
|
||||
|
||||
**CSP03班 - 家长信格式·要求型(含OJ数据)**
|
||||
> 家长好,本周学习的内容是《字符串处理》:
|
||||
> 子煜家长好,本周学习的内容是《字符串处理》:
|
||||
> 1. string 类型的声明与使用
|
||||
> 2. 字符串的输入输出(cin / getline)
|
||||
> 3. 字符串的拼接与比较操作
|
||||
|
||||
16
node_modules/.bin/browsers
generated
vendored
Normal file
16
node_modules/.bin/browsers
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../@puppeteer/browsers/lib/main-cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../@puppeteer/browsers/lib/main-cli.js" "$@"
|
||||
fi
|
||||
17
node_modules/.bin/browsers.cmd
generated
vendored
Normal file
17
node_modules/.bin/browsers.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@puppeteer\browsers\lib\main-cli.js" %*
|
||||
28
node_modules/.bin/browsers.ps1
generated
vendored
Normal file
28
node_modules/.bin/browsers.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../@puppeteer/browsers/lib/main-cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../@puppeteer/browsers/lib/main-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../@puppeteer/browsers/lib/main-cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../@puppeteer/browsers/lib/main-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
node_modules/.bin/puppeteer
generated
vendored
Normal file
16
node_modules/.bin/puppeteer
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../puppeteer/lib/puppeteer/node/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../puppeteer/lib/puppeteer/node/cli.js" "$@"
|
||||
fi
|
||||
17
node_modules/.bin/puppeteer.cmd
generated
vendored
Normal file
17
node_modules/.bin/puppeteer.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\puppeteer\lib\puppeteer\node\cli.js" %*
|
||||
28
node_modules/.bin/puppeteer.ps1
generated
vendored
Normal file
28
node_modules/.bin/puppeteer.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../puppeteer/lib/puppeteer/node/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../puppeteer/lib/puppeteer/node/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../puppeteer/lib/puppeteer/node/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../puppeteer/lib/puppeteer/node/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
564
node_modules/.package-lock.json
generated
vendored
564
node_modules/.package-lock.json
generated
vendored
@@ -1,350 +1,318 @@
|
||||
{
|
||||
"name": "ClassFeedback",
|
||||
"name": "02-ClassFeedback",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"license": "MIT",
|
||||
"node_modules/@puppeteer/browsers": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/@puppeteer/browsers/-/browsers-3.0.5.tgz",
|
||||
"integrity": "sha512-xYXNuEQmHNIPWWcbL/skf2KF7seyp7c1xmKFRk3wmdFx7VwBsKVrtOLKs8ecaezsKPsWeF1YsgwIiElAscaryA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
"modern-tar": "^0.7.6",
|
||||
"yargs": "^18.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"browsers": "lib/main-cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.16.1.tgz",
|
||||
"integrity": "sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.16.0",
|
||||
"form-data": "^4.0.5",
|
||||
"https-proxy-agent": "^5.0.1",
|
||||
"proxy-from-env": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
"peerDependencies": {
|
||||
"proxy-agent": ">=8.0.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"proxy-agent": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "17.4.2",
|
||||
"resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-17.4.2.tgz",
|
||||
"integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz",
|
||||
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chromium-bidi": {
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/chromium-bidi/-/chromium-bidi-16.0.1.tgz",
|
||||
"integrity": "sha512-J63PGu/9PpeCwLIcKYyzWP6yaVL5pxuBc0shlYCYM8BaAkmlwiQboXO1iNbOgSDbVklEyYFfNEcHD8oOAWacUA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
"mitt": "^3.0.1",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
"node": ">=20.19.0 <22.0.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"devtools-protocol": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"license": "MIT",
|
||||
"node_modules/cliui": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-9.0.1.tgz",
|
||||
"integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
"string-width": "^7.2.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"node_modules/devtools-protocol": {
|
||||
"version": "0.0.1638949",
|
||||
"resolved": "https://registry.npmmirror.com/devtools-protocol/-/devtools-protocol-0.0.1638949.tgz",
|
||||
"integrity": "sha512-mXwg4Fqnv0WR4iuAT/gYUmctNkjILwXFHyZ+m7Ty1dfr0ezZt2U3gnrrJTfRobJTHoXf+IbuFvFITzLrLFjwJA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.6.0.tgz",
|
||||
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/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-east-asian-width": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
|
||||
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.3.tgz",
|
||||
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antonk52"
|
||||
}
|
||||
},
|
||||
"node_modules/mitt": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz",
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/modern-tar": {
|
||||
"version": "0.7.6",
|
||||
"resolved": "https://registry.npmmirror.com/modern-tar/-/modern-tar-0.7.6.tgz",
|
||||
"integrity": "sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/puppeteer": {
|
||||
"version": "25.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/puppeteer/-/puppeteer-25.2.1.tgz",
|
||||
"integrity": "sha512-2D5RMkQH9FRhDU57a1/jV9xWoxqZvUjaZOYjAAPdRCEY8A01V5sxzyGOMs8XiKU9fPF91SOSwNYpHRu5SD958g==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
"@puppeteer/browsers": "3.0.5",
|
||||
"chromium-bidi": "16.0.1",
|
||||
"devtools-protocol": "0.0.1638949",
|
||||
"lilconfig": "^3.1.3",
|
||||
"puppeteer-core": "25.2.1",
|
||||
"typed-query-selector": "^2.12.2"
|
||||
},
|
||||
"bin": {
|
||||
"puppeteer": "lib/puppeteer/node/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
"node": ">=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.16.0.tgz",
|
||||
"integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"node_modules/puppeteer-core": {
|
||||
"version": "25.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/puppeteer-core/-/puppeteer-core-25.2.1.tgz",
|
||||
"integrity": "sha512-MwEZ4FFGJ1ZLOmu/04eISxoEMKtCnHyJBRFfgpwPPSYNG6gT6Xw1laNziFSV7uwDcx3jK+ATYIo9SfOd8Uhc3w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@puppeteer/browsers": "3.0.5",
|
||||
"chromium-bidi": "16.0.1",
|
||||
"devtools-protocol": "0.0.1638949",
|
||||
"typed-query-selector": "^2.12.2",
|
||||
"webdriver-bidi-protocol": "0.4.2",
|
||||
"ws": "^8.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-7.2.0.tgz",
|
||||
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^10.3.0",
|
||||
"get-east-asian-width": "^1.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.2.0.tgz",
|
||||
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/typed-query-selector": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmmirror.com/typed-query-selector/-/typed-query-selector-2.12.2.tgz",
|
||||
"integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/webdriver-bidi-protocol": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmmirror.com/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.2.tgz",
|
||||
"integrity": "sha512-VSV+fzfChirL3e7jay2yUC7B4HQCGtEWEg/MSSQbK+qWbqeGlRLlXTzPpYr3XGUvbpDHumWZBJxgesg4N7dbtA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
|
||||
"integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.2.1",
|
||||
"string-width": "^7.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.21.0",
|
||||
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.21.0.tgz",
|
||||
"integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.3.tgz",
|
||||
"integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
|
||||
"integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
|
||||
"license": "MIT",
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-18.0.0.tgz",
|
||||
"integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^9.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"string-width": "^7.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^22.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "22.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-22.0.0.tgz",
|
||||
"integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.25.76",
|
||||
"resolved": "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz",
|
||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
186
node_modules/@puppeteer/browsers/README.md
generated
vendored
Normal file
186
node_modules/@puppeteer/browsers/README.md
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
# @puppeteer/browsers
|
||||
|
||||
Manage and launch browsers/drivers from a CLI or programmatically.
|
||||
|
||||
## System requirements
|
||||
|
||||
- A compatible Node version (see `engines` in `package.json`).
|
||||
- For Firefox downloads:
|
||||
- Linux builds: `xz` and `bzip2` utilities are required to unpack `.tar.gz` and `.tar.bz2` archives.
|
||||
- MacOS builds: `hdiutil` is required to unpack `.dmg` archives.
|
||||
- For Chrome downloads:
|
||||
- On Linux/MacOS: `unzip`.
|
||||
- On Windows: `tar.exe`.
|
||||
|
||||
## CLI
|
||||
|
||||
Use `npx` to run the CLI:
|
||||
|
||||
```bash
|
||||
# This will install and run the @puppeteer/browsers package.
|
||||
# If it is already installed in the current directory, the installed
|
||||
# version will be used.
|
||||
npx @puppeteer/browsers --help
|
||||
```
|
||||
|
||||
Built-in per-command `help` will provide all documentation you need to use the CLI.
|
||||
|
||||
```bash
|
||||
npx @puppeteer/browsers --help # help for all commands
|
||||
npx @puppeteer/browsers install --help # help for the install command
|
||||
npx @puppeteer/browsers launch --help # help for the launch command
|
||||
npx @puppeteer/browsers clear --help # help for the clear command
|
||||
npx @puppeteer/browsers list --help # help for the list command
|
||||
```
|
||||
|
||||
You can specify the version of the `@puppeteer/browsers` when using
|
||||
`npx`:
|
||||
|
||||
```bash
|
||||
# Always install and use the latest version from the registry.
|
||||
npx @puppeteer/browsers@latest --help
|
||||
# Always use a specifc version.
|
||||
npx @puppeteer/browsers@2.4.1 --help
|
||||
# Always install the latest version and automatically confirm the installation.
|
||||
npx --yes @puppeteer/browsers@latest --help
|
||||
```
|
||||
|
||||
To clear all installed browsers, use the `clear` command:
|
||||
|
||||
```bash
|
||||
npx @puppeteer/browsers clear
|
||||
```
|
||||
|
||||
To list all installed browsers, use the `list` command:
|
||||
|
||||
```bash
|
||||
npx @puppeteer/browsers list
|
||||
```
|
||||
|
||||
Some example to give an idea of what the CLI looks like (use the `--help` command for more examples):
|
||||
|
||||
```sh
|
||||
# Download the latest available Chrome for Testing binary corresponding to the Stable channel.
|
||||
npx @puppeteer/browsers install chrome@stable
|
||||
|
||||
# Download a specific Chrome for Testing version.
|
||||
npx @puppeteer/browsers install chrome@116.0.5793.0
|
||||
|
||||
# Download the latest Chrome for Testing version for the given milestone.
|
||||
npx @puppeteer/browsers install chrome@117
|
||||
|
||||
# Download the latest available ChromeDriver version corresponding to the Canary channel.
|
||||
npx @puppeteer/browsers install chromedriver@canary
|
||||
|
||||
# Download a specific ChromeDriver version.
|
||||
npx @puppeteer/browsers install chromedriver@116.0.5793.0
|
||||
|
||||
# On Ubuntu/Debian and only for Chrome, install the browser and required system dependencies.
|
||||
# If the browser version has already been installed, the command
|
||||
# will still attempt to install system dependencies.
|
||||
# Requires root privileges.
|
||||
npx puppeteer browsers install chrome --install-deps
|
||||
```
|
||||
|
||||
## Known limitations
|
||||
|
||||
1. Launching the system browsers is only possible for Chrome/Chromium.
|
||||
|
||||
## Proxies
|
||||
|
||||
The library and CLI respect `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` environment variables. For them to work, you must have the `proxy-agent` package installed:
|
||||
|
||||
```bash
|
||||
npm install proxy-agent
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
To enable verbose logging for `@puppeteer/browsers` operations (like download progress, installation steps, and launching parameters), use Node.js's built-in `NODE_DEBUG` environment variable.
|
||||
|
||||
```bash
|
||||
env NODE_DEBUG="puppeteer:browsers:*" npx @puppeteer/browsers install chrome@stable
|
||||
```
|
||||
|
||||
The following debug channels are available:
|
||||
|
||||
- `puppeteer:browsers:cache`: Caching operations.
|
||||
- `puppeteer:browsers:fileUtil`: Decompressing and other file utility operations.
|
||||
- `puppeteer:browsers:install`: Download and install progress.
|
||||
- `puppeteer:browsers:launcher`: Browser launching parameters and process state.
|
||||
|
||||
## Custom Providers
|
||||
|
||||
You can implement custom browser providers to download from alternative sources like corporate mirrors, private repositories, or specialized browser builds.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
BrowserProvider,
|
||||
DownloadOptions,
|
||||
Browser,
|
||||
BrowserPlatform,
|
||||
} from '@puppeteer/browsers';
|
||||
|
||||
class SimpleMirrorProvider implements BrowserProvider {
|
||||
constructor(private mirrorUrl: string) {}
|
||||
|
||||
supports(options: DownloadOptions): boolean {
|
||||
return options.browser === Browser.CHROME;
|
||||
}
|
||||
|
||||
getDownloadUrl(options: DownloadOptions): URL | null {
|
||||
const {buildId, platform} = options;
|
||||
const filenameMap = {
|
||||
[BrowserPlatform.LINUX]: 'chrome-linux64.zip',
|
||||
[BrowserPlatform.MAC]: 'chrome-mac-x64.zip',
|
||||
[BrowserPlatform.MAC_ARM]: 'chrome-mac-arm64.zip',
|
||||
[BrowserPlatform.WIN32]: 'chrome-win32.zip',
|
||||
[BrowserPlatform.WIN64]: 'chrome-win64.zip',
|
||||
};
|
||||
const filename = filenameMap[platform];
|
||||
if (!filename) return null;
|
||||
return new URL(`${this.mirrorUrl}/chrome/${buildId}/${filename}`);
|
||||
}
|
||||
|
||||
getExecutablePath(options: DownloadOptions): string {
|
||||
const {platform} = options;
|
||||
if (
|
||||
platform === BrowserPlatform.MAC ||
|
||||
platform === BrowserPlatform.MAC_ARM
|
||||
) {
|
||||
return 'chrome-mac/Chromium.app/Contents/MacOS/Chromium';
|
||||
} else if (platform === BrowserPlatform.LINUX) {
|
||||
return 'chrome-linux64/chrome';
|
||||
} else if (platform.includes('win')) {
|
||||
return 'chrome-win64/chrome.exe';
|
||||
}
|
||||
throw new Error(`Unsupported platform: ${platform}`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use with the `install` API:
|
||||
|
||||
```typescript
|
||||
import {install} from '@puppeteer/browsers';
|
||||
|
||||
const customProvider = new SimpleMirrorProvider('https://internal.company.com');
|
||||
|
||||
await install({
|
||||
browser: Browser.CHROME,
|
||||
buildId: '120.0.6099.109',
|
||||
platform: BrowserPlatform.LINUX,
|
||||
cacheDir: '/tmp/puppeteer-cache',
|
||||
providers: [customProvider],
|
||||
});
|
||||
```
|
||||
|
||||
Multiple providers can be chained - they're tried in order until one succeeds, with a default provider such as Chrome for Testing, as an automatic fallback.
|
||||
|
||||
:::caution
|
||||
Custom providers are NOT officially supported by Puppeteer. You accept full responsibility for binary compatibility, testing, and maintenance.
|
||||
:::
|
||||
|
||||
## API
|
||||
|
||||
The programmatic API allows installing and launching browsers from your code. See the `test` folder for examples on how to use the `install`, `canInstall`, `launch`, `computeExecutablePath`, `computeSystemExecutablePath`, and other methods.
|
||||
29
node_modules/@puppeteer/browsers/lib/CLI.d.ts
generated
vendored
Normal file
29
node_modules/@puppeteer/browsers/lib/CLI.d.ts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
import * as readline from 'node:readline';
|
||||
import { Browser } from './browser-data/browser-data.js';
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export declare class CLI {
|
||||
#private;
|
||||
constructor(opts?: string | {
|
||||
cachePath?: string;
|
||||
scriptName?: string;
|
||||
version?: string;
|
||||
prefixCommand?: {
|
||||
cmd: string;
|
||||
description: string;
|
||||
};
|
||||
allowCachePathOverride?: boolean;
|
||||
pinnedBrowsers?: Partial<Record<Browser, {
|
||||
buildId: string;
|
||||
skipDownload: boolean;
|
||||
}>>;
|
||||
}, rl?: readline.Interface);
|
||||
run(argv: string[]): Promise<void>;
|
||||
}
|
||||
//# sourceMappingURL=CLI.d.ts.map
|
||||
1
node_modules/@puppeteer/browsers/lib/CLI.d.ts.map
generated
vendored
Normal file
1
node_modules/@puppeteer/browsers/lib/CLI.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../src/CLI.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAI1C,OAAO,EACL,OAAO,EAIR,MAAM,gCAAgC,CAAC;AAoCxC;;GAEG;AACH,qBAAa,GAAG;;gBAkBZ,IAAI,CAAC,EACD,MAAM,GACN;QACE,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAC,CAAC;QACnD,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,cAAc,CAAC,EAAE,OAAO,CACtB,MAAM,CACJ,OAAO,EACP;YACE,OAAO,EAAE,MAAM,CAAC;YAChB,YAAY,EAAE,OAAO,CAAC;SACvB,CACF,CACF,CAAC;KACH,EACL,EAAE,CAAC,EAAE,QAAQ,CAAC,SAAS;IA+EnB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAyezC"}
|
||||
415
node_modules/@puppeteer/browsers/lib/CLI.js
generated
vendored
Normal file
415
node_modules/@puppeteer/browsers/lib/CLI.js
generated
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
import { spawn } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { stdin as input, stdout as output } from 'node:process';
|
||||
import * as readline from 'node:readline';
|
||||
import { Browser, resolveBuildId, BrowserPlatform, verifyChromeReleaseChannel, } from './browser-data/browser-data.js';
|
||||
import { Cache } from './Cache.js';
|
||||
import { detectBrowserPlatform } from './detectPlatform.js';
|
||||
import { install } from './install.js';
|
||||
import { computeExecutablePath, computeSystemExecutablePath, launch, } from './launch.js';
|
||||
function isValidBrowser(browser) {
|
||||
return Object.values(Browser).includes(browser);
|
||||
}
|
||||
function isValidPlatform(platform) {
|
||||
return Object.values(BrowserPlatform).includes(platform);
|
||||
}
|
||||
// If moved update release-please config
|
||||
// x-release-please-start-version
|
||||
const packageVersion = '3.0.5';
|
||||
// x-release-please-end
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export class CLI {
|
||||
#cachePath;
|
||||
#rl;
|
||||
#scriptName;
|
||||
#version;
|
||||
#allowCachePathOverride;
|
||||
#pinnedBrowsers;
|
||||
#prefixCommand;
|
||||
constructor(opts, rl) {
|
||||
if (!opts) {
|
||||
opts = {};
|
||||
}
|
||||
if (typeof opts === 'string') {
|
||||
opts = {
|
||||
cachePath: opts,
|
||||
};
|
||||
}
|
||||
this.#cachePath = opts.cachePath ?? process.cwd();
|
||||
this.#rl = rl;
|
||||
this.#scriptName = opts.scriptName ?? '@puppeteer/browsers';
|
||||
this.#version = opts.version ?? packageVersion;
|
||||
this.#allowCachePathOverride = opts.allowCachePathOverride ?? true;
|
||||
this.#pinnedBrowsers = opts.pinnedBrowsers;
|
||||
this.#prefixCommand = opts.prefixCommand;
|
||||
}
|
||||
#defineBrowserParameter(yargs, required) {
|
||||
return yargs.positional('browser', {
|
||||
description: 'Which browser to install <browser>[@<buildId|latest>]. `latest` will try to find the latest available build. `buildId` is a browser-specific identifier such as a version or a revision.',
|
||||
type: 'string',
|
||||
coerce: (opt) => {
|
||||
const browser = {
|
||||
name: this.#parseBrowser(opt),
|
||||
buildId: this.#parseBuildId(opt),
|
||||
};
|
||||
if (!isValidBrowser(browser.name)) {
|
||||
throw new Error(`Unsupported browser '${browser.name}'`);
|
||||
}
|
||||
return browser;
|
||||
},
|
||||
demandOption: required,
|
||||
});
|
||||
}
|
||||
#definePlatformParameter(yargs) {
|
||||
return yargs.option('platform', {
|
||||
type: 'string',
|
||||
desc: 'Platform that the binary needs to be compatible with.',
|
||||
choices: Object.values(BrowserPlatform),
|
||||
default: detectBrowserPlatform(),
|
||||
coerce: platform => {
|
||||
if (!isValidPlatform(platform)) {
|
||||
throw new Error(`Unsupported platform '${platform}'`);
|
||||
}
|
||||
return platform;
|
||||
},
|
||||
defaultDescription: 'Auto-detected',
|
||||
});
|
||||
}
|
||||
#definePathParameter(yargs, required = false) {
|
||||
if (!this.#allowCachePathOverride) {
|
||||
return yargs;
|
||||
}
|
||||
return yargs.option('path', {
|
||||
type: 'string',
|
||||
desc: 'Path to the root folder for the browser downloads and installation. If a relative path is provided, it will be resolved relative to the current working directory. The installation folder structure is compatible with the cache structure used by Puppeteer.',
|
||||
defaultDescription: 'Current working directory',
|
||||
...(required ? {} : { default: process.cwd() }),
|
||||
demandOption: required,
|
||||
});
|
||||
}
|
||||
async run(argv) {
|
||||
const { default: yargs } = await import('yargs');
|
||||
const { hideBin } = await import('yargs/helpers');
|
||||
const yargsInstance = yargs(hideBin(argv));
|
||||
let target = yargsInstance
|
||||
.scriptName(this.#scriptName)
|
||||
.version(this.#version);
|
||||
if (this.#prefixCommand) {
|
||||
target = target.command(this.#prefixCommand.cmd, this.#prefixCommand.description, yargs => {
|
||||
return this.#build(yargs);
|
||||
});
|
||||
}
|
||||
else {
|
||||
target = this.#build(target);
|
||||
}
|
||||
await target
|
||||
.demandCommand(1)
|
||||
.help()
|
||||
.wrap(Math.min(120, yargsInstance.terminalWidth()))
|
||||
.parseAsync();
|
||||
}
|
||||
#build(yargs) {
|
||||
const latestOrPinned = this.#pinnedBrowsers ? 'pinned' : 'latest';
|
||||
// If there are pinned browsers allow the positional arg to be optional
|
||||
const browserArgType = this.#pinnedBrowsers ? '[browser]' : '<browser>';
|
||||
return yargs
|
||||
.command(`install ${browserArgType}`, 'Download and install the specified browser. If successful, the command outputs the actual browser buildId that was installed and the absolute path to the browser executable (see --format).', yargs => {
|
||||
if (this.#pinnedBrowsers) {
|
||||
yargs.example('$0 install', 'Install all pinned browsers');
|
||||
}
|
||||
yargs
|
||||
.example('$0 install chrome', `Install the ${latestOrPinned} available build of the Chrome browser.`)
|
||||
.example('$0 install chrome@latest', 'Install the latest available build for the Chrome browser.')
|
||||
.example('$0 install chrome@stable', 'Install the latest available build for the Chrome browser from the stable channel.')
|
||||
.example('$0 install chrome@beta', 'Install the latest available build for the Chrome browser from the beta channel.')
|
||||
.example('$0 install chrome@dev', 'Install the latest available build for the Chrome browser from the dev channel.')
|
||||
.example('$0 install chrome@canary', 'Install the latest available build for the Chrome Canary browser.')
|
||||
.example('$0 install chrome@115', 'Install the latest available build for Chrome 115.')
|
||||
.example('$0 install chromedriver@canary', 'Install the latest available build for ChromeDriver Canary.')
|
||||
.example('$0 install chromedriver@115', 'Install the latest available build for ChromeDriver 115.')
|
||||
.example('$0 install chromedriver@115.0.5790', 'Install the latest available patch (115.0.5790.X) build for ChromeDriver.')
|
||||
.example('$0 install chrome-headless-shell', 'Install the latest available chrome-headless-shell build.')
|
||||
.example('$0 install chrome-headless-shell@beta', 'Install the latest available chrome-headless-shell build corresponding to the Beta channel.')
|
||||
.example('$0 install chrome-headless-shell@118', 'Install the latest available chrome-headless-shell 118 build.')
|
||||
.example('$0 install chromium@1083080', 'Install the revision 1083080 of the Chromium browser.')
|
||||
.example('$0 install firefox', 'Install the latest nightly available build of the Firefox browser.')
|
||||
.example('$0 install firefox@stable', 'Install the latest stable build of the Firefox browser.')
|
||||
.example('$0 install firefox@beta', 'Install the latest beta build of the Firefox browser.')
|
||||
.example('$0 install firefox@devedition', 'Install the latest devedition build of the Firefox browser.')
|
||||
.example('$0 install firefox@esr', 'Install the latest ESR build of the Firefox browser.')
|
||||
.example('$0 install firefox@nightly', 'Install the latest nightly build of the Firefox browser.')
|
||||
.example('$0 install firefox@stable_111.0.1', 'Install a specific version of the Firefox browser.')
|
||||
.example('$0 install firefox --platform mac', 'Install the latest Mac (Intel) build of the Firefox browser.');
|
||||
if (this.#allowCachePathOverride) {
|
||||
yargs.example('$0 install firefox --path /tmp/my-browser-cache', 'Install to the specified cache directory.');
|
||||
}
|
||||
const yargsWithBrowserParam = this.#defineBrowserParameter(yargs, !Boolean(this.#pinnedBrowsers));
|
||||
const yargsWithPlatformParam = this.#definePlatformParameter(yargsWithBrowserParam);
|
||||
return this.#definePathParameter(yargsWithPlatformParam, false)
|
||||
.option('base-url', {
|
||||
type: 'string',
|
||||
desc: 'Base URL to download from',
|
||||
})
|
||||
.option('install-deps', {
|
||||
type: 'boolean',
|
||||
desc: 'Whether to attempt installing system dependencies (only supported on Linux, requires root privileges).',
|
||||
default: false,
|
||||
})
|
||||
.option('format', {
|
||||
type: 'string',
|
||||
desc: 'Format to use for the output. Supported placeholders: {{browser}}, {{buildId}}, {{path}}, {{platform}}',
|
||||
default: '{{browser}}@{{buildId}} {{path}}',
|
||||
});
|
||||
}, async (args) => {
|
||||
if (this.#pinnedBrowsers && !args.browser) {
|
||||
// Use allSettled to avoid scenarios that
|
||||
// a browser may fail early and leave the other
|
||||
// installation in a faulty state
|
||||
const result = await Promise.allSettled(Object.entries(this.#pinnedBrowsers).map(async ([browser, options]) => {
|
||||
if (options.skipDownload) {
|
||||
return;
|
||||
}
|
||||
await this.#install({
|
||||
...args,
|
||||
browser: {
|
||||
name: browser,
|
||||
buildId: options.buildId,
|
||||
},
|
||||
});
|
||||
}));
|
||||
for (const install of result) {
|
||||
if (install.status === 'rejected') {
|
||||
throw install.reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
await this.#install(args);
|
||||
}
|
||||
})
|
||||
.command('launch <browser>', 'Launch the specified browser', yargs => {
|
||||
yargs
|
||||
.example('$0 launch chrome@115.0.5790.170', 'Launch Chrome 115.0.5790.170')
|
||||
.example('$0 launch firefox@112.0a1', 'Launch the Firefox browser identified by the milestone 112.0a1.')
|
||||
.example('$0 launch chrome@115.0.5790.170 --detached', 'Launch the browser but detach the sub-processes.')
|
||||
.example('$0 launch chrome@canary --system', 'Try to locate the Canary build of Chrome installed on the system and launch it.')
|
||||
.example('$0 launch chrome@115.0.5790.170 -- --version', 'Launch Chrome 115.0.5790.170 and pass custom argument to the binary.');
|
||||
const yargsWithExtraAgs = yargs.parserConfiguration({
|
||||
'populate--': true,
|
||||
// Yargs does not have the correct overload for this.
|
||||
});
|
||||
const yargsWithBrowserParam = this.#defineBrowserParameter(yargsWithExtraAgs, true);
|
||||
const yargsWithPlatformParam = this.#definePlatformParameter(yargsWithBrowserParam);
|
||||
return this.#definePathParameter(yargsWithPlatformParam)
|
||||
.option('detached', {
|
||||
type: 'boolean',
|
||||
desc: 'Detach the child process.',
|
||||
default: false,
|
||||
})
|
||||
.option('system', {
|
||||
type: 'boolean',
|
||||
desc: 'Search for a browser installed on the system instead of the cache folder.',
|
||||
default: false,
|
||||
})
|
||||
.option('dumpio', {
|
||||
type: 'boolean',
|
||||
desc: "Forwards the browser's process stdout and stderr",
|
||||
default: false,
|
||||
});
|
||||
}, async (args) => {
|
||||
const extraArgs = args['--']?.filter(arg => {
|
||||
return typeof arg === 'string';
|
||||
});
|
||||
args.browser.buildId = this.#resolvePinnedBrowserIfNeeded(args.browser.buildId, args.browser.name);
|
||||
const executablePath = args.system
|
||||
? computeSystemExecutablePath({
|
||||
browser: args.browser.name,
|
||||
channel: verifyChromeReleaseChannel(args.browser.buildId),
|
||||
platform: args.platform,
|
||||
})
|
||||
: computeExecutablePath({
|
||||
browser: args.browser.name,
|
||||
buildId: args.browser.buildId,
|
||||
cacheDir: args.path ?? this.#cachePath,
|
||||
platform: args.platform,
|
||||
});
|
||||
launch({
|
||||
args: extraArgs,
|
||||
executablePath,
|
||||
dumpio: args.dumpio,
|
||||
detached: args.detached,
|
||||
});
|
||||
})
|
||||
.command('clear', this.#allowCachePathOverride
|
||||
? 'Removes all installed browsers from the specified cache directory'
|
||||
: `Removes all installed browsers from ${this.#cachePath}`, yargs => {
|
||||
return this.#definePathParameter(yargs, true);
|
||||
}, async (args) => {
|
||||
const cacheDir = args.path ?? this.#cachePath;
|
||||
const rl = this.#rl ?? readline.createInterface({ input, output });
|
||||
rl.question(`Do you want to permanently and recursively delete the content of ${cacheDir} (yes/No)? `, answer => {
|
||||
rl.close();
|
||||
if (!['y', 'yes'].includes(answer.toLowerCase().trim())) {
|
||||
console.log('Cancelled.');
|
||||
return;
|
||||
}
|
||||
const cache = new Cache(cacheDir);
|
||||
cache.clear();
|
||||
console.log(`${cacheDir} cleared.`);
|
||||
});
|
||||
})
|
||||
.command('list', 'List all installed browsers in the cache directory', yargs => {
|
||||
yargs.example('$0 list', 'List all installed browsers in the cache directory');
|
||||
if (this.#allowCachePathOverride) {
|
||||
yargs.example('$0 list --path /tmp/my-browser-cache', 'List browsers installed in the specified cache directory');
|
||||
}
|
||||
return this.#definePathParameter(yargs);
|
||||
}, async (args) => {
|
||||
const cacheDir = args.path ?? this.#cachePath;
|
||||
const cache = new Cache(cacheDir);
|
||||
const browsers = cache.getInstalledBrowsers();
|
||||
for (const browser of browsers) {
|
||||
console.log(`${browser.browser}@${browser.buildId} (${browser.platform}) ${browser.executablePath}`);
|
||||
}
|
||||
})
|
||||
.command('bisect <path>', '(experimental) Bisect Chrome for Testing using the specified script. Downloads https://chromium.googlesource.com/chromium/src.git/+/main/tools/bisect-builds.py to ~/bisect-builds.py if needed.', yargs => {
|
||||
return yargs
|
||||
.positional('path', {
|
||||
type: 'string',
|
||||
description: 'Path to a script or test name to bisect.',
|
||||
demandOption: true,
|
||||
})
|
||||
.option('good', {
|
||||
type: 'string',
|
||||
alias: 'g',
|
||||
demandOption: true,
|
||||
desc: 'Last known good version',
|
||||
})
|
||||
.option('bad', {
|
||||
type: 'string',
|
||||
alias: 'b',
|
||||
demandOption: true,
|
||||
desc: 'First known bad version',
|
||||
})
|
||||
.option('cft', {
|
||||
type: 'boolean',
|
||||
desc: 'Use -cft',
|
||||
default: true,
|
||||
});
|
||||
}, async (args) => {
|
||||
const isScript = args.path.endsWith('.mjs') ||
|
||||
args.path.endsWith('.cjs') ||
|
||||
args.path.endsWith('.js');
|
||||
const testCommand = isScript
|
||||
? `PUPPETEER_EXECUTABLE_PATH=%p node ${args.path}`
|
||||
: `BINARY=%p npm run ${args.path}`;
|
||||
const bisectScriptPath = path.join(os.homedir(), 'bisect-builds.py');
|
||||
if (!fs.existsSync(bisectScriptPath)) {
|
||||
console.log('Downloading bisect-builds.py...');
|
||||
const response = await fetch('https://chromium.googlesource.com/chromium/src.git/+/main/tools/bisect-builds.py?format=TEXT');
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to download bisect-builds.py: ${response.statusText}`);
|
||||
}
|
||||
const base64Text = await response.text();
|
||||
const decodedText = Buffer.from(base64Text, 'base64').toString('utf-8');
|
||||
fs.writeFileSync(bisectScriptPath, decodedText, { mode: 0o755 });
|
||||
console.log(`Saved bisect-builds.py to ${bisectScriptPath}`);
|
||||
}
|
||||
const pythonExecutable = 'python3';
|
||||
const bisectArgs = [
|
||||
bisectScriptPath,
|
||||
'-g',
|
||||
args.good,
|
||||
'-b',
|
||||
args.bad,
|
||||
args.cft ? '-cft' : '-s',
|
||||
'-v',
|
||||
'--verify-range',
|
||||
'--not-interactive',
|
||||
'-c',
|
||||
testCommand,
|
||||
];
|
||||
await new Promise((resolve, reject) => {
|
||||
const createProcess = spawn(pythonExecutable, bisectArgs, {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
createProcess.on('error', message => {
|
||||
reject(message);
|
||||
});
|
||||
createProcess.on('exit', code => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Process exited with code ${code}`));
|
||||
}
|
||||
else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
.demandCommand(1)
|
||||
.help();
|
||||
}
|
||||
#parseBrowser(version) {
|
||||
return version.split('@').shift();
|
||||
}
|
||||
#parseBuildId(version) {
|
||||
const parts = version.split('@');
|
||||
return parts.length === 2
|
||||
? parts[1]
|
||||
: this.#pinnedBrowsers
|
||||
? 'pinned'
|
||||
: 'latest';
|
||||
}
|
||||
#resolvePinnedBrowserIfNeeded(buildId, browserName) {
|
||||
if (buildId === 'pinned') {
|
||||
const options = this.#pinnedBrowsers?.[browserName];
|
||||
if (!options || !options.buildId) {
|
||||
throw new Error(`No pinned version found for ${browserName}`);
|
||||
}
|
||||
return options.buildId;
|
||||
}
|
||||
return buildId;
|
||||
}
|
||||
async #install(args) {
|
||||
if (!args.browser) {
|
||||
throw new Error(`No browser arg provided`);
|
||||
}
|
||||
if (!args.platform) {
|
||||
throw new Error(`Could not resolve the current platform`);
|
||||
}
|
||||
args.browser.buildId = this.#resolvePinnedBrowserIfNeeded(args.browser.buildId, args.browser.name);
|
||||
const originalBuildId = args.browser.buildId;
|
||||
args.browser.buildId = await resolveBuildId(args.browser.name, args.platform, args.browser.buildId);
|
||||
await install({
|
||||
browser: args.browser.name,
|
||||
buildId: args.browser.buildId,
|
||||
platform: args.platform,
|
||||
cacheDir: args.path ?? this.#cachePath,
|
||||
downloadProgressCallback: 'default',
|
||||
baseUrl: args.baseUrl,
|
||||
buildIdAlias: originalBuildId !== args.browser.buildId ? originalBuildId : undefined,
|
||||
installDeps: args.installDeps,
|
||||
});
|
||||
const executablePath = computeExecutablePath({
|
||||
browser: args.browser.name,
|
||||
buildId: args.browser.buildId,
|
||||
cacheDir: args.path ?? this.#cachePath,
|
||||
platform: args.platform,
|
||||
});
|
||||
console.log(args.format
|
||||
.replace(/{{browser}}/g, args.browser.name)
|
||||
.replace(/{{buildId}}/g, args.browser.buildId)
|
||||
.replace(/{{path}}/g, executablePath)
|
||||
.replace(/{{platform}}/g, args.platform));
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=CLI.js.map
|
||||
1
node_modules/@puppeteer/browsers/lib/CLI.js.map
generated
vendored
Normal file
1
node_modules/@puppeteer/browsers/lib/CLI.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
89
node_modules/@puppeteer/browsers/lib/Cache.d.ts
generated
vendored
Normal file
89
node_modules/@puppeteer/browsers/lib/Cache.d.ts
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
import { Browser, type BrowserPlatform } from './browser-data/browser-data.js';
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export declare class InstalledBrowser {
|
||||
#private;
|
||||
browser: Browser;
|
||||
buildId: string;
|
||||
platform: BrowserPlatform;
|
||||
readonly executablePath: string;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(cache: Cache, browser: Browser, buildId: string, platform: BrowserPlatform);
|
||||
/**
|
||||
* Path to the root of the installation folder. Use
|
||||
* {@link computeExecutablePath} to get the path to the executable binary.
|
||||
*/
|
||||
get path(): string;
|
||||
readMetadata(): Metadata;
|
||||
writeMetadata(metadata: Metadata): void;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface ComputeExecutablePathOptions {
|
||||
/**
|
||||
* Determines which platform the browser will be suited for.
|
||||
*
|
||||
* @defaultValue **Auto-detected.**
|
||||
*/
|
||||
platform?: BrowserPlatform;
|
||||
/**
|
||||
* Determines which browser to launch.
|
||||
*/
|
||||
browser: Browser;
|
||||
/**
|
||||
* Determines which buildId to download. BuildId should uniquely identify
|
||||
* binaries and they are used for caching.
|
||||
*/
|
||||
buildId: string;
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Metadata {
|
||||
aliases: Record<string, string>;
|
||||
executablePaths?: Record<string, string>;
|
||||
}
|
||||
/**
|
||||
* The cache used by Puppeteer relies on the following structure:
|
||||
*
|
||||
* - rootDir
|
||||
* -- <browser1> | browserRoot(browser1)
|
||||
* ---- <platform>-<buildId> | installationDir()
|
||||
* ------ the browser-platform-buildId
|
||||
* ------ specific structure.
|
||||
* -- <browser2> | browserRoot(browser2)
|
||||
* ---- <platform>-<buildId> | installationDir()
|
||||
* ------ the browser-platform-buildId
|
||||
* ------ specific structure.
|
||||
* @internal
|
||||
*/
|
||||
export declare class Cache {
|
||||
#private;
|
||||
constructor(rootDir: string);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get rootDir(): string;
|
||||
browserRoot(browser: Browser): string;
|
||||
metadataFile(browser: Browser): string;
|
||||
readMetadata(browser: Browser): Metadata;
|
||||
writeMetadata(browser: Browser, metadata: Metadata): void;
|
||||
readExecutablePath(browser: Browser, platform: BrowserPlatform, buildId: string): string | null;
|
||||
writeExecutablePath(browser: Browser, platform: BrowserPlatform, buildId: string, executablePath: string): void;
|
||||
resolveAlias(browser: Browser, alias: string): string | undefined;
|
||||
installationDir(browser: Browser, platform: BrowserPlatform, buildId: string): string;
|
||||
clear(): void;
|
||||
uninstall(browser: Browser, platform: BrowserPlatform, buildId: string): void;
|
||||
getInstalledBrowsers(): InstalledBrowser[];
|
||||
computeExecutablePath(options: ComputeExecutablePathOptions): string;
|
||||
}
|
||||
//# sourceMappingURL=Cache.d.ts.map
|
||||
1
node_modules/@puppeteer/browsers/lib/Cache.d.ts.map
generated
vendored
Normal file
1
node_modules/@puppeteer/browsers/lib/Cache.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../src/Cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EACL,OAAO,EACP,KAAK,eAAe,EAGrB,MAAM,gCAAgC,CAAC;AAMxC;;GAEG;AACH,qBAAa,gBAAgB;;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAIhC;;OAEG;gBAED,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe;IAa3B;;;OAGG;IACH,IAAI,IAAI,IAAI,MAAM,CAMjB;IAED,YAAY,IAAI,QAAQ;IAIxB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAGxC;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IAEvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,KAAK;;gBAGJ,OAAO,EAAE,MAAM;IAI3B;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAIrC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAItC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ;IAaxC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAMzD,kBAAkB,CAChB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI;IAMhB,mBAAmB,CACjB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,GACrB,IAAI;IAUP,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAUjE,eAAe,CACb,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,GACd,MAAM;IAIT,KAAK,IAAI,IAAI;IASb,SAAS,CACP,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,GACd,IAAI;IAqBP,oBAAoB,IAAI,gBAAgB,EAAE;IA+B1C,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,MAAM;CAqCrE"}
|
||||
208
node_modules/@puppeteer/browsers/lib/Cache.js
generated
vendored
Normal file
208
node_modules/@puppeteer/browsers/lib/Cache.js
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { Browser, executablePathByBrowser, getVersionComparator, } from './browser-data/browser-data.js';
|
||||
import { debug } from './debug.js';
|
||||
import { detectBrowserPlatform } from './detectPlatform.js';
|
||||
const debugCache = debug('puppeteer:browsers:cache');
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export class InstalledBrowser {
|
||||
browser;
|
||||
buildId;
|
||||
platform;
|
||||
executablePath;
|
||||
#cache;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(cache, browser, buildId, platform) {
|
||||
this.#cache = cache;
|
||||
this.browser = browser;
|
||||
this.buildId = buildId;
|
||||
this.platform = platform;
|
||||
this.executablePath = cache.computeExecutablePath({
|
||||
browser,
|
||||
buildId,
|
||||
platform,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Path to the root of the installation folder. Use
|
||||
* {@link computeExecutablePath} to get the path to the executable binary.
|
||||
*/
|
||||
get path() {
|
||||
return this.#cache.installationDir(this.browser, this.platform, this.buildId);
|
||||
}
|
||||
readMetadata() {
|
||||
return this.#cache.readMetadata(this.browser);
|
||||
}
|
||||
writeMetadata(metadata) {
|
||||
this.#cache.writeMetadata(this.browser, metadata);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The cache used by Puppeteer relies on the following structure:
|
||||
*
|
||||
* - rootDir
|
||||
* -- <browser1> | browserRoot(browser1)
|
||||
* ---- <platform>-<buildId> | installationDir()
|
||||
* ------ the browser-platform-buildId
|
||||
* ------ specific structure.
|
||||
* -- <browser2> | browserRoot(browser2)
|
||||
* ---- <platform>-<buildId> | installationDir()
|
||||
* ------ the browser-platform-buildId
|
||||
* ------ specific structure.
|
||||
* @internal
|
||||
*/
|
||||
export class Cache {
|
||||
#rootDir;
|
||||
constructor(rootDir) {
|
||||
this.#rootDir = rootDir;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get rootDir() {
|
||||
return this.#rootDir;
|
||||
}
|
||||
browserRoot(browser) {
|
||||
return path.join(this.#rootDir, browser);
|
||||
}
|
||||
metadataFile(browser) {
|
||||
return path.join(this.browserRoot(browser), '.metadata');
|
||||
}
|
||||
readMetadata(browser) {
|
||||
const metatadaPath = this.metadataFile(browser);
|
||||
if (!fs.existsSync(metatadaPath)) {
|
||||
return { aliases: {} };
|
||||
}
|
||||
// TODO: add type-safe parsing.
|
||||
const data = JSON.parse(fs.readFileSync(metatadaPath, 'utf8'));
|
||||
if (typeof data !== 'object') {
|
||||
throw new Error('.metadata is not an object');
|
||||
}
|
||||
return data;
|
||||
}
|
||||
writeMetadata(browser, metadata) {
|
||||
const metatadaPath = this.metadataFile(browser);
|
||||
fs.mkdirSync(path.dirname(metatadaPath), { recursive: true });
|
||||
fs.writeFileSync(metatadaPath, JSON.stringify(metadata, null, 2));
|
||||
}
|
||||
readExecutablePath(browser, platform, buildId) {
|
||||
const metadata = this.readMetadata(browser);
|
||||
const key = `${platform}-${buildId}`;
|
||||
return metadata.executablePaths?.[key] ?? null;
|
||||
}
|
||||
writeExecutablePath(browser, platform, buildId, executablePath) {
|
||||
const metadata = this.readMetadata(browser);
|
||||
if (!metadata.executablePaths) {
|
||||
metadata.executablePaths = {};
|
||||
}
|
||||
const key = `${platform}-${buildId}`;
|
||||
metadata.executablePaths[key] = executablePath;
|
||||
this.writeMetadata(browser, metadata);
|
||||
}
|
||||
resolveAlias(browser, alias) {
|
||||
const metadata = this.readMetadata(browser);
|
||||
if (alias === 'latest') {
|
||||
return Object.values(metadata.aliases || {})
|
||||
.sort(getVersionComparator(browser))
|
||||
.at(-1);
|
||||
}
|
||||
return metadata.aliases[alias];
|
||||
}
|
||||
installationDir(browser, platform, buildId) {
|
||||
return path.join(this.browserRoot(browser), `${platform}-${buildId}`);
|
||||
}
|
||||
clear() {
|
||||
fs.rmSync(this.#rootDir, {
|
||||
force: true,
|
||||
recursive: true,
|
||||
maxRetries: 10,
|
||||
retryDelay: 500,
|
||||
});
|
||||
}
|
||||
uninstall(browser, platform, buildId) {
|
||||
const metadata = this.readMetadata(browser);
|
||||
for (const alias of Object.keys(metadata.aliases)) {
|
||||
if (metadata.aliases[alias] === buildId) {
|
||||
delete metadata.aliases[alias];
|
||||
}
|
||||
}
|
||||
// Clean up executable path entry
|
||||
const key = `${platform}-${buildId}`;
|
||||
if (metadata.executablePaths?.[key]) {
|
||||
delete metadata.executablePaths[key];
|
||||
this.writeMetadata(browser, metadata);
|
||||
}
|
||||
fs.rmSync(this.installationDir(browser, platform, buildId), {
|
||||
force: true,
|
||||
recursive: true,
|
||||
maxRetries: 10,
|
||||
retryDelay: 500,
|
||||
});
|
||||
}
|
||||
getInstalledBrowsers() {
|
||||
if (!fs.existsSync(this.#rootDir)) {
|
||||
return [];
|
||||
}
|
||||
const types = fs.readdirSync(this.#rootDir);
|
||||
const browsers = types.filter((t) => {
|
||||
return Object.values(Browser).includes(t);
|
||||
});
|
||||
return browsers.flatMap(browser => {
|
||||
const files = fs.readdirSync(this.browserRoot(browser));
|
||||
return files
|
||||
.map(file => {
|
||||
const result = parseFolderPath(path.join(this.browserRoot(browser), file));
|
||||
if (!result) {
|
||||
return null;
|
||||
}
|
||||
return new InstalledBrowser(this, browser, result.buildId, result.platform);
|
||||
})
|
||||
.filter((item) => {
|
||||
return item !== null;
|
||||
});
|
||||
});
|
||||
}
|
||||
computeExecutablePath(options) {
|
||||
options.platform ??= detectBrowserPlatform();
|
||||
if (!options.platform) {
|
||||
throw new Error(`Cannot download a binary for the provided platform: ${os.platform()} (${os.arch()})`);
|
||||
}
|
||||
try {
|
||||
options.buildId =
|
||||
this.resolveAlias(options.browser, options.buildId) ?? options.buildId;
|
||||
}
|
||||
catch {
|
||||
debugCache?.('could not read .metadata file for the browser');
|
||||
}
|
||||
const installationDir = this.installationDir(options.browser, options.platform, options.buildId);
|
||||
const storedExecutablePath = this.readExecutablePath(options.browser, options.platform, options.buildId);
|
||||
if (storedExecutablePath) {
|
||||
// The metadata contains a resolved relative path from the installation dir
|
||||
return path.join(installationDir, storedExecutablePath);
|
||||
}
|
||||
return path.join(installationDir, executablePathByBrowser[options.browser](options.platform, options.buildId));
|
||||
}
|
||||
}
|
||||
function parseFolderPath(folderPath) {
|
||||
const name = path.basename(folderPath);
|
||||
const splits = name.split('-');
|
||||
if (splits.length !== 2) {
|
||||
return;
|
||||
}
|
||||
const [platform, buildId] = splits;
|
||||
if (!buildId || !platform) {
|
||||
return;
|
||||
}
|
||||
return { platform, buildId };
|
||||
}
|
||||
//# sourceMappingURL=Cache.js.map
|
||||
1
node_modules/@puppeteer/browsers/lib/Cache.js.map
generated
vendored
Normal file
1
node_modules/@puppeteer/browsers/lib/Cache.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
26
node_modules/@puppeteer/browsers/lib/DefaultProvider.d.ts
generated
vendored
Normal file
26
node_modules/@puppeteer/browsers/lib/DefaultProvider.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
import type { Browser, BrowserPlatform } from './browser-data/browser-data.js';
|
||||
import type { BrowserProvider, DownloadOptions } from './provider.js';
|
||||
/**
|
||||
* Default provider implementation that uses default sources.
|
||||
* This is the standard provider used by Puppeteer.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare class DefaultProvider implements BrowserProvider {
|
||||
#private;
|
||||
constructor(baseUrl?: string);
|
||||
supports(_options: DownloadOptions): boolean;
|
||||
getDownloadUrl(options: DownloadOptions): URL;
|
||||
getExecutablePath(options: {
|
||||
browser: Browser;
|
||||
buildId: string;
|
||||
platform: BrowserPlatform;
|
||||
}): string;
|
||||
getName(): string;
|
||||
}
|
||||
//# sourceMappingURL=DefaultProvider.d.ts.map
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user