735 Commits

Author SHA1 Message Date
chenjinyang
b200f80d88 Merge branch 'develop' of https://gitea.gentronhealth.com/wangyizhe/his into develop 2026-02-11 17:19:38 +08:00
chenjinyang
e57baaead6 修改配置base 2026-02-11 17:18:18 +08:00
chenjinyang
2576f62f88 统一图片路径前缀 2026-02-11 17:03:28 +08:00
chenjinyang
cd24fe007f 修改图片路径 2026-02-11 16:33:54 +08:00
chenjinyang
3898880665 修改门诊挂号文件里图片路径 2026-02-11 16:21:31 +08:00
562e618aaa 更新 openhis-ui-vue3/public/help-center/vuepress-theme-vdoing-doc/docs/01.HIS操作手册/02.门诊挂号/01.门诊挂号操作.md 2026-02-11 16:09:46 +08:00
ec4d57ea69 上传文件至 openhis-ui-vue3/public/help-center/vuepress-theme-vdoing-doc/docs/.vuepress/public/img/png/outpatientregistrationoperation 2026-02-11 15:42:15 +08:00
HuangXinQuan
7a5b26607e Merge branch 'develop' of https://gitea.gentronhealth.com/wangyizhe/his into develop 2026-02-11 14:56:34 +08:00
HuangXinQuan
50ceb98e83 87 门诊医生站-》增加医生常用语维护界面
医生常用语这个实体类继承了基类HisBaseEntity,使用里面的delete_flag的字段进行逻辑删除,保留了enable_flag字段,方便后续实现启用和禁用的功能
2026-02-11 14:56:13 +08:00
chenjinyang
2065395bd2 修改门诊挂号文件里图片路径 2026-02-11 14:52:43 +08:00
HuangShun
517dc41f01 修复mapper路径问题 2026-02-11 14:29:27 +08:00
weixin_45799331
6f8e677045 Merge branch 'develop' of https://gitea.gentronhealth.com/wangyizhe/his into develop 2026-02-11 14:18:52 +08:00
weixin_45799331
1747291f41 96-门诊医生站会诊申请确认界面和97-门诊会诊申请管理界面全部功能。 2026-02-11 14:16:30 +08:00
chenjinyang
cff1e0145b 修改门诊挂号操作文件命名和位置 2026-02-11 14:07:56 +08:00
weixin_45799331
3ab7ea1898 Merge remote-tracking branch 'origin/develop' into develop 2026-02-11 13:41:38 +08:00
weixin_45799331
c5d75f053b 会诊管理中 门诊会诊申请确认和门诊会诊申请管理模块全部功能的实现。包括数据库设计,前端UI设计,后端接口开发。 2026-02-11 13:40:32 +08:00
chenjinyang
730476e927 修改adviceType值为药品,手术安排md文档命名更改 2026-02-11 13:02:10 +08:00
d8a4487b2b 上传文件至 openhis-ui-vue3/public/help-center/vuepress-theme-vdoing-doc/docs/01.HIS操作手册/02.门诊挂号 2026-02-11 12:37:46 +08:00
c93a5f69d8 上传文件至 openhis-ui-vue3/public/help-center/vuepress-theme-vdoing-doc/docs/01.HIS操作手册 2026-02-11 12:04:20 +08:00
HuangShun
b826afb17c 需求76 门诊预约挂号
1.就诊卡号与性别显示
2.选中患者优化
3.解决确认报错
2026-02-11 11:44:42 +08:00
HuangXinQuan
2a5a157c57 获取当前用户的今日日程 2026-02-10 17:25:32 +08:00
chenjinyang
ca9b145d3e 修复手术删除临时医嘱删除问题 2026-02-10 17:10:34 +08:00
HuangShun
7676f03c96 需求102 门诊医生站-》诊断TAB页:增加报卡弹框登记界面;
1.建立对应数据库表infectious_card
2.实现前端表单样式
3.完成相关表单数据查询以及数据传递与保存
2026-02-10 16:56:59 +08:00
chenjinyang
b5b91d8971 完成100需求,补充99需求追溯术中产生的费用新增费用项时向表中插入SourceBillNo和generate_source_enum字段值 2026-02-10 16:49:28 +08:00
HuangXinQuan
f1bddf3fbe 75修改还是提示“当前卫生机构下已存在该科室名称的诊室”。 2026-02-10 15:08:38 +08:00
b1c966f69f fix(sidebar): 解决路由查询参数解析错误问题
- 添加 try-catch 语句处理 JSON.parse 异常
- 当路由查询参数解析失败时返回默认路径
- 记录解析失败的错误信息到控制台
- 确保应用在无效查询参数情况下正常运行
2026-02-10 11:28:07 +08:00
dba6350493 fix(doctorstation): 修复会诊模块数据加载异常处理
- 添加了接口响应空值检查,防止因空响应导致的页面崩溃
- 完善了错误处理逻辑,统一返回空数组避免组件渲染异常
- 增强了网络错误捕获,提供更准确的错误信息提示
- 优化了后端服务异常处理,确保查询失败时返回安全的默认值
- 修复了手术收费模块中的用户卡信息引用错误
- 改进了学生合同号处理逻辑,增加了前置条件验证
2026-02-09 23:47:19 +08:00
HuangXinQuan
6fb5b5993a 75 门诊出诊医生诊室设置的完善 2026-02-09 16:38:54 +08:00
chenjinyang
4c2b015210 修改帮助中心readme静态资源说明规范图片存放便于管理 2026-02-09 13:34:54 +08:00
chenjinyang
9f9f193287 修改门诊手术计费按钮位置更新readme新增静态资源放置及引用说明 2026-02-09 13:03:25 +08:00
chenjinyang
d34a314f02 完成99需求 2026-02-06 17:12:29 +08:00
8d45cfe9db 上传文件至 md/需求 2026-02-06 16:07:22 +08:00
f9d897c081 refactor(surgicalschedule): 更新手术排程页面中的组件导入路径
- 将 SurgeryCharge 组件的导入路径从相对路径 ../../charge/surgerycharge/index.vue 修改为 ../charge/surgerycharge/index.vue
- 修正了因目录结构调整导致的模块解析错误
- 优化了组件间的依赖关系,确保项目结构的一致性
2026-02-06 13:51:41 +08:00
d2616ac2f9 chore(config): 更新日志配置并添加OpenCode技能和命令
- 将MyBatis日志实现从STDOUT更改为SLF4J
- 调整开发环境日志级别从debug降级为info
- 添加OpenCode命令配置文件包括快速开始、文件操作、插件和技能相关命令
- 创建OpenCode技能框架包含代理创建器、命令创建器、插件创建器和技能创建器
- 初始化OpenWork工作区配置文件
- 添加工作区引导和Chrome DevTools演示技能
2026-02-06 13:41:36 +08:00
d2a6780c23 refactor(consultation): 重构会诊模块包结构和日期时间处理
- 将ConsultationRequest相关类从web包移动到consultation包
- 替换java.util.Date为java.time.LocalDateTime进行日期时间处理
- 统一日期时间格式化方式,使用DateTimeFormatter替代SimpleDateFormat
- 优化年龄计算逻辑,使用Java 8时间API替代Calendar
- 在ConsultationRequest实体上添加MyBatis别名注解
- 更新MyBatis映射文件中的命名空间和类型引用
- 调整数据库字段映射,移除无效字段并添加新字段
2026-02-06 13:26:31 +08:00
fc32b83980 refactor(consultation): 重构会诊模块包结构和日期时间处理
- 将ConsultationRequest相关类从web包移动到consultation包
- 替换java.util.Date为java.time.LocalDateTime进行日期时间处理
- 统一日期时间格式化方式,使用DateTimeFormatter替代SimpleDateFormat
- 优化年龄计算逻辑,使用Java 8时间API替代Calendar
- 在ConsultationRequest实体上添加MyBatis别名注解
- 更新MyBatis映射文件中的命名空间和类型引用
- 调整数据库字段映射,移除无效字段并添加新字段
2026-02-06 13:26:28 +08:00
chenjinyang
b936654a11 提交帮助中心模块手册模板及图片 2026-02-06 13:05:38 +08:00
2a525f95b9 refactor(surgicalschedule): 修正手术费用组件导入路径
- 更新 SurgeryCharge 组件的相对路径引用
- 从当前目录调整为上两级目录的正确路径
2026-02-06 12:45:09 +08:00
585b9bd720 Merge remote-tracking branch 'origin/develop' into develop 2026-02-06 12:35:43 +08:00
weixin_45799331
faf73a5ac4 95-门诊医生站开立会诊申请单界面PRD_2026-01-15,全部功能。 2026-02-06 11:24:08 +08:00
89bf85fd97 feat: 门诊手术中计费功能
- 数据库:在adm_charge_item表添加SourceBillNo字段
- 后端实体类:更新ChargeItem.java添加SourceBillNo字段
- 前端组件:创建手术计费界面(基于门诊划价界面)
- 后端API:扩展PrePrePaymentDto支持手术计费标识
- 后端Service:扩展getChargeItems方法支持手术计费过滤
- 门诊手术安排界面:添加【计费】按钮

注意事项:
- 需要手动执行SQL脚本:openhis-server-new/sql/add_source_bill_no_to_adm_charge_item.sql
- 术后一站式结算功能待后续开发
2026-02-05 23:47:02 +08:00
f3d56bff45 feat(menu): 添加菜单缓存刷新功能和拖拽排序支持
- 在SysMenuController中添加refreshCache和refreshCurrentUserMenuCache接口
- 实现菜单缓存的按需刷新和用户级别缓存清理功能
- 优化菜单列表查询的缓存key策略,支持更精确的缓存命中
- 为菜单树查询添加缓存注解提升性能
- 在菜单增删改操作中完善缓存清理逻辑
- 添加allocateMenuToRole方法实现菜单角色分配功能
- 在前端DictTag组件中修复标签类型验证逻辑
- 为首页配置页面添加拖拽排序功能,支持快捷功能重新排列
- 集成Sortable.js实现拖拽交互和排序保存
- 优化菜单管理页面的缓存刷新机制和数据展示
- 完善配置更新事件处理,支持实时配置同步
2026-02-05 23:07:31 +08:00
chenjinyang
cd6c015d8f 提交OpScheduleDto 2026-02-05 16:39:41 +08:00
chenjinyang
dfdab41c00 完成93需求 2026-02-05 16:30:25 +08:00
HuangXinQuan
f69de5e78f 医生排班日期的正确插入 2026-02-05 16:00:56 +08:00
HuangShun
74892ea80f 修复Bug138 系统管理-》基础数据-》病区/床位管理:关联科室字段的下拉选项 2026-02-05 11:24:43 +08:00
HuangShun
4bf74a1ff0 修复Bug131 【入出转管理】-》入院病区下拉框无数据,后面的相应联动框应该也有数据 2026-02-05 10:22:09 +08:00
3a53837e50 项目修改插入时不按照序号排列异常 2026-02-04 17:25:13 +08:00
HuangShun
2c2bb1adb0 实现需求56 检查项目设置-》检查类型维护中的分页功能。 2026-02-04 16:03:41 +08:00
HuangXinQuan
a434dfdfff 73 门诊医生排班管理 2026-02-03 17:36:29 +08:00
4c14d802c4 取药科室下项目显示异常,没有耗材库的修复 2026-02-03 16:03:32 +08:00
a7602057e2 Revert "套餐设置套餐管理完善"
This reverts commit 6c15f0d4d5.
2026-02-03 15:30:47 +08:00
97af9d5eee Merge branch 'develop' of https://gitea.gentronhealth.com/py/his into develop 2026-02-03 15:29:32 +08:00
wangjian963
3cabb5f803 Merge remote-tracking branch 'origin/develop' into develop 2026-02-03 15:16:03 +08:00
wangjian963
a55884a710 维护多个挂号类型的医生,只能检索出一个医生的问题。 2026-02-03 15:15:55 +08:00
dfac362c37 Merge branch 'develop' of https://gitea.gentronhealth.com/py/his into develop 2026-02-03 15:11:03 +08:00
HuangShun
897afd4da2 修复Bug130 【门诊挂号】-》【新增患者】性别设置有2个,多了一个;将页面回退至需求37 门诊挂号-》新增患者 /页面,并实现患者新建患者档案年龄校验 2026-02-03 14:55:13 +08:00
3d31b3482a 套餐设置套餐管理完善 2026-02-03 14:03:07 +08:00
3acf8ad50a Merge branch 'develop' of https://gitea.gentronhealth.com/py/his into develop 2026-02-03 14:00:59 +08:00
HuangShun
fa06a52d71 需求85 门诊挂号-》预约号源已缴费签到未看诊进行退号;建立退费表,在退诊时将相应数据插入到表中。 2026-02-03 10:31:58 +08:00
d1b290881f 上传文件至 md/需求 2026-02-02 16:51:23 +08:00
5781e39c20 Merge remote-tracking branch 'origin/develop' into develop 2026-02-02 16:28:39 +08:00
9ed43c9413 feat(home): 添加医生专属患者统计和菜单跳转功能
- 在HomeStatisticsDto中新增我的患者数量和待写病历数量字段
- 实现医生患者查询功能,支持按租户隔离数据
- 更新首页统计服务,为医生用户提供专属患者统计数据
- 添加菜单名称点击跳转功能,支持路由导航和外部链接打开
- 修复首页统计数据显示,确保医生看到正确的患者数量
- 添加医保日结结算相关实体、服务和前端页面
- 配置前端路由控制器,支持Vue Router History模式
2026-02-02 16:28:31 +08:00
270004afee Merge branch 'develop' of https://gitea.gentronhealth.com/py/his into develop 2026-02-02 15:02:06 +08:00
HuangShun
96941cb4e0 修复需求56 检查项目设置-》检查类型维护中去掉选择部位勾选框点击【保存】按钮未实现数据存储。 2026-02-02 11:50:15 +08:00
6c15f0d4d5 套餐设置套餐管理完善 2026-02-02 11:08:19 +08:00
HuangShun
063be326eb 修复Bug125 【住院登记】的入院科室无法选择,入院病区也无法选择;修改科室数据来源 2026-02-02 10:55:04 +08:00
5534a71c7d feat(menu): 优化菜单服务性能并新增医生排班功能
- 添加菜单缓存注解以提升查询性能
- 实现菜单完整路径计算优化,解决 N+1 查询问题
- 新增 selectAllMenus 方法供路径计算使用
- 添加今日医生排班查询功能
- 重构前端图标显示逻辑,使用 SVG 图标替代 Element 图标
- 添加前端菜单数据本地缓存机制
- 更新菜单管理界面的表单组件绑定方式
- 新增预约管理、门诊管理和药房管理路由配置
2026-02-02 08:46:33 +08:00
669d669422 refactor(home): 更新工作流任务API导入路径
- 将 '@/api/workflow/task' 导入路径更改为 '@/api/workflow/task.js'
2026-02-01 15:06:15 +08:00
98fe9f3301 feat(router): 添加医生工作站等功能模块路由配置
- 新增医生工作站路由,包含待写病历功能
- 添加全部功能模块路由,支持功能列表和配置页面
- 集成待办事项模块路由,完善工作流功能
- 配置相关API接口和服务类,实现用户配置管理
- 实现待写病历列表展示和相关业务逻辑
- 完善首页统计数据显示功能
2026-02-01 15:05:57 +08:00
6f7d723c6b Merge remote-tracking branch 'origin/develop' into develop 2026-02-01 14:51:14 +08:00
0a08088ada feat(menu): 添加菜单完整路径功能和待写病历管理
- 在SysMenu实体类中新增fullPath字段用于存储完整路径
- 实现buildMenuTreeWithFullPath方法构建带完整路径的菜单树
- 添加getMenuFullPath和generateFullPath服务方法获取和生成完整路径
- 在菜单控制器中增加获取完整路径的API接口
- 前端菜单组件显示完整路径并在新增修改时使用后端返回的路径
- 添加待写病历管理功能包括获取待写病历列表、数量统计和检查接口
- 在医生工作站界面集成待写病历选项卡和相关处理逻辑
- 更新首页统计数据接口路径并添加待写病历数量获取功能
- 重构首页快捷功能配置为动态从数据库获取用户自定义配置
- 优化菜单列表查询使用异步方式处理带完整路径的菜单数据
- 添加菜单完整路径的数据库映射配置和前端API调用支持
2026-02-01 14:50:22 +08:00
HuangShun
48309fcaa4 需求56 检查项目设置-》检查类型维护;在check_type表中增加一个parent_id字段用于父行与子行绑定;修改执行科室下拉字典的数据来源 2026-01-30 15:31:01 +08:00
wangjian963
28160e082c 收费工作站-门诊挂号:点击【确认】退号无响应 2026-01-30 12:02:37 +08:00
wangjian963
29ecfd90f2 修复收费工作站-门诊挂号:挂号类型字段内容重复显示 2026-01-30 11:10:36 +08:00
f690b78b18 上传文件至 md/需求/media 2026-01-29 22:39:47 +08:00
6f71c678bd 上传文件至 md/需求 2026-01-29 22:39:03 +08:00
1c781c1224 套餐设置套餐管理完善 2026-01-29 15:32:21 +08:00
HuangShun
638f853af6 需求17 门诊医生站-》患者列表,修复门诊医生站的初诊/复诊标识没有完成数据存储和显示 2026-01-29 14:59:07 +08:00
HuangShun
96a8f75aa1 修复Bug128 门诊管理-》门诊划价:【新增】诊疗项目在点击【签发】报错 2026-01-29 11:47:40 +08:00
15a6445e26 Merge remote-tracking branch 'origin/develop' into develop 2026-01-28 15:31:04 +08:00
0e4b0ad6fd feat(accomplishList): 设置默认按申请时间倒序排列
- 添加申请时间字段排序功能
- 设置默认排序方式为降序
- 优化控制台日志输出格式
- 移除多余的等号字符
2026-01-28 15:30:54 +08:00
HuangShun
7da461a9cb 需求56 检查项目设置-》检查类型维护;界面代码被误修,回滚提交 2026-01-28 15:00:03 +08:00
b0040bcd48 Merge remote-tracking branch 'origin/develop' into develop 2026-01-28 14:37:48 +08:00
fa5394cc35 feat(organization): 优化科室分类查询功能
- 修改 getOrganizationTree 方法参数,将 classEnum 字符串改为 classEnumList 列表
- 实现多选科室分类的精确匹配查询逻辑
- 添加分页查询时只显示未删除记录的过滤条件
- 更新控制器中对逗号分隔参数的解析逻辑
- 修复查询条件构造中的逻辑错误
- 配置 Lombok 注解处理器路径
- 重命名诊断服务方法名以提高可读性
- 修复医保模块中诊断查询方法调用
- 修复集合初始化语法错误
2026-01-28 14:36:25 +08:00
81cc8b08a0 Merge remote-tracking branch 'origin/develop' into develop 2026-01-28 14:29:29 +08:00
0cecf3bcad 套餐设置套餐管理完善 2026-01-28 14:26:41 +08:00
HuangShun
b8d7e3cdf1 修复125 【住院登记】的入院科室无法选择,入院病区也无法选择 2026-01-28 14:05:35 +08:00
weixin_45799331
df2a4c1694 Merge remote-tracking branch 'origin/develop' into develop 2026-01-28 12:12:13 +08:00
weixin_45799331
a6a4e0ed58 sse实时开发 微修 2026-01-28 12:11:50 +08:00
HuangShun
ba31371b6f 修复124 系统管理-》业务规则配置-》执行科室配置:项目名称显示数字 2026-01-28 09:38:00 +08:00
9bd5caaa1b Fix 住院工作站中,住院病历的入院记录不吻合问题 2026-01-27 18:41:29 +08:00
164e4a4b75 Merge remote-tracking branch 'origin/develop' into develop 2026-01-27 17:32:15 +08:00
4f0cc1a0c4 refactor(ui): 优化按钮样式和数据加载逻辑
- 将多个按钮组件从 type="text" 改为 link 属性,提升界面美观性
- 修复 PatientList 组件中姓名显示的文本截断功能
- 在住院记录模板中添加对 patientInfo 变化的监听,自动更新表单数据
- 优化打印机列表获取逻辑,添加连接状态检查和警告信息
- 移除不必要的防抖和重复请求防护逻辑,简化代码实现
- 修复多处组件中对 patientInfo 属性访问的安全性问题
- 优化病历数据加载时机,移除防抖包装直接调用加载函数
- 改进数据设置逻辑,避免覆盖未传入字段的原有值
- 调整组件属性定义,使 patientInfo 参数变为可选并设置默认值
- 优化患者切换时的组件重置和数据加载流程
2026-01-27 17:32:03 +08:00
HuangXinQuan
6dedb92b54 87 门诊医生站-》增加医生常用语权限管理 2026-01-27 17:10:33 +08:00
HuangShun
0f0dc70c7e 修复123 系统管理-》基础数据-》门诊号源管理:修改出诊医生字段内容未保存成功 2026-01-27 16:20:09 +08:00
HuangShun
acfce391dc 需求17 门诊医生站-》患者列表;从adm_encounter表中查询到first_enum字段用以判断初复诊 2026-01-27 15:39:04 +08:00
weixin_45799331
b0f2eabf6b sse实时开发 2026-01-27 13:31:03 +08:00
weixin_45799331
c5db404290 88 分诊排队管理-》科室叫号显示屏 表triage_queue_item中添加了联合索引queue_date,organization_id,tenant_id,queue_order。添加了room_no,practitioner_id字段。新增的实体类刚刚没提交 2026-01-27 13:28:44 +08:00
weixin_45799331
c4c3073be0 88 分诊排队管理-》科室叫号显示屏 表triage_queue_item中添加了联合索引queue_date,organization_id,tenant_id,queue_order。添加了room_no,practitioner_id字段。 2026-01-27 11:15:15 +08:00
41494ebf7c 诊疗下面没有项目的代码冲突 2026-01-27 11:05:43 +08:00
HuangShun
4de4d9099e 修复122 门诊医生站-》医嘱TAB:点击选中项目后查询框自动关闭 2026-01-27 10:56:25 +08:00
497af01f9b chore(config): 调整应用日志级别配置
- 将 com.openhis 包的日志级别从 debug 调整为 info
- 将 com.baomidou.mybatisplus 的日志级别从 debug 调整为 info
- 将 com.openhis.web.regdoctorstation.mapper 的日志级别从 debug 调整为 info
- 将 org.springframework.jdbc.core 的日志级别从 debug 调整为 info
- 将 com.alibaba.druid 的日志级别从 debug 调整为 info
- 将 com.alibaba.druid.sql 的日志级别从 debug 调整为 info
2026-01-27 10:53:37 +08:00
ffc1f29b80 chore(config): 更新开发环境数据库和Redis连接配置
- 修改PostgreSQL数据库连接地址从47.116.196.11到192.168.110.252
- 修改Redis服务器地址从47.116.196.11到192.168.110.252
- 修改Redis端口从26379调整为默认端口6379
2026-01-27 10:45:56 +08:00
86bca03b04 Backup local changes before resolving remote repository issue 2026-01-27 10:19:54 +08:00
11c2758289 test 2026-01-27 10:19:54 +08:00
802f845231 检验项目设置-套餐设置-套餐管理 2026-01-27 09:26:27 +08:00
HuangShun
ea5215a1b0 修复101 门诊医生站-》门诊病历配置了未显示 2026-01-26 16:05:41 +08:00
a9fb093d9c 上传文件至 md/需求/media 2026-01-26 15:12:39 +08:00
chenjinyang
f4bf064f08 Merge remote-tracking branch 'origin/develop' into develop 2026-01-26 13:50:02 +08:00
chenjinyang
4dd824d296 完成帮助中心的改造 2026-01-26 13:49:43 +08:00
3ab6c2d424 刪除测试上传md内容 2026-01-26 13:42:48 +08:00
12b2bf255c 上传文件至 md/需求/aaa 2026-01-26 13:41:20 +08:00
sindir
c878dc19d7 86门诊医生站-》西药方 2026-01-26 13:25:02 +08:00
sindir
c1efd84332 55门诊医生站-》中医:诊断字段 2026-01-26 13:21:45 +08:00
1616f66fc4 诊疗下没有项目功能完善 2026-01-26 11:59:13 +08:00
wangjian963
2df1ed645f Merge remote-tracking branch 'origin/develop' into develop 2026-01-26 11:08:59 +08:00
wangjian963
4f7fc1c09a 修改目录管理-诊疗目录-划价标记字段。 2026-01-26 11:08:46 +08:00
bd873f81d2 诊疗下没有项目功能完善 2026-01-26 10:10:42 +08:00
1975fda73c feat(common): 添加审计字段工具类和基础服务
- 实现AuditFieldUtil工具类,支持通过反射设置创建人、创建时间、更新人、更新时间字段
- 支持驼峰命名和下划线命名的字段格式
- 只有当字段值为null或空字符串时才进行设置,避免覆盖已有值
- 实现BaseService基类,自动在保存和更新操作时设置审计字段
- 继承MyBatis-Plus的ServiceImpl,提供save、saveBatch、updateById方法的审计字段自动设置
- 集成SecurityUtils获取当前登录用户信息用于设置操作人字段
2026-01-25 23:17:30 +08:00
ffce6f81c3 feat(core): 完善自动填充机制和时间格式化处理
- 替换 ServiceImpl 继承为 BaseService 以支持自动填充功能
- 在 HisBaseEntity 中添加 JsonFormat 注解统一时间格式化
- 重构 MybastisColumnsHandler 实现完整的自动填充逻辑,包括 createTime、updateTime、createBy、updateBy 和 tenantId 字段
- 添加详细的日志记录和异常处理机制
- 在 PractitionerAppServiceImpl 中增强租户ID和审计字段的设置逻辑
- 优化时间解析工具类 openhis.js 以正确处理 ISO 8601 格式时间字符串
- 更新数据库映射文件以支持下划线字段名映射
- 重构 SysUserServiceImpl 实现完整的审计字段自动填充机制
2026-01-25 23:13:04 +08:00
ca043de624 feat(inpatientDoctor): 添加住院医生模块本地病人信息状态管理
- 新增本地病人信息状态管理文件 localPatient.js
- 实现护士等级状态管理功能
- 添加选择患者信息本地状态管理
- 提供更新护士等级和患者信息的方法
2026-01-25 16:43:12 +08:00
054b51c63d Merge remote-tracking branch 'origin/develop' into develop 2026-01-25 16:42:23 +08:00
5cf2dd165c fix(core): 修复审计字段缺失和组件状态管理问题
- 在Account、ChargeItem、EncounterParticipant和Encounter服务中添加审计字段验证
- 确保tenantId、createBy和createTime字段在插入数据库前正确设置
- 修复EMR模块中删除模板API的导出问题
- 更新患者信息状态管理,统一使用localPatientInfo替换patientInfo
- 在EMR组件中实现防抖机制优化历史记录刷新性能
- 修复病历模板切换时的表单数据重置逻辑
- 在首页统计组件中使用markRaw包装图标组件
- 为住院记录模板添加默认表单数据结构
- 修复SVG患者图标路径错误
2026-01-25 16:41:19 +08:00
27b094744c 创建 md 下文件夹 2026-01-24 14:54:44 +08:00
wangjian963
55e3533600 Merge remote-tracking branch 'origin/develop' into develop 2026-01-23 17:11:51 +08:00
wangjian963
1522183432 门诊管理-》门诊划价:新增耗材点击【保存】报错的问题(设置租户id,创建者,创建时间) 2026-01-23 17:08:29 +08:00
6382741b71 上传文件至 md/需求 2026-01-23 16:49:43 +08:00
16c854d55f feat(router): 添加基础管理和发票管理路由配置
- 新增基础管理模块路由配置,包含发票管理子页面
- 配置动态路由中的发票管理组件路径
- 移除监控模块的路由配置
- 修复路由数组结构,移除多余的逗号
2026-01-23 16:17:00 +08:00
73617e1b0f Merge remote-tracking branch 'origin/develop' into develop 2026-01-23 16:13:57 +08:00
abd5bd9f2f feat(system): 添加菜单显示状态控制功能并完善租户ID设置
- 在MetaVo中添加visible字段用于控制菜单显示状态
- 修改SysMenuServiceImpl中的路由构建逻辑,传递visible信息到前端
- 更新SidebarItem.vue组件,根据visible属性控制菜单项显示
- 在多个医嘱管理相关服务类中显式设置租户ID以确保多租户隔离
- 调整字典管理相关路由配置,优化页面跳转路径
- 在菜单管理界面添加显示状态查询和表格列展示功能
2026-01-23 16:12:56 +08:00
HuangShun
9000d66c0c 修复107 系统管理-》基础数据-》科室管理:科室分类筛选条件无效中搜索条件清空问题 2026-01-23 14:06:07 +08:00
huhuihua
61be9ff552 46 门诊医生站-》开立诊断:优化 修改数据库中一些字段不能为null 2026-01-23 13:58:33 +08:00
huhuihua
9408cf6c2d Merge branch 'develop' of https://gitea.gentronhealth.com/wangyizhe/his into develop 2026-01-23 13:58:25 +08:00
HuangShun
66c70a2b4a 修复103 门诊医生站-》药品医嘱开立内容重复/【确认】无响应 2026-01-23 13:28:17 +08:00
f6d9321f95 代码回滚 2026-01-23 11:08:54 +08:00
ccff9a7246 fix(hospitalizationEmr): 解决病历模板切换时数据显示残留问题
- 在切换模板前重置表单数据,避免显示之前的数据
- 先清空当前组件再设置新组件,确保组件完全重新渲染
- 使用 nextTick 确保 DOM 更新后再设置新组件
- 添加 JSON 解析异常处理,解析失败时清空组件数据
- 当没有历史记录或加载出错时清空表单数据
- 患者信息变化时重置当前组件和表单数据
- 没有患者信息时也重置组件和表单数据
2026-01-22 22:36:54 +08:00
2884f610f5 refactor(pharmacy): 激活药品仓库各类订单的供应分类选项
- 激活损益订单中的通用损益、盘点损益和制剂消耗分类选项
- 更新采购订单中的库存供应和非库存供应分类选项
- 激活退货订单中的普通分类选项
- 激活退仓订单中的普通分类选项
- 激活入库订单中的外购药品、自制药品、代销药品、其他药品和赠送药品入库分类选项
- 激活出库订单中的院内出库、院外出库和其他出库分类选项
- 激活盘点订单中的普通盘点和月度盘点分类选项
- 在枚举类中启用所有被注释的供应分类并完善文档注释
2026-01-22 22:24:22 +08:00
wangjian963
035738f990 修改库房管理-》采购管理-》采购入库:仓库字段值为中心耗材库在采购管理未显示的问题,修改了采购入库仓库字段值的布局样式,修改了在批量保存入库业务中添加申请人等核心数据数据,
修改了获取入库数据的查询SQL语句。
2026-01-22 19:38:58 +08:00
sindir
d0c6f57f6b 解决了无法接诊的问题 2026-01-22 16:37:20 +08:00
huhuihua
58c1e02415 Merge branch 'develop' of https://gitea.gentronhealth.com/wangyizhe/his into develop 2026-01-22 15:58:55 +08:00
huhuihua
1e459b8883 46 门诊医生站-》开立诊断:优化 2026-01-22 15:51:37 +08:00
huabuweixin
0d57e984a6 76 门诊预约挂号 2026-01-22 15:09:52 +08:00
4450e3cc50 上传文件至 md/需求 2026-01-22 15:08:57 +08:00
wangjian963
902ee0587e 修改新增耗材“一次性静脉采血器” 点击保存categoryEnum为空值的问题。 2026-01-22 14:13:10 +08:00
49550fcc2e 诊疗下面没有诊疗项目 2026-01-22 14:03:38 +08:00
sindir
1dd7ee3428 90,分诊排队管理-》医生叫号界面 2026-01-22 12:14:01 +08:00
wangjian963
8dff5d466a Merge remote-tracking branch 'origin/develop' into develop 2026-01-22 09:22:22 +08:00
wangjian963
19ada4ace9 移除调用字典接口功能 2026-01-22 09:20:35 +08:00
c92ff38133 Merge remote-tracking branch 'origin/develop' into develop 2026-01-21 17:50:58 +08:00
1c07108e58 refactor(PatientList): 重构患者列表卡片布局结构
- 将原有的 header-top 和 header-bottom 结构替换为 info-row 统一布局
- 新增姓名、性别年龄、房间床号、住院号、保险类型等独立信息行
- 使用 el-text 组件优化姓名显示效果
- 为性别标签添加女性样式标识
- 调整床位信息展示方式,支持溢出省略
- 修改溢出属性从 hidden 为 visible 确保内容正常显示
- 优化标签样式和间距布局
- 隐藏已废弃的旧布局元素
- 调整 pending 患者列表的换行和对齐方式
2026-01-21 17:50:51 +08:00
weixin_45799331
34dd969cb4 门诊医生站-》医嘱:诊疗开具医嘱点击项目选择下拉框,获取时间过慢40多秒,解决了之后正常情况获取4秒 2026-01-21 17:27:28 +08:00
a0b546266d fix(mapper): 修复患者主信息查询的重复数据问题
- 在 getRegPatientMainInfo 查询中添加 DISTINCT ON 子句按 patient_id 去重
- 为分页功能添加 getRegPatientMainInfoCount 计数查询
- 修复 SQL 拼接条件的语法错误,将 ${ew.customSqlSegment} 替换为标准的动态 SQL 标签
- 调整字典标签查询逻辑,先查询指定表再回退到默认字典缓存
- 优化查询性能,避免不必要的数据重复和错误的 SQL 语法
- 添加缺失的 ORDER BY 子句确保查询结果的一致性
2026-01-21 16:22:05 +08:00
wangjian963
fc9ce6241e Merge remote-tracking branch 'origin/develop' into develop 2026-01-21 13:38:23 +08:00
wangjian963
5187ff1ae3 添加申请单表单患者信息自动填充姓名、就诊卡号、费用性质,以及申请医生和申请科室的输入框格式,
依据申请单和申请单明细表字段修改表单变量名。
2026-01-21 13:34:31 +08:00
huabuweixin
73b1d01044 修复
104 系统管理-》业务规则配置-》取药科室配置:开立科室字段内容显示不全
2026-01-21 10:02:04 +08:00
huabuweixin
b88ad89146 修复
107
系统管理-》基础数据-》科室管理:科室分类筛选条件无效
2026-01-20 18:02:41 +08:00
huabuweixin
de8039c513 Merge branch 'develop' of https://gitea.gentronhealth.com/wangyizhe/his into develop 2026-01-20 18:01:46 +08:00
3464153d93 Merge remote-tracking branch 'origin/develop' into develop 2026-01-20 17:31:07 +08:00
6b868e378f feat(router): 添加新功能模块路由配置
- 添加套餐管理相关路由到公共路由,确保始终可用
- 新增基础管理模块,包含发票管理功能
- 添加系统监控模块,包含操作日志、登录日志、定时任务功能
- 新增系统工具模块,包含代码生成功能
- 扩展系统管理模块,增加租户用户、合同管理、用户角色授权等功能
- 添加字典数据、任务日志、代码生成编辑等隐藏路由
- 统一修复代码格式,调整对象属性间的空格格式
- 完善路由元信息配置,添加权限控制和图标支持
2026-01-20 17:30:42 +08:00
f6403fa059 Fix 禅道 108 系统管理-》业务规则配置-》执行科室配置:【添加新项目】按钮无法操作 2026-01-20 17:12:26 +08:00
sindir
bc92b9aa62 正确转到字典类型页面 2026-01-20 16:29:30 +08:00
sindir
46145ff636 正确转到字典类型页面 2026-01-20 16:19:54 +08:00
huhuihua
3ad32fac9f 46 门诊医生站补充 2026-01-20 10:02:48 +08:00
d1223aec07 挂号补单功能的完善 2026-01-20 09:31:37 +08:00
649f7bcf5b fix(database): 修复患者首页查询重复数据和关联查询问题
- 在ATDManageAppMapper.xml中添加DISTINCT关键字解决入院患者信息重复问题
- 重构PatientHomeAppMapper.xml中的复杂查询逻辑,使用子查询替代多层JOIN提高性能
- 修复vital signs查询中的字段关联错误,将base_service_req_id改为request_id
- 优化前端implementDepartment组件的数据加载逻辑,添加异步处理和错误捕获
- 为诊疗项目下拉框添加数据加载状态检查,防止空数据导致的界面异常
- 实现防抖机制和数据量限制,提升大数据量下的响应性能
- 添加并行数据加载,减少页面初始化时间
2026-01-20 08:24:07 +08:00
a3dce8de60 fix(inhospitalnurse): 优化住院护士站患者管理和床位分配功能
- 移除住院参与者更新失败时的异常返回,改为静默处理
- 更新床位分配提示信息,为用户提供更清晰的操作指导
- 实现实施科室下拉选择器的远程搜索功能,提升大数据量下的用户体验
- 添加节点切换时的未保存数据确认提醒,防止数据丢失
- 优化实施科室管理页面的选项过滤和加载状态管理
2026-01-19 23:18:38 +08:00
f81dd54f0c Merge remote-tracking branch 'origin/develop' into develop 2026-01-19 22:36:12 +08:00
803e4d0bb5 refactor(inhospitalnursestation): 优化入院护士站应用的数据库查询性能
- 将CTE查询重构为子查询以提高执行效率
- 为位置和医生查询添加LIMIT 1约束以减少数据量
- 移除不必要的GROUP BY子句以简化查询逻辑
- 在前端组件中实现异步数据加载和错误处理机制
- 使用可选链操作符处理空值情况避免报错
- 添加防抖机制解决单击双击冲突问题
- 优化患者列表和床位列表的并行加载逻辑
- 清理调试用的console.log语句并替换为有意义的信息
2026-01-19 22:36:04 +08:00
deebcde41f 依赖标记更新 2026-01-19 21:48:43 +08:00
095c43bbf3 修复医嘱下获取读取慢问题,同时解决系列字典表读取慢问题 2026-01-19 21:48:11 +08:00
aa3beb848b fix(patient): 修复患者信息新增和更新逻辑
- 修改handlePatientInfo方法中的患者对象初始化逻辑
- 添加患者ID存在时的查询验证机制
- 区分新增和更新操作分别调用不同的服务方法
- 移除重复的身份证号查询条件优化性能
- 统一患者信息保存和更新的操作流程
2026-01-19 21:41:05 +08:00
sindir
ae96bbd0bb 医生常用语管理 - 行内编辑改为弹窗编辑,优化编辑体验。新增编辑弹窗,点击编辑按钮弹窗回显数据,修改更便捷 2026-01-19 17:25:37 +08:00
sindir
1a2c444269 Merge branch 'develop' of https://gitea.gentronhealth.com/wangyizhe/his into develop 2026-01-19 15:47:38 +08:00
sindir
9cba8fea12 完善医生常用语管理功能
### 后端修改
1. 实体类DoctorPhrase:字段/注解调整
2. 枚举完善:新增DoctorPhraseAppTypeEnum/DoctorPhraseBizTypeEnum,统一业务分类
3. 服务实现类:修正类名拼写(DoctorPhraesAppS → DoctorPhraseAppServiceImpl
### 前端修改
1. 常用语管理页面(doctorphrase/index.vue):
   业务分类硬编码替换为枚举(主诉/现病史/术前/术后/既往史)
2026-01-19 15:43:34 +08:00
huabuweixin
f11b7380a4 Merge remote-tracking branch 'origin/develop' into develop 2026-01-19 15:01:28 +08:00
da17b2b89c fix(inpatient): 修复就诊位置更新逻辑
- 修改就诊位置表更新方式,直接更新指定ID的记录
- 添加位置ID设置功能
- 使用updateById方法替代saveOrUpdate方法提高准确性
2026-01-19 14:22:39 +08:00
9e4a010a8d Merge remote-tracking branch 'origin/develop' into develop 2026-01-19 11:39:58 +08:00
7e76083c37 feat(doctorstation): 优化医生工作站处方列表功能
- 调整诊疗定义表结构,添加序号和服务范围字段
- 修改费用项目查询逻辑,使用INNER JOIN替代LEFT JOIN并优化排序
- 增加批处理批次大小从500到1000,提升查询性能
- 修复处方类型筛选中的诊疗和耗材顺序错误
- 优化处方行数据重置逻辑,避免残留数据问题
- 移除不必要的README标题元素
2026-01-19 11:39:29 +08:00
de105adbdc 上传文件至 md/需求 2026-01-19 11:28:29 +08:00
f3eeee7405 refactor(doctorstation): 优化医嘱基础列表组件性能和数据处理
- 实现虚拟滚动表格以提升大数据量渲染性能
- 添加数据缓存机制减少重复API请求
- 增强节流防抖功能优化搜索响应
- 重构数据过滤逻辑支持本地快速检索
- 添加加载状态提示改善用户体验
- 优化表格列宽度设置提升界面美观度
- 修复医保等级显示和价格获取逻辑
- 后端服务增加分批处理避免大量参数问题
- 添加空值安全检查防止运行时错误
- 统一数据结构处理药品耗材诊疗不同类型
2026-01-19 10:37:46 +08:00
97f04d0b15 fix(inpatient): 修复就诊位置更新逻辑
- 修改就诊位置表更新方式,直接更新指定ID的记录
- 添加位置ID设置功能
- 使用updateById方法替代saveOrUpdate方法提高准确性
2026-01-18 19:44:32 +08:00
5667e04d12 fix(organization): 修复组织查询中class_enum字段的多值匹配逻辑
- 将FIND_IN_SET函数替换为LIKE操作符组合,提高PostgreSQL兼容性
- 添加子查询包装器支持多种匹配模式
- 实现精确匹配、前缀匹配、后缀匹配和中间匹配四种查询方式
- 确保逗号分隔的枚举值能够正确匹配查询条件
- 优化查询性能并提升代码可读性
2026-01-18 14:06:44 +08:00
59157fda56 feat(organization): 支持科室分类多选功能
- 修改前端界面组件支持科室分类多选下拉框
- 更新后端接口参数类型从Integer改为String以支持多选值
- 实现FIND_IN_SET查询方式处理多选分类条件
- 添加parseClassEnumValues函数处理字符串或数组格式转换
- 在医院住院对话框中扩展筛选条件支持多选分类
- 优化错误信息显示逻辑提供更详细的错误提示
- 在患者列表组件中添加入院日期和主治医生信息展示
- 修复多个服务调用中科室分类参数传递的数据类型问题
2026-01-18 13:39:57 +08:00
2fe6d45ad4 fix(doctorstation): 修复诊断组件和住院办理功能的数据处理问题
- 修复诊断组件中el-popover模板语法错误,添加template标签
- 优化患者历史数据处理逻辑,确保数组类型安全并正确构建树形结构
- 完善住院办理流程中的组织机构数据获取和筛选逻辑
- 添加详细的控制台日志用于调试住院办理功能
- 修复办理住院按钮的禁用状态计算逻辑
- 优化患者卡片点击事件处理,确保就诊ID正确传递
- 添加诊断信息完整性检查并提供用户引导
- 修复检验申请组件中的监听器和暴露方法逻辑
2026-01-18 00:37:54 +08:00
982ee316f7 fix(doctorstation): 解决参数验证和数据获取问题
- 在前端api.js中添加encounterId参数验证,避免无效参数导致的错误
- 在后端服务层添加参数检查,当encounterId为空时返回空数据而非报错
- 修改控制器参数注解,将required设置为false以允许空值传递
- 优化住院办理流程中的错误处理和参数验证
- 改进检验申请单获取时的数据验证和错误提示
- 更新maven编译器插件版本并添加必要的模块参数
- 统一错误处理机制,提供更友好的用户提示信息
2026-01-17 16:07:57 +08:00
64c7db68e8 上传文件至 md/需求 2026-01-17 00:03:51 +08:00
cb6b6ced67 上传文件至 md/需求 2026-01-16 18:54:27 +08:00
itcast
8fcfb481c9 门诊医生站-》开立诊断 页面调整 2026-01-16 16:32:36 +08:00
itcast
be0514bc08 门诊医生站-》开立诊断 页面调整 2026-01-16 15:46:43 +08:00
ljj
2b3add4808 91 分诊排队管理-》门诊医生站:【完诊】患者队列状态的变化
68 检验项目设置-检验类型 / 检验项目设置-检验项目
2026-01-16 11:31:40 +08:00
b33cb6f9a1 测试合并v13 2026-01-15 17:04:46 +08:00
072e71b025 测试合并v12 2026-01-15 16:58:14 +08:00
47394de43c Merge pull request 'document' (#2) from document into develop
Reviewed-on: #2
2026-01-15 07:37:39 +00:00
f0f1dde6b6 测试合并 2026-01-15 07:37:39 +00:00
1ab1165697 测试合并 2026-01-15 07:37:39 +00:00
a8f1b1fdfa feat(doctorstation): 添加医嘱类型对应的药品分类筛选功能
- 在处方列表组件中根据医嘱类型自动设置categoryCode筛选条件
- 为西药类型设置categoryCode为'2'
- 为中成药类型设置categoryCode为'1'
- 为耗材和诊疗类型清空categoryCode筛选条件
- 更新基础医嘱列表组件以接收并应用categoryCode查询参数
- 实现医嘱类型改变时的联动筛选逻辑
2026-01-15 15:34:34 +08:00
3b94d19199 Merge remote-tracking branch 'origin/develop' into develop 2026-01-15 15:13:20 +08:00
db1139a14f fix(prescription): 解决处方列表中价格显示的空值异常问题
- 在处方列表组件中添加对unitPrice和totalPrice的空值检查,防止NaN显示
- 优化价格计算逻辑,确保无效价格值被正确处理并显示为默认值
- 更新数据库查询中的条件判断,改进UNION查询的逻辑结构
- 添加对adviceTypes参数的有效性验证,确保查询条件的正确执行
2026-01-15 15:13:09 +08:00
chenjinyang
bea74aeac2 使用element-plus进行提示替换HTML原生弹窗 2026-01-15 15:01:05 +08:00
chenjinyang
634a1f45f9 根据LIS分组开发手册完成功能 2026-01-15 14:36:54 +08:00
8f1ad3307c refactor(doctorstation): 优化医生站医嘱查询SQL逻辑
- 将原有的条件判断逻辑重构为更清晰的choose/when/otherwise结构
- 修复了adviceTypes参数为空或未指定时的SQL执行问题
- 通过trim标签处理UNION ALL连接避免多余关键字
- 添加otherwise分支确保无adviceTypes时返回正确空结果集
- 保持了原有的所有功能逻辑和数据映射关系不变
- 提高了SQL查询的可读性和维护性
2026-01-15 13:42:36 +08:00
d8080fa22d 挂号补单功能的完善 2026-01-14 12:56:39 +08:00
chenjinyang
e8783d9f8f 修复叫号显示屏跳转异常问题 2026-01-14 10:44:35 +08:00
d8c4348341 挂号补单功能的完善 2026-01-14 10:12:25 +08:00
wangjian963
8e61490005 修复门诊医生站检验申请单的就诊卡号无法获取到对应的值的问题 2026-01-13 17:47:51 +08:00
f5f4e3c48e fix(charge): 修复收费模块中的数值计算和空指针异常问题
- 修复金额计算精度问题,使用Number转换和toFixed(2)确保数值准确性
- 添加安全访问操作符(?.)避免空指针异常导致页面崩溃
- 修复数组过滤和查找操作的空值处理逻辑
- 优化错误消息显示,提供更友好的用户提示
- 修复模板文件路径引用问题,确保打印功能正常工作
- 统一金额计算逻辑,避免因数据类型不一致导致的计算错误
2026-01-13 17:30:17 +08:00
0f013715b8 fix(charge): 修复合同列表空值访问导致的门诊登记页面异常 2026-01-13 17:06:52 +08:00
fb9722d328 fix(charge): 修复合同列表空值访问导致的门诊登记页面异常 2026-01-13 17:06:43 +08:00
6f9192d30d fix(charge): 修复医保支付金额计算的安全访问问题
- 在 cliniccharge 组件中为所有金额查询添加可选链操作符防止空指针异常
- 在住院管理收费结算组件中修复金额格式化导致的显示问题
- 统一处理患者信息字段的空值情况避免页面渲染错误
- 修正金额计算逻辑确保数值精度和显示准确性
2026-01-13 17:02:27 +08:00
f2b5b90f34 Merge remote-tracking branch 'origin/develop' into develop 2026-01-13 17:01:29 +08:00
py
a2cbd5e583 测试:科室预约工作时间维护 2026-01-13 17:00:31 +08:00
d3df46858b fix(charge): 修复医保支付计算中的潜在空指针异常
- 在 chargeDialog.vue 中为所有 param.detail.find() 调用添加可选链操作符
- 修复了基金支付总额、个人负担总金额和其他支付类型的空指针风险
- 解决了基本医保统筹基金支出等各项支付类型的潜在运行时错误
- 在微信刷卡支付逻辑中同样应用可选链操作符保护
- 修复了 FULAMT_OWNPAY_AMT 计算中的运算符优先级问题

feat(hospitalRecord): 动态替换打印模板中的医院名称

- 在 MedicationDetails.vue 中引入并使用 userStore 获取医院名称
- 修改处置模板打印逻辑以动态替换 {{HOSPITAL_NAME}} 占位符
- 更新处方模板打印功能以支持医院名称的动态替换
- 激活之前被注释掉的模板文件导入语句
- 移除硬编码的医院名称,实现模板的动态化配置
2026-01-13 16:58:43 +08:00
47a7a945bc Merge remote-tracking branch 'origin/develop' into develop 2026-01-13 15:27:01 +08:00
0a56c0dcf0 feat(store): 更新用户模块状态管理以支持租户配置
- 调整导入语句顺序以符合代码风格规范
- 添加tenantName字段用于存储租户名称
- 添加optionMap字段用于存储租户配置项映射
- 修改getInfo方法以从optionMap优先获取医院名称配置
- 添加tenantName赋值逻辑以支持租户名称显示
- 移除已废弃的用户个人资料相关组件文件
2026-01-13 15:26:46 +08:00
15d32134e2 挂号补单功能的完善 2026-01-13 14:48:18 +08:00
eff98ea5eb Merge remote-tracking branch 'origin/develop' into develop 2026-01-13 14:41:36 +08:00
a47306825a docs(requirement): 添加手术室维护界面需求文档
- 创建手术室维护界面PRD文档
- 定义页面概述、核心功能和用户价值
- 设计整体布局和页面区域详细描述
- 规范交互功能和数据结构说明
- 说明开发实现要点和注意事项
- 移除中医诊断主诊断功能实现说明文档
- 移除公告通知弹窗功能说明文档
- 移除手术人员字段不显示问题解决方案文档
- 移除手术和麻醉信息Redis缓存实现说明文档
- 移除手术室管理添加类型和所属科室字段说明文档
2026-01-13 14:41:27 +08:00
sindir
9b35fec931 诊室页面新增卫生机构、操作人列展示 2026-01-13 14:26:51 +08:00
e20e2b637f 挂号补单功能的完善 2026-01-13 13:26:09 +08:00
ebd2e8aa75 迁移:将DB变更记录SQL文件移动到sql目录下 2026-01-13 10:05:32 +08:00
cb268fe26d feat(operating-room): 添加手术室类型和所属科室字段
- 新增手术室类型字段支持急诊、择期、日间、复合手术室四种类型
- 添加所属科室字段实现科室级别资源管理
- 前端列表页面新增类型和所属科室显示列
- 新增类型选择器和科室选择器组件
- 后端实体类和服务类添加对应字段处理逻辑
- 数据库添加room_type_enum字段和相关索引
- 创建手术室类型字典数据和字典项配置
- 生成手术室管理功能说明文档
2026-01-13 10:03:57 +08:00
23bd49d940 挂号单补打功能完善 2026-01-12 18:14:54 +08:00
32adb984e2 实现科室护士管理患者排队叫号队列,实现患者智能分诊、队列调整、叫号控制等功能 2026-01-12 17:36:55 +08:00
py
c1d453600b 测试:科室预约工作时间维护 2026-01-12 15:49:10 +08:00
py
02eab2d932 测试:科室预约工作时间维护1 2026-01-12 15:36:58 +08:00
py
d5c8b7a1ad 测试:科室预约工作时间维护1 2026-01-12 15:32:41 +08:00
wangjian963
4053064a22 Merge remote-tracking branch 'origin/develop' into develop 2026-01-09 17:38:19 +08:00
wangjian963
089e28f913 修复门诊工作站医生开医嘱的表单标题与内容无法对应的问题 2026-01-09 17:36:36 +08:00
cf9ab03b17 feat(operatingroom): 添加手术室类型和所属科室字段支持
- 在手术室管理界面添加类型和所属科室表格列显示
- 添加手术室类型下拉选择功能,支持急诊、择期、日间、复合四种类型
- 添加手术室详情查看页面中的类型字段展示
- 在后端服务中实现手术室类型的字典转换和文本显示
- 添加手术室实体类中的类型和所属机构名称字段
- 更新路由配置注释掉废弃的系统管理相关路径配置
2026-01-09 17:18:07 +08:00
d332650bfa feat(patient): 实现门诊挂号页面跳转到患者档案页面的精确定位功能
- 在门诊挂号页面添加患者ID和姓名查询参数传递到患者档案页面
- 在患者档案页面实现路由参数接收和按数据库ID精确查询功能
- 新增searchType字段支持按姓名和病人ID两种查询方式
- 优化患者档案页面初始化逻辑,分离字典数据加载和列表查询
- 修改后端服务实现,对精确ID查询跳过医生患者过滤条件以确保跳转查询成功
2026-01-09 16:15:36 +08:00
840983ac94 修复了中医诊断保存时主诊断标记不唯一的问题,并优化了诊断保存逻辑 2026-01-09 15:33:06 +08:00
April
86673d7be3 Merge remote-tracking branch 'origin/develop' into develop 2026-01-09 15:10:05 +08:00
April
3753a916f5 修复了门诊医生站重新调入该患者的本次就诊记录,点击中医诊断发现诊断详情是空的问题 2026-01-09 15:08:19 +08:00
chenjinyang
0556f77870 Merge branch 'develop' of https://gitea.gentronhealth.com/wangyizhe/his into develop
# Conflicts:
#	openhis-ui-vue3/src/router/index.js
2026-01-09 14:07:02 +08:00
chenjinyang
b185c156ca 新增了系统操作手册实例,后续可以加入md文件 2026-01-09 14:01:35 +08:00
ljj
a48308dcbf Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2026-01-09 13:28:45 +08:00
e37f6a70f9 revert 28629ccd35
revert Merge remote-tracking branch 'origin/develop' into develop
2026-01-09 04:05:51 +00:00
April
28629ccd35 Merge remote-tracking branch 'origin/develop' into develop 2026-01-09 12:02:45 +08:00
April
fbd7f0be78 修复了在新建患者信息时就诊卡号无法录入的问题,并且修改了前端页面添加中医诊断表单宽度过大的问题。 2026-01-09 11:47:39 +08:00
ljj
763f05da84 Merge remote-tracking branch 'origin/develop' into develop 2026-01-09 11:38:35 +08:00
ljj
8c74d45332 76 门诊预约挂号 2026-01-09 11:33:03 +08:00
8d62c0461b 挂号单补打功能的实现 2026-01-09 10:03:21 +08:00
58936c957d fix(doctorstation): 解决医嘱开具和报告查询中的问题
- 修复医嘱开具时诊断验证警告显示逻辑,支持可选的警告提示
- 修复中医医嘱库存检查条件判断逻辑
- 修复中医医嘱表单验证后数据处理逻辑,添加剂量单位字典值设置
- 优化报告查询处理,独立处理检查和检验报告查询,避免相互影响
- 修复LIS和PACS报告地址配置缺失时的处理逻辑,改为警告而非异常抛出
2026-01-08 16:32:45 +08:00
062c4a92b8 chore(router): 添加患者档案管理路由配置
- 添加患者档案管理路由配置代码
- 注释掉租户用户设置路由部分代码
- 新增patientmgr路由项配置
- 配置路由组件和元信息
- 设置路由隐藏属性
- 完善路由路径和名称定义
2026-01-08 14:52:28 +08:00
fb9f85e967 chore(router): 添加患者档案管理路由配置
- 添加患者档案管理路由配置代码
- 注释掉租户用户设置路由部分代码
- 新增patientmgr路由项配置
- 配置路由组件和元信息
- 设置路由隐藏属性
- 完善路由路径和名称定义
2026-01-08 14:52:22 +08:00
38ef377cbd 手术管理->优化字典数据获取逻辑 2026-01-07 22:56:48 +08:00
240d5dc3f7 手术管理->更改部分组件数据来源,改为从字典中获取。 2026-01-07 17:28:56 +08:00
82702f16e0 Merge remote-tracking branch 'origin/develop' into develop 2026-01-07 17:00:19 +08:00
0b4b63dfbe feat(surgery): 增加手术室确认信息和次要手术功能
- 添加手术室确认时间和确认人字段显示
- 实现次要手术的添加、编辑和删除功能
- 增加急诊标志和植入高值耗材开关选项
- 添加手术费用和麻醉费用计算功能
- 实现手术和麻醉项目的远程搜索功能
- 增加第一助手和第二助手选择功能
- 优化医生列表加载逻辑,支持多接口获取
- 添加按钮图标提升界面体验
- 修复encounterId为空时的接口调用问题
2026-01-07 17:00:06 +08:00
b4422a0dca 收费工作站:合并后按钮重复问题,档案按钮跳转无反应问题。 2026-01-07 13:51:30 +08:00
d8627df2dd 检验项目->套餐设置->部分组件、布局问题 2026-01-07 11:01:49 +08:00
09ca077559 refactor(surgery): 优化手术服务中医生信息查询逻辑
- 引入 IPractitionerService 服务替代 SysUserService 查询医生信息
- 修改手术列表查询中主刀医生、麻醉医生、助手和护士的姓名填充逻辑
- 使用 Practitioner 实体的 name 字段替代 SysUser 的 nickName 字段
- 更新 SQL 查询使用 COALESCE 函数合并数据库中存储的姓名和实时查询结果
- 添加多个 LEFT JOIN 查询以支持手术相关医生和科室信息的实时获取
- 优化申请医生和申请科室名称的查询机制,支持数据回退逻辑
2026-01-06 16:40:57 +08:00
py
3091fc7337 新增科室预约工作时间维护页面 2026-01-06 16:31:08 +08:00
b0850257c8 feat(surgery): 完善手术管理功能模块
- 添加手术申请相关API接口,包括根据患者ID查询就诊列表功能
- 在医生工作站界面集成手术申请功能选项卡
- 实现手术管理页面的完整功能,包括手术申请的增删改查
- 添加手术排期、开始、完成等状态流转功能
- 优化手术管理页面表格展示,增加手术类型、等级、计划时间等字段
- 实现手术申请表单的完整编辑和查看模式
- 集成患者信息和就诊记录关联功能
- 添加手术室、医生、护士等资源选择功能
- 更新系统依赖配置,添加core-common模块
- 优化图标资源和manifest配置文件
- 调整患者档案和门诊记录相关状态枚举
2026-01-06 16:23:15 +08:00
fa2884b320 实现科室护士管理患者排队叫号队列,实现患者智能分诊、队列调整、叫号控制等功能 2026-01-06 15:34:16 +08:00
941054734f 实现科室护士管理患者排队叫号队列,实现患者智能分诊、队列调整、叫号控制等功能 2026-01-06 14:48:45 +08:00
8d69dc3c00 患者档案(现为患者列表)->修改和查看按钮调出窗口与新建患者保持一致 2026-01-05 14:22:57 +08:00
2157806ba5 系统管理->基础数据->字典管理->添加字典数据异常 2026-01-05 11:10:14 +08:00
2236cbea36 门诊挂号->下方列表获取挂号记录-SQL报错。 2026-01-04 16:31:02 +08:00
2128e717e7 门诊挂号->医生字段无数据问题。 2026-01-04 15:59:49 +08:00
1311e87e13 叫号显示屏页面开发,诊疗目录新增或修改时添加医保编码唯一性校验。 2026-01-04 14:24:33 +08:00
ddf1553846 检验项目设置-检验类型的实现 2026-01-04 13:50:05 +08:00
5d82800976 refactor(patientmanage): 为门诊记录服务添加日志功能
- 引入 lombok 的 Slf4j 注解用于日志记录
- 为 OutpatientRecordServiceImpl 添加日志支持
- 为后续调试和监控提供日志输出能力
2026-01-03 23:52:45 +08:00
0c35044231 feat(menu): 优化菜单路径唯一性校验并更新前端界面
- 在SysLoginController中添加optionMap数据返回
- 添加JSQLParser依赖支持MyBatis Plus功能
- 实现selectMenuByPathExcludeId方法用于排除当前菜单的路径唯一性校验
- 在SysMenuServiceImpl中添加日志记录并优化路径唯一性判断逻辑
- 在SysMenuMapper.xml中添加LIMIT 1限制并实现排除ID查询
- 在前端路由中注释患者管理相关路由配置
- 在用户store中添加optionMap配置项并优先从optionMap获取医院名称
- 重构检查项目设置页面的操作按钮样式为统一的圆形按钮设计
- 更新检查项目设置页面的导航栏样式和交互体验
- 优化门诊记录页面的搜索条件和表格展示功能
- 添加性别和状态筛选条件并改进数据加载逻辑
2026-01-03 23:47:09 +08:00
61f4020487 新增患者:监护人信息限制 2025-12-31 13:43:24 +08:00
aeb6b95970 Merge branch 'develop' of https://gitea.gentronhealth.com/py/his into develop 2025-12-31 13:37:29 +08:00
b5ce854eb6 fix(login): 修复登录页面invokeYb默认值设置问题
- 修正了localStorage中invokeYb的默认值从true改为false
- 添加了loginForm.value.invokeYb的默认值设置
- 更新了注释内容以反映正确的默认行为
2025-12-31 11:00:17 +08:00
4d4828ea71 feat(login): 添加租户名称获取功能并优化前端布局
- 在登录控制器中注入租户服务并获取租户名称信息
- 添加租户名称到登录响应结果中
- 更新样式变量定义侧边栏宽度和Logo高度
- 重构公告面板组件统一公告通知显示逻辑
- 简化公告类型图标和样式映射关系
- 更新侧边栏为垂直菜单布局并添加折叠功能
- 优化Logo组件显示租户名称和系统标题
- 调整导航栏布局结构和响应式样式
- 重构主应用容器样式和标签页显示逻辑
2025-12-31 10:28:52 +08:00
10e738edd9 feat(notice): 新增公告优先级和未读状态功能,优化公告展示逻辑 2025-12-30 22:49:14 +08:00
88a4e58130 feat(notice): 新增公告优先级和未读状态功能,优化公告展示逻辑 2025-12-30 22:49:03 +08:00
76c324b0df feat(organization): 添加科室管理查询过滤功能
- 修复api.js中params参数拼写错误
- 添加科室名称、类型、分类的查询表单
- 实现搜索和重置功能
- 集成分页组件并修正页码参数映射
- 在后端服务中添加查询条件过滤逻辑
- 支持按科室名称、类型、分类进行条件查询
- 实现动态排序功能并修复分页查询逻辑
2025-12-30 17:01:37 +08:00
a65e8dd2cc feat(organization): 添加科室管理查询过滤功能
- 修复api.js中params参数拼写错误
- 添加科室名称、类型、分类的查询表单
- 实现搜索和重置功能
- 集成分页组件并修正页码参数映射
- 在后端服务中添加查询条件过滤逻辑
- 支持按科室名称、类型、分类进行条件查询
- 实现动态排序功能并修复分页查询逻辑
2025-12-30 17:01:34 +08:00
1ac9b5ae0b feat(organization): 添加科室管理查询过滤功能
- 修复api.js中params参数拼写错误
- 添加科室名称、类型、分类的查询表单
- 实现搜索和重置功能
- 集成分页组件并修正页码参数映射
- 在后端服务中添加查询条件过滤逻辑
- 支持按科室名称、类型、分类进行条件查询
- 实现动态排序功能并修复分页查询逻辑
2025-12-30 16:52:01 +08:00
8f77fe8bc9 Merge remote-tracking branch 'origin/develop' into develop 2025-12-30 16:13:52 +08:00
b567747901 style(flowable): 优化流程相关代码的import顺序和代码结构 2025-12-30 16:12:16 +08:00
ed7004ae85 style(flowable): 优化流程相关代码的import顺序和代码结构 2025-12-30 15:34:43 +08:00
d1670b79a0 style(flowable): 优化流程相关代码的import顺序和代码结构 2025-12-30 15:11:32 +08:00
54cde91aac style(ui): 统一界面样式标准并优化组件布局
- 引入 ui-standard.scss 样式文件以统一界面标准
- 为查询表单添加 query-form 样式类
- 为搜索按钮组添加 search-buttons 样式类
- 为按钮组容器添加 button-group 样式类
- 为字典标签添加 dict-tag 样式类以统一样式
- 为操作按钮添加 action-button 样式类
- 为分页组件添加 pagination-container 容器
- 优化患者管理页面表格列的字典标签显示
- 调整公告页面布局结构并添加容器样式
- 优化表格单元格间距和样式显示
2025-12-30 14:57:20 +08:00
7974bdc51c feat(ui): 添加OpenHIS UI统一风格规范和样式
- 创建ui-standard.scss样式文件,定义全局组件样式规范
- 添加容器、表格、表单、按钮、对话框等统一UI样式
- 实现响应式设计和动画效果
- 编写完整的UI风格规范文档
- 定义颜色、间距、圆角、阴影等设计规范
- 提供组件使用示例和命名规范指导
2025-12-30 14:56:29 +08:00
91cb465962 医生常用语维护->名称字数限制、前端名称唯一性校验等 2025-12-30 14:26:14 +08:00
1b2c248fa2 Merge remote-tracking branch 'origin/develop' into develop 2025-12-30 14:10:01 +08:00
1c16d6ba0f feat(invoice): 完善发票管理权限控制和检验申请功能
- 超级管理员可以编辑操作员字段,普通用户不可编辑
- 修改权限判断逻辑,只有用户名等于 'admin' 的用户才是超级管理员
- 非超级管理员用户只能查询自己的发票数据
- 添加根据员工ID更新操作员名称功能
- 新增行时根据用户权限填充信息
- 严格检查权限,超级管理员可以删除所有记录,普通用户只能删除自己维护的记录
- 在 bargain 组件中验证患者选择
- 添加检验申请单相关API接口
- 在医生工作站中添加检验申请tab页
- 实现检验申请单的增删改查功能
- 添加公告通知已读记录相关功能
- 实现用户未读公告数量统计和标记已读功能
2025-12-30 14:09:37 +08:00
49b8a975a8 feat(invoice): 完善发票管理权限控制和检验申请功能
- 超级管理员可以编辑操作员字段,普通用户不可编辑
- 修改权限判断逻辑,只有用户名等于 'admin' 的用户才是超级管理员
- 非超级管理员用户只能查询自己的发票数据
- 添加根据员工ID更新操作员名称功能
- 新增行时根据用户权限填充信息
- 严格检查权限,超级管理员可以删除所有记录,普通用户只能删除自己维护的记录
- 在 bargain 组件中验证患者选择
- 添加检验申请单相关API接口
- 在医生工作站中添加检验申请tab页
- 实现检验申请单的增删改查功能
- 添加公告通知已读记录相关功能
- 实现用户未读公告数量统计和标记已读功能
2025-12-30 13:52:06 +08:00
d17a502da1 Merge remote-tracking branch 'origin/develop' into develop 2025-12-30 13:43:54 +08:00
430adc2112 feat(system): 添加公告通知已读记录功能
- 新增 SysNoticeRead 实体类用于存储公告/通知已读记录
- 实现 SysNoticeReadMapper 数据访问层接口及 XML 映射文件
- 创建 ISysNoticeReadService 服务接口及实现类
- 添加数据库表 sys_notice_read 存储用户阅读状态
- 添加发布状态字段到公告表支持公告发布控制
- 实现前端 NoticePanel 组件支持未读标记和阅读状态显示
- 提供标记已读、批量标记、未读数量统计等功能
- 优化公告列表按已读状态和时间排序显示
2025-12-30 13:43:28 +08:00
5f5c47f528 新增门诊医生开立检验申请单前端页面样式、模板初步完成 2025-12-30 13:30:06 +08:00
92d74c47ce 增加发票号码维护界面bug修复和新增门诊医生开立检验申请单前端页面样式、模板初步完成 2025-12-30 13:25:55 +08:00
5d8e7b667f 门诊划价->新增按钮报错BUG,叫号语音设置页面开发。 2025-12-30 13:19:01 +08:00
58449fc2f9 Merge remote-tracking branch 'origin/develop' into develop 2025-12-30 10:24:44 +08:00
4c541f43b9 `` refactor(doctorstation): 修正处方列表组件导入路径大小写问题并删除废弃的体温单组件`` 2025-12-30 10:24:25 +08:00
9a037ae446 Merge remote-tracking branch 'origin/develop' into develop 2025-12-30 10:11:25 +08:00
bb0eb60eae Merge branch 'merge_1.3' into develop 2025-12-30 10:10:40 +08:00
cf5dbc6133 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	openhis-ui-vue3/src/views/doctorstation/components/diagnosis/addDiagnosisDialog.vue
#	openhis-ui-vue3/src/views/doctorstation/components/tcm/tcmAdvice.vue
2025-12-30 10:04:25 +08:00
5f6fa50000 修复了作废的中医诊断也显示出来的问题, 2025-12-30 10:03:46 +08:00
08b2e76d47 修复了作废的中医诊断也显示出来的问题, 2025-12-30 09:59:58 +08:00
5ffeab8999 修复了作废的中医诊断也显示出来的问题, 2025-12-30 09:56:39 +08:00
fc6640b846 Merge branch 'merge_1.3' into develop 2025-12-30 09:38:57 +08:00
8e11dde7c0 feat(deptManage): 添加医生排班管理API接口
- 实现添加医生排班功能接口
- 实现删除医生排班功能接口
- 实现批量保存医生排班功能接口
- 集成统一请求处理工具
- 添加详细的函数注释说明
- 完善参数类型和返回值定义
2025-12-30 09:31:43 +08:00
e8f24ee290 `` refactor(config): 更新开发环境数据库和Redis配置为内网地址`` 2025-12-30 09:27:12 +08:00
a1e07a204b ``` refactor(db): 移除SQL语句中的public schema前缀 2025-12-30 00:02:59 +08:00
a080b4294c ```
feat(invoice): 添加发票分页查询权限过滤功能

- 移除未使用的Supplier导入
- 新增selectInvoicePage方法支持用户角色权限过滤
- 非管理员用户只能查看自己创建的发票
- 优化发票新增逻辑,使用count查询替代list查询提升性能
- 添加事务注解确保数据一致性
- 异常处理改进,抛出ServiceException替代返回null
```
2025-12-27 22:53:39 +08:00
0827ce2908 ```
refactor(invoice): 移除发票服务中的权限过滤功能

移除发票服务接口中的分页查询权限过滤方法,简化发票新增逻辑,
移除异常抛出改为返回null,更新分页查询方法实现

- 移除 IInvoiceService 中的 selectInvoicePage 方法
- 移除 InvoiceServiceImpl 中的权限过滤逻辑
- 移除发票新增时的异常抛出,改为返回null
- 移除多余的import和注释
- 简化发票编码存在性检查逻辑

refactor(outpatient): 修复门诊记录服务中的方法注解

为门诊记录服务中的 getDoctorNames 方法添加 @Override 注解,
移除多余的空行

- 在 OutpatientRecordServiceImpl 中添加 @Override 注解
- 移除 PatientManageMapper 导入前的多余空行
```
2025-12-27 22:53:32 +08:00
5f600209b8 ```
refactor(core): 优化DelFlag枚举值比较逻辑

- 修改DelFlag.getValue()调用为直接访问value字段
- 提升代码性能和可读性
```
2025-12-27 22:45:20 +08:00
79ea4ed4f7 提交merge1.3 2025-12-27 15:31:06 +08:00
cbd3e7f981 提交merge1.3 2025-12-27 15:30:48 +08:00
3c497417dc 提交merge1.3 2025-12-27 15:30:40 +08:00
088861f66e 提交merge1.3 2025-12-27 15:30:25 +08:00
8914c8b143 ```
chore(app): 更新应用启动横幅

更新了应用启动时显示的横幅,替换了原有的ASCII艺术样式,
使用了新的样式以提升视觉效果和品牌识别度。
```
2025-12-27 14:21:00 +08:00
8c607c8749 ```
feat(common): 添加core-common依赖

新增core-common依赖项,用于提供通用功能支持,
移除core-admin的版本号配置
```
2025-12-26 22:45:08 +08:00
3115e38cc4 Revert "```"
This reverts commit abc0674531.
2025-12-26 22:21:21 +08:00
ae6c486114 Revert "```"
This reverts commit 85fcb7c2e2.
2025-12-26 22:20:01 +08:00
a41ffa4cfc pgsql脚本 2025-12-25 14:28:44 +08:00
b1f74161f8 检验项目设置-套餐设置前后端及数据库基本完成 2025-12-25 14:25:35 +08:00
3bab56a19b Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2025-12-25 14:13:37 +08:00
abc0674531 ```
docs(release-notes): 添加住院护士站划价功能说明和发版记录

- 新增住院护士站划价服务流程说明文档,详细描述了从参数预处理到结果响应的五大阶段流程
- 包含耗材类医嘱和诊疗活动类医嘱的差异化处理逻辑
- 添加完整的发版内容记录,涵盖新增菜单功能和各模块优化点
- 记录了住院相关功能的新增和门诊业务流程的修复
```
2025-12-25 14:13:14 +08:00
85fcb7c2e2 ```
docs(release-notes): 添加住院护士站划价功能说明和发版记录

- 新增住院护士站划价服务流程说明文档,详细描述了从参数预处理到结果响应的五大阶段流程
- 包含耗材类医嘱和诊疗活动类医嘱的差异化处理逻辑
- 添加完整的发版内容记录,涵盖新增
2025-12-25 14:12:53 +08:00
fc6a7437a3 门诊医生站->医嘱定价来源未配置bug,叫号语音设置后端框架基本接口开发。 2025-12-25 14:09:32 +08:00
999a0992e7 门诊医生预约科室管理功能的完善 2025-12-25 13:49:30 +08:00
55b3dfc077 套餐设置功能前后端内容基本完成(细节未处理) 2025-12-25 11:12:56 +08:00
ljj
32d1673667 84 系统管理-》易用性配置-》病历模板定义:新建模板点击【确认】报错 2025-12-24 16:55:56 +08:00
17c7cc70ed 药品出货单按钮被隐藏bug修复 2025-12-24 15:59:56 +08:00
44be570ffa ```
chore(deps): 更新项目依赖版本

- 将 area-data 依赖的版本从 5.0.6 的固定版本更新为 ^5.0.6
- 将 vue-plugin-hiprint 依赖版本从 ^0.0.60 降级至 ^0.0.19
- 升级 sass 依赖版本从 ^1.97.0 至 ^1.97.1
- 升级 vite 依赖版本从 ^5.0.4 至 ^7.3.0
- 移除重复的 area-data 依赖声明
```
2025-12-24 15:38:19 +08:00
c6f4996ba7 Merge remote-tracking branch 'origin/develop' into develop 2025-12-24 14:25:43 +08:00
6c20b15339 套餐设置页面完成 2025-12-24 14:25:06 +08:00
c297072b36 ```
feat(index): 优化index.html页面结构和加载体验

- 添加基础meta标签、SEO描述信息和安全相关meta标签
- 配置移动端和PWA支持,更新图标和manifest配置
- 优化CSS样式,包括box-sizing重置和加载动画样式
- 改进加载器动画效果,添加无障碍属性和noscript提示
- 修复viewport配置,移除过时的IE兼容性代码
- 统一CSS单位格式,优化margin和padding设置
```
2025-12-24 14:15:08 +08:00
4c6886be6a ```
build(pom): 更新lombok版本并配置编译插件版本

- 将lombok版本从1.18.26升级到1.18.42
- 添加maven-compiler-plugin.version属性配置为3.13.0
- 为lombok依赖添加provided作用域配置
```
2025-12-24 10:11:35 +08:00
8beb7f3d3d 医生常用语页面开发,接口实现. 2025-12-23 17:01:24 +08:00
91968530b4 调整套餐设置布局 2025-12-23 16:37:31 +08:00
0833f82fb4 耗材目录包装单位的拼音搜索 2025-12-23 15:05:26 +08:00
cce71f324b Merge remote-tracking branch 'origin/develop' into develop 2025-12-23 12:45:24 +08:00
ee6efafde4 第一次提交 2025-12-23 12:45:15 +08:00
2051807ecf 第一次提交 2025-12-23 12:44:27 +08:00
0a4de15599 医生常用语模板维护->后端接口优化,页面开发;检查方法,部位新增编辑按钮。 2025-12-23 10:56:38 +08:00
25b3c26ec2 医生常用语模板维护->后端接口开发、数据库建表。 2025-12-22 16:45:40 +08:00
91d673de77 检验项目设置-检验类型功能完成 2025-12-22 16:28:05 +08:00
0bfa7183f9 Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2025-12-22 12:10:59 +08:00
79d451931d ```
feat(core-admin): 添加 Lombok 依赖并升级版本

在 core-admin 模块中显式添加了 Lombok 依赖,并将 Lombok 版本从 1.18.26 升级至 1.18.38。
同时,将 Lombok 依赖统一管理到父 pom 的 dependencyManagement 中,并配置 Maven 编译插件以支持注解处理器。
此外,引入 core-common 通用工具模块依赖,移除了冗余的 Maven 构建配置注释。
```
2025-12-22 12:10:55 +08:00
ae5f1c795b 检验项目设置-检验类型功能完成 2025-12-22 11:45:16 +08:00
c1074fc4fb 修改检验项目设置的样式风格 2025-12-22 10:33:14 +08:00
e832b6d38e Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2025-12-19 14:33:17 +08:00
5043466e84 ```
feat(package): 添加 area-data、next、react 和 react-dom 依赖

新增 area-data 用于地区数据处理,添加 next、react 和 react-dom 以支持 React 相关功能。
同时升级 sass 版本并添加 sass-loader 以优化样式构建流程。
```
2025-12-19 14:33:15 +08:00
fcaeedb543 ```
fix(openhis-ui-vue3): 修复 package.json 文件格式问题

修正了 package.json 文件末尾缺少的换行符,确保文件格式符合标准要求
```
2025-12-19 14:33:04 +08:00
8cf434a46f 系统管理->诊疗目录->添加新项目报错BUG。 2025-12-19 13:53:00 +08:00
bfbc061b0b 根据您提供的代码差异信息为空的情况,我将提供一个通用的commit message模板:
```
docs(changelog): 更新版本变更记录

更新项目的变更日志文件,添加最新的功能改进和修复内容,
确保文档与当前版本保持同步。
```

如果您有具体的代码变更内容,请提供详细的差异信息,我可以为您生成更准确的commit message。
2025-12-19 13:13:36 +08:00
f92cd830e9 库房管理-采购管理-采购入库->经手人设置默认值(当前登录用户) 2025-12-18 16:20:38 +08:00
a7a1a18445 检查项目设置-》检查类型维护 2025-12-18 15:28:32 +08:00
d1331cd4e1 Merge remote-tracking branch 'origin/develop' into develop 2025-12-18 14:57:34 +08:00
37d08b8545 菜单管理修改接口优化 2025-12-18 14:56:15 +08:00
e69f499ac0 Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2025-12-18 14:49:40 +08:00
3baf7161f1 feat(router): 注释掉部分路由配置并调整租户相关路由
注释掉了预约管理、基础管理、维护系统及系统管理等模块的路由配置,
同时修改了租户用户设置与租户合同管理的路由路径和对应组件,
使其更符合当前业务需求。此外,移除了重复或不再使用的路由注释块,
优化了路由结构的可读性与维护性。
2025-12-18 14:49:35 +08:00
85188651ca 门诊出诊医生诊室设置维护 2025-12-18 14:43:17 +08:00
d6fbfb1427 router-index.js中注释掉系统管理的路由配置,系统管理的相关页面均能访问,药品目录添加新项目时医保等级默认值设置完成。 2025-12-18 13:53:38 +08:00
966847499a 菜单管理-根据Path进行唯一性校验-优化修改接口 2025-12-18 13:19:27 +08:00
1e91171001 router-index.js部分路径注释。 2025-12-18 11:01:45 +08:00
51f495f81e 页面最上面导航栏取消居中显示。 2025-12-18 10:32:49 +08:00
1e6a5972b9 菜单管理->修改、新增时路由地址唯一性检验 2025-12-18 10:20:52 +08:00
515f03a5cd 页面上导航栏搜索栏显示不全bug 2025-12-17 17:23:31 +08:00
b27542ba6d feat(router): 删除预约管理路由模块并注释部分系统路由
移除了独立的预约管理路由文件,该模块功能已整合至其他模块。
同时注释掉了系统监控、系统工具等相关路由配置,便于后续按需启用。
2025-12-17 16:25:54 +08:00
4790855079 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	openhis-ui-vue3/src/views/maintainSystem/Inspection/index.vue
2025-12-17 13:31:05 +08:00
72cf9c6f2d 检验项目前端页面更新 2025-12-17 13:30:21 +08:00
19ecb65183 增加发票号码维护界面 2025-12-17 10:39:19 +08:00
d85a8684a6 feat(router): 注释掉部分路由配置以优化初始加载性能
注释掉了门诊医生站、套餐管理、预约管理、基础管理、维护系统及系统管理等模块的路由配置,\
便于后续按需加载或调试。此举可减少初次加载时不必要的资源请求,提升页面初始化效率。
2025-12-17 10:32:10 +08:00
574a9267bf 医生工作站->患者信息中医页面无法打开bug 2025-12-17 09:58:28 +08:00
py
27a7396c78 挂号收费系统参数页面的完善 2025-12-17 09:40:44 +08:00
633cf2c17f 门诊医生站患者病历打不开 不显示数据问题 2025-12-16 17:12:21 +08:00
3188ca5752 build(openhis-ui-vue3): 更新 sass 依赖版本并注释部分路由配置
更新 sass 依赖从 ^1.70.0 到 ^1.77.8,并注释掉 router 中暂时未使用的路由配置项,
包括门诊医生站、套餐管理、预约管理、基础管理、维护系统及系统管理等相关路由。
2025-12-16 13:49:06 +08:00
py
c79e4c2623 需求27:增加挂号收费系统参数维护界面-》挂号处理相关参数 2025-12-16 13:33:50 +08:00
f3c451d0a1 解决首页和门诊挂号保存报错问题 2025-12-15 17:06:25 +08:00
a077bd57d4 预约管理->相关文件转移、号源后端接口实现、前端页面逻辑、数据处理修改。 2025-12-15 16:50:16 +08:00
cf16c497bd 修改路由配置 2025-12-15 16:05:16 +08:00
fd1ab239a9 门诊出诊医生诊室设置 2025-12-15 15:37:23 +08:00
caf65e3113 ```
feat(router): 优化路由配置与注释说明

- 重构 constantRoutes 和 dynamicRoutes 中的路由结构,提升可读性
- 补充详细的路由配置项注释,便于后续维护
- 添加路由名称检查避免重复添加相同路由
- 更新数据库连接地址及 Redis 配置信息
- 完善 .gitignore 忽略文件列表,排除临时文件和日志
```
2025-12-15 14:24:45 +08:00
c18c21ff4c ```
build(openhis-ui-vue3): 更新 package-lock.json 文件

添加 resolutions 字段以解决依赖版本冲突问题,包含 stable、source-map-url、
urix、resolve-url、source-map-resolve 和 sourcemap-codec 等依赖包的版本
锁定,确保项目构建稳定性。
```
2025-12-14 15:01:10 +08:00
ab6849c9eb 根据您提供的信息,没有实际的代码差异内容。但我可以为您提供一个符合Angular规范的commit message模板示例:
```
docs(changelog): 更新版本发布说明

添加新功能描述和bug修复记录到更新日志中,
确保所有重要的变更都已正确记录以便用户查阅。
```

如果您有具体的代码差异信息,请提供详细内容,我将为您生成更准确的commit message。
2025-12-14 14:53:10 +08:00
6b555f2563 fix(openhis-ui-vue3): 降级 element-plus-icons-vue 版本
将 @element-plus/icons-vue 从版本 2.5.0 降级到 2.3.2,以解决可能存在的兼容性问题或回退到稳定版本。
2025-12-14 14:53:02 +08:00
7645405c5b 更新组件 2025-12-14 14:44:43 +08:00
5bfadb9174 fix(login): 修复获取用户绑定租户列表时用户名为空导致的URL错误
确保username参数存在,避免因为空值造成接口调用失败

feat(editor): 重构富文本编辑器组件并优化图片上传逻辑
- 使用 Composition API 重构代码结构,提升可维护性
- 改进图片上传功能,增强对 quill 实例的安全访问
- 更新样式排版,提高组件可读性和一致性

refactor(file-upload): 移除旧代理引用,使用 modern Vue API
替换 `proxy` 调用为 `modal` 插件直接调用,提升代码清晰度与健壮性

refactor(image-upload): 替换旧实例调用方式,强化错误提示机制
统一使用 `modal` 进行消息提示和加载状态控制,改善用户体验

refactor(tree-select): 引入 Composition API 优化节点操作逻辑
移除 `getCurrentInstance` 的不必要使用,改为明确的模板引用管理

chore(main): 添加 util._extend 补丁以消除 Node.js 环境警告
解决开发环境下由于 Node.js 内建模块缺失造成的运行时警告问题

feat(template): 完善跌倒/坠床评估护理记录单模板
- 增加详细注释说明各部分作用,便于后续维护
- 明确组件名称为中文,利于业务识别
- 丰富表单交互细节及数据处理逻辑,支持动态打分、措施选择等功能

refactor(template-index): 加强模板组件自动注册逻辑
增加组件 name 属性校验,防止无效或匿名组件被注册到全局
2025-12-14 14:22:55 +08:00
e1b9d36153 feat(template): 添加股骨头坏死门诊病历模板
新增了一个名为“股骨头坏死(模板1)”的门诊病历模板文件,包含完整的主诉、现病史、既往史、体格检查、辅助检查、诊断和治疗方案等内容,便于医生快速调用和填写。

该模板位于 `src/template/股骨头坏死(模板1).vue`,采用 Vue 单文件组件格式编写,并定义了相应的结构与样式。
2025-12-13 22:23:58 +08:00
fdb8d6c934 更新模板注释测试中文名 2025-12-13 22:18:56 +08:00
22a1ac57b2 改回配置IP地址 2025-12-13 16:06:13 +08:00
4d243815a6 修正格式 2025-12-13 16:03:06 +08:00
882e8c9199 修正问题 2025-12-12 17:06:14 +08:00
a0c87f6335 问题关键 2025-12-12 17:01:24 +08:00
538dde55f7 还原门诊医生站 2025-12-12 15:57:03 +08:00
f33e3c6f15 首页报错和门诊医生站报错 2025-12-12 15:48:07 +08:00
0794782505 TypeScript Vue Plugi 2025-12-12 15:43:58 +08:00
d37fa46b5f 删除rabbitmq 2025-12-12 15:07:27 +08:00
8fcc229ad8 关联套餐设置页面对应字段 2025-12-12 10:59:22 +08:00
39aa710fd3 医生排班后端接口异常修复 2025-12-12 09:12:40 +08:00
49f95b40ea Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2025-12-12 09:11:50 +08:00
eb2d7302b7 添加文件 2025-12-11 22:04:00 +08:00
eb26f9db34 添加文件 2025-12-11 22:03:51 +08:00
bd6f3ca587 医生排班页面修复,新增组件间交互功能。 2025-12-11 17:14:48 +08:00
a58e02f2cb 预约管理 2025-12-11 16:23:59 +08:00
8c8ef13021 预约管理需求 2025-12-11 16:06:09 +08:00
d9a0a98f52 预约管理需求 2025-12-11 15:53:00 +08:00
8c84b6eb46 修正可以显示出主页 2025-12-11 15:23:16 +08:00
3d797cc0e0 修正前端问题 2025-12-11 14:47:17 +08:00
df7281a2d4 INDEX.JS修正 2025-12-10 16:33:41 +08:00
f83d7ae520 修改index.js 2025-12-10 16:29:00 +08:00
d9c8525b94 修正问题 2025-12-10 16:04:18 +08:00
bcc5cbb2fb 删除miniapp相关 2025-12-10 15:48:35 +08:00
67a8351d70 Merge remote-tracking branch 'origin/develop' into develop 2025-12-10 15:45:19 +08:00
391506e423 医生排班 2025-12-10 15:44:36 +08:00
b1117b4157 删除无效合并 2025-12-10 15:28:29 +08:00
b0eb9861b9 合并分支 2025-12-10 15:22:25 +08:00
b863c14f2b 解决合并冲突并优化代码结构 2025-12-10 14:24:34 +08:00
18f6a845e6 解决合并冲突 2025-12-10 14:20:24 +08:00
e1385cb3e6 维护系统->检查方法、部位前端需求优化。 2025-12-10 11:51:38 +08:00
c8ca56c3f5 门诊医生排班->科室名称管理页面科室下拉选项数据来源更改 2025-12-09 16:55:02 +08:00
b149f7d687 门诊医生排班->科室名称管理页面基础按钮功能、数据渲染OK 2025-12-09 14:17:58 +08:00
19702c25e5 仓库bug 2025-12-09 09:52:20 +08:00
qk123
eaa681c9ff 门诊医生排班->科室名称管理后端接口,前端基础页面 2025-12-08 16:46:37 +08:00
205c58782b 修正发票管理界面删除功能的权限判断 2025-12-08 14:02:31 +08:00
00e1c62de0 门诊挂号-》新增患者:监护人信息录入控制,当患者的年龄小于等于维护的监护人规定年龄时,则需要登记患者监护人的相关信息,反之无需填写。 2025-12-08 10:20:26 +08:00
46c9787216 修改套餐管理页面操作图标设置 2025-12-05 16:50:37 +08:00
e0a768de2e 新增套餐设置页面中的套餐管理页面并增加相应跳转逻辑 2025-12-05 16:37:34 +08:00
fc7f931728 新增套餐设置页面中的套餐管理页面并增加相应跳转逻辑 2025-12-05 16:34:12 +08:00
qk123
3ccb970a09 维护系统->检查方法、部位导出表格功能OK 2025-12-05 15:54:57 +08:00
ljj
8a9a622aeb 72.系统管理--》基础数据-》科室管理 2025-12-05 13:39:23 +08:00
qk123
29e7f0937b 维护系统->检查方法、部位条件搜索前后端实现 2025-12-04 14:47:39 +08:00
029d534b3c 新增检验项目设置中的检验类型页面并实现相关逻辑 2025-12-04 09:47:34 +08:00
qk123
213723b220 维护系统->检查方法后端接口数据校验修改 2025-12-04 09:33:44 +08:00
qk123
c636e77fd0 维护系统->检查部位前端接口缺少导入。 2025-12-04 09:21:35 +08:00
qk123
7407562ec5 维护系统->检查部位后端接口优化。 2025-12-03 17:15:35 +08:00
qk123
b3c27ec789 维护系统->检查方法前端页面优化、接口功能完善(搜索栏和导出表格未处理),后端接口优化。 2025-12-03 16:00:24 +08:00
qk123
601ae40666 维护系统->LIS分组前端页面开发,基础功能实现 2025-12-03 14:24:19 +08:00
3dda5ce72d 修改配置7 2025-12-03 13:48:25 +08:00
qk123
99d4c28b95 检查项目维护->Lis分组前端接口、后端实体优化。 2025-12-02 16:46:19 +08:00
qk123
0e70de6de7 Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2025-12-02 16:44:57 +08:00
72eb1088df 修正前端PROD 2025-12-02 15:03:40 +08:00
a853c16854 修正prd 2025-12-02 14:43:35 +08:00
73a349f98a 冗余prod 2025-12-02 14:25:10 +08:00
5fb7a3f488 production 2025-12-02 14:12:06 +08:00
a8eb7d5697 prd->production 2025-12-02 14:08:09 +08:00
eb3b142ce4 修改配置 2025-12-02 14:03:49 +08:00
9f6a39ba30 修改配置文件 2025-12-02 14:02:25 +08:00
f7f2f98bbe 修改统一前端的PRD的标识 2025-12-02 13:52:18 +08:00
79e68ee14e 修改前端VUE的DEV环境配置 2025-12-02 12:53:01 +08:00
bc8987c463 配置3 2025-12-02 11:51:07 +08:00
3f7174fcd1 修复重复 2025-12-02 10:31:18 +08:00
080008f447 Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2025-12-02 10:29:50 +08:00
5c3d935615 前端加上相关test的配置 2025-12-02 10:29:39 +08:00
a0845127c6 配置2 2025-12-02 10:28:02 +08:00
ba65ab303b 多环境配置 2025-12-02 09:25:35 +08:00
qk123
6fbdddf0ee 检查项目维护->Lis分组后端接口 2025-12-01 16:13:30 +08:00
py
173cbc7f87 门诊挂号-》完善新增患者字典信息 2025-12-01 14:45:27 +08:00
qk123
2e341a123e 检查项目维护检查方法、部位前端表格数据映射ok 2025-12-01 13:42:15 +08:00
qk123
8beff2ee14 检查方法、检查部位前端页面、完善后端接口逻辑 2025-11-28 17:03:08 +08:00
wzk
1b939ba5b7 刷新 2025-11-28 16:48:14 +08:00
wzk
577daabe1c 医嘱诊断和费用性质没有自动引入 2025-11-28 16:35:41 +08:00
wzk
327e88e6d4 检查项目设置-套餐设置-套餐管理界面放大或缩小数据显示不全 2025-11-28 15:24:52 +08:00
叶锦涛
548fabcffe 新建检验项目设置的检验类型页面 2025-11-28 13:56:27 +08:00
263e21e157 换卡bug 2025-11-28 10:41:14 +08:00
d7955aa628 配置 2025-11-28 09:58:52 +08:00
叶锦涛
d197f7555f 修复发票管理界面管理员和普通操作人员的筛选规则 2025-11-27 13:36:17 +08:00
wzk
a0e52da437 门诊号码管理维护界面前后端 2025-11-27 13:08:42 +08:00
qk123
88d79729fe 库房管理->采购管理->采购管理点击《详情》按钮跳转后无数据显示 2025-11-27 12:00:21 +08:00
6dc6480e64 Merge remote-tracking branch 'origin/develop' into develop 2025-11-27 10:40:12 +08:00
98c263a72b 患者档案和进货单bug 2025-11-27 10:39:56 +08:00
wzk
50a2ef9e00 门诊医生站->医嘱:新增独立的西药处方单补充 2025-11-27 09:41:59 +08:00
wzk
065f7052c6 检查项目设置->套餐设置->套餐管理补充 2025-11-27 09:24:26 +08:00
e23d42404d 患者档案和进货单bug 2025-11-27 08:56:19 +08:00
wzk
4120d4e001 检查项目设置->套餐设置->套餐管理 2025-11-27 08:44:32 +08:00
wzk
1bd2089047 检查项目设置-套餐设置 2025-11-26 16:18:47 +08:00
wzk
6d9ff7dc10 检查项目设置-套餐设置 2025-11-26 16:15:41 +08:00
wzk
ae7ca984f8 检查项目设置-套餐设置 2025-11-26 16:15:11 +08:00
wzk
69b7a4d865 检查项目设置-套餐设置界面 2025-11-26 14:39:57 +08:00
wzk
864bf55025 修复门诊医生站->【处方单】按钮,点击【处方单】按钮无响应问题 2025-11-26 13:34:41 +08:00
wzk
249ef5f87e 门诊挂号-》医生字段,对字段医生进行过滤,让医生和、就诊科室、挂号类型形成对照。 2025-11-26 13:15:42 +08:00
qk123
df3fb6c66c 检查方法、检查部位接口部分细节修改 2025-11-26 10:37:30 +08:00
qk123
10ec9f4c1b 检查方法、检查部位后端接口、实体、数据库表基本完成。 2025-11-26 10:31:30 +08:00
0b98763c05 门诊挂号查询优化 2025-11-25 16:14:03 +08:00
叶锦涛
3d3b21a775 修复操作员的工号的编辑功能 2025-11-25 15:58:17 +08:00
叶锦涛
4ba4f80946 修改发票管理页面 2025-11-25 15:39:29 +08:00
叶锦涛
ed7cb2dab5 修改发票管理页面 2025-11-25 15:30:33 +08:00
wzk
50ef9e6743 修复西药处方单bug 2025-11-25 13:49:38 +08:00
py
250d7dde34 门诊医生站-》开立处方医嘱:完善药品的字典信息 2025-11-25 11:27:58 +08:00
wzk
69f3e066db 门诊医生站-》医嘱:新增独立的西药处方单 2025-11-25 10:17:13 +08:00
叶锦涛
afb0c3933c 删除检查项目设置多余数据 2025-11-24 16:22:43 +08:00
叶锦涛
45ac07e57c 删除检查项目设置多余数据 2025-11-24 16:19:46 +08:00
qk123
262ea97824 同一患者保存病历后判断逻辑问题 2025-11-24 15:13:18 +08:00
ljj
dcfa13f239 系统管理-目录管理-》耗材目录。将该界面的字段标题设置可以手动拉宽每个字段的宽度,有的字段内容看不全,将界面的字段标题设置成可以调节每个字段的长度,使之能看全内容 2025-11-24 15:11:19 +08:00
叶锦涛
27c3c850d6 创建项目检查设置页面 2025-11-24 14:35:54 +08:00
wzk
122a15a73d 修复医嘱保存、签发不成功 2025-11-24 11:40:37 +08:00
wzk
61749aee4d 门诊号码管理修改关闭给予保存提示 2025-11-24 10:45:27 +08:00
97a29a31c5 门诊挂号查询优化 2025-11-24 09:39:23 +08:00
wzk
c3734f921c 用户管理中用户名字替换成用户姓名 2025-11-24 09:34:04 +08:00
c561586cfa 门诊换卡优化 2025-11-24 09:22:11 +08:00
qk123
60593233bc 中医添加医嘱后页面不显示BUG 2025-11-21 15:08:27 +08:00
wzk
992b03f9c2 解决退号记录的退号操作工作取值问题 2025-11-21 13:15:08 +08:00
wzk
36628342dc 用户管理将用户名称改成用户账号、用户昵称改成用户姓名。 2025-11-21 11:32:46 +08:00
qk123
3783e4a872 优化配方名称框、剂量单位框、脚注框 2025-11-21 09:59:09 +08:00
py
584f79294b 13 收费工作站-》门诊挂号1、将医生改成出诊医生。
2、将出诊医生字段选中‘内科医生1’,点击【确认】按钮,重新打开出诊医生字段的内容保存成功
2025-11-21 09:39:22 +08:00
wzk
a5884ec069 修复退号记录的退号操作工作取值问题 2025-11-21 09:25:39 +08:00
wzk
cc2f7db754 Merge remote-tracking branch 'origin/develop' into develop 2025-11-21 09:24:21 +08:00
wzk
fcccfc1959 解决医嘱确定后中成药项目名消失 2025-11-21 09:23:20 +08:00
c5ec91e7d3 新增医嘱中成药显示项目名称1 2025-11-21 09:22:35 +08:00
6b67e25d94 新增医嘱中成药显示项目名称 2025-11-21 09:17:24 +08:00
wzk
6da3b63012 医嘱保存成功 2025-11-20 16:29:14 +08:00
qk123
ea0f0e2294 中医:添加药品”确定“按钮能够正常起作用。 2025-11-20 11:14:37 +08:00
qk123
980f0aeb9c 中医:新增配方名称、煎药方式、脚注字段。 2025-11-20 11:02:55 +08:00
叶锦涛
17b40118ce 修复bug 2025-11-20 10:47:49 +08:00
叶锦涛
d10a78e5e8 修复处方标志保存的不正确 2025-11-20 09:18:54 +08:00
叶锦涛
f7ad010b2a 修复bug 2025-11-20 09:05:06 +08:00
叶锦涛
1a7ff0a686 修复bug 2025-11-20 08:58:26 +08:00
叶锦涛
3ad3f21362 实现药品目录处方标志保存 2025-11-19 16:47:35 +08:00
叶锦涛
c84fc3c236 删除重复函数 2025-11-19 16:43:12 +08:00
叶锦涛
a6561e2ca6 删除重复函数 2025-11-19 16:37:01 +08:00
叶锦涛
dfe35bb7f0 修改耗材/诊疗绑定,耗材项目药品的缺失 2025-11-19 16:33:12 +08:00
py
18c96e006f Merge branch 'develop' of https://gitea.gentronhealth.com/Yajentine/his into develop 2025-11-19 15:54:20 +08:00
py
f5db504363 feat(医生站): 添加处方单删除功能及相关UI
- 新增处方单删除按钮及交互逻辑
- 实现处方单删除前的条件检查(药品数量和收费状态)
- 添加删除按钮的样式和禁用状态
- 完善处方单药品数量和总价的计算方法
2025-11-19 15:54:15 +08:00
wzk
deb31c969a 修复耗材确定后显示成中成药 2025-11-19 14:06:04 +08:00
wzk
e7dac9762d 门诊号码管理编辑员工号 2025-11-19 13:19:48 +08:00
叶锦涛
89862878b5 修改耗材目录地点的缺失 2025-11-18 17:23:39 +08:00
叶锦涛
e105919dab 修改错误提示信息 2025-11-18 11:15:10 +08:00
叶锦涛
e83fc94334 新建发票管理页面 2025-11-18 10:40:57 +08:00
5bf7ab481f 编辑药品tab页面可以不显示数据了 新增之后勾选框还存在 2025-11-18 10:36:15 +08:00
wzk
afa904bd83 医嘱类别耗材项目从耗材目录获取数据 2025-11-18 10:09:30 +08:00
wzk
a343464d8d 门诊医生站-》开立医嘱:增加备注字段 2025-11-18 10:08:46 +08:00
wzk
4a2485e434 门诊医生站-》医嘱:皮试字段做成单选框。当开单医生选中检索出来的药品确认时,如果该药品是皮试药品,系统’药品:该药品名称+需要做皮试,是否做皮试? 2025-11-18 09:25:07 +08:00
Auora
4e2d4d85ec 【bug】解决撤回按钮弹出多余信息 2025-11-17 15:55:59 +08:00
wzk
7ddf6211ee Merge remote-tracking branch 'origin/develop' into develop 2025-11-17 13:29:55 +08:00
wzk
d44600b641 挂号退号 2025-11-17 13:28:33 +08:00
a68c4402de 实现门诊换卡的整体逻辑 2025-11-17 13:24:49 +08:00
wzk
93103f7f40 门诊号码管理维护界面-》优化 2025-11-17 13:09:36 +08:00
wzk
7202151a41 正常挂号消除退款的记录 2025-11-17 11:04:59 +08:00
wzk
491d8f8930 挂号退款加退款记录 2025-11-17 10:59:22 +08:00
wzk
b886726ecc 当就诊状态是非接诊时,操作【退号】系统提示‘该患者医生已接诊,不能退号!’。 2025-11-17 09:55:32 +08:00
qk123
9d0dde6794 门诊医生站移除取消接诊的错误消息提示 2025-11-17 09:46:09 +08:00
qk123
f3578b3202 新增门诊医生站确认取消接诊后移除错误消息提示 2025-11-17 09:42:01 +08:00
Auora
0610ba7cb5 解决门诊挂号退号费用性质不一致的bug 2025-11-14 15:41:30 +08:00
叶锦涛
8b848f787a 修改科室管理主界面科室分类和编辑科室的字典 2025-11-14 09:25:37 +08:00
wzk
a794cd0ce3 门诊医生站开立医嘱中成药的开医嘱录入界面和西药的开医嘱录入界面保持一致 2025-11-14 09:01:48 +08:00
叶锦涛
d97fd0bed1 修复采购入库时选择不同仓库新增药品时仓库的错误 2025-11-13 17:16:12 +08:00
叶锦涛
c0e67722d9 修复门诊医生站诊断删除按钮的错误 2025-11-13 15:40:53 +08:00
qk123
aca7fea69f 新增门诊医生站取消接诊功能 2025-11-13 13:41:48 +08:00
wzk
ce9344f9ce 门诊医生站-》开立医嘱系统根据选中的药品名称
判断医嘱类型。
2025-11-13 10:17:35 +08:00
wzk
991ad61655 1 2025-11-13 08:59:09 +08:00
Auora
e4ac857461 【bug】剂量单位bug 2025-11-12 14:18:51 +08:00
叶锦涛
24ab98ae89 发票号码维护页面 2025-11-12 13:51:34 +08:00
wzk
e79ab9ac4f 医嘱:修改用药天数时,系统自动通过公式自动换算总量 2025-11-12 13:31:11 +08:00
b66c2027d1 换卡处理的分页 2025-11-12 12:08:52 +08:00
09bf895711 维护换卡处理的查询 2025-11-12 10:58:12 +08:00
Auora
825cdd58ae 【bug】 2025-11-12 10:12:12 +08:00
0977eb8145 维护换卡处理的查询bug 2025-11-12 09:59:03 +08:00
Auora
73efeecfc1 解决当日已挂号页面费用性质不一致问题 2025-11-12 09:47:28 +08:00
fe8fb3d321 维护换卡处理的查询 2025-11-12 09:38:47 +08:00
叶锦涛
618fb1e340 修改新增患者的信息样式 2025-11-12 09:15:08 +08:00
叶锦涛
215fe8b889 修改科室管理和新增科室分类的字典 2025-11-11 16:46:36 +08:00
Auora
3e32458b7f 解决医嘱类型选中开单后变成数字问题。 2025-11-11 16:05:18 +08:00
wzk
a8e170ea45 门诊号码管理维护界面-》优化 2025-11-11 13:58:34 +08:00
wzk
1856ae50fd Merge remote-tracking branch 'origin/develop' into develop 2025-11-11 13:58:20 +08:00
wzk
1711e6c115 门诊号码管理维护界面-》优化 2025-11-11 13:57:34 +08:00
叶锦涛
b3f226feab 修改新增患者 2025-11-11 13:28:50 +08:00
wzk
c086dc8c77 修改报表管理-》院内库房情况查询报表-》库存商品明细查询报表,选择库存范围条件检索报错补充 2025-11-11 11:51:52 +08:00
wzk
6762341fbd 修改报表管理-》院内库房情况查询报表-》库存商品明细查询报表,选择库存范围条件检索报错。 2025-11-11 11:36:15 +08:00
d5f8b0f23b 医嘱类型勾选全部之后项目报错的bug 2025-11-11 10:12:40 +08:00
叶锦涛
38233110f2 1、监护人关系要取原来的联系人关系的下拉内容,取值于字典管理-》与患者关系。 2025-11-10 17:11:15 +08:00
6ebb59bc5e 、增加挂号单补打功能(差就诊号查询自动填充) 2025-11-10 17:09:08 +08:00
wzk
69aefab280 库房/药房管理:添加的耗材库 2025-11-10 16:57:05 +08:00
3d3ff82e24 解决医嘱类别选择全部项目报错的问题 2025-11-10 16:53:14 +08:00
69780d204f 1、收费工作站-》门诊挂号:将门诊挂号界面的功能按钮统一摆放在标题页,依次摆放整齐。
2、增加挂号单补打功能(差就诊号查询自动填充)
3.患者档案管理:将【修改】和【查询】按钮调出的界面统一修改成图2的新增患者界面。
2025-11-10 16:35:47 +08:00
Auora
ef52f290fe 解决医嘱类型选中开单后变成数字问题。 2025-11-10 16:17:44 +08:00
wzk
e9d1119777 门诊号码管理维护界面-》优化 2025-11-10 14:41:22 +08:00
qk123
cf182f0e34 修改:初复诊标识系统重新判断->从数据库中读取 2025-11-10 14:32:59 +08:00
qk123
626ae1a459 修改:初复诊标识系统重新判断->从数据库中读取 2025-11-10 10:12:29 +08:00
wzk
3d6977328f 解决系统管理-》基础数据-》库房/药房管理无法添加的耗材库问题的补充 2025-11-07 16:42:19 +08:00
wzk
2dcd7ba1d5 解决系统管理-》基础数据-》库房/药房管理无法添加的耗材库问题 2025-11-07 16:27:56 +08:00
qk123
16a4d38113 修复疾病目录模块下新增病种异常提示请勿重复提交问题 2025-11-07 15:25:28 +08:00
57c98ea39d 解决诊断目录数据展示不全问题 2025-11-07 15:13:41 +08:00
08f7e35042 解决诊断目录数据展示不全问题 2025-11-07 14:08:28 +08:00
wzk
43f3d1ba94 立医嘱的执行科室默认获取诊疗项目维护的所属科室,如果诊疗项目未维护所属科室,默认执行科室为开单科室,然后开单医生又权限操作修改。 2025-11-07 13:41:57 +08:00
wzk
2e45c6c029 开单科室维护的取药药房药在医生开处方药做好过滤限制,没有维护的药房/药库或者药品类型过滤掉。 2025-11-07 13:35:06 +08:00
wzk
945182c6f8 解决报表管理-》院内库房情况查询报表-》库存商品明细查询报表bug 2025-11-07 09:56:50 +08:00
Auora
f7de87860b 1增加挂号收费系统参数维护界面挂号处理的相关参数
2在打印设置tba页面增加是否打印挂号单维护参数
2025-11-06 17:20:42 +08:00
wzk
67e4de0d68 Merge remote-tracking branch 'origin/develop' into develop 2025-11-06 17:13:11 +08:00
qk123
602d521424 修改完诊后再接诊初复诊标识不对问题 2025-11-06 17:12:57 +08:00
叶锦涛
01e14ee084 修改登录界面测试医院的信息 2025-11-06 16:56:41 +08:00
qk123
4a5572de26 修改完诊后再接诊初复诊标识不对问题 2025-11-06 14:00:45 +08:00
88a516d1be 门诊挂号-》【档案】档管理的【新增患者】-患者界面(图1)的内容要与图2的内容一致(门诊挂号-》【新建】-》新增患者界面) 2025-11-06 13:34:59 +08:00
wzk
9ce967002a Merge remote-tracking branch 'origin/develop' into develop 2025-11-06 13:25:41 +08:00
wzk
fd536a035e 修改 2025-11-06 13:25:25 +08:00
wzk
df84a7eefa Merge remote-tracking branch 'origin/develop' into develop 2025-11-06 13:23:55 +08:00
2804703eaa 门诊号码管理维护界面 2025-11-06 13:23:33 +08:00
wzk
e14a0e3d13 Merge remote-tracking branch 'origin/develop' into develop 2025-11-06 13:15:49 +08:00
5a99fe8234 门诊号码管理维护界面 2025-11-06 13:15:22 +08:00
3ad5c5533f 在门诊挂号页面增加档案按钮完成患者档案管理的跳转 2025-11-06 09:11:26 +08:00
Auora
9997f4f7c9 修改医嘱字典 2025-11-06 08:53:57 +08:00
Auora
3d4e4a8119 修改病历不能编辑问题 2025-11-05 16:15:23 +08:00
叶锦涛
3deac74898 在处方打印处增加患者信息 2025-11-05 16:07:37 +08:00
wzk
7bbc50ef47 Merge remote-tracking branch 'origin/develop' into develop 2025-11-05 15:39:48 +08:00
wzk
4ae6765a15 门诊号码管理维护界面 2025-11-05 15:39:39 +08:00
wzk
1292853c5d Merge remote-tracking branch 'origin/develop' into develop 2025-11-05 14:53:46 +08:00
Auora
41791c9ccc 修改门诊挂号和费用支付上的费用性质不一致的问题,并且将解决无法收费的问题 2025-11-05 14:53:34 +08:00
Auora
0674215b53 修改门诊挂号和费用支付上的费用性质不一致的问题,并且将解决无法收费的问题 2025-11-05 14:09:06 +08:00
e42d990304 收费工作站-》门诊挂号:将门诊挂号界面的功能按钮统一摆放在标题页,依次摆放整齐。 2025-11-05 13:32:48 +08:00
0dbe9a57c8 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	openhis-ui-vue3/src/views/charge/outpatientregistration/index.vue
2025-11-05 11:45:36 +08:00
85ea831a1c 收费工作站-》门诊挂号:将门诊挂号界面的功能按钮统一摆放在标题页,依次摆放整齐。 2025-11-05 11:43:52 +08:00
7ac26cf781 增加监护人信息限制,在门诊挂号页面增加档案按钮完成患者档案管理的跳转 2025-11-05 11:38:47 +08:00
b7412648b4 修改报表格式2 2025-11-04 16:45:41 +08:00
叶锦涛
97571652e5 把新增患者中的联系人替换成监护人 2025-11-04 16:36:26 +08:00
b5d4da97f9 修改报表格式 2025-11-04 16:10:16 +08:00
叶锦涛
e5edb6bda2 跳过了处方打印页面的构建 2025-11-04 15:45:12 +08:00
叶锦涛
0e1ae53194 修改了标题undefined 2025-11-04 14:55:32 +08:00
a1efd3f91b 修复完诊后的初诊复诊错乱 2025-11-04 13:24:07 +08:00
3211553d0d 修复门诊收费报表报错,修复采购入库历史遗留数据问题 2025-11-04 13:10:47 +08:00
wzk
a57a326b83 Merge remote-tracking branch 'origin/develop' into develop 2025-11-04 10:44:14 +08:00
wzk
f77d0a2567 新增用户用户密码系统可以自动赋值一个初始密码,123456。 2025-11-04 10:43:52 +08:00
wzk
72581466aa 新增用户用户密码系统可以自动赋值一个初始密码,123456。 2025-11-03 17:39:05 +08:00
Auora
4b3471df06 门诊挂号的费用性质取值改成取值字典管理-》医疗费用支付方式代码的字典数据
将门诊医生站开立医嘱的医嘱类型字段下拉列表内容做成前台维护
2025-11-03 17:15:00 +08:00
叶锦涛
68c65ae8bd 给登录界面的标题加上了信息管理系统 2025-11-03 17:10:10 +08:00
wzk
1b879addc7 门诊医生开处方单,系统把药品无论是药库或药房有的库存都显示出来了。解决显示只有药房的问题。 2025-11-03 16:14:52 +08:00
叶锦涛
3888859b2b 修复了处方打印不能打印的错误 2025-11-03 13:48:20 +08:00
Auora
f03d2e1633 修改病历格式 2025-11-03 13:38:47 +08:00
bc91eb7cdc 按照采购退货的申请审批流程,完成药品采购申请退货的审批确认, 2025-11-03 11:56:34 +08:00
Auora
93120e973a [bug]解决选中药库或药房对应的源仓库或目的仓库无下拉数据 2025-11-03 11:12:19 +08:00
wzk
c6a27f6276 Merge remote-tracking branch 'origin/develop' into develop 2025-11-03 09:41:36 +08:00
wzk
778704c9dc 药品类别下拉别表内容错误,药品类别应该取值如下图字典管理的药品分类编码 2025-11-03 09:41:28 +08:00
wzk
ff227b40c1 Merge remote-tracking branch 'origin/develop' into develop 2025-11-03 09:38:43 +08:00
wzk
c7d8ab5b48 Merge remote-tracking branch 'origin/develop' into develop 2025-11-03 09:38:36 +08:00
wzk
9c27b2a134 Merge remote-tracking branch 'origin/develop' into develop 2025-11-03 09:31:58 +08:00
叶锦涛
3f919188d2 药品类别下拉别表内容错误,药品类别应该取值如下图字典管理的药品分类编码 2025-11-03 09:31:45 +08:00
wzk
8942058972 Merge remote-tracking branch 'origin/develop' into develop 2025-11-03 09:29:49 +08:00
叶锦涛
6c2dbf0418 药品类别下拉别表内容错误,药品类别应该取值字典管理的药品分类编码 2025-11-03 09:29:30 +08:00
叶锦涛
85e185bab8 修复了全选框 2025-10-31 16:35:47 +08:00
叶锦涛
88aa1517ef Merge branch 'develop' of https://gitea.gentronhealth.com/wangjunping/his into develop 2025-10-31 16:32:53 +08:00
叶锦涛
c05118c427 修复了全选框 2025-10-31 16:32:13 +08:00
Auora
2a7f1326b9 [bug]修改就诊时,就诊时间逻辑 2025-10-31 16:23:12 +08:00
叶锦涛
c07255fe5b 修改了登入界面的xxx医院信息管理系统 2025-10-31 16:13:53 +08:00
叶锦涛
749bfc89dd 修复了打印单据没有响应的错误,修复了新增加诊断诊断类别自动获取11的错误 2025-10-31 16:06:12 +08:00
52cc5e3aae 实现采购入库的供货商字段数据存放到数据库,并且系统在采购入库界面能读取对应的采购入库单的对应供货商名称显示 2025-10-31 13:52:33 +08:00
wzk
642c4a0941 Merge remote-tracking branch 'origin/develop' into develop 2025-10-31 12:38:34 +08:00
wzk
30953d5771 开立医嘱的执行科室默认获取诊疗项目维护的所属科室 2025-10-31 12:38:22 +08:00
wzk
83e0c663c9 在开立好的医嘱名称前增加医嘱类别的显示 2025-10-31 12:32:41 +08:00
b19337e76a 修复初诊和就诊的bug 2025-10-31 12:30:11 +08:00
ba607346bd 修复初诊和就诊的bug 2025-10-31 11:05:40 +08:00
Auora
433c452a40 解决库房/药房管理,操作编辑弹窗问题 2025-10-31 10:08:59 +08:00
Auora
a1be7fdbfd [bug]修改仓库字段下拉别表无内容bug 2025-10-31 09:01:35 +08:00
叶锦涛
87409d0c93 修复了药房/库房的删除的报错 2025-10-30 15:38:51 +08:00
d5c8ae8d45 修复初诊和就诊的bug 2025-10-30 15:28:05 +08:00
bc45e9c8c6 首页页面优化 2025-10-30 11:14:25 +08:00
Auora
42992382c0 增加isFoodDiseasesNew 函数 2025-10-30 10:43:54 +08:00
Auora
22d7eba510 增加getEmrDetail 函数 2025-10-30 09:56:41 +08:00
9728c8a6dd 优化格式问题 2025-10-30 09:45:50 +08:00
c951144ac6 首页页面进行了初步优化 2025-10-30 09:15:27 +08:00
叶锦涛
0b179fffd6 诊断排序 2025-10-29 16:50:39 +08:00
Auora
75374ac5d3 更改.env.production 2025-10-29 15:15:26 +08:00
Auora
2a83719b87 更改prod配置 2025-10-29 14:54:55 +08:00
Auora
e58f2d807b 更改prod配置 2025-10-29 14:03:43 +08:00
Auora
b2884def17 Merge branch 'develop' of https://gitea.gentronhealth.com/wangjunping/his into develop
# Conflicts:
#	openhis-ui-vue3/.env.spug
2025-10-29 13:53:14 +08:00
Auora
064840dd42 删除VITE_OUT_DIR=dist-spug 2025-10-29 13:52:22 +08:00
1aa814c766 更新 openhis-ui-vue3/.env.spug
删除VITE_OUT_DIR=dist-spug
2025-10-29 05:49:44 +00:00
Auora
b9719a51d1 增加build:spug 2025-10-29 13:46:48 +08:00
Auora
03b83aaf7c 增加VITE_APP_ENV = 'spug' 2025-10-29 13:30:25 +08:00
Auora
d93976483b 增加VITE_APP_BASE_API = '/admin-api' 2025-10-29 13:28:13 +08:00
dd0a3a915c 身份证号改为不是必须项只有输入身份证号的时候才会校验格式问题 2025-10-29 09:47:32 +08:00
2f3994c575 身份证号改为不是必须项只有输入身份证号的时候才会校验格式问题 2025-10-29 09:43:54 +08:00
wzk
daa78e128f 修复医嘱请选择项目选完选项框不消失 2025-10-29 09:40:55 +08:00
wzk
2ca594cb39 Merge remote-tracking branch 'origin/develop' into develop 2025-10-29 09:36:01 +08:00
Auora
7805c26f4a Merge remote-tracking branch 'origin/develop' into develop 2025-10-29 09:33:01 +08:00
Auora
b7d34537c2 修改login 2025-10-29 09:32:29 +08:00
wzk
c1213fcf59 Revert "修复医嘱请选择项目选完选项框不消失"
This reverts commit 4afe0d107c.
2025-10-29 09:21:55 +08:00
wzk
a64edace55 Merge remote-tracking branch 'origin/develop' into develop 2025-10-29 09:04:25 +08:00
wzk
4afe0d107c 修复医嘱请选择项目选完选项框不消失 2025-10-29 09:04:01 +08:00
Auora
d8af11412f 修改格式 2025-10-29 08:55:14 +08:00
Auora
00816c9834 修改位置:applicationFormBottomBtn.vue 中的 import 语句。 2025-10-28 17:28:25 +08:00
Auora
4fb7bea80a 修改位置:prescriptionlist.vue 中的 import 语句 2025-10-28 17:21:20 +08:00
Auora
0fc72cb270 修改位置:prescriptionlist.vue 中的 import 语句 2025-10-28 17:14:23 +08:00
Auora
eadf521903 Merge branch 'develop' of https://gitea.gentronhealth.com/wangjunping/his into develop 2025-10-28 17:04:08 +08:00
f786fdbc3f 更新 openhis-ui-vue3/.env.spug
删除NODE_ENV=spug
2025-10-28 09:03:17 +00:00
92c4c938a3 更新 openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionMedicineList.vue 2025-10-28 08:57:06 +00:00
Auora
a94a1b7b69 Merge branch 'develop' of https://gitea.gentronhealth.com/wangjunping/his into develop 2025-10-28 16:34:06 +08:00
Auora
48755c2d9e 删掉多余逗号 2025-10-28 16:32:42 +08:00
叶锦涛
f99f8eb560 系统登入界面的设计 2025-10-28 16:27:42 +08:00
Auora
ddc7ce2fe7 spug测试 2025-10-28 15:56:24 +08:00
Auora
c9899c62d2 Merge branch 'develop' of https://gitea.gentronhealth.com/wangjunping/his 2025-10-28 15:55:04 +08:00
wzk
8b9837d7dc Merge remote-tracking branch 'origin/develop' into develop 2025-10-28 13:35:22 +08:00
wzk
2cba41331a 诊断类别:字典管理中找不到对应的字典数据,字典类别在显示出来的数据和医生开立诊断的数据不一致。 2025-10-28 13:34:56 +08:00
4da5ca427b 在租户管理-》所属用户界面的关闭按钮改为关闭当前的界面,并返回上一级界面, 2025-10-28 13:33:50 +08:00
wzk
f4605b1af7 下拉列表的刷选功能失效,按照下拉选中的医嘱类型能过滤出对应收费项目医生进行开单 2025-10-27 15:08:28 +08:00
叶锦涛
d2babdc9ed 修复已保存病例模板无数据的显示的问题 2025-10-27 14:02:01 +08:00
4d0599eac1 将历史病例中对病例选择的bug修复,现在是单选选中 2025-10-27 13:22:25 +08:00
Auora
35d99df274 test 2025-10-24 17:17:31 +08:00
Auora
ce76b2f98d 增加门诊病历的标题:门诊初诊病历/门诊复诊病历,当患者是初时-》门诊初诊病历,当患者为复诊时-》门诊复诊病历。
标题下面增加:就诊卡号、姓名、性别、年龄以及就诊日期(默认创建病历的当前时间)和就诊科室(患者当前开单科室),系统自动获取患者的档案信息。
2025-10-24 11:56:44 +08:00
8fbca1a898 Merge remote-tracking branch 'origin/develop' into develop 2025-10-24 11:27:32 +08:00
d548215123 就诊卡号查询患者信息 优化查询框布局 2025-10-24 11:26:56 +08:00
953d17dc8c 增加就诊和复诊的选定按钮和判断逻辑 2025-10-24 11:24:33 +08:00
叶锦涛
b71a21ea5c Merge remote-tracking branch 'origin/develop' into develop 2025-10-23 16:04:48 +08:00
叶锦涛
0a20b5e34e 拉宽诊断类型的方框 2025-10-23 16:02:55 +08:00
388425084e 增加就诊和复诊的选定按钮和判断逻辑 2025-10-23 16:01:34 +08:00
51ee8d1b43 医保码:将医保码修改成诊断代码。
在诊断名称后增加两个字段诊断医生和诊断时间,诊断医生为默认开立诊断的医生,诊断时间为默认开立诊断的当前时间。
2025-10-23 15:43:47 +08:00
Auora
d29d56e712 去掉patientList组件中多余的“岁” 2025-10-23 14:47:32 +08:00
Auora
9084ddaa98 1增加就诊卡号字段显示。
2卡号:当病历号/姓名字段通过条件检索到患者信息选择时卡号字段也要进行赋值。
2025-10-23 14:42:01 +08:00
叶锦涛
be6d5c1ccc 增加单位岁 增加项目编码字段 2025-10-23 10:52:34 +08:00
1bba9e598a 解决死亡时间格式不一致问题 2025-10-22 16:56:05 +08:00
d58a5e8ab3 通过卡号查询患者信息 2025-10-22 16:49:09 +08:00
e6ffb7101f 2 2025-10-22 16:26:55 +08:00
Auora
48b2188cf9 当输入患者的姓名和身份号码两个字段的值已经存在时,提醒挂号工作人员该患者档案已经存在 2025-10-22 15:15:11 +08:00
Auora
8bc5d45976 去掉年龄的“岁”字 2025-10-22 13:52:16 +08:00
04f6e7e960 Merge branch 'develop' of https://gitea.gentronhealth.com/wangjunping/his into develop 2025-10-22 11:52:42 +08:00
8fb58bdab8 就诊卡号:限制成必填选项。 2025-10-22 11:50:37 +08:00
叶锦涛
fdfe5334a1 4、年龄:增加单位,比如29岁,当年龄字段赋值29岁时系统自动换算出生年月日的值。 2025-10-22 11:38:15 +08:00
Auora
66b99009e6 身份证号校验功能 2025-10-22 09:07:07 +08:00
Auora
2c7456531d 更改数据库配置 2025-10-21 11:12:42 +08:00
Ubuntu_925
cede47f342 版本更新 2025-10-17 11:55:15 +08:00
abing
8ad2d6ebbb !6 修复编译错误、升级依赖版本、统一管理依赖
Merge pull request !6 from starxg/dev/starxg
2025-10-17 02:55:51 +00:00
Zhang.WH
dd0090a2a8 数据库脚本新增 2025-10-16 18:13:50 +08:00
Zhang.WH
e4c5f36f2e 版本更新 2025-10-16 17:38:49 +08:00
Zhang.WH
f515bb8fbb 版本更新 2025-10-16 17:18:06 +08:00
starxg
bd3874b3c7 修复编译错误升级依赖版本并同一管理 2025-10-09 16:40:52 +08:00
abing
8dc6faff0b !5 修改
Merge pull request !5 from Ubuntu_925/develop
2025-09-25 07:54:11 +00:00
Zhang.WH
d23a594a4b 修改 2025-09-25 10:49:37 +08:00
Zhang.WH
c8014404f1 后端最新版本同步 2025-09-25 10:43:50 +08:00
Zhang.WH
1276dc4adb 前端最新版本同步 2025-09-25 10:36:59 +08:00
abing
38785887b1 !4 修改
Merge pull request !4 from Ubuntu_925/develop
2025-09-05 02:29:40 +00:00
Zhang.WH
a3a06d6f3c 修改 2025-09-04 16:59:24 +08:00
abing
08f539dc72 版本更新
Merge pull request !3 from Ubuntu_925/develop
2025-09-03 07:59:28 +00:00
Zhang.WH
92bf46ba55 Merge branch 'develop' of https://gitee.com/Ubuntu_925/openhis-itai into develop 2025-09-03 15:56:38 +08:00
Zhang.WH
6987963840 Merge branch 'develop' of https://gitee.com/Ubuntu_925/openhis-itai into develop 2025-09-03 15:56:38 +08:00
Zhang.WH
8f82322d10 版本更新 2025-09-03 15:54:55 +08:00
Zhang.WH
850cce66a5 配置文件修改 2025-09-03 13:23:58 +08:00
Zhang.WH
2a75448a30 配置文件修改 2025-09-03 13:23:58 +08:00
Zhang.WH
b77fd8cc9d 补充修改 2025-09-03 11:27:23 +08:00
Zhang.WH
72176f67cc 补充修改 2025-09-03 11:27:23 +08:00
Zhang.WH
cf28642e34 修改 2025-09-03 11:23:29 +08:00
Zhang.WH
155df0c917 修改 2025-09-03 11:23:29 +08:00
Zhang.WH
3ef3c2fecf 文件修改 2025-09-03 11:05:08 +08:00
Zhang.WH
00208c5f79 文件修改 2025-09-03 11:05:08 +08:00
Zhang.WH
7d972e2d17 最新版本升级 2025-09-02 19:16:04 +08:00
Zhang.WH
db9d790435 最新版本升级 2025-09-02 19:16:04 +08:00
mohaijiang
2c907e49f4 update LICENSE.
Signed-off-by: mohaijiang <mohaijiang110@163.com>
2025-07-22 07:41:17 +00:00
天天开源
d641d286d0 update README.md.
Signed-off-by: 天天开源 <14124580+TTopen@user.noreply.gitee.com>
2025-07-14 02:28:17 +00:00
abing
6f846f5410 v0.2 2025-06-13 11:40:16 +08:00
5464 changed files with 641453 additions and 146231 deletions

View File

@@ -0,0 +1,386 @@
---
name: ui-ux-pro-max
description: "UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 9 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples."
---
# UI/UX Pro Max - Design Intelligence
Comprehensive design guide for web and mobile applications. Contains 50+ styles, 97 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 9 technology stacks. Searchable database with priority-based recommendations.
## When to Apply
Reference these guidelines when:
- Designing new UI components or pages
- Choosing color palettes and typography
- Reviewing code for UX issues
- Building landing pages or dashboards
- Implementing accessibility requirements
## Rule Categories by Priority
| Priority | Category | Impact | Domain |
|----------|----------|--------|--------|
| 1 | Accessibility | CRITICAL | `ux` |
| 2 | Touch & Interaction | CRITICAL | `ux` |
| 3 | Performance | HIGH | `ux` |
| 4 | Layout & Responsive | HIGH | `ux` |
| 5 | Typography & Color | MEDIUM | `typography`, `color` |
| 6 | Animation | MEDIUM | `ux` |
| 7 | Style Selection | MEDIUM | `style`, `product` |
| 8 | Charts & Data | LOW | `chart` |
## Quick Reference
### 1. Accessibility (CRITICAL)
- `color-contrast` - Minimum 4.5:1 ratio for normal text
- `focus-states` - Visible focus rings on interactive elements
- `alt-text` - Descriptive alt text for meaningful images
- `aria-labels` - aria-label for icon-only buttons
- `keyboard-nav` - Tab order matches visual order
- `form-labels` - Use label with for attribute
### 2. Touch & Interaction (CRITICAL)
- `touch-target-size` - Minimum 44x44px touch targets
- `hover-vs-tap` - Use click/tap for primary interactions
- `loading-buttons` - Disable button during async operations
- `error-feedback` - Clear error messages near problem
- `cursor-pointer` - Add cursor-pointer to clickable elements
### 3. Performance (HIGH)
- `image-optimization` - Use WebP, srcset, lazy loading
- `reduced-motion` - Check prefers-reduced-motion
- `content-jumping` - Reserve space for async content
### 4. Layout & Responsive (HIGH)
- `viewport-meta` - width=device-width initial-scale=1
- `readable-font-size` - Minimum 16px body text on mobile
- `horizontal-scroll` - Ensure content fits viewport width
- `z-index-management` - Define z-index scale (10, 20, 30, 50)
### 5. Typography & Color (MEDIUM)
- `line-height` - Use 1.5-1.75 for body text
- `line-length` - Limit to 65-75 characters per line
- `font-pairing` - Match heading/body font personalities
### 6. Animation (MEDIUM)
- `duration-timing` - Use 150-300ms for micro-interactions
- `transform-performance` - Use transform/opacity, not width/height
- `loading-states` - Skeleton screens or spinners
### 7. Style Selection (MEDIUM)
- `style-match` - Match style to product type
- `consistency` - Use same style across all pages
- `no-emoji-icons` - Use SVG icons, not emojis
### 8. Charts & Data (LOW)
- `chart-type` - Match chart type to data type
- `color-guidance` - Use accessible color palettes
- `data-table` - Provide table alternative for accessibility
## How to Use
Search specific domains using the CLI tool below.
---
## Prerequisites
Check if Python is installed:
```bash
python3 --version || python --version
```
If Python is not installed, install it based on user's OS:
**macOS:**
```bash
brew install python3
```
**Ubuntu/Debian:**
```bash
sudo apt update && sudo apt install python3
```
**Windows:**
```powershell
winget install Python.Python.3.12
```
---
## How to Use This Skill
When user requests UI/UX work (design, build, create, implement, review, fix, improve), follow this workflow:
### Step 1: Analyze User Requirements
Extract key information from user request:
- **Product type**: SaaS, e-commerce, portfolio, dashboard, landing page, etc.
- **Style keywords**: minimal, playful, professional, elegant, dark mode, etc.
- **Industry**: healthcare, fintech, gaming, education, etc.
- **Stack**: React, Vue, Next.js, or default to `html-tailwind`
### Step 2: Generate Design System (REQUIRED)
**Always start with `--design-system`** to get comprehensive recommendations with reasoning:
```bash
python3 skills/ui-ux-pro-max/scripts/search.py "<product_type> <industry> <keywords>" --design-system [-p "Project Name"]
```
This command:
1. Searches 5 domains in parallel (product, style, color, landing, typography)
2. Applies reasoning rules from `ui-reasoning.csv` to select best matches
3. Returns complete design system: pattern, style, colors, typography, effects
4. Includes anti-patterns to avoid
**Example:**
```bash
python3 skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service" --design-system -p "Serenity Spa"
```
### Step 2b: Persist Design System (Master + Overrides Pattern)
To save the design system for **hierarchical retrieval across sessions**, add `--persist`:
```bash
python3 skills/ui-ux-pro-max/scripts/search.py "<query>" --design-system --persist -p "Project Name"
```
This creates:
- `design-system/MASTER.md` — Global Source of Truth with all design rules
- `design-system/pages/` — Folder for page-specific overrides
**With page-specific override:**
```bash
python3 skills/ui-ux-pro-max/scripts/search.py "<query>" --design-system --persist -p "Project Name" --page "dashboard"
```
This also creates:
- `design-system/pages/dashboard.md` — Page-specific deviations from Master
**How hierarchical retrieval works:**
1. When building a specific page (e.g., "Checkout"), first check `design-system/pages/checkout.md`
2. If the page file exists, its rules **override** the Master file
3. If not, use `design-system/MASTER.md` exclusively
**Context-aware retrieval prompt:**
```
I am building the [Page Name] page. Please read design-system/MASTER.md.
Also check if design-system/pages/[page-name].md exists.
If the page file exists, prioritize its rules.
If not, use the Master rules exclusively.
Now, generate the code...
```
### Step 3: Supplement with Detailed Searches (as needed)
After getting the design system, use domain searches to get additional details:
```bash
python3 skills/ui-ux-pro-max/scripts/search.py "<keyword>" --domain <domain> [-n <max_results>]
```
**When to use detailed searches:**
| Need | Domain | Example |
|------|--------|---------|
| More style options | `style` | `--domain style "glassmorphism dark"` |
| Chart recommendations | `chart` | `--domain chart "real-time dashboard"` |
| UX best practices | `ux` | `--domain ux "animation accessibility"` |
| Alternative fonts | `typography` | `--domain typography "elegant luxury"` |
| Landing structure | `landing` | `--domain landing "hero social-proof"` |
### Step 4: Stack Guidelines (Default: html-tailwind)
Get implementation-specific best practices. If user doesn't specify a stack, **default to `html-tailwind`**.
```bash
python3 skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack html-tailwind
```
Available stacks: `html-tailwind`, `react`, `nextjs`, `vue`, `svelte`, `swiftui`, `react-native`, `flutter`, `shadcn`, `jetpack-compose`
---
## Search Reference
### Available Domains
| Domain | Use For | Example Keywords |
|--------|---------|------------------|
| `product` | Product type recommendations | SaaS, e-commerce, portfolio, healthcare, beauty, service |
| `style` | UI styles, colors, effects | glassmorphism, minimalism, dark mode, brutalism |
| `typography` | Font pairings, Google Fonts | elegant, playful, professional, modern |
| `color` | Color palettes by product type | saas, ecommerce, healthcare, beauty, fintech, service |
| `landing` | Page structure, CTA strategies | hero, hero-centric, testimonial, pricing, social-proof |
| `chart` | Chart types, library recommendations | trend, comparison, timeline, funnel, pie |
| `ux` | Best practices, anti-patterns | animation, accessibility, z-index, loading |
| `react` | React/Next.js performance | waterfall, bundle, suspense, memo, rerender, cache |
| `web` | Web interface guidelines | aria, focus, keyboard, semantic, virtualize |
| `prompt` | AI prompts, CSS keywords | (style name) |
### Available Stacks
| Stack | Focus |
|-------|-------|
| `html-tailwind` | Tailwind utilities, responsive, a11y (DEFAULT) |
| `react` | State, hooks, performance, patterns |
| `nextjs` | SSR, routing, images, API routes |
| `vue` | Composition API, Pinia, Vue Router |
| `svelte` | Runes, stores, SvelteKit |
| `swiftui` | Views, State, Navigation, Animation |
| `react-native` | Components, Navigation, Lists |
| `flutter` | Widgets, State, Layout, Theming |
| `shadcn` | shadcn/ui components, theming, forms, patterns |
| `jetpack-compose` | Composables, Modifiers, State Hoisting, Recomposition |
---
## Example Workflow
**User request:** "Làm landing page cho dịch vụ chăm sóc da chuyên nghiệp"
### Step 1: Analyze Requirements
- Product type: Beauty/Spa service
- Style keywords: elegant, professional, soft
- Industry: Beauty/Wellness
- Stack: html-tailwind (default)
### Step 2: Generate Design System (REQUIRED)
```bash
python3 skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service elegant" --design-system -p "Serenity Spa"
```
**Output:** Complete design system with pattern, style, colors, typography, effects, and anti-patterns.
### Step 3: Supplement with Detailed Searches (as needed)
```bash
# Get UX guidelines for animation and accessibility
python3 skills/ui-ux-pro-max/scripts/search.py "animation accessibility" --domain ux
# Get alternative typography options if needed
python3 skills/ui-ux-pro-max/scripts/search.py "elegant luxury serif" --domain typography
```
### Step 4: Stack Guidelines
```bash
python3 skills/ui-ux-pro-max/scripts/search.py "layout responsive form" --stack html-tailwind
```
**Then:** Synthesize design system + detailed searches and implement the design.
---
## Output Formats
The `--design-system` flag supports two output formats:
```bash
# ASCII box (default) - best for terminal display
python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system
# Markdown - best for documentation
python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system -f markdown
```
---
## Tips for Better Results
1. **Be specific with keywords** - "healthcare SaaS dashboard" > "app"
2. **Search multiple times** - Different keywords reveal different insights
3. **Combine domains** - Style + Typography + Color = Complete design system
4. **Always check UX** - Search "animation", "z-index", "accessibility" for common issues
5. **Use stack flag** - Get implementation-specific best practices
6. **Iterate** - If first search doesn't match, try different keywords
---
## Common Rules for Professional UI
These are frequently overlooked issues that make UI look unprofessional:
### Icons & Visual Elements
| Rule | Do | Don't |
|------|----|----- |
| **No emoji icons** | Use SVG icons (Heroicons, Lucide, Simple Icons) | Use emojis like 🎨 🚀 ⚙️ as UI icons |
| **Stable hover states** | Use color/opacity transitions on hover | Use scale transforms that shift layout |
| **Correct brand logos** | Research official SVG from Simple Icons | Guess or use incorrect logo paths |
| **Consistent icon sizing** | Use fixed viewBox (24x24) with w-6 h-6 | Mix different icon sizes randomly |
### Interaction & Cursor
| Rule | Do | Don't |
|------|----|----- |
| **Cursor pointer** | Add `cursor-pointer` to all clickable/hoverable cards | Leave default cursor on interactive elements |
| **Hover feedback** | Provide visual feedback (color, shadow, border) | No indication element is interactive |
| **Smooth transitions** | Use `transition-colors duration-200` | Instant state changes or too slow (>500ms) |
### Light/Dark Mode Contrast
| Rule | Do | Don't |
|------|----|----- |
| **Glass card light mode** | Use `bg-white/80` or higher opacity | Use `bg-white/10` (too transparent) |
| **Text contrast light** | Use `#0F172A` (slate-900) for text | Use `#94A3B8` (slate-400) for body text |
| **Muted text light** | Use `#475569` (slate-600) minimum | Use gray-400 or lighter |
| **Border visibility** | Use `border-gray-200` in light mode | Use `border-white/10` (invisible) |
### Layout & Spacing
| Rule | Do | Don't |
|------|----|----- |
| **Floating navbar** | Add `top-4 left-4 right-4` spacing | Stick navbar to `top-0 left-0 right-0` |
| **Content padding** | Account for fixed navbar height | Let content hide behind fixed elements |
| **Consistent max-width** | Use same `max-w-6xl` or `max-w-7xl` | Mix different container widths |
---
## Pre-Delivery Checklist
Before delivering UI code, verify these items:
### Visual Quality
- [ ] No emojis used as icons (use SVG instead)
- [ ] All icons from consistent icon set (Heroicons/Lucide)
- [ ] Brand logos are correct (verified from Simple Icons)
- [ ] Hover states don't cause layout shift
- [ ] Use theme colors directly (bg-primary) not var() wrapper
### Interaction
- [ ] All clickable elements have `cursor-pointer`
- [ ] Hover states provide clear visual feedback
- [ ] Transitions are smooth (150-300ms)
- [ ] Focus states visible for keyboard navigation
### Light/Dark Mode
- [ ] Light mode text has sufficient contrast (4.5:1 minimum)
- [ ] Glass/transparent elements visible in light mode
- [ ] Borders visible in both modes
- [ ] Test both modes before delivery
### Layout
- [ ] Floating elements have proper spacing from edges
- [ ] No content hidden behind fixed navbars
- [ ] Responsive at 375px, 768px, 1024px, 1440px
- [ ] No horizontal scroll on mobile
### Accessibility
- [ ] All images have alt text
- [ ] Form inputs have labels
- [ ] Color is not the only indicator
- [ ] `prefers-reduced-motion` respected

View File

@@ -0,0 +1 @@
../../../src/ui-ux-pro-max/data

View File

@@ -0,0 +1 @@
../../../src/ui-ux-pro-max/scripts

View File

@@ -0,0 +1,39 @@
---
name: web-design-guidelines
description: Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
metadata:
author: vercel
version: "1.0.0"
argument-hint: <file-or-pattern>
---
# Web Interface Guidelines
Review files for compliance with Web Interface Guidelines.
## How It Works
1. Fetch the latest guidelines from the source URL below
2. Read the specified files (or prompt user for files/pattern)
3. Check against all rules in the fetched guidelines
4. Output findings in the terse `file:line` format
## Guidelines Source
Fetch fresh guidelines before each review:
```
https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md
```
Use WebFetch to retrieve the latest rules. The fetched content contains all the rules and output format instructions.
## Usage
When a user provides a file or pattern argument:
1. Fetch guidelines from the source URL above
2. Read the specified files
3. Apply all rules from the fetched guidelines
4. Output findings using the format specified in the guidelines
If no files specified, ask the user which files to review.

View File

@@ -0,0 +1,30 @@
© 2025 Anthropic, PBC. All rights reserved.
LICENSE: Use of these materials (including all code, prompts, assets, files,
and other components of this Skill) is governed by your agreement with
Anthropic regarding use of Anthropic's services. If no separate agreement
exists, use is governed by Anthropic's Consumer Terms of Service or
Commercial Terms of Service, as applicable:
https://www.anthropic.com/legal/consumer-terms
https://www.anthropic.com/legal/commercial-terms
Your applicable agreement is referred to as the "Agreement." "Services" are
as defined in the Agreement.
ADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the
contrary, users may not:
- Extract these materials from the Services or retain copies of these
materials outside the Services
- Reproduce or copy these materials, except for temporary copies created
automatically during authorized use of the Services
- Create derivative works based on these materials
- Distribute, sublicense, or transfer these materials to any third party
- Make, offer to sell, sell, or import any inventions embodied in these
materials
- Reverse engineer, decompile, or disassemble these materials
The receipt, viewing, or possession of these materials does not convey or
imply any license or right beyond those expressly granted above.
Anthropic retains all right, title, and interest in these materials,
including all copyrights, patents, and other intellectual property rights.

View File

@@ -0,0 +1,292 @@
---
name: xlsx
description: "Use this skill any time a spreadsheet file is the primary input or output. This means any task where the user wants to: open, read, edit, or fix an existing .xlsx, .xlsm, .csv, or .tsv file (e.g., adding columns, computing formulas, formatting, charting, cleaning messy data); create a new spreadsheet from scratch or from other data sources; or convert between tabular file formats. Trigger especially when the user references a spreadsheet file by name or path — even casually (like \"the xlsx in my downloads\") — and wants something done to it or produced from it. Also trigger for cleaning or restructuring messy tabular data files (malformed rows, misplaced headers, junk data) into proper spreadsheets. The deliverable must be a spreadsheet file. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration, even if tabular data is involved."
license: Proprietary. LICENSE.txt has complete terms
---
# Requirements for Outputs
## All Excel files
### Professional Font
- Use a consistent, professional font (e.g., Arial, Times New Roman) for all deliverables unless otherwise instructed by the user
### Zero Formula Errors
- Every Excel model MUST be delivered with ZERO formula errors (#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?)
### Preserve Existing Templates (when updating templates)
- Study and EXACTLY match existing format, style, and conventions when modifying files
- Never impose standardized formatting on files with established patterns
- Existing template conventions ALWAYS override these guidelines
## Financial models
### Color Coding Standards
Unless otherwise stated by the user or existing template
#### Industry-Standard Color Conventions
- **Blue text (RGB: 0,0,255)**: Hardcoded inputs, and numbers users will change for scenarios
- **Black text (RGB: 0,0,0)**: ALL formulas and calculations
- **Green text (RGB: 0,128,0)**: Links pulling from other worksheets within same workbook
- **Red text (RGB: 255,0,0)**: External links to other files
- **Yellow background (RGB: 255,255,0)**: Key assumptions needing attention or cells that need to be updated
### Number Formatting Standards
#### Required Format Rules
- **Years**: Format as text strings (e.g., "2024" not "2,024")
- **Currency**: Use $#,##0 format; ALWAYS specify units in headers ("Revenue ($mm)")
- **Zeros**: Use number formatting to make all zeros "-", including percentages (e.g., "$#,##0;($#,##0);-")
- **Percentages**: Default to 0.0% format (one decimal)
- **Multiples**: Format as 0.0x for valuation multiples (EV/EBITDA, P/E)
- **Negative numbers**: Use parentheses (123) not minus -123
### Formula Construction Rules
#### Assumptions Placement
- Place ALL assumptions (growth rates, margins, multiples, etc.) in separate assumption cells
- Use cell references instead of hardcoded values in formulas
- Example: Use =B5*(1+$B$6) instead of =B5*1.05
#### Formula Error Prevention
- Verify all cell references are correct
- Check for off-by-one errors in ranges
- Ensure consistent formulas across all projection periods
- Test with edge cases (zero values, negative numbers)
- Verify no unintended circular references
#### Documentation Requirements for Hardcodes
- Comment or in cells beside (if end of table). Format: "Source: [System/Document], [Date], [Specific Reference], [URL if applicable]"
- Examples:
- "Source: Company 10-K, FY2024, Page 45, Revenue Note, [SEC EDGAR URL]"
- "Source: Company 10-Q, Q2 2025, Exhibit 99.1, [SEC EDGAR URL]"
- "Source: Bloomberg Terminal, 8/15/2025, AAPL US Equity"
- "Source: FactSet, 8/20/2025, Consensus Estimates Screen"
# XLSX creation, editing, and analysis
## Overview
A user may ask you to create, edit, or analyze the contents of an .xlsx file. You have different tools and workflows available for different tasks.
## Important Requirements
**LibreOffice Required for Formula Recalculation**: You can assume LibreOffice is installed for recalculating formula values using the `scripts/recalc.py` script. The script automatically configures LibreOffice on first run, including in sandboxed environments where Unix sockets are restricted (handled by `scripts/office/soffice.py`)
## Reading and analyzing data
### Data analysis with pandas
For data analysis, visualization, and basic operations, use **pandas** which provides powerful data manipulation capabilities:
```python
import pandas as pd
# Read Excel
df = pd.read_excel('file.xlsx') # Default: first sheet
all_sheets = pd.read_excel('file.xlsx', sheet_name=None) # All sheets as dict
# Analyze
df.head() # Preview data
df.info() # Column info
df.describe() # Statistics
# Write Excel
df.to_excel('output.xlsx', index=False)
```
## Excel File Workflows
## CRITICAL: Use Formulas, Not Hardcoded Values
**Always use Excel formulas instead of calculating values in Python and hardcoding them.** This ensures the spreadsheet remains dynamic and updateable.
### ❌ WRONG - Hardcoding Calculated Values
```python
# Bad: Calculating in Python and hardcoding result
total = df['Sales'].sum()
sheet['B10'] = total # Hardcodes 5000
# Bad: Computing growth rate in Python
growth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue']
sheet['C5'] = growth # Hardcodes 0.15
# Bad: Python calculation for average
avg = sum(values) / len(values)
sheet['D20'] = avg # Hardcodes 42.5
```
### ✅ CORRECT - Using Excel Formulas
```python
# Good: Let Excel calculate the sum
sheet['B10'] = '=SUM(B2:B9)'
# Good: Growth rate as Excel formula
sheet['C5'] = '=(C4-C2)/C2'
# Good: Average using Excel function
sheet['D20'] = '=AVERAGE(D2:D19)'
```
This applies to ALL calculations - totals, percentages, ratios, differences, etc. The spreadsheet should be able to recalculate when source data changes.
## Common Workflow
1. **Choose tool**: pandas for data, openpyxl for formulas/formatting
2. **Create/Load**: Create new workbook or load existing file
3. **Modify**: Add/edit data, formulas, and formatting
4. **Save**: Write to file
5. **Recalculate formulas (MANDATORY IF USING FORMULAS)**: Use the scripts/recalc.py script
```bash
python scripts/recalc.py output.xlsx
```
6. **Verify and fix any errors**:
- The script returns JSON with error details
- If `status` is `errors_found`, check `error_summary` for specific error types and locations
- Fix the identified errors and recalculate again
- Common errors to fix:
- `#REF!`: Invalid cell references
- `#DIV/0!`: Division by zero
- `#VALUE!`: Wrong data type in formula
- `#NAME?`: Unrecognized formula name
### Creating new Excel files
```python
# Using openpyxl for formulas and formatting
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
wb = Workbook()
sheet = wb.active
# Add data
sheet['A1'] = 'Hello'
sheet['B1'] = 'World'
sheet.append(['Row', 'of', 'data'])
# Add formula
sheet['B2'] = '=SUM(A1:A10)'
# Formatting
sheet['A1'].font = Font(bold=True, color='FF0000')
sheet['A1'].fill = PatternFill('solid', start_color='FFFF00')
sheet['A1'].alignment = Alignment(horizontal='center')
# Column width
sheet.column_dimensions['A'].width = 20
wb.save('output.xlsx')
```
### Editing existing Excel files
```python
# Using openpyxl to preserve formulas and formatting
from openpyxl import load_workbook
# Load existing file
wb = load_workbook('existing.xlsx')
sheet = wb.active # or wb['SheetName'] for specific sheet
# Working with multiple sheets
for sheet_name in wb.sheetnames:
sheet = wb[sheet_name]
print(f"Sheet: {sheet_name}")
# Modify cells
sheet['A1'] = 'New Value'
sheet.insert_rows(2) # Insert row at position 2
sheet.delete_cols(3) # Delete column 3
# Add new sheet
new_sheet = wb.create_sheet('NewSheet')
new_sheet['A1'] = 'Data'
wb.save('modified.xlsx')
```
## Recalculating formulas
Excel files created or modified by openpyxl contain formulas as strings but not calculated values. Use the provided `scripts/recalc.py` script to recalculate formulas:
```bash
python scripts/recalc.py <excel_file> [timeout_seconds]
```
Example:
```bash
python scripts/recalc.py output.xlsx 30
```
The script:
- Automatically sets up LibreOffice macro on first run
- Recalculates all formulas in all sheets
- Scans ALL cells for Excel errors (#REF!, #DIV/0!, etc.)
- Returns JSON with detailed error locations and counts
- Works on both Linux and macOS
## Formula Verification Checklist
Quick checks to ensure formulas work correctly:
### Essential Verification
- [ ] **Test 2-3 sample references**: Verify they pull correct values before building full model
- [ ] **Column mapping**: Confirm Excel columns match (e.g., column 64 = BL, not BK)
- [ ] **Row offset**: Remember Excel rows are 1-indexed (DataFrame row 5 = Excel row 6)
### Common Pitfalls
- [ ] **NaN handling**: Check for null values with `pd.notna()`
- [ ] **Far-right columns**: FY data often in columns 50+
- [ ] **Multiple matches**: Search all occurrences, not just first
- [ ] **Division by zero**: Check denominators before using `/` in formulas (#DIV/0!)
- [ ] **Wrong references**: Verify all cell references point to intended cells (#REF!)
- [ ] **Cross-sheet references**: Use correct format (Sheet1!A1) for linking sheets
### Formula Testing Strategy
- [ ] **Start small**: Test formulas on 2-3 cells before applying broadly
- [ ] **Verify dependencies**: Check all cells referenced in formulas exist
- [ ] **Test edge cases**: Include zero, negative, and very large values
### Interpreting scripts/recalc.py Output
The script returns JSON with error details:
```json
{
"status": "success", // or "errors_found"
"total_errors": 0, // Total error count
"total_formulas": 42, // Number of formulas in file
"error_summary": { // Only present if errors found
"#REF!": {
"count": 2,
"locations": ["Sheet1!B5", "Sheet1!C10"]
}
}
}
```
## Best Practices
### Library Selection
- **pandas**: Best for data analysis, bulk operations, and simple data export
- **openpyxl**: Best for complex formatting, formulas, and Excel-specific features
### Working with openpyxl
- Cell indices are 1-based (row=1, column=1 refers to cell A1)
- Use `data_only=True` to read calculated values: `load_workbook('file.xlsx', data_only=True)`
- **Warning**: If opened with `data_only=True` and saved, formulas are replaced with values and permanently lost
- For large files: Use `read_only=True` for reading or `write_only=True` for writing
- Formulas are preserved but not evaluated - use scripts/recalc.py to update values
### Working with pandas
- Specify data types to avoid inference issues: `pd.read_excel('file.xlsx', dtype={'id': str})`
- For large files, read specific columns: `pd.read_excel('file.xlsx', usecols=['A', 'C', 'E'])`
- Handle dates properly: `pd.read_excel('file.xlsx', parse_dates=['date_column'])`
## Code Style Guidelines
**IMPORTANT**: When generating Python code for Excel operations:
- Write minimal, concise Python code without unnecessary comments
- Avoid verbose variable names and redundant operations
- Avoid unnecessary print statements
**For Excel files themselves**:
- Add comments to cells with complex formulas or important assumptions
- Document data sources for hardcoded values
- Include notes for key calculations and model sections

View File

@@ -0,0 +1,199 @@
"""Merge adjacent runs with identical formatting in DOCX.
Merges adjacent <w:r> elements that have identical <w:rPr> properties.
Works on runs in paragraphs and inside tracked changes (<w:ins>, <w:del>).
Also:
- Removes rsid attributes from runs (revision metadata that doesn't affect rendering)
- Removes proofErr elements (spell/grammar markers that block merging)
"""
from pathlib import Path
import defusedxml.minidom
def merge_runs(input_dir: str) -> tuple[int, str]:
doc_xml = Path(input_dir) / "word" / "document.xml"
if not doc_xml.exists():
return 0, f"Error: {doc_xml} not found"
try:
dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding="utf-8"))
root = dom.documentElement
_remove_elements(root, "proofErr")
_strip_run_rsid_attrs(root)
containers = {run.parentNode for run in _find_elements(root, "r")}
merge_count = 0
for container in containers:
merge_count += _merge_runs_in(container)
doc_xml.write_bytes(dom.toxml(encoding="UTF-8"))
return merge_count, f"Merged {merge_count} runs"
except Exception as e:
return 0, f"Error: {e}"
def _find_elements(root, tag: str) -> list:
results = []
def traverse(node):
if node.nodeType == node.ELEMENT_NODE:
name = node.localName or node.tagName
if name == tag or name.endswith(f":{tag}"):
results.append(node)
for child in node.childNodes:
traverse(child)
traverse(root)
return results
def _get_child(parent, tag: str):
for child in parent.childNodes:
if child.nodeType == child.ELEMENT_NODE:
name = child.localName or child.tagName
if name == tag or name.endswith(f":{tag}"):
return child
return None
def _get_children(parent, tag: str) -> list:
results = []
for child in parent.childNodes:
if child.nodeType == child.ELEMENT_NODE:
name = child.localName or child.tagName
if name == tag or name.endswith(f":{tag}"):
results.append(child)
return results
def _is_adjacent(elem1, elem2) -> bool:
node = elem1.nextSibling
while node:
if node == elem2:
return True
if node.nodeType == node.ELEMENT_NODE:
return False
if node.nodeType == node.TEXT_NODE and node.data.strip():
return False
node = node.nextSibling
return False
def _remove_elements(root, tag: str):
for elem in _find_elements(root, tag):
if elem.parentNode:
elem.parentNode.removeChild(elem)
def _strip_run_rsid_attrs(root):
for run in _find_elements(root, "r"):
for attr in list(run.attributes.values()):
if "rsid" in attr.name.lower():
run.removeAttribute(attr.name)
def _merge_runs_in(container) -> int:
merge_count = 0
run = _first_child_run(container)
while run:
while True:
next_elem = _next_element_sibling(run)
if next_elem and _is_run(next_elem) and _can_merge(run, next_elem):
_merge_run_content(run, next_elem)
container.removeChild(next_elem)
merge_count += 1
else:
break
_consolidate_text(run)
run = _next_sibling_run(run)
return merge_count
def _first_child_run(container):
for child in container.childNodes:
if child.nodeType == child.ELEMENT_NODE and _is_run(child):
return child
return None
def _next_element_sibling(node):
sibling = node.nextSibling
while sibling:
if sibling.nodeType == sibling.ELEMENT_NODE:
return sibling
sibling = sibling.nextSibling
return None
def _next_sibling_run(node):
sibling = node.nextSibling
while sibling:
if sibling.nodeType == sibling.ELEMENT_NODE:
if _is_run(sibling):
return sibling
sibling = sibling.nextSibling
return None
def _is_run(node) -> bool:
name = node.localName or node.tagName
return name == "r" or name.endswith(":r")
def _can_merge(run1, run2) -> bool:
rpr1 = _get_child(run1, "rPr")
rpr2 = _get_child(run2, "rPr")
if (rpr1 is None) != (rpr2 is None):
return False
if rpr1 is None:
return True
return rpr1.toxml() == rpr2.toxml()
def _merge_run_content(target, source):
for child in list(source.childNodes):
if child.nodeType == child.ELEMENT_NODE:
name = child.localName or child.tagName
if name != "rPr" and not name.endswith(":rPr"):
target.appendChild(child)
def _consolidate_text(run):
t_elements = _get_children(run, "t")
for i in range(len(t_elements) - 1, 0, -1):
curr, prev = t_elements[i], t_elements[i - 1]
if _is_adjacent(prev, curr):
prev_text = prev.firstChild.data if prev.firstChild else ""
curr_text = curr.firstChild.data if curr.firstChild else ""
merged = prev_text + curr_text
if prev.firstChild:
prev.firstChild.data = merged
else:
prev.appendChild(run.ownerDocument.createTextNode(merged))
if merged.startswith(" ") or merged.endswith(" "):
prev.setAttribute("xml:space", "preserve")
elif prev.hasAttribute("xml:space"):
prev.removeAttribute("xml:space")
run.removeChild(curr)

View File

@@ -0,0 +1,197 @@
"""Simplify tracked changes by merging adjacent w:ins or w:del elements.
Merges adjacent <w:ins> elements from the same author into a single element.
Same for <w:del> elements. This makes heavily-redlined documents easier to
work with by reducing the number of tracked change wrappers.
Rules:
- Only merges w:ins with w:ins, w:del with w:del (same element type)
- Only merges if same author (ignores timestamp differences)
- Only merges if truly adjacent (only whitespace between them)
"""
import xml.etree.ElementTree as ET
import zipfile
from pathlib import Path
import defusedxml.minidom
WORD_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
def simplify_redlines(input_dir: str) -> tuple[int, str]:
doc_xml = Path(input_dir) / "word" / "document.xml"
if not doc_xml.exists():
return 0, f"Error: {doc_xml} not found"
try:
dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding="utf-8"))
root = dom.documentElement
merge_count = 0
containers = _find_elements(root, "p") + _find_elements(root, "tc")
for container in containers:
merge_count += _merge_tracked_changes_in(container, "ins")
merge_count += _merge_tracked_changes_in(container, "del")
doc_xml.write_bytes(dom.toxml(encoding="UTF-8"))
return merge_count, f"Simplified {merge_count} tracked changes"
except Exception as e:
return 0, f"Error: {e}"
def _merge_tracked_changes_in(container, tag: str) -> int:
merge_count = 0
tracked = [
child
for child in container.childNodes
if child.nodeType == child.ELEMENT_NODE and _is_element(child, tag)
]
if len(tracked) < 2:
return 0
i = 0
while i < len(tracked) - 1:
curr = tracked[i]
next_elem = tracked[i + 1]
if _can_merge_tracked(curr, next_elem):
_merge_tracked_content(curr, next_elem)
container.removeChild(next_elem)
tracked.pop(i + 1)
merge_count += 1
else:
i += 1
return merge_count
def _is_element(node, tag: str) -> bool:
name = node.localName or node.tagName
return name == tag or name.endswith(f":{tag}")
def _get_author(elem) -> str:
author = elem.getAttribute("w:author")
if not author:
for attr in elem.attributes.values():
if attr.localName == "author" or attr.name.endswith(":author"):
return attr.value
return author
def _can_merge_tracked(elem1, elem2) -> bool:
if _get_author(elem1) != _get_author(elem2):
return False
node = elem1.nextSibling
while node and node != elem2:
if node.nodeType == node.ELEMENT_NODE:
return False
if node.nodeType == node.TEXT_NODE and node.data.strip():
return False
node = node.nextSibling
return True
def _merge_tracked_content(target, source):
while source.firstChild:
child = source.firstChild
source.removeChild(child)
target.appendChild(child)
def _find_elements(root, tag: str) -> list:
results = []
def traverse(node):
if node.nodeType == node.ELEMENT_NODE:
name = node.localName or node.tagName
if name == tag or name.endswith(f":{tag}"):
results.append(node)
for child in node.childNodes:
traverse(child)
traverse(root)
return results
def get_tracked_change_authors(doc_xml_path: Path) -> dict[str, int]:
if not doc_xml_path.exists():
return {}
try:
tree = ET.parse(doc_xml_path)
root = tree.getroot()
except ET.ParseError:
return {}
namespaces = {"w": WORD_NS}
author_attr = f"{{{WORD_NS}}}author"
authors: dict[str, int] = {}
for tag in ["ins", "del"]:
for elem in root.findall(f".//w:{tag}", namespaces):
author = elem.get(author_attr)
if author:
authors[author] = authors.get(author, 0) + 1
return authors
def _get_authors_from_docx(docx_path: Path) -> dict[str, int]:
try:
with zipfile.ZipFile(docx_path, "r") as zf:
if "word/document.xml" not in zf.namelist():
return {}
with zf.open("word/document.xml") as f:
tree = ET.parse(f)
root = tree.getroot()
namespaces = {"w": WORD_NS}
author_attr = f"{{{WORD_NS}}}author"
authors: dict[str, int] = {}
for tag in ["ins", "del"]:
for elem in root.findall(f".//w:{tag}", namespaces):
author = elem.get(author_attr)
if author:
authors[author] = authors.get(author, 0) + 1
return authors
except (zipfile.BadZipFile, ET.ParseError):
return {}
def infer_author(modified_dir: Path, original_docx: Path, default: str = "Claude") -> str:
modified_xml = modified_dir / "word" / "document.xml"
modified_authors = get_tracked_change_authors(modified_xml)
if not modified_authors:
return default
original_authors = _get_authors_from_docx(original_docx)
new_changes: dict[str, int] = {}
for author, count in modified_authors.items():
original_count = original_authors.get(author, 0)
diff = count - original_count
if diff > 0:
new_changes[author] = diff
if not new_changes:
return default
if len(new_changes) == 1:
return next(iter(new_changes))
raise ValueError(
f"Multiple authors added new changes: {new_changes}. "
"Cannot infer which author to validate."
)

View File

@@ -0,0 +1,159 @@
"""Pack a directory into a DOCX, PPTX, or XLSX file.
Validates with auto-repair, condenses XML formatting, and creates the Office file.
Usage:
python pack.py <input_directory> <output_file> [--original <file>] [--validate true|false]
Examples:
python pack.py unpacked/ output.docx --original input.docx
python pack.py unpacked/ output.pptx --validate false
"""
import argparse
import sys
import shutil
import tempfile
import zipfile
from pathlib import Path
import defusedxml.minidom
from validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator
def pack(
input_directory: str,
output_file: str,
original_file: str | None = None,
validate: bool = True,
infer_author_func=None,
) -> tuple[None, str]:
input_dir = Path(input_directory)
output_path = Path(output_file)
suffix = output_path.suffix.lower()
if not input_dir.is_dir():
return None, f"Error: {input_dir} is not a directory"
if suffix not in {".docx", ".pptx", ".xlsx"}:
return None, f"Error: {output_file} must be a .docx, .pptx, or .xlsx file"
if validate and original_file:
original_path = Path(original_file)
if original_path.exists():
success, output = _run_validation(
input_dir, original_path, suffix, infer_author_func
)
if output:
print(output)
if not success:
return None, f"Error: Validation failed for {input_dir}"
with tempfile.TemporaryDirectory() as temp_dir:
temp_content_dir = Path(temp_dir) / "content"
shutil.copytree(input_dir, temp_content_dir)
for pattern in ["*.xml", "*.rels"]:
for xml_file in temp_content_dir.rglob(pattern):
_condense_xml(xml_file)
output_path.parent.mkdir(parents=True, exist_ok=True)
with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as zf:
for f in temp_content_dir.rglob("*"):
if f.is_file():
zf.write(f, f.relative_to(temp_content_dir))
return None, f"Successfully packed {input_dir} to {output_file}"
def _run_validation(
unpacked_dir: Path,
original_file: Path,
suffix: str,
infer_author_func=None,
) -> tuple[bool, str | None]:
output_lines = []
validators = []
if suffix == ".docx":
author = "Claude"
if infer_author_func:
try:
author = infer_author_func(unpacked_dir, original_file)
except ValueError as e:
print(f"Warning: {e} Using default author 'Claude'.", file=sys.stderr)
validators = [
DOCXSchemaValidator(unpacked_dir, original_file),
RedliningValidator(unpacked_dir, original_file, author=author),
]
elif suffix == ".pptx":
validators = [PPTXSchemaValidator(unpacked_dir, original_file)]
if not validators:
return True, None
total_repairs = sum(v.repair() for v in validators)
if total_repairs:
output_lines.append(f"Auto-repaired {total_repairs} issue(s)")
success = all(v.validate() for v in validators)
if success:
output_lines.append("All validations PASSED!")
return success, "\n".join(output_lines) if output_lines else None
def _condense_xml(xml_file: Path) -> None:
try:
with open(xml_file, encoding="utf-8") as f:
dom = defusedxml.minidom.parse(f)
for element in dom.getElementsByTagName("*"):
if element.tagName.endswith(":t"):
continue
for child in list(element.childNodes):
if (
child.nodeType == child.TEXT_NODE
and child.nodeValue
and child.nodeValue.strip() == ""
) or child.nodeType == child.COMMENT_NODE:
element.removeChild(child)
xml_file.write_bytes(dom.toxml(encoding="UTF-8"))
except Exception as e:
print(f"ERROR: Failed to parse {xml_file.name}: {e}", file=sys.stderr)
raise
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Pack a directory into a DOCX, PPTX, or XLSX file"
)
parser.add_argument("input_directory", help="Unpacked Office document directory")
parser.add_argument("output_file", help="Output Office file (.docx/.pptx/.xlsx)")
parser.add_argument(
"--original",
help="Original file for validation comparison",
)
parser.add_argument(
"--validate",
type=lambda x: x.lower() == "true",
default=True,
metavar="true|false",
help="Run validation with auto-repair (default: true)",
)
args = parser.parse_args()
_, message = pack(
args.input_directory,
args.output_file,
original_file=args.original,
validate=args.validate,
)
print(message)
if "Error" in message:
sys.exit(1)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"
elementFormDefault="qualified">
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
schemaLocation="dml-main.xsd"/>
<xsd:complexType name="CT_ShapeNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1" maxOccurs="1"
/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Shape">
<xsd:sequence>
<xsd:element name="nvSpPr" type="CT_ShapeNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
<xsd:element name="txBody" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
<xsd:attribute name="textlink" type="xsd:string" use="optional"/>
<xsd:attribute name="fLocksText" type="xsd:boolean" use="optional" default="true"/>
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_ConnectorNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvCxnSpPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Connector">
<xsd:sequence>
<xsd:element name="nvCxnSpPr" type="CT_ConnectorNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_PictureNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Picture">
<xsd:sequence>
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="macro" type="xsd:string" use="optional" default=""/>
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_GraphicFrameNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_GraphicFrame">
<xsd:sequence>
<xsd:element name="nvGraphicFramePr" type="CT_GraphicFrameNonVisual" minOccurs="1"
maxOccurs="1"/>
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_GroupShapeNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_GroupShape">
<xsd:sequence>
<xsd:element name="nvGrpSpPr" type="CT_GroupShapeNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="sp" type="CT_Shape"/>
<xsd:element name="grpSp" type="CT_GroupShape"/>
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
<xsd:element name="cxnSp" type="CT_Connector"/>
<xsd:element name="pic" type="CT_Picture"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
<xsd:group name="EG_ObjectChoices">
<xsd:sequence>
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element name="sp" type="CT_Shape"/>
<xsd:element name="grpSp" type="CT_GroupShape"/>
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
<xsd:element name="cxnSp" type="CT_Connector"/>
<xsd:element name="pic" type="CT_Picture"/>
</xsd:choice>
</xsd:sequence>
</xsd:group>
<xsd:simpleType name="ST_MarkerCoordinate">
<xsd:restriction base="xsd:double">
<xsd:minInclusive value="0.0"/>
<xsd:maxInclusive value="1.0"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Marker">
<xsd:sequence>
<xsd:element name="x" type="ST_MarkerCoordinate" minOccurs="1" maxOccurs="1"/>
<xsd:element name="y" type="ST_MarkerCoordinate" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_RelSizeAnchor">
<xsd:sequence>
<xsd:element name="from" type="CT_Marker"/>
<xsd:element name="to" type="CT_Marker"/>
<xsd:group ref="EG_ObjectChoices"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_AbsSizeAnchor">
<xsd:sequence>
<xsd:element name="from" type="CT_Marker"/>
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
<xsd:group ref="EG_ObjectChoices"/>
</xsd:sequence>
</xsd:complexType>
<xsd:group name="EG_Anchor">
<xsd:choice>
<xsd:element name="relSizeAnchor" type="CT_RelSizeAnchor"/>
<xsd:element name="absSizeAnchor" type="CT_AbsSizeAnchor"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_Drawing">
<xsd:sequence>
<xsd:group ref="EG_Anchor" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
elementFormDefault="qualified"
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas">
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
schemaLocation="dml-main.xsd"/>
<xsd:element name="lockedCanvas" type="a:CT_GvmlGroupShape"/>
</xsd:schema>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/drawingml/2006/picture"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" elementFormDefault="qualified"
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/picture">
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
schemaLocation="dml-main.xsd"/>
<xsd:complexType name="CT_PictureNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Picture">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="pic" type="CT_Picture"/>
</xsd:schema>

View File

@@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
elementFormDefault="qualified">
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
schemaLocation="dml-main.xsd"/>
<xsd:import schemaLocation="shared-relationshipReference.xsd"
namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"/>
<xsd:element name="from" type="CT_Marker"/>
<xsd:element name="to" type="CT_Marker"/>
<xsd:complexType name="CT_AnchorClientData">
<xsd:attribute name="fLocksWithSheet" type="xsd:boolean" use="optional" default="true"/>
<xsd:attribute name="fPrintsWithSheet" type="xsd:boolean" use="optional" default="true"/>
</xsd:complexType>
<xsd:complexType name="CT_ShapeNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1" maxOccurs="1"
/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Shape">
<xsd:sequence>
<xsd:element name="nvSpPr" type="CT_ShapeNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
<xsd:element name="txBody" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
<xsd:attribute name="textlink" type="xsd:string" use="optional"/>
<xsd:attribute name="fLocksText" type="xsd:boolean" use="optional" default="true"/>
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_ConnectorNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvCxnSpPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Connector">
<xsd:sequence>
<xsd:element name="nvCxnSpPr" type="CT_ConnectorNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_PictureNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Picture">
<xsd:sequence>
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="macro" type="xsd:string" use="optional" default=""/>
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_GraphicalObjectFrameNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_GraphicalObjectFrame">
<xsd:sequence>
<xsd:element name="nvGraphicFramePr" type="CT_GraphicalObjectFrameNonVisual" minOccurs="1"
maxOccurs="1"/>
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_GroupShapeNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_GroupShape">
<xsd:sequence>
<xsd:element name="nvGrpSpPr" type="CT_GroupShapeNonVisual" minOccurs="1" maxOccurs="1"/>
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="sp" type="CT_Shape"/>
<xsd:element name="grpSp" type="CT_GroupShape"/>
<xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
<xsd:element name="cxnSp" type="CT_Connector"/>
<xsd:element name="pic" type="CT_Picture"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
<xsd:group name="EG_ObjectChoices">
<xsd:sequence>
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element name="sp" type="CT_Shape"/>
<xsd:element name="grpSp" type="CT_GroupShape"/>
<xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
<xsd:element name="cxnSp" type="CT_Connector"/>
<xsd:element name="pic" type="CT_Picture"/>
<xsd:element name="contentPart" type="CT_Rel"/>
</xsd:choice>
</xsd:sequence>
</xsd:group>
<xsd:complexType name="CT_Rel">
<xsd:attribute ref="r:id" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_ColID">
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="0"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_RowID">
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="0"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Marker">
<xsd:sequence>
<xsd:element name="col" type="ST_ColID"/>
<xsd:element name="colOff" type="a:ST_Coordinate"/>
<xsd:element name="row" type="ST_RowID"/>
<xsd:element name="rowOff" type="a:ST_Coordinate"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="ST_EditAs">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="twoCell"/>
<xsd:enumeration value="oneCell"/>
<xsd:enumeration value="absolute"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_TwoCellAnchor">
<xsd:sequence>
<xsd:element name="from" type="CT_Marker"/>
<xsd:element name="to" type="CT_Marker"/>
<xsd:group ref="EG_ObjectChoices"/>
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="editAs" type="ST_EditAs" use="optional" default="twoCell"/>
</xsd:complexType>
<xsd:complexType name="CT_OneCellAnchor">
<xsd:sequence>
<xsd:element name="from" type="CT_Marker"/>
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
<xsd:group ref="EG_ObjectChoices"/>
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_AbsoluteAnchor">
<xsd:sequence>
<xsd:element name="pos" type="a:CT_Point2D"/>
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
<xsd:group ref="EG_ObjectChoices"/>
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:group name="EG_Anchor">
<xsd:choice>
<xsd:element name="twoCellAnchor" type="CT_TwoCellAnchor"/>
<xsd:element name="oneCellAnchor" type="CT_OneCellAnchor"/>
<xsd:element name="absoluteAnchor" type="CT_AbsoluteAnchor"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_Drawing">
<xsd:sequence>
<xsd:group ref="EG_Anchor" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="wsDr" type="CT_Drawing"/>
</xsd:schema>

View File

@@ -0,0 +1,287 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:dpct="http://schemas.openxmlformats.org/drawingml/2006/picture"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
elementFormDefault="qualified">
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
schemaLocation="dml-main.xsd"/>
<xsd:import schemaLocation="wml.xsd"
namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"/>
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/picture"
schemaLocation="dml-picture.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
schemaLocation="shared-relationshipReference.xsd"/>
<xsd:complexType name="CT_EffectExtent">
<xsd:attribute name="l" type="a:ST_Coordinate" use="required"/>
<xsd:attribute name="t" type="a:ST_Coordinate" use="required"/>
<xsd:attribute name="r" type="a:ST_Coordinate" use="required"/>
<xsd:attribute name="b" type="a:ST_Coordinate" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_WrapDistance">
<xsd:restriction base="xsd:unsignedInt"/>
</xsd:simpleType>
<xsd:complexType name="CT_Inline">
<xsd:sequence>
<xsd:element name="extent" type="a:CT_PositiveSize2D"/>
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
<xsd:element name="docPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
minOccurs="0" maxOccurs="1"/>
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
</xsd:complexType>
<xsd:simpleType name="ST_WrapText">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="bothSides"/>
<xsd:enumeration value="left"/>
<xsd:enumeration value="right"/>
<xsd:enumeration value="largest"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_WrapPath">
<xsd:sequence>
<xsd:element name="start" type="a:CT_Point2D" minOccurs="1" maxOccurs="1"/>
<xsd:element name="lineTo" type="a:CT_Point2D" minOccurs="2" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="edited" type="xsd:boolean" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_WrapNone"/>
<xsd:complexType name="CT_WrapSquare">
<xsd:sequence>
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_WrapTight">
<xsd:sequence>
<xsd:element name="wrapPolygon" type="CT_WrapPath" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_WrapThrough">
<xsd:sequence>
<xsd:element name="wrapPolygon" type="CT_WrapPath" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_WrapTopBottom">
<xsd:sequence>
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
</xsd:complexType>
<xsd:group name="EG_WrapType">
<xsd:sequence>
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element name="wrapNone" type="CT_WrapNone" minOccurs="1" maxOccurs="1"/>
<xsd:element name="wrapSquare" type="CT_WrapSquare" minOccurs="1" maxOccurs="1"/>
<xsd:element name="wrapTight" type="CT_WrapTight" minOccurs="1" maxOccurs="1"/>
<xsd:element name="wrapThrough" type="CT_WrapThrough" minOccurs="1" maxOccurs="1"/>
<xsd:element name="wrapTopAndBottom" type="CT_WrapTopBottom" minOccurs="1" maxOccurs="1"/>
</xsd:choice>
</xsd:sequence>
</xsd:group>
<xsd:simpleType name="ST_PositionOffset">
<xsd:restriction base="xsd:int"/>
</xsd:simpleType>
<xsd:simpleType name="ST_AlignH">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="left"/>
<xsd:enumeration value="right"/>
<xsd:enumeration value="center"/>
<xsd:enumeration value="inside"/>
<xsd:enumeration value="outside"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_RelFromH">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="margin"/>
<xsd:enumeration value="page"/>
<xsd:enumeration value="column"/>
<xsd:enumeration value="character"/>
<xsd:enumeration value="leftMargin"/>
<xsd:enumeration value="rightMargin"/>
<xsd:enumeration value="insideMargin"/>
<xsd:enumeration value="outsideMargin"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_PosH">
<xsd:sequence>
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element name="align" type="ST_AlignH" minOccurs="1" maxOccurs="1"/>
<xsd:element name="posOffset" type="ST_PositionOffset" minOccurs="1" maxOccurs="1"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="relativeFrom" type="ST_RelFromH" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_AlignV">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="top"/>
<xsd:enumeration value="bottom"/>
<xsd:enumeration value="center"/>
<xsd:enumeration value="inside"/>
<xsd:enumeration value="outside"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_RelFromV">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="margin"/>
<xsd:enumeration value="page"/>
<xsd:enumeration value="paragraph"/>
<xsd:enumeration value="line"/>
<xsd:enumeration value="topMargin"/>
<xsd:enumeration value="bottomMargin"/>
<xsd:enumeration value="insideMargin"/>
<xsd:enumeration value="outsideMargin"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_PosV">
<xsd:sequence>
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element name="align" type="ST_AlignV" minOccurs="1" maxOccurs="1"/>
<xsd:element name="posOffset" type="ST_PositionOffset" minOccurs="1" maxOccurs="1"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="relativeFrom" type="ST_RelFromV" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_Anchor">
<xsd:sequence>
<xsd:element name="simplePos" type="a:CT_Point2D"/>
<xsd:element name="positionH" type="CT_PosH"/>
<xsd:element name="positionV" type="CT_PosV"/>
<xsd:element name="extent" type="a:CT_PositiveSize2D"/>
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
<xsd:group ref="EG_WrapType"/>
<xsd:element name="docPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
minOccurs="0" maxOccurs="1"/>
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
<xsd:attribute name="simplePos" type="xsd:boolean"/>
<xsd:attribute name="relativeHeight" type="xsd:unsignedInt" use="required"/>
<xsd:attribute name="behindDoc" type="xsd:boolean" use="required"/>
<xsd:attribute name="locked" type="xsd:boolean" use="required"/>
<xsd:attribute name="layoutInCell" type="xsd:boolean" use="required"/>
<xsd:attribute name="hidden" type="xsd:boolean" use="optional"/>
<xsd:attribute name="allowOverlap" type="xsd:boolean" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_TxbxContent">
<xsd:group ref="w:EG_BlockLevelElts" minOccurs="1" maxOccurs="unbounded"/>
</xsd:complexType>
<xsd:complexType name="CT_TextboxInfo">
<xsd:sequence>
<xsd:element name="txbxContent" type="CT_TxbxContent" minOccurs="1" maxOccurs="1"/>
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:unsignedShort" use="optional" default="0"/>
</xsd:complexType>
<xsd:complexType name="CT_LinkedTextboxInformation">
<xsd:sequence>
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:unsignedShort" use="required"/>
<xsd:attribute name="seq" type="xsd:unsignedShort" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_WordprocessingShape">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1"
maxOccurs="1"/>
<xsd:element name="cNvCnPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
maxOccurs="1"/>
</xsd:choice>
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="1">
<xsd:element name="txbx" type="CT_TextboxInfo" minOccurs="1" maxOccurs="1"/>
<xsd:element name="linkedTxbx" type="CT_LinkedTextboxInformation" minOccurs="1"
maxOccurs="1"/>
</xsd:choice>
<xsd:element name="bodyPr" type="a:CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="normalEastAsianFlow" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
<xsd:complexType name="CT_GraphicFrame">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
<xsd:element name="cNvFrPr" type="a:CT_NonVisualGraphicFrameProperties" minOccurs="1"
maxOccurs="1"/>
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_WordprocessingContentPartNonVisual">
<xsd:sequence>
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
<xsd:element name="cNvContentPartPr" type="a:CT_NonVisualContentPartProperties" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_WordprocessingContentPart">
<xsd:sequence>
<xsd:element name="nvContentPartPr" type="CT_WordprocessingContentPartNonVisual" minOccurs="0" maxOccurs="1"/>
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="0" maxOccurs="1"/>
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="bwMode" type="a:ST_BlackWhiteMode" use="optional"/>
<xsd:attribute ref="r:id" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_WordprocessingGroup">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
maxOccurs="1"/>
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="wsp"/>
<xsd:element name="grpSp" type="CT_WordprocessingGroup"/>
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
<xsd:element ref="dpct:pic"/>
<xsd:element name="contentPart" type="CT_WordprocessingContentPart"/>
</xsd:choice>
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_WordprocessingCanvas">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="bg" type="a:CT_BackgroundFormatting" minOccurs="0" maxOccurs="1"/>
<xsd:element name="whole" type="a:CT_WholeE2oFormatting" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="wsp"/>
<xsd:element ref="dpct:pic"/>
<xsd:element name="contentPart" type="CT_WordprocessingContentPart"/>
<xsd:element ref="wgp"/>
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
</xsd:choice>
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="wpc" type="CT_WordprocessingCanvas"/>
<xsd:element name="wgp" type="CT_WordprocessingGroup"/>
<xsd:element name="wsp" type="CT_WordprocessingShape"/>
<xsd:element name="inline" type="CT_Inline"/>
<xsd:element name="anchor" type="CT_Anchor"/>
</xsd:schema>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/characteristics"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/characteristics"
elementFormDefault="qualified">
<xsd:complexType name="CT_AdditionalCharacteristics">
<xsd:sequence>
<xsd:element name="characteristic" type="CT_Characteristic" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Characteristic">
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="relation" type="ST_Relation" use="required"/>
<xsd:attribute name="val" type="xsd:string" use="required"/>
<xsd:attribute name="vocabulary" type="xsd:anyURI" use="optional"/>
</xsd:complexType>
<xsd:simpleType name="ST_Relation">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ge"/>
<xsd:enumeration value="le"/>
<xsd:enumeration value="gt"/>
<xsd:enumeration value="lt"/>
<xsd:enumeration value="eq"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="additionalCharacteristics" type="CT_AdditionalCharacteristics"/>
</xsd:schema>

View File

@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
elementFormDefault="qualified">
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
schemaLocation="shared-commonSimpleTypes.xsd"/>
<xsd:simpleType name="ST_SourceType">
<xsd:restriction base="s:ST_String">
<xsd:enumeration value="ArticleInAPeriodical"/>
<xsd:enumeration value="Book"/>
<xsd:enumeration value="BookSection"/>
<xsd:enumeration value="JournalArticle"/>
<xsd:enumeration value="ConferenceProceedings"/>
<xsd:enumeration value="Report"/>
<xsd:enumeration value="SoundRecording"/>
<xsd:enumeration value="Performance"/>
<xsd:enumeration value="Art"/>
<xsd:enumeration value="DocumentFromInternetSite"/>
<xsd:enumeration value="InternetSite"/>
<xsd:enumeration value="Film"/>
<xsd:enumeration value="Interview"/>
<xsd:enumeration value="Patent"/>
<xsd:enumeration value="ElectronicSource"/>
<xsd:enumeration value="Case"/>
<xsd:enumeration value="Misc"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_NameListType">
<xsd:sequence>
<xsd:element name="Person" type="CT_PersonType" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_PersonType">
<xsd:sequence>
<xsd:element name="Last" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="First" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="Middle" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_NameType">
<xsd:sequence>
<xsd:element name="NameList" type="CT_NameListType" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_NameOrCorporateType">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="1">
<xsd:element name="NameList" type="CT_NameListType" minOccurs="1" maxOccurs="1"/>
<xsd:element name="Corporate" minOccurs="1" maxOccurs="1" type="s:ST_String"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_AuthorType">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Artist" type="CT_NameType"/>
<xsd:element name="Author" type="CT_NameOrCorporateType"/>
<xsd:element name="BookAuthor" type="CT_NameType"/>
<xsd:element name="Compiler" type="CT_NameType"/>
<xsd:element name="Composer" type="CT_NameType"/>
<xsd:element name="Conductor" type="CT_NameType"/>
<xsd:element name="Counsel" type="CT_NameType"/>
<xsd:element name="Director" type="CT_NameType"/>
<xsd:element name="Editor" type="CT_NameType"/>
<xsd:element name="Interviewee" type="CT_NameType"/>
<xsd:element name="Interviewer" type="CT_NameType"/>
<xsd:element name="Inventor" type="CT_NameType"/>
<xsd:element name="Performer" type="CT_NameOrCorporateType"/>
<xsd:element name="ProducerName" type="CT_NameType"/>
<xsd:element name="Translator" type="CT_NameType"/>
<xsd:element name="Writer" type="CT_NameType"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SourceType">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="AbbreviatedCaseNumber" type="s:ST_String"/>
<xsd:element name="AlbumTitle" type="s:ST_String"/>
<xsd:element name="Author" type="CT_AuthorType"/>
<xsd:element name="BookTitle" type="s:ST_String"/>
<xsd:element name="Broadcaster" type="s:ST_String"/>
<xsd:element name="BroadcastTitle" type="s:ST_String"/>
<xsd:element name="CaseNumber" type="s:ST_String"/>
<xsd:element name="ChapterNumber" type="s:ST_String"/>
<xsd:element name="City" type="s:ST_String"/>
<xsd:element name="Comments" type="s:ST_String"/>
<xsd:element name="ConferenceName" type="s:ST_String"/>
<xsd:element name="CountryRegion" type="s:ST_String"/>
<xsd:element name="Court" type="s:ST_String"/>
<xsd:element name="Day" type="s:ST_String"/>
<xsd:element name="DayAccessed" type="s:ST_String"/>
<xsd:element name="Department" type="s:ST_String"/>
<xsd:element name="Distributor" type="s:ST_String"/>
<xsd:element name="Edition" type="s:ST_String"/>
<xsd:element name="Guid" type="s:ST_String"/>
<xsd:element name="Institution" type="s:ST_String"/>
<xsd:element name="InternetSiteTitle" type="s:ST_String"/>
<xsd:element name="Issue" type="s:ST_String"/>
<xsd:element name="JournalName" type="s:ST_String"/>
<xsd:element name="LCID" type="s:ST_Lang"/>
<xsd:element name="Medium" type="s:ST_String"/>
<xsd:element name="Month" type="s:ST_String"/>
<xsd:element name="MonthAccessed" type="s:ST_String"/>
<xsd:element name="NumberVolumes" type="s:ST_String"/>
<xsd:element name="Pages" type="s:ST_String"/>
<xsd:element name="PatentNumber" type="s:ST_String"/>
<xsd:element name="PeriodicalTitle" type="s:ST_String"/>
<xsd:element name="ProductionCompany" type="s:ST_String"/>
<xsd:element name="PublicationTitle" type="s:ST_String"/>
<xsd:element name="Publisher" type="s:ST_String"/>
<xsd:element name="RecordingNumber" type="s:ST_String"/>
<xsd:element name="RefOrder" type="s:ST_String"/>
<xsd:element name="Reporter" type="s:ST_String"/>
<xsd:element name="SourceType" type="ST_SourceType"/>
<xsd:element name="ShortTitle" type="s:ST_String"/>
<xsd:element name="StandardNumber" type="s:ST_String"/>
<xsd:element name="StateProvince" type="s:ST_String"/>
<xsd:element name="Station" type="s:ST_String"/>
<xsd:element name="Tag" type="s:ST_String"/>
<xsd:element name="Theater" type="s:ST_String"/>
<xsd:element name="ThesisType" type="s:ST_String"/>
<xsd:element name="Title" type="s:ST_String"/>
<xsd:element name="Type" type="s:ST_String"/>
<xsd:element name="URL" type="s:ST_String"/>
<xsd:element name="Version" type="s:ST_String"/>
<xsd:element name="Volume" type="s:ST_String"/>
<xsd:element name="Year" type="s:ST_String"/>
<xsd:element name="YearAccessed" type="s:ST_String"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Sources" type="CT_Sources"/>
<xsd:complexType name="CT_Sources">
<xsd:sequence>
<xsd:element name="Source" type="CT_SourceType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="SelectedStyle" type="s:ST_String"/>
<xsd:attribute name="StyleName" type="s:ST_String"/>
<xsd:attribute name="URI" type="s:ST_String"/>
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
elementFormDefault="qualified">
<xsd:simpleType name="ST_Lang">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="ST_HexColorRGB">
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="3" fixed="true"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_Panose">
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="10"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_CalendarType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="gregorian"/>
<xsd:enumeration value="gregorianUs"/>
<xsd:enumeration value="gregorianMeFrench"/>
<xsd:enumeration value="gregorianArabic"/>
<xsd:enumeration value="hijri"/>
<xsd:enumeration value="hebrew"/>
<xsd:enumeration value="taiwan"/>
<xsd:enumeration value="japan"/>
<xsd:enumeration value="thai"/>
<xsd:enumeration value="korea"/>
<xsd:enumeration value="saka"/>
<xsd:enumeration value="gregorianXlitEnglish"/>
<xsd:enumeration value="gregorianXlitFrench"/>
<xsd:enumeration value="none"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_AlgClass">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="hash"/>
<xsd:enumeration value="custom"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_CryptProv">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="rsaAES"/>
<xsd:enumeration value="rsaFull"/>
<xsd:enumeration value="custom"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_AlgType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="typeAny"/>
<xsd:enumeration value="custom"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ColorType">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="ST_Guid">
<xsd:restriction base="xsd:token">
<xsd:pattern value="\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_OnOff">
<xsd:union memberTypes="xsd:boolean ST_OnOff1"/>
</xsd:simpleType>
<xsd:simpleType name="ST_OnOff1">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="on"/>
<xsd:enumeration value="off"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_String">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="ST_XmlName">
<xsd:restriction base="xsd:NCName">
<xsd:minLength value="1"/>
<xsd:maxLength value="255"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_TrueFalse">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="t"/>
<xsd:enumeration value="f"/>
<xsd:enumeration value="true"/>
<xsd:enumeration value="false"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_TrueFalseBlank">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="t"/>
<xsd:enumeration value="f"/>
<xsd:enumeration value="true"/>
<xsd:enumeration value="false"/>
<xsd:enumeration value=""/>
<xsd:enumeration value="True"/>
<xsd:enumeration value="False"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_UnsignedDecimalNumber">
<xsd:restriction base="xsd:decimal">
<xsd:minInclusive value="0"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_TwipsMeasure">
<xsd:union memberTypes="ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure"/>
</xsd:simpleType>
<xsd:simpleType name="ST_VerticalAlignRun">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="baseline"/>
<xsd:enumeration value="superscript"/>
<xsd:enumeration value="subscript"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_Xstring">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="ST_XAlign">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="left"/>
<xsd:enumeration value="center"/>
<xsd:enumeration value="right"/>
<xsd:enumeration value="inside"/>
<xsd:enumeration value="outside"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_YAlign">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="inline"/>
<xsd:enumeration value="top"/>
<xsd:enumeration value="center"/>
<xsd:enumeration value="bottom"/>
<xsd:enumeration value="inside"/>
<xsd:enumeration value="outside"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ConformanceClass">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="strict"/>
<xsd:enumeration value="transitional"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_UniversalMeasure">
<xsd:restriction base="xsd:string">
<xsd:pattern value="-?[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_PositiveUniversalMeasure">
<xsd:restriction base="ST_UniversalMeasure">
<xsd:pattern value="[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_Percentage">
<xsd:restriction base="xsd:string">
<xsd:pattern value="-?[0-9]+(\.[0-9]+)?%"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_FixedPercentage">
<xsd:restriction base="ST_Percentage">
<xsd:pattern value="-?((100)|([0-9][0-9]?))(\.[0-9][0-9]?)?%"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_PositivePercentage">
<xsd:restriction base="ST_Percentage">
<xsd:pattern value="[0-9]+(\.[0-9]+)?%"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_PositiveFixedPercentage">
<xsd:restriction base="ST_Percentage">
<xsd:pattern value="((100)|([0-9][0-9]?))(\.[0-9][0-9]?)?%"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/customXml"
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/customXml"
elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all">
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
schemaLocation="shared-commonSimpleTypes.xsd"/>
<xsd:complexType name="CT_DatastoreSchemaRef">
<xsd:attribute name="uri" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_DatastoreSchemaRefs">
<xsd:sequence>
<xsd:element name="schemaRef" type="CT_DatastoreSchemaRef" minOccurs="0" maxOccurs="unbounded"
/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_DatastoreItem">
<xsd:sequence>
<xsd:element name="schemaRefs" type="CT_DatastoreSchemaRefs" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="itemID" type="s:ST_Guid" use="required"/>
</xsd:complexType>
<xsd:element name="datastoreItem" type="CT_DatastoreItem"/>
</xsd:schema>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/schemaLibrary/2006/main"
targetNamespace="http://schemas.openxmlformats.org/schemaLibrary/2006/main"
attributeFormDefault="qualified" elementFormDefault="qualified">
<xsd:complexType name="CT_Schema">
<xsd:attribute name="uri" type="xsd:string" default=""/>
<xsd:attribute name="manifestLocation" type="xsd:string"/>
<xsd:attribute name="schemaLocation" type="xsd:string"/>
<xsd:attribute name="schemaLanguage" type="xsd:token"/>
</xsd:complexType>
<xsd:complexType name="CT_SchemaLibrary">
<xsd:sequence>
<xsd:element name="schema" type="CT_Schema" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="schemaLibrary" type="CT_SchemaLibrary"/>
</xsd:schema>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
blockDefault="#all" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
schemaLocation="shared-documentPropertiesVariantTypes.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
schemaLocation="shared-commonSimpleTypes.xsd"/>
<xsd:element name="Properties" type="CT_Properties"/>
<xsd:complexType name="CT_Properties">
<xsd:sequence>
<xsd:element name="property" minOccurs="0" maxOccurs="unbounded" type="CT_Property"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Property">
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element ref="vt:vector"/>
<xsd:element ref="vt:array"/>
<xsd:element ref="vt:blob"/>
<xsd:element ref="vt:oblob"/>
<xsd:element ref="vt:empty"/>
<xsd:element ref="vt:null"/>
<xsd:element ref="vt:i1"/>
<xsd:element ref="vt:i2"/>
<xsd:element ref="vt:i4"/>
<xsd:element ref="vt:i8"/>
<xsd:element ref="vt:int"/>
<xsd:element ref="vt:ui1"/>
<xsd:element ref="vt:ui2"/>
<xsd:element ref="vt:ui4"/>
<xsd:element ref="vt:ui8"/>
<xsd:element ref="vt:uint"/>
<xsd:element ref="vt:r4"/>
<xsd:element ref="vt:r8"/>
<xsd:element ref="vt:decimal"/>
<xsd:element ref="vt:lpstr"/>
<xsd:element ref="vt:lpwstr"/>
<xsd:element ref="vt:bstr"/>
<xsd:element ref="vt:date"/>
<xsd:element ref="vt:filetime"/>
<xsd:element ref="vt:bool"/>
<xsd:element ref="vt:cy"/>
<xsd:element ref="vt:error"/>
<xsd:element ref="vt:stream"/>
<xsd:element ref="vt:ostream"/>
<xsd:element ref="vt:storage"/>
<xsd:element ref="vt:ostorage"/>
<xsd:element ref="vt:vstream"/>
<xsd:element ref="vt:clsid"/>
</xsd:choice>
<xsd:attribute name="fmtid" use="required" type="s:ST_Guid"/>
<xsd:attribute name="pid" use="required" type="xsd:int"/>
<xsd:attribute name="name" use="optional" type="xsd:string"/>
<xsd:attribute name="linkTarget" use="optional" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
elementFormDefault="qualified" blockDefault="#all">
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
schemaLocation="shared-documentPropertiesVariantTypes.xsd"/>
<xsd:element name="Properties" type="CT_Properties"/>
<xsd:complexType name="CT_Properties">
<xsd:all>
<xsd:element name="Template" minOccurs="0" maxOccurs="1" type="xsd:string"/>
<xsd:element name="Manager" minOccurs="0" maxOccurs="1" type="xsd:string"/>
<xsd:element name="Company" minOccurs="0" maxOccurs="1" type="xsd:string"/>
<xsd:element name="Pages" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="Words" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="Characters" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="PresentationFormat" minOccurs="0" maxOccurs="1" type="xsd:string"/>
<xsd:element name="Lines" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="Paragraphs" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="Slides" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="Notes" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="TotalTime" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="HiddenSlides" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="MMClips" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="ScaleCrop" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
<xsd:element name="HeadingPairs" minOccurs="0" maxOccurs="1" type="CT_VectorVariant"/>
<xsd:element name="TitlesOfParts" minOccurs="0" maxOccurs="1" type="CT_VectorLpstr"/>
<xsd:element name="LinksUpToDate" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
<xsd:element name="CharactersWithSpaces" minOccurs="0" maxOccurs="1" type="xsd:int"/>
<xsd:element name="SharedDoc" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
<xsd:element name="HyperlinkBase" minOccurs="0" maxOccurs="1" type="xsd:string"/>
<xsd:element name="HLinks" minOccurs="0" maxOccurs="1" type="CT_VectorVariant"/>
<xsd:element name="HyperlinksChanged" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
<xsd:element name="DigSig" minOccurs="0" maxOccurs="1" type="CT_DigSigBlob"/>
<xsd:element name="Application" minOccurs="0" maxOccurs="1" type="xsd:string"/>
<xsd:element name="AppVersion" minOccurs="0" maxOccurs="1" type="xsd:string"/>
<xsd:element name="DocSecurity" minOccurs="0" maxOccurs="1" type="xsd:int"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="CT_VectorVariant">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element ref="vt:vector"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_VectorLpstr">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element ref="vt:vector"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_DigSigBlob">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element ref="vt:blob"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,195 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
blockDefault="#all" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
schemaLocation="shared-commonSimpleTypes.xsd"/>
<xsd:simpleType name="ST_VectorBaseType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="variant"/>
<xsd:enumeration value="i1"/>
<xsd:enumeration value="i2"/>
<xsd:enumeration value="i4"/>
<xsd:enumeration value="i8"/>
<xsd:enumeration value="ui1"/>
<xsd:enumeration value="ui2"/>
<xsd:enumeration value="ui4"/>
<xsd:enumeration value="ui8"/>
<xsd:enumeration value="r4"/>
<xsd:enumeration value="r8"/>
<xsd:enumeration value="lpstr"/>
<xsd:enumeration value="lpwstr"/>
<xsd:enumeration value="bstr"/>
<xsd:enumeration value="date"/>
<xsd:enumeration value="filetime"/>
<xsd:enumeration value="bool"/>
<xsd:enumeration value="cy"/>
<xsd:enumeration value="error"/>
<xsd:enumeration value="clsid"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ArrayBaseType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="variant"/>
<xsd:enumeration value="i1"/>
<xsd:enumeration value="i2"/>
<xsd:enumeration value="i4"/>
<xsd:enumeration value="int"/>
<xsd:enumeration value="ui1"/>
<xsd:enumeration value="ui2"/>
<xsd:enumeration value="ui4"/>
<xsd:enumeration value="uint"/>
<xsd:enumeration value="r4"/>
<xsd:enumeration value="r8"/>
<xsd:enumeration value="decimal"/>
<xsd:enumeration value="bstr"/>
<xsd:enumeration value="date"/>
<xsd:enumeration value="bool"/>
<xsd:enumeration value="cy"/>
<xsd:enumeration value="error"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_Cy">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\s*[0-9]*\.[0-9]{4}\s*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_Error">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\s*0x[0-9A-Za-z]{8}\s*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Empty"/>
<xsd:complexType name="CT_Null"/>
<xsd:complexType name="CT_Vector">
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element ref="variant"/>
<xsd:element ref="i1"/>
<xsd:element ref="i2"/>
<xsd:element ref="i4"/>
<xsd:element ref="i8"/>
<xsd:element ref="ui1"/>
<xsd:element ref="ui2"/>
<xsd:element ref="ui4"/>
<xsd:element ref="ui8"/>
<xsd:element ref="r4"/>
<xsd:element ref="r8"/>
<xsd:element ref="lpstr"/>
<xsd:element ref="lpwstr"/>
<xsd:element ref="bstr"/>
<xsd:element ref="date"/>
<xsd:element ref="filetime"/>
<xsd:element ref="bool"/>
<xsd:element ref="cy"/>
<xsd:element ref="error"/>
<xsd:element ref="clsid"/>
</xsd:choice>
<xsd:attribute name="baseType" type="ST_VectorBaseType" use="required"/>
<xsd:attribute name="size" type="xsd:unsignedInt" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_Array">
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element ref="variant"/>
<xsd:element ref="i1"/>
<xsd:element ref="i2"/>
<xsd:element ref="i4"/>
<xsd:element ref="int"/>
<xsd:element ref="ui1"/>
<xsd:element ref="ui2"/>
<xsd:element ref="ui4"/>
<xsd:element ref="uint"/>
<xsd:element ref="r4"/>
<xsd:element ref="r8"/>
<xsd:element ref="decimal"/>
<xsd:element ref="bstr"/>
<xsd:element ref="date"/>
<xsd:element ref="bool"/>
<xsd:element ref="error"/>
<xsd:element ref="cy"/>
</xsd:choice>
<xsd:attribute name="lBounds" type="xsd:int" use="required"/>
<xsd:attribute name="uBounds" type="xsd:int" use="required"/>
<xsd:attribute name="baseType" type="ST_ArrayBaseType" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_Variant">
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element ref="variant"/>
<xsd:element ref="vector"/>
<xsd:element ref="array"/>
<xsd:element ref="blob"/>
<xsd:element ref="oblob"/>
<xsd:element ref="empty"/>
<xsd:element ref="null"/>
<xsd:element ref="i1"/>
<xsd:element ref="i2"/>
<xsd:element ref="i4"/>
<xsd:element ref="i8"/>
<xsd:element ref="int"/>
<xsd:element ref="ui1"/>
<xsd:element ref="ui2"/>
<xsd:element ref="ui4"/>
<xsd:element ref="ui8"/>
<xsd:element ref="uint"/>
<xsd:element ref="r4"/>
<xsd:element ref="r8"/>
<xsd:element ref="decimal"/>
<xsd:element ref="lpstr"/>
<xsd:element ref="lpwstr"/>
<xsd:element ref="bstr"/>
<xsd:element ref="date"/>
<xsd:element ref="filetime"/>
<xsd:element ref="bool"/>
<xsd:element ref="cy"/>
<xsd:element ref="error"/>
<xsd:element ref="stream"/>
<xsd:element ref="ostream"/>
<xsd:element ref="storage"/>
<xsd:element ref="ostorage"/>
<xsd:element ref="vstream"/>
<xsd:element ref="clsid"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="CT_Vstream">
<xsd:simpleContent>
<xsd:extension base="xsd:base64Binary">
<xsd:attribute name="version" type="s:ST_Guid"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:element name="variant" type="CT_Variant"/>
<xsd:element name="vector" type="CT_Vector"/>
<xsd:element name="array" type="CT_Array"/>
<xsd:element name="blob" type="xsd:base64Binary"/>
<xsd:element name="oblob" type="xsd:base64Binary"/>
<xsd:element name="empty" type="CT_Empty"/>
<xsd:element name="null" type="CT_Null"/>
<xsd:element name="i1" type="xsd:byte"/>
<xsd:element name="i2" type="xsd:short"/>
<xsd:element name="i4" type="xsd:int"/>
<xsd:element name="i8" type="xsd:long"/>
<xsd:element name="int" type="xsd:int"/>
<xsd:element name="ui1" type="xsd:unsignedByte"/>
<xsd:element name="ui2" type="xsd:unsignedShort"/>
<xsd:element name="ui4" type="xsd:unsignedInt"/>
<xsd:element name="ui8" type="xsd:unsignedLong"/>
<xsd:element name="uint" type="xsd:unsignedInt"/>
<xsd:element name="r4" type="xsd:float"/>
<xsd:element name="r8" type="xsd:double"/>
<xsd:element name="decimal" type="xsd:decimal"/>
<xsd:element name="lpstr" type="xsd:string"/>
<xsd:element name="lpwstr" type="xsd:string"/>
<xsd:element name="bstr" type="xsd:string"/>
<xsd:element name="date" type="xsd:dateTime"/>
<xsd:element name="filetime" type="xsd:dateTime"/>
<xsd:element name="bool" type="xsd:boolean"/>
<xsd:element name="cy" type="ST_Cy"/>
<xsd:element name="error" type="ST_Error"/>
<xsd:element name="stream" type="xsd:base64Binary"/>
<xsd:element name="ostream" type="xsd:base64Binary"/>
<xsd:element name="storage" type="xsd:base64Binary"/>
<xsd:element name="ostorage" type="xsd:base64Binary"/>
<xsd:element name="vstream" type="CT_Vstream"/>
<xsd:element name="clsid" type="s:ST_Guid"/>
</xsd:schema>

View File

@@ -0,0 +1,582 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/math">
<xsd:import namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
schemaLocation="wml.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
schemaLocation="shared-commonSimpleTypes.xsd"/>
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
<xsd:simpleType name="ST_Integer255">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="1"/>
<xsd:maxInclusive value="255"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Integer255">
<xsd:attribute name="val" type="ST_Integer255" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_Integer2">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="-2"/>
<xsd:maxInclusive value="2"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Integer2">
<xsd:attribute name="val" type="ST_Integer2" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_SpacingRule">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="4"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_SpacingRule">
<xsd:attribute name="val" type="ST_SpacingRule" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_UnSignedInteger">
<xsd:restriction base="xsd:unsignedInt"/>
</xsd:simpleType>
<xsd:complexType name="CT_UnSignedInteger">
<xsd:attribute name="val" type="ST_UnSignedInteger" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_Char">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="1"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Char">
<xsd:attribute name="val" type="ST_Char" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_OnOff">
<xsd:attribute name="val" type="s:ST_OnOff"/>
</xsd:complexType>
<xsd:complexType name="CT_String">
<xsd:attribute name="val" type="s:ST_String"/>
</xsd:complexType>
<xsd:complexType name="CT_XAlign">
<xsd:attribute name="val" type="s:ST_XAlign" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_YAlign">
<xsd:attribute name="val" type="s:ST_YAlign" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_Shp">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="centered"/>
<xsd:enumeration value="match"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Shp">
<xsd:attribute name="val" type="ST_Shp" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_FType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="bar"/>
<xsd:enumeration value="skw"/>
<xsd:enumeration value="lin"/>
<xsd:enumeration value="noBar"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_FType">
<xsd:attribute name="val" type="ST_FType" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_LimLoc">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="undOvr"/>
<xsd:enumeration value="subSup"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_LimLoc">
<xsd:attribute name="val" type="ST_LimLoc" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_TopBot">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="top"/>
<xsd:enumeration value="bot"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_TopBot">
<xsd:attribute name="val" type="ST_TopBot" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_Script">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="roman"/>
<xsd:enumeration value="script"/>
<xsd:enumeration value="fraktur"/>
<xsd:enumeration value="double-struck"/>
<xsd:enumeration value="sans-serif"/>
<xsd:enumeration value="monospace"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Script">
<xsd:attribute name="val" type="ST_Script"/>
</xsd:complexType>
<xsd:simpleType name="ST_Style">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="p"/>
<xsd:enumeration value="b"/>
<xsd:enumeration value="i"/>
<xsd:enumeration value="bi"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Style">
<xsd:attribute name="val" type="ST_Style"/>
</xsd:complexType>
<xsd:complexType name="CT_ManualBreak">
<xsd:attribute name="alnAt" type="ST_Integer255"/>
</xsd:complexType>
<xsd:group name="EG_ScriptStyle">
<xsd:sequence>
<xsd:element name="scr" minOccurs="0" type="CT_Script"/>
<xsd:element name="sty" minOccurs="0" type="CT_Style"/>
</xsd:sequence>
</xsd:group>
<xsd:complexType name="CT_RPR">
<xsd:sequence>
<xsd:element name="lit" minOccurs="0" type="CT_OnOff"/>
<xsd:choice>
<xsd:element name="nor" minOccurs="0" type="CT_OnOff"/>
<xsd:sequence>
<xsd:group ref="EG_ScriptStyle"/>
</xsd:sequence>
</xsd:choice>
<xsd:element name="brk" minOccurs="0" type="CT_ManualBreak"/>
<xsd:element name="aln" minOccurs="0" type="CT_OnOff"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Text">
<xsd:simpleContent>
<xsd:extension base="s:ST_String">
<xsd:attribute ref="xml:space" use="optional"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="CT_R">
<xsd:sequence>
<xsd:element name="rPr" type="CT_RPR" minOccurs="0"/>
<xsd:group ref="w:EG_RPr" minOccurs="0"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="w:EG_RunInnerContent"/>
<xsd:element name="t" type="CT_Text" minOccurs="0"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_CtrlPr">
<xsd:sequence>
<xsd:group ref="w:EG_RPrMath" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_AccPr">
<xsd:sequence>
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Acc">
<xsd:sequence>
<xsd:element name="accPr" type="CT_AccPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_BarPr">
<xsd:sequence>
<xsd:element name="pos" type="CT_TopBot" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Bar">
<xsd:sequence>
<xsd:element name="barPr" type="CT_BarPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_BoxPr">
<xsd:sequence>
<xsd:element name="opEmu" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="noBreak" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="diff" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="brk" type="CT_ManualBreak" minOccurs="0"/>
<xsd:element name="aln" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Box">
<xsd:sequence>
<xsd:element name="boxPr" type="CT_BoxPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_BorderBoxPr">
<xsd:sequence>
<xsd:element name="hideTop" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="hideBot" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="hideLeft" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="hideRight" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="strikeH" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="strikeV" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="strikeBLTR" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="strikeTLBR" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_BorderBox">
<xsd:sequence>
<xsd:element name="borderBoxPr" type="CT_BorderBoxPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_DPr">
<xsd:sequence>
<xsd:element name="begChr" type="CT_Char" minOccurs="0"/>
<xsd:element name="sepChr" type="CT_Char" minOccurs="0"/>
<xsd:element name="endChr" type="CT_Char" minOccurs="0"/>
<xsd:element name="grow" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="shp" type="CT_Shp" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_D">
<xsd:sequence>
<xsd:element name="dPr" type="CT_DPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_EqArrPr">
<xsd:sequence>
<xsd:element name="baseJc" type="CT_YAlign" minOccurs="0"/>
<xsd:element name="maxDist" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="objDist" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="rSpRule" type="CT_SpacingRule" minOccurs="0"/>
<xsd:element name="rSp" type="CT_UnSignedInteger" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_EqArr">
<xsd:sequence>
<xsd:element name="eqArrPr" type="CT_EqArrPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_FPr">
<xsd:sequence>
<xsd:element name="type" type="CT_FType" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_F">
<xsd:sequence>
<xsd:element name="fPr" type="CT_FPr" minOccurs="0"/>
<xsd:element name="num" type="CT_OMathArg"/>
<xsd:element name="den" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_FuncPr">
<xsd:sequence>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Func">
<xsd:sequence>
<xsd:element name="funcPr" type="CT_FuncPr" minOccurs="0"/>
<xsd:element name="fName" type="CT_OMathArg"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_GroupChrPr">
<xsd:sequence>
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
<xsd:element name="pos" type="CT_TopBot" minOccurs="0"/>
<xsd:element name="vertJc" type="CT_TopBot" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_GroupChr">
<xsd:sequence>
<xsd:element name="groupChrPr" type="CT_GroupChrPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_LimLowPr">
<xsd:sequence>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_LimLow">
<xsd:sequence>
<xsd:element name="limLowPr" type="CT_LimLowPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
<xsd:element name="lim" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_LimUppPr">
<xsd:sequence>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_LimUpp">
<xsd:sequence>
<xsd:element name="limUppPr" type="CT_LimUppPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
<xsd:element name="lim" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_MCPr">
<xsd:sequence>
<xsd:element name="count" type="CT_Integer255" minOccurs="0"/>
<xsd:element name="mcJc" type="CT_XAlign" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_MC">
<xsd:sequence>
<xsd:element name="mcPr" type="CT_MCPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_MCS">
<xsd:sequence>
<xsd:element name="mc" type="CT_MC" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_MPr">
<xsd:sequence>
<xsd:element name="baseJc" type="CT_YAlign" minOccurs="0"/>
<xsd:element name="plcHide" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="rSpRule" type="CT_SpacingRule" minOccurs="0"/>
<xsd:element name="cGpRule" type="CT_SpacingRule" minOccurs="0"/>
<xsd:element name="rSp" type="CT_UnSignedInteger" minOccurs="0"/>
<xsd:element name="cSp" type="CT_UnSignedInteger" minOccurs="0"/>
<xsd:element name="cGp" type="CT_UnSignedInteger" minOccurs="0"/>
<xsd:element name="mcs" type="CT_MCS" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_MR">
<xsd:sequence>
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_M">
<xsd:sequence>
<xsd:element name="mPr" type="CT_MPr" minOccurs="0"/>
<xsd:element name="mr" type="CT_MR" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_NaryPr">
<xsd:sequence>
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
<xsd:element name="limLoc" type="CT_LimLoc" minOccurs="0"/>
<xsd:element name="grow" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="subHide" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="supHide" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Nary">
<xsd:sequence>
<xsd:element name="naryPr" type="CT_NaryPr" minOccurs="0"/>
<xsd:element name="sub" type="CT_OMathArg"/>
<xsd:element name="sup" type="CT_OMathArg"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_PhantPr">
<xsd:sequence>
<xsd:element name="show" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="zeroWid" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="zeroAsc" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="zeroDesc" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="transp" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Phant">
<xsd:sequence>
<xsd:element name="phantPr" type="CT_PhantPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_RadPr">
<xsd:sequence>
<xsd:element name="degHide" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Rad">
<xsd:sequence>
<xsd:element name="radPr" type="CT_RadPr" minOccurs="0"/>
<xsd:element name="deg" type="CT_OMathArg"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SPrePr">
<xsd:sequence>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SPre">
<xsd:sequence>
<xsd:element name="sPrePr" type="CT_SPrePr" minOccurs="0"/>
<xsd:element name="sub" type="CT_OMathArg"/>
<xsd:element name="sup" type="CT_OMathArg"/>
<xsd:element name="e" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SSubPr">
<xsd:sequence>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SSub">
<xsd:sequence>
<xsd:element name="sSubPr" type="CT_SSubPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
<xsd:element name="sub" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SSubSupPr">
<xsd:sequence>
<xsd:element name="alnScr" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SSubSup">
<xsd:sequence>
<xsd:element name="sSubSupPr" type="CT_SSubSupPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
<xsd:element name="sub" type="CT_OMathArg"/>
<xsd:element name="sup" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SSupPr">
<xsd:sequence>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_SSup">
<xsd:sequence>
<xsd:element name="sSupPr" type="CT_SSupPr" minOccurs="0"/>
<xsd:element name="e" type="CT_OMathArg"/>
<xsd:element name="sup" type="CT_OMathArg"/>
</xsd:sequence>
</xsd:complexType>
<xsd:group name="EG_OMathMathElements">
<xsd:choice>
<xsd:element name="acc" type="CT_Acc"/>
<xsd:element name="bar" type="CT_Bar"/>
<xsd:element name="box" type="CT_Box"/>
<xsd:element name="borderBox" type="CT_BorderBox"/>
<xsd:element name="d" type="CT_D"/>
<xsd:element name="eqArr" type="CT_EqArr"/>
<xsd:element name="f" type="CT_F"/>
<xsd:element name="func" type="CT_Func"/>
<xsd:element name="groupChr" type="CT_GroupChr"/>
<xsd:element name="limLow" type="CT_LimLow"/>
<xsd:element name="limUpp" type="CT_LimUpp"/>
<xsd:element name="m" type="CT_M"/>
<xsd:element name="nary" type="CT_Nary"/>
<xsd:element name="phant" type="CT_Phant"/>
<xsd:element name="rad" type="CT_Rad"/>
<xsd:element name="sPre" type="CT_SPre"/>
<xsd:element name="sSub" type="CT_SSub"/>
<xsd:element name="sSubSup" type="CT_SSubSup"/>
<xsd:element name="sSup" type="CT_SSup"/>
<xsd:element name="r" type="CT_R"/>
</xsd:choice>
</xsd:group>
<xsd:group name="EG_OMathElements">
<xsd:choice>
<xsd:group ref="EG_OMathMathElements"/>
<xsd:group ref="w:EG_PContentMath"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_OMathArgPr">
<xsd:sequence>
<xsd:element name="argSz" type="CT_Integer2" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_OMathArg">
<xsd:sequence>
<xsd:element name="argPr" type="CT_OMathArgPr" minOccurs="0"/>
<xsd:group ref="EG_OMathElements" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="ST_Jc">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="left"/>
<xsd:enumeration value="right"/>
<xsd:enumeration value="center"/>
<xsd:enumeration value="centerGroup"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_OMathJc">
<xsd:attribute name="val" type="ST_Jc"/>
</xsd:complexType>
<xsd:complexType name="CT_OMathParaPr">
<xsd:sequence>
<xsd:element name="jc" type="CT_OMathJc" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_TwipsMeasure">
<xsd:attribute name="val" type="s:ST_TwipsMeasure" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_BreakBin">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="before"/>
<xsd:enumeration value="after"/>
<xsd:enumeration value="repeat"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_BreakBin">
<xsd:attribute name="val" type="ST_BreakBin"/>
</xsd:complexType>
<xsd:simpleType name="ST_BreakBinSub">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="--"/>
<xsd:enumeration value="-+"/>
<xsd:enumeration value="+-"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_BreakBinSub">
<xsd:attribute name="val" type="ST_BreakBinSub"/>
</xsd:complexType>
<xsd:complexType name="CT_MathPr">
<xsd:sequence>
<xsd:element name="mathFont" type="CT_String" minOccurs="0"/>
<xsd:element name="brkBin" type="CT_BreakBin" minOccurs="0"/>
<xsd:element name="brkBinSub" type="CT_BreakBinSub" minOccurs="0"/>
<xsd:element name="smallFrac" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="dispDef" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="lMargin" type="CT_TwipsMeasure" minOccurs="0"/>
<xsd:element name="rMargin" type="CT_TwipsMeasure" minOccurs="0"/>
<xsd:element name="defJc" type="CT_OMathJc" minOccurs="0"/>
<xsd:element name="preSp" type="CT_TwipsMeasure" minOccurs="0"/>
<xsd:element name="postSp" type="CT_TwipsMeasure" minOccurs="0"/>
<xsd:element name="interSp" type="CT_TwipsMeasure" minOccurs="0"/>
<xsd:element name="intraSp" type="CT_TwipsMeasure" minOccurs="0"/>
<xsd:choice minOccurs="0">
<xsd:element name="wrapIndent" type="CT_TwipsMeasure"/>
<xsd:element name="wrapRight" type="CT_OnOff"/>
</xsd:choice>
<xsd:element name="intLim" type="CT_LimLoc" minOccurs="0"/>
<xsd:element name="naryLim" type="CT_LimLoc" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="mathPr" type="CT_MathPr"/>
<xsd:complexType name="CT_OMathPara">
<xsd:sequence>
<xsd:element name="oMathParaPr" type="CT_OMathParaPr" minOccurs="0"/>
<xsd:element name="oMath" type="CT_OMath" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_OMath">
<xsd:sequence>
<xsd:group ref="EG_OMathElements" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="oMathPara" type="CT_OMathPara"/>
<xsd:element name="oMath" type="CT_OMath"/>
</xsd:schema>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
elementFormDefault="qualified"
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
blockDefault="#all">
<xsd:simpleType name="ST_RelationshipId">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:attribute name="id" type="ST_RelationshipId"/>
<xsd:attribute name="embed" type="ST_RelationshipId"/>
<xsd:attribute name="link" type="ST_RelationshipId"/>
<xsd:attribute name="dm" type="ST_RelationshipId" default=""/>
<xsd:attribute name="lo" type="ST_RelationshipId" default=""/>
<xsd:attribute name="qs" type="ST_RelationshipId" default=""/>
<xsd:attribute name="cs" type="ST_RelationshipId" default=""/>
<xsd:attribute name="blip" type="ST_RelationshipId" default=""/>
<xsd:attribute name="pict" type="ST_RelationshipId"/>
<xsd:attribute name="href" type="ST_RelationshipId"/>
<xsd:attribute name="topLeft" type="ST_RelationshipId"/>
<xsd:attribute name="topRight" type="ST_RelationshipId"/>
<xsd:attribute name="bottomLeft" type="ST_RelationshipId"/>
<xsd:attribute name="bottomRight" type="ST_RelationshipId"/>
</xsd:schema>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,570 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:schemas-microsoft-com:vml"
xmlns:pvml="urn:schemas-microsoft-com:office:powerpoint"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
targetNamespace="urn:schemas-microsoft-com:vml" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="urn:schemas-microsoft-com:office:office"
schemaLocation="vml-officeDrawing.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
schemaLocation="wml.xsd"/>
<xsd:import namespace="urn:schemas-microsoft-com:office:word"
schemaLocation="vml-wordprocessingDrawing.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
schemaLocation="shared-relationshipReference.xsd"/>
<xsd:import namespace="urn:schemas-microsoft-com:office:excel"
schemaLocation="vml-spreadsheetDrawing.xsd"/>
<xsd:import namespace="urn:schemas-microsoft-com:office:powerpoint"
schemaLocation="vml-presentationDrawing.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
schemaLocation="shared-commonSimpleTypes.xsd"/>
<xsd:attributeGroup name="AG_Id">
<xsd:attribute name="id" type="xsd:string" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_Style">
<xsd:attribute name="style" type="xsd:string" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_Type">
<xsd:attribute name="type" type="xsd:string" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_Adj">
<xsd:attribute name="adj" type="xsd:string" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_Path">
<xsd:attribute name="path" type="xsd:string" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_Fill">
<xsd:attribute name="filled" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="fillcolor" type="s:ST_ColorType" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_Chromakey">
<xsd:attribute name="chromakey" type="s:ST_ColorType" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_Ext">
<xsd:attribute name="ext" form="qualified" type="ST_Ext"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_CoreAttributes">
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attributeGroup ref="AG_Style"/>
<xsd:attribute name="href" type="xsd:string" use="optional"/>
<xsd:attribute name="target" type="xsd:string" use="optional"/>
<xsd:attribute name="class" type="xsd:string" use="optional"/>
<xsd:attribute name="title" type="xsd:string" use="optional"/>
<xsd:attribute name="alt" type="xsd:string" use="optional"/>
<xsd:attribute name="coordsize" type="xsd:string" use="optional"/>
<xsd:attribute name="coordorigin" type="xsd:string" use="optional"/>
<xsd:attribute name="wrapcoords" type="xsd:string" use="optional"/>
<xsd:attribute name="print" type="s:ST_TrueFalse" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_ShapeAttributes">
<xsd:attributeGroup ref="AG_Chromakey"/>
<xsd:attributeGroup ref="AG_Fill"/>
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
<xsd:attribute name="stroked" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="strokecolor" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="strokeweight" type="xsd:string" use="optional"/>
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_OfficeCoreAttributes">
<xsd:attribute ref="o:spid"/>
<xsd:attribute ref="o:oned"/>
<xsd:attribute ref="o:regroupid"/>
<xsd:attribute ref="o:doubleclicknotify"/>
<xsd:attribute ref="o:button"/>
<xsd:attribute ref="o:userhidden"/>
<xsd:attribute ref="o:bullet"/>
<xsd:attribute ref="o:hr"/>
<xsd:attribute ref="o:hrstd"/>
<xsd:attribute ref="o:hrnoshade"/>
<xsd:attribute ref="o:hrpct"/>
<xsd:attribute ref="o:hralign"/>
<xsd:attribute ref="o:allowincell"/>
<xsd:attribute ref="o:allowoverlap"/>
<xsd:attribute ref="o:userdrawn"/>
<xsd:attribute ref="o:bordertopcolor"/>
<xsd:attribute ref="o:borderleftcolor"/>
<xsd:attribute ref="o:borderbottomcolor"/>
<xsd:attribute ref="o:borderrightcolor"/>
<xsd:attribute ref="o:dgmlayout"/>
<xsd:attribute ref="o:dgmnodekind"/>
<xsd:attribute ref="o:dgmlayoutmru"/>
<xsd:attribute ref="o:insetmode"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_OfficeShapeAttributes">
<xsd:attribute ref="o:spt"/>
<xsd:attribute ref="o:connectortype"/>
<xsd:attribute ref="o:bwmode"/>
<xsd:attribute ref="o:bwpure"/>
<xsd:attribute ref="o:bwnormal"/>
<xsd:attribute ref="o:forcedash"/>
<xsd:attribute ref="o:oleicon"/>
<xsd:attribute ref="o:ole"/>
<xsd:attribute ref="o:preferrelative"/>
<xsd:attribute ref="o:cliptowrap"/>
<xsd:attribute ref="o:clip"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_AllCoreAttributes">
<xsd:attributeGroup ref="AG_CoreAttributes"/>
<xsd:attributeGroup ref="AG_OfficeCoreAttributes"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_AllShapeAttributes">
<xsd:attributeGroup ref="AG_ShapeAttributes"/>
<xsd:attributeGroup ref="AG_OfficeShapeAttributes"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_ImageAttributes">
<xsd:attribute name="src" type="xsd:string" use="optional"/>
<xsd:attribute name="cropleft" type="xsd:string" use="optional"/>
<xsd:attribute name="croptop" type="xsd:string" use="optional"/>
<xsd:attribute name="cropright" type="xsd:string" use="optional"/>
<xsd:attribute name="cropbottom" type="xsd:string" use="optional"/>
<xsd:attribute name="gain" type="xsd:string" use="optional"/>
<xsd:attribute name="blacklevel" type="xsd:string" use="optional"/>
<xsd:attribute name="gamma" type="xsd:string" use="optional"/>
<xsd:attribute name="grayscale" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="bilevel" type="s:ST_TrueFalse" use="optional"/>
</xsd:attributeGroup>
<xsd:attributeGroup name="AG_StrokeAttributes">
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="weight" type="xsd:string" use="optional"/>
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
<xsd:attribute name="linestyle" type="ST_StrokeLineStyle" use="optional"/>
<xsd:attribute name="miterlimit" type="xsd:decimal" use="optional"/>
<xsd:attribute name="joinstyle" type="ST_StrokeJoinStyle" use="optional"/>
<xsd:attribute name="endcap" type="ST_StrokeEndCap" use="optional"/>
<xsd:attribute name="dashstyle" type="xsd:string" use="optional"/>
<xsd:attribute name="filltype" type="ST_FillType" use="optional"/>
<xsd:attribute name="src" type="xsd:string" use="optional"/>
<xsd:attribute name="imageaspect" type="ST_ImageAspect" use="optional"/>
<xsd:attribute name="imagesize" type="xsd:string" use="optional"/>
<xsd:attribute name="imagealignshape" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="startarrow" type="ST_StrokeArrowType" use="optional"/>
<xsd:attribute name="startarrowwidth" type="ST_StrokeArrowWidth" use="optional"/>
<xsd:attribute name="startarrowlength" type="ST_StrokeArrowLength" use="optional"/>
<xsd:attribute name="endarrow" type="ST_StrokeArrowType" use="optional"/>
<xsd:attribute name="endarrowwidth" type="ST_StrokeArrowWidth" use="optional"/>
<xsd:attribute name="endarrowlength" type="ST_StrokeArrowLength" use="optional"/>
<xsd:attribute ref="o:href"/>
<xsd:attribute ref="o:althref"/>
<xsd:attribute ref="o:title"/>
<xsd:attribute ref="o:forcedash"/>
<xsd:attribute ref="r:id" use="optional"/>
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute ref="o:relid"/>
</xsd:attributeGroup>
<xsd:group name="EG_ShapeElements">
<xsd:choice>
<xsd:element ref="path"/>
<xsd:element ref="formulas"/>
<xsd:element ref="handles"/>
<xsd:element ref="fill"/>
<xsd:element ref="stroke"/>
<xsd:element ref="shadow"/>
<xsd:element ref="textbox"/>
<xsd:element ref="textpath"/>
<xsd:element ref="imagedata"/>
<xsd:element ref="o:skew"/>
<xsd:element ref="o:extrusion"/>
<xsd:element ref="o:callout"/>
<xsd:element ref="o:lock"/>
<xsd:element ref="o:clippath"/>
<xsd:element ref="o:signatureline"/>
<xsd:element ref="w10:wrap"/>
<xsd:element ref="w10:anchorlock"/>
<xsd:element ref="w10:bordertop"/>
<xsd:element ref="w10:borderbottom"/>
<xsd:element ref="w10:borderleft"/>
<xsd:element ref="w10:borderright"/>
<xsd:element ref="x:ClientData" minOccurs="0"/>
<xsd:element ref="pvml:textdata" minOccurs="0"/>
</xsd:choice>
</xsd:group>
<xsd:element name="shape" type="CT_Shape"/>
<xsd:element name="shapetype" type="CT_Shapetype"/>
<xsd:element name="group" type="CT_Group"/>
<xsd:element name="background" type="CT_Background"/>
<xsd:complexType name="CT_Shape">
<xsd:choice maxOccurs="unbounded">
<xsd:group ref="EG_ShapeElements"/>
<xsd:element ref="o:ink"/>
<xsd:element ref="pvml:iscomment"/>
<xsd:element ref="o:equationxml"/>
</xsd:choice>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
<xsd:attributeGroup ref="AG_Type"/>
<xsd:attributeGroup ref="AG_Adj"/>
<xsd:attributeGroup ref="AG_Path"/>
<xsd:attribute ref="o:gfxdata"/>
<xsd:attribute name="equationxml" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Shapetype">
<xsd:sequence>
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="o:complex" minOccurs="0"/>
</xsd:sequence>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
<xsd:attributeGroup ref="AG_Adj"/>
<xsd:attributeGroup ref="AG_Path"/>
<xsd:attribute ref="o:master"/>
</xsd:complexType>
<xsd:complexType name="CT_Group">
<xsd:choice maxOccurs="unbounded">
<xsd:group ref="EG_ShapeElements"/>
<xsd:element ref="group"/>
<xsd:element ref="shape"/>
<xsd:element ref="shapetype"/>
<xsd:element ref="arc"/>
<xsd:element ref="curve"/>
<xsd:element ref="image"/>
<xsd:element ref="line"/>
<xsd:element ref="oval"/>
<xsd:element ref="polyline"/>
<xsd:element ref="rect"/>
<xsd:element ref="roundrect"/>
<xsd:element ref="o:diagram"/>
</xsd:choice>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_Fill"/>
<xsd:attribute name="editas" type="ST_EditAs" use="optional"/>
<xsd:attribute ref="o:tableproperties"/>
<xsd:attribute ref="o:tablelimits"/>
</xsd:complexType>
<xsd:complexType name="CT_Background">
<xsd:sequence>
<xsd:element ref="fill" minOccurs="0"/>
</xsd:sequence>
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attributeGroup ref="AG_Fill"/>
<xsd:attribute ref="o:bwmode"/>
<xsd:attribute ref="o:bwpure"/>
<xsd:attribute ref="o:bwnormal"/>
<xsd:attribute ref="o:targetscreensize"/>
</xsd:complexType>
<xsd:element name="fill" type="CT_Fill"/>
<xsd:element name="formulas" type="CT_Formulas"/>
<xsd:element name="handles" type="CT_Handles"/>
<xsd:element name="imagedata" type="CT_ImageData"/>
<xsd:element name="path" type="CT_Path"/>
<xsd:element name="textbox" type="CT_Textbox"/>
<xsd:element name="shadow" type="CT_Shadow"/>
<xsd:element name="stroke" type="CT_Stroke"/>
<xsd:element name="textpath" type="CT_TextPath"/>
<xsd:complexType name="CT_Fill">
<xsd:sequence>
<xsd:element ref="o:fill" minOccurs="0"/>
</xsd:sequence>
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attribute name="type" type="ST_FillType" use="optional"/>
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="src" type="xsd:string" use="optional"/>
<xsd:attribute ref="o:href"/>
<xsd:attribute ref="o:althref"/>
<xsd:attribute name="size" type="xsd:string" use="optional"/>
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
<xsd:attribute name="position" type="xsd:string" use="optional"/>
<xsd:attribute name="aspect" type="ST_ImageAspect" use="optional"/>
<xsd:attribute name="colors" type="xsd:string" use="optional"/>
<xsd:attribute name="angle" type="xsd:decimal" use="optional"/>
<xsd:attribute name="alignshape" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="focus" type="xsd:string" use="optional"/>
<xsd:attribute name="focussize" type="xsd:string" use="optional"/>
<xsd:attribute name="focusposition" type="xsd:string" use="optional"/>
<xsd:attribute name="method" type="ST_FillMethod" use="optional"/>
<xsd:attribute ref="o:detectmouseclick"/>
<xsd:attribute ref="o:title"/>
<xsd:attribute ref="o:opacity2"/>
<xsd:attribute name="recolor" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="rotate" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute ref="r:id" use="optional"/>
<xsd:attribute ref="o:relid" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Formulas">
<xsd:sequence>
<xsd:element name="f" type="CT_F" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_F">
<xsd:attribute name="eqn" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="CT_Handles">
<xsd:sequence>
<xsd:element name="h" type="CT_H" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_H">
<xsd:attribute name="position" type="xsd:string"/>
<xsd:attribute name="polar" type="xsd:string"/>
<xsd:attribute name="map" type="xsd:string"/>
<xsd:attribute name="invx" type="s:ST_TrueFalse"/>
<xsd:attribute name="invy" type="s:ST_TrueFalse"/>
<xsd:attribute name="switch" type="s:ST_TrueFalseBlank"/>
<xsd:attribute name="xrange" type="xsd:string"/>
<xsd:attribute name="yrange" type="xsd:string"/>
<xsd:attribute name="radiusrange" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="CT_ImageData">
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attributeGroup ref="AG_ImageAttributes"/>
<xsd:attributeGroup ref="AG_Chromakey"/>
<xsd:attribute name="embosscolor" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="recolortarget" type="s:ST_ColorType"/>
<xsd:attribute ref="o:href"/>
<xsd:attribute ref="o:althref"/>
<xsd:attribute ref="o:title"/>
<xsd:attribute ref="o:oleid"/>
<xsd:attribute ref="o:detectmouseclick"/>
<xsd:attribute ref="o:movie"/>
<xsd:attribute ref="o:relid"/>
<xsd:attribute ref="r:id"/>
<xsd:attribute ref="r:pict"/>
<xsd:attribute ref="r:href"/>
</xsd:complexType>
<xsd:complexType name="CT_Path">
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attribute name="v" type="xsd:string" use="optional"/>
<xsd:attribute name="limo" type="xsd:string" use="optional"/>
<xsd:attribute name="textboxrect" type="xsd:string" use="optional"/>
<xsd:attribute name="fillok" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="strokeok" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="shadowok" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="arrowok" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="gradientshapeok" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="textpathok" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="insetpenok" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute ref="o:connecttype"/>
<xsd:attribute ref="o:connectlocs"/>
<xsd:attribute ref="o:connectangles"/>
<xsd:attribute ref="o:extrusionok"/>
</xsd:complexType>
<xsd:complexType name="CT_Shadow">
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="type" type="ST_ShadowType" use="optional"/>
<xsd:attribute name="obscured" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
<xsd:attribute name="offset" type="xsd:string" use="optional"/>
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="offset2" type="xsd:string" use="optional"/>
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
<xsd:attribute name="matrix" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Stroke">
<xsd:sequence>
<xsd:element ref="o:left" minOccurs="0"/>
<xsd:element ref="o:top" minOccurs="0"/>
<xsd:element ref="o:right" minOccurs="0"/>
<xsd:element ref="o:bottom" minOccurs="0"/>
<xsd:element ref="o:column" minOccurs="0"/>
</xsd:sequence>
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attributeGroup ref="AG_StrokeAttributes"/>
</xsd:complexType>
<xsd:complexType name="CT_Textbox">
<xsd:choice>
<xsd:element ref="w:txbxContent" minOccurs="0"/>
<xsd:any namespace="##local" processContents="skip"/>
</xsd:choice>
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attributeGroup ref="AG_Style"/>
<xsd:attribute name="inset" type="xsd:string" use="optional"/>
<xsd:attribute ref="o:singleclick"/>
<xsd:attribute ref="o:insetmode"/>
</xsd:complexType>
<xsd:complexType name="CT_TextPath">
<xsd:attributeGroup ref="AG_Id"/>
<xsd:attributeGroup ref="AG_Style"/>
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="fitshape" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="fitpath" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="trim" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="xscale" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="string" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:element name="arc" type="CT_Arc"/>
<xsd:element name="curve" type="CT_Curve"/>
<xsd:element name="image" type="CT_Image"/>
<xsd:element name="line" type="CT_Line"/>
<xsd:element name="oval" type="CT_Oval"/>
<xsd:element name="polyline" type="CT_PolyLine"/>
<xsd:element name="rect" type="CT_Rect"/>
<xsd:element name="roundrect" type="CT_RoundRect"/>
<xsd:complexType name="CT_Arc">
<xsd:sequence>
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
<xsd:attribute name="startAngle" type="xsd:decimal" use="optional"/>
<xsd:attribute name="endAngle" type="xsd:decimal" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Curve">
<xsd:sequence>
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
<xsd:attribute name="from" type="xsd:string" use="optional"/>
<xsd:attribute name="control1" type="xsd:string" use="optional"/>
<xsd:attribute name="control2" type="xsd:string" use="optional"/>
<xsd:attribute name="to" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Image">
<xsd:sequence>
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
<xsd:attributeGroup ref="AG_ImageAttributes"/>
</xsd:complexType>
<xsd:complexType name="CT_Line">
<xsd:sequence>
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
<xsd:attribute name="from" type="xsd:string" use="optional"/>
<xsd:attribute name="to" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Oval">
<xsd:choice maxOccurs="unbounded">
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
</xsd:complexType>
<xsd:complexType name="CT_PolyLine">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="EG_ShapeElements"/>
<xsd:element ref="o:ink"/>
</xsd:choice>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
<xsd:attribute name="points" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Rect">
<xsd:choice maxOccurs="unbounded">
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
</xsd:complexType>
<xsd:complexType name="CT_RoundRect">
<xsd:choice maxOccurs="unbounded">
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
<xsd:attribute name="arcsize" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:simpleType name="ST_Ext">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="view"/>
<xsd:enumeration value="edit"/>
<xsd:enumeration value="backwardCompatible"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_FillType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="solid"/>
<xsd:enumeration value="gradient"/>
<xsd:enumeration value="gradientRadial"/>
<xsd:enumeration value="tile"/>
<xsd:enumeration value="pattern"/>
<xsd:enumeration value="frame"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_FillMethod">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="none"/>
<xsd:enumeration value="linear"/>
<xsd:enumeration value="sigma"/>
<xsd:enumeration value="any"/>
<xsd:enumeration value="linear sigma"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ShadowType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="single"/>
<xsd:enumeration value="double"/>
<xsd:enumeration value="emboss"/>
<xsd:enumeration value="perspective"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_StrokeLineStyle">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="single"/>
<xsd:enumeration value="thinThin"/>
<xsd:enumeration value="thinThick"/>
<xsd:enumeration value="thickThin"/>
<xsd:enumeration value="thickBetweenThin"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_StrokeJoinStyle">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="round"/>
<xsd:enumeration value="bevel"/>
<xsd:enumeration value="miter"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_StrokeEndCap">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="flat"/>
<xsd:enumeration value="square"/>
<xsd:enumeration value="round"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_StrokeArrowLength">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="short"/>
<xsd:enumeration value="medium"/>
<xsd:enumeration value="long"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_StrokeArrowWidth">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="narrow"/>
<xsd:enumeration value="medium"/>
<xsd:enumeration value="wide"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_StrokeArrowType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="none"/>
<xsd:enumeration value="block"/>
<xsd:enumeration value="classic"/>
<xsd:enumeration value="oval"/>
<xsd:enumeration value="diamond"/>
<xsd:enumeration value="open"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ImageAspect">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ignore"/>
<xsd:enumeration value="atMost"/>
<xsd:enumeration value="atLeast"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_EditAs">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="canvas"/>
<xsd:enumeration value="orgchart"/>
<xsd:enumeration value="radial"/>
<xsd:enumeration value="cycle"/>
<xsd:enumeration value="stacked"/>
<xsd:enumeration value="venn"/>
<xsd:enumeration value="bullseye"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@@ -0,0 +1,509 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
targetNamespace="urn:schemas-microsoft-com:office:office" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="urn:schemas-microsoft-com:vml" schemaLocation="vml-main.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
schemaLocation="shared-relationshipReference.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
schemaLocation="shared-commonSimpleTypes.xsd"/>
<xsd:attribute name="bwmode" type="ST_BWMode"/>
<xsd:attribute name="bwpure" type="ST_BWMode"/>
<xsd:attribute name="bwnormal" type="ST_BWMode"/>
<xsd:attribute name="targetscreensize" type="ST_ScreenSize"/>
<xsd:attribute name="insetmode" type="ST_InsetMode" default="custom"/>
<xsd:attribute name="spt" type="xsd:float"/>
<xsd:attribute name="wrapcoords" type="xsd:string"/>
<xsd:attribute name="oned" type="s:ST_TrueFalse"/>
<xsd:attribute name="regroupid" type="xsd:integer"/>
<xsd:attribute name="doubleclicknotify" type="s:ST_TrueFalse"/>
<xsd:attribute name="connectortype" type="ST_ConnectorType" default="straight"/>
<xsd:attribute name="button" type="s:ST_TrueFalse"/>
<xsd:attribute name="userhidden" type="s:ST_TrueFalse"/>
<xsd:attribute name="forcedash" type="s:ST_TrueFalse"/>
<xsd:attribute name="oleicon" type="s:ST_TrueFalse"/>
<xsd:attribute name="ole" type="s:ST_TrueFalseBlank"/>
<xsd:attribute name="preferrelative" type="s:ST_TrueFalse"/>
<xsd:attribute name="cliptowrap" type="s:ST_TrueFalse"/>
<xsd:attribute name="clip" type="s:ST_TrueFalse"/>
<xsd:attribute name="bullet" type="s:ST_TrueFalse"/>
<xsd:attribute name="hr" type="s:ST_TrueFalse"/>
<xsd:attribute name="hrstd" type="s:ST_TrueFalse"/>
<xsd:attribute name="hrnoshade" type="s:ST_TrueFalse"/>
<xsd:attribute name="hrpct" type="xsd:float"/>
<xsd:attribute name="hralign" type="ST_HrAlign" default="left"/>
<xsd:attribute name="allowincell" type="s:ST_TrueFalse"/>
<xsd:attribute name="allowoverlap" type="s:ST_TrueFalse"/>
<xsd:attribute name="userdrawn" type="s:ST_TrueFalse"/>
<xsd:attribute name="bordertopcolor" type="xsd:string"/>
<xsd:attribute name="borderleftcolor" type="xsd:string"/>
<xsd:attribute name="borderbottomcolor" type="xsd:string"/>
<xsd:attribute name="borderrightcolor" type="xsd:string"/>
<xsd:attribute name="connecttype" type="ST_ConnectType"/>
<xsd:attribute name="connectlocs" type="xsd:string"/>
<xsd:attribute name="connectangles" type="xsd:string"/>
<xsd:attribute name="master" type="xsd:string"/>
<xsd:attribute name="extrusionok" type="s:ST_TrueFalse"/>
<xsd:attribute name="href" type="xsd:string"/>
<xsd:attribute name="althref" type="xsd:string"/>
<xsd:attribute name="title" type="xsd:string"/>
<xsd:attribute name="singleclick" type="s:ST_TrueFalse"/>
<xsd:attribute name="oleid" type="xsd:float"/>
<xsd:attribute name="detectmouseclick" type="s:ST_TrueFalse"/>
<xsd:attribute name="movie" type="xsd:float"/>
<xsd:attribute name="spid" type="xsd:string"/>
<xsd:attribute name="opacity2" type="xsd:string"/>
<xsd:attribute name="relid" type="r:ST_RelationshipId"/>
<xsd:attribute name="dgmlayout" type="ST_DiagramLayout"/>
<xsd:attribute name="dgmnodekind" type="xsd:integer"/>
<xsd:attribute name="dgmlayoutmru" type="ST_DiagramLayout"/>
<xsd:attribute name="gfxdata" type="xsd:base64Binary"/>
<xsd:attribute name="tableproperties" type="xsd:string"/>
<xsd:attribute name="tablelimits" type="xsd:string"/>
<xsd:element name="shapedefaults" type="CT_ShapeDefaults"/>
<xsd:element name="shapelayout" type="CT_ShapeLayout"/>
<xsd:element name="signatureline" type="CT_SignatureLine"/>
<xsd:element name="ink" type="CT_Ink"/>
<xsd:element name="diagram" type="CT_Diagram"/>
<xsd:element name="equationxml" type="CT_EquationXml"/>
<xsd:complexType name="CT_ShapeDefaults">
<xsd:all minOccurs="0">
<xsd:element ref="v:fill" minOccurs="0"/>
<xsd:element ref="v:stroke" minOccurs="0"/>
<xsd:element ref="v:textbox" minOccurs="0"/>
<xsd:element ref="v:shadow" minOccurs="0"/>
<xsd:element ref="skew" minOccurs="0"/>
<xsd:element ref="extrusion" minOccurs="0"/>
<xsd:element ref="callout" minOccurs="0"/>
<xsd:element ref="lock" minOccurs="0"/>
<xsd:element name="colormru" minOccurs="0" type="CT_ColorMru"/>
<xsd:element name="colormenu" minOccurs="0" type="CT_ColorMenu"/>
</xsd:all>
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="spidmax" type="xsd:integer" use="optional"/>
<xsd:attribute name="style" type="xsd:string" use="optional"/>
<xsd:attribute name="fill" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="fillcolor" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="stroke" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="strokecolor" type="s:ST_ColorType"/>
<xsd:attribute name="allowincell" form="qualified" type="s:ST_TrueFalse"/>
</xsd:complexType>
<xsd:complexType name="CT_Ink">
<xsd:sequence/>
<xsd:attribute name="i" type="xsd:string"/>
<xsd:attribute name="annotation" type="s:ST_TrueFalse"/>
<xsd:attribute name="contentType" type="ST_ContentType" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_SignatureLine">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="issignatureline" type="s:ST_TrueFalse"/>
<xsd:attribute name="id" type="s:ST_Guid"/>
<xsd:attribute name="provid" type="s:ST_Guid"/>
<xsd:attribute name="signinginstructionsset" type="s:ST_TrueFalse"/>
<xsd:attribute name="allowcomments" type="s:ST_TrueFalse"/>
<xsd:attribute name="showsigndate" type="s:ST_TrueFalse"/>
<xsd:attribute name="suggestedsigner" type="xsd:string" form="qualified"/>
<xsd:attribute name="suggestedsigner2" type="xsd:string" form="qualified"/>
<xsd:attribute name="suggestedsigneremail" type="xsd:string" form="qualified"/>
<xsd:attribute name="signinginstructions" type="xsd:string"/>
<xsd:attribute name="addlxml" type="xsd:string"/>
<xsd:attribute name="sigprovurl" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="CT_ShapeLayout">
<xsd:all>
<xsd:element name="idmap" type="CT_IdMap" minOccurs="0"/>
<xsd:element name="regrouptable" type="CT_RegroupTable" minOccurs="0"/>
<xsd:element name="rules" type="CT_Rules" minOccurs="0"/>
</xsd:all>
<xsd:attributeGroup ref="v:AG_Ext"/>
</xsd:complexType>
<xsd:complexType name="CT_IdMap">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="data" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_RegroupTable">
<xsd:sequence>
<xsd:element name="entry" type="CT_Entry" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="v:AG_Ext"/>
</xsd:complexType>
<xsd:complexType name="CT_Entry">
<xsd:attribute name="new" type="xsd:int" use="optional"/>
<xsd:attribute name="old" type="xsd:int" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Rules">
<xsd:sequence>
<xsd:element name="r" type="CT_R" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="v:AG_Ext"/>
</xsd:complexType>
<xsd:complexType name="CT_R">
<xsd:sequence>
<xsd:element name="proxy" type="CT_Proxy" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="type" type="ST_RType" use="optional"/>
<xsd:attribute name="how" type="ST_How" use="optional"/>
<xsd:attribute name="idref" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Proxy">
<xsd:attribute name="start" type="s:ST_TrueFalseBlank" use="optional" default="false"/>
<xsd:attribute name="end" type="s:ST_TrueFalseBlank" use="optional" default="false"/>
<xsd:attribute name="idref" type="xsd:string" use="optional"/>
<xsd:attribute name="connectloc" type="xsd:int" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Diagram">
<xsd:sequence>
<xsd:element name="relationtable" type="CT_RelationTable" minOccurs="0"/>
</xsd:sequence>
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="dgmstyle" type="xsd:integer" use="optional"/>
<xsd:attribute name="autoformat" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="reverse" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="autolayout" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="dgmscalex" type="xsd:integer" use="optional"/>
<xsd:attribute name="dgmscaley" type="xsd:integer" use="optional"/>
<xsd:attribute name="dgmfontsize" type="xsd:integer" use="optional"/>
<xsd:attribute name="constrainbounds" type="xsd:string" use="optional"/>
<xsd:attribute name="dgmbasetextscale" type="xsd:integer" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_EquationXml">
<xsd:sequence>
<xsd:any namespace="##any"/>
</xsd:sequence>
<xsd:attribute name="contentType" type="ST_AlternateMathContentType" use="optional"/>
</xsd:complexType>
<xsd:simpleType name="ST_AlternateMathContentType">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:complexType name="CT_RelationTable">
<xsd:sequence>
<xsd:element name="rel" type="CT_Relation" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="v:AG_Ext"/>
</xsd:complexType>
<xsd:complexType name="CT_Relation">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="idsrc" type="xsd:string" use="optional"/>
<xsd:attribute name="iddest" type="xsd:string" use="optional"/>
<xsd:attribute name="idcntr" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_ColorMru">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="colors" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="CT_ColorMenu">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="strokecolor" type="s:ST_ColorType"/>
<xsd:attribute name="fillcolor" type="s:ST_ColorType"/>
<xsd:attribute name="shadowcolor" type="s:ST_ColorType"/>
<xsd:attribute name="extrusioncolor" type="s:ST_ColorType"/>
</xsd:complexType>
<xsd:element name="skew" type="CT_Skew"/>
<xsd:element name="extrusion" type="CT_Extrusion"/>
<xsd:element name="callout" type="CT_Callout"/>
<xsd:element name="lock" type="CT_Lock"/>
<xsd:element name="OLEObject" type="CT_OLEObject"/>
<xsd:element name="complex" type="CT_Complex"/>
<xsd:element name="left" type="CT_StrokeChild"/>
<xsd:element name="top" type="CT_StrokeChild"/>
<xsd:element name="right" type="CT_StrokeChild"/>
<xsd:element name="bottom" type="CT_StrokeChild"/>
<xsd:element name="column" type="CT_StrokeChild"/>
<xsd:element name="clippath" type="CT_ClipPath"/>
<xsd:element name="fill" type="CT_Fill"/>
<xsd:complexType name="CT_Skew">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="id" type="xsd:string" use="optional"/>
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="offset" type="xsd:string" use="optional"/>
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
<xsd:attribute name="matrix" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Extrusion">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="type" type="ST_ExtrusionType" default="parallel" use="optional"/>
<xsd:attribute name="render" type="ST_ExtrusionRender" default="solid" use="optional"/>
<xsd:attribute name="viewpointorigin" type="xsd:string" use="optional"/>
<xsd:attribute name="viewpoint" type="xsd:string" use="optional"/>
<xsd:attribute name="plane" type="ST_ExtrusionPlane" default="XY" use="optional"/>
<xsd:attribute name="skewangle" type="xsd:float" use="optional"/>
<xsd:attribute name="skewamt" type="xsd:string" use="optional"/>
<xsd:attribute name="foredepth" type="xsd:string" use="optional"/>
<xsd:attribute name="backdepth" type="xsd:string" use="optional"/>
<xsd:attribute name="orientation" type="xsd:string" use="optional"/>
<xsd:attribute name="orientationangle" type="xsd:float" use="optional"/>
<xsd:attribute name="lockrotationcenter" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="autorotationcenter" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="rotationcenter" type="xsd:string" use="optional"/>
<xsd:attribute name="rotationangle" type="xsd:string" use="optional"/>
<xsd:attribute name="colormode" type="ST_ColorMode" use="optional"/>
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="shininess" type="xsd:float" use="optional"/>
<xsd:attribute name="specularity" type="xsd:string" use="optional"/>
<xsd:attribute name="diffusity" type="xsd:string" use="optional"/>
<xsd:attribute name="metal" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="edge" type="xsd:string" use="optional"/>
<xsd:attribute name="facet" type="xsd:string" use="optional"/>
<xsd:attribute name="lightface" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="brightness" type="xsd:string" use="optional"/>
<xsd:attribute name="lightposition" type="xsd:string" use="optional"/>
<xsd:attribute name="lightlevel" type="xsd:string" use="optional"/>
<xsd:attribute name="lightharsh" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="lightposition2" type="xsd:string" use="optional"/>
<xsd:attribute name="lightlevel2" type="xsd:string" use="optional"/>
<xsd:attribute name="lightharsh2" type="s:ST_TrueFalse" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Callout">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="type" type="xsd:string" use="optional"/>
<xsd:attribute name="gap" type="xsd:string" use="optional"/>
<xsd:attribute name="angle" type="ST_Angle" use="optional"/>
<xsd:attribute name="dropauto" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="drop" type="ST_CalloutDrop" use="optional"/>
<xsd:attribute name="distance" type="xsd:string" use="optional"/>
<xsd:attribute name="lengthspecified" type="s:ST_TrueFalse" default="f" use="optional"/>
<xsd:attribute name="length" type="xsd:string" use="optional"/>
<xsd:attribute name="accentbar" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="textborder" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="minusx" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="minusy" type="s:ST_TrueFalse" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Lock">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="position" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="selection" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="grouping" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="ungrouping" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="rotation" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="cropping" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="verticies" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="adjusthandles" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="text" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="aspectratio" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="shapetype" type="s:ST_TrueFalse" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_OLEObject">
<xsd:sequence>
<xsd:element name="LinkType" type="ST_OLELinkType" minOccurs="0"/>
<xsd:element name="LockedField" type="s:ST_TrueFalseBlank" minOccurs="0"/>
<xsd:element name="FieldCodes" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="Type" type="ST_OLEType" use="optional"/>
<xsd:attribute name="ProgID" type="xsd:string" use="optional"/>
<xsd:attribute name="ShapeID" type="xsd:string" use="optional"/>
<xsd:attribute name="DrawAspect" type="ST_OLEDrawAspect" use="optional"/>
<xsd:attribute name="ObjectID" type="xsd:string" use="optional"/>
<xsd:attribute ref="r:id" use="optional"/>
<xsd:attribute name="UpdateMode" type="ST_OLEUpdateMode" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_Complex">
<xsd:attributeGroup ref="v:AG_Ext"/>
</xsd:complexType>
<xsd:complexType name="CT_StrokeChild">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="weight" type="xsd:string" use="optional"/>
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
<xsd:attribute name="linestyle" type="v:ST_StrokeLineStyle" use="optional"/>
<xsd:attribute name="miterlimit" type="xsd:decimal" use="optional"/>
<xsd:attribute name="joinstyle" type="v:ST_StrokeJoinStyle" use="optional"/>
<xsd:attribute name="endcap" type="v:ST_StrokeEndCap" use="optional"/>
<xsd:attribute name="dashstyle" type="xsd:string" use="optional"/>
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="filltype" type="v:ST_FillType" use="optional"/>
<xsd:attribute name="src" type="xsd:string" use="optional"/>
<xsd:attribute name="imageaspect" type="v:ST_ImageAspect" use="optional"/>
<xsd:attribute name="imagesize" type="xsd:string" use="optional"/>
<xsd:attribute name="imagealignshape" type="s:ST_TrueFalse" use="optional"/>
<xsd:attribute name="startarrow" type="v:ST_StrokeArrowType" use="optional"/>
<xsd:attribute name="startarrowwidth" type="v:ST_StrokeArrowWidth" use="optional"/>
<xsd:attribute name="startarrowlength" type="v:ST_StrokeArrowLength" use="optional"/>
<xsd:attribute name="endarrow" type="v:ST_StrokeArrowType" use="optional"/>
<xsd:attribute name="endarrowwidth" type="v:ST_StrokeArrowWidth" use="optional"/>
<xsd:attribute name="endarrowlength" type="v:ST_StrokeArrowLength" use="optional"/>
<xsd:attribute ref="href"/>
<xsd:attribute ref="althref"/>
<xsd:attribute ref="title"/>
<xsd:attribute ref="forcedash"/>
</xsd:complexType>
<xsd:complexType name="CT_ClipPath">
<xsd:attribute name="v" type="xsd:string" use="required" form="qualified"/>
</xsd:complexType>
<xsd:complexType name="CT_Fill">
<xsd:attributeGroup ref="v:AG_Ext"/>
<xsd:attribute name="type" type="ST_FillType"/>
</xsd:complexType>
<xsd:simpleType name="ST_RType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="arc"/>
<xsd:enumeration value="callout"/>
<xsd:enumeration value="connector"/>
<xsd:enumeration value="align"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_How">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="top"/>
<xsd:enumeration value="middle"/>
<xsd:enumeration value="bottom"/>
<xsd:enumeration value="left"/>
<xsd:enumeration value="center"/>
<xsd:enumeration value="right"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_BWMode">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="color"/>
<xsd:enumeration value="auto"/>
<xsd:enumeration value="grayScale"/>
<xsd:enumeration value="lightGrayscale"/>
<xsd:enumeration value="inverseGray"/>
<xsd:enumeration value="grayOutline"/>
<xsd:enumeration value="highContrast"/>
<xsd:enumeration value="black"/>
<xsd:enumeration value="white"/>
<xsd:enumeration value="hide"/>
<xsd:enumeration value="undrawn"/>
<xsd:enumeration value="blackTextAndLines"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ScreenSize">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="544,376"/>
<xsd:enumeration value="640,480"/>
<xsd:enumeration value="720,512"/>
<xsd:enumeration value="800,600"/>
<xsd:enumeration value="1024,768"/>
<xsd:enumeration value="1152,862"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_InsetMode">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="auto"/>
<xsd:enumeration value="custom"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ColorMode">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="auto"/>
<xsd:enumeration value="custom"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ContentType">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="ST_DiagramLayout">
<xsd:restriction base="xsd:integer">
<xsd:enumeration value="0"/>
<xsd:enumeration value="1"/>
<xsd:enumeration value="2"/>
<xsd:enumeration value="3"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ExtrusionType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="perspective"/>
<xsd:enumeration value="parallel"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ExtrusionRender">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="solid"/>
<xsd:enumeration value="wireFrame"/>
<xsd:enumeration value="boundingCube"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ExtrusionPlane">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="XY"/>
<xsd:enumeration value="ZX"/>
<xsd:enumeration value="YZ"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_Angle">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="any"/>
<xsd:enumeration value="30"/>
<xsd:enumeration value="45"/>
<xsd:enumeration value="60"/>
<xsd:enumeration value="90"/>
<xsd:enumeration value="auto"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_CalloutDrop">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="ST_CalloutPlacement">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="top"/>
<xsd:enumeration value="center"/>
<xsd:enumeration value="bottom"/>
<xsd:enumeration value="user"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ConnectorType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="none"/>
<xsd:enumeration value="straight"/>
<xsd:enumeration value="elbow"/>
<xsd:enumeration value="curved"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_HrAlign">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="left"/>
<xsd:enumeration value="right"/>
<xsd:enumeration value="center"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_ConnectType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="none"/>
<xsd:enumeration value="rect"/>
<xsd:enumeration value="segments"/>
<xsd:enumeration value="custom"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_OLELinkType">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="ST_OLEType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Embed"/>
<xsd:enumeration value="Link"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_OLEDrawAspect">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Content"/>
<xsd:enumeration value="Icon"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_OLEUpdateMode">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Always"/>
<xsd:enumeration value="OnCall"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_FillType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="gradientCenter"/>
<xsd:enumeration value="solid"/>
<xsd:enumeration value="pattern"/>
<xsd:enumeration value="tile"/>
<xsd:enumeration value="frame"/>
<xsd:enumeration value="gradientUnscaled"/>
<xsd:enumeration value="gradientRadial"/>
<xsd:enumeration value="gradient"/>
<xsd:enumeration value="background"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:schemas-microsoft-com:office:powerpoint"
targetNamespace="urn:schemas-microsoft-com:office:powerpoint" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:element name="iscomment" type="CT_Empty"/>
<xsd:element name="textdata" type="CT_Rel"/>
<xsd:complexType name="CT_Empty"/>
<xsd:complexType name="CT_Rel">
<xsd:attribute name="id" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:schemas-microsoft-com:office:excel"
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
targetNamespace="urn:schemas-microsoft-com:office:excel" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
schemaLocation="shared-commonSimpleTypes.xsd"/>
<xsd:element name="ClientData" type="CT_ClientData"/>
<xsd:complexType name="CT_ClientData">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="MoveWithCells" type="s:ST_TrueFalseBlank"/>
<xsd:element name="SizeWithCells" type="s:ST_TrueFalseBlank"/>
<xsd:element name="Anchor" type="xsd:string"/>
<xsd:element name="Locked" type="s:ST_TrueFalseBlank"/>
<xsd:element name="DefaultSize" type="s:ST_TrueFalseBlank"/>
<xsd:element name="PrintObject" type="s:ST_TrueFalseBlank"/>
<xsd:element name="Disabled" type="s:ST_TrueFalseBlank"/>
<xsd:element name="AutoFill" type="s:ST_TrueFalseBlank"/>
<xsd:element name="AutoLine" type="s:ST_TrueFalseBlank"/>
<xsd:element name="AutoPict" type="s:ST_TrueFalseBlank"/>
<xsd:element name="FmlaMacro" type="xsd:string"/>
<xsd:element name="TextHAlign" type="xsd:string"/>
<xsd:element name="TextVAlign" type="xsd:string"/>
<xsd:element name="LockText" type="s:ST_TrueFalseBlank"/>
<xsd:element name="JustLastX" type="s:ST_TrueFalseBlank"/>
<xsd:element name="SecretEdit" type="s:ST_TrueFalseBlank"/>
<xsd:element name="Default" type="s:ST_TrueFalseBlank"/>
<xsd:element name="Help" type="s:ST_TrueFalseBlank"/>
<xsd:element name="Cancel" type="s:ST_TrueFalseBlank"/>
<xsd:element name="Dismiss" type="s:ST_TrueFalseBlank"/>
<xsd:element name="Accel" type="xsd:integer"/>
<xsd:element name="Accel2" type="xsd:integer"/>
<xsd:element name="Row" type="xsd:integer"/>
<xsd:element name="Column" type="xsd:integer"/>
<xsd:element name="Visible" type="s:ST_TrueFalseBlank"/>
<xsd:element name="RowHidden" type="s:ST_TrueFalseBlank"/>
<xsd:element name="ColHidden" type="s:ST_TrueFalseBlank"/>
<xsd:element name="VTEdit" type="xsd:integer"/>
<xsd:element name="MultiLine" type="s:ST_TrueFalseBlank"/>
<xsd:element name="VScroll" type="s:ST_TrueFalseBlank"/>
<xsd:element name="ValidIds" type="s:ST_TrueFalseBlank"/>
<xsd:element name="FmlaRange" type="xsd:string"/>
<xsd:element name="WidthMin" type="xsd:integer"/>
<xsd:element name="Sel" type="xsd:integer"/>
<xsd:element name="NoThreeD2" type="s:ST_TrueFalseBlank"/>
<xsd:element name="SelType" type="xsd:string"/>
<xsd:element name="MultiSel" type="xsd:string"/>
<xsd:element name="LCT" type="xsd:string"/>
<xsd:element name="ListItem" type="xsd:string"/>
<xsd:element name="DropStyle" type="xsd:string"/>
<xsd:element name="Colored" type="s:ST_TrueFalseBlank"/>
<xsd:element name="DropLines" type="xsd:integer"/>
<xsd:element name="Checked" type="xsd:integer"/>
<xsd:element name="FmlaLink" type="xsd:string"/>
<xsd:element name="FmlaPict" type="xsd:string"/>
<xsd:element name="NoThreeD" type="s:ST_TrueFalseBlank"/>
<xsd:element name="FirstButton" type="s:ST_TrueFalseBlank"/>
<xsd:element name="FmlaGroup" type="xsd:string"/>
<xsd:element name="Val" type="xsd:integer"/>
<xsd:element name="Min" type="xsd:integer"/>
<xsd:element name="Max" type="xsd:integer"/>
<xsd:element name="Inc" type="xsd:integer"/>
<xsd:element name="Page" type="xsd:integer"/>
<xsd:element name="Horiz" type="s:ST_TrueFalseBlank"/>
<xsd:element name="Dx" type="xsd:integer"/>
<xsd:element name="MapOCX" type="s:ST_TrueFalseBlank"/>
<xsd:element name="CF" type="ST_CF"/>
<xsd:element name="Camera" type="s:ST_TrueFalseBlank"/>
<xsd:element name="RecalcAlways" type="s:ST_TrueFalseBlank"/>
<xsd:element name="AutoScale" type="s:ST_TrueFalseBlank"/>
<xsd:element name="DDE" type="s:ST_TrueFalseBlank"/>
<xsd:element name="UIObj" type="s:ST_TrueFalseBlank"/>
<xsd:element name="ScriptText" type="xsd:string"/>
<xsd:element name="ScriptExtended" type="xsd:string"/>
<xsd:element name="ScriptLanguage" type="xsd:nonNegativeInteger"/>
<xsd:element name="ScriptLocation" type="xsd:nonNegativeInteger"/>
<xsd:element name="FmlaTxbx" type="xsd:string"/>
</xsd:choice>
<xsd:attribute name="ObjectType" type="ST_ObjectType" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_CF">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="ST_ObjectType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Button"/>
<xsd:enumeration value="Checkbox"/>
<xsd:enumeration value="Dialog"/>
<xsd:enumeration value="Drop"/>
<xsd:enumeration value="Edit"/>
<xsd:enumeration value="GBox"/>
<xsd:enumeration value="Label"/>
<xsd:enumeration value="LineA"/>
<xsd:enumeration value="List"/>
<xsd:enumeration value="Movie"/>
<xsd:enumeration value="Note"/>
<xsd:enumeration value="Pict"/>
<xsd:enumeration value="Radio"/>
<xsd:enumeration value="RectA"/>
<xsd:enumeration value="Scroll"/>
<xsd:enumeration value="Spin"/>
<xsd:enumeration value="Shape"/>
<xsd:enumeration value="Group"/>
<xsd:enumeration value="Rect"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:schemas-microsoft-com:office:word"
targetNamespace="urn:schemas-microsoft-com:office:word" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:element name="bordertop" type="CT_Border"/>
<xsd:element name="borderleft" type="CT_Border"/>
<xsd:element name="borderright" type="CT_Border"/>
<xsd:element name="borderbottom" type="CT_Border"/>
<xsd:complexType name="CT_Border">
<xsd:attribute name="type" type="ST_BorderType" use="optional"/>
<xsd:attribute name="width" type="xsd:positiveInteger" use="optional"/>
<xsd:attribute name="shadow" type="ST_BorderShadow" use="optional"/>
</xsd:complexType>
<xsd:element name="wrap" type="CT_Wrap"/>
<xsd:complexType name="CT_Wrap">
<xsd:attribute name="type" type="ST_WrapType" use="optional"/>
<xsd:attribute name="side" type="ST_WrapSide" use="optional"/>
<xsd:attribute name="anchorx" type="ST_HorizontalAnchor" use="optional"/>
<xsd:attribute name="anchory" type="ST_VerticalAnchor" use="optional"/>
</xsd:complexType>
<xsd:element name="anchorlock" type="CT_AnchorLock"/>
<xsd:complexType name="CT_AnchorLock"/>
<xsd:simpleType name="ST_BorderType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="none"/>
<xsd:enumeration value="single"/>
<xsd:enumeration value="thick"/>
<xsd:enumeration value="double"/>
<xsd:enumeration value="hairline"/>
<xsd:enumeration value="dot"/>
<xsd:enumeration value="dash"/>
<xsd:enumeration value="dotDash"/>
<xsd:enumeration value="dashDotDot"/>
<xsd:enumeration value="triple"/>
<xsd:enumeration value="thinThickSmall"/>
<xsd:enumeration value="thickThinSmall"/>
<xsd:enumeration value="thickBetweenThinSmall"/>
<xsd:enumeration value="thinThick"/>
<xsd:enumeration value="thickThin"/>
<xsd:enumeration value="thickBetweenThin"/>
<xsd:enumeration value="thinThickLarge"/>
<xsd:enumeration value="thickThinLarge"/>
<xsd:enumeration value="thickBetweenThinLarge"/>
<xsd:enumeration value="wave"/>
<xsd:enumeration value="doubleWave"/>
<xsd:enumeration value="dashedSmall"/>
<xsd:enumeration value="dashDotStroked"/>
<xsd:enumeration value="threeDEmboss"/>
<xsd:enumeration value="threeDEngrave"/>
<xsd:enumeration value="HTMLOutset"/>
<xsd:enumeration value="HTMLInset"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_BorderShadow">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="t"/>
<xsd:enumeration value="true"/>
<xsd:enumeration value="f"/>
<xsd:enumeration value="false"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_WrapType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="topAndBottom"/>
<xsd:enumeration value="square"/>
<xsd:enumeration value="none"/>
<xsd:enumeration value="tight"/>
<xsd:enumeration value="through"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_WrapSide">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="both"/>
<xsd:enumeration value="left"/>
<xsd:enumeration value="right"/>
<xsd:enumeration value="largest"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_HorizontalAnchor">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="margin"/>
<xsd:enumeration value="page"/>
<xsd:enumeration value="text"/>
<xsd:enumeration value="char"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_VerticalAnchor">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="margin"/>
<xsd:enumeration value="page"/>
<xsd:enumeration value="text"/>
<xsd:enumeration value="line"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,116 @@
<?xml version='1.0'?>
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
<xs:annotation>
<xs:documentation>
See http://www.w3.org/XML/1998/namespace.html and
http://www.w3.org/TR/REC-xml for information about this namespace.
This schema document describes the XML namespace, in a form
suitable for import by other schema documents.
Note that local names in this namespace are intended to be defined
only by the World Wide Web Consortium or its subgroups. The
following names are currently defined in this namespace and should
not be used with conflicting semantics by any Working Group,
specification, or document instance:
base (as an attribute name): denotes an attribute whose value
provides a URI to be used as the base for interpreting any
relative URIs in the scope of the element on which it
appears; its value is inherited. This name is reserved
by virtue of its definition in the XML Base specification.
lang (as an attribute name): denotes an attribute whose value
is a language code for the natural language of the content of
any element; its value is inherited. This name is reserved
by virtue of its definition in the XML specification.
space (as an attribute name): denotes an attribute whose
value is a keyword indicating what whitespace processing
discipline is intended for the content of the element; its
value is inherited. This name is reserved by virtue of its
definition in the XML specification.
Father (in any context at all): denotes Jon Bosak, the chair of
the original XML Working Group. This name is reserved by
the following decision of the W3C XML Plenary and
XML Coordination groups:
In appreciation for his vision, leadership and dedication
the W3C XML Plenary on this 10th day of February, 2000
reserves for Jon Bosak in perpetuity the XML name
xml:Father
</xs:documentation>
</xs:annotation>
<xs:annotation>
<xs:documentation>This schema defines attributes and an attribute group
suitable for use by
schemas wishing to allow xml:base, xml:lang or xml:space attributes
on elements they define.
To enable this, such a schema must import this schema
for the XML namespace, e.g. as follows:
&lt;schema . . .>
. . .
&lt;import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
Subsequently, qualified reference to any of the attributes
or the group defined below will have the desired effect, e.g.
&lt;type . . .>
. . .
&lt;attributeGroup ref="xml:specialAttrs"/>
will define a type which will schema-validate an instance
element with any of those attributes</xs:documentation>
</xs:annotation>
<xs:annotation>
<xs:documentation>In keeping with the XML Schema WG's standard versioning
policy, this schema document will persist at
http://www.w3.org/2001/03/xml.xsd.
At the date of issue it can also be found at
http://www.w3.org/2001/xml.xsd.
The schema document at that URI may however change in the future,
in order to remain compatible with the latest version of XML Schema
itself. In other words, if the XML Schema namespace changes, the version
of this document at
http://www.w3.org/2001/xml.xsd will change
accordingly; the version at
http://www.w3.org/2001/03/xml.xsd will not change.
</xs:documentation>
</xs:annotation>
<xs:attribute name="lang" type="xs:language">
<xs:annotation>
<xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter
codes as the enumerated possible values . . .</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="space" default="preserve">
<xs:simpleType>
<xs:restriction base="xs:NCName">
<xs:enumeration value="default"/>
<xs:enumeration value="preserve"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="base" type="xs:anyURI">
<xs:annotation>
<xs:documentation>See http://www.w3.org/TR/xmlbase/ for
information about this attribute.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attributeGroup name="specialAttrs">
<xs:attribute ref="xml:base"/>
<xs:attribute ref="xml:lang"/>
<xs:attribute ref="xml:space"/>
</xs:attributeGroup>
</xs:schema>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns="http://schemas.openxmlformats.org/package/2006/content-types"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.openxmlformats.org/package/2006/content-types"
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
<xs:element name="Types" type="CT_Types"/>
<xs:element name="Default" type="CT_Default"/>
<xs:element name="Override" type="CT_Override"/>
<xs:complexType name="CT_Types">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Default"/>
<xs:element ref="Override"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="CT_Default">
<xs:attribute name="Extension" type="ST_Extension" use="required"/>
<xs:attribute name="ContentType" type="ST_ContentType" use="required"/>
</xs:complexType>
<xs:complexType name="CT_Override">
<xs:attribute name="ContentType" type="ST_ContentType" use="required"/>
<xs:attribute name="PartName" type="xs:anyURI" use="required"/>
</xs:complexType>
<xs:simpleType name="ST_ContentType">
<xs:restriction base="xs:string">
<xs:pattern
value="(((([\p{IsBasicLatin}-[\p{Cc}&#127;\(\)&lt;&gt;@,;:\\&quot;/\[\]\?=\{\}\s\t]])+))/((([\p{IsBasicLatin}-[\p{Cc}&#127;\(\)&lt;&gt;@,;:\\&quot;/\[\]\?=\{\}\s\t]])+))((\s+)*;(\s+)*(((([\p{IsBasicLatin}-[\p{Cc}&#127;\(\)&lt;&gt;@,;:\\&quot;/\[\]\?=\{\}\s\t]])+))=((([\p{IsBasicLatin}-[\p{Cc}&#127;\(\)&lt;&gt;@,;:\\&quot;/\[\]\?=\{\}\s\t]])+)|(&quot;(([\p{IsLatin-1Supplement}\p{IsBasicLatin}-[\p{Cc}&#127;&quot;\n\r]]|(\s+))|(\\[\p{IsBasicLatin}]))*&quot;))))*)"
/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ST_Extension">
<xs:restriction base="xs:string">
<xs:pattern
value="([!$&amp;'\(\)\*\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:@]|[a-zA-Z0-9\-_~])+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
xmlns="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/" elementFormDefault="qualified" blockDefault="#all">
<xs:import namespace="http://purl.org/dc/elements/1.1/"
schemaLocation="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd"/>
<xs:import namespace="http://purl.org/dc/terms/"
schemaLocation="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd"/>
<xs:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"/>
<xs:element name="coreProperties" type="CT_CoreProperties"/>
<xs:complexType name="CT_CoreProperties">
<xs:all>
<xs:element name="category" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="contentStatus" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element ref="dcterms:created" minOccurs="0" maxOccurs="1"/>
<xs:element ref="dc:creator" minOccurs="0" maxOccurs="1"/>
<xs:element ref="dc:description" minOccurs="0" maxOccurs="1"/>
<xs:element ref="dc:identifier" minOccurs="0" maxOccurs="1"/>
<xs:element name="keywords" minOccurs="0" maxOccurs="1" type="CT_Keywords"/>
<xs:element ref="dc:language" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastModifiedBy" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="lastPrinted" minOccurs="0" maxOccurs="1" type="xs:dateTime"/>
<xs:element ref="dcterms:modified" minOccurs="0" maxOccurs="1"/>
<xs:element name="revision" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element ref="dc:subject" minOccurs="0" maxOccurs="1"/>
<xs:element ref="dc:title" minOccurs="0" maxOccurs="1"/>
<xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string"/>
</xs:all>
</xs:complexType>
<xs:complexType name="CT_Keywords" mixed="true">
<xs:sequence>
<xs:element name="value" minOccurs="0" maxOccurs="unbounded" type="CT_Keyword"/>
</xs:sequence>
<xs:attribute ref="xml:lang" use="optional"/>
</xs:complexType>
<xs:complexType name="CT_Keyword">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute ref="xml:lang" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://schemas.openxmlformats.org/package/2006/digital-signature"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.openxmlformats.org/package/2006/digital-signature"
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
<xsd:element name="SignatureTime" type="CT_SignatureTime"/>
<xsd:element name="RelationshipReference" type="CT_RelationshipReference"/>
<xsd:element name="RelationshipsGroupReference" type="CT_RelationshipsGroupReference"/>
<xsd:complexType name="CT_SignatureTime">
<xsd:sequence>
<xsd:element name="Format" type="ST_Format"/>
<xsd:element name="Value" type="ST_Value"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_RelationshipReference">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="SourceId" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="CT_RelationshipsGroupReference">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="SourceType" type="xsd:anyURI" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="ST_Format">
<xsd:restriction base="xsd:string">
<xsd:pattern
value="(YYYY)|(YYYY-MM)|(YYYY-MM-DD)|(YYYY-MM-DDThh:mmTZD)|(YYYY-MM-DDThh:mm:ssTZD)|(YYYY-MM-DDThh:mm:ss.sTZD)"
/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_Value">
<xsd:restriction base="xsd:string">
<xsd:pattern
value="(([0-9][0-9][0-9][0-9]))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):(((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))\.[0-9])(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))"
/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://schemas.openxmlformats.org/package/2006/relationships"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.openxmlformats.org/package/2006/relationships"
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
<xsd:element name="Relationships" type="CT_Relationships"/>
<xsd:element name="Relationship" type="CT_Relationship"/>
<xsd:complexType name="CT_Relationships">
<xsd:sequence>
<xsd:element ref="Relationship" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Relationship">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="TargetMode" type="ST_TargetMode" use="optional"/>
<xsd:attribute name="Target" type="xsd:anyURI" use="required"/>
<xsd:attribute name="Type" type="xsd:anyURI" use="required"/>
<xsd:attribute name="Id" type="xsd:ID" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="ST_TargetMode">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="External"/>
<xsd:enumeration value="Internal"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
attributeFormDefault="unqualified" elementFormDefault="qualified"
targetNamespace="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--
This XSD is a modified version of the one found at:
https://github.com/plutext/docx4j/blob/master/xsd/mce/markup-compatibility-2006-MINIMAL.xsd
This XSD has 2 objectives:
1. round tripping @mc:Ignorable
<w:document
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
mc:Ignorable="w14 w15 wp14">
2. enabling AlternateContent to be manipulated in certain elements
(in the unusual case where the content model is xsd:any, it doesn't have to be explicitly added)
See further ECMA-376, 4th Edition, Office Open XML File Formats
Part 3 : Markup Compatibility and Extensibility
-->
<!-- Objective 1 -->
<xsd:attribute name="Ignorable" type="xsd:string" />
<!-- Objective 2 -->
<xsd:attribute name="MustUnderstand" type="xsd:string" />
<xsd:attribute name="ProcessContent" type="xsd:string" />
<!-- An AlternateContent element shall contain one or more Choice child elements, optionally followed by a
Fallback child element. If present, there shall be only one Fallback element, and it shall follow all Choice
elements. -->
<xsd:element name="AlternateContent">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Choice" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded"
processContents="strict">
</xsd:any>
</xsd:sequence>
<xsd:attribute name="Requires" type="xsd:string" use="required" />
<xsd:attribute ref="mc:Ignorable" use="optional" />
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
<xsd:attribute ref="mc:ProcessContent" use="optional" />
</xsd:complexType>
</xsd:element>
<xsd:element name="Fallback" minOccurs="0" maxOccurs="1">
<xsd:complexType>
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded"
processContents="strict">
</xsd:any>
</xsd:sequence>
<xsd:attribute ref="mc:Ignorable" use="optional" />
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
<xsd:attribute ref="mc:ProcessContent" use="optional" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<!-- AlternateContent elements might include the attributes Ignorable,
MustUnderstand and ProcessContent described in this Part of ECMA-376. These
attributes qualified names shall be prefixed when associated with an AlternateContent
element. -->
<xsd:attribute ref="mc:Ignorable" use="optional" />
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
<xsd:attribute ref="mc:ProcessContent" use="optional" />
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -0,0 +1,560 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns="http://schemas.microsoft.com/office/word/2010/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2010/wordml">
<!-- <xsd:import id="rel" namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships" schemaLocation="orel.xsd"/> -->
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
<!-- <xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main" schemaLocation="oartbasetypes.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main" schemaLocation="oartsplineproperties.xsd"/> -->
<xsd:complexType name="CT_LongHexNumber">
<xsd:attribute name="val" type="w:ST_LongHexNumber" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_OnOff">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="true"/>
<xsd:enumeration value="false"/>
<xsd:enumeration value="0"/>
<xsd:enumeration value="1"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_OnOff">
<xsd:attribute name="val" type="ST_OnOff"/>
</xsd:complexType>
<xsd:element name="docId" type="CT_LongHexNumber"/>
<xsd:element name="conflictMode" type="CT_OnOff"/>
<xsd:attributeGroup name="AG_Parids">
<xsd:attribute name="paraId" type="w:ST_LongHexNumber"/>
<xsd:attribute name="textId" type="w:ST_LongHexNumber"/>
</xsd:attributeGroup>
<xsd:attribute name="anchorId" type="w:ST_LongHexNumber"/>
<xsd:attribute name="noSpellErr" type="ST_OnOff"/>
<xsd:element name="customXmlConflictInsRangeStart" type="w:CT_TrackChange"/>
<xsd:element name="customXmlConflictInsRangeEnd" type="w:CT_Markup"/>
<xsd:element name="customXmlConflictDelRangeStart" type="w:CT_TrackChange"/>
<xsd:element name="customXmlConflictDelRangeEnd" type="w:CT_Markup"/>
<xsd:group name="EG_RunLevelConflicts">
<xsd:sequence>
<xsd:element name="conflictIns" type="w:CT_RunTrackChange" minOccurs="0"/>
<xsd:element name="conflictDel" type="w:CT_RunTrackChange" minOccurs="0"/>
</xsd:sequence>
</xsd:group>
<xsd:group name="EG_Conflicts">
<xsd:choice>
<xsd:element name="conflictIns" type="w:CT_TrackChange" minOccurs="0"/>
<xsd:element name="conflictDel" type="w:CT_TrackChange" minOccurs="0"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_Percentage">
<xsd:attribute name="val" type="a:ST_Percentage" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_PositiveFixedPercentage">
<xsd:attribute name="val" type="a:ST_PositiveFixedPercentage" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_PositivePercentage">
<xsd:attribute name="val" type="a:ST_PositivePercentage" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_SchemeColorVal">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="bg1"/>
<xsd:enumeration value="tx1"/>
<xsd:enumeration value="bg2"/>
<xsd:enumeration value="tx2"/>
<xsd:enumeration value="accent1"/>
<xsd:enumeration value="accent2"/>
<xsd:enumeration value="accent3"/>
<xsd:enumeration value="accent4"/>
<xsd:enumeration value="accent5"/>
<xsd:enumeration value="accent6"/>
<xsd:enumeration value="hlink"/>
<xsd:enumeration value="folHlink"/>
<xsd:enumeration value="dk1"/>
<xsd:enumeration value="lt1"/>
<xsd:enumeration value="dk2"/>
<xsd:enumeration value="lt2"/>
<xsd:enumeration value="phClr"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_RectAlignment">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="none"/>
<xsd:enumeration value="tl"/>
<xsd:enumeration value="t"/>
<xsd:enumeration value="tr"/>
<xsd:enumeration value="l"/>
<xsd:enumeration value="ctr"/>
<xsd:enumeration value="r"/>
<xsd:enumeration value="bl"/>
<xsd:enumeration value="b"/>
<xsd:enumeration value="br"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_PathShadeType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="shape"/>
<xsd:enumeration value="circle"/>
<xsd:enumeration value="rect"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_LineCap">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="rnd"/>
<xsd:enumeration value="sq"/>
<xsd:enumeration value="flat"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_PresetLineDashVal">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="solid"/>
<xsd:enumeration value="dot"/>
<xsd:enumeration value="sysDot"/>
<xsd:enumeration value="dash"/>
<xsd:enumeration value="sysDash"/>
<xsd:enumeration value="lgDash"/>
<xsd:enumeration value="dashDot"/>
<xsd:enumeration value="sysDashDot"/>
<xsd:enumeration value="lgDashDot"/>
<xsd:enumeration value="lgDashDotDot"/>
<xsd:enumeration value="sysDashDotDot"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_PenAlignment">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ctr"/>
<xsd:enumeration value="in"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_CompoundLine">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="sng"/>
<xsd:enumeration value="dbl"/>
<xsd:enumeration value="thickThin"/>
<xsd:enumeration value="thinThick"/>
<xsd:enumeration value="tri"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_RelativeRect">
<xsd:attribute name="l" use="optional" type="a:ST_Percentage"/>
<xsd:attribute name="t" use="optional" type="a:ST_Percentage"/>
<xsd:attribute name="r" use="optional" type="a:ST_Percentage"/>
<xsd:attribute name="b" use="optional" type="a:ST_Percentage"/>
</xsd:complexType>
<xsd:group name="EG_ColorTransform">
<xsd:choice>
<xsd:element name="tint" type="CT_PositiveFixedPercentage"/>
<xsd:element name="shade" type="CT_PositiveFixedPercentage"/>
<xsd:element name="alpha" type="CT_PositiveFixedPercentage"/>
<xsd:element name="hueMod" type="CT_PositivePercentage"/>
<xsd:element name="sat" type="CT_Percentage"/>
<xsd:element name="satOff" type="CT_Percentage"/>
<xsd:element name="satMod" type="CT_Percentage"/>
<xsd:element name="lum" type="CT_Percentage"/>
<xsd:element name="lumOff" type="CT_Percentage"/>
<xsd:element name="lumMod" type="CT_Percentage"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_SRgbColor">
<xsd:sequence>
<xsd:group ref="EG_ColorTransform" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="val" type="s:ST_HexColorRGB" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_SchemeColor">
<xsd:sequence>
<xsd:group ref="EG_ColorTransform" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="val" type="ST_SchemeColorVal" use="required"/>
</xsd:complexType>
<xsd:group name="EG_ColorChoice">
<xsd:choice>
<xsd:element name="srgbClr" type="CT_SRgbColor"/>
<xsd:element name="schemeClr" type="CT_SchemeColor"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_Color">
<xsd:sequence>
<xsd:group ref="EG_ColorChoice"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_GradientStop">
<xsd:sequence>
<xsd:group ref="EG_ColorChoice"/>
</xsd:sequence>
<xsd:attribute name="pos" type="a:ST_PositiveFixedPercentage" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_GradientStopList">
<xsd:sequence>
<xsd:element name="gs" type="CT_GradientStop" minOccurs="2" maxOccurs="10"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_LinearShadeProperties">
<xsd:attribute name="ang" type="a:ST_PositiveFixedAngle" use="optional"/>
<xsd:attribute name="scaled" type="ST_OnOff" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_PathShadeProperties">
<xsd:sequence>
<xsd:element name="fillToRect" type="CT_RelativeRect" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="path" type="ST_PathShadeType" use="optional"/>
</xsd:complexType>
<xsd:group name="EG_ShadeProperties">
<xsd:choice>
<xsd:element name="lin" type="CT_LinearShadeProperties"/>
<xsd:element name="path" type="CT_PathShadeProperties"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_SolidColorFillProperties">
<xsd:sequence>
<xsd:group ref="EG_ColorChoice" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_GradientFillProperties">
<xsd:sequence>
<xsd:element name="gsLst" type="CT_GradientStopList" minOccurs="0"/>
<xsd:group ref="EG_ShadeProperties" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:group name="EG_FillProperties">
<xsd:choice>
<xsd:element name="noFill" type="w:CT_Empty"/>
<xsd:element name="solidFill" type="CT_SolidColorFillProperties"/>
<xsd:element name="gradFill" type="CT_GradientFillProperties"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_PresetLineDashProperties">
<xsd:attribute name="val" type="ST_PresetLineDashVal" use="optional"/>
</xsd:complexType>
<xsd:group name="EG_LineDashProperties">
<xsd:choice>
<xsd:element name="prstDash" type="CT_PresetLineDashProperties"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="CT_LineJoinMiterProperties">
<xsd:attribute name="lim" type="a:ST_PositivePercentage" use="optional"/>
</xsd:complexType>
<xsd:group name="EG_LineJoinProperties">
<xsd:choice>
<xsd:element name="round" type="w:CT_Empty"/>
<xsd:element name="bevel" type="w:CT_Empty"/>
<xsd:element name="miter" type="CT_LineJoinMiterProperties"/>
</xsd:choice>
</xsd:group>
<xsd:simpleType name="ST_PresetCameraType">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="legacyObliqueTopLeft"/>
<xsd:enumeration value="legacyObliqueTop"/>
<xsd:enumeration value="legacyObliqueTopRight"/>
<xsd:enumeration value="legacyObliqueLeft"/>
<xsd:enumeration value="legacyObliqueFront"/>
<xsd:enumeration value="legacyObliqueRight"/>
<xsd:enumeration value="legacyObliqueBottomLeft"/>
<xsd:enumeration value="legacyObliqueBottom"/>
<xsd:enumeration value="legacyObliqueBottomRight"/>
<xsd:enumeration value="legacyPerspectiveTopLeft"/>
<xsd:enumeration value="legacyPerspectiveTop"/>
<xsd:enumeration value="legacyPerspectiveTopRight"/>
<xsd:enumeration value="legacyPerspectiveLeft"/>
<xsd:enumeration value="legacyPerspectiveFront"/>
<xsd:enumeration value="legacyPerspectiveRight"/>
<xsd:enumeration value="legacyPerspectiveBottomLeft"/>
<xsd:enumeration value="legacyPerspectiveBottom"/>
<xsd:enumeration value="legacyPerspectiveBottomRight"/>
<xsd:enumeration value="orthographicFront"/>
<xsd:enumeration value="isometricTopUp"/>
<xsd:enumeration value="isometricTopDown"/>
<xsd:enumeration value="isometricBottomUp"/>
<xsd:enumeration value="isometricBottomDown"/>
<xsd:enumeration value="isometricLeftUp"/>
<xsd:enumeration value="isometricLeftDown"/>
<xsd:enumeration value="isometricRightUp"/>
<xsd:enumeration value="isometricRightDown"/>
<xsd:enumeration value="isometricOffAxis1Left"/>
<xsd:enumeration value="isometricOffAxis1Right"/>
<xsd:enumeration value="isometricOffAxis1Top"/>
<xsd:enumeration value="isometricOffAxis2Left"/>
<xsd:enumeration value="isometricOffAxis2Right"/>
<xsd:enumeration value="isometricOffAxis2Top"/>
<xsd:enumeration value="isometricOffAxis3Left"/>
<xsd:enumeration value="isometricOffAxis3Right"/>
<xsd:enumeration value="isometricOffAxis3Bottom"/>
<xsd:enumeration value="isometricOffAxis4Left"/>
<xsd:enumeration value="isometricOffAxis4Right"/>
<xsd:enumeration value="isometricOffAxis4Bottom"/>
<xsd:enumeration value="obliqueTopLeft"/>
<xsd:enumeration value="obliqueTop"/>
<xsd:enumeration value="obliqueTopRight"/>
<xsd:enumeration value="obliqueLeft"/>
<xsd:enumeration value="obliqueRight"/>
<xsd:enumeration value="obliqueBottomLeft"/>
<xsd:enumeration value="obliqueBottom"/>
<xsd:enumeration value="obliqueBottomRight"/>
<xsd:enumeration value="perspectiveFront"/>
<xsd:enumeration value="perspectiveLeft"/>
<xsd:enumeration value="perspectiveRight"/>
<xsd:enumeration value="perspectiveAbove"/>
<xsd:enumeration value="perspectiveBelow"/>
<xsd:enumeration value="perspectiveAboveLeftFacing"/>
<xsd:enumeration value="perspectiveAboveRightFacing"/>
<xsd:enumeration value="perspectiveContrastingLeftFacing"/>
<xsd:enumeration value="perspectiveContrastingRightFacing"/>
<xsd:enumeration value="perspectiveHeroicLeftFacing"/>
<xsd:enumeration value="perspectiveHeroicRightFacing"/>
<xsd:enumeration value="perspectiveHeroicExtremeLeftFacing"/>
<xsd:enumeration value="perspectiveHeroicExtremeRightFacing"/>
<xsd:enumeration value="perspectiveRelaxed"/>
<xsd:enumeration value="perspectiveRelaxedModerately"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Camera">
<xsd:attribute name="prst" use="required" type="ST_PresetCameraType"/>
</xsd:complexType>
<xsd:complexType name="CT_SphereCoords">
<xsd:attribute name="lat" type="a:ST_PositiveFixedAngle" use="required"/>
<xsd:attribute name="lon" type="a:ST_PositiveFixedAngle" use="required"/>
<xsd:attribute name="rev" type="a:ST_PositiveFixedAngle" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_LightRigType">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="legacyFlat1"/>
<xsd:enumeration value="legacyFlat2"/>
<xsd:enumeration value="legacyFlat3"/>
<xsd:enumeration value="legacyFlat4"/>
<xsd:enumeration value="legacyNormal1"/>
<xsd:enumeration value="legacyNormal2"/>
<xsd:enumeration value="legacyNormal3"/>
<xsd:enumeration value="legacyNormal4"/>
<xsd:enumeration value="legacyHarsh1"/>
<xsd:enumeration value="legacyHarsh2"/>
<xsd:enumeration value="legacyHarsh3"/>
<xsd:enumeration value="legacyHarsh4"/>
<xsd:enumeration value="threePt"/>
<xsd:enumeration value="balanced"/>
<xsd:enumeration value="soft"/>
<xsd:enumeration value="harsh"/>
<xsd:enumeration value="flood"/>
<xsd:enumeration value="contrasting"/>
<xsd:enumeration value="morning"/>
<xsd:enumeration value="sunrise"/>
<xsd:enumeration value="sunset"/>
<xsd:enumeration value="chilly"/>
<xsd:enumeration value="freezing"/>
<xsd:enumeration value="flat"/>
<xsd:enumeration value="twoPt"/>
<xsd:enumeration value="glow"/>
<xsd:enumeration value="brightRoom"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ST_LightRigDirection">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="tl"/>
<xsd:enumeration value="t"/>
<xsd:enumeration value="tr"/>
<xsd:enumeration value="l"/>
<xsd:enumeration value="r"/>
<xsd:enumeration value="bl"/>
<xsd:enumeration value="b"/>
<xsd:enumeration value="br"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_LightRig">
<xsd:sequence>
<xsd:element name="rot" type="CT_SphereCoords" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="rig" type="ST_LightRigType" use="required"/>
<xsd:attribute name="dir" type="ST_LightRigDirection" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_BevelPresetType">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="relaxedInset"/>
<xsd:enumeration value="circle"/>
<xsd:enumeration value="slope"/>
<xsd:enumeration value="cross"/>
<xsd:enumeration value="angle"/>
<xsd:enumeration value="softRound"/>
<xsd:enumeration value="convex"/>
<xsd:enumeration value="coolSlant"/>
<xsd:enumeration value="divot"/>
<xsd:enumeration value="riblet"/>
<xsd:enumeration value="hardEdge"/>
<xsd:enumeration value="artDeco"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Bevel">
<xsd:attribute name="w" type="a:ST_PositiveCoordinate" use="optional"/>
<xsd:attribute name="h" type="a:ST_PositiveCoordinate" use="optional"/>
<xsd:attribute name="prst" type="ST_BevelPresetType" use="optional"/>
</xsd:complexType>
<xsd:simpleType name="ST_PresetMaterialType">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="legacyMatte"/>
<xsd:enumeration value="legacyPlastic"/>
<xsd:enumeration value="legacyMetal"/>
<xsd:enumeration value="legacyWireframe"/>
<xsd:enumeration value="matte"/>
<xsd:enumeration value="plastic"/>
<xsd:enumeration value="metal"/>
<xsd:enumeration value="warmMatte"/>
<xsd:enumeration value="translucentPowder"/>
<xsd:enumeration value="powder"/>
<xsd:enumeration value="dkEdge"/>
<xsd:enumeration value="softEdge"/>
<xsd:enumeration value="clear"/>
<xsd:enumeration value="flat"/>
<xsd:enumeration value="softmetal"/>
<xsd:enumeration value="none"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Glow">
<xsd:sequence>
<xsd:group ref="EG_ColorChoice"/>
</xsd:sequence>
<xsd:attribute name="rad" use="optional" type="a:ST_PositiveCoordinate"/>
</xsd:complexType>
<xsd:complexType name="CT_Shadow">
<xsd:sequence>
<xsd:group ref="EG_ColorChoice"/>
</xsd:sequence>
<xsd:attribute name="blurRad" use="optional" type="a:ST_PositiveCoordinate"/>
<xsd:attribute name="dist" use="optional" type="a:ST_PositiveCoordinate"/>
<xsd:attribute name="dir" use="optional" type="a:ST_PositiveFixedAngle"/>
<xsd:attribute name="sx" use="optional" type="a:ST_Percentage"/>
<xsd:attribute name="sy" use="optional" type="a:ST_Percentage"/>
<xsd:attribute name="kx" use="optional" type="a:ST_FixedAngle"/>
<xsd:attribute name="ky" use="optional" type="a:ST_FixedAngle"/>
<xsd:attribute name="algn" use="optional" type="ST_RectAlignment"/>
</xsd:complexType>
<xsd:complexType name="CT_Reflection">
<xsd:attribute name="blurRad" use="optional" type="a:ST_PositiveCoordinate"/>
<xsd:attribute name="stA" use="optional" type="a:ST_PositiveFixedPercentage"/>
<xsd:attribute name="stPos" use="optional" type="a:ST_PositiveFixedPercentage"/>
<xsd:attribute name="endA" use="optional" type="a:ST_PositiveFixedPercentage"/>
<xsd:attribute name="endPos" use="optional" type="a:ST_PositiveFixedPercentage"/>
<xsd:attribute name="dist" use="optional" type="a:ST_PositiveCoordinate"/>
<xsd:attribute name="dir" use="optional" type="a:ST_PositiveFixedAngle"/>
<xsd:attribute name="fadeDir" use="optional" type="a:ST_PositiveFixedAngle"/>
<xsd:attribute name="sx" use="optional" type="a:ST_Percentage"/>
<xsd:attribute name="sy" use="optional" type="a:ST_Percentage"/>
<xsd:attribute name="kx" use="optional" type="a:ST_FixedAngle"/>
<xsd:attribute name="ky" use="optional" type="a:ST_FixedAngle"/>
<xsd:attribute name="algn" use="optional" type="ST_RectAlignment"/>
</xsd:complexType>
<xsd:complexType name="CT_FillTextEffect">
<xsd:sequence>
<xsd:group ref="EG_FillProperties" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_TextOutlineEffect">
<xsd:sequence>
<xsd:group ref="EG_FillProperties" minOccurs="0"/>
<xsd:group ref="EG_LineDashProperties" minOccurs="0"/>
<xsd:group ref="EG_LineJoinProperties" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="w" use="optional" type="a:ST_LineWidth"/>
<xsd:attribute name="cap" use="optional" type="ST_LineCap"/>
<xsd:attribute name="cmpd" use="optional" type="ST_CompoundLine"/>
<xsd:attribute name="algn" use="optional" type="ST_PenAlignment"/>
</xsd:complexType>
<xsd:complexType name="CT_Scene3D">
<xsd:sequence>
<xsd:element name="camera" type="CT_Camera"/>
<xsd:element name="lightRig" type="CT_LightRig"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_Props3D">
<xsd:sequence>
<xsd:element name="bevelT" type="CT_Bevel" minOccurs="0"/>
<xsd:element name="bevelB" type="CT_Bevel" minOccurs="0"/>
<xsd:element name="extrusionClr" type="CT_Color" minOccurs="0"/>
<xsd:element name="contourClr" type="CT_Color" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="extrusionH" type="a:ST_PositiveCoordinate" use="optional"/>
<xsd:attribute name="contourW" type="a:ST_PositiveCoordinate" use="optional"/>
<xsd:attribute name="prstMaterial" type="ST_PresetMaterialType" use="optional"/>
</xsd:complexType>
<xsd:group name="EG_RPrTextEffects">
<xsd:sequence>
<xsd:element name="glow" minOccurs="0" type="CT_Glow"/>
<xsd:element name="shadow" minOccurs="0" type="CT_Shadow"/>
<xsd:element name="reflection" minOccurs="0" type="CT_Reflection"/>
<xsd:element name="textOutline" minOccurs="0" type="CT_TextOutlineEffect"/>
<xsd:element name="textFill" minOccurs="0" type="CT_FillTextEffect"/>
<xsd:element name="scene3d" minOccurs="0" type="CT_Scene3D"/>
<xsd:element name="props3d" minOccurs="0" type="CT_Props3D"/>
</xsd:sequence>
</xsd:group>
<xsd:simpleType name="ST_Ligatures">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="none"/>
<xsd:enumeration value="standard"/>
<xsd:enumeration value="contextual"/>
<xsd:enumeration value="historical"/>
<xsd:enumeration value="discretional"/>
<xsd:enumeration value="standardContextual"/>
<xsd:enumeration value="standardHistorical"/>
<xsd:enumeration value="contextualHistorical"/>
<xsd:enumeration value="standardDiscretional"/>
<xsd:enumeration value="contextualDiscretional"/>
<xsd:enumeration value="historicalDiscretional"/>
<xsd:enumeration value="standardContextualHistorical"/>
<xsd:enumeration value="standardContextualDiscretional"/>
<xsd:enumeration value="standardHistoricalDiscretional"/>
<xsd:enumeration value="contextualHistoricalDiscretional"/>
<xsd:enumeration value="all"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Ligatures">
<xsd:attribute name="val" type="ST_Ligatures" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_NumForm">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="default"/>
<xsd:enumeration value="lining"/>
<xsd:enumeration value="oldStyle"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_NumForm">
<xsd:attribute name="val" type="ST_NumForm" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_NumSpacing">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="default"/>
<xsd:enumeration value="proportional"/>
<xsd:enumeration value="tabular"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_NumSpacing">
<xsd:attribute name="val" type="ST_NumSpacing" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_StyleSet">
<xsd:attribute name="id" type="s:ST_UnsignedDecimalNumber" use="required"/>
<xsd:attribute name="val" type="ST_OnOff" use="optional"/>
</xsd:complexType>
<xsd:complexType name="CT_StylisticSets">
<xsd:sequence minOccurs="0">
<xsd:element name="styleSet" minOccurs="0" maxOccurs="unbounded" type="CT_StyleSet"/>
</xsd:sequence>
</xsd:complexType>
<xsd:group name="EG_RPrOpenType">
<xsd:sequence>
<xsd:element name="ligatures" minOccurs="0" type="CT_Ligatures"/>
<xsd:element name="numForm" minOccurs="0" type="CT_NumForm"/>
<xsd:element name="numSpacing" minOccurs="0" type="CT_NumSpacing"/>
<xsd:element name="stylisticSets" minOccurs="0" type="CT_StylisticSets"/>
<xsd:element name="cntxtAlts" minOccurs="0" type="CT_OnOff"/>
</xsd:sequence>
</xsd:group>
<xsd:element name="discardImageEditingData" type="CT_OnOff"/>
<xsd:element name="defaultImageDpi" type="CT_DefaultImageDpi"/>
<xsd:complexType name="CT_DefaultImageDpi">
<xsd:attribute name="val" type="w:ST_DecimalNumber" use="required"/>
</xsd:complexType>
<xsd:element name="entityPicker" type="w:CT_Empty"/>
<xsd:complexType name="CT_SdtCheckboxSymbol">
<xsd:attribute name="font" type="s:ST_String"/>
<xsd:attribute name="val" type="w:ST_ShortHexNumber"/>
</xsd:complexType>
<xsd:complexType name="CT_SdtCheckbox">
<xsd:sequence>
<xsd:element name="checked" type="CT_OnOff" minOccurs="0"/>
<xsd:element name="checkedState" type="CT_SdtCheckboxSymbol" minOccurs="0"/>
<xsd:element name="uncheckedState" type="CT_SdtCheckboxSymbol" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="checkbox" type="CT_SdtCheckbox"/>
</xsd:schema>

View File

@@ -0,0 +1,67 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2012/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2012/wordml">
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" schemaLocation="../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd"/>
<xsd:element name="color" type="w12:CT_Color"/>
<xsd:simpleType name="ST_SdtAppearance">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="boundingBox"/>
<xsd:enumeration value="tags"/>
<xsd:enumeration value="hidden"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="dataBinding" type="w12:CT_DataBinding"/>
<xsd:complexType name="CT_SdtAppearance">
<xsd:attribute name="val" type="ST_SdtAppearance"/>
</xsd:complexType>
<xsd:element name="appearance" type="CT_SdtAppearance"/>
<xsd:complexType name="CT_CommentsEx">
<xsd:sequence>
<xsd:element name="commentEx" type="CT_CommentEx" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_CommentEx">
<xsd:attribute name="paraId" type="w12:ST_LongHexNumber" use="required"/>
<xsd:attribute name="paraIdParent" type="w12:ST_LongHexNumber" use="optional"/>
<xsd:attribute name="done" type="s:ST_OnOff" use="optional"/>
</xsd:complexType>
<xsd:element name="commentsEx" type="CT_CommentsEx"/>
<xsd:complexType name="CT_People">
<xsd:sequence>
<xsd:element name="person" type="CT_Person" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_PresenceInfo">
<xsd:attribute name="providerId" type="xsd:string" use="required"/>
<xsd:attribute name="userId" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="CT_Person">
<xsd:sequence>
<xsd:element name="presenceInfo" type="CT_PresenceInfo" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="author" type="s:ST_String" use="required"/>
</xsd:complexType>
<xsd:element name="people" type="CT_People"/>
<xsd:complexType name="CT_SdtRepeatedSection">
<xsd:sequence>
<xsd:element name="sectionTitle" type="w12:CT_String" minOccurs="0"/>
<xsd:element name="doNotAllowInsertDeleteSection" type="w12:CT_OnOff" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="ST_Guid">
<xsd:restriction base="xsd:token">
<xsd:pattern value="\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="CT_Guid">
<xsd:attribute name="val" type="ST_Guid"/>
</xsd:complexType>
<xsd:element name="repeatingSection" type="CT_SdtRepeatedSection"/>
<xsd:element name="repeatingSectionItem" type="w12:CT_Empty"/>
<xsd:element name="chartTrackingRefBased" type="w12:CT_OnOff"/>
<xsd:element name="collapsed" type="w12:CT_OnOff"/>
<xsd:element name="docId" type="CT_Guid"/>
<xsd:element name="footnoteColumns" type="w12:CT_DecimalNumber"/>
<xsd:element name="webExtensionLinked" type="w12:CT_OnOff"/>
<xsd:element name="webExtensionCreated" type="w12:CT_OnOff"/>
<xsd:attribute name="restartNumberingAfterBreak" type="s:ST_OnOff"/>
</xsd:schema>

View File

@@ -0,0 +1,14 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2018/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2018/wordml">
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
<xsd:complexType name="CT_Extension">
<xsd:sequence>
<xsd:any processContents="lax"/>
</xsd:sequence>
<xsd:attribute name="uri" type="xsd:token"/>
</xsd:complexType>
<xsd:complexType name="CT_ExtensionList">
<xsd:sequence>
<xsd:element name="ext" type="CT_Extension" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,20 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2018/wordml/cex" targetNamespace="http://schemas.microsoft.com/office/word/2018/wordml/cex">
<xsd:import id="w16" namespace="http://schemas.microsoft.com/office/word/2018/wordml" schemaLocation="wml-2018.xsd"/>
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
<xsd:import id="s" namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" schemaLocation="../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd"/>
<xsd:complexType name="CT_CommentsExtensible">
<xsd:sequence>
<xsd:element name="commentExtensible" type="CT_CommentExtensible" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="extLst" type="w16:CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_CommentExtensible">
<xsd:sequence>
<xsd:element name="extLst" type="w16:CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="durableId" type="w:ST_LongHexNumber" use="required"/>
<xsd:attribute name="dateUtc" type="w:ST_DateTime" use="optional"/>
<xsd:attribute name="intelligentPlaceholder" type="s:ST_OnOff" use="optional"/>
</xsd:complexType>
<xsd:element name="commentsExtensible" type="CT_CommentsExtensible"/>
</xsd:schema>

View File

@@ -0,0 +1,13 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2016/wordml/cid" targetNamespace="http://schemas.microsoft.com/office/word/2016/wordml/cid">
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
<xsd:complexType name="CT_CommentsIds">
<xsd:sequence>
<xsd:element name="commentId" type="CT_CommentId" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CT_CommentId">
<xsd:attribute name="paraId" type="w12:ST_LongHexNumber" use="required"/>
<xsd:attribute name="durableId" type="w12:ST_LongHexNumber" use="required"/>
</xsd:complexType>
<xsd:element name="commentsIds" type="CT_CommentsIds"/>
</xsd:schema>

View File

@@ -0,0 +1,4 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" targetNamespace="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash">
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
<xsd:attribute name="storeItemChecksum" type="w12:ST_String"/>
</xsd:schema>

View File

@@ -0,0 +1,8 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2015/wordml/symex" targetNamespace="http://schemas.microsoft.com/office/word/2015/wordml/symex">
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
<xsd:complexType name="CT_SymEx">
<xsd:attribute name="font" type="w12:ST_String"/>
<xsd:attribute name="char" type="w12:ST_LongHexNumber"/>
</xsd:complexType>
<xsd:element name="symEx" type="CT_SymEx"/>
</xsd:schema>

View File

@@ -0,0 +1,183 @@
"""
Helper for running LibreOffice (soffice) in environments where AF_UNIX
sockets may be blocked (e.g., sandboxed VMs). Detects the restriction
at runtime and applies an LD_PRELOAD shim if needed.
Usage:
from office.soffice import run_soffice, get_soffice_env
# Option 1 run soffice directly
result = run_soffice(["--headless", "--convert-to", "pdf", "input.docx"])
# Option 2 get env dict for your own subprocess calls
env = get_soffice_env()
subprocess.run(["soffice", ...], env=env)
"""
import os
import socket
import subprocess
import tempfile
from pathlib import Path
def get_soffice_env() -> dict:
env = os.environ.copy()
env["SAL_USE_VCLPLUGIN"] = "svp"
if _needs_shim():
shim = _ensure_shim()
env["LD_PRELOAD"] = str(shim)
return env
def run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess:
env = get_soffice_env()
return subprocess.run(["soffice"] + args, env=env, **kwargs)
_SHIM_SO = Path(tempfile.gettempdir()) / "lo_socket_shim.so"
def _needs_shim() -> bool:
try:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.close()
return False
except OSError:
return True
def _ensure_shim() -> Path:
if _SHIM_SO.exists():
return _SHIM_SO
src = Path(tempfile.gettempdir()) / "lo_socket_shim.c"
src.write_text(_SHIM_SOURCE)
subprocess.run(
["gcc", "-shared", "-fPIC", "-o", str(_SHIM_SO), str(src), "-ldl"],
check=True,
capture_output=True,
)
src.unlink()
return _SHIM_SO
_SHIM_SOURCE = r"""
#define _GNU_SOURCE
#include <dlfcn.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
static int (*real_socket)(int, int, int);
static int (*real_socketpair)(int, int, int, int[2]);
static int (*real_listen)(int, int);
static int (*real_accept)(int, struct sockaddr *, socklen_t *);
static int (*real_close)(int);
static int (*real_read)(int, void *, size_t);
/* Per-FD bookkeeping (FDs >= 1024 are passed through unshimmed). */
static int is_shimmed[1024];
static int peer_of[1024];
static int wake_r[1024]; /* accept() blocks reading this */
static int wake_w[1024]; /* close() writes to this */
static int listener_fd = -1; /* FD that received listen() */
__attribute__((constructor))
static void init(void) {
real_socket = dlsym(RTLD_NEXT, "socket");
real_socketpair = dlsym(RTLD_NEXT, "socketpair");
real_listen = dlsym(RTLD_NEXT, "listen");
real_accept = dlsym(RTLD_NEXT, "accept");
real_close = dlsym(RTLD_NEXT, "close");
real_read = dlsym(RTLD_NEXT, "read");
for (int i = 0; i < 1024; i++) {
peer_of[i] = -1;
wake_r[i] = -1;
wake_w[i] = -1;
}
}
/* ---- socket ---------------------------------------------------------- */
int socket(int domain, int type, int protocol) {
if (domain == AF_UNIX) {
int fd = real_socket(domain, type, protocol);
if (fd >= 0) return fd;
/* socket(AF_UNIX) blocked fall back to socketpair(). */
int sv[2];
if (real_socketpair(domain, type, protocol, sv) == 0) {
if (sv[0] >= 0 && sv[0] < 1024) {
is_shimmed[sv[0]] = 1;
peer_of[sv[0]] = sv[1];
int wp[2];
if (pipe(wp) == 0) {
wake_r[sv[0]] = wp[0];
wake_w[sv[0]] = wp[1];
}
}
return sv[0];
}
errno = EPERM;
return -1;
}
return real_socket(domain, type, protocol);
}
/* ---- listen ---------------------------------------------------------- */
int listen(int sockfd, int backlog) {
if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {
listener_fd = sockfd;
return 0;
}
return real_listen(sockfd, backlog);
}
/* ---- accept ---------------------------------------------------------- */
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {
/* Block until close() writes to the wake pipe. */
if (wake_r[sockfd] >= 0) {
char buf;
real_read(wake_r[sockfd], &buf, 1);
}
errno = ECONNABORTED;
return -1;
}
return real_accept(sockfd, addr, addrlen);
}
/* ---- close ----------------------------------------------------------- */
int close(int fd) {
if (fd >= 0 && fd < 1024 && is_shimmed[fd]) {
int was_listener = (fd == listener_fd);
is_shimmed[fd] = 0;
if (wake_w[fd] >= 0) { /* unblock accept() */
char c = 0;
write(wake_w[fd], &c, 1);
real_close(wake_w[fd]);
wake_w[fd] = -1;
}
if (wake_r[fd] >= 0) { real_close(wake_r[fd]); wake_r[fd] = -1; }
if (peer_of[fd] >= 0) { real_close(peer_of[fd]); peer_of[fd] = -1; }
if (was_listener)
_exit(0); /* conversion done exit */
}
return real_close(fd);
}
"""
if __name__ == "__main__":
import sys
result = run_soffice(sys.argv[1:])
sys.exit(result.returncode)

View File

@@ -0,0 +1,132 @@
"""Unpack Office files (DOCX, PPTX, XLSX) for editing.
Extracts the ZIP archive, pretty-prints XML files, and optionally:
- Merges adjacent runs with identical formatting (DOCX only)
- Simplifies adjacent tracked changes from same author (DOCX only)
Usage:
python unpack.py <office_file> <output_dir> [options]
Examples:
python unpack.py document.docx unpacked/
python unpack.py presentation.pptx unpacked/
python unpack.py document.docx unpacked/ --merge-runs false
"""
import argparse
import sys
import zipfile
from pathlib import Path
import defusedxml.minidom
from helpers.merge_runs import merge_runs as do_merge_runs
from helpers.simplify_redlines import simplify_redlines as do_simplify_redlines
SMART_QUOTE_REPLACEMENTS = {
"\u201c": "&#x201C;",
"\u201d": "&#x201D;",
"\u2018": "&#x2018;",
"\u2019": "&#x2019;",
}
def unpack(
input_file: str,
output_directory: str,
merge_runs: bool = True,
simplify_redlines: bool = True,
) -> tuple[None, str]:
input_path = Path(input_file)
output_path = Path(output_directory)
suffix = input_path.suffix.lower()
if not input_path.exists():
return None, f"Error: {input_file} does not exist"
if suffix not in {".docx", ".pptx", ".xlsx"}:
return None, f"Error: {input_file} must be a .docx, .pptx, or .xlsx file"
try:
output_path.mkdir(parents=True, exist_ok=True)
with zipfile.ZipFile(input_path, "r") as zf:
zf.extractall(output_path)
xml_files = list(output_path.rglob("*.xml")) + list(output_path.rglob("*.rels"))
for xml_file in xml_files:
_pretty_print_xml(xml_file)
message = f"Unpacked {input_file} ({len(xml_files)} XML files)"
if suffix == ".docx":
if simplify_redlines:
simplify_count, _ = do_simplify_redlines(str(output_path))
message += f", simplified {simplify_count} tracked changes"
if merge_runs:
merge_count, _ = do_merge_runs(str(output_path))
message += f", merged {merge_count} runs"
for xml_file in xml_files:
_escape_smart_quotes(xml_file)
return None, message
except zipfile.BadZipFile:
return None, f"Error: {input_file} is not a valid Office file"
except Exception as e:
return None, f"Error unpacking: {e}"
def _pretty_print_xml(xml_file: Path) -> None:
try:
content = xml_file.read_text(encoding="utf-8")
dom = defusedxml.minidom.parseString(content)
xml_file.write_bytes(dom.toprettyxml(indent=" ", encoding="utf-8"))
except Exception:
pass
def _escape_smart_quotes(xml_file: Path) -> None:
try:
content = xml_file.read_text(encoding="utf-8")
for char, entity in SMART_QUOTE_REPLACEMENTS.items():
content = content.replace(char, entity)
xml_file.write_text(content, encoding="utf-8")
except Exception:
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Unpack an Office file (DOCX, PPTX, XLSX) for editing"
)
parser.add_argument("input_file", help="Office file to unpack")
parser.add_argument("output_directory", help="Output directory")
parser.add_argument(
"--merge-runs",
type=lambda x: x.lower() == "true",
default=True,
metavar="true|false",
help="Merge adjacent runs with identical formatting (DOCX only, default: true)",
)
parser.add_argument(
"--simplify-redlines",
type=lambda x: x.lower() == "true",
default=True,
metavar="true|false",
help="Merge adjacent tracked changes from same author (DOCX only, default: true)",
)
args = parser.parse_args()
_, message = unpack(
args.input_file,
args.output_directory,
merge_runs=args.merge_runs,
simplify_redlines=args.simplify_redlines,
)
print(message)
if "Error" in message:
sys.exit(1)

View File

@@ -0,0 +1,111 @@
"""
Command line tool to validate Office document XML files against XSD schemas and tracked changes.
Usage:
python validate.py <path> [--original <original_file>] [--auto-repair] [--author NAME]
The first argument can be either:
- An unpacked directory containing the Office document XML files
- A packed Office file (.docx/.pptx/.xlsx) which will be unpacked to a temp directory
Auto-repair fixes:
- paraId/durableId values that exceed OOXML limits
- Missing xml:space="preserve" on w:t elements with whitespace
"""
import argparse
import sys
import tempfile
import zipfile
from pathlib import Path
from validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator
def main():
parser = argparse.ArgumentParser(description="Validate Office document XML files")
parser.add_argument(
"path",
help="Path to unpacked directory or packed Office file (.docx/.pptx/.xlsx)",
)
parser.add_argument(
"--original",
required=False,
default=None,
help="Path to original file (.docx/.pptx/.xlsx). If omitted, all XSD errors are reported and redlining validation is skipped.",
)
parser.add_argument(
"-v",
"--verbose",
action="store_true",
help="Enable verbose output",
)
parser.add_argument(
"--auto-repair",
action="store_true",
help="Automatically repair common issues (hex IDs, whitespace preservation)",
)
parser.add_argument(
"--author",
default="Claude",
help="Author name for redlining validation (default: Claude)",
)
args = parser.parse_args()
path = Path(args.path)
assert path.exists(), f"Error: {path} does not exist"
original_file = None
if args.original:
original_file = Path(args.original)
assert original_file.is_file(), f"Error: {original_file} is not a file"
assert original_file.suffix.lower() in [".docx", ".pptx", ".xlsx"], (
f"Error: {original_file} must be a .docx, .pptx, or .xlsx file"
)
file_extension = (original_file or path).suffix.lower()
assert file_extension in [".docx", ".pptx", ".xlsx"], (
f"Error: Cannot determine file type from {path}. Use --original or provide a .docx/.pptx/.xlsx file."
)
if path.is_file() and path.suffix.lower() in [".docx", ".pptx", ".xlsx"]:
temp_dir = tempfile.mkdtemp()
with zipfile.ZipFile(path, "r") as zf:
zf.extractall(temp_dir)
unpacked_dir = Path(temp_dir)
else:
assert path.is_dir(), f"Error: {path} is not a directory or Office file"
unpacked_dir = path
match file_extension:
case ".docx":
validators = [
DOCXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),
]
if original_file:
validators.append(
RedliningValidator(unpacked_dir, original_file, verbose=args.verbose, author=args.author)
)
case ".pptx":
validators = [
PPTXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),
]
case _:
print(f"Error: Validation not supported for file type {file_extension}")
sys.exit(1)
if args.auto_repair:
total_repairs = sum(v.repair() for v in validators)
if total_repairs:
print(f"Auto-repaired {total_repairs} issue(s)")
success = all(v.validate() for v in validators)
if success:
print("All validations PASSED!")
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,847 @@
"""
Base validator with common validation logic for document files.
"""
import re
from pathlib import Path
import defusedxml.minidom
import lxml.etree
class BaseSchemaValidator:
IGNORED_VALIDATION_ERRORS = [
"hyphenationZone",
"purl.org/dc/terms",
]
UNIQUE_ID_REQUIREMENTS = {
"comment": ("id", "file"),
"commentrangestart": ("id", "file"),
"commentrangeend": ("id", "file"),
"bookmarkstart": ("id", "file"),
"bookmarkend": ("id", "file"),
"sldid": ("id", "file"),
"sldmasterid": ("id", "global"),
"sldlayoutid": ("id", "global"),
"cm": ("authorid", "file"),
"sheet": ("sheetid", "file"),
"definedname": ("id", "file"),
"cxnsp": ("id", "file"),
"sp": ("id", "file"),
"pic": ("id", "file"),
"grpsp": ("id", "file"),
}
EXCLUDED_ID_CONTAINERS = {
"sectionlst",
}
ELEMENT_RELATIONSHIP_TYPES = {}
SCHEMA_MAPPINGS = {
"word": "ISO-IEC29500-4_2016/wml.xsd",
"ppt": "ISO-IEC29500-4_2016/pml.xsd",
"xl": "ISO-IEC29500-4_2016/sml.xsd",
"[Content_Types].xml": "ecma/fouth-edition/opc-contentTypes.xsd",
"app.xml": "ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
"core.xml": "ecma/fouth-edition/opc-coreProperties.xsd",
"custom.xml": "ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
".rels": "ecma/fouth-edition/opc-relationships.xsd",
"people.xml": "microsoft/wml-2012.xsd",
"commentsIds.xml": "microsoft/wml-cid-2016.xsd",
"commentsExtensible.xml": "microsoft/wml-cex-2018.xsd",
"commentsExtended.xml": "microsoft/wml-2012.xsd",
"chart": "ISO-IEC29500-4_2016/dml-chart.xsd",
"theme": "ISO-IEC29500-4_2016/dml-main.xsd",
"drawing": "ISO-IEC29500-4_2016/dml-main.xsd",
}
MC_NAMESPACE = "http://schemas.openxmlformats.org/markup-compatibility/2006"
XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"
PACKAGE_RELATIONSHIPS_NAMESPACE = (
"http://schemas.openxmlformats.org/package/2006/relationships"
)
OFFICE_RELATIONSHIPS_NAMESPACE = (
"http://schemas.openxmlformats.org/officeDocument/2006/relationships"
)
CONTENT_TYPES_NAMESPACE = (
"http://schemas.openxmlformats.org/package/2006/content-types"
)
MAIN_CONTENT_FOLDERS = {"word", "ppt", "xl"}
OOXML_NAMESPACES = {
"http://schemas.openxmlformats.org/officeDocument/2006/math",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships",
"http://schemas.openxmlformats.org/schemaLibrary/2006/main",
"http://schemas.openxmlformats.org/drawingml/2006/main",
"http://schemas.openxmlformats.org/drawingml/2006/chart",
"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
"http://schemas.openxmlformats.org/drawingml/2006/diagram",
"http://schemas.openxmlformats.org/drawingml/2006/picture",
"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main",
"http://schemas.openxmlformats.org/presentationml/2006/main",
"http://schemas.openxmlformats.org/spreadsheetml/2006/main",
"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes",
"http://www.w3.org/XML/1998/namespace",
}
def __init__(self, unpacked_dir, original_file=None, verbose=False):
self.unpacked_dir = Path(unpacked_dir).resolve()
self.original_file = Path(original_file) if original_file else None
self.verbose = verbose
self.schemas_dir = Path(__file__).parent.parent / "schemas"
patterns = ["*.xml", "*.rels"]
self.xml_files = [
f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)
]
if not self.xml_files:
print(f"Warning: No XML files found in {self.unpacked_dir}")
def validate(self):
raise NotImplementedError("Subclasses must implement the validate method")
def repair(self) -> int:
return self.repair_whitespace_preservation()
def repair_whitespace_preservation(self) -> int:
repairs = 0
for xml_file in self.xml_files:
try:
content = xml_file.read_text(encoding="utf-8")
dom = defusedxml.minidom.parseString(content)
modified = False
for elem in dom.getElementsByTagName("*"):
if elem.tagName.endswith(":t") and elem.firstChild:
text = elem.firstChild.nodeValue
if text and (text.startswith((' ', '\t')) or text.endswith((' ', '\t'))):
if elem.getAttribute("xml:space") != "preserve":
elem.setAttribute("xml:space", "preserve")
text_preview = repr(text[:30]) + "..." if len(text) > 30 else repr(text)
print(f" Repaired: {xml_file.name}: Added xml:space='preserve' to {elem.tagName}: {text_preview}")
repairs += 1
modified = True
if modified:
xml_file.write_bytes(dom.toxml(encoding="UTF-8"))
except Exception:
pass
return repairs
def validate_xml(self):
errors = []
for xml_file in self.xml_files:
try:
lxml.etree.parse(str(xml_file))
except lxml.etree.XMLSyntaxError as e:
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Line {e.lineno}: {e.msg}"
)
except Exception as e:
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Unexpected error: {str(e)}"
)
if errors:
print(f"FAILED - Found {len(errors)} XML violations:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print("PASSED - All XML files are well-formed")
return True
def validate_namespaces(self):
errors = []
for xml_file in self.xml_files:
try:
root = lxml.etree.parse(str(xml_file)).getroot()
declared = set(root.nsmap.keys()) - {None}
for attr_val in [
v for k, v in root.attrib.items() if k.endswith("Ignorable")
]:
undeclared = set(attr_val.split()) - declared
errors.extend(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Namespace '{ns}' in Ignorable but not declared"
for ns in undeclared
)
except lxml.etree.XMLSyntaxError:
continue
if errors:
print(f"FAILED - {len(errors)} namespace issues:")
for error in errors:
print(error)
return False
if self.verbose:
print("PASSED - All namespace prefixes properly declared")
return True
def validate_unique_ids(self):
errors = []
global_ids = {}
for xml_file in self.xml_files:
try:
root = lxml.etree.parse(str(xml_file)).getroot()
file_ids = {}
mc_elements = root.xpath(
".//mc:AlternateContent", namespaces={"mc": self.MC_NAMESPACE}
)
for elem in mc_elements:
elem.getparent().remove(elem)
for elem in root.iter():
tag = (
elem.tag.split("}")[-1].lower()
if "}" in elem.tag
else elem.tag.lower()
)
if tag in self.UNIQUE_ID_REQUIREMENTS:
in_excluded_container = any(
ancestor.tag.split("}")[-1].lower() in self.EXCLUDED_ID_CONTAINERS
for ancestor in elem.iterancestors()
)
if in_excluded_container:
continue
attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]
id_value = None
for attr, value in elem.attrib.items():
attr_local = (
attr.split("}")[-1].lower()
if "}" in attr
else attr.lower()
)
if attr_local == attr_name:
id_value = value
break
if id_value is not None:
if scope == "global":
if id_value in global_ids:
prev_file, prev_line, prev_tag = global_ids[
id_value
]
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> "
f"already used in {prev_file} at line {prev_line} in <{prev_tag}>"
)
else:
global_ids[id_value] = (
xml_file.relative_to(self.unpacked_dir),
elem.sourceline,
tag,
)
elif scope == "file":
key = (tag, attr_name)
if key not in file_ids:
file_ids[key] = {}
if id_value in file_ids[key]:
prev_line = file_ids[key][id_value]
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> "
f"(first occurrence at line {prev_line})"
)
else:
file_ids[key][id_value] = elem.sourceline
except (lxml.etree.XMLSyntaxError, Exception) as e:
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
)
if errors:
print(f"FAILED - Found {len(errors)} ID uniqueness violations:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print("PASSED - All required IDs are unique")
return True
def validate_file_references(self):
errors = []
rels_files = list(self.unpacked_dir.rglob("*.rels"))
if not rels_files:
if self.verbose:
print("PASSED - No .rels files found")
return True
all_files = []
for file_path in self.unpacked_dir.rglob("*"):
if (
file_path.is_file()
and file_path.name != "[Content_Types].xml"
and not file_path.name.endswith(".rels")
):
all_files.append(file_path.resolve())
all_referenced_files = set()
if self.verbose:
print(
f"Found {len(rels_files)} .rels files and {len(all_files)} target files"
)
for rels_file in rels_files:
try:
rels_root = lxml.etree.parse(str(rels_file)).getroot()
rels_dir = rels_file.parent
referenced_files = set()
broken_refs = []
for rel in rels_root.findall(
".//ns:Relationship",
namespaces={"ns": self.PACKAGE_RELATIONSHIPS_NAMESPACE},
):
target = rel.get("Target")
if target and not target.startswith(
("http", "mailto:")
):
if target.startswith("/"):
target_path = self.unpacked_dir / target.lstrip("/")
elif rels_file.name == ".rels":
target_path = self.unpacked_dir / target
else:
base_dir = rels_dir.parent
target_path = base_dir / target
try:
target_path = target_path.resolve()
if target_path.exists() and target_path.is_file():
referenced_files.add(target_path)
all_referenced_files.add(target_path)
else:
broken_refs.append((target, rel.sourceline))
except (OSError, ValueError):
broken_refs.append((target, rel.sourceline))
if broken_refs:
rel_path = rels_file.relative_to(self.unpacked_dir)
for broken_ref, line_num in broken_refs:
errors.append(
f" {rel_path}: Line {line_num}: Broken reference to {broken_ref}"
)
except Exception as e:
rel_path = rels_file.relative_to(self.unpacked_dir)
errors.append(f" Error parsing {rel_path}: {e}")
unreferenced_files = set(all_files) - all_referenced_files
if unreferenced_files:
for unref_file in sorted(unreferenced_files):
unref_rel_path = unref_file.relative_to(self.unpacked_dir)
errors.append(f" Unreferenced file: {unref_rel_path}")
if errors:
print(f"FAILED - Found {len(errors)} relationship validation errors:")
for error in errors:
print(error)
print(
"CRITICAL: These errors will cause the document to appear corrupt. "
+ "Broken references MUST be fixed, "
+ "and unreferenced files MUST be referenced or removed."
)
return False
else:
if self.verbose:
print(
"PASSED - All references are valid and all files are properly referenced"
)
return True
def validate_all_relationship_ids(self):
import lxml.etree
errors = []
for xml_file in self.xml_files:
if xml_file.suffix == ".rels":
continue
rels_dir = xml_file.parent / "_rels"
rels_file = rels_dir / f"{xml_file.name}.rels"
if not rels_file.exists():
continue
try:
rels_root = lxml.etree.parse(str(rels_file)).getroot()
rid_to_type = {}
for rel in rels_root.findall(
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
):
rid = rel.get("Id")
rel_type = rel.get("Type", "")
if rid:
if rid in rid_to_type:
rels_rel_path = rels_file.relative_to(self.unpacked_dir)
errors.append(
f" {rels_rel_path}: Line {rel.sourceline}: "
f"Duplicate relationship ID '{rid}' (IDs must be unique)"
)
type_name = (
rel_type.split("/")[-1] if "/" in rel_type else rel_type
)
rid_to_type[rid] = type_name
xml_root = lxml.etree.parse(str(xml_file)).getroot()
r_ns = self.OFFICE_RELATIONSHIPS_NAMESPACE
rid_attrs_to_check = ["id", "embed", "link"]
for elem in xml_root.iter():
for attr_name in rid_attrs_to_check:
rid_attr = elem.get(f"{{{r_ns}}}{attr_name}")
if not rid_attr:
continue
xml_rel_path = xml_file.relative_to(self.unpacked_dir)
elem_name = (
elem.tag.split("}")[-1] if "}" in elem.tag else elem.tag
)
if rid_attr not in rid_to_type:
errors.append(
f" {xml_rel_path}: Line {elem.sourceline}: "
f"<{elem_name}> r:{attr_name} references non-existent relationship '{rid_attr}' "
f"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})"
)
elif attr_name == "id" and self.ELEMENT_RELATIONSHIP_TYPES:
expected_type = self._get_expected_relationship_type(
elem_name
)
if expected_type:
actual_type = rid_to_type[rid_attr]
if expected_type not in actual_type.lower():
errors.append(
f" {xml_rel_path}: Line {elem.sourceline}: "
f"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' "
f"but should point to a '{expected_type}' relationship"
)
except Exception as e:
xml_rel_path = xml_file.relative_to(self.unpacked_dir)
errors.append(f" Error processing {xml_rel_path}: {e}")
if errors:
print(f"FAILED - Found {len(errors)} relationship ID reference errors:")
for error in errors:
print(error)
print("\nThese ID mismatches will cause the document to appear corrupt!")
return False
else:
if self.verbose:
print("PASSED - All relationship ID references are valid")
return True
def _get_expected_relationship_type(self, element_name):
elem_lower = element_name.lower()
if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:
return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]
if elem_lower.endswith("id") and len(elem_lower) > 2:
prefix = elem_lower[:-2]
if prefix.endswith("master"):
return prefix.lower()
elif prefix.endswith("layout"):
return prefix.lower()
else:
if prefix == "sld":
return "slide"
return prefix.lower()
if elem_lower.endswith("reference") and len(elem_lower) > 9:
prefix = elem_lower[:-9]
return prefix.lower()
return None
def validate_content_types(self):
errors = []
content_types_file = self.unpacked_dir / "[Content_Types].xml"
if not content_types_file.exists():
print("FAILED - [Content_Types].xml file not found")
return False
try:
root = lxml.etree.parse(str(content_types_file)).getroot()
declared_parts = set()
declared_extensions = set()
for override in root.findall(
f".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override"
):
part_name = override.get("PartName")
if part_name is not None:
declared_parts.add(part_name.lstrip("/"))
for default in root.findall(
f".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default"
):
extension = default.get("Extension")
if extension is not None:
declared_extensions.add(extension.lower())
declarable_roots = {
"sld",
"sldLayout",
"sldMaster",
"presentation",
"document",
"workbook",
"worksheet",
"theme",
}
media_extensions = {
"png": "image/png",
"jpg": "image/jpeg",
"jpeg": "image/jpeg",
"gif": "image/gif",
"bmp": "image/bmp",
"tiff": "image/tiff",
"wmf": "image/x-wmf",
"emf": "image/x-emf",
}
all_files = list(self.unpacked_dir.rglob("*"))
all_files = [f for f in all_files if f.is_file()]
for xml_file in self.xml_files:
path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(
"\\", "/"
)
if any(
skip in path_str
for skip in [".rels", "[Content_Types]", "docProps/", "_rels/"]
):
continue
try:
root_tag = lxml.etree.parse(str(xml_file)).getroot().tag
root_name = root_tag.split("}")[-1] if "}" in root_tag else root_tag
if root_name in declarable_roots and path_str not in declared_parts:
errors.append(
f" {path_str}: File with <{root_name}> root not declared in [Content_Types].xml"
)
except Exception:
continue
for file_path in all_files:
if file_path.suffix.lower() in {".xml", ".rels"}:
continue
if file_path.name == "[Content_Types].xml":
continue
if "_rels" in file_path.parts or "docProps" in file_path.parts:
continue
extension = file_path.suffix.lstrip(".").lower()
if extension and extension not in declared_extensions:
if extension in media_extensions:
relative_path = file_path.relative_to(self.unpacked_dir)
errors.append(
f' {relative_path}: File with extension \'{extension}\' not declared in [Content_Types].xml - should add: <Default Extension="{extension}" ContentType="{media_extensions[extension]}"/>'
)
except Exception as e:
errors.append(f" Error parsing [Content_Types].xml: {e}")
if errors:
print(f"FAILED - Found {len(errors)} content type declaration errors:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print(
"PASSED - All content files are properly declared in [Content_Types].xml"
)
return True
def validate_file_against_xsd(self, xml_file, verbose=False):
xml_file = Path(xml_file).resolve()
unpacked_dir = self.unpacked_dir.resolve()
is_valid, current_errors = self._validate_single_file_xsd(
xml_file, unpacked_dir
)
if is_valid is None:
return None, set()
elif is_valid:
return True, set()
original_errors = self._get_original_file_errors(xml_file)
assert current_errors is not None
new_errors = current_errors - original_errors
new_errors = {
e for e in new_errors
if not any(pattern in e for pattern in self.IGNORED_VALIDATION_ERRORS)
}
if new_errors:
if verbose:
relative_path = xml_file.relative_to(unpacked_dir)
print(f"FAILED - {relative_path}: {len(new_errors)} new error(s)")
for error in list(new_errors)[:3]:
truncated = error[:250] + "..." if len(error) > 250 else error
print(f" - {truncated}")
return False, new_errors
else:
if verbose:
print(
f"PASSED - No new errors (original had {len(current_errors)} errors)"
)
return True, set()
def validate_against_xsd(self):
new_errors = []
original_error_count = 0
valid_count = 0
skipped_count = 0
for xml_file in self.xml_files:
relative_path = str(xml_file.relative_to(self.unpacked_dir))
is_valid, new_file_errors = self.validate_file_against_xsd(
xml_file, verbose=False
)
if is_valid is None:
skipped_count += 1
continue
elif is_valid and not new_file_errors:
valid_count += 1
continue
elif is_valid:
original_error_count += 1
valid_count += 1
continue
new_errors.append(f" {relative_path}: {len(new_file_errors)} new error(s)")
for error in list(new_file_errors)[:3]:
new_errors.append(
f" - {error[:250]}..." if len(error) > 250 else f" - {error}"
)
if self.verbose:
print(f"Validated {len(self.xml_files)} files:")
print(f" - Valid: {valid_count}")
print(f" - Skipped (no schema): {skipped_count}")
if original_error_count:
print(f" - With original errors (ignored): {original_error_count}")
print(
f" - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith(' ')]) or 0}"
)
if new_errors:
print("\nFAILED - Found NEW validation errors:")
for error in new_errors:
print(error)
return False
else:
if self.verbose:
print("\nPASSED - No new XSD validation errors introduced")
return True
def _get_schema_path(self, xml_file):
if xml_file.name in self.SCHEMA_MAPPINGS:
return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]
if xml_file.suffix == ".rels":
return self.schemas_dir / self.SCHEMA_MAPPINGS[".rels"]
if "charts/" in str(xml_file) and xml_file.name.startswith("chart"):
return self.schemas_dir / self.SCHEMA_MAPPINGS["chart"]
if "theme/" in str(xml_file) and xml_file.name.startswith("theme"):
return self.schemas_dir / self.SCHEMA_MAPPINGS["theme"]
if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:
return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]
return None
def _clean_ignorable_namespaces(self, xml_doc):
xml_string = lxml.etree.tostring(xml_doc, encoding="unicode")
xml_copy = lxml.etree.fromstring(xml_string)
for elem in xml_copy.iter():
attrs_to_remove = []
for attr in elem.attrib:
if "{" in attr:
ns = attr.split("}")[0][1:]
if ns not in self.OOXML_NAMESPACES:
attrs_to_remove.append(attr)
for attr in attrs_to_remove:
del elem.attrib[attr]
self._remove_ignorable_elements(xml_copy)
return lxml.etree.ElementTree(xml_copy)
def _remove_ignorable_elements(self, root):
elements_to_remove = []
for elem in list(root):
if not hasattr(elem, "tag") or callable(elem.tag):
continue
tag_str = str(elem.tag)
if tag_str.startswith("{"):
ns = tag_str.split("}")[0][1:]
if ns not in self.OOXML_NAMESPACES:
elements_to_remove.append(elem)
continue
self._remove_ignorable_elements(elem)
for elem in elements_to_remove:
root.remove(elem)
def _preprocess_for_mc_ignorable(self, xml_doc):
root = xml_doc.getroot()
if f"{{{self.MC_NAMESPACE}}}Ignorable" in root.attrib:
del root.attrib[f"{{{self.MC_NAMESPACE}}}Ignorable"]
return xml_doc
def _validate_single_file_xsd(self, xml_file, base_path):
schema_path = self._get_schema_path(xml_file)
if not schema_path:
return None, None
try:
with open(schema_path, "rb") as xsd_file:
parser = lxml.etree.XMLParser()
xsd_doc = lxml.etree.parse(
xsd_file, parser=parser, base_url=str(schema_path)
)
schema = lxml.etree.XMLSchema(xsd_doc)
with open(xml_file, "r") as f:
xml_doc = lxml.etree.parse(f)
xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)
xml_doc = self._preprocess_for_mc_ignorable(xml_doc)
relative_path = xml_file.relative_to(base_path)
if (
relative_path.parts
and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS
):
xml_doc = self._clean_ignorable_namespaces(xml_doc)
if schema.validate(xml_doc):
return True, set()
else:
errors = set()
for error in schema.error_log:
errors.add(error.message)
return False, errors
except Exception as e:
return False, {str(e)}
def _get_original_file_errors(self, xml_file):
if self.original_file is None:
return set()
import tempfile
import zipfile
xml_file = Path(xml_file).resolve()
unpacked_dir = self.unpacked_dir.resolve()
relative_path = xml_file.relative_to(unpacked_dir)
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
with zipfile.ZipFile(self.original_file, "r") as zip_ref:
zip_ref.extractall(temp_path)
original_xml_file = temp_path / relative_path
if not original_xml_file.exists():
return set()
is_valid, errors = self._validate_single_file_xsd(
original_xml_file, temp_path
)
return errors if errors else set()
def _remove_template_tags_from_text_nodes(self, xml_doc):
warnings = []
template_pattern = re.compile(r"\{\{[^}]*\}\}")
xml_string = lxml.etree.tostring(xml_doc, encoding="unicode")
xml_copy = lxml.etree.fromstring(xml_string)
def process_text_content(text, content_type):
if not text:
return text
matches = list(template_pattern.finditer(text))
if matches:
for match in matches:
warnings.append(
f"Found template tag in {content_type}: {match.group()}"
)
return template_pattern.sub("", text)
return text
for elem in xml_copy.iter():
if not hasattr(elem, "tag") or callable(elem.tag):
continue
tag_str = str(elem.tag)
if tag_str.endswith("}t") or tag_str == "t":
continue
elem.text = process_text_content(elem.text, "text content")
elem.tail = process_text_content(elem.tail, "tail content")
return lxml.etree.ElementTree(xml_copy), warnings
if __name__ == "__main__":
raise RuntimeError("This module should not be run directly.")

View File

@@ -0,0 +1,446 @@
"""
Validator for Word document XML files against XSD schemas.
"""
import random
import re
import tempfile
import zipfile
import defusedxml.minidom
import lxml.etree
from .base import BaseSchemaValidator
class DOCXSchemaValidator(BaseSchemaValidator):
WORD_2006_NAMESPACE = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
W14_NAMESPACE = "http://schemas.microsoft.com/office/word/2010/wordml"
W16CID_NAMESPACE = "http://schemas.microsoft.com/office/word/2016/wordml/cid"
ELEMENT_RELATIONSHIP_TYPES = {}
def validate(self):
if not self.validate_xml():
return False
all_valid = True
if not self.validate_namespaces():
all_valid = False
if not self.validate_unique_ids():
all_valid = False
if not self.validate_file_references():
all_valid = False
if not self.validate_content_types():
all_valid = False
if not self.validate_against_xsd():
all_valid = False
if not self.validate_whitespace_preservation():
all_valid = False
if not self.validate_deletions():
all_valid = False
if not self.validate_insertions():
all_valid = False
if not self.validate_all_relationship_ids():
all_valid = False
if not self.validate_id_constraints():
all_valid = False
if not self.validate_comment_markers():
all_valid = False
self.compare_paragraph_counts()
return all_valid
def validate_whitespace_preservation(self):
errors = []
for xml_file in self.xml_files:
if xml_file.name != "document.xml":
continue
try:
root = lxml.etree.parse(str(xml_file)).getroot()
for elem in root.iter(f"{{{self.WORD_2006_NAMESPACE}}}t"):
if elem.text:
text = elem.text
if re.search(r"^[ \t\n\r]", text) or re.search(
r"[ \t\n\r]$", text
):
xml_space_attr = f"{{{self.XML_NAMESPACE}}}space"
if (
xml_space_attr not in elem.attrib
or elem.attrib[xml_space_attr] != "preserve"
):
text_preview = (
repr(text)[:50] + "..."
if len(repr(text)) > 50
else repr(text)
)
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}"
)
except (lxml.etree.XMLSyntaxError, Exception) as e:
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
)
if errors:
print(f"FAILED - Found {len(errors)} whitespace preservation violations:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print("PASSED - All whitespace is properly preserved")
return True
def validate_deletions(self):
errors = []
for xml_file in self.xml_files:
if xml_file.name != "document.xml":
continue
try:
root = lxml.etree.parse(str(xml_file)).getroot()
namespaces = {"w": self.WORD_2006_NAMESPACE}
for t_elem in root.xpath(".//w:del//w:t", namespaces=namespaces):
if t_elem.text:
text_preview = (
repr(t_elem.text)[:50] + "..."
if len(repr(t_elem.text)) > 50
else repr(t_elem.text)
)
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}"
)
for instr_elem in root.xpath(
".//w:del//w:instrText", namespaces=namespaces
):
text_preview = (
repr(instr_elem.text or "")[:50] + "..."
if len(repr(instr_elem.text or "")) > 50
else repr(instr_elem.text or "")
)
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Line {instr_elem.sourceline}: <w:instrText> found within <w:del> (use <w:delInstrText>): {text_preview}"
)
except (lxml.etree.XMLSyntaxError, Exception) as e:
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
)
if errors:
print(f"FAILED - Found {len(errors)} deletion validation violations:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print("PASSED - No w:t elements found within w:del elements")
return True
def count_paragraphs_in_unpacked(self):
count = 0
for xml_file in self.xml_files:
if xml_file.name != "document.xml":
continue
try:
root = lxml.etree.parse(str(xml_file)).getroot()
paragraphs = root.findall(f".//{{{self.WORD_2006_NAMESPACE}}}p")
count = len(paragraphs)
except Exception as e:
print(f"Error counting paragraphs in unpacked document: {e}")
return count
def count_paragraphs_in_original(self):
original = self.original_file
if original is None:
return 0
count = 0
try:
with tempfile.TemporaryDirectory() as temp_dir:
with zipfile.ZipFile(original, "r") as zip_ref:
zip_ref.extractall(temp_dir)
doc_xml_path = temp_dir + "/word/document.xml"
root = lxml.etree.parse(doc_xml_path).getroot()
paragraphs = root.findall(f".//{{{self.WORD_2006_NAMESPACE}}}p")
count = len(paragraphs)
except Exception as e:
print(f"Error counting paragraphs in original document: {e}")
return count
def validate_insertions(self):
errors = []
for xml_file in self.xml_files:
if xml_file.name != "document.xml":
continue
try:
root = lxml.etree.parse(str(xml_file)).getroot()
namespaces = {"w": self.WORD_2006_NAMESPACE}
invalid_elements = root.xpath(
".//w:ins//w:delText[not(ancestor::w:del)]", namespaces=namespaces
)
for elem in invalid_elements:
text_preview = (
repr(elem.text or "")[:50] + "..."
if len(repr(elem.text or "")) > 50
else repr(elem.text or "")
)
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}"
)
except (lxml.etree.XMLSyntaxError, Exception) as e:
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
)
if errors:
print(f"FAILED - Found {len(errors)} insertion validation violations:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print("PASSED - No w:delText elements within w:ins elements")
return True
def compare_paragraph_counts(self):
original_count = self.count_paragraphs_in_original()
new_count = self.count_paragraphs_in_unpacked()
diff = new_count - original_count
diff_str = f"+{diff}" if diff > 0 else str(diff)
print(f"\nParagraphs: {original_count}{new_count} ({diff_str})")
def _parse_id_value(self, val: str, base: int = 16) -> int:
return int(val, base)
def validate_id_constraints(self):
errors = []
para_id_attr = f"{{{self.W14_NAMESPACE}}}paraId"
durable_id_attr = f"{{{self.W16CID_NAMESPACE}}}durableId"
for xml_file in self.xml_files:
try:
for elem in lxml.etree.parse(str(xml_file)).iter():
if val := elem.get(para_id_attr):
if self._parse_id_value(val, base=16) >= 0x80000000:
errors.append(
f" {xml_file.name}:{elem.sourceline}: paraId={val} >= 0x80000000"
)
if val := elem.get(durable_id_attr):
if xml_file.name == "numbering.xml":
try:
if self._parse_id_value(val, base=10) >= 0x7FFFFFFF:
errors.append(
f" {xml_file.name}:{elem.sourceline}: "
f"durableId={val} >= 0x7FFFFFFF"
)
except ValueError:
errors.append(
f" {xml_file.name}:{elem.sourceline}: "
f"durableId={val} must be decimal in numbering.xml"
)
else:
if self._parse_id_value(val, base=16) >= 0x7FFFFFFF:
errors.append(
f" {xml_file.name}:{elem.sourceline}: "
f"durableId={val} >= 0x7FFFFFFF"
)
except Exception:
pass
if errors:
print(f"FAILED - {len(errors)} ID constraint violations:")
for e in errors:
print(e)
elif self.verbose:
print("PASSED - All paraId/durableId values within constraints")
return not errors
def validate_comment_markers(self):
errors = []
document_xml = None
comments_xml = None
for xml_file in self.xml_files:
if xml_file.name == "document.xml" and "word" in str(xml_file):
document_xml = xml_file
elif xml_file.name == "comments.xml":
comments_xml = xml_file
if not document_xml:
if self.verbose:
print("PASSED - No document.xml found (skipping comment validation)")
return True
try:
doc_root = lxml.etree.parse(str(document_xml)).getroot()
namespaces = {"w": self.WORD_2006_NAMESPACE}
range_starts = {
elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
for elem in doc_root.xpath(
".//w:commentRangeStart", namespaces=namespaces
)
}
range_ends = {
elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
for elem in doc_root.xpath(
".//w:commentRangeEnd", namespaces=namespaces
)
}
references = {
elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
for elem in doc_root.xpath(
".//w:commentReference", namespaces=namespaces
)
}
orphaned_ends = range_ends - range_starts
for comment_id in sorted(
orphaned_ends, key=lambda x: int(x) if x and x.isdigit() else 0
):
errors.append(
f' document.xml: commentRangeEnd id="{comment_id}" has no matching commentRangeStart'
)
orphaned_starts = range_starts - range_ends
for comment_id in sorted(
orphaned_starts, key=lambda x: int(x) if x and x.isdigit() else 0
):
errors.append(
f' document.xml: commentRangeStart id="{comment_id}" has no matching commentRangeEnd'
)
comment_ids = set()
if comments_xml and comments_xml.exists():
comments_root = lxml.etree.parse(str(comments_xml)).getroot()
comment_ids = {
elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
for elem in comments_root.xpath(
".//w:comment", namespaces=namespaces
)
}
marker_ids = range_starts | range_ends | references
invalid_refs = marker_ids - comment_ids
for comment_id in sorted(
invalid_refs, key=lambda x: int(x) if x and x.isdigit() else 0
):
if comment_id:
errors.append(
f' document.xml: marker id="{comment_id}" references non-existent comment'
)
except (lxml.etree.XMLSyntaxError, Exception) as e:
errors.append(f" Error parsing XML: {e}")
if errors:
print(f"FAILED - {len(errors)} comment marker violations:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print("PASSED - All comment markers properly paired")
return True
def repair(self) -> int:
repairs = super().repair()
repairs += self.repair_durableId()
return repairs
def repair_durableId(self) -> int:
repairs = 0
for xml_file in self.xml_files:
try:
content = xml_file.read_text(encoding="utf-8")
dom = defusedxml.minidom.parseString(content)
modified = False
for elem in dom.getElementsByTagName("*"):
if not elem.hasAttribute("w16cid:durableId"):
continue
durable_id = elem.getAttribute("w16cid:durableId")
needs_repair = False
if xml_file.name == "numbering.xml":
try:
needs_repair = (
self._parse_id_value(durable_id, base=10) >= 0x7FFFFFFF
)
except ValueError:
needs_repair = True
else:
try:
needs_repair = (
self._parse_id_value(durable_id, base=16) >= 0x7FFFFFFF
)
except ValueError:
needs_repair = True
if needs_repair:
value = random.randint(1, 0x7FFFFFFE)
if xml_file.name == "numbering.xml":
new_id = str(value)
else:
new_id = f"{value:08X}"
elem.setAttribute("w16cid:durableId", new_id)
print(
f" Repaired: {xml_file.name}: durableId {durable_id}{new_id}"
)
repairs += 1
modified = True
if modified:
xml_file.write_bytes(dom.toxml(encoding="UTF-8"))
except Exception:
pass
return repairs
if __name__ == "__main__":
raise RuntimeError("This module should not be run directly.")

View File

@@ -0,0 +1,275 @@
"""
Validator for PowerPoint presentation XML files against XSD schemas.
"""
import re
from .base import BaseSchemaValidator
class PPTXSchemaValidator(BaseSchemaValidator):
PRESENTATIONML_NAMESPACE = (
"http://schemas.openxmlformats.org/presentationml/2006/main"
)
ELEMENT_RELATIONSHIP_TYPES = {
"sldid": "slide",
"sldmasterid": "slidemaster",
"notesmasterid": "notesmaster",
"sldlayoutid": "slidelayout",
"themeid": "theme",
"tablestyleid": "tablestyles",
}
def validate(self):
if not self.validate_xml():
return False
all_valid = True
if not self.validate_namespaces():
all_valid = False
if not self.validate_unique_ids():
all_valid = False
if not self.validate_uuid_ids():
all_valid = False
if not self.validate_file_references():
all_valid = False
if not self.validate_slide_layout_ids():
all_valid = False
if not self.validate_content_types():
all_valid = False
if not self.validate_against_xsd():
all_valid = False
if not self.validate_notes_slide_references():
all_valid = False
if not self.validate_all_relationship_ids():
all_valid = False
if not self.validate_no_duplicate_slide_layouts():
all_valid = False
return all_valid
def validate_uuid_ids(self):
import lxml.etree
errors = []
uuid_pattern = re.compile(
r"^[\{\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\}\)]?$"
)
for xml_file in self.xml_files:
try:
root = lxml.etree.parse(str(xml_file)).getroot()
for elem in root.iter():
for attr, value in elem.attrib.items():
attr_name = attr.split("}")[-1].lower()
if attr_name == "id" or attr_name.endswith("id"):
if self._looks_like_uuid(value):
if not uuid_pattern.match(value):
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: "
f"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters"
)
except (lxml.etree.XMLSyntaxError, Exception) as e:
errors.append(
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
)
if errors:
print(f"FAILED - Found {len(errors)} UUID ID validation errors:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print("PASSED - All UUID-like IDs contain valid hex values")
return True
def _looks_like_uuid(self, value):
clean_value = value.strip("{}()").replace("-", "")
return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)
def validate_slide_layout_ids(self):
import lxml.etree
errors = []
slide_masters = list(self.unpacked_dir.glob("ppt/slideMasters/*.xml"))
if not slide_masters:
if self.verbose:
print("PASSED - No slide masters found")
return True
for slide_master in slide_masters:
try:
root = lxml.etree.parse(str(slide_master)).getroot()
rels_file = slide_master.parent / "_rels" / f"{slide_master.name}.rels"
if not rels_file.exists():
errors.append(
f" {slide_master.relative_to(self.unpacked_dir)}: "
f"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}"
)
continue
rels_root = lxml.etree.parse(str(rels_file)).getroot()
valid_layout_rids = set()
for rel in rels_root.findall(
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
):
rel_type = rel.get("Type", "")
if "slideLayout" in rel_type:
valid_layout_rids.add(rel.get("Id"))
for sld_layout_id in root.findall(
f".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId"
):
r_id = sld_layout_id.get(
f"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id"
)
layout_id = sld_layout_id.get("id")
if r_id and r_id not in valid_layout_rids:
errors.append(
f" {slide_master.relative_to(self.unpacked_dir)}: "
f"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' "
f"references r:id='{r_id}' which is not found in slide layout relationships"
)
except (lxml.etree.XMLSyntaxError, Exception) as e:
errors.append(
f" {slide_master.relative_to(self.unpacked_dir)}: Error: {e}"
)
if errors:
print(f"FAILED - Found {len(errors)} slide layout ID validation errors:")
for error in errors:
print(error)
print(
"Remove invalid references or add missing slide layouts to the relationships file."
)
return False
else:
if self.verbose:
print("PASSED - All slide layout IDs reference valid slide layouts")
return True
def validate_no_duplicate_slide_layouts(self):
import lxml.etree
errors = []
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
for rels_file in slide_rels_files:
try:
root = lxml.etree.parse(str(rels_file)).getroot()
layout_rels = [
rel
for rel in root.findall(
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
)
if "slideLayout" in rel.get("Type", "")
]
if len(layout_rels) > 1:
errors.append(
f" {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references"
)
except Exception as e:
errors.append(
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
)
if errors:
print("FAILED - Found slides with duplicate slideLayout references:")
for error in errors:
print(error)
return False
else:
if self.verbose:
print("PASSED - All slides have exactly one slideLayout reference")
return True
def validate_notes_slide_references(self):
import lxml.etree
errors = []
notes_slide_references = {}
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
if not slide_rels_files:
if self.verbose:
print("PASSED - No slide relationship files found")
return True
for rels_file in slide_rels_files:
try:
root = lxml.etree.parse(str(rels_file)).getroot()
for rel in root.findall(
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
):
rel_type = rel.get("Type", "")
if "notesSlide" in rel_type:
target = rel.get("Target", "")
if target:
normalized_target = target.replace("../", "")
slide_name = rels_file.stem.replace(
".xml", ""
)
if normalized_target not in notes_slide_references:
notes_slide_references[normalized_target] = []
notes_slide_references[normalized_target].append(
(slide_name, rels_file)
)
except (lxml.etree.XMLSyntaxError, Exception) as e:
errors.append(
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
)
for target, references in notes_slide_references.items():
if len(references) > 1:
slide_names = [ref[0] for ref in references]
errors.append(
f" Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}"
)
for slide_name, rels_file in references:
errors.append(f" - {rels_file.relative_to(self.unpacked_dir)}")
if errors:
print(
f"FAILED - Found {len([e for e in errors if not e.startswith(' ')])} notes slide reference validation errors:"
)
for error in errors:
print(error)
print("Each slide may optionally have its own slide file.")
return False
else:
if self.verbose:
print("PASSED - All notes slide references are unique")
return True
if __name__ == "__main__":
raise RuntimeError("This module should not be run directly.")

View File

@@ -0,0 +1,247 @@
"""
Validator for tracked changes in Word documents.
"""
import subprocess
import tempfile
import zipfile
from pathlib import Path
class RedliningValidator:
def __init__(self, unpacked_dir, original_docx, verbose=False, author="Claude"):
self.unpacked_dir = Path(unpacked_dir)
self.original_docx = Path(original_docx)
self.verbose = verbose
self.author = author
self.namespaces = {
"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
}
def repair(self) -> int:
return 0
def validate(self):
modified_file = self.unpacked_dir / "word" / "document.xml"
if not modified_file.exists():
print(f"FAILED - Modified document.xml not found at {modified_file}")
return False
try:
import xml.etree.ElementTree as ET
tree = ET.parse(modified_file)
root = tree.getroot()
del_elements = root.findall(".//w:del", self.namespaces)
ins_elements = root.findall(".//w:ins", self.namespaces)
author_del_elements = [
elem
for elem in del_elements
if elem.get(f"{{{self.namespaces['w']}}}author") == self.author
]
author_ins_elements = [
elem
for elem in ins_elements
if elem.get(f"{{{self.namespaces['w']}}}author") == self.author
]
if not author_del_elements and not author_ins_elements:
if self.verbose:
print(f"PASSED - No tracked changes by {self.author} found.")
return True
except Exception:
pass
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
try:
with zipfile.ZipFile(self.original_docx, "r") as zip_ref:
zip_ref.extractall(temp_path)
except Exception as e:
print(f"FAILED - Error unpacking original docx: {e}")
return False
original_file = temp_path / "word" / "document.xml"
if not original_file.exists():
print(
f"FAILED - Original document.xml not found in {self.original_docx}"
)
return False
try:
import xml.etree.ElementTree as ET
modified_tree = ET.parse(modified_file)
modified_root = modified_tree.getroot()
original_tree = ET.parse(original_file)
original_root = original_tree.getroot()
except ET.ParseError as e:
print(f"FAILED - Error parsing XML files: {e}")
return False
self._remove_author_tracked_changes(original_root)
self._remove_author_tracked_changes(modified_root)
modified_text = self._extract_text_content(modified_root)
original_text = self._extract_text_content(original_root)
if modified_text != original_text:
error_message = self._generate_detailed_diff(
original_text, modified_text
)
print(error_message)
return False
if self.verbose:
print(f"PASSED - All changes by {self.author} are properly tracked")
return True
def _generate_detailed_diff(self, original_text, modified_text):
error_parts = [
f"FAILED - Document text doesn't match after removing {self.author}'s tracked changes",
"",
"Likely causes:",
" 1. Modified text inside another author's <w:ins> or <w:del> tags",
" 2. Made edits without proper tracked changes",
" 3. Didn't nest <w:del> inside <w:ins> when deleting another's insertion",
"",
"For pre-redlined documents, use correct patterns:",
" - To reject another's INSERTION: Nest <w:del> inside their <w:ins>",
" - To restore another's DELETION: Add new <w:ins> AFTER their <w:del>",
"",
]
git_diff = self._get_git_word_diff(original_text, modified_text)
if git_diff:
error_parts.extend(["Differences:", "============", git_diff])
else:
error_parts.append("Unable to generate word diff (git not available)")
return "\n".join(error_parts)
def _get_git_word_diff(self, original_text, modified_text):
try:
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
original_file = temp_path / "original.txt"
modified_file = temp_path / "modified.txt"
original_file.write_text(original_text, encoding="utf-8")
modified_file.write_text(modified_text, encoding="utf-8")
result = subprocess.run(
[
"git",
"diff",
"--word-diff=plain",
"--word-diff-regex=.",
"-U0",
"--no-index",
str(original_file),
str(modified_file),
],
capture_output=True,
text=True,
)
if result.stdout.strip():
lines = result.stdout.split("\n")
content_lines = []
in_content = False
for line in lines:
if line.startswith("@@"):
in_content = True
continue
if in_content and line.strip():
content_lines.append(line)
if content_lines:
return "\n".join(content_lines)
result = subprocess.run(
[
"git",
"diff",
"--word-diff=plain",
"-U0",
"--no-index",
str(original_file),
str(modified_file),
],
capture_output=True,
text=True,
)
if result.stdout.strip():
lines = result.stdout.split("\n")
content_lines = []
in_content = False
for line in lines:
if line.startswith("@@"):
in_content = True
continue
if in_content and line.strip():
content_lines.append(line)
return "\n".join(content_lines)
except (subprocess.CalledProcessError, FileNotFoundError, Exception):
pass
return None
def _remove_author_tracked_changes(self, root):
ins_tag = f"{{{self.namespaces['w']}}}ins"
del_tag = f"{{{self.namespaces['w']}}}del"
author_attr = f"{{{self.namespaces['w']}}}author"
for parent in root.iter():
to_remove = []
for child in parent:
if child.tag == ins_tag and child.get(author_attr) == self.author:
to_remove.append(child)
for elem in to_remove:
parent.remove(elem)
deltext_tag = f"{{{self.namespaces['w']}}}delText"
t_tag = f"{{{self.namespaces['w']}}}t"
for parent in root.iter():
to_process = []
for child in parent:
if child.tag == del_tag and child.get(author_attr) == self.author:
to_process.append((child, list(parent).index(child)))
for del_elem, del_index in reversed(to_process):
for elem in del_elem.iter():
if elem.tag == deltext_tag:
elem.tag = t_tag
for child in reversed(list(del_elem)):
parent.insert(del_index, child)
parent.remove(del_elem)
def _extract_text_content(self, root):
p_tag = f"{{{self.namespaces['w']}}}p"
t_tag = f"{{{self.namespaces['w']}}}t"
paragraphs = []
for p_elem in root.findall(f".//{p_tag}"):
text_parts = []
for t_elem in p_elem.findall(f".//{t_tag}"):
if t_elem.text:
text_parts.append(t_elem.text)
paragraph_text = "".join(text_parts)
if paragraph_text:
paragraphs.append(paragraph_text)
return "\n".join(paragraphs)
if __name__ == "__main__":
raise RuntimeError("This module should not be run directly.")

View File

@@ -0,0 +1,184 @@
"""
Excel Formula Recalculation Script
Recalculates all formulas in an Excel file using LibreOffice
"""
import json
import os
import platform
import subprocess
import sys
from pathlib import Path
from office.soffice import get_soffice_env
from openpyxl import load_workbook
MACRO_DIR_MACOS = "~/Library/Application Support/LibreOffice/4/user/basic/Standard"
MACRO_DIR_LINUX = "~/.config/libreoffice/4/user/basic/Standard"
MACRO_FILENAME = "Module1.xba"
RECALCULATE_MACRO = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic">
Sub RecalculateAndSave()
ThisComponent.calculateAll()
ThisComponent.store()
ThisComponent.close(True)
End Sub
</script:module>"""
def has_gtimeout():
try:
subprocess.run(
["gtimeout", "--version"], capture_output=True, timeout=1, check=False
)
return True
except (FileNotFoundError, subprocess.TimeoutExpired):
return False
def setup_libreoffice_macro():
macro_dir = os.path.expanduser(
MACRO_DIR_MACOS if platform.system() == "Darwin" else MACRO_DIR_LINUX
)
macro_file = os.path.join(macro_dir, MACRO_FILENAME)
if (
os.path.exists(macro_file)
and "RecalculateAndSave" in Path(macro_file).read_text()
):
return True
if not os.path.exists(macro_dir):
subprocess.run(
["soffice", "--headless", "--terminate_after_init"],
capture_output=True,
timeout=10,
env=get_soffice_env(),
)
os.makedirs(macro_dir, exist_ok=True)
try:
Path(macro_file).write_text(RECALCULATE_MACRO)
return True
except Exception:
return False
def recalc(filename, timeout=30):
if not Path(filename).exists():
return {"error": f"File {filename} does not exist"}
abs_path = str(Path(filename).absolute())
if not setup_libreoffice_macro():
return {"error": "Failed to setup LibreOffice macro"}
cmd = [
"soffice",
"--headless",
"--norestore",
"vnd.sun.star.script:Standard.Module1.RecalculateAndSave?language=Basic&location=application",
abs_path,
]
if platform.system() == "Linux":
cmd = ["timeout", str(timeout)] + cmd
elif platform.system() == "Darwin" and has_gtimeout():
cmd = ["gtimeout", str(timeout)] + cmd
result = subprocess.run(cmd, capture_output=True, text=True, env=get_soffice_env())
if result.returncode != 0 and result.returncode != 124:
error_msg = result.stderr or "Unknown error during recalculation"
if "Module1" in error_msg or "RecalculateAndSave" not in error_msg:
return {"error": "LibreOffice macro not configured properly"}
return {"error": error_msg}
try:
wb = load_workbook(filename, data_only=True)
excel_errors = [
"#VALUE!",
"#DIV/0!",
"#REF!",
"#NAME?",
"#NULL!",
"#NUM!",
"#N/A",
]
error_details = {err: [] for err in excel_errors}
total_errors = 0
for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
for row in ws.iter_rows():
for cell in row:
if cell.value is not None and isinstance(cell.value, str):
for err in excel_errors:
if err in cell.value:
location = f"{sheet_name}!{cell.coordinate}"
error_details[err].append(location)
total_errors += 1
break
wb.close()
result = {
"status": "success" if total_errors == 0 else "errors_found",
"total_errors": total_errors,
"error_summary": {},
}
for err_type, locations in error_details.items():
if locations:
result["error_summary"][err_type] = {
"count": len(locations),
"locations": locations[:20],
}
wb_formulas = load_workbook(filename, data_only=False)
formula_count = 0
for sheet_name in wb_formulas.sheetnames:
ws = wb_formulas[sheet_name]
for row in ws.iter_rows():
for cell in row:
if (
cell.value
and isinstance(cell.value, str)
and cell.value.startswith("=")
):
formula_count += 1
wb_formulas.close()
result["total_formulas"] = formula_count
return result
except Exception as e:
return {"error": str(e)}
def main():
if len(sys.argv) < 2:
print("Usage: python recalc.py <excel_file> [timeout_seconds]")
print("\nRecalculates all formulas in an Excel file using LibreOffice")
print("\nReturns JSON with error details:")
print(" - status: 'success' or 'errors_found'")
print(" - total_errors: Total number of Excel errors found")
print(" - total_formulas: Number of formulas in the file")
print(" - error_summary: Breakdown by error type with locations")
print(" - #VALUE!, #DIV/0!, #REF!, #NAME?, #NULL!, #NUM!, #N/A")
sys.exit(1)
filename = sys.argv[1]
timeout = int(sys.argv[2]) if len(sys.argv) > 2 else 30
result = recalc(filename, timeout)
print(json.dumps(result, indent=2))
if __name__ == "__main__":
main()

76
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,76 @@
# OpenHIS — AI 编码助手 指南
目的:帮助自动化/AI 编码代理快速上手本仓库,包含架构要点、关键文件、常用构建/运行命令以及项目约定。请只按照仓库内真实可见的内容提出修改建议或补充说明。
- **代码组织**: 本项目是一个 Java 后端(多模块 Maven+ Vue3 前端Vite的大型应用。
- 后端主模块目录:`openhis-server-new/`(顶层为 `pom`,包含多个子模块)。关键子模块示例:`openhis-application`, `openhis-domain`, `openhis-common`, `core-*` 系列。
- 前端目录:`openhis-ui-vue3/`Vite + Vue 3使用 Pinia、Element Plus 等)。
- **大局观Big Picture**: 后端以 Spring BootJava 17实现使用多模块 Maven 管理公共库与业务模块;前端由单独仓库目录通过 Vite 构建并以环境变量(`VITE_APP_BASE_API`)与后端交互。后端扫描 `com.core``com.openhis` 包(见 `OpenHisApplication.java`),启动类位于:`openhis-server-new/openhis-application/src/main/java/com/openhis/OpenHisApplication.java`
- **运行/构建Windows PowerShell 示例)**:
- 构建后端(从仓库根执行):
```powershell
cd openhis-server-new
mvn clean package -DskipTests
```
- 仅运行后端模块(开发时常用):
```powershell
cd openhis-server-new/openhis-application
mvn spring-boot:run
# 或在 IDE 中运行 `com.openhis.OpenHisApplication` 的 main()
```
- 前端启动与构建(需要 Node.js v16.x仓库 README 建议 v16.15
```powershell
cd openhis-ui-vue3
npm install
npm run dev # 本地开发(热重载)
npm run build:prod # 生产构建
```
- **环境与配置**:
- 后端配置:`openhis-server-new/openhis-application/src/main/resources/application.yml`数据库、端口、profile 等。README 还提及 `application-druid.yml`(若存在请优先查看)。
- 前端配置:多个 `.env.*` 文件(例如 `.env.development`, `.env.staging`, `.env.production`),关键变量:`VITE_APP_BASE_API`(例如 `/dev-api`),前端通过 `import.meta.env.VITE_APP_BASE_API` 拼接后端 URL`src/utils/request.js`、多个视图与组件)。
- **重要约定 / 模式**:
- 后端采用 Java 17、Spring Boot 2.5.x 家族,父 POM在 `openhis-server-new/pom.xml` 定义。常用依赖版本在该 POM 的 `<properties>` 中集中维护。
- 模块间以 Maven 模块依赖与 `com.core` / `com.openhis` 包名分层(见 `pom.xml``<modules>``dependencyManagement`)。
- 前端通过 Vite 插件配置(`openhis-ui-vue3/vite/plugins`)管理 svg、自动导入等。UI 框架为 Element Plus状态管理为 Pinia。
- **集成点 & 外部依赖**:
- 数据库PostgreSQLREADME 建议 v16.2),仓库根含一个大型初始化 SQL`数据库初始话脚本请使用navicat16版本导入.sql`,用于初始化表与演示数据。
- 缓存/会话Redis需自行配置
- 其他Flowable工作流Druid连接池监控第三方服务通过特定配置类例如 `YbServiceConfig``OpenHisApplication` 中启用)。
- **调试与常见位置**:
- 启动类:`openhis-server-new/openhis-application/src/main/java/com/openhis/OpenHisApplication.java`
- 全局配置:`openhis-server-new/openhis-application/src/main/resources/``application.yml`、profile 文件等)。
- 前端入口:`openhis-ui-vue3/src/main.js`、路由在 `openhis-ui-vue3/src/router/index.js`
- API 文档与监控路径(通常由后端暴露并被前端访问):
- Swagger UI: `<VITE_APP_BASE_API>/swagger-ui/index.html`(前端视图在 `src/views/tool/swagger/index.vue`)。
- Druid: `<VITE_APP_BASE_API>/druid/login.html`(见前端相关视图引用)。
- **为 AI 代理的具体建议(如何安全、有效地修改代码)**:
- 修改后端时:优先在子模块(例如 `openhis-application`)本地运行 `mvn spring-boot:run` 验证启动与基础 API大量改动前先执行 `mvn -T1C -DskipTests clean package` 在 CI 环境上验证构建(本地机器也可用)。
- 修改前端时:检查/调整对应 `.env.*` 文件中的 `VITE_APP_BASE_API`,使用 `npm run dev` 本地联调后端接口(可通过代理或将 `VITE_APP_BASE_API` 指向后端地址)。
- 修改数据库结构或 seed请参考仓库根的 SQL 初始化脚本,任何 DDL/数据变更需同步该脚本并通知数据库管理员/运维。
- **举例(常见任务示例)**:
- 本地联调前端 + 后端PowerShell:
```powershell
# 启动后端
cd openhis-server-new/openhis-application
mvn spring-boot:run
# 启动前端(另开终端)
cd openhis-ui-vue3
npm run dev
```
如需我把这些内容合并为更短或更详细的版本,或把其中某部分(例如后端模块依赖关系图、关键 Java 包说明)展开,请告诉我要增强哪一节。

5
.gitignore vendored
View File

@@ -58,3 +58,8 @@
PostgreSQL/openHis_DB设计书.xlsx
public.sql
发版记录/2025-11-12/~$发版日志.docx
发版记录/2025-11-12/~$S-管理系统-调价管理.docx
发版记录/2025-11-12/发版日志.docx
.gitignore
openhis-server-new/openhis-application/src/main/resources/application-dev.yml

View File

@@ -0,0 +1 @@
seeded

View File

@@ -0,0 +1,5 @@
---
description: "Get started"
---
get started

View File

@@ -0,0 +1,5 @@
---
description: "Safe, practical file workflows"
---
Show me how to interact with files in this workspace. Include safe examples for reading, summarizing, and editing.

View File

@@ -0,0 +1,5 @@
---
description: "What plugins are and how to install them"
---
Explain what plugins are and how to install them in this workspace.

View File

@@ -0,0 +1,5 @@
---
description: "How skills work and how to create your own"
---
Explain what skills are, how to use them, and how to create a new skill for this workspace.

11
.opencode/openwork.json Normal file
View File

@@ -0,0 +1,11 @@
{
"version": 1,
"workspace": {
"name": "his",
"createdAt": 1770354192916,
"preset": "starter"
},
"authorizedRoots": [
"D:\\his"
]
}

View File

@@ -0,0 +1 @@
# No environment variables are required for this skill.

View File

@@ -0,0 +1,51 @@
---
name: agent-creator
description: Create new OpenCode agents with a gpt-5.2-codex default.
---
## Quick Usage (Already Configured)
### Create a project agent
```bash
opencode agent create
```
### Agent file locations
- Project agents: `.opencode/agents/<name>.md`
- Global agents: `~/.config/opencode/agents/<name>.md`
## Default model
Use `gpt-5.2-codex` as the default model for new agents unless a workflow needs a different model.
## Minimal agent template
```markdown
---
description: One-line description of what the agent does
mode: subagent
model: gpt-5.2-codex
tools:
write: false
edit: false
bash: false
---
You are a specialized agent. Describe your task, boundaries, and expected output.
```
## Notes from OpenCode docs
- Agent files are markdown with YAML frontmatter.
- The markdown filename becomes the agent name.
- Set `mode` to `primary`, `subagent`, or `all`.
- If no model is specified, subagents inherit the caller model.
- `tools` controls per-agent tool access.
## Reference
Follow the official OpenCode agent docs: https://opencode.ai/docs/agents/
## First-Time Setup (If Not Configured)
1. Run `opencode agent create` and choose project scope.
2. Paste in the default template above and adjust tools as needed.

View File

@@ -0,0 +1,3 @@
export type AgentCreatorClient = Record<string, never>;
export const client: AgentCreatorClient = {};

View File

@@ -0,0 +1,10 @@
import { config } from "./load-env";
async function main() {
void config;
console.log("agent-creator: no credentials required.");
}
main().catch((error) => {
console.error(error);
});

View File

@@ -0,0 +1,3 @@
export type AgentCreatorConfig = Record<string, never>;
export const config: AgentCreatorConfig = {};

View File

@@ -0,0 +1 @@
# No environment variables are required for this skill.

View File

@@ -0,0 +1,8 @@
# Required credentials (if any)
# - List the credential name
# - Where to obtain it
# - How to store it locally
# Example:
# - GITHUB_TOKEN: https://github.com/settings/tokens
# - Store in .env (gitignored)

View File

@@ -0,0 +1,352 @@
---
name: command-creator
description: Create OpenCode custom commands for repeatable tasks.
---
## Quick Usage (Already Configured)
### Create a new command file
```bash
mkdir -p .opencode/commands
```
Create `.opencode/commands/<name>.md` with frontmatter and a prompt template.
### Command file example
```
---
description: Run tests with coverage
agent: build
model: gpt-5.2-codex
---
Run the full test suite with coverage report and show any failures.
Focus on the failing tests and suggest fixes.
```
## Prompt config essentials
- Use `$ARGUMENTS` for all arguments, or `$1`, `$2`, `$3` for positional args.
- Use `!\`command\`` to inject shell output into the prompt.
- Use `@path/to/file` to include file contents in the prompt.
## Notes from OpenCode docs
- Command files live in `.opencode/commands/` (project) or `~/.config/opencode/commands/` (global).
- The markdown filename becomes the command name (e.g., `test.md``/test`).
- JSON config also supports commands in `opencode.json` under `command`.
- Custom commands can override built-ins like `/init`, `/undo`, `/redo`, `/share`, `/help`.
## Reference
Follow the official OpenCode command docs: https://opencode.ai/docs/commands/
Use the docs as the escape hatch when unsure.
## Docs snapshot
Skip to content
OpenCode
Search
K
Intro
Config
Providers
Network
Enterprise
Troubleshooting
Migrating to 1.0
TUI
CLI
Web
IDE
Zen
Share
GitHub
GitLab
Tools
Rules
Agents
Models
Themes
Keybinds
Commands
Formatters
Permissions
LSP Servers
MCP servers
ACP Support
Agent Skills
Custom Tools
SDK
Server
Plugins
Ecosystem
On this page
Overview
Create command files
Configure
JSON
Markdown
Prompt config
Arguments
Shell output
File references
Options
Template
Description
Agent
Subtask
Model
Built-in
Commands
Create custom commands for repetitive tasks.
Custom commands let you specify a prompt you want to run when that command is executed in the TUI.
/my-command
Custom commands are in addition to the built-in commands like /init, /undo, /redo, /share, /help. Learn more.
Create command files
Create markdown files in the commands/ directory to define custom commands.
Create .opencode/commands/test.md:
.opencode/commands/test.md
---
description: Run tests with coverage
agent: build
model: anthropic/claude-3-sonnet-20241022
---
Run the full test suite with coverage report and show any failures.
Focus on the failing tests and suggest fixes.
The frontmatter defines command properties. The content becomes the template.
Use the command by typing / followed by the command name.
"/test"
Configure
You can add custom commands through the OpenCode config or by creating markdown files in the commands/ directory.
JSON
Use the command option in your OpenCode config:
opencode.jsonc
{
"$schema": "https://opencode.ai/config.json",
"command": {
// This becomes the name of the command
"test": {
// This is the prompt that will be sent to the LLM
"template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.",
// This is shown as the description in the TUI
"description": "Run tests with coverage",
"agent": "build",
"model": "anthropic/claude-3-5-sonnet-20241022"
}
}
}
Now you can run this command in the TUI:
/test
Markdown
You can also define commands using markdown files. Place them in:
Global: ~/.config/opencode/commands/
Per-project: .opencode/commands/
~/.config/opencode/commands/test.md
---
description: Run tests with coverage
agent: build
model: anthropic/claude-3-5-sonnet-20241022
---
Run the full test suite with coverage report and show any failures.
Focus on the failing tests and suggest fixes.
The markdown file name becomes the command name. For example, test.md lets you run:
/test
Prompt config
The prompts for the custom commands support several special placeholders and syntax.
Arguments
Pass arguments to commands using the $ARGUMENTS placeholder.
.opencode/commands/component.md
---
description: Create a new component
---
Create a new React component named $ARGUMENTS with TypeScript support.
Include proper typing and basic structure.
Run the command with arguments:
/component Button
And $ARGUMENTS will be replaced with Button.
You can also access individual arguments using positional parameters:
$1 - First argument
$2 - Second argument
$3 - Third argument
And so on…
For example:
.opencode/commands/create-file.md
---
description: Create a new file with content
---
Create a file named $1 in the directory $2
with the following content: $3
Run the command:
/create-file config.json src "{ \"key\": \"value\" }"
This replaces:
$1 with config.json
$2 with src
$3 with { "key": "value" }
Shell output
Use !command to inject bash command output into your prompt.
For example, to create a custom command that analyzes test coverage:
.opencode/commands/analyze-coverage.md
---
description: Analyze test coverage
---
Here are the current test results:
!`npm test`
Based on these results, suggest improvements to increase coverage.
Or to review recent changes:
.opencode/commands/review-changes.md
---
description: Review recent changes
---
Recent git commits:
!`git log --oneline -10`
Review these changes and suggest any improvements.
Commands run in your projects root directory and theutput becomes part of the prompt.
File references
Include files in your command using @ followed by the filename.
.opencode/commands/review-component.md
---
description: Review component
---
Review the component in @src/components/Button.tsx.
Check for performance issues and suggest improvements.
The file content gets included in the prompt automatically.
Options
Lets look at the configuration options in detail.
Template
The template option defines the prompt that will be sent to the LLM when the command is executed.
opencode.json
{
"command": {
"test": {
"template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes."
}
}
}
This is a required config option.
Description
Use the description option to provide a brief description of what the command does.
opencode.json
{
"command": {
"test": {
"description": "Run tests with coverage"
}
}
}
This is shown as the description in the TUI when you type ithe command.
Agent
Use the agent config to optionally specify which agent should execute this command. If this is a subagent the command will trigger a subagent invocation by default. To disable this behavior, set subtask to false.
opencode.json
{
"command": {
"review": {
"agent": "plan"
}
}
}
This is an optional config option. If not specified, defaults to your current agent.
Subtask
Use the subtask boolean to force the command to trigger a subagent invocation. This is useful if you want the command to not pollute your primary context and will force the agent to act as a subagent, even if mode is set to primary on the agent configuration.
opencode.json
{
"command": {
"analyze": {
"subtask": true
}
}
}
This is an optional config option.
Model
Use the model config to override the default model for this command.
opencode.json
{
"command": {
"analyze": {
"model": "anthropic/claude-3-5-sonnet-20241022"
}
}
}
This is an optional config option.
Built-in
opencode includes several built-in commands like /init, /undo, /redo, /share, /help; learn more.
Note
Custom commands can override built-in commands.
If you define a custom command with the same name, it will override the built-in command.
Edit this page
Find a bug? Open an issue
Join our Discord community
© Anomaly
Jan 24, 2026

View File

@@ -0,0 +1,18 @@
---
name: get-started
description: Guide users through the get started setup and Chrome DevTools demo.
---
## When to use
- Always load this skill when the user says \"get started\".
## What to do
- Reply with these four lines, exactly and in order:
1) hey there welcome this is openwork
2) we've pre-configured you with a couple tools
3) Get Started
4) write \"hey go on google.com\"
## Then
- If the user writes \"go on google.com\" (or \"hey go on google.com\"), use the chrome-devtools MCP to open the site.
- After the navigation completes, reply: \"I'm on <site>\" where <site> is the final URL or page title they asked for.

View File

@@ -0,0 +1 @@
# No environment variables are required for this skill.

View File

@@ -0,0 +1,8 @@
# Required credentials (if any)
# - List the credential name
# - Where to obtain it
# - How to store it locally
# Example:
# - GITHUB_TOKEN: https://github.com/settings/tokens
# - Store in .env (gitignored)

View File

@@ -0,0 +1,41 @@
---
name: plugin-creator
description: Create OpenCode plugins and know where to load them.
---
## Quick Usage (Already Configured)
### Where plugins live
- Project plugins: `.opencode/plugins/*.js` or `.opencode/plugins/*.ts`
- Global plugins: `~/.config/opencode/plugins/*.js` or `.ts`
### Load from npm
Add npm plugin packages in `opencode.json`:
```json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-helicone-session", "opencode-wakatime"]
}
```
## Minimal plugin template
```ts
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
return {
// Hook implementations go here
}
}
```
## Notes from OpenCode docs
- Plugins are JS/TS modules exporting one or more plugin functions.
- Local plugins are loaded directly from the plugin directory.
- NPM plugins are installed via Bun at startup and cached in `~/.cache/opencode/node_modules/`.
- Load order: global config → project config → global plugins → project plugins.
## Reference
Follow the official OpenCode plugin docs: https://opencode.ai/docs/plugins/
Use the docs as the escape hatch when unsure.

View File

@@ -0,0 +1 @@
# No environment variables are required for this skill.

View File

@@ -0,0 +1,8 @@
# Required credentials (if any)
# - List the credential name
# - Where to obtain it
# - How to store it locally
# Example:
# - GITHUB_TOKEN: https://github.com/settings/tokens
# - Store in .env (gitignored)

View File

@@ -0,0 +1,101 @@
---
name: skill-creator
description: Create new OpenCode skills with the standard scaffold.
---
Skill creator helps create other skills that are self-buildable.
The best way to use it is after a user already executed a flow and says: create a skill for this. Alternatively, if the user asks for a skill to be created, suggest they do the task first and ask for skill creation at the end.
This should trigger this scaffold:
- If the user needed to configure things, create a `.env.example` without credentials and include all required variables.
- Ask the user if they want to store credentials. If yes, write them to a `.env` file in the skill, and suggest rotating keys later.
- Always add a `.gitignore` in the skill that ignores `.env`, and verify `.env` is not tracked.
- If the user needed to interact with an API and you created scripts, add reusable scripts under `scripts/`.
- New skills should explain how to use the `scripts/` and that `.env.example` defines the minimum config.
- Skills should state that they infer what they can do from the available config.
## Trigger phrases (critical)
The description field is how Claude decides when to use your skill.
Include 2-3 specific phrases that should trigger it.
Bad example:
"Use when working with content"
Good examples:
"Use when user mentions 'content pipeline', 'add to content database', or 'schedule a post'"
"Triggers on: 'rotate PDF', 'flip PDF pages', 'change PDF orientation'"
Quick validation:
- Contains at least one quoted phrase
- Uses "when" or "triggers"
- Longer than ~50 characters
## Frontmatter template
```yaml
---
name: my-skill
description: |
[What it does in one sentence]
Triggers when user mentions:
- "[specific phrase 1]"
- "[specific phrase 2]"
- "[specific phrase 3]"
---
```
## Quick Usage (Already Configured)
### Create a new skill folder
```bash
mkdir -p .opencode/skills/<skill-name>
```
### Minimum scaffold files
- `SKILL.md`
- `scripts/`
- `.env`
- `.env.example` (use this to guide the minimum config)
- `.gitignore` (ignore `.env`)
## .env (credentials + config)
- Use `.env.example` to document required credentials or external setup.
- Do not include any real credentials in `.env.example`.
## Minimal skill template
```markdown
---
name: skill-name
description: One-line description
---
## Quick Usage (Already Configured)
### Action 1
```bash
command here
```
## Common Gotchas
- Thing that doesn't work as expected
## First-Time Setup (If Not Configured)
1. ...
```
## Notes from OpenCode docs
- Skill folders live in `.opencode/skills/<name>/SKILL.md`.
- `name` must be lowercase and match the folder.
- Frontmatter requires `name` and `description`.
## Reference
Follow the official OpenCode skills docs: https://opencode.ai/docs/skills/

View File

@@ -0,0 +1,47 @@
---
name: workspace-guide
description: Workspace guide to introduce OpenWork and onboard new users.
---
# Welcome to OpenWork
Hi, I'm Ben and this is OpenWork. It's an open-source alternative to Claude's cowork. It helps you work on your files with AI and automate the mundane tasks so you don't have to.
Before we start, use the question tool to ask:
"Are you more technical or non-technical? I'll tailor the explanation."
## If the person is non-technical
OpenWork feels like a chat app, but it can safely work with the files you allow. Put files in this workspace and I can summarize them, create new ones, or help organize them.
Try:
- "Summarize the files in this workspace."
- "Create a checklist for my week."
- "Draft a short summary from this document."
## Skills and plugins (simple)
Skills add new capabilities. Plugins add advanced features like scheduling or browser automation. We can add them later when you're ready.
## If the person is technical
OpenWork is a GUI for OpenCode. Everything that works in OpenCode works here.
Most reliable setup today:
1) Install OpenCode from opencode.ai
2) Configure providers there (models and API keys)
3) Come back to OpenWork and start a session
Skills:
- Install from the Skills tab, or add them to this workspace.
- Docs: https://opencode.ai/docs/skills
Plugins:
- Configure in opencode.json or use the Plugins tab.
- Docs: https://opencode.ai/docs/plugins/
MCP servers:
- Add external tools via opencode.json.
- Docs: https://opencode.ai/docs/mcp-servers/
Config reference:
- Docs: https://opencode.ai/docs/config/
End with two friendly next actions to try in OpenWork.

View File

@@ -0,0 +1,29 @@
---
name: full-stack-developer
description: Use this agent when you need comprehensive full-stack development assistance including frontend, backend, database design, API integration, deployment planning, and architectural decisions. This agent excels at analyzing complex technical requirements, designing scalable solutions, implementing clean code across multiple technologies, and providing expert guidance on best practices for modern web applications.
color: Blue
---
You are an elite full-stack software engineer with extensive experience across all layers of modern web application development. You possess deep expertise in frontend technologies (React, Vue, Angular, HTML/CSS, JavaScript/TypeScript), backend systems (Node.js, Python, Java, .NET, Ruby), databases (SQL and NoSQL), cloud platforms (AWS, Azure, GCP), and DevOps practices.
Your primary responsibilities include:
- Analyzing complex technical requirements and proposing optimal architectural solutions
- Writing clean, efficient, maintainable code across frontend and backend systems
- Designing robust APIs and data models
- Optimizing performance and ensuring security best practices
- Providing guidance on scalability, testing, and deployment strategies
- Troubleshooting complex issues spanning multiple technology stacks
When working on projects, you will:
1. First understand the complete scope and requirements before proposing solutions
2. Consider scalability, maintainability, and security implications of your designs
3. Follow industry best practices for code organization, documentation, and testing
4. Suggest appropriate technologies based on project requirements and constraints
5. Provide implementation details with proper error handling and edge case considerations
6. Recommend optimization strategies for performance and resource utilization
For frontend development, focus on responsive design, accessibility, state management, and user experience. For backend work, emphasize proper architecture patterns, database design, authentication/authorization, and API design principles. When addressing databases, consider normalization, indexing, query optimization, and data consistency.
Always prioritize clean code principles, proper separation of concerns, and modular design. When uncertain about requirements, ask clarifying questions to ensure your solution meets the actual needs. Provide code examples that demonstrate best practices and include comments where necessary for understanding.
In your responses, balance technical depth with practical applicability. Consider trade-offs between different approaches and explain your recommendations. When reviewing existing code, identify potential improvements related to performance, security, maintainability, and adherence to best practices.

View File

@@ -0,0 +1,32 @@
---
name: his-architect-developer
description: Use this agent when designing, developing, reviewing, or troubleshooting Hospital Information System (HIS) applications. This agent specializes in full-stack development for healthcare systems including database design, backend APIs, frontend interfaces, security compliance, and integration with medical devices or third-party systems.
color: Blue
---
You are an elite Healthcare Information System (HIS) Development Architect and Full-Stack Engineer with extensive experience in designing and implementing comprehensive hospital management solutions. You possess deep expertise in healthcare software architecture, regulatory compliance (HIPAA, FDA, etc.), medical data standards (HL7, FHIR), and secure system integration.
Your responsibilities include:
- Designing scalable, secure, and compliant HIS architectures
- Developing robust backend services and APIs
- Creating intuitive frontend interfaces for healthcare professionals
- Ensuring patient data security and privacy compliance
- Integrating with medical devices and external healthcare systems
- Optimizing system performance for high-availability environments
- Troubleshooting complex technical issues in healthcare IT infrastructure
When working on HIS projects, you will:
1. Prioritize patient safety and data security above all other considerations
2. Follow healthcare industry standards and regulations (HIPAA, HITECH, FDA guidelines)
3. Implement proper audit trails and logging for all patient-related operations
4. Design fail-safe mechanisms and disaster recovery procedures
5. Ensure accessibility compliance for users with varying technical expertise
6. Plan for high availability and minimal downtime in critical systems
For database design, focus on normalized schemas that support medical record integrity, implement proper indexing for fast queries, and ensure backup/recovery procedures meet healthcare requirements. When developing APIs, follow RESTful principles while incorporating OAuth 2.0 or similar authentication methods suitable for healthcare environments.
For frontend development, prioritize usability for healthcare workers who may be operating under stress, ensuring clear workflows and minimizing cognitive load. Implement responsive designs that work across various devices commonly used in healthcare settings.
Always consider scalability requirements for growing healthcare institutions and plan for future expansion. When troubleshooting, approach problems systematically considering the potential impact on patient care.
In your responses, provide detailed explanations of your architectural decisions, code implementations, and recommendations. Include relevant healthcare industry best practices and explain how your solutions address specific regulatory requirements.

View File

@@ -0,0 +1,33 @@
---
name: his-developer-architect
description: Use this agent when developing or architecting Hospital Information System (HIS) solutions using Vue3, Spring Boot, and MyBatis technologies. This agent specializes in healthcare system development, understanding medical workflows, patient management systems, and hospital operational processes. Ideal for designing secure, scalable, and compliant healthcare applications.
color: Blue
---
You are an elite Healthcare Information System (HIS) developer and architect with deep expertise in Vue3, Spring Boot, and MyBatis technologies. You specialize in building robust, secure, and scalable hospital management systems that handle critical healthcare operations including patient records, medical workflows, billing, pharmacy management, and administrative processes.
Your responsibilities include:
- Designing and implementing full-stack HIS solutions using Vue3 for modern, responsive frontends and Spring Boot with MyBatis for secure, efficient backends
- Ensuring compliance with healthcare industry standards such as HIPAA, HL7, FHIR, and local health data protection regulations
- Creating secure authentication and authorization systems for healthcare staff with role-based access controls
- Optimizing database designs for handling large volumes of sensitive patient data efficiently
- Implementing audit trails and logging systems required for healthcare environments
- Building integration capabilities between different hospital systems and external healthcare providers
Technical Guidelines:
- Follow Vue3 best practices using Composition API, TypeScript, and state management with Pinia
- Implement Spring Boot microservices architecture with proper security configurations (Spring Security)
- Use MyBatis effectively with proper transaction management and connection pooling
- Apply healthcare-specific design patterns and architectural principles
- Prioritize data integrity, security, and system reliability over performance optimizations when there's a conflict
- Implement comprehensive error handling and logging for healthcare regulatory compliance
When designing solutions, consider:
- Patient privacy and data security requirements
- High availability and disaster recovery needs for critical healthcare systems
- Scalability to handle varying loads during peak times
- Integration with existing hospital infrastructure and legacy systems
- User experience for healthcare professionals who need quick, reliable access to information
- Regulatory compliance and audit requirements specific to healthcare systems
You will provide detailed technical recommendations, code implementations, architectural diagrams, and best practices tailored specifically to healthcare information systems. Always prioritize patient safety and data security in your solutions.

6
.qwen/settings.json Normal file
View File

@@ -0,0 +1,6 @@
{
"tools": {
"approvalMode": "yolo"
},
"$version": 2
}

View File

@@ -0,0 +1,26 @@
# 修复门诊预约界面专家号查询结果显示问题
## 问题分析
1. 前端传递的参数正确:`type=expert`,后端正确转换为`ticketType=专家`
2. 实际查询返回了5条记录但COUNT查询只返回了1条记录
3. 这导致前端只显示了1条记录而不是全部5条
4. 原因MyBatis-Plus自动生成的COUNT查询和实际查询使用了不同的条件特别是逻辑删除条件
## 解决方案
1. 修改TicketMapper.xml中的自定义COUNT查询显式添加`delete_flag = '0'`条件
2. 在selectTicketPage和selectTicketPage_mpCount查询中都添加逻辑删除条件
3. 确保两个查询使用完全相同的WHERE条件
## 修复步骤
1. 修改`selectTicketPage`查询,添加逻辑删除条件`and delete_flag = '0'`
2. 修改`selectTicketPage_mpCount`查询,添加逻辑删除条件`and delete_flag = '0'`
3. 确保两个查询的WHERE条件完全一致
4. 测试修复后的功能确保专家号能正确显示全部5条记录
## 代码修改点
- 文件:`d:/work/openhis-server-new/openhis-domain/src/main/resources/mapper/clinical/TicketMapper.xml`
- 查询:`selectTicketPage``selectTicketPage_mpCount`
- 修改内容:添加逻辑删除条件`and delete_flag = '0'`
## 预期效果
修复后COUNT查询和实际查询将使用完全相同的条件包括逻辑删除条件从而确保COUNT查询返回正确的总记录数前端能显示所有5条专家号记录。

View File

@@ -0,0 +1,30 @@
# 修复门诊预约界面专家号查询COUNT结果不正确问题
## 问题分析
1. 前端传递的参数正确:`type=expert`,后端正确转换为`ticketType=专家`
2. COUNT查询和实际查询的WHERE条件完全相同`WHERE delete_flag = '0' AND ticket_type = '专家'`
3. 但COUNT查询只返回1条记录而实际查询返回5条记录
4. 原因MyBatis-Plus的分页插件在处理自定义COUNT查询时存在bug导致COUNT查询结果不正确
## 解决方案
修改`TicketAppServiceImpl.java`中的`listTicket`方法不使用MyBatis-Plus的自动分页功能而是手动实现分页查询
1. 直接调用`ticketService.countTickets`方法获取总记录数
2. 手动构建查询条件
3. 确保COUNT查询和实际查询使用完全相同的条件
## 修复步骤
1. 修改`TicketAppServiceImpl.java`中的`listTicket`方法
2. 手动实现分页查询,包括:
- 构建查询条件
- 调用`countTickets`获取总记录数
- 调用`selectTicketList`获取分页数据
- 手动组装分页结果
3. 测试修复后的功能确保专家号能正确显示全部5条记录
## 代码修改点
- 文件:`d:/work/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java`
- 方法:`listTicket`
- 修改内容替换MyBatis-Plus的自动分页改为手动分页实现
## 预期效果
修复后COUNT查询和实际查询将使用完全相同的条件COUNT查询将返回正确的总记录数5条前端能显示所有5条专家号记录。

View File

@@ -0,0 +1,32 @@
## 问题分析
根据日志和代码分析,发现号源列表显示"没有更多数据了"的问题原因:
1. **后端查询正常**成功查询到5条符合条件的专家号源记录
2. **数据转换失败**:在`convertToDto`方法中,`fee`字段类型转换错误
3. **响应返回空列表**:由于转换异常,最终返回给前端的号源列表为空
## 问题根源
- `Ticket`实体类的`fee`字段为**BigDecimal类型**(数据库存储)
- `TicketDto`类的`fee`字段为**String类型**(前端展示)
-`convertToDto`方法中直接将BigDecimal类型的`fee`赋值给String类型的`fee`,导致**ClassCastException**
## 修复方案
修改`TicketAppServiceImpl.java`文件中的`convertToDto`方法将BigDecimal类型的`fee`转换为String类型
```java
// 原代码
dto.setFee(ticket.getFee());
// 修复后代码
dto.setFee(ticket.getFee().toString());
```
## 预期效果
1. 修复后,后端能成功将`Ticket`实体转换为`TicketDto`
2. 前端能接收到包含5条专家号源的完整列表
3. 页面显示正常,不再出现"没有更多数据了"的提示
## 验证方法
1. 重新启动项目,访问号源管理页面
2. 选择"专家号"类型查看是否能正确显示5条号源记录
3. 检查日志,确认没有类型转换异常

View File

@@ -0,0 +1,23 @@
# 修复门诊预约界面专家号查询问题
## 问题分析
从日志中发现关键问题:
- 前端传递的ticket_type值是英文`general` (普通号) 和 `expert` (专家号)
- 数据库中存储的ticket_type值是中文`普通``专家`
- 导致查询条件不匹配,无法查询到数据
## 解决方案
需要在后端添加类型映射转换,将前端传递的英文类型转换为数据库中存储的中文类型。
## 修复步骤
1. 修改 `TicketAppServiceImpl.java` 文件在处理type参数时添加映射转换逻辑
2. 添加从英文类型到中文类型的映射关系
3. 测试修复后的功能,确保普通号和专家号都能正确查询
## 代码修改点
- 文件:`d:/work/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java`
- 方法:`listTicket` 中的type参数处理部分
- 修改内容:添加类型映射转换,将 "general" 转换为 "普通""expert" 转换为 "专家"
## 预期效果
修复后,前端选择"普通号"或"专家号"时,系统能正确查询到对应的号源数据,不再出现"没有更多数据了"的提示。

View File

@@ -0,0 +1,23 @@
**问题分析**
后端返回的响应格式是`{code: 200, msg: "操作成功", data: {total: 5, limit: 20, page: 1, list: [5条记录]}}`,而前端可能期望直接访问`list`属性导致只能显示1条数据。
**修复方案**
1. 修改`TicketAppServiceImpl.java``listTicket`方法,确保返回的分页数据格式正确
2. 调整响应结构,使其更符合前端期望
3. 保持与现有代码的兼容性
**修改点**
* `TicketAppServiceImpl.java`:优化`listTicket`方法的响应格式
* 确保分页信息和列表数据都能正确返回给前端
**预期效果**
* 后端返回正确格式的响应数据
* 前端能够正确显示所有5条专家号数据
* 保持与现有代码的兼容性

188
AGENTS.md Normal file
View File

@@ -0,0 +1,188 @@
# OpenHIS - AI Agent Development Guide
## 项目概览
OpenHIS 是一个医院管理系统,采用 Java 17 + Spring Boot 后端和 Vue 3 + Vite 前端架构。
## 构建和运行命令
### 后端Java/Spring Boot
```bash
# 构建整个项目
cd openhis-server-new
mvn clean package -DskipTests
# 运行后端(开发模式)
cd openhis-server-new/openhis-application
mvn spring-boot:run
# 运行特定模块
cd openhis-server-new/[module-name]
mvn spring-boot:run
```
### 前端Vue 3 + Vite
```bash
# 安装依赖
cd openhis-ui-vue3
npm install
# 开发服务器
npm run dev
# 生产构建
npm run build:prod
# 测试环境构建
npm run build:test
# 预览构建结果
npm run preview
```
### 测试
项目当前没有配置正式的测试框架。如需添加测试:
- 后端:考虑使用 JUnit 5 + Mockito
- 前端:考虑使用 Vitest + Vue Test Utils
## 代码风格规范
### Java 后端规范
- **Java 版本**: 17
- **框架**: Spring Boot 2.5.15
- **ORM**: MyBatis Plus 3.5.5
- **数据库**: PostgreSQL
- **包结构**:
- `com.openhis` - 业务逻辑
- `com.core` - 核心框架
- **命名约定**:
- 类名PascalCase`UserController`
- 方法名camelCase`getUserList`
- 常量SCREAMING_SNAKE_CASE
- 配置文件kebab-case
- **注解使用**:
- 使用 `@Slf4j` 替代手动声明 logger
- 使用 `@Data` 在实体类中
- 使用 `@Service/@Controller/@Repository` 等 Spring 注解
- **异常处理**:
- 使用统一的异常处理机制
- 自定义业务异常继承 `RuntimeException`
### Vue 前端规范
- **框架**: Vue 3 + Composition API
- **UI 库**: Element Plus
- **状态管理**: Pinia
- **路由**: Vue Router 4
- **构建工具**: Vite 5
- **组件命名**: PascalCase
- **文件命名**: kebab-case
- **变量命名**: camelCase
- **常量命名**: SCREAMING_SNAKE_CASE
- **函数命名**:
- 事件处理:`handle` 前缀
- 数据获取:`get`/`load` 前缀
- 提交操作:`submit` 前缀
### 导入顺序
#### Java
1. `java.*`
2. `javax.*`
3. 第三方库
4. `com.core.*`
5. `com.openhis.*`
6. `*.*`(其他包)
#### JavaScript/Vue
1. `vue` 相关
2. 第三方库
3. `@/` 别名导入
4. 相对路径导入
### 代码格式
#### Java
- 缩进4个空格
- 行长度120字符
- 左大括号不换行
#### Vue/JavaScript
- 缩进2个空格
- 字符串:优先使用单引号
- 行长度100字符
## 关键配置文件
### 后端配置
- 主配置:`openhis-server-new/openhis-application/src/main/resources/application.yml`
- 环境配置:`application-{profile}.yml`
- Maven 父 POM`openhis-server-new/pom.xml`
### 前端配置
- Vite 配置:`openhis-ui-vue3/vite.config.js`
- 环境变量:`.env.*` 文件
- 路由配置:`openhis-ui-vue3/src/router/index.js`
## 开发约定
### API 设计
- RESTful API 风格
- 统一响应格式
- 使用 Swagger 文档
- 错误码统一管理
### 数据库
- 表名snake_case
- 字段名snake_case
- 主键:使用 `id`
- 软删除:使用 `valid_flag` 字段
### 前端组件
- 单一职责原则
- Props 使用 camelCase
- Events 使用 kebab-case
- 使用 Composition API
- 组件文档使用 JSDoc
### 状态管理
- 模块化设计
- 异步操作使用 actions
- 避免在组件中直接修改状态
## 环境变量
### 前端
- `VITE_APP_BASE_API`: API 基础路径
- `VITE_APP_ENV`: 环境标识
### 后端
- `spring.profiles.active`: 激活的配置文件
- `core.name`: 应用名称
- `core.version`: 应用版本
## 安全规范
- 所有 API 接口需要权限验证
- 敏感信息使用环境变量
- SQL 注入防护
- XSS 攻击防护
## 性能优化
- 后端使用连接池Druid
- 前端使用路由懒加载
- 图片使用 WebP 格式
- 大列表使用虚拟滚动
## 常用工具类
- 后端:`com.core.common.utils.*`
- 前端:`@/utils/*`
## 注意事项
1. 修改数据库结构需要同步 SQL 脚本
2. 新增功能需要添加权限配置
3. 前端路由需要在权限系统中注册
4. 接口变更需要更新 Swagger 文档
5. 遵循现有代码风格,避免不必要的变化
## 故障排除
- 后端端口18080
- 前端端口81
- API 前缀:`/openhis`
- Swagger UI`/openhis/swagger-ui/index.html`
- Druid 监控:`/openhis/druid/login.html`

376
CODEBUDDY.md Normal file
View File

@@ -0,0 +1,376 @@
# CODEBUDDY.md
This file provides guidance to CodeBuddy Code when working with code in this repository.
## Project Overview
This is a comprehensive Hospital Information System (HIS) built with a Java Spring Boot backend and Vue 3 frontend.
- **Backend**: Java 17, Spring Boot 2.5.15, multi-module Maven architecture
- **Frontend**: Vue 3, Vite, Element Plus, Pinia state management
- **Database**: PostgreSQL (recommended v16.2)
- **Cache**: Redis
## Repository Structure
```
.
├── openhis-server-new/ # Backend multi-module Maven project
│ ├── openhis-application/ # Main application module with startup class
│ ├── openhis-domain/ # Business domain modules (administration, clinical, financial, etc.)
│ ├── openhis-common/ # Shared utilities and common code
│ ├── core-admin/ # Core administration module
│ ├── core-framework/ # Framework configuration and security
│ ├── core-system/ # System management module
│ ├── core-quartz/ # Scheduled tasks
│ ├── core-generator/ # Code generation utilities
│ ├── core-common/ # Core utilities
│ └── core-flowable/ # Workflow engine integration
└── openhis-ui-vue3/ # Vue 3 frontend
├── src/
│ ├── api/ # API service layer
│ ├── components/ # Reusable components
│ ├── router/ # Vue Router configuration
│ ├── store/ # Pinia state management
│ ├── utils/ # Utility functions
│ └── views/ # Page components
└── vite/ # Vite plugins configuration
```
## Build and Development Commands
### Backend (Java)
**Build the entire backend:**
```bash
cd openhis-server-new
mvn clean package -DskipTests
```
**Run the backend application (development):**
```bash
cd openhis-server-new/openhis-application
mvn spring-boot:run
```
**Alternative: Run directly from IDE:**
- Run the main method in `openhis-server-new/openhis-application/src/main/java/com/openhis/OpenHisApplication.java`
**Start scripts:**
- Linux/Mac: `openhis-server-new/start.sh`
- Windows: `openhis-server-new/start.bat`
### Frontend (Vue 3)
**Install dependencies:**
```bash
cd openhis-ui-vue3
npm install
```
**Development server (with hot reload):**
```bash
npm run dev
```
- Runs on port 81 by default
- Proxies `/dev-api` requests to `http://localhost:18080/openhis`
**Build for production:**
```bash
npm run build:prod # Production build
npm run build:stage # Staging build
npm run build:test # Test environment build
npm run build:dev # Development build
npm run build:spug # Spug environment build
```
**Preview production build:**
```bash
npm run preview
```
## Architecture Overview
### Backend Architecture
The backend uses a multi-module Maven architecture with clear separation of concerns:
1. **openhis-application**: Entry point with `OpenHisApplication.java` (d:\his\openhis-server-new\openhis-application\src\main\java\com\openhis\OpenHisApplication.java:20)
- Scans `com.core` and `com.openhis` packages
- Configures async processing and YAML service configuration
- Runs on port 18080 with context path `/openhis`
2. **openhis-domain**: Business domain modules organized by medical functionality:
- `administration`: Administrative functions
- `appointmentmanage`: Appointment management
- `check`: Medical examination/checkup
- `clinical`: Clinical workflows
- `crosssystem`: Cross-system integration
- `document`: Document management
- `financial`: Financial/billing
- `lab`: Laboratory operations
- `medication`: Medication management
- `triageandqueuemanage`: Patient triage and queue management
- `yb`, `ybcatalog`, `ybelep`: Insurance (Yi Bao) integration
- `workflow`: Workflow management
- `jlau`, `nenu`: Additional domain modules
- `template`: Template management
3. **Core Modules** (com.core package):
- `core-system`: User, role, menu, and permission management
- `core-framework`: Security, exception handling, and framework configurations
- `core-common`: Shared utilities and base classes
- `core-quartz`: Scheduled task management
- `core-generator`: Code generation tools
- `core-flowable`: Workflow engine integration
- `core-admin`: Administrative functions
4. **openhis-common**: Domain-specific shared code and utilities under `com.openhis.common` package
**Key Technologies:**
- MyBatis-Plus 3.5.5 for ORM with enhanced CRUD operations
- Druid 1.2.27 connection pool with monitoring at `/druid/*`
- Flowable 6.8.0 for workflow management
- LiteFlow 2.12.4.1 for business rule orchestration
- Swagger 3.0.0 for API documentation
- JWT 0.9.1 for authentication
- Hutool 5.3.8 utility library
- Fastjson2 2.0.58 for JSON processing
- Pinyin4j 2.5.1 for Chinese character to Pinyin conversion
### Frontend Architecture
The frontend uses Vue 3 with composition API and modern tooling:
**Key Files:**
- Entry point: `openhis-ui-vue3/src/main.js`
- Router configuration: `openhis-ui-vue3/src/router/index.js`
- Store initialization: `openhis-ui-vue3/src/store/store.js`
- Vite configuration: `openhis-ui-vue3/vite.config.js`
**State Management:**
- Pinia for global state (replaces Vuex)
- Store modules: `app`, `dict`, `permission`, `settings`, `tagsView`, `user`
- Modules located in `openhis-ui-vue3/src/store/modules/`
**Routing:**
- Vue Router 4.3.0
- Two types of routes:
- `constantRoutes`: Public routes (login, 404, etc.)
- `dynamicRoutes`: Permission-based routes loaded dynamically
- Route meta fields: `title`, `icon`, `permissions`, `noCache`, `activeMenu`
**API Integration:**
- Axios 0.27.2 for HTTP requests
- Base API URL configured via environment variables (`VITE_APP_BASE_API`)
- Proxy configuration in vite.config.js for development
- `/dev-api``http://localhost:18080/openhis`
- `/ybplugin``http://localhost:5000` (insurance plugin)
- Request/response interceptors in `openhis-ui-vue3/src/utils/request.js`
- API service files organized by module in `openhis-ui-vue3/src/api/`
- `administration`, `appoinmentmanage`, `monitor`, `system`, `tool`
- Shared APIs: `home.js`, `login.js`, `menu.js`, `public.js`
**Component Architecture:**
- Element Plus as the UI framework
- Custom components in `openhis-ui-vue3/src/components/`
- Global components registered in main.js:
- Pagination, TreeSelect, FileUpload, ImageUpload, ImagePreview
- RightToolbar, Editor, DictTag
## Configuration
### Backend Configuration
**Main configuration file:** `openhis-server-new/openhis-application/src/main/resources/application.yml`
**Environment-specific profiles:**
- `application-dev.yml` - Development environment
- `application-test.yml` - Test environment
- `application-prd.yml` - Production environment
**Key configuration sections:**
- Database: PostgreSQL connection (URL, username, password, pool settings)
- Redis: Cache configuration (host, port, database index)
- Server: Port (18080), context path (/openhis), thread pool
- MyBatis-Plus: Mapper scanning (`com.core.**.domain,com.openhis.**.domain`), type aliases, logical delete
- Logging: Debug levels for com.openhis and com.baomidou.mybatisplus
- Swagger: API documentation at `/swagger-ui/index.html`
- Druid: Database monitoring at `/druid/*` (credentials: openhis/123456)
- Flowable: Workflow engine settings (schema update disabled)
- LiteFlow: Business rule configuration at `config/flow.el.xml`
- Token: JWT configuration (secret, expire time, header)
- File upload: Max file size (10MB), max request size (20MB)
### Frontend Configuration
**Environment files** (in `openhis-ui-vue3/`):
- `.env.dev` - Dev environment
- `.env.development` - Development environment variables
- `.env.staging` - Staging environment variables
- `.env.production` - Production environment variables
- `.env.test` - Test environment variables
- `.env.spug` - Spug environment variables
**Key environment variables:**
- `VITE_APP_TITLE`: Application title (e.g., "医院信息管理系统")
- `VITE_APP_BASE_API`: Backend API base URL (e.g., `/dev-api`)
- `VITE_APP_ENV`: Environment identifier
**Vite configuration:**
- Development server: Port 81, host true, auto-open
- Proxy: `/dev-api``http://localhost:18080/openhis`
- Path aliases: `@``./src`, `~``./`
## Database
**Initialization script:** `数据库初始话脚本请使用navicat16版本导入.sql` (located at repository root)
- Use Navicat version 16 to import
- Contains schema and initial demonstration data
**Database connection (dev environment):**
- Type: PostgreSQL
- URL: `jdbc:postgresql://47.116.196.11:15432/postgresql?currentSchema=hisdev`
- Driver: `org.postgresql.Driver`
- Schema: `hisdev`
## Common Development Tasks
### Running Full Stack Locally
**Terminal 1 - Start backend:**
```bash
cd openhis-server-new/openhis-application
mvn spring-boot:run
```
**Terminal 2 - Start frontend:**
```bash
cd openhis-ui-vue3
npm run dev
```
Access the application at:
- Frontend: http://localhost:81
- Backend API: http://localhost:18080/openhis
- Swagger UI: http://localhost:18080/openhis/swagger-ui/index.html
- Druid monitoring: http://localhost:18080/openhis/druid/login.html
### Adding a New Backend Feature
1. Create domain entity in appropriate module under `openhis-domain/[module]/domain/`
2. Create mapper interface in `openhis-domain/[module]/mapper/`
3. Create mapper XML in `openhis-domain/[module]/resources/mapper/` (if custom SQL needed)
4. Create service interface and implementation in `openhis-domain/[module]/service/`
5. Create controller in `openhis-application/src/main/java/com/openhis/web/[module]/`
6. Add MyBatis-Plus annotations if using enhanced features
7. Test endpoints via Swagger UI at `http://localhost:18080/openhis/swagger-ui/index.html`
**Note:** Controllers are organized under `com.openhis.web` by business module (e.g., `web.administration`, `web.clinicalmanage`, `web.patientmanage`, etc.)
### Adding a New Frontend Page
1. Create Vue component in `openhis-ui-vue3/src/views/[module]/`
2. Add API service methods in `openhis-ui-vue3/src/api/`
3. Add route to `openhis-ui-vue3/src/router/index.js` (constantRoutes or dynamicRoutes)
4. Add Pinia store module if state management needed
5. Register global components if reusable
### Testing
**Backend:**
```bash
cd openhis-server-new
mvn test
```
**Frontend:**
- Run unit tests (if configured):
```bash
cd openhis-ui-vue3
npm test
```
## Key Patterns and Conventions
### Backend
- Package structure follows domain-driven design
- Service layer uses `@Service` annotation
- Controllers use `@RestController` with request mapping
- MyBatis-Plus base mapper: `BaseMapper<T>`
- Logical delete field: `validFlag` (1 = active, 0 = deleted)
- Use `@EnableAsync` for async processing
- JWT token stored in `Authorization` header
### Frontend
- Use Vue 3 Composition API (`<script setup>`)
- Element Plus components with Chinese locale (zhCn)
- API calls through centralized request utility in `src/utils/request.js`
- Route-based permission control
- Dictionary data through `useDict()` composable
- Global properties: `$download`, `$downloadGet`, `$parseTime`, `$resetForm`, `$handleTree`, `$formatDateStr`
- CSS in SCSS with global styles in `src/assets/styles/index.scss`
- Registered global components: DictTag, Pagination, TreeSelect, FileUpload, ImageUpload, ImagePreview, RightToolbar, Editor
- Hiprint plugin for printing functionality (window.hiprint)
## Important Files
### Backend
- Startup class: `openhis-server-new/openhis-application/src/main/java/com/openhis/OpenHisApplication.java`
- Main config: `openhis-server-new/openhis-application/src/main/resources/application.yml`
- MyBatis config: `openhis-server-new/openhis-application/src/main/resources/mybatis/mybatis-config.xml`
- Parent POM: `openhis-server-new/pom.xml`
### Frontend
- Entry point: `openhis-ui-vue3/src/main.js`
- Router: `openhis-ui-vue3/src/router/index.js`
- Request utils: `openhis-ui-vue3/src/utils/request.js`
- Vite config: `openhis-ui-vue3/vite.config.js`
- Environment files: `openhis-ui-vue3/.env.*`
## External Integrations
- **PostgreSQL 42.2.27**: Primary database
- **MySQL Connector 9.4.0**: MySQL database support (alternative)
- **Redis**: Caching and session management
- **Flowable 6.8.0**: Workflow engine
- **LiteFlow 2.12.4.1**: Business rule engine
- **Swagger 3.0.0**: API documentation
- **Druid 1.2.27**: Database connection pool and monitoring
- **Element Plus 2.12.0**: Vue 3 UI component library
- **Pinia 2.2.0**: State management
- **Vite 5.0.4**: Build tool and dev server
- **Hutool 5.3.8**: Java utility library
- **Fastjson2 2.0.58**: JSON processing
- **Pinyin4j 2.5.1**: Chinese character to Pinyin conversion
- **iText 5.5.12**: PDF generation
- **Apache POI 4.1.2**: Excel file processing
## Additional Notes
### WebView Integration
- Frontend supports WebView environment (e.g., embedded in desktop applications)
- Chrome WebView integration with C# accessor (`chrome.webview.hostObjects.CSharpAccessor`)
- Mounted to Vue instance as `csAccessor` global property
### File Upload
- Backend upload path: Configured in `core.profile` property (default: `D:/home/uploadPath`)
- Max file size: 10MB per file, 20MB total request
- File upload component: `FileUpload` (global component)
### Authentication
- JWT token stored in `Authorization` header
- Token configuration: `token.secret`, `token.expireTime`, `token.header`
- Password lockout: 5 failed attempts, 10-minute lock time
### Logging
- Backend logs: Configured in `logback.xml`
- Debug logging enabled for: `com.openhis`, `com.baomidou.mybatisplus`, `com.alibaba.druid`
- Druid slow SQL threshold: 1000ms
### Code Generation
- Backend code generator: `core-generator` module
- Access via Swagger or `/tool/gen` route
- Uses Velocity templates in `openhis-application/src/main/resources/vm/`

View File

@@ -0,0 +1,223 @@
# MyBatis-Plus 自动填充处理器优化指南
## 概述
本文档说明如何优化 `MybastisColumnsHandler` 以确保所有实体的审计字段create_by、create_time、update_by、update_time能够正确自动填充。
## 问题背景
在 OpenHIS 系统中,当保存实体时可能会遇到以下错误:
```
org.postgresql.util.PSQLException: ERROR: null value in column "create_by" of relation "adm_practitioner" violates not-null constraint
```
这是因为数据库表中的审计字段设置了 NOT NULL 约束,但在某些情况下自动填充机制未能正确设置这些字段。
## 解决方案
通过优化 `MybastisColumnsHandler` 来确保总是使用当前登录用户的用户名填充 `create_by` 字段,使用当前时间填充 `create_time` 字段。
## 实施步骤
### 1. 替换现有处理器
`D:\his\openhis-server-new\core-framework\src\main\java\com\core\framework\handler\MybastisColumnsHandler.java` 文件替换为以下内容:
```java
package com.core.framework.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.core.common.core.domain.model.LoginUser;
import com.core.common.utils.SecurityUtils;
import com.core.framework.config.TenantContext;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* MyBatis-Plus 自动填充处理器
* 用于自动填充创建时间和更新时间,以及创建人和更新人
*/
@Component
public class MybastisColumnsHandler implements MetaObjectHandler {
// 设置数据新增时的字段自动赋值规则
@Override
public void insertFill(MetaObject metaObject) {
// 填充创建时间
Date currentTime = new Date();
this.strictInsertFill(metaObject, "createTime", Date.class, currentTime);
this.strictInsertFill(metaObject, "create_time", Date.class, currentTime);
// 获取当前登录用户名
String username = getCurrentUsername();
// 填充创建人
this.strictInsertFill(metaObject, "createBy", String.class, username);
this.strictInsertFill(metaObject, "create_by", String.class, username);
// 确保tenantId被设置
Integer tenantId = getCurrentTenantId();
if (tenantId == null) {
throw new RuntimeException("无法获取当前租户ID请确保用户已登录或正确设置租户上下文");
}
this.strictInsertFill(metaObject, "tenantId", Integer.class, tenantId);
this.strictInsertFill(metaObject, "tenant_id", Integer.class, tenantId);
}
// 设置数据修改时的字段自动赋值规则
@Override
public void updateFill(MetaObject metaObject) {
// 填充更新时间
Date currentTime = new Date();
this.strictUpdateFill(metaObject, "updateTime", Date.class, currentTime);
this.strictUpdateFill(metaObject, "update_time", Date.class, currentTime);
// 填充更新人
String username = getCurrentUsername();
this.strictUpdateFill(metaObject, "updateBy", String.class, username);
this.strictUpdateFill(metaObject, "update_by", String.class, username);
}
/**
* 获取当前登录用户名
* @return 当前登录用户名,如果无法获取则返回 "system"
*/
private String getCurrentUsername() {
String username = "system"; // 默认值
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
username = loginUser.getUsername();
} else {
// 尝试从请求中获取用户信息
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
// 可以在这里添加额外的逻辑来从请求中获取用户信息
// 例如从请求头、session等获取用户信息
}
}
} catch (Exception e) {
// 记录异常但不中断处理流程
System.err.println("获取当前登录用户时发生异常: " + e.getMessage());
// 可以考虑记录日志
}
return username;
}
/**
* 获取当前租户 ID
*/
private Integer getCurrentTenantId() {
Integer result = null;
// 首先尝试从线程局部变量中获取租户ID适用于定时任务等场景
Integer threadLocalTenantId = TenantContext.getCurrentTenant();
if (threadLocalTenantId != null) {
result = threadLocalTenantId;
} else {
// 获取当前登录用户的租户ID优先使用SecurityUtils中储存的LoginUser的租户ID
try {
if (SecurityUtils.getAuthentication() != null) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
result = loginUser.getTenantId();
}
}
} catch (Exception e) {
// 记录异常但不中断处理
System.err.println("获取当前登录用户租户ID时发生异常: " + e.getMessage());
}
if (result == null) {
// 尝试从请求头中获取租户ID
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
if (request != null) {
// 从请求头获取租户ID假设header名称为"X-Tenant-ID" ; 登录接口前端把租户id放到请求头里
String tenantIdHeader = request.getHeader("X-Tenant-ID");
String requestMethodName = request.getHeader("Request-Method-Name");
// 登录
if ("login".equals(requestMethodName)) {
if (tenantIdHeader != null && !tenantIdHeader.isEmpty()) {
try {
result = Integer.parseInt(tenantIdHeader);
} catch (NumberFormatException e) {
System.err.println("解析请求头中的租户ID时发生异常: " + e.getMessage());
}
}
}
}
}
}
}
// 如果仍然没有获取到租户ID返回默认值
if (result == null) {
System.out.println("警告: 未能获取当前租户ID将使用默认租户ID 1");
result = 1; // 默认租户ID
}
return result;
}
}
```
### 2. 验证处理器是否被正确扫描
确保在主应用类或配置类中启用了自动填充功能:
```java
@SpringBootApplication
@MapperScan("com.openhis.*.mapper") // 确保扫描到你的mapper
@EnableTransactionManagement // 启用事务管理
public class OpenHisApplication {
public static void main(String[] args) {
SpringApplication.run(OpenHisApplication.class, args);
}
}
```
### 3. 测试验证
创建一个简单的测试来验证自动填充是否正常工作:
```java
@SpringBootTest
public class AuditFieldTest {
@Autowired
private PractitionerMapper practitionerMapper;
@Test
public void testAuditFieldsAutoFill() {
Practitioner practitioner = new Practitioner();
practitioner.setName("Test Practitioner");
// 保存实体
practitionerMapper.insert(practitioner);
// 验证审计字段是否被正确填充
assertThat(practitioner.getCreateBy()).isNotNull();
assertThat(practitioner.getCreateBy()).isNotEqualTo("");
assertThat(practitioner.getCreateTime()).isNotNull();
// 清理测试数据
practitionerMapper.deleteById(practitioner.getId());
}
}
```
## 注意事项
1. **安全上下文**:确保在调用保存方法时用户已登录,这样 `SecurityUtils.getLoginUser()` 才能返回有效的用户对象。
2. **异常处理**:处理器中包含了异常处理,如果无法获取当前用户,将使用 "system" 作为默认值。
3. **租户ID**处理器也处理租户ID的自动填充这对于多租户系统很重要。
4. **兼容性**处理器同时支持驼峰命名createBy和下划线命名create_by的字段以兼容不同的配置。
## 总结
通过优化 `MybastisColumnsHandler`,我们可以确保所有实体在保存时都能正确填充审计字段,避免因缺少这些字段而引发的数据库约束错误,同时保持数据完整性和审计跟踪功能。

184
QWEN.md Normal file
View File

@@ -0,0 +1,184 @@
# Qwen Code Context for HIS (Hospital Information System)
## Project Overview
This is a comprehensive Hospital Information System (HIS) called OpenHIS, built with a Java Spring Boot backend and Vue 3 frontend. The system is designed to manage hospital operations including patient management, appointments, clinical workflows, billing, and administrative tasks.
### Technology Stack
**Backend:**
- Java 17
- Spring Boot 2.5.15
- PostgreSQL (recommended v16.2)
- Redis
- MyBatis-Plus 3.5.5 for ORM
- Druid 1.2.27 for database connection pooling
- Flowable 6.8.0 for workflow management
- LiteFlow 2.12.4.1 for business rule orchestration
- Swagger 3.0.0 for API documentation
- JWT 0.9.1 for authentication
**Frontend:**
- Vue 3 with Composition API
- Vite 5.0.4 as build tool
- Element Plus 2.12.0 as UI component library
- Pinia 2.2.0 for state management
- Axios 0.27.2 for HTTP requests
- Sass for styling
## Repository Structure
```
.
├── openhis-server-new/ # Backend multi-module Maven project
│ ├── openhis-application/ # Main application module with startup class
│ ├── openhis-domain/ # Business domain modules (administration, clinical, financial, etc.)
│ ├── openhis-common/ # Shared utilities and common code
│ ├── core-admin/ # Core administration module
│ ├── core-framework/ # Framework configuration and security
│ ├── core-system/ # System management module
│ ├── core-quartz/ # Scheduled tasks
│ ├── core-generator/ # Code generation utilities
│ ├── core-common/ # Core utilities
│ └── core-flowable/ # Workflow engine integration
├── openhis-ui-vue3/ # Vue 3 frontend
│ ├── src/
│ │ ├── api/ # API service layer
│ │ ├── components/ # Reusable components
│ │ ├── router/ # Vue Router configuration
│ │ ├── store/ # Pinia state management
│ │ ├── utils/ # Utility functions
│ │ └── views/ # Page components
│ └── vite/ # Vite plugins configuration
├── sql/ # Database scripts
├── 发版记录/ # Release records
└── 迁移记录-DB变更记录/ # Database migration records
```
## Building and Running
### Backend Setup
1. **Prerequisites:**
- JDK 17 (required)
- PostgreSQL v16.2 (required)
- Redis (stable version)
2. **Database Setup:**
- Import the database initialization script using Navicat 16 or later
- Script location: `sql/20251224init脚本(使用Navicat Premium 17导入).sql`
- Configure database connection in `application.yml` or `application-dev.yml`
3. **Build and Run:**
```bash
cd openhis-server-new
mvn clean package -DskipTests
cd openhis-application
mvn spring-boot:run
```
Or run directly from IDE by executing `OpenHisApplication.java`
### Frontend Setup
1. **Prerequisites:**
- Node.js v16.15 (recommended)
2. **Installation and Run:**
```bash
cd openhis-ui-vue3
npm install
npm run dev
```
3. **Access the application:**
- Frontend: http://localhost:81
- Backend API: http://localhost:18080/openhis
- Swagger UI: http://localhost:18080/openhis/swagger-ui/index.html
## Development Conventions
### Backend Architecture
The backend follows a multi-module Maven architecture with clear separation of concerns:
1. **openhis-application**: Entry point with `OpenHisApplication.java`
- Scans `com.core` and `com.openhis` packages
- Configured to run on port 18080 with context path `/openhis`
2. **openhis-domain**: Business domain modules organized by medical functionality:
- `administration`: Administrative functions
- `appointmentmanage`: Appointment management
- `check`: Medical examination/checkup
- `clinical`: Clinical workflows
- `crosssystem`: Cross-system integration
- `document`: Document management
- `financial`: Financial/billing
- `lab`: Laboratory operations
- `medication`: Medication management
- `triageandqueuemanage`: Patient triage and queue management
- `yb`, `ybcatalog`, `ybelep`: Insurance (Yi Bao) integration
- `workflow`: Workflow management
3. **Core Modules** (com.core package):
- `core-system`: User, role, menu, and permission management
- `core-framework`: Security, exception handling, and framework configurations
- `core-common`: Shared utilities and base classes
- `core-quartz`: Scheduled task management
- `core-generator`: Code generation tools
- `core-flowable`: Workflow engine integration
- `core-admin`: Administrative functions
### Frontend Architecture
The frontend uses Vue 3 with composition API and modern tooling:
1. **State Management:** Pinia for global state with modules for app, dict, permission, settings, tagsView, and user
2. **Routing:** Vue Router 4.3.0 with public routes and dynamic permission-based routes
3. **API Integration:** Axios with request/response interceptors and API services organized by module
4. **Component Architecture:** Element Plus as UI framework with custom components in `src/components/`
## Key Configuration Files
### Backend Configuration
- Main config: `openhis-server-new/openhis-application/src/main/resources/application.yml`
- Environment-specific: `application-dev.yml`, `application-test.yml`, `application-prd.yml`
- Database connection settings, Redis configuration, server settings, and MyBatis-Plus configuration
### Frontend Configuration
- Environment files: `.env.*` in `openhis-ui-vue3/`
- Vite configuration: `vite.config.js`
- Main entry: `src/main.js`
- Router: `src/router/index.js`
## Common Development Tasks
### Adding a New Backend Feature
1. Create domain entity in appropriate module under `openhis-domain/[module]/domain/`
2. Create mapper interface in `openhis-domain/[module]/mapper/`
3. Create service interface and implementation in `openhis-domain/[module]/service/`
4. Create controller in `openhis-application/src/main/java/com/openhis/web/[module]/`
5. Test endpoints via Swagger UI
### Adding a New Frontend Page
1. Create Vue component in `openhis-ui-vue3/src/views/[module]/`
2. Add API service methods in `openhis-ui-vue3/src/api/`
3. Add route to `openhis-ui-vue3/src/router/index.js`
4. Add Pinia store module if state management needed
## Important Notes
- The system uses logical deletion with a `validFlag` field (1 = active, 0 = deleted)
- JWT tokens are stored in the `Authorization` header
- The system supports WebView environments with C# accessor integration
- File uploads are configured with max 10MB per file and 20MB total request size
- Password lockout occurs after 5 failed attempts with a 10-minute lock time
- The system includes a code generator accessible via `/tool/gen` route
- Printing functionality is implemented using the hiprint plugin

View File

@@ -1,68 +0,0 @@
# 平台介绍
## 🏠【关于我们】
![天天开源](https://open.tntlinking.com/assets/logo-b-BzFUYaRU.png)
天天开源致⼒于打造中国应⽤管理软件开源⽣态⾯向医疗、企业、教育三⼤⾏业信息化需求提供优质的开源软件产品与解决⽅案。平台现已发布OpenHIS、OpenCOM、OpenEDU系列开源产品并持续招募⽣态合作伙伴期待共同构建开源创新的⾏业协作模式加速⾏业的数字化进程。
天天开源的前⾝是新致开源最早于2022年6⽉发布开源医疗软件平台OpenHIS.org.cn于2023年6⽉发布开源企业软件平台OpenCOM.com.cn。2025年7⽉新致开源品牌更新为天天开源我们始终秉持开源、专业、协作的理念致⼒于为医疗、教育、中⼩企业等⾏业提供优质的开源解决⽅案。
了解我们https://open.tntlinking.com/about?site=gitee
## 💾【部署包下载】
请访问官网产品中心下载部署包https://open.tntlinking.com/resource/productCenter?site=gitee
## 📚【支持文档】
技术支持资源https://open.tntlinking.com/resource/technicalSupport?site=gitee
(含演示环境、操作手册、部署手册、开发手册、常见问题等)
产品介绍https://open.tntlinking.com/resource/industryKnowledge?site=gitee
操作教程https://open.tntlinking.com/resource/operationTutorial?site=gitee
沙龙回顾https://open.tntlinking.com/resource/openSourceSalon#23?site=gitee
## 🤝【合作方式】
产品服务价格https://open.tntlinking.com/cost?site=gitee
加入生态伙伴https://open.tntlinking.com/ecology/becomePartner?site=gitee
## 🤗【技术社区】
请访问官网扫码加入技术社区交流https://open.tntlinking.com/ecology/joinCommunity?site=gitee
请关注公众号【天天开源软件】以便获得最新产品更新信息。
# 项目介绍
OpenHIS医院系统信创版集十大核心模块于一体涵盖目录管理、基础数据配置、个性化设置、门诊/住院全流程管理、药房药库智能管控、精细化耗材管理、财务核算体系、医保合规对接及多维报表分析等功能模块共计372项标准化功能。
系统深度适配民营及公立一二级医院业务场景,支持单体医院、集团化运营及区域医疗协同等多种部署模式,并通过国家信创认证体系,确保全栈技术自主可控。如有项目需求,可联系官方平台合作。
## 运行环境
jdk17 (必须)
node.js-v16.15 (推荐)
PostgreSQL-v16.2 (必须)
redis (常用稳定版本即可)
## 开发提示
需要修改数据库和redis的连接信息,详见:
application.yml
application-druid.yml
## 目录解释
前端: openhis-ui-vue3
后端: openhis-server
启动类: OpenHisApplication

View File

@@ -0,0 +1,13 @@
-- 添加缺失的字段到 sys_user_config 表
-- 添加 create_by 字段
ALTER TABLE sys_user_config ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT NULL COMMENT '创建者';
-- 添加 create_time 字段
ALTER TABLE sys_user_config ADD COLUMN IF NOT EXISTS create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间';
-- 添加 update_by 字段
ALTER TABLE sys_user_config ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT NULL COMMENT '更新者';
-- 添加 update_time 字段
ALTER TABLE sys_user_config ADD COLUMN IF NOT EXISTS update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间';

View File

@@ -0,0 +1,39 @@
-- 添加缺失的字段到 sys_user_config 表 (PostgreSQL 版本)
-- 添加 create_by 字段
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name='sys_user_config' AND column_name='create_by') THEN
ALTER TABLE sys_user_config ADD COLUMN create_by VARCHAR(64) DEFAULT NULL;
END IF;
END $$;
-- 添加 create_time 字段
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name='sys_user_config' AND column_name='create_time') THEN
ALTER TABLE sys_user_config ADD COLUMN create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
COMMENT ON COLUMN sys_user_config.create_time IS '创建时间';
END IF;
END $$;
-- 添加 update_by 字段
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name='sys_user_config' AND column_name='update_by') THEN
ALTER TABLE sys_user_config ADD COLUMN update_by VARCHAR(64) DEFAULT NULL;
END IF;
END $$;
-- 添加 update_time 字段
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name='sys_user_config' AND column_name='update_time') THEN
ALTER TABLE sys_user_config ADD COLUMN update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
COMMENT ON COLUMN sys_user_config.update_time IS '更新时间';
END IF;
END $$;

View File

@@ -0,0 +1,202 @@
# OpenHIS 系统审计字段填充最佳实践
## 概述
本文档介绍如何在 OpenHIS 系统中确保所有实体的审计字段create_by、create_time、update_by、update_time能够正确自动填充。
## 自动填充机制
### 1. 基础实体类
所有需要审计字段的实体类都应该继承自 `HisBaseEntity`
```java
import com.core.common.core.domain.HisBaseEntity;
@Data
@TableName("adm_practitioner")
public class Practitioner extends HisBaseEntity {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
// 其他业务字段...
}
```
### 2. 自动填充处理器
系统使用 `MybastisColumnsHandler` 来自动填充审计字段:
```java
@Component
public class MybastisColumnsHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 填充创建时间和创建人
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "create_time", Date.class, new Date());
String username = getCurrentUsername(); // 获取当前用户名
this.strictInsertFill(metaObject, "createBy", String.class, username);
this.strictInsertFill(metaObject, "create_by", String.class, username);
}
@Override
public void updateFill(MetaObject metaObject) {
// 填充更新时间和更新人
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
this.strictUpdateFill(metaObject, "update_time", Date.class, new Date());
String username = getCurrentUsername(); // 获取当前用户名
this.strictUpdateFill(metaObject, "updateBy", String.class, username);
this.strictUpdateFill(metaObject, "update_by", String.class, username);
}
private String getCurrentUsername() {
String username = "system";
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
username = loginUser.getUsername();
}
} catch (Exception ignored) {
}
return username;
}
}
```
## 确保自动填充正常工作的要点
### 1. 检查实体类继承关系
确保所有实体类都正确继承了 `HisBaseEntity`
```java
// 正确的做法
public class Practitioner extends HisBaseEntity { ... }
// 如果不能继承 HisBaseEntity则需要手动添加审计字段
public class CustomEntity {
@TableField(fill = FieldFill.INSERT)
private String createBy;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.UPDATE)
private String updateBy;
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
}
```
### 2. 验证安全上下文
确保在执行数据库操作时有有效的安全上下文:
```java
@Service
public class PractitionerService {
public void savePractitioner(Practitioner practitioner) {
// 确保调用此方法时用户已登录
// SecurityUtils.getLoginUser() 应该能返回有效的 LoginUser 对象
// MyBatis-Plus 会在保存时自动调用 MybastisColumnsHandler
practitionerMapper.insert(practitioner);
}
}
```
### 3. 检查配置
确保自动填充处理器被正确配置:
```yaml
# application.yml
mybatis-plus:
global-config:
db-config:
# 其他配置...
configuration:
# 其他配置...
```
### 4. 手动填充(特殊情况)
在某些特殊情况下,如果自动填充不工作,可以手动设置:
```java
@Service
public class PractitionerService {
public void savePractitionerManually(Practitioner practitioner) {
// 手动设置审计字段
Date now = new Date();
String currentUser = getCurrentUsername();
practitioner.setCreateTime(now);
practitioner.setCreateBy(currentUser);
practitioner.setUpdateTime(now);
practitioner.setUpdateBy(currentUser);
practitionerMapper.insert(practitioner);
}
}
```
## 常见问题及解决方案
### 问题1自动填充不生效
**原因:**
- 实体类没有继承 `HisBaseEntity`
- `MybastisColumnsHandler` 没有被Spring管理缺少@Component注解
- 没有有效的安全上下文
**解决方案:**
- 确保实体类继承 `HisBaseEntity`
- 检查 `MybastisColumnsHandler` 是否有 `@Component` 注解
- 确保在调用保存方法时用户已登录
### 问题2获取不到当前用户
**原因:**
- 用户未登录
- 安全上下文配置错误
**解决方案:**
- 在调用保存方法前确保用户已登录
- 检查安全配置是否正确
### 问题3批量操作时审计字段未填充
**原因:**
- 批量操作可能绕过了自动填充机制
**解决方案:**
- 对于批量操作,手动设置审计字段
- 或者使用 MyBatis-Plus 的批量操作方法,确保它们支持自动填充
## 测试验证
创建一个简单的测试来验证自动填充是否正常工作:
```java
@SpringBootTest
public class AuditFieldTest {
@Autowired
private PractitionerMapper practitionerMapper;
@Test
public void testAuditFieldsAutoFill() {
Practitioner practitioner = new Practitioner();
practitioner.setName("Test Practitioner");
// 保存实体
practitionerMapper.insert(practitioner);
// 验证审计字段是否被正确填充
assertThat(practitioner.getCreateBy()).isNotNull();
assertThat(practitioner.getCreateTime()).isNotNull();
// 清理测试数据
practitionerMapper.deleteById(practitioner.getId());
}
}
```
## 总结
通过遵循以上最佳实践,可以确保 OpenHIS 系统中的所有实体在保存时都能正确填充审计字段,避免因缺少这些字段而引发的数据库约束错误。

113
audit_field_solution.md Normal file
View File

@@ -0,0 +1,113 @@
# 关于数据库审计字段create_by, create_time等的处理方案
## 问题描述
在使用OpenHIS系统时可能会遇到如下错误
```
org.postgresql.util.PSQLException: ERROR: null value in column "create_by" of relation "adm_practitioner" violates not-null constraint
```
## 问题分析
1. 数据库表中的审计字段如create_by, create_time设置了NOT NULL约束
2. 应用程序层面使用了MyBatis-Plus的自动填充功能来设置这些字段
3. 当自动填充机制失效时,就会出现违反非空约束的错误
## 解决方案
### 方案一:修复自动填充机制(推荐)
系统已经实现了自动填充机制,位于 `MybastisColumnsHandler.java`
```java
// 设置数据新增时候的,字段自动赋值规则
@Override
public void insertFill(MetaObject metaObject) {
// 同时填充驼峰和下划线命名的字段,以兼容不同的配置
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "create_time", Date.class, new Date());
String username = "system";
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
username = loginUser.getUsername();
}
} catch (Exception ignored) {
}
// 使用 fillStrategy 确保即使字段为 null 也会被填充
this.strictInsertFill(metaObject, "createBy", String.class, username);
this.strictInsertFill(metaObject, "create_by", String.class, username);
// 如果 strictInsertFill 没有生效,使用 setFieldValByName 强制设置
if (metaObject.hasGetter("createBy") && metaObject.getValue("createBy") == null) {
this.setFieldValByName("createBy", username, metaObject);
}
if (metaObject.hasGetter("create_by") && metaObject.getValue("create_by") == null) {
this.setFieldValByName("create_by", username, metaObject);
}
...
}
```
确保所有实体类都继承自 `HisBaseEntity``BaseEntity`,这样就能自动获得审计字段。
### 方案二:移除数据库约束(谨慎使用)
如果确实需要允许审计字段为NULL可以移除数据库约束
```sql
-- 移除 adm_practitioner 表中 create_by 列的 NOT NULL 约束
ALTER TABLE "public"."adm_practitioner"
ALTER COLUMN "create_by" DROP NOT NULL;
-- 同样处理 create_time 列(如果需要)
ALTER TABLE "public"."adm_practitioner"
ALTER COLUMN "create_time" DROP NOT NULL;
```
### 方案三:批量修复所有表的约束
如果多个表都存在这个问题,可以使用以下脚本:
```sql
-- 为所有表的审计字段移除NOT NULL约束
-- 注意:执行前请备份数据库!
-- 1. 检查所有包含审计字段的表
SELECT
table_name,
column_name,
is_nullable
FROM
information_schema.columns
WHERE
column_name IN ('create_by', 'create_time', 'update_by', 'update_time')
AND table_schema = 'public'
AND is_nullable = 'NO'; -- NO 表示 NOT NULL 约束
-- 2. 根据需要移除特定表的约束
-- 示例移除多个表的create_by约束
ALTER TABLE "public"."adm_practitioner" ALTER COLUMN "create_by" DROP NOT NULL;
ALTER TABLE "public"."adm_patient" ALTER COLUMN "create_by" DROP NOT NULL;
-- 添加更多表的处理...
```
## 最佳实践
### 1. 确保实体类继承基础类
所有实体类应继承 `HisBaseEntity``BaseEntity`
```java
@Data
@TableName("adm_practitioner")
public class Practitioner extends HisBaseEntity {
// 其他字段...
}
```
### 2. 检查安全上下文
确保在保存数据时有有效的安全上下文,这样自动填充处理器才能获取到当前用户信息。
### 3. 验证自动填充配置
确保 `MybastisColumnsHandler` 在Spring容器中被正确注册使用@Component注解)。
## 总结
- 推荐保持数据库中的NOT NULL约束确保数据完整性
- 依赖MyBatis-Plus的自动填充机制来设置审计字段
- 确保所有实体类继承基础实体类
- 在必要时才考虑移除数据库约束

104
check_display_order.sql Normal file
View File

@@ -0,0 +1,104 @@
-- 检查流水号display_order是否按“科室+医生+当天”正确递增
--
-- 说明:
-- 1. display_order 存的是纯数字1, 2, 3...),不带时间戳前缀
-- 2. 时间戳前缀(如 20260109是在前端显示时加上的
-- 3. 后端用 Redis key "ORG-{科室ID}-DOC-{医生ID}" 按天自增
--
-- 如何判断逻辑是否正确:
-- 同一科室、同一医生、同一天的记录display_order 应该递增1, 2, 3...
-- 不同科室、不同医生、不同天的记录,可能都是 1这是正常的
-- ========================================
-- 查询1按“科室+医生+日期”分组,看每组内的 display_order 是否递增
-- ========================================
SELECT
DATE(start_time) AS ,
organization_id AS ID,
registrar_id AS ID,
COUNT(*) AS ,
MIN(display_order) AS ,
MAX(display_order) AS ,
STRING_AGG(display_order::text, ', ' ORDER BY start_time) AS ,
STRING_AGG(id::text, ', ' ORDER BY start_time) AS ID列表
FROM adm_encounter
WHERE delete_flag = '0'
AND start_time >= CURRENT_DATE - INTERVAL '7 days' -- 只看最近7天
AND display_order IS NOT NULL
GROUP BY DATE(start_time), organization_id, registrar_id
ORDER BY DESC, ID, ID;
-- ========================================
-- 查询2详细查看每条记录看同组内的序号是否连续
-- ========================================
SELECT
id AS ID,
DATE(start_time) AS ,
organization_id AS ID,
registrar_id AS ID,
start_time AS ,
display_order AS ,
-- 计算:同组内的序号应该是 1, 2, 3...,看是否有重复或跳号
ROW_NUMBER() OVER (
PARTITION BY DATE(start_time), organization_id, registrar_id
ORDER BY start_time
) AS ,
CASE
WHEN display_order = ROW_NUMBER() OVER (
PARTITION BY DATE(start_time), organization_id, registrar_id
ORDER BY start_time
) THEN '✓ 正常'
ELSE '✗ 异常'
END AS
FROM adm_encounter
WHERE delete_flag = '0'
AND start_time >= CURRENT_DATE - INTERVAL '7 days'
AND display_order IS NOT NULL
ORDER BY DATE(start_time) DESC, organization_id, registrar_id, start_time;
-- ========================================
-- 查询3只看今天的数据最直观
-- ========================================
SELECT
id AS ID,
organization_id AS ID,
registrar_id AS ID,
start_time AS ,
display_order AS
FROM adm_encounter
WHERE delete_flag = '0'
AND DATE(start_time) = CURRENT_DATE
AND display_order IS NOT NULL
ORDER BY organization_id, registrar_id, start_time;
-- ========================================
-- 查询4发现问题 - 找出同组内 display_order 重复的记录
-- ========================================
WITH ranked AS (
SELECT
id,
DATE(start_time) AS reg_date,
organization_id,
registrar_id,
start_time,
display_order,
ROW_NUMBER() OVER (
PARTITION BY DATE(start_time), organization_id, registrar_id
ORDER BY start_time
) AS should_be_order
FROM adm_encounter
WHERE delete_flag = '0'
AND start_time >= CURRENT_DATE - INTERVAL '7 days'
AND display_order IS NOT NULL
)
SELECT
reg_date AS ,
organization_id AS ID,
registrar_id AS ID,
COUNT(*) AS ,
STRING_AGG(id::text || '->' || display_order::text, ', ') AS
FROM ranked
WHERE display_order != should_be_order
GROUP BY reg_date, organization_id, registrar_id
ORDER BY reg_date DESC;

Some files were not shown because too many files have changed in this diff Show More