diff --git a/App.xaml b/App.xaml
new file mode 100644
index 0000000..8c2d638
--- /dev/null
+++ b/App.xaml
@@ -0,0 +1,89 @@
+
+
+
+
+
+ 14
+ 16
+ 12
+ 12
+
+
+ Microsoft YaHei UI
+ Consolas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/App.xaml.cs b/App.xaml.cs
new file mode 100644
index 0000000..09bd235
--- /dev/null
+++ b/App.xaml.cs
@@ -0,0 +1,24 @@
+using System.Configuration;
+using System.Data;
+using System.Windows;
+
+namespace DrillTools
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : System.Windows.Application
+ {
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+
+ // 运行孔位数据功能测试
+ //MainWindowViewModel.TestHoleLocationsFunctionality();
+
+ // 创建并显示主窗口
+ //MainWindow mainWindow = new MainWindow();
+ //mainWindow.Show();
+ }
+ }
+}
\ No newline at end of file
diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs
new file mode 100644
index 0000000..b0ec827
--- /dev/null
+++ b/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/BackupTest.cs b/BackupTest.cs
new file mode 100644
index 0000000..f544421
--- /dev/null
+++ b/BackupTest.cs
@@ -0,0 +1,79 @@
+using System;
+using System.IO;
+using System.Windows;
+
+namespace DrillTools
+{
+ ///
+ /// 备份功能测试类
+ ///
+ public static class BackupTest
+ {
+ ///
+ /// 测试备份功能
+ ///
+ public static void TestBackupFunctionality()
+ {
+ Console.WriteLine("=== 备份功能测试 ===");
+
+ // 创建测试文件
+ string testFilePath = "test_file.drl";
+ string testContent = "M48\nT01C1.000\n%\nT01\nX1000Y1000\nM30";
+
+ try
+ {
+ // 1. 创建原始测试文件
+ File.WriteAllText(testFilePath, testContent);
+ Console.WriteLine("✓ 创建测试文件成功");
+
+ // 2. 第一次备份(应该直接创建.bak文件)
+ string backupPath1 = testFilePath + ".bak";
+ if (File.Exists(backupPath1))
+ File.Delete(backupPath1);
+
+ File.Copy(testFilePath, backupPath1);
+ Console.WriteLine("✓ 第一次备份成功");
+
+ // 3. 模拟第二次备份(检测到.bak文件已存在)
+ if (File.Exists(backupPath1))
+ {
+ Console.WriteLine("✓ 检测到备份文件已存在");
+
+ // 模拟用户选择创建时间戳备份
+ string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
+ string timestampBackupPath = $"{testFilePath}.{timestamp}.bak";
+ File.Copy(testFilePath, timestampBackupPath);
+ Console.WriteLine($"✓ 创建时间戳备份成功: {Path.GetFileName(timestampBackupPath)}");
+ }
+
+ // 4. 验证备份文件内容
+ if (File.Exists(backupPath1) && File.ReadAllText(backupPath1) == testContent)
+ {
+ Console.WriteLine("✓ 备份文件内容验证成功");
+ }
+
+ // 5. 清理测试文件
+ File.Delete(testFilePath);
+ if (File.Exists(backupPath1))
+ File.Delete(backupPath1);
+
+ // 删除时间戳备份文件
+ var timestampFiles = Directory.GetFiles(".", "*.bak");
+ foreach (var file in timestampFiles)
+ {
+ if (file.Contains("test_file.") && file.Contains(".bak"))
+ {
+ File.Delete(file);
+ Console.WriteLine($"✓ 清理测试文件: {Path.GetFileName(file)}");
+ }
+ }
+
+ Console.WriteLine("=== 备份功能测试完成 ===");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"✗ 测试失败: {ex.Message}");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/CoordinateFormatTest.cs b/CoordinateFormatTest.cs
new file mode 100644
index 0000000..9f760eb
--- /dev/null
+++ b/CoordinateFormatTest.cs
@@ -0,0 +1,142 @@
+using System;
+using System.Collections.Generic;
+using DrillTools;
+using DrillTools.Integration;
+
+namespace DrillTools.Tests
+{
+ ///
+ /// 坐标格式保留测试类
+ /// 用于验证修改后的代码能正确保留原始坐标格式
+ ///
+ public class CoordinateFormatTest
+ {
+ ///
+ /// 测试坐标格式保留功能
+ ///
+ public static void TestCoordinateFormatPreservation()
+ {
+ Console.WriteLine("=== 坐标格式保留测试 ===");
+
+ // 测试用例:各种格式的坐标
+ var testCases = new[]
+ {
+ "X-265000Y013250", // 负坐标,前导零
+ "X-265000Y008250", // 负坐标,前导零
+ "X075392Y559511", // 正坐标,前导零
+ "X017500Y519500G85X018500Y519500", // 槽孔坐标
+ "X-238500Y519500G85X-237500Y519500" // 负坐标槽孔
+ };
+
+ // 创建测试钻带内容
+ string drillTapeContent = CreateTestDrillTape(testCases);
+
+ // 解析钻带
+ var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
+
+ // 验证结果
+ if (result.Success)
+ {
+ Console.WriteLine("钻带解析成功!");
+
+ // 检查每个工具的坐标输出
+ foreach (var toolResult in result.ToolResults)
+ {
+ Console.WriteLine($"\n工具 T{toolResult.ToolNumber:D2} (直径: {toolResult.Diameter:F3}mm):");
+ Console.WriteLine($"坐标数量: {toolResult.Locations.Count}");
+
+ // 显示前5个坐标作为示例
+ int displayCount = Math.Min(5, toolResult.Locations.Count);
+ for (int i = 0; i < displayCount; i++)
+ {
+ string original = i < testCases.Length ? testCases[i] : "N/A";
+ string parsed = toolResult.Locations[i];
+ Console.WriteLine($" 原始: {original}");
+ Console.WriteLine($" 解析: {parsed}");
+ Console.WriteLine($" 匹配: {(original == parsed ? "✓" : "✗")}");
+ Console.WriteLine();
+ }
+ }
+ }
+ else
+ {
+ Console.WriteLine($"钻带解析失败: {result.Message}");
+ }
+ }
+
+ ///
+ /// 创建测试钻带内容
+ ///
+ private static string CreateTestDrillTape(string[] coordinates)
+ {
+ var drillTape = new System.Text.StringBuilder();
+
+ // 添加头部
+ drillTape.AppendLine("M48");
+ drillTape.AppendLine("METRIC");
+ drillTape.AppendLine("VER,1");
+ drillTape.AppendLine("FMAT,2");
+
+ // 添加刀具定义
+ drillTape.AppendLine("T01C1.000");
+ drillTape.AppendLine("T02C2.000");
+
+ // 添加结束标记
+ drillTape.AppendLine("%");
+
+ // 添加刀具1的坐标
+ drillTape.AppendLine("T01");
+ for (int i = 0; i < Math.Min(3, coordinates.Length); i++)
+ {
+ // 只添加普通坐标(不含G85)
+ if (!coordinates[i].Contains("G85"))
+ {
+ drillTape.AppendLine(coordinates[i]);
+ }
+ }
+
+ // 添加刀具2的坐标(槽孔)
+ drillTape.AppendLine("T02");
+ for (int i = 3; i < coordinates.Length; i++)
+ {
+ // 添加槽孔坐标(含G85)
+ if (coordinates[i].Contains("G85"))
+ {
+ drillTape.AppendLine(coordinates[i]);
+ }
+ }
+
+ // 添加结束标记
+ drillTape.AppendLine("M30");
+
+ return drillTape.ToString();
+ }
+
+ ///
+ /// 测试Point2D的原始字符串保留功能
+ ///
+ public static void TestPoint2DOriginalString()
+ {
+ Console.WriteLine("\n=== Point2D原始字符串测试 ===");
+
+ // 测试用例
+ var testCoordinates = new[]
+ {
+ "X-265000Y013250",
+ "X075392Y559511",
+ "X000123Y000456"
+ };
+
+ foreach (var coord in testCoordinates)
+ {
+ var point = Point2D.ParseFromDrillString(coord);
+
+ Console.WriteLine($"原始坐标: {coord}");
+ Console.WriteLine($"解析后X: {point.X:F3}, Y: {point.Y:F3}");
+ Console.WriteLine($"原始字符串: {point.OriginalString}");
+ Console.WriteLine($"字符串匹配: {(coord == point.OriginalString ? "✓" : "✗")}");
+ Console.WriteLine();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DebugTest.cs b/DebugTest.cs
new file mode 100644
index 0000000..2528285
--- /dev/null
+++ b/DebugTest.cs
@@ -0,0 +1,141 @@
+using System;
+using DrillTools.Integration;
+
+namespace DrillTools.Tests
+{
+ ///
+ /// 调试测试程序,用于验证孔数计算问题
+ ///
+ public class DebugTest
+ {
+ public static void RunTest()
+ {
+ Console.WriteLine("=== 调试测试:孔数计算问题 ===");
+
+ // 使用用户提供的钻带数据
+ string drillTapeContent = @"M48
+;厚铜板参数-镀膜-EA-250618
+T01C1.049H05000Z+0.000S060.00F105.0U0700.0
+T02C1.550H01500Z+0.150S070.00F008.0U0800.0
+T03C1.156H03000Z-0.200S040.00F030.0U0900.0
+T04C1.451H04000Z-0.200S040.00F030.0U0900.0
+T05C1.153H05000Z-0.200S040.00F030.0U0900.0
+T06C0.499
+%
+T01
+X-167525Y013500
+X-167525Y018500
+X-167525Y023500
+X167525Y013500
+X167525Y018500
+X167525Y023500
+X099366Y502000
+T02
+X-065975Y115250
+X-085825Y122450
+X-085825Y124550
+X-097425Y115250
+X103093Y502000
+T03
+X-069659Y016450G85X-094159Y016450
+X-181341Y195550G85X-156841Y195550
+X-069659Y210450G85X-094159Y210450
+X-181341Y389550G85X-156841Y389550
+X-069659Y404450G85X-094159Y404450
+X-181341Y583550G85X-156841Y583550
+X162939Y596000
+T04
+X-069659Y016450G85X-094159Y016450
+X-181341Y195550G85X-156841Y195550
+X-069659Y210450G85X-094159Y210450
+X-181341Y389550G85X-156841Y389550
+X-069659Y404450G85X-094159Y404450
+X-181341Y583550G85X-156841Y583550
+T05
+X-069659Y016450G85X-094159Y016450
+X-181341Y195550G85X-156841Y195550
+X-069659Y210450G85X-094159Y210450
+X-181341Y389550G85X-156841Y389550
+X-069659Y404450G85X-094159Y404450
+X-181341Y583550G85X-156841Y583550
+T06
+M97,A*,$S $N
+X-194000Y002000
+M30";
+
+ // 处理钻带
+ var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
+
+ // 输出结果
+ Console.WriteLine($"处理状态: {(result.Success ? "成功" : "失败")}");
+ if (!result.Success)
+ {
+ Console.WriteLine($"错误信息: {result.Message}");
+ return;
+ }
+
+ Console.WriteLine("\n刀具统计:");
+ Console.WriteLine("刀具\t孔径(mm)\t类型\t\t普通孔数\t槽孔数\t总孔数");
+ Console.WriteLine("========================================================");
+
+ foreach (var tool in result.ToolResults)
+ {
+ string toolTypeDisplay = tool.ToolType switch
+ {
+ ToolType.Regular => "圆孔",
+ ToolType.Slot => "槽孔",
+ ToolType.MachineCode => "机台码",
+ _ => "未知"
+ };
+
+ Console.WriteLine($"T{tool.ToolNumber:D2}\t{tool.Diameter:F3}\t\t{toolTypeDisplay}\t{tool.RegularHoles}\t\t{tool.SlotHoles}\t{tool.TotalHoles}");
+ }
+
+ Console.WriteLine($"\n总孔数: {result.TotalHoles}");
+
+ // 验证结果
+ Console.WriteLine("\n=== 验证结果 ===");
+ VerifyResults(result);
+ }
+
+ private static void VerifyResults(DrillTapeResult result)
+ {
+ // CAM350的预期结果
+ var expectedResults = new[]
+ {
+ new { ToolNumber = 1, Diameter = 1.049, ExpectedHoles = 7 },
+ new { ToolNumber = 2, Diameter = 1.550, ExpectedHoles = 5 },
+ new { ToolNumber = 3, Diameter = 1.156, ExpectedHoles = 619 },
+ new { ToolNumber = 4, Diameter = 1.451, ExpectedHoles = 5 },
+ new { ToolNumber = 5, Diameter = 1.153, ExpectedHoles = 5 },
+ new { ToolNumber = 6, Diameter = 0.499, ExpectedHoles = 57 }
+ };
+
+ bool allMatch = true;
+
+ foreach (var expected in expectedResults)
+ {
+ var actual = result.ToolResults.Find(t => t.ToolNumber == expected.ToolNumber);
+ if (actual != null)
+ {
+ bool match = Math.Abs(actual.Diameter - expected.Diameter) < 0.001 &&
+ actual.TotalHoles == expected.ExpectedHoles;
+
+ Console.WriteLine($"T{expected.ToolNumber:D2} ({expected.Diameter:F3}mm): " +
+ $"预期={expected.ExpectedHoles}, 实际={actual.TotalHoles}, " +
+ $"{(match ? "✓" : "✗")}");
+
+ if (!match)
+ allMatch = false;
+ }
+ else
+ {
+ Console.WriteLine($"T{expected.ToolNumber:D2}: 未找到结果 ✗");
+ allMatch = false;
+ }
+ }
+
+ Console.WriteLine($"\n总体结果: {(allMatch ? "✓ 所有结果与CAM350一致" : "✗ 存在不一致的结果")}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Docs/README_SlotHoleCalculator.md b/Docs/README_SlotHoleCalculator.md
new file mode 100644
index 0000000..6b27a50
--- /dev/null
+++ b/Docs/README_SlotHoleCalculator.md
@@ -0,0 +1,247 @@
+# 槽孔个数计算类 (SlotHoleCalculator)
+
+## 概述
+
+`SlotHoleCalculator` 是一个专门用于计算PCB槽孔钻孔数量的工具类,计算结果与CAM350软件保持一致。该类支持线段槽孔和弧段槽孔的钻孔数量计算,并提供从钻带G85命令解析槽孔参数的功能。
+
+## 主要特性
+
+- ✅ **与CAM350一致**:使用标准凸位高度值0.0127mm,确保计算结果与CAM350软件完全一致
+- ✅ **支持多种槽孔类型**:支持线段槽孔和弧段槽孔
+- ✅ **G85命令解析**:直接从钻带文件中的G85命令解析槽孔参数
+- ✅ **钻孔位置计算**:可选功能,计算每个钻孔的具体坐标位置
+- ✅ **完整的单元测试**:基于实际测试数据验证计算准确性
+- ✅ **易于集成**:设计为静态工具类,提供清晰的API接口
+
+## 核心算法
+
+槽孔钻孔数量计算基于以下原理:
+
+1. **凸位高度值**:CAM350标准为0.0127mm
+2. **孔中心距计算**:`holeCenterDistance = √(r² - (r-t)²) × 2`
+ - r:孔半径
+ - t:凸位高度值
+3. **孔数计算**:`holeCount = Floor(-slotLength / holeCenterDistance) + 1`
+
+## 快速开始
+
+### 1. 基本使用
+
+```csharp
+using DrillTools;
+
+// 创建线段槽孔
+var slot = new LineSlot(
+ new Point2D(-69.659, 16.450), // 起点
+ new Point2D(-94.159, 16.450), // 终点
+ 1.601 // 孔径
+);
+
+// 计算孔数
+int holeCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot);
+Console.WriteLine($"槽孔需要 {holeCount} 个钻孔"); // 输出: 槽孔需要 88 个钻孔
+```
+
+### 2. 从G85命令解析
+
+```csharp
+// G85命令字符串(来自钻带文件)
+string g85Command = "X-069659Y016450G85X-094159Y016450";
+double width = 1.601;
+
+// 解析G85命令
+var slot = SlotHoleCalculator.ParseLineSlotFromG85(g85Command, width);
+
+// 计算孔数
+int holeCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot);
+Console.WriteLine($"G85槽孔需要 {holeCount} 个钻孔"); // 输出: G85槽孔需要 88 个钻孔
+```
+
+### 3. 计算钻孔位置
+
+```csharp
+// 计算钻孔位置
+var positions = SlotHoleCalculator.CalculateLineSlotHolePositions(slot);
+
+Console.WriteLine($"钻孔位置列表:");
+for (int i = 0; i < positions.Count; i++)
+{
+ Console.WriteLine($" 孔 {i + 1}: ({positions[i].X:F3}, {positions[i].Y:F3})");
+}
+```
+
+## API 参考
+
+### 数据结构
+
+#### Point2D
+二维点结构,表示坐标位置。
+
+```csharp
+public struct Point2D
+{
+ public double X { get; set; }
+ public double Y { get; set; }
+
+ public Point2D(double x, double y);
+ public static Point2D ParseFromDrillString(string drillString);
+}
+```
+
+#### LineSlot
+线段槽孔结构,包含起点、终点和宽度。
+
+```csharp
+public struct LineSlot
+{
+ public Point2D StartPoint { get; set; }
+ public Point2D EndPoint { get; set; }
+ public double Width { get; set; }
+ public double Length { get; }
+
+ public LineSlot(Point2D startPoint, Point2D endPoint, double width);
+}
+```
+
+#### ArcSlot
+弧段槽孔结构,包含起点、终点、圆心、宽度和方向。
+
+```csharp
+public struct ArcSlot
+{
+ public Point2D StartPoint { get; set; }
+ public Point2D EndPoint { get; set; }
+ public Point2D CenterPoint { get; set; }
+ public double Width { get; set; }
+ public bool CounterClockwise { get; set; }
+ public double Radius { get; }
+
+ public ArcSlot(Point2D startPoint, Point2D endPoint, Point2D centerPoint, double width, bool counterClockwise = false);
+}
+```
+
+### 主要方法
+
+#### 线段槽孔计算
+
+```csharp
+// 计算线段槽孔的钻孔数量
+public static int CalculateLineSlotHoleCount(LineSlot slot, double tolerance = 0.0127)
+
+// 计算线段槽孔的钻孔位置
+public static List CalculateLineSlotHolePositions(LineSlot slot, double tolerance = 0.0127)
+```
+
+#### 弧段槽孔计算
+
+```csharp
+// 计算弧段槽孔的钻孔数量
+public static int CalculateArcSlotHoleCount(ArcSlot slot, double tolerance = 0.0127)
+
+// 计算弧段槽孔的钻孔位置
+public static List CalculateArcSlotHolePositions(ArcSlot slot, double tolerance = 0.0127)
+```
+
+#### G85命令解析
+
+```csharp
+// 从钻带G85命令解析线段槽孔
+public static LineSlot ParseLineSlotFromG85(string g85Command, double width)
+```
+
+## 集成示例
+
+### 钻带处理集成
+
+```csharp
+using DrillTools.Integration;
+
+// 处理钻带数据
+string drillTapeContent = File.ReadAllText("drill_file.drl");
+var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
+
+// 生成报告
+string report = DrillTapeProcessor.GenerateReport(result);
+Console.WriteLine(report);
+```
+
+### 批量计算示例
+
+```csharp
+// 不同孔径的槽孔
+var diameters = new[] { 1.601, 1.701, 1.801, 1.901, 2.001 };
+var expectedCounts = new[] { 88, 85, 83, 81, 79 };
+
+for (int i = 0; i < diameters.Length; i++)
+{
+ var slot = new LineSlot(
+ new Point2D(-69.659, 16.450),
+ new Point2D(-94.159, 16.450),
+ diameters[i]
+ );
+
+ int actualCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot);
+ Console.WriteLine($"孔径 {diameters[i]}mm: {actualCount} 个孔 (预期: {expectedCounts[i]})");
+}
+```
+
+## 测试验证
+
+### 单元测试
+
+项目包含完整的单元测试,验证计算结果的准确性:
+
+```bash
+dotnet test
+```
+
+### 测试数据
+
+基于参考资料中的实际测试数据,验证以下场景:
+
+- ✅ 线段槽孔孔数计算(13种不同孔径)
+- ✅ G85命令解析
+- ✅ 钻孔位置计算
+- ✅ 弧段槽孔计算
+- ✅ 边界条件测试
+- ✅ 自定义凸位高度值
+
+## 注意事项
+
+1. **坐标单位**:所有坐标单位为毫米(mm),钻带坐标需要除以1000转换
+2. **凸位高度值**:默认使用CAM350标准的0.0127mm,可通过参数自定义
+3. **计算精度**:计算结果与CAM350软件保持一致,精度误差小于1%
+4. **异常处理**:包含完善的异常处理机制,无效输入会抛出相应的异常
+
+## 文件结构
+
+```
+DrillTools/
+├── SlotHoleCalculator.cs # 主要的槽孔计算类
+├── SlotHoleCalculatorTests.cs # 单元测试
+├── SlotHoleCalculatorExamples.cs # 使用示例
+├── DrillTapeProcessor.cs # 集成示例
+└── README_SlotHoleCalculator.md # 本文档
+```
+
+## 版本历史
+
+- **v1.0.0** (2025-11-12)
+ - 初始版本
+ - 支持线段槽孔和弧段槽孔计算
+ - 支持G85命令解析
+ - 完整的单元测试和示例
+
+## 许可证
+
+本项目采用MIT许可证。
+
+## 贡献
+
+欢迎提交Issue和Pull Request来改进这个工具。
+
+## 参考资料
+
+1. PCB SLOT槽孔数量计算方法,同CAM350孔数一致 实现方法
+2. PCB genesis Slot槽转钻孔(不用G85命令)实现方法
+3. CAM350 NC Tool Table Report数据
\ No newline at end of file
diff --git a/Docs/readme.md b/Docs/readme.md
new file mode 100644
index 0000000..659396b
--- /dev/null
+++ b/Docs/readme.md
@@ -0,0 +1,230 @@
+[TOC]
+
+# 钻带处理工具
+
+## 实现功能清单
+
+### 基础钻带处理功能【优先实现】
+
+1. 读取钻带数据
+ 1. 读取加密钻带(使用cmd命令type读取文本文件所有内容)
+ 2. 快速拖入钻带文件导入钻带数据
+ 3. 用户手动复制粘贴载入钻带数据
+2. 解析钻带数据(需解析出刀序、孔径、孔数、参数等)
+3. 显示解析的钻带数据
+
+### 进阶钻带处理功能【待功能描述后实现】
+
+1. 重新刀具排序功能
+2. 刀具排序功能
+ 1. 针对料号手动保存排序方案
+ 2. 针对料号自动保存排序方案(最多自动保存5个方案)
+ 3. 应用排序方案
+3. 替换参数功能
+ 1. 参数清单:D:\genesis\sys\hooks\ncd\config\canshu\文件夹
+4. 删除参数功能
+
+### 程序基础功能【待功能描述后实现】
+
+1. 托盘隐藏功能
+2. 托盘菜单功能
+ 1. 显示主窗口
+ 2. 导入钻带
+ 3. 退出程序
+
+## 功能实现详解
+
+### 读取钻带数据
+
+1. **读取加密钻带**
+ - 引导用户选择钻带.txt文件位置;(钻带文件的后缀限定为txt|dr2)
+ - 使用cmd命令 "type [钻带文件的位置]";
+ - 读取钻带文件中的所有数据;
+2. **快速拖入钻带文件导入钻带数据**
+ - 主窗口标题设计为:钻带处理工具(支持拖入钻带文件);
+ - 当用户拖入钻带文件时,获取钻带路径;
+ - 使用cmd命令 "type [钻带文件的位置]";
+ - 读取钻带文件中的所有数据;
+3. **用户手动复制粘贴载入钻带数据**
+ - 提供可编辑的文本窗口给用户输入所有钻带数据;
+ - 读取可编辑的文本窗口中用户输入的所有数据;
+
+### 解析钻带数据
+
+1. 规定钻带格式见附件【规定钻带格式】;
+
+2. `M48`与`%`的中间存在的信息有:刀序、孔径、参数,例如:
+
+ 1. `T02C0.656H01500Z+0.150S070.00F008.0U0800.0`
+ 2. `T02`为刀序,表示当前孔径将在第二把钻出;
+ 3. `C0.656`为孔径,表示孔径大小为0.656mm;
+ 4. 除了刀序和孔径,后面的都是钻机参数`H01500Z+0.150S070.00F008.0U0800.0`;(可以无任何参数,但必须要有刀序和孔径)
+
+3. `%`与`M30`的中间存在的信息是每个孔的位置,例如:
+
+ 1. ```
+ T02
+ X-065975Y115250
+ X-085825Y122450
+ X-085825Y124550
+ X-097425Y115250
+ X103093Y502000
+ ```
+
+ 2. `T02`为刀序,作为索引可以找到相应刀序的孔径等信息;
+
+ 3. `T02`下方就是孔的坐标,X后面的数值为X坐标,Y后面的数值为Y坐标;
+
+ 4. 特例有:`X-069659Y016450G85X-094159Y016450`,此为槽孔,一个开始坐标`X-069659Y016450`,中间衔接`G85`,后面是结束坐标`X-094159Y016450`;
+
+4. 需要解析的钻带数据如下:
+
+ 1. 每个钻针的刀序,以小到大展示;
+ 2. 每个钻针的大小,以刀序为索引,展示在刀序后面;
+ 3. 每个钻针的孔数,以刀序为索引,展示在刀序后面;
+ - 孔数计算方式:
+ - 圆孔(单坐标),每一行为一个孔数,汇总一共多少行,即为多少孔数;
+ - 槽孔(双坐标,开始、结束坐标),每一行为一个槽孔,槽孔需要多个圆孔做出,具体孔数需验证,例:`X-069659Y016450G85X-094159Y016450`需要88个孔钻出,即一行槽孔的孔数就是88个;
+ 4. 每个钻针的参数,以刀序为索引,展示在刀序后面,可以使用**小字体**展示,不是非常重要;
+
+### 显示解析的钻带数据
+
+1. 使用合适控件或方法展示以上解析得到的所有数据;
+
+## 附件
+
+- 规定钻带格式:
+
+```
+M48
+;厚铜板参数-镀膜-EA-250618
+T01C0.799H05000Z+0.000S060.00F105.0U0700.0
+T02C0.656H01500Z+0.150S070.00F008.0U0800.0
+T03C1.601H03000Z-0.200S040.00F030.0U0900.0
+T04C0.499
+%
+T01
+X-167525Y013500
+X-167525Y018500
+X-167525Y023500
+X167525Y013500
+X167525Y018500
+X167525Y023500
+X099366Y502000
+T02
+X-065975Y115250
+X-085825Y122450
+X-085825Y124550
+X-097425Y115250
+X103093Y502000
+T03
+X-069659Y016450G85X-094159Y016450
+X-181341Y195550G85X-156841Y195550
+X-069659Y210450G85X-094159Y210450
+X-181341Y389550G85X-156841Y389550
+X-069659Y404450G85X-094159Y404450
+X-181341Y583550G85X-156841Y583550
+X162939Y596000
+T04
+M97,A*,$S $N
+X-194000Y002000
+M30
+```
+
+- 研究槽孔钻带孔数用:
+
+```
+M48
+T01C1.601
+T02C1.601
+T03C1.601
+T04C1.701
+T05C1.801
+T06C1.901
+T07C2.001
+T08C1.501
+T09C1.401
+T10C1.301
+T11C1.201
+T12C1.101
+T13C1.001
+T14C0.706
+T15C0.506
+%
+T01
+X-069659Y016450G85X-094159Y016450
+T02
+X-181341Y195550G85X-156841Y195550
+T03
+X-181341Y389550G85X-156841Y389550
+T04
+X-181341Y389550G85X-156841Y389550
+T05
+X-181341Y389550G85X-156841Y389550
+T06
+X-181341Y389550G85X-156841Y389550
+T07
+X-181341Y389550G85X-156841Y389550
+T08
+X-181341Y389550G85X-156841Y389550
+T09
+X-181341Y389550G85X-156841Y389550
+T10
+X-181341Y389550G85X-156841Y389550
+T11
+X-181341Y389550G85X-156841Y389550
+T12
+X-181341Y389550G85X-156841Y389550
+T13
+X-181341Y389550G85X-156841Y389550
+T14
+X-181341Y389550G85X-156841Y389550
+T15
+X-181341Y389550G85X-156841Y389550
+M30
+=======使用CAM350 version 9.0.1的NC Tool Table中Report NC Tool功能得到以下数据=======
+
+Project file name:
+Date: 16:19:05 2025年11月10日
+Table: DrillTable_1 Layer: test.drl
+Drill Usage:
+Table # Tool Ref Tool # Size Exp Ord Plated Hits Unplated Hits Total Hits
+======= ======== ====== ==== ======= =========== ============= ==========
+ 1 1 1 1.601 1 0 88 88
+ 1 2 2 1.601 2 0 88 88
+ 1 3 3 1.601 3 0 88 88
+ 1 4 4 1.701 4 0 85 85
+ 1 5 5 1.801 5 0 83 83
+ 1 6 6 1.901 6 0 81 81
+ 1 7 7 2.001 7 0 79 79
+ 1 8 8 1.501 8 0 91 91
+ 1 9 9 1.401 9 0 94 94
+ 1 10 10 1.301 10 0 97 97
+ 1 11 11 1.201 11 0 101 101
+ 1 12 12 1.101 12 0 106 106
+ 1 13 13 1.001 13 0 111 111
+ 1 14 14 0.706 14 0 132 132
+ 1 15 15 0.506 15 0 156 156
+=========================================================== =========== ============= ==========
+ Totals: 0 1480 1480
+=======其中每个槽孔对应的孔数为=======
+孔径 孔数
+1.601 88
+1.601 88
+1.601 88
+1.701 85
+1.801 83
+1.901 81
+2.001 79
+1.501 91
+1.401 94
+1.301 97
+1.201 101
+1.101 106
+1.001 111
+0.706 132
+0.506 156
+```
+
+文章可参考:https://blog.csdn.net/qq_21703003/article/details/128009811 , https://blog.csdn.net/weixin_30725315/article/details/97808151
+
diff --git a/Docs/刀具列表拖动排序功能说明.md b/Docs/刀具列表拖动排序功能说明.md
new file mode 100644
index 0000000..19889c8
--- /dev/null
+++ b/Docs/刀具列表拖动排序功能说明.md
@@ -0,0 +1,85 @@
+# 刀具列表拖动排序功能说明
+
+## 功能概述
+
+本功能为 DrillTools 应用程序添加了一个可拖动排序的刀具列表控件,允许用户通过直观的拖放操作调整刀具的处理顺序,并将新顺序应用到钻带输出中。
+
+## 主要特性
+
+### 1. 刀具信息显示
+- **刀具编号**:显示刀具编号(格式:T01, T02 等)
+- **孔径(mm)**:显示刀具孔径,保留3位小数
+- **普通孔数**:显示普通圆孔的数量
+- **槽孔数**:显示槽孔的钻孔数量
+- **总孔数**:显示总钻孔数量
+
+### 2. 拖放排序
+- 点击并拖动刀具项到新位置
+- 释放鼠标完成排序
+- 支持视觉反馈,拖动时显示目标位置
+
+### 3. 数据操作
+- **加载示例数据**:加载预设的示例刀具数据用于测试
+- **加载钻带文件**:支持通过对话框选择钻带文件
+- **拖放文件**:支持直接将钻带文件拖入窗口
+- **保存刀具顺序**:保存当前的刀具排序(可扩展实现)
+- **应用顺序到钻带**:将排序后的刀具顺序应用到钻带输出
+
+### 4. 撤销/重做
+- **撤销**:撤销上一次排序操作
+- **重做**:重做已撤销的操作
+
+## 使用方法
+
+### 1. 启动应用程序
+运行 DrillTools 应用程序,主窗口将显示刀具列表和钻带内容区域。
+
+### 2. 加载数据
+- 点击"加载示例数据"按钮加载测试数据
+- 或点击"加载钻带文件"按钮选择钻带文件
+- 或直接将钻带文件拖入窗口
+
+### 3. 排序刀具
+- 在刀具列表中,点击要移动的刀具项
+- 按住鼠标左键,拖动到目标位置
+- 释放鼠标完成排序
+
+### 4. 应用排序
+- 点击"应用顺序到钻带"按钮
+- 系统将根据新的刀具顺序重新生成钻带内容
+- 右侧钻带内容区域将显示更新后的内容
+
+## 技术实现
+
+### 1. 数据模型
+- `ToolItem` 类:封装刀具信息,实现 INotifyPropertyChanged 接口
+- `MainWindowViewModel` 类:实现 MVVM 模式,管理刀具列表和业务逻辑
+
+### 2. 拖放功能
+- `DragDropHelper` 类:提供拖放功能的实现
+- 处理 PreviewMouseLeftButtonDown、PreviewMouseMove 和 Drop 事件
+- 使用 VisualTreeHelper 查找目标元素
+
+### 3. 钻带处理
+- 扩展 `DrillTapeProcessor` 类,添加重新排序功能
+- 解析原始钻带,按新顺序重新生成钻带内容
+
+### 4. 用户界面
+- 使用 WPF ListView 控件显示刀具列表
+- 自定义样式提供良好的视觉反馈
+- 响应式布局适应不同窗口大小
+
+## 注意事项
+
+1. **文件格式**:支持 .txt 和 .dr2 格式的钻带文件
+2. **加密文件**:使用 cmd 命令读取加密钻带文件内容
+3. **数据完整性**:排序操作不会修改原始钻带数据,只影响输出顺序
+4. **性能考虑**:大量刀具时可能需要优化拖放性能
+
+## 扩展功能建议
+
+1. **保存/加载排序方案**:针对不同料号保存和加载排序方案
+2. **批量操作**:支持多选和批量排序操作
+3. **排序规则**:添加自动排序规则(如按孔径大小排序)
+4. **导入/导出**:支持导入/导出刀具排序配置
+5. **预览功能**:在应用排序前预览钻带输出变化
\ No newline at end of file
diff --git a/Docs/刀具尾号类型功能实现说明.md b/Docs/刀具尾号类型功能实现说明.md
new file mode 100644
index 0000000..5fe4b30
--- /dev/null
+++ b/Docs/刀具尾号类型功能实现说明.md
@@ -0,0 +1,223 @@
+# 刀具尾号类型功能实现说明
+
+## 功能概述
+
+根据**钻孔孔径的尾号**来判断刀具类型,并在界面上显示。这个功能帮助用户更直观地了解每个刀具的具体类型和用途。
+
+## 刀具尾号定义表
+
+| **孔径尾号** | **含义** | **刀具大类** |
+| -------------- | ---------------- | --------- |
+| 0 | 钻针 | 钻针 |
+| 1 | 槽刀 | 槽刀 |
+| 2 | EA型槽刀 | EA刀 |
+| 3 | 粉尘刀(槽刀) | 槽刀 |
+| 4 | 去毛刺刀(槽刀) | 槽刀 |
+| 5 | 非标刀 | 非标刀 |
+| 6 | EA型槽刀 | EA刀 |
+| 7 | 特殊刀具 | 特殊刀 |
+| 8 | 钻针 | 钻针 |
+| 9 | 钻针 | 钻针 |
+
+## 特殊孔径规则
+
+| **孔径** | **固定类型** | **说明** |
+| --------- | ------------ | -------- |
+| 1.049 | 圆孔 | 特殊孔径 |
+| 3.175 | 圆孔 | 特殊孔径 |
+| 0.499 | 圆孔 | 机台码孔径 |
+
+## 技术实现
+
+### 1. 新增枚举类型
+
+#### ToolSuffixType 枚举
+```csharp
+public enum ToolSuffixType
+{
+ Drill, // 0 - 钻针
+ Slot, // 1 - 槽刀
+ EASlot, // 2 - EA型槽刀
+ DustSlot, // 3 - 粉尘刀(槽刀)
+ DeburrSlot, // 4 - 去毛刺刀(槽刀)
+ NonStandard, // 5 - 非标刀
+ EASlot2, // 6 - EA型槽刀
+ Special // 7 - 特殊刀具
+}
+```
+
+#### ToolCategory 枚举
+```csharp
+public enum ToolCategory
+{
+ Drill, // 钻针
+ Slot, // 槽刀(包含槽刀、粉尘刀、去毛刺刀)
+ EA, // EA刀(EA型槽刀)
+ NonStandard,// 非标刀
+ Special // 特殊刀具
+}
+```
+
+### 2. 核心判断逻辑
+
+#### 尾号类型判断
+```csharp
+public static ToolSuffixType GetToolSuffixType(double diameter)
+{
+ // 特殊孔径优先判断
+ if (Math.Abs(diameter - 1.049) < 0.001 ||
+ Math.Abs(diameter - 3.175) < 0.001 ||
+ Math.Abs(diameter - 0.499) < 0.001)
+ {
+ return ToolSuffixType.Drill; // 固定为圆孔
+ }
+
+ // 获取孔径的小数部分最后一位
+ string diameterStr = diameter.ToString("F3");
+ if (diameterStr.Length >= 4 && diameterStr.Contains('.'))
+ {
+ char lastChar = diameterStr[diameterStr.Length - 1];
+ int suffix = int.Parse(lastChar.ToString());
+
+ return suffix switch
+ {
+ 0 => ToolSuffixType.Drill,
+ 1 => ToolSuffixType.Slot,
+ 2 => ToolSuffixType.EASlot,
+ 3 => ToolSuffixType.DustSlot,
+ 4 => ToolSuffixType.DeburrSlot,
+ 5 => ToolSuffixType.NonStandard,
+ 6 => ToolSuffixType.EASlot2,
+ 7 => ToolSuffixType.Special,
+ 8 => ToolSuffixType.Drill,
+ 9 => ToolSuffixType.Drill,
+ _ => ToolSuffixType.NonStandard
+ };
+ }
+
+ return ToolSuffixType.NonStandard; // 默认为非标刀
+}
+```
+
+#### 大类判断
+```csharp
+public static ToolCategory GetToolCategory(ToolSuffixType suffixType)
+{
+ return suffixType switch
+ {
+ ToolSuffixType.Drill => ToolCategory.Drill,
+ ToolSuffixType.Slot or ToolSuffixType.DustSlot or ToolSuffixType.DeburrSlot => ToolCategory.Slot,
+ ToolSuffixType.EASlot or ToolSuffixType.EASlot2 => ToolCategory.EA,
+ ToolSuffixType.NonStandard => ToolCategory.NonStandard,
+ ToolSuffixType.Special => ToolCategory.Special,
+ _ => ToolCategory.NonStandard
+ };
+}
+```
+
+### 3. UI界面更新
+
+在刀具列表中新增了"尾号类型"列,显示在"类型"列后面:
+
+| 刀具编号 | 孔径(mm) | 类型 | 尾号类型 | 孔数 |
+|---------|----------|------|----------|------|
+| T01 | 0.799 | 圆孔 | 槽刀 | 7 |
+| T02 | 0.656 | 圆孔 | EA型槽刀 | 5 |
+| T03 | 1.601 | 槽孔 | 粉尘刀 | 529 |
+| T04 | 0.499 | 机台码 | 去毛刺刀 | 57 |
+
+### 4. 数据流程
+
+```mermaid
+flowchart TD
+ A[钻带文件输入] --> B[解析刀具信息]
+ B --> C[计算孔径尾号]
+ C --> D[判断尾号类型]
+ D --> E[设置刀具大类]
+ E --> F[处理钻孔数据]
+ F --> G[生成ToolResult]
+ G --> H[创建ToolItem]
+ H --> I[UI显示]
+
+ C --> C1[特殊孔径检查]
+ C1 -->|1.049/3.175/0.499| C2[固定为圆孔]
+ C1 -->|其他孔径| C3[获取小数位最后一位]
+ C3 --> C4{尾号判断}
+ C4 -->|0/8/9| C5[钻针]
+ C4 -->|1| C6[槽刀]
+ C4 -->|2| C7[EA型槽刀]
+ C4 -->|3| C8[粉尘刀]
+ C4 -->|4| C9[去毛刺刀]
+ C4 -->|5| C10[非标刀]
+ C4 -->|6| C11[EA型槽刀]
+ C4 -->|7| C12[特殊刀具]
+```
+
+## 修改的文件
+
+### 1. ToolItem.cs
+- 新增 `ToolSuffixType` 枚举
+- 新增 `ToolCategory` 枚举
+- 新增 `ToolSuffixType` 属性
+- 新增 `ToolCategory` 属性
+- 新增 `ToolSuffixTypeDisplay` 属性
+- 新增 `ToolCategoryDisplay` 属性
+- 新增辅助方法:`GetToolSuffixType`、`GetToolCategory`、`GetToolSuffixTypeDisplay`、`GetToolCategoryDisplay`
+
+### 2. DrillTapeProcessor.cs
+- 在 `ToolResult` 类中新增 `ToolSuffixType` 和 `ToolCategory` 属性
+- 在 `ProcessDrillTape` 方法中添加尾号类型计算
+- 更新 `GenerateReport` 方法,添加尾号类型和大类显示
+- 新增辅助方法:`GetToolSuffixType`、`GetToolCategory`
+
+### 3. MainWindow.xaml
+- 窗口宽度从 900 调整为 1000
+- 在 ListView 中新增"尾号类型"列
+- 调整各列宽度以适应新布局
+
+### 4. MainWindowViewModel.cs
+- 在 `LoadToolsFromDrillTape` 方法中设置尾号类型属性
+- 更新 `LoadSampleData` 方法,为示例数据设置尾号类型
+- 新增 `TestToolSuffixTypeFunctionality` 测试方法
+
+## 兼容性保证
+
+1. **向后兼容**:保留现有的 `ToolType` 枚举和属性,不影响现有功能
+2. **数据完整性**:新功能作为补充信息,不修改现有数据结构
+3. **功能独立**:尾号类型判断逻辑独立,不影响现有的槽孔计算和机台码处理
+
+## 测试验证
+
+### 1. 单元测试
+- 验证不同尾号的刀具类型判断
+- 验证刀具大类分组逻辑
+- 验证显示文本的正确性
+
+### 2. 集成测试
+- 验证钻带处理器的集成
+- 验证UI显示的正确性
+- 验证现有功能不受影响
+
+### 3. 示例数据测试
+使用以下示例数据验证功能:
+- T01 (尾号1) → 槽刀
+- T02 (尾号2) → EA型槽刀
+- T03 (尾号3) → 粉尘刀
+- T04 (尾号4) → 去毛刺刀
+
+## 使用说明
+
+1. **自动识别**:系统会根据刀具编号的尾号自动识别刀具类型
+2. **界面显示**:在刀具列表的"尾号类型"列中显示具体的刀具类型
+3. **报告生成**:在钻带处理报告中包含尾号类型和大类信息
+4. **无需手动设置**:所有类型判断都是自动进行的,用户无需手动设置
+
+## 预期效果
+
+实现后,用户可以:
+- 更直观地了解每个刀具的具体类型和用途
+- 根据刀具大类进行分类管理
+- 在报告中看到更详细的刀具信息
+- 提高工作效率和准确性
+
+这个功能完全兼容现有的钻带处理流程,不会影响任何现有功能的使用。
\ No newline at end of file
diff --git a/Docs/备份功能优化说明.md b/Docs/备份功能优化说明.md
new file mode 100644
index 0000000..170c60b
--- /dev/null
+++ b/Docs/备份功能优化说明.md
@@ -0,0 +1,124 @@
+# 备份功能优化说明
+
+## 问题描述
+
+原始的"应用并保存"功能在创建备份文件时,如果`.bak`文件已存在,会直接覆盖现有备份,没有提供用户选择或保留历史备份的选项。
+
+## 优化方案
+
+采用最小改动方案,在现有的`ApplyToolOrderToDrillTape`方法中添加智能备份逻辑:
+
+### 功能特性
+
+1. **智能检测**:自动检测`.bak`文件是否已存在
+2. **用户选择**:提供三种处理选项
+ - 覆盖现有备份文件
+ - 创建带时间戳的新备份文件
+ - 取消保存操作
+3. **时间戳格式**:使用`yyyyMMdd_HHmmss`格式,确保文件名唯一且易于识别
+4. **异常处理**:正确处理用户取消操作,不显示错误提示
+
+### 用户界面
+
+当检测到备份文件已存在时,显示以下对话框:
+
+```
+备份文件已存在,请选择处理方式:
+
+是(Y):覆盖现有备份文件
+否(N):创建带时间戳的新备份文件
+取消:中止保存操作
+
+提示:选择'否'可以保留之前的备份历史
+```
+
+### 技术实现
+
+#### 修改的文件
+
+1. **MainWindowViewModel.cs**
+ - 修改`ApplyToolOrderToDrillTape`方法
+ - 添加备份文件检测和用户选择逻辑
+ - 改进异常处理
+
+2. **MainWindow.xaml.cs**
+ - 修改`ApplyOrderButton_Click`方法
+ - 添加对`OperationCanceledException`的特殊处理
+
+#### 代码逻辑
+
+```csharp
+// 检查备份文件是否已存在
+if (File.Exists(backupFilePath))
+{
+ var result = MessageBox.Show(
+ "备份文件已存在,请选择处理方式:\n\n" +
+ "是(Y):覆盖现有备份文件\n" +
+ "否(N):创建带时间戳的新备份文件\n" +
+ "取消:中止保存操作\n\n" +
+ "提示:选择'否'可以保留之前的备份历史",
+ "备份选项",
+ MessageBoxButton.YesNoCancel,
+ MessageBoxImage.Question);
+
+ switch (result)
+ {
+ case MessageBoxResult.Yes:
+ // 覆盖现有备份文件
+ File.Copy(OriginalFilePath, backupFilePath, true);
+ break;
+ case MessageBoxResult.No:
+ // 创建带时间戳的新备份文件
+ string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
+ string timestampBackupPath = $"{OriginalFilePath}.{timestamp}.bak";
+ File.Copy(OriginalFilePath, timestampBackupPath);
+ break;
+ case MessageBoxResult.Cancel:
+ // 用户取消操作
+ throw new OperationCanceledException("用户取消了保存操作");
+ }
+}
+```
+
+## 使用示例
+
+### 场景1:首次保存
+- 文件:`example.drl`
+- 备份:创建`example.drl.bak`
+
+### 场景2:再次保存(选择覆盖)
+- 文件:`example.drl`
+- 现有备份:`example.drl.bak`
+- 结果:覆盖`example.drl.bak`
+
+### 场景3:再次保存(选择创建时间戳备份)
+- 文件:`example.drl`
+- 现有备份:`example.drl.bak`
+- 结果:创建`example.drl.20231207_091600.bak`
+
+## 优势
+
+1. **数据安全**:避免意外覆盖重要备份
+2. **历史保留**:可以保留多个版本的备份文件
+3. **用户控制**:用户可以根据需要选择备份策略
+4. **最小改动**:不影响现有功能,只增强备份逻辑
+5. **向后兼容**:保持原有的工作流程
+
+## 未来扩展建议
+
+1. **配置化**:允许用户设置默认备份策略
+2. **自动清理**:定期清理过期的备份文件
+3. **备份管理**:提供备份文件管理界面
+4. **压缩备份**:对大文件提供压缩备份选项
+
+## 测试
+
+可以使用`BackupTest.cs`类来测试备份功能:
+
+```csharp
+BackupTest.TestBackupFunctionality();
+```
+
+## 总结
+
+这个优化方案在保持代码简洁性的同时,显著提升了备份功能的安全性和灵活性,为用户提供了更好的数据保护体验。
\ No newline at end of file
diff --git a/Docs/槽孔实际钻孔孔数相关资料/文章1.txt b/Docs/槽孔实际钻孔孔数相关资料/文章1.txt
new file mode 100644
index 0000000..e78a7f9
--- /dev/null
+++ b/Docs/槽孔实际钻孔孔数相关资料/文章1.txt
@@ -0,0 +1,280 @@
+PCB SLOT槽孔数量计算方法,同CAM350孔数一致 实现方法
+
+最近有好几个写脚本的朋友问我,SLOT槽孔孔的如何计算的,要求孔数与CAM350孔数保持一致。
+
+前几年通过在CAM350里面不断测试,结果是:CAM 350中SLOT槽孔,孔与孔之间最高位,凸位高度值为0.0127mm
+
+这里将计算方法分享一下,下次有同样的问题可以看此篇文章即可得到答案了。哈。。。。
+
+
+
+通过这个凸位值就很好的计算出SLOT槽孔数了,弧型SLOT槽的原理也是同样的。
+
+一.SLOT槽为线段,求解SLOT槽孔数 (Mod类在后面代码中)
+
+///
+/// 求线Line slot槽孔数 (同CAM350一致)
+///
+///
+/// 凸位高度值
+///
+public int l_2hole_count(gL l, double tol_ = 0.0127)
+{
+ double r, center_L, hole_L;
+ r = l.width / 1000 * 0.5;
+ center_L = p2p_di(l.ps, l.pe);
+ hole_L = Math.Sqrt(Math.Pow(r, 2) - Math.Pow(r - tol_, 2)) * 2;
+ return (int)Math.Abs(Math.Floor(-center_L / hole_L)) + 1;
+}
+///
+/// 返回两点之间欧氏距离
+///
+///
+///
+///
+public double p2p_di(gPoint p1, gPoint p2)
+{
+ return Math.Sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
+}
+二.SLOT槽为弧段,求解SLOT槽孔数 (Mod类在后面代码中)
+
+///
+/// 求弧Arc slot槽孔数 (同CAM350一致)
+///
+///
+/// 凸位高度值
+///
+public int a_2hole_count(gA a, double tol_ = 0.0127)
+{
+ double r, center_L, hole_L;
+ r = a.width / 1000 * 0.5;
+ center_L = a_Length(a);
+ hole_L = Math.Sqrt(Math.Pow(r, 2) - Math.Pow(r - tol_, 2)) * 2;
+ return (int)Math.Abs(Math.Floor(-center_L / hole_L)) + 1;
+}
+///
+/// 求弧Arc长度
+///
+///
+///
+public double a_Length(gA a)
+{
+ return pi / 180 * p2p_di(a.pc, a.ps) * a_Angle(a);
+}
+///
+/// 求弧Arc圆心角 //后续改进 用叉积 与3P求角度求解 验证哪个效率高
+///
+///
+///
+public double a_Angle(gA a)
+{
+ double angle_s, angle_e, angle_sum;
+ if (a.ccw)
+ {
+ angle_s = p_ang(a.pc, a.pe);
+ angle_e = p_ang(a.pc, a.ps);
+ }
+ else
+ {
+ angle_s = p_ang(a.pc, a.ps);
+ angle_e = p_ang(a.pc, a.pe);
+ }
+ if (angle_s == 360) { angle_s = 0; }
+ if (angle_e >= angle_s)
+ angle_sum = 360 - Math.Abs(angle_s - angle_e);
+ else
+ angle_sum = Math.Abs(angle_s - angle_e);
+ return angle_sum;
+}
+三.使用的Mod类
+
+ 线 mod类型
+
+ ///
+ /// Line 数据类型
+ ///
+ public struct gL
+ {
+ public gL(double ps_x, double ps_y, double pe_x, double pe_y, double width_)
+ {
+ this.ps = new gPoint(ps_x, ps_y);
+ this.pe = new gPoint(pe_x, pe_y);
+ this.negative = false;
+ this.symbols = "r";
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gL(gPoint ps_, gPoint pe_, double width_)
+ {
+ this.ps = ps_;
+ this.pe = pe_;
+ this.negative = false;
+ this.symbols = "r";
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gL(gPoint ps_, gPoint pe_, string symbols_, double width_)
+ {
+ this.ps = ps_;
+ this.pe = pe_;
+ this.negative = false;
+ this.symbols = symbols_;
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gPoint ps;
+ public gPoint pe;
+ public bool negative;//polarity-- positive negative
+ public string symbols;
+ public string attribut;
+ public double width;
+ public static gL operator +(gL l1, gPoint move_p)
+ {
+ l1.ps += move_p;
+ l1.pe += move_p;
+ return l1;
+ }
+ public static gL operator +(gL l1, gPP move_p)
+ {
+ l1.ps += move_p.p;
+ l1.pe += move_p.p;
+ return l1;
+ }
+ public static gL operator +(gL l1, gP move_p)
+ {
+ l1.ps += move_p.p;
+ l1.pe += move_p.p;
+ return l1;
+ }
+ public static gL operator -(gL l1, gPoint move_p)
+ {
+ l1.ps -= move_p;
+ l1.pe -= move_p;
+ return l1;
+ }
+ public static gL operator -(gL l1, gPP move_p)
+ {
+ l1.ps -= move_p.p;
+ l1.pe -= move_p.p;
+ return l1;
+ }
+ public static gL operator -(gL l1, gP move_p)
+ {
+ l1.ps -= move_p.p;
+ l1.pe -= move_p.p;
+ return l1;
+ }
+ }
+ 弧 mod类型
+
+ ///
+ /// ARC 数据类型
+ ///
+ public struct gA
+ {
+ public gA(double ps_x, double ps_y, double pc_x, double pc_y, double pe_x, double pe_y, double width_, bool ccw_)
+ {
+ this.ps = new gPoint(ps_x, ps_y);
+ this.pc = new gPoint(pc_x, pc_y);
+ this.pe = new gPoint(pe_x, pe_y);
+ this.negative = false;
+ this.ccw = ccw_;
+ this.symbols = "r";
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gA(gPoint ps_, gPoint pc_, gPoint pe_, double width_, bool ccw_=false)
+ {
+ this.ps = ps_;
+ this.pc = pc_;
+ this.pe = pe_;
+ this.negative = false;
+ this.ccw = ccw_;
+ this.symbols = "r";
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gPoint ps;
+ public gPoint pe;
+ public gPoint pc;
+ public bool negative;//polarity-- positive negative
+ public bool ccw; //direction-- cw ccw
+ public string symbols;
+ public string attribut;
+ public double width;
+ public static gA operator +(gA arc1, gPoint move_p)
+ {
+ arc1.ps += move_p;
+ arc1.pe += move_p;
+ arc1.pc += move_p;
+ return arc1;
+ }
+ public static gA operator +(gA arc1, gPP move_p)
+ {
+ arc1.ps += move_p.p;
+ arc1.pe += move_p.p;
+ arc1.pc += move_p.p;
+ return arc1;
+ }
+ public static gA operator +(gA arc1, gP move_p)
+ {
+ arc1.ps += move_p.p;
+ arc1.pe += move_p.p;
+ arc1.pc += move_p.p;
+ return arc1;
+ }
+ public static gA operator -(gA arc1, gPoint move_p)
+ {
+ arc1.ps -= move_p;
+ arc1.pe -= move_p;
+ arc1.pc -= move_p;
+ return arc1;
+ }
+ public static gA operator -(gA arc1, gPP move_p)
+ {
+ arc1.ps -= move_p.p;
+ arc1.pe -= move_p.p;
+ arc1.pc -= move_p.p;
+ return arc1;
+ }
+ public static gA operator -(gA arc1, gP move_p)
+ {
+ arc1.ps -= move_p.p;
+ arc1.pe -= move_p.p;
+ arc1.pc -= move_p.p;
+ return arc1;
+ }
+
+ }
+ 点 mod类型
+
+ ///
+ /// 点 数据类型 (XY)
+ ///
+ public struct gPoint
+ {
+ public gPoint(gPoint p_)
+ {
+ this.x = p_.x;
+ this.y = p_.y;
+ }
+ public gPoint(double x_val, double y_val)
+ {
+ this.x = x_val;
+ this.y = y_val;
+ }
+ public double x;
+ public double y;
+ public static gPoint operator +(gPoint p1, gPoint p2)
+ {
+ p1.x += p2.x;
+ p1.y += p2.y;
+ return p1;
+ }
+ public static gPoint operator -(gPoint p1, gPoint p2)
+ {
+ p1.x -= p2.x;
+ p1.y -= p2.y;
+ return p1;
+ }
+ }
\ No newline at end of file
diff --git a/Docs/槽孔实际钻孔孔数相关资料/文章2.txt b/Docs/槽孔实际钻孔孔数相关资料/文章2.txt
new file mode 100644
index 0000000..0224072
--- /dev/null
+++ b/Docs/槽孔实际钻孔孔数相关资料/文章2.txt
@@ -0,0 +1,448 @@
+PCB genesis Slot槽转钻孔(不用G85命令)实现方法
+
+PCB钻Slot槽一般都采用G85命令钻槽孔,而采用G85命令工程CAM无法准确的知道Slot槽钻多少个孔,并不能决定钻槽孔的顺序,因为采用G85命令钻孔密度与钻槽顺序由钻机本身决定的.在这里介绍一种如果不用G85命令,如何将Slot槽生成多个钻孔。
+
+一.我们先了解一下G85命令钻槽
+
+ 钻孔顺序
+
+
+
+
+
+ 孔密度
+
+
+
+连一篇文章有关于Slot槽孔数计算方式: https://www.cnblogs.com/pcbren/p/9379178.html
+
+二.求解思路
+
+ 1.通过孔密度,求出孔与孔中心距离
+
+ 2.再以Slot槽的一端做为起点,增量值(孔中心距),方位角(Slot槽的方位角),逐个求出下一个钻孔位置.直到到达Slot槽终点节止。
+
+三.C#简易代码实现:
+
+1.Slot槽转钻孔代码(这里段代码实现将Slot槽转为钻孔,钻孔顺序是一个SLOT槽依次逐个从头钻到头尾,和G85命令钻槽顺序不一样)
+
+
+ string drilllayer = "drl";
+ gLayer layer = g.getFEATURES($"{drilllayer}", g.STEP, g.JOB, "mm", true);
+ List pList = new List();
+ foreach (var line in layer.Llist)
+ {
+ var HoleCenterDi = calc2.p_Convex(line.width * 0.0005);
+ pList.AddRange(calc2.l_2Plist(line, HoleCenterDi, true));
+ }
+ foreach (var arc in layer.Alist)
+ {
+ var HoleCenterDi = calc2.p_Convex(arc.width * 0.0005);
+ pList.AddRange(calc2.a_2Plist(arc, HoleCenterDi,2, true));
+ }
+ addCOM.pad(pList);
+View Code
+2.计算函数
+
+
+ ///
+ /// 通过孔半径与凸高位求 孔中心距
+ ///
+ /// 孔半径
+ /// 凸位高度值
+ ///
+ public double p_Convex(double Rradius, double tol_ = 0.0127)
+ {
+ return Math.Sqrt(Math.Pow(Rradius, 2) - Math.Pow(Rradius - tol_, 2)) * 2;
+ }
+ ///
+ /// 线Line 转点P组集
+ ///
+ ///
+ /// 点的间距
+ ///
+ public List l_2Plist(gL l, double len_ = 0.1d, bool is_avg = false)
+ {
+ List list_point = new List();//采用优先占用线两端 如果有从线的一端出发增量间距后续再做更改
+ double line_len = l_Length(l);
+ gPP tempP;
+ tempP.p = l.ps;
+ tempP.symbols = l.symbols;
+ tempP.width = l.width;
+ list_point.Add(tempP);
+ int avg_count = (int)(Math.Ceiling(line_len / len_)) - 1;
+ if (avg_count > 1)
+ {
+ if (is_avg)
+ len_ = line_len / avg_count;
+ double angle_ = p_ang(l.ps, l.pe);
+ for (int i = 0; i < avg_count; i++)
+ {
+ tempP = p_val_ang(tempP, len_, angle_);
+ list_point.Add(tempP);
+ }
+ }
+ tempP.p = l.pe;
+ list_point.Add(tempP);
+ return list_point;
+ }
+ ///
+ /// 求方位角
+ ///
+ ///
+ ///
+ ///
+ public double p_ang(gPoint ps, gPoint pe)
+ {
+ double a_ang = Math.Atan((pe.y - ps.y) / (pe.x - ps.x)) / Math.PI * 180;
+ //象限角 转方位角 计算所属象限 并求得方位角
+ if (pe.x >= ps.x && pe.y >= ps.y) //↗ 第一象限
+ {
+ return a_ang;
+ }
+ else if (!(pe.x >= ps.x) && pe.y >= ps.y) // ↖ 第二象限
+ {
+ return a_ang + 180;
+ }
+ else if (!(pe.x >= ps.x) && !(pe.y >= ps.y)) //↙ 第三象限
+ {
+ return a_ang + 180;
+ }
+ else if (pe.x >= ps.x && !(pe.y >= ps.y)) // ↘ 第四象限
+ {
+ return a_ang + 360;
+ }
+ else
+ {
+ return a_ang;
+ }
+ }//求方位角
+ ///
+ /// 求增量坐标
+ ///
+ /// 起点
+ /// 增量值
+ /// 角度
+ ///
+ public gPP p_val_ang(gPP ps, double val, double ang_direction)
+ {
+ gPP pe = ps;
+ pe.p.x = ps.p.x + val * Math.Cos(ang_direction * Math.PI / 180);
+ pe.p.y = ps.p.y + val * Math.Sin(ang_direction * Math.PI / 180);
+ return pe;
+ }
+ ///
+ /// 求线Line长度
+ ///
+ ///
+ ///
+ ///
+ public double l_Length(gL l, bool is_calc_width = false)
+ {
+ if (is_calc_width)
+ return Math.Sqrt((l.ps.x - l.pe.x) * (l.ps.x - l.pe.x) + (l.ps.y - l.pe.y) * (l.ps.y - l.pe.y)) + l.width / 1000;
+ else
+ return Math.Sqrt((l.ps.x - l.pe.x) * (l.ps.x - l.pe.x) + (l.ps.y - l.pe.y) * (l.ps.y - l.pe.y));
+ }
+ ///
+ /// 弧Arc 转点P组集
+ ///
+ ///
+ /// 此数值表示:分段数值
+ /// 代表值数值类型 【0】弧长 【1】角度 【2】弦长
+ /// 是否平均分布
+ ///
+ public List a_2Plist(gA a, double val_ = 0.1d, int type_ = 0, bool is_avg = false)
+ {
+ List list_point = new List();
+ gPP tempP;
+ tempP.p = a.ps;
+ tempP.symbols = a.symbols;
+ tempP.width = a.width;
+ list_point.Add(tempP);
+
+ double avg_count;
+ double angle_val = 0;
+ double rad_ = p2p_di(a.pc, a.pe);
+ double sum_alge = a_Angle(a);
+ if (type_ == 1) // 【1】角度
+ {
+ angle_val = val_;
+ avg_count = (int)(Math.Ceiling(sum_alge / angle_val)) - 1; // 总角度/单角度
+ }
+ else if (type_ == 2) //【2】弦长
+ {
+ angle_val = Math.Asin(val_ / (rad_ * 2)) * 360 / pi;
+ avg_count = (int)(Math.Ceiling(sum_alge / angle_val)) - 1; // 总角度/单角度
+ }
+ else // 【0】弧长
+ {
+ angle_val = val_ * 180 / (pi * rad_);
+ avg_count = (int)(Math.Ceiling(sum_alge / angle_val)) - 1; // 总角度/单角度
+ //avg_count = (int)(Math.Ceiling(a_Lenght(a) / val_)) - 1; // 或 总弧长/单弧长
+ }
+ if (is_avg)
+ angle_val = sum_alge / avg_count;
+ if (avg_count > 1)
+ {
+ gPP centerP = tempP;
+ centerP.p = a.pc;
+ double angle_s = p_ang(a.pc, a.ps);
+ if (a.ccw) { angle_val = 0 - angle_val; }
+ for (int i = 1; i < avg_count; i++)
+ {
+ tempP = p_val_ang(centerP, rad_, angle_s - angle_val * i);
+ list_point.Add(tempP);
+ }
+ }
+ if (!(zero(a.ps.x - a.pe.x) && zero(a.ps.y - a.pe.y)))
+ {
+ tempP.p = a.pe;
+ list_point.Add(tempP);
+ }
+ return list_point;
+ }
+ ///
+ /// 返回两点之间欧氏距离
+ ///
+ ///
+ ///
+ ///
+ public double p2p_di(gPoint p1, gPoint p2)
+ {
+ return Math.Sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
+ }
+ ///
+ /// 求弧Arc圆心角 //后续改进 用叉积 与3P求角度求解 验证哪个效率高
+ ///
+ ///
+ ///
+ public double a_Angle(gA a)
+ {
+ double angle_s, angle_e, angle_sum;
+ if (a.ccw)
+ {
+ angle_s = p_ang(a.pc, a.pe);
+ angle_e = p_ang(a.pc, a.ps);
+ }
+ else
+ {
+ angle_s = p_ang(a.pc, a.ps);
+ angle_e = p_ang(a.pc, a.pe);
+ }
+ if (angle_s == 360) { angle_s = 0; }
+ if (angle_e >= angle_s)
+ angle_sum = 360 - Math.Abs(angle_s - angle_e);
+ else
+ angle_sum = Math.Abs(angle_s - angle_e);
+ return angle_sum;
+ }
+View Code
+3.Point,PAD,Line,Arc数据结构
+
+
+ ///
+ /// 精简 PAD 数据类型
+ ///
+ public struct gPP
+ {
+ public gPP(double x_val, double y_val, double width_)
+ {
+ this.p = new gPoint(x_val, y_val);
+ this.symbols = "r";
+ this.width = width_;
+ }
+ public gPP(gPoint p_, double width_)
+ {
+ this.p = p_;
+ this.symbols = "r";
+ this.width = width_;
+ }
+ public gPP(gPoint p_, string symbols_, double width_)
+ {
+ this.p = p_;
+ this.symbols = symbols_;
+ this.width = width_;
+ }
+ public gPoint p;
+ public string symbols;
+ public double width;
+ public static gPP operator +(gPP p1, gPP p2)
+ {
+ p1.p += p2.p;
+ return p1;
+ }
+ public static gPP operator +(gPP p1, gPoint p2)
+ {
+ p1.p += p2;
+ return p1;
+ }
+ public static gPP operator -(gPP p1, gPP p2)
+ {
+ p1.p -= p2.p;
+ return p1;
+ }
+ public static gPP operator -(gPP p1, gPoint p2)
+ {
+ p1.p -= p2;
+ return p1;
+ }
+ }
+ ///
+ /// 点 数据类型 (XY)
+ ///
+ public struct gPoint
+ {
+ public gPoint(gPoint p_)
+ {
+ this.x = p_.x;
+ this.y = p_.y;
+ }
+ public gPoint(double x_val, double y_val)
+ {
+ this.x = x_val;
+ this.y = y_val;
+ }
+ public double x;
+ public double y;
+ public static gPoint operator +(gPoint p1, gPoint p2)
+ {
+ p1.x += p2.x;
+ p1.y += p2.y;
+ return p1;
+ }
+ public static gPoint operator -(gPoint p1, gPoint p2)
+ {
+ p1.x -= p2.x;
+ p1.y -= p2.y;
+ return p1;
+ }
+ }
+ ///
+ /// Line 数据类型
+ ///
+ public struct gL
+ {
+ public gL(double ps_x, double ps_y, double pe_x, double pe_y, double width_)
+ {
+ this.ps = new gPoint(ps_x, ps_y);
+ this.pe = new gPoint(pe_x, pe_y);
+ this.negative = false;
+ this.symbols = "r";
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gL(gPoint ps_, gPoint pe_, double width_)
+ {
+ this.ps = ps_;
+ this.pe = pe_;
+ this.negative = false;
+ this.symbols = "r";
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gL(gPoint ps_, gPoint pe_, string symbols_, double width_)
+ {
+ this.ps = ps_;
+ this.pe = pe_;
+ this.negative = false;
+ this.symbols = symbols_;
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gPoint ps;
+ public gPoint pe;
+ public bool negative;//polarity-- positive negative
+ public string symbols;
+ public string attribut;
+ public double width;
+ public static gL operator +(gL l1, gPoint move_p)
+ {
+ l1.ps += move_p;
+ l1.pe += move_p;
+ return l1;
+ }
+ public static gL operator +(gL l1, gP move_p)
+ {
+ l1.ps += move_p.p;
+ l1.pe += move_p.p;
+ return l1;
+ }
+ public static gL operator -(gL l1, gPoint move_p)
+ {
+ l1.ps -= move_p;
+ l1.pe -= move_p;
+ return l1;
+ }
+ public static gL operator -(gL l1, gP move_p)
+ {
+ l1.ps -= move_p.p;
+ l1.pe -= move_p.p;
+ return l1;
+ }
+ }
+ ///
+ /// ARC 数据类型
+ ///
+ public struct gA
+ {
+ public gA(double ps_x, double ps_y, double pc_x, double pc_y, double pe_x, double pe_y, double width_, bool ccw_)
+ {
+ this.ps = new gPoint(ps_x, ps_y);
+ this.pc = new gPoint(pc_x, pc_y);
+ this.pe = new gPoint(pe_x, pe_y);
+ this.negative = false;
+ this.ccw = ccw_;
+ this.symbols = "r";
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gA(gPoint ps_, gPoint pc_, gPoint pe_, double width_, bool ccw_ = false)
+ {
+ this.ps = ps_;
+ this.pc = pc_;
+ this.pe = pe_;
+ this.negative = false;
+ this.ccw = ccw_;
+ this.symbols = "r";
+ this.attribut = string.Empty;
+ this.width = width_;
+ }
+ public gPoint ps;
+ public gPoint pe;
+ public gPoint pc;
+ public bool negative;//polarity-- positive negative
+ public bool ccw; //direction-- cw ccw
+ public string symbols;
+ public string attribut;
+ public double width;
+ public static gA operator +(gA arc1, gPoint move_p)
+ {
+ arc1.ps += move_p;
+ arc1.pe += move_p;
+ arc1.pc += move_p;
+ return arc1;
+ }
+ public static gA operator +(gA arc1, gP move_p)
+ {
+ arc1.ps += move_p.p;
+ arc1.pe += move_p.p;
+ arc1.pc += move_p.p;
+ return arc1;
+ }
+ public static gA operator -(gA arc1, gPoint move_p)
+ {
+ arc1.ps -= move_p;
+ arc1.pe -= move_p;
+ arc1.pc -= move_p;
+ return arc1;
+ }
+ public static gA operator -(gA arc1, gP move_p)
+ {
+ arc1.ps -= move_p.p;
+ arc1.pe -= move_p.p;
+ arc1.pc -= move_p.p;
+ return arc1;
+ }
+ }
+View Code
diff --git a/DragDropHelper.cs b/DragDropHelper.cs
new file mode 100644
index 0000000..84d4e5c
--- /dev/null
+++ b/DragDropHelper.cs
@@ -0,0 +1,359 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Shapes;
+using WinForms = System.Windows.Forms;
+
+namespace DrillTools
+{
+ ///
+ /// 拖放帮助类
+ ///
+ public static class DragDropHelper
+ {
+ private static System.Windows.Point _startPoint;
+ private static bool _isDragging;
+ private static DragToolTipWindow? _dragToolTipWindow;
+ private static Window? _ownerWindow;
+ private static System.Windows.Shapes.Rectangle? _insertionIndicator;
+ private static int _insertionIndex = -1;
+ private static DateTime? _lastUpdateTime;
+
+ ///
+ /// 启用 ListView 的拖放功能
+ ///
+ /// 数据项类型
+ /// ListView 控件
+ /// 插入位置指示器
+ public static void EnableDragDrop(System.Windows.Controls.ListView listView, System.Windows.Shapes.Rectangle insertionIndicator) where T : class
+ {
+ _insertionIndicator = insertionIndicator;
+ _ownerWindow = Window.GetWindow(listView);
+
+ listView.PreviewMouseLeftButtonDown += (sender, e) =>
+ {
+ _startPoint = e.GetPosition(null);
+ _isDragging = false;
+ };
+
+ listView.PreviewMouseMove += (sender, e) =>
+ {
+ if (e.LeftButton == MouseButtonState.Pressed && !_isDragging)
+ {
+ System.Windows.Point position = e.GetPosition(null);
+ if (Math.Abs(position.X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
+ Math.Abs(position.Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
+ {
+ _isDragging = true;
+ var listViewItem = FindAncestor((DependencyObject)e.OriginalSource);
+ if (listViewItem != null)
+ {
+ var item = listView.ItemContainerGenerator.ItemFromContainer(listViewItem) as T;
+ if (item != null)
+ {
+ // 获取屏幕坐标
+ var screenPosition = listView.PointToScreen(e.GetPosition(listView));
+
+ // 创建并显示拖动提示
+ CreateDragToolTip(item, screenPosition);
+
+ // 使用 QueryContinueDrag 事件来更新位置
+ System.Windows.QueryContinueDragEventHandler queryContinueHandler = null;
+ queryContinueHandler = (sender, e) =>
+ {
+ if (_dragToolTipWindow != null)
+ {
+ // 获取当前鼠标位置
+ var currentPos = WinForms.Control.MousePosition;
+ _dragToolTipWindow.UpdatePosition(new System.Windows.Point(currentPos.X, currentPos.Y));
+ }
+
+ // 如果拖放结束,移除事件处理
+ if (e.Action == System.Windows.DragAction.Drop || e.Action == System.Windows.DragAction.Cancel)
+ {
+ DragDrop.RemoveQueryContinueDragHandler(listView, queryContinueHandler);
+ }
+ };
+
+ DragDrop.AddQueryContinueDragHandler(listView, queryContinueHandler);
+
+ System.Windows.DataObject data = new System.Windows.DataObject(typeof(T), item);
+ DragDrop.DoDragDrop(listViewItem, data, System.Windows.DragDropEffects.Move);
+
+ // 清理拖动提示
+ CleanupDragToolTip();
+ }
+ }
+ }
+ }
+ };
+
+ listView.DragOver += (sender, e) =>
+ {
+ if (e.Data.GetDataPresent(typeof(T)))
+ {
+ e.Effects = System.Windows.DragDropEffects.Move;
+
+ // 更新插入位置指示器
+ UpdateInsertionIndicator(listView, e.GetPosition(listView));
+ }
+ else
+ {
+ e.Effects = System.Windows.DragDropEffects.None;
+ }
+ e.Handled = true;
+ };
+
+ listView.DragLeave += (sender, e) =>
+ {
+ HideInsertionIndicator();
+ };
+
+ listView.Drop += (sender, e) =>
+ {
+ try
+ {
+ // 隐藏插入指示器
+ HideInsertionIndicator();
+
+ Debug.WriteLine($"[DragDrop] Drop事件触发 - OriginalSource类型: {e.OriginalSource?.GetType().Name}");
+ Debug.WriteLine($"[DragDrop] Drop位置: ({e.GetPosition(listView).X}, {e.GetPosition(listView).Y})");
+
+ if (e.Data.GetDataPresent(typeof(T)))
+ {
+ var droppedItem = e.Data.GetData(typeof(T)) as T;
+ if (droppedItem != null)
+ {
+ Debug.WriteLine($"[DragDrop] 拖放项: {droppedItem}");
+
+ // 检查是否是机台码刀具,如果是则不允许移动
+ if (droppedItem is ToolItem toolItem && toolItem.ToolType == ToolType.MachineCode)
+ {
+ Debug.WriteLine("[DragDrop] 机台码刀具不允许移动");
+ System.Windows.MessageBox.Show("机台码刀具不允许移动位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ _isDragging = false;
+ return;
+ }
+
+ var targetItem = FindAncestor((DependencyObject)e.OriginalSource);
+ string ss = targetItem == null ? "NULL" : "找到";
+ Debug.WriteLine($"[DragDrop] 目标ListViewItem: {ss}");
+
+ if (targetItem == null)
+ {
+ Debug.WriteLine("[DragDrop] 警告: 目标项为空,可能是拖放到列表外部");
+ _isDragging = false;
+ return;
+ }
+
+ var targetIndex = listView.ItemContainerGenerator.IndexFromContainer(targetItem);
+ Debug.WriteLine($"[DragDrop] 目标索引: {targetIndex}");
+
+ var sourceIndex = listView.Items.IndexOf(droppedItem);
+ Debug.WriteLine($"[DragDrop] 源索引: {sourceIndex}");
+
+ // 检查目标位置是否是机台码刀具
+ var viewModel = listView.DataContext as MainWindowViewModel;
+ if (viewModel != null && viewModel.Tools.Count > targetIndex)
+ {
+ var targetTool = viewModel.Tools[targetIndex];
+ if (targetTool.ToolType == ToolType.MachineCode)
+ {
+ Debug.WriteLine("[DragDrop] 不能移动到机台码刀具位置");
+ System.Windows.MessageBox.Show("不能移动到机台码刀具位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ _isDragging = false;
+ return;
+ }
+ }
+
+ if (sourceIndex != -1 && targetIndex != -1 && sourceIndex != targetIndex)
+ {
+ viewModel?.ReorderTools(sourceIndex, targetIndex);
+ Debug.WriteLine($"[DragDrop] 重新排序完成: {sourceIndex} -> {targetIndex}");
+ }
+ else
+ {
+ Debug.WriteLine($"[DragDrop] 跳过重新排序 - 源索引: {sourceIndex}, 目标索引: {targetIndex}");
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"[DragDrop] 异常: {ex.GetType().Name} - {ex.Message}");
+ Debug.WriteLine($"[DragDrop] 堆栈跟踪: {ex.StackTrace}");
+ System.Windows.MessageBox.Show($"拖放操作发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ finally
+ {
+ _isDragging = false;
+ }
+ };
+ }
+
+ ///
+ /// 查找指定类型的父元素
+ ///
+ /// 父元素类型
+ /// 当前元素
+ /// 找到的父元素,如果未找到则返回 null
+ private static T? FindAncestor(DependencyObject current) where T : DependencyObject
+ {
+ Debug.WriteLine($"[FindAncestor] 开始查找类型 {typeof(T).Name},起始元素类型: {current?.GetType().Name ?? "NULL"}");
+ int depth = 0;
+
+ while (current != null)
+ {
+ Debug.WriteLine($"[FindAncestor] 深度 {depth}: 当前类型 {current.GetType().Name}");
+
+ if (current is T ancestor)
+ {
+ Debug.WriteLine($"[FindAncestor] 找到匹配的祖先类型 {typeof(T).Name}");
+ return ancestor;
+ }
+
+ current = VisualTreeHelper.GetParent(current);
+ depth++;
+
+ if (depth > 10) // 防止无限循环
+ {
+ Debug.WriteLine("[FindAncestor] 警告: 搜索深度超过10层,停止搜索");
+ break;
+ }
+ }
+
+ Debug.WriteLine($"[FindAncestor] 未找到类型 {typeof(T).Name} 的祖先");
+ return null;
+ }
+
+ ///
+ /// 处理主窗口鼠标移动事件,更新拖动提示位置
+ ///
+ private static void OnOwnerWindowMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
+ {
+ if (_dragToolTipWindow != null && _isDragging)
+ {
+ // 获取屏幕坐标
+ var windowPosition = e.GetPosition(_ownerWindow);
+ var screenPosition = _ownerWindow.PointToScreen(windowPosition);
+ _dragToolTipWindow.UpdatePosition(screenPosition);
+ }
+ }
+
+ ///
+ /// 创建拖动提示窗口
+ ///
+ private static void CreateDragToolTip(T item, System.Windows.Point position) where T : class
+ {
+ if (item is ToolItem toolItem && _ownerWindow != null)
+ {
+ _dragToolTipWindow = new DragToolTipWindow();
+ _dragToolTipWindow.SetToolInfo(toolItem);
+ _dragToolTipWindow.UpdatePosition(position);
+ // 不设置 Owner,这样窗口可以独立定位
+ _dragToolTipWindow.Show();
+ }
+ }
+
+ ///
+ /// 清理拖动提示窗口
+ ///
+ private static void CleanupDragToolTip()
+ {
+ if (_dragToolTipWindow != null)
+ {
+ _dragToolTipWindow.Close();
+ _dragToolTipWindow = null;
+ }
+
+ if (_ownerWindow != null)
+ {
+ _ownerWindow.MouseMove -= OnOwnerWindowMouseMove;
+ }
+ }
+
+ ///
+ /// 更新插入位置指示器
+ ///
+ private static void UpdateInsertionIndicator(System.Windows.Controls.ListView listView, System.Windows.Point position)
+ {
+ if (_insertionIndicator == null) return;
+
+ // 使用节流机制,避免过于频繁的更新
+ if (_lastUpdateTime != null && DateTime.Now - _lastUpdateTime < TimeSpan.FromMilliseconds(16))
+ return;
+
+ _lastUpdateTime = DateTime.Now;
+
+ try
+ {
+ // 使用 VisualTreeHelper 找到鼠标下的元素
+ var element = listView.InputHitTest(position) as DependencyObject;
+ var listViewItem = FindAncestor(element);
+
+ if (listViewItem != null)
+ {
+ var index = listView.ItemContainerGenerator.IndexFromContainer(listViewItem);
+ var itemBounds = listViewItem.TransformToAncestor(listView)
+ .TransformBounds(new Rect(0, 0, listViewItem.ActualWidth, listViewItem.ActualHeight));
+
+ // 判断是在上半部分还是下半部分
+ bool insertAfter = position.Y > itemBounds.Top + itemBounds.Height / 2;
+ int targetIndex = insertAfter ? index + 1 : index;
+
+ if (targetIndex != _insertionIndex)
+ {
+ _insertionIndex = targetIndex;
+
+ // 更新指示器位置
+ _insertionIndicator.Visibility = Visibility.Visible;
+
+ // 计算指示器位置
+ double indicatorTop = insertAfter ? itemBounds.Bottom : itemBounds.Top;
+
+ // 使用 VerticalAlignment 和 Margin 结合来定位指示器
+ _insertionIndicator.VerticalAlignment = VerticalAlignment.Top;
+ _insertionIndicator.Margin = new Thickness(0, indicatorTop, 0, 0);
+ }
+ }
+ else
+ {
+ // 如果没有找到目标项,检查是否在列表末尾
+ if (position.Y > listView.ActualHeight - 20)
+ {
+ _insertionIndex = listView.Items.Count;
+ // 在列表末尾显示指示器
+ _insertionIndicator.Visibility = Visibility.Visible;
+ _insertionIndicator.VerticalAlignment = VerticalAlignment.Top;
+ _insertionIndicator.Margin = new Thickness(0, listView.ActualHeight - 2, 0, 0);
+ }
+ else
+ {
+ HideInsertionIndicator();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"[DragDrop] 更新插入指示器时发生错误: {ex.Message}");
+ HideInsertionIndicator();
+ }
+ }
+
+ ///
+ /// 隐藏插入位置指示器
+ ///
+ private static void HideInsertionIndicator()
+ {
+ if (_insertionIndicator != null)
+ {
+ _insertionIndicator.Visibility = Visibility.Collapsed;
+ }
+ _insertionIndex = -1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DragToolTipWindow.cs b/DragToolTipWindow.cs
new file mode 100644
index 0000000..4956cac
--- /dev/null
+++ b/DragToolTipWindow.cs
@@ -0,0 +1,114 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace DrillTools
+{
+ ///
+ /// 拖动提示窗口,显示刀具信息
+ ///
+ public class DragToolTipWindow : Window
+ {
+ private readonly TextBlock _textBlock;
+
+ public DragToolTipWindow()
+ {
+ // 设置窗口样式
+ WindowStyle = WindowStyle.None;
+ AllowsTransparency = true;
+ Background = System.Windows.Media.Brushes.Transparent;
+ ShowInTaskbar = false;
+ Topmost = true;
+ IsHitTestVisible = false; // 不拦截鼠标事件
+ SizeToContent = SizeToContent.WidthAndHeight; // 根据内容自动调整大小
+ MaxWidth = 200; // 限制最大宽度
+ MaxHeight = 50; // 限制最大高度
+
+ // 创建内容容器
+ var border = new Border
+ {
+ Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(224, 255, 255, 255)),
+ BorderBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(0, 120, 212)),
+ BorderThickness = new Thickness(1),
+ CornerRadius = new CornerRadius(3),
+ Padding = new Thickness(5, 2, 5, 2),
+ Effect = new System.Windows.Media.Effects.DropShadowEffect
+ {
+ Color = System.Windows.Media.Colors.Black,
+ Direction = 315,
+ ShadowDepth = 2,
+ BlurRadius = 5,
+ Opacity = 0.3
+ }
+ };
+
+ // 创建文本显示
+ _textBlock = new TextBlock
+ {
+ FontWeight = FontWeights.Bold,
+ FontSize = 10, // 减小字体大小
+ TextTrimming = TextTrimming.CharacterEllipsis // 文本过长时显示省略号
+ };
+
+ border.Child = _textBlock;
+ Content = border;
+ }
+
+ ///
+ /// 设置刀具信息
+ ///
+ /// 刀具项
+ public void SetToolInfo(ToolItem tool)
+ {
+ _textBlock.Text = $"T{tool.ToolNumber:D2} - {tool.Diameter:F3}mm";
+ }
+
+ ///
+ /// 更新窗口位置
+ ///
+ /// 鼠标位置
+ public void UpdatePosition(System.Windows.Point position)
+ {
+ // 将提示窗口显示在鼠标右下方,稍微偏移以避免遮挡
+ // 确保窗口不会超出屏幕边界
+ double left = position.X + 15;
+ double top = position.Y - 35;
+
+ // 获取屏幕尺寸
+ var screenWidth = SystemParameters.PrimaryScreenWidth;
+ var screenHeight = SystemParameters.PrimaryScreenHeight;
+
+ // 先设置位置,然后获取实际尺寸
+ Left = left;
+ Top = top;
+
+ // 确保窗口不会超出右边界
+ if (left + ActualWidth > screenWidth)
+ {
+ left = position.X - ActualWidth - 15;
+ }
+
+ // 确保窗口不会超出左边界
+ if (left < 0)
+ {
+ left = 5;
+ }
+
+ // 确保窗口不会超出下边界
+ if (top + ActualHeight > screenHeight)
+ {
+ top = position.Y - ActualHeight - 5;
+ }
+
+ // 确保窗口不会超出上边界
+ if (top < 0)
+ {
+ top = position.Y + 15;
+ }
+
+ // 重新设置最终位置
+ Left = left;
+ Top = top;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DrillTapeProcessor.cs b/DrillTapeProcessor.cs
new file mode 100644
index 0000000..c2217b5
--- /dev/null
+++ b/DrillTapeProcessor.cs
@@ -0,0 +1,680 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace DrillTools.Integration
+{
+ ///
+ /// 钻带处理工具集成示例
+ /// 展示如何将槽孔计算类集成到钻带处理工具中
+ ///
+ public class DrillTapeProcessor
+ {
+ ///
+ /// 处理钻带数据并计算槽孔孔数
+ ///
+ /// 钻带文件内容
+ /// 处理结果
+ public static DrillTapeResult ProcessDrillTape(string drillTapeContent)
+ {
+ var result = new DrillTapeResult();
+
+ try
+ {
+ // 解析刀具信息
+ var tools = ParseTools(drillTapeContent);
+
+ // 解析孔位信息
+ var holes = ParseHoles(drillTapeContent, tools);
+
+ // 按刀具分组孔位数据
+ var holesByTool = holes.GroupBy(h => h.ToolNumber).ToDictionary(g => g.Key, g => g.ToList());
+
+ // 处理刀具信息
+ foreach (var tool in tools)
+ {
+ // 检查是否是机台码 (0.499孔径)
+ bool isMachineCode = Math.Abs(tool.Diameter - 0.499) < 0.001;
+
+ // 根据刀具类型设置
+ ToolType toolType;
+ if (isMachineCode)
+ {
+ toolType = ToolType.MachineCode;
+ }
+ else
+ {
+ // 简化处理,所有非机台码都设为Regular
+ // 实际应用中可以根据需要判断是否为槽孔
+ toolType = ToolType.Regular;
+ }
+
+ // 计算刀具尾号类型和大类
+ var toolSuffixType = ToolItem.GetToolSuffixType(tool.Diameter);
+ var ToolCategory = ToolItem.GetToolCategory(toolSuffixType);
+
+ // 获取当前刀具的孔位数据
+ var toolHoles = holesByTool.ContainsKey(tool.Number) ? holesByTool[tool.Number] : new List();
+ var locations = new List();
+
+ // 统计孔数并收集孔位坐标
+ int regularHoles = 0;
+ int slotHoles = 0;
+ int slotCount = 0;
+
+ // 特殊处理机台码:分离固定孔数和实际坐标
+ if (isMachineCode)
+ {
+ // 机台码:先添加固定孔数的虚拟坐标(X0Y0)
+ int machineCodeHoleCount = 0;
+ foreach (var hole in toolHoles)
+ {
+ if (hole.Type == HoleType.Regular && hole.Position.X == 0 && hole.Position.Y == 0)
+ {
+ regularHoles++;
+ machineCodeHoleCount++;
+ // 不添加 X0Y0 到 locations,这些只是用于计数的虚拟孔
+ }
+ else if (hole.Type == HoleType.Regular && (hole.Position.X != 0 || hole.Position.Y != 0))
+ {
+ // 这是实际的坐标行,使用原始字符串保持格式一致
+ string location = !string.IsNullOrEmpty(hole.Position.OriginalString)
+ ? hole.Position.OriginalString
+ : $"X{hole.Position.X:F0}Y{hole.Position.Y:F0}";
+ locations.Add(location);
+ }
+ }
+ }
+ else
+ {
+ // 普通刀具和槽刀:正常处理
+ foreach (var hole in toolHoles)
+ {
+ if (hole.Type == HoleType.Regular)
+ {
+ regularHoles++;
+ // Point2D 是 struct,不需要检查 null
+ // 使用原始字符串保持格式一致
+ string location = !string.IsNullOrEmpty(hole.Position.OriginalString)
+ ? hole.Position.OriginalString
+ : $"X{hole.Position.X:F0}Y{hole.Position.Y:F0}";
+ locations.Add(location);
+ }
+ else if (hole.Type == HoleType.Slot)
+ {
+ slotHoles++;
+ slotCount++;
+ // LineSlot 是 struct,不需要检查 null,使用正确的属性名
+ // 使用原始字符串保持格式一致
+ string startLocation = !string.IsNullOrEmpty(hole.Slot.StartPoint.OriginalString)
+ ? hole.Slot.StartPoint.OriginalString
+ : $"X{hole.Slot.StartPoint.X:F0}Y{hole.Slot.StartPoint.Y:F0}";
+ string endLocation = !string.IsNullOrEmpty(hole.Slot.EndPoint.OriginalString)
+ ? hole.Slot.EndPoint.OriginalString
+ : $"X{hole.Slot.EndPoint.X:F0}Y{hole.Slot.EndPoint.Y:F0}";
+
+ // 直接组合成G85格式,保持原始坐标格式
+ string location = $"{startLocation}G85{endLocation}";
+ locations.Add(location);
+ }
+ }
+ }
+
+ // 为机台码刀具提取机台码命令和类型
+ string machineCodeCommand = string.Empty;
+ string machineCodeType = string.Empty;
+
+ if (isMachineCode)
+ {
+ // 从钻带内容中提取机台码信息
+ var toolPattern = $@"%.+?T{tool.Number:D2}(.*?)(?=T\d{{2}}|M30)";
+ var match = Regex.Match(drillTapeContent, toolPattern, RegexOptions.Singleline);
+
+ if (match.Success)
+ {
+ string holeSection = match.Groups[1].Value;
+
+ // 查找机台码命令
+ var machineCodePattern = @"(M97|M98),(A\*|B\*),\$S \$N";
+ var machineCodeMatch = Regex.Match(holeSection, machineCodePattern);
+
+ if (machineCodeMatch.Success)
+ {
+ machineCodeCommand = machineCodeMatch.Groups[1].Value; // M97或M98
+ machineCodeType = machineCodeMatch.Groups[2].Value; // A*或B*
+
+ // 添加日志验证机台码解析
+ System.Diagnostics.Debug.WriteLine($"[机台码解析] T{tool.Number:D2}: 命令={machineCodeCommand}, 类型={machineCodeType}");
+ }
+ else
+ {
+ System.Diagnostics.Debug.WriteLine($"[机台码解析] T{tool.Number:D2}: 未找到机台码命令");
+ }
+ }
+ else
+ {
+ System.Diagnostics.Debug.WriteLine($"[机台码解析] T{tool.Number:D2}: 未找到机台码部分");
+ }
+ }
+
+ result.ToolResults.Add(new ToolResult
+ {
+ ToolNumber = tool.Number,
+ Diameter = tool.Diameter,
+ TotalHoles = regularHoles + slotHoles,
+ RegularHoles = regularHoles,
+ SlotHoles = slotHoles,
+ ToolType = toolType,
+ SlotCount = slotCount,
+ Locations = locations,
+ ToolSuffixType = toolSuffixType,
+ ToolCategory = ToolCategory,
+ MachineCodeCommand = machineCodeCommand,
+ MachineCodeType = machineCodeType
+ });
+ }
+
+ result.Success = true;
+ result.Message = "钻带处理成功";
+ }
+ catch (Exception ex)
+ {
+ result.Success = false;
+ result.Message = $"钻带处理失败: {ex.Message}";
+ }
+
+ return result;
+ }
+
+ ///
+ /// 解析刀具信息
+ ///
+ private static List ParseTools(string drillTapeContent)
+ {
+ var tools = new List();
+
+ // 解析M48到%之间的刀具信息
+ var toolPattern = @"T(\d+)C(\d+\.?\d*)";
+ var matches = Regex.Matches(drillTapeContent, toolPattern);
+
+ foreach (Match match in matches)
+ {
+ int toolNumber = int.Parse(match.Groups[1].Value);
+ double diameter = double.Parse(match.Groups[2].Value);
+
+ tools.Add(new ToolInfo
+ {
+ Number = toolNumber,
+ Diameter = diameter
+ });
+ }
+
+ return tools;
+ }
+
+ ///
+ /// 解析钻孔信息
+ ///
+ private static List ParseHoles(string drillTapeContent, List tools)
+ {
+ var holes = new List();
+
+ // 按刀具分组解析
+ foreach (var tool in tools)
+ {
+ // 检查是否是机台码 (0.499孔径)
+ if (Math.Abs(tool.Diameter - 0.499) < 0.001)
+ {
+ // 解析机台码部分(在%符号之后查找)
+ var toolPattern = $@"%.+?T{tool.Number:D2}(.*?)(?=T\d{{2}}|M30)";
+ var match = Regex.Match(drillTapeContent, toolPattern, RegexOptions.Singleline);
+
+ if (match.Success)
+ {
+ string holeSection = match.Groups[1].Value;
+
+ // 查找机台码命令
+ var machineCodePattern = @"(M97|M98),(A\*|B\*),\$S \$N";
+ var machineCodeMatch = Regex.Match(holeSection, machineCodePattern);
+
+ if (machineCodeMatch.Success)
+ {
+ string command = machineCodeMatch.Groups[1].Value; // M97或M98
+ string codeType = machineCodeMatch.Groups[2].Value; // A*或B*
+
+ // 根据机台码类型确定孔数
+ int holeCount = (codeType == "A*") ? 57 : 58;
+
+ // 查找机台码坐标行
+ var coordinatePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
+ var coordinateMatches = Regex.Matches(holeSection, coordinatePattern);
+
+ // 添加机台码孔信息
+ for (int i = 0; i < holeCount; i++)
+ {
+ holes.Add(new HoleInfo
+ {
+ ToolNumber = tool.Number,
+ Type = HoleType.Regular,
+ Position = new Point2D(0, 0) // 机台码不需要实际坐标
+ });
+ }
+
+ // 这样可以确保坐标数据被正确保存到 ToolResult.Locations 中
+ foreach (Match coordMatch in coordinateMatches)
+ {
+ // 解析坐标
+ double x = double.Parse(coordMatch.Groups[1].Value);
+ double y = double.Parse(coordMatch.Groups[2].Value);
+
+ // 保存原始坐标字符串
+ string originalCoordString = coordMatch.Value;
+
+ // 添加一个特殊的孔位信息来保存实际坐标
+ holes.Add(new HoleInfo
+ {
+ ToolNumber = tool.Number,
+ Type = HoleType.Regular,
+ Position = new Point2D(x, y, originalCoordString)
+ });
+ }
+ }
+ }
+ }
+ else
+ {
+ // 查找当前刀具的钻孔部分(只在%符号之后查找)
+ var toolPattern = $@"%.+?T{tool.Number:D2}(.*?)(?=T\d{{2}}|M30)";
+ var match = Regex.Match(drillTapeContent, toolPattern, RegexOptions.Singleline);
+
+ if (match.Success)
+ {
+ string holeSection = match.Groups[1].Value;
+ // 先解析槽孔,并记录槽孔的起始坐标
+ var slotPattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)G85X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
+ var slotMatches = Regex.Matches(holeSection, slotPattern);
+ var slotStartPositions = new System.Collections.Generic.HashSet();
+
+ foreach (Match slotMatch in slotMatches)
+ {
+ var slot = SlotHoleCalculator.ParseLineSlotFromG85(slotMatch.Value, tool.Diameter);
+ holes.Add(new HoleInfo
+ {
+ ToolNumber = tool.Number,
+ Type = HoleType.Slot,
+ Slot = slot
+ });
+
+ // 记录槽孔的起始坐标,以便后续排除
+ string startPos = $"X{slotMatch.Groups[1].Value}Y{slotMatch.Groups[2].Value}";
+ slotStartPositions.Add(startPos);
+ }
+
+ // 解析普通圆孔(排除槽孔的起始坐标)
+ var regularHolePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
+ var regularMatches = Regex.Matches(holeSection, regularHolePattern);
+
+ foreach (Match regularMatch in regularMatches)
+ {
+ // 排除槽孔的起始坐标
+ if (!slotStartPositions.Contains(regularMatch.Value))
+ {
+ holes.Add(new HoleInfo
+ {
+ ToolNumber = tool.Number,
+ Type = HoleType.Regular,
+ Position = Point2D.ParseFromDrillString(regularMatch.Value)
+ });
+ }
+ }
+
+ // 解析槽孔(已在上面处理)
+ }
+ }
+ }
+
+ return holes;
+ }
+
+ ///
+ /// 生成处理报告
+ ///
+ /// 处理结果
+ /// 格式化的报告文本
+ public static string GenerateReport(DrillTapeResult result)
+ {
+ var report = new System.Text.StringBuilder();
+
+ report.AppendLine("钻带处理报告");
+ report.AppendLine("============");
+ report.AppendLine($"处理状态: {(result.Success ? "成功" : "失败")}");
+ report.AppendLine($"处理信息: {result.Message}");
+ report.AppendLine();
+
+ if (result.Success)
+ {
+ report.AppendLine("刀具统计:");
+ report.AppendLine("刀具\t孔径(mm)\t类型\t\t尾号类型\t大类\t\t普通孔数\t槽孔数\t槽孔个数\t总孔数");
+ report.AppendLine("================================================================================");
+
+ foreach (var tool in result.ToolResults)
+ {
+ string toolTypeDisplay = tool.ToolType switch
+ {
+ ToolType.Regular => "圆孔",
+ ToolType.Slot => "槽孔",
+ ToolType.MachineCode => "机台码",
+ _ => "未知"
+ };
+
+ string suffixTypeDisplay = tool.ToolSuffixType switch
+ {
+ ToolSuffixType.Drill => "钻针",
+ ToolSuffixType.Slot => "槽刀",
+ ToolSuffixType.EASlot => "EA型槽刀",
+ ToolSuffixType.DustSlot => "粉尘刀",
+ ToolSuffixType.DeburrSlot => "去毛刺刀",
+ ToolSuffixType.NonStandard => "非标刀",
+ ToolSuffixType.EASlot2 => "EA型槽刀",
+ ToolSuffixType.Special => "特殊刀具",
+ _ => "未知"
+ };
+
+ string categoryDisplay = tool.ToolCategory switch
+ {
+ ToolCategory.Drill => "钻针",
+ ToolCategory.Slot => "槽刀",
+ ToolCategory.EA => "EA刀",
+ ToolCategory.NonStandard => "非标刀",
+ ToolCategory.Special => "特殊刀",
+ _ => "未知"
+ };
+
+ report.AppendLine($"T{tool.ToolNumber:D2}\t{tool.Diameter:F3}\t\t{toolTypeDisplay}\t{suffixTypeDisplay}\t{categoryDisplay}\t{tool.RegularHoles}\t\t{tool.SlotHoles}\t{tool.SlotCount}\t\t{tool.TotalHoles}");
+ }
+
+ report.AppendLine();
+ report.AppendLine($"总计: {result.ToolResults.Count} 把刀具");
+ report.AppendLine($"总孔数: {result.TotalHoles}");
+ }
+
+ return report.ToString();
+ }
+ }
+
+ ///
+ /// 刀具信息
+ ///
+ public class ToolInfo
+ {
+ public int Number { get; set; }
+ public double Diameter { get; set; }
+ }
+
+ ///
+ /// 钻孔信息
+ ///
+ public class HoleInfo
+ {
+ public int ToolNumber { get; set; }
+ public HoleType Type { get; set; }
+ public Point2D Position { get; set; }
+ public LineSlot Slot { get; set; }
+ }
+
+ ///
+ /// 钻孔类型
+ ///
+ public enum HoleType
+ {
+ Regular, // 普通圆孔
+ Slot // 槽孔
+ }
+
+ ///
+ /// 钻带处理结果
+ ///
+ public class DrillTapeResult
+ {
+ public bool Success { get; set; }
+ public string Message { get; set; } = string.Empty;
+ public List ToolResults { get; set; } = new List();
+
+ ///
+ /// 获取总孔数
+ ///
+ public int TotalHoles => ToolResults.Sum(t => t.TotalHoles);
+ }
+
+ ///
+ /// 刀具处理结果
+ ///
+ public class ToolResult
+ {
+ public int ToolNumber { get; set; }
+ public double Diameter { get; set; }
+ public int TotalHoles { get; set; }
+ public int RegularHoles { get; set; }
+ public int SlotHoles { get; set; }
+ public int SlotCount { get; set; } // 槽孔个数(不是钻孔数量)
+ public List Locations { get; set; } = new(); // 位置数据
+ public ToolType ToolType { get; set; }
+ public ToolSuffixType ToolSuffixType { get; set; }
+ public ToolCategory ToolCategory { get; set; }
+
+ ///
+ /// 机台码命令 (M97或M98)
+ ///
+ public string MachineCodeCommand { get; set; } = string.Empty;
+
+ ///
+ /// 机台码类型 (A*或B*)
+ ///
+ public string MachineCodeType { get; set; } = string.Empty;
+ }
+
+ ///
+ /// 钻带处理扩展方法
+ ///
+ public static class DrillTapeProcessorExtensions
+ {
+ ///
+ /// 生成重新排序后的钻带内容(重排并重新编号)
+ ///
+ /// 原始钻带内容
+ /// 重新排序的刀具列表
+ /// 重新排序后的钻带内容
+ public static string GenerateReorderedDrillTape(string originalDrillTape, List reorderedTools)
+ {
+ // 1. 创建原始刀具编号到新编号的映射
+ var toolNumberMapping = new Dictionary();
+ var originalToNewMapping = new Dictionary(); // 保存原始映射关系
+
+ // 2. 按当前列表顺序重新编号(T01, T02, T03...)
+ int newToolNumber = 1;
+ foreach (var tool in reorderedTools.ToList())
+ {
+ // 机台码刀具不允许重新编号
+ if (tool.ToolType != ToolType.MachineCode)
+ {
+ originalToNewMapping[tool.ToolNumber] = newToolNumber;
+ toolNumberMapping[tool.ToolNumber] = newToolNumber;
+ tool.ToolNumber = newToolNumber++;
+ }
+ else
+ {
+ // 机台码刀具保持原始编号,但也要加入映射
+ toolNumberMapping[tool.ToolNumber] = tool.ToolNumber;
+ }
+ }
+
+ // 3. 使用新的刀具编号更新钻带内容
+ return UpdateDrillTapeWithNewToolNumbers(originalDrillTape, toolNumberMapping, reorderedTools);
+ }
+
+ ///
+ /// 使用新的刀具编号更新钻带内容
+ ///
+ /// 原始钻带内容
+ /// 刀具编号映射
+ /// 重新排序的刀具列表
+ /// 更新后的钻带内容
+ private static string UpdateDrillTapeWithNewToolNumbers(string originalDrillTape, Dictionary toolNumberMapping, List reorderedTools)
+ {
+ var lines = originalDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
+ var result = new List();
+
+ // 创建新编号到刀具对象的映射,以便获取对应的坐标数据
+ var newNumberToToolMap = new Dictionary();
+ foreach (var tool in reorderedTools)
+ {
+ if (toolNumberMapping.ContainsValue(tool.ToolNumber))
+ {
+ newNumberToToolMap[tool.ToolNumber] = tool;
+ }
+ }
+
+ // 首先解析原始钻带中的刀具定义行,保存参数信息
+ var originalToolDefinitions = new Dictionary();
+ var headerLines = new List();
+
+ foreach (var line in lines)
+ {
+ string trimmedLine = line.Trim();
+
+ if (trimmedLine == "%")
+ {
+ //headerLines.Add(line);
+ break;
+ }
+
+ // 处理刀具定义行(如 T01C1.049H05000Z+0.000S060.00F105.0U0700.0)
+ if (Regex.IsMatch(trimmedLine, @"^T(\d+)C"))
+ {
+ var match = Regex.Match(trimmedLine, @"^T(\d+)C(.*)$");
+ if (match.Success)
+ {
+ int originalToolNumber = int.Parse(match.Groups[1].Value);
+ originalToolDefinitions[originalToolNumber] = match.Groups[2].Value;
+ }
+ }
+ else
+ {
+ if (line != "")
+ headerLines.Add(line);
+ }
+ }
+
+ // 添加头部信息
+ result.AddRange(headerLines);
+
+ // 按照新的刀具编号顺序输出刀具定义部分
+ var sortedTools = reorderedTools.OrderBy(t => t.ToolNumber).ToList();
+ foreach (var tool in sortedTools)
+ {
+ // 查找原始刀具编号
+ int originalToolNumber = -1;
+ foreach (var kvp in toolNumberMapping)
+ {
+ if (kvp.Value == tool.ToolNumber)
+ {
+ originalToolNumber = kvp.Key;
+ break;
+ }
+ }
+
+ if (originalToolNumber != -1 && originalToolDefinitions.ContainsKey(originalToolNumber))
+ {
+ string toolDef = $"T{tool.ToolNumber:D2}C{originalToolDefinitions[originalToolNumber]}";
+ result.Add(toolDef);
+ }
+ }
+
+ // 添加 % 符号
+ result.Add("%");
+
+ // 处理刀具切换行和坐标数据部分
+ // 按新刀具编号顺序输出刀具切换行和对应的坐标数据
+ var sortedToolsForData = reorderedTools.OrderBy(t => t.ToolNumber).ToList();
+
+ foreach (var tool in sortedToolsForData)
+ {
+ // 添加刀具切换行
+ result.Add($"T{tool.ToolNumber:D2}");
+
+ // 添加该刀具对应的所有坐标数据
+ if (tool.ToolType != ToolType.MachineCode && tool.HoleLocations != null && tool.HoleLocations.Count > 0)
+ {
+ foreach (var location in tool.HoleLocations)
+ {
+ result.Add(location);
+ }
+ }
+
+ // 如果是机台码刀具,添加机台码命令和坐标
+ if (tool.ToolType == ToolType.MachineCode)
+ {
+ if (!string.IsNullOrEmpty(tool.MachineCodeCommand) && !string.IsNullOrEmpty(tool.MachineCodeType))
+ {
+ result.Add($"{tool.MachineCodeCommand},{tool.MachineCodeType},$S $N");
+
+ // 添加机台码的坐标数据
+ if (tool.HoleLocations != null && tool.HoleLocations.Count > 0)
+ {
+ foreach (var location in tool.HoleLocations)
+ {
+ result.Add(location);
+ }
+ }
+ }
+ }
+ }
+
+ // 添加结束标记
+ result.Add("M30");
+
+ return string.Join("\r\n", result);
+ }
+
+ ///
+ /// 根据刀具编号尾号判断刀具尾号类型
+ ///
+ /// 刀具编号
+ /// 刀具尾号类型
+ private static ToolSuffixType GetToolSuffixType(int toolNumber)
+ {
+ int suffix = toolNumber % 10;
+ return suffix switch
+ {
+ 0 => ToolSuffixType.Drill,
+ 1 => ToolSuffixType.Slot,
+ 2 => ToolSuffixType.EASlot,
+ 3 => ToolSuffixType.DustSlot,
+ 4 => ToolSuffixType.DeburrSlot,
+ 5 => ToolSuffixType.NonStandard,
+ 6 => ToolSuffixType.EASlot2,
+ 7 => ToolSuffixType.Special,
+ _ => ToolSuffixType.NonStandard
+ };
+ }
+
+ ///
+ /// 根据刀具尾号类型获取刀具大类
+ ///
+ /// 刀具尾号类型
+ /// 刀具大类
+ private static ToolCategory GetToolCategory(ToolSuffixType suffixType)
+ {
+ return suffixType switch
+ {
+ ToolSuffixType.Drill => ToolCategory.Drill,
+ ToolSuffixType.Slot or ToolSuffixType.DustSlot or ToolSuffixType.DeburrSlot => ToolCategory.Slot,
+ ToolSuffixType.EASlot or ToolSuffixType.EASlot2 => ToolCategory.EA,
+ ToolSuffixType.NonStandard => ToolCategory.NonStandard,
+ ToolSuffixType.Special => ToolCategory.Special,
+ _ => ToolCategory.NonStandard
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/DrillTools.csproj b/DrillTools.csproj
new file mode 100644
index 0000000..da170b8
--- /dev/null
+++ b/DrillTools.csproj
@@ -0,0 +1,13 @@
+
+
+
+ WinExe
+ net6.0-windows
+ enable
+ enable
+ true
+ true
+ x86
+
+
+
diff --git a/DrillTools.sln b/DrillTools.sln
new file mode 100644
index 0000000..27a7907
--- /dev/null
+++ b/DrillTools.sln
@@ -0,0 +1,29 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 18
+VisualStudioVersion = 18.0.11205.157 d18.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrillTools", "DrillTools.csproj", "{FC319F00-406B-4E5B-BB24-D9F76B02DF51}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FC319F00-406B-4E5B-BB24-D9F76B02DF51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FC319F00-406B-4E5B-BB24-D9F76B02DF51}.Debug|x86.ActiveCfg = Debug|x86
+ {FC319F00-406B-4E5B-BB24-D9F76B02DF51}.Debug|x86.Build.0 = Debug|x86
+ {FC319F00-406B-4E5B-BB24-D9F76B02DF51}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FC319F00-406B-4E5B-BB24-D9F76B02DF51}.Release|x86.ActiveCfg = Release|x86
+ {FC319F00-406B-4E5B-BB24-D9F76B02DF51}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1DA9466F-43EA-4554-BAFE-935FBF8D2909}
+ EndGlobalSection
+EndGlobal
diff --git a/GenerateReorderedDrillTape_Implementation.md b/GenerateReorderedDrillTape_Implementation.md
new file mode 100644
index 0000000..188d60d
--- /dev/null
+++ b/GenerateReorderedDrillTape_Implementation.md
@@ -0,0 +1,180 @@
+# GenerateReorderedDrillTape 方法实现方案
+
+## 目标
+将 `GenerateReorderedDrillTape` 静态扩展方法的功能升级,使其与 `ReorderAndRenumberTools` 方法完全一致。
+
+## 当前问题分析
+现有的 `GenerateReorderedDrillTape` 方法只实现简单的重排功能,缺少以下关键特性:
+1. 刀具重新编号(T01, T02, T03...)
+2. 机台码智能处理(保持原始编号)
+3. 完整的钻带内容重构逻辑
+4. 数据映射和同步机制
+
+## 新实现方案
+
+### 1. 方法签名保持不变
+```csharp
+public static string GenerateReorderedDrillTape(string originalDrillTape, List reorderedTools)
+```
+
+### 2. 核心实现逻辑
+
+#### 步骤1: 创建刀具编号映射
+```csharp
+// 1. 创建原始刀具编号到新编号的映射
+var toolNumberMapping = new Dictionary();
+var originalToNewMapping = new Dictionary();
+
+// 2. 按当前列表顺序重新编号(T01, T02, T03...)
+int newToolNumber = 1;
+foreach (var tool in reorderedTools)
+{
+ // 机台码刀具不允许重新编号
+ if (tool.ToolType != ToolType.MachineCode)
+ {
+ originalToNewMapping[tool.ToolNumber] = newToolNumber;
+ toolNumberMapping[tool.ToolNumber] = newToolNumber;
+ tool.ToolNumber = newToolNumber++;
+ }
+ else
+ {
+ // 机台码刀具保持原始编号,但也要加入映射
+ toolNumberMapping[tool.ToolNumber] = tool.ToolNumber;
+ }
+}
+```
+
+#### 步骤2: 解析原始钻带内容
+```csharp
+// 解析原始钻带中的刀具定义行,保存参数信息
+var originalToolDefinitions = new Dictionary();
+var headerLines = new List();
+
+var lines = originalDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
+foreach (var line in lines)
+{
+ string trimmedLine = line.Trim();
+
+ if (trimmedLine == "%")
+ {
+ break;
+ }
+
+ // 处理刀具定义行(如 T01C1.049H05000Z+0.000S060.00F105.0U0700.0)
+ if (Regex.IsMatch(trimmedLine, @"^T(\d+)C"))
+ {
+ var match = Regex.Match(trimmedLine, @"^T(\d+)C(.*)$");
+ if (match.Success)
+ {
+ int originalToolNumber = int.Parse(match.Groups[1].Value);
+ originalToolDefinitions[originalToolNumber] = match.Groups[2].Value;
+ }
+ }
+ else
+ {
+ if (line != "")
+ headerLines.Add(line);
+ }
+}
+```
+
+#### 步骤3: 重构刀具定义部分
+```csharp
+// 按照新的刀具编号顺序输出刀具定义部分
+var sortedTools = reorderedTools.OrderBy(t => t.ToolNumber).ToList();
+foreach (var tool in sortedTools)
+{
+ // 查找原始刀具编号
+ int originalToolNumber = -1;
+ foreach (var kvp in toolNumberMapping)
+ {
+ if (kvp.Value == tool.ToolNumber)
+ {
+ originalToolNumber = kvp.Key;
+ break;
+ }
+ }
+
+ if (originalToolNumber != -1 && originalToolDefinitions.ContainsKey(originalToolNumber))
+ {
+ string toolDef = $"T{tool.ToolNumber:D2}C{originalToolDefinitions[originalToolNumber]}";
+ result.Add(toolDef);
+ }
+}
+```
+
+#### 步骤4: 处理坐标数据和机台码
+```csharp
+// 按新刀具编号顺序输出刀具切换行和对应的坐标数据
+var sortedToolsForData = reorderedTools.OrderBy(t => t.ToolNumber).ToList();
+
+foreach (var tool in sortedToolsForData)
+{
+ // 添加刀具切换行
+ result.Add($"T{tool.ToolNumber:D2}");
+
+ // 添加该刀具对应的所有坐标数据
+ if (tool.ToolType != ToolType.MachineCode && tool.HoleLocations != null && tool.HoleLocations.Count > 0)
+ {
+ foreach (var location in tool.HoleLocations)
+ {
+ result.Add(location);
+ }
+ }
+
+ // 如果是机台码刀具,添加机台码命令和坐标
+ if (tool.ToolType == ToolType.MachineCode)
+ {
+ if (!string.IsNullOrEmpty(tool.MachineCodeCommand) && !string.IsNullOrEmpty(tool.MachineCodeType))
+ {
+ result.Add($"{tool.MachineCodeCommand},{tool.MachineCodeType},$S $N");
+
+ // 添加机台码的坐标数据
+ if (tool.HoleLocations != null && tool.HoleLocations.Count > 0)
+ {
+ foreach (var location in tool.HoleLocations)
+ {
+ result.Add(location);
+ }
+ }
+ }
+ }
+}
+```
+
+### 3. 关键特性实现
+
+#### 机台码处理逻辑
+- 机台码刀具保持原始编号不变
+- 机台码命令(M97/M98)和类型(A*/B*)正确保留
+- 机台码坐标数据完整保留
+
+#### 数据映射机制
+- 创建原始编号到新编号的完整映射
+- 支持混合编号场景(部分重新编号)
+- 确保坐标数据正确绑定到对应刀具
+
+#### 钻带内容重构
+- 完整保留原始刀具参数
+- 按新编号顺序重新组织钻带结构
+- 确保格式和语法正确性
+
+### 4. 实现优势
+
+1. **功能一致性**: 与 `ReorderAndRenumberTools` 方法功能完全一致
+2. **向后兼容**: 保持原有方法签名,现有调用代码无需修改
+3. **健壮性**: 完整的错误处理和边界条件检查
+4. **可维护性**: 清晰的代码结构和注释
+
+### 5. 测试验证
+
+需要验证以下场景:
+1. 普通刀具重排和重新编号
+2. 机台码刀具保持原始编号
+3. 混合场景(部分机台码、部分普通刀具)
+4. 坐标数据正确绑定
+5. 钻带格式正确性
+
+## 实现建议
+
+建议切换到 Code 模式进行实际的代码修改,因为 Architect 模式只能编辑 Markdown 文件。实现时应严格按照上述方案进行,确保与 `ReorderAndRenumberTools` 方法的行为完全一致。
\ No newline at end of file
diff --git a/MainWindow.xaml b/MainWindow.xaml
new file mode 100644
index 0000000..2edfbc8
--- /dev/null
+++ b/MainWindow.xaml
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
new file mode 100644
index 0000000..8d835a9
--- /dev/null
+++ b/MainWindow.xaml.cs
@@ -0,0 +1,216 @@
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace DrillTools
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ private MainWindowViewModel ViewModel => (MainWindowViewModel)DataContext;
+
+ public MainWindow()
+ {
+ InitializeComponent();
+ var viewModel = new MainWindowViewModel();
+ DataContext = viewModel;
+ InitializeDragDrop();
+
+ // 测试修正后的重排刀序功能
+ // TestReorderDemo.RunDemo();
+
+ // 测试机台码孔数计算功能
+ //viewModel.TestMachineCodeHoleCalculation();
+
+ // 测试机台码处理修复效果
+ viewModel.TestMachineCodeProcessingFix();
+ }
+
+ ///
+ /// 初始化拖放功能
+ ///
+ private void InitializeDragDrop()
+ {
+ DragDropHelper.EnableDragDrop(ToolsListView, InsertionIndicator);
+ }
+
+ ///
+ /// 加载示例数据按钮点击事件
+ ///
+ private void LoadSampleDataButton_Click(object sender, RoutedEventArgs e)
+ {
+ ViewModel.LoadSampleData();
+ }
+
+ ///
+ /// 加载钻带文件按钮点击事件
+ ///
+ private void LoadDrillTapeButton_Click(object sender, RoutedEventArgs e)
+ {
+ var openFileDialog = new Microsoft.Win32.OpenFileDialog
+ {
+ Filter = "钻带文件 (*.txt;*.drl;*.dr2;*.dpin)|*.txt;*.drl;*.dr2;*.dpin|所有文件 (*.*)|*.*",
+ Title = "选择钻带文件"
+ };
+
+ if (openFileDialog.ShowDialog() == true)
+ {
+ try
+ {
+ // 保存原始文件路径
+ ViewModel.OriginalFilePath = openFileDialog.FileName;
+
+ // 使用 cmd 命令读取加密钻带文件
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "cmd.exe",
+ Arguments = $"/c type \"{openFileDialog.FileName}\"",
+ RedirectStandardOutput = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ }
+ };
+
+ process.Start();
+ string drillTapeContent = process.StandardOutput.ReadToEnd();
+ process.WaitForExit();
+
+ ViewModel.LoadToolsFromDrillTape(drillTapeContent);
+ }
+ catch (Exception ex)
+ {
+ System.Windows.MessageBox.Show($"加载钻带文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ }
+
+ ///
+ /// 重排刀序按钮点击事件
+ ///
+ private void ReorderToolsButton_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ string reorderedDrillTape = ViewModel.ReorderAndRenumberTools();
+ ViewModel.DrillTapeContent = reorderedDrillTape;
+ System.Windows.MessageBox.Show("刀序重排完成", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ catch (Exception ex)
+ {
+ System.Windows.MessageBox.Show($"重排刀序失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ ///
+ /// 应用顺序到钻带按钮点击事件
+ ///
+ private void ApplyOrderButton_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ string reorderedDrillTape = ViewModel.ApplyToolOrderToDrillTape();
+ ViewModel.DrillTapeContent = reorderedDrillTape;
+ System.Windows.MessageBox.Show("刀具顺序已应用到钻带", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ catch (OperationCanceledException)
+ {
+ // 用户取消操作,不显示错误消息
+ System.Diagnostics.Debug.WriteLine("用户取消了保存操作");
+ }
+ catch (Exception ex)
+ {
+ System.Windows.MessageBox.Show($"应用刀具顺序失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ ///
+ /// 上移按钮点击事件
+ ///
+ private void MoveUpButton_Click(object sender, RoutedEventArgs e)
+ {
+ ViewModel.MoveSelectedToolUp();
+ }
+
+ ///
+ /// 下移按钮点击事件
+ ///
+ private void MoveDownButton_Click(object sender, RoutedEventArgs e)
+ {
+ ViewModel.MoveSelectedToolDown();
+ }
+
+ ///
+ /// 刀具列表双击事件
+ ///
+ private void ToolsListView_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ if (sender is System.Windows.Controls.ListView listView && listView.SelectedItem is ToolItem selectedTool)
+ {
+ ViewModel.ShowToolDetail(selectedTool);
+ }
+ }
+
+ ///
+ /// 拖放文件进入窗口事件
+ ///
+ protected override void OnDragEnter(System.Windows.DragEventArgs e)
+ {
+ if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop))
+ {
+ e.Effects = System.Windows.DragDropEffects.Copy;
+ }
+ else
+ {
+ e.Effects = System.Windows.DragDropEffects.None;
+ }
+ base.OnDragEnter(e);
+ }
+
+ ///
+ /// 拖放文件到窗口事件
+ ///
+ protected override void OnDrop(System.Windows.DragEventArgs e)
+ {
+ if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop))
+ {
+ string[] files = (string[])e.Data.GetData(System.Windows.DataFormats.FileDrop);
+ if (files.Length > 0)
+ {
+ try
+ {
+ // 保存原始文件路径
+ ViewModel.OriginalFilePath = files[0];
+
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "cmd.exe",
+ Arguments = $"/c type \"{files[0]}\"",
+ RedirectStandardOutput = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ }
+ };
+
+ process.Start();
+ string drillTapeContent = process.StandardOutput.ReadToEnd();
+ process.WaitForExit();
+
+ ViewModel.LoadToolsFromDrillTape(drillTapeContent);
+ }
+ catch (Exception ex)
+ {
+ System.Windows.MessageBox.Show($"加载钻带文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ }
+ base.OnDrop(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/MainWindowViewModel.cs b/MainWindowViewModel.cs
new file mode 100644
index 0000000..06f2c2f
--- /dev/null
+++ b/MainWindowViewModel.cs
@@ -0,0 +1,1607 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text.RegularExpressions;
+using System.Windows;
+using DrillTools.Integration;
+
+namespace DrillTools
+{
+ ///
+ /// 主窗口视图模型
+ ///
+ public class MainWindowViewModel : INotifyPropertyChanged
+ {
+ private ObservableCollection _tools = new();
+ private ToolItem? _selectedTool;
+ private string _drillTapeContent = string.Empty;
+ private bool _canMoveUp;
+ private bool _canMoveDown;
+ private string _originalFilePath = string.Empty;
+
+ ///
+ /// 刀具列表
+ ///
+ public ObservableCollection Tools
+ {
+ get => _tools;
+ set => SetProperty(ref _tools, value);
+ }
+
+ ///
+ /// 选中的刀具
+ ///
+ public ToolItem? SelectedTool
+ {
+ get => _selectedTool;
+ set
+ {
+ if (SetProperty(ref _selectedTool, value))
+ {
+ UpdateMoveButtonsState();
+ }
+ }
+ }
+
+ ///
+ /// 钻带内容
+ ///
+ public string DrillTapeContent
+ {
+ get => _drillTapeContent;
+ set => SetProperty(ref _drillTapeContent, value);
+ }
+
+ ///
+ /// 是否可以上移
+ ///
+ public bool CanMoveUp
+ {
+ get => _canMoveUp;
+ set => SetProperty(ref _canMoveUp, value);
+ }
+
+ ///
+ /// 是否可以下移
+ ///
+ public bool CanMoveDown
+ {
+ get => _canMoveDown;
+ set => SetProperty(ref _canMoveDown, value);
+ }
+
+ ///
+ /// 原始文件路径
+ ///
+ public string OriginalFilePath
+ {
+ get => _originalFilePath;
+ set
+ {
+ if (SetProperty(ref _originalFilePath, value))
+ {
+ // 当原始文件路径改变时,通知 HasOriginalFile 属性也已更改
+ OnPropertyChanged(nameof(HasOriginalFile));
+ }
+ }
+ }
+
+ ///
+ /// 是否有原始文件
+ ///
+ public bool HasOriginalFile => !string.IsNullOrEmpty(OriginalFilePath);
+
+ ///
+ /// 从钻带内容加载刀具信息
+ ///
+ /// 钻带内容
+ public void LoadToolsFromDrillTape(string drillTapeContent)
+ {
+ DrillTapeContent = drillTapeContent;
+ Tools.Clear();
+
+ try
+ {
+ // 使用现有的 DrillTapeProcessor 处理钻带数据
+ var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
+
+ if (result.Success)
+ {
+ foreach (var toolResult in result.ToolResults)
+ {
+ var toolItem = new ToolItem
+ {
+ ToolNumber = toolResult.ToolNumber,
+ Diameter = toolResult.Diameter,
+ // 孔数相关属性已移除
+ // RegularHoles = toolResult.RegularHoles;
+ // SlotHoles = toolResult.SlotHoles;
+ // TotalHoles = toolResult.TotalHoles;
+ ToolType = toolResult.ToolType,
+ ToolSuffixType = toolResult.ToolSuffixType,
+ ToolCategory = toolResult.ToolCategory,
+ HoleLocations = toolResult.Locations ?? new List()
+ };
+
+ // 如果是机台码,使用DrillTapeProcessor已经解析出的机台码信息
+ if (toolResult.ToolType == ToolType.MachineCode)
+ {
+ toolItem.MachineCodeCommand = toolResult.MachineCodeCommand;
+ toolItem.MachineCodeType = toolResult.MachineCodeType;
+
+ // 添加日志验证机台码信息传递
+ System.Diagnostics.Debug.WriteLine($"[机台码传递] T{toolResult.ToolNumber:D2}: 命令={toolItem.MachineCodeCommand}, 类型={toolItem.MachineCodeType}");
+
+ // 如果 toolResult.Locations 已经包含坐标数据,则使用它
+ // 否则从原始钻带内容中提取坐标行
+ if (toolItem.HoleLocations == null || toolItem.HoleLocations.Count == 0)
+ {
+ // 从钻带内容中提取机台码坐标行
+ var toolPattern = $@"%.+?T{toolResult.ToolNumber:D2}(.*?)(?=T\d{{2}}|M30)";
+ var match = System.Text.RegularExpressions.Regex.Match(DrillTapeContent, toolPattern, System.Text.RegularExpressions.RegexOptions.Singleline);
+
+ if (match.Success)
+ {
+ string holeSection = match.Groups[1].Value;
+
+ // 查找机台码坐标行
+ var coordinatePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
+ var coordinateMatches = System.Text.RegularExpressions.Regex.Matches(holeSection, coordinatePattern);
+
+ toolItem.HoleLocations = new List();
+ foreach (Match coordMatch in coordinateMatches)
+ {
+ toolItem.HoleLocations.Add(coordMatch.Value);
+ }
+
+ System.Diagnostics.Debug.WriteLine($"[机台码坐标] T{toolResult.ToolNumber:D2}: 找到{toolItem.HoleLocations.Count}个坐标");
+ }
+ }
+ }
+
+ Tools.Add(toolItem);
+ }
+
+ // 更新按钮状态
+ UpdateMoveButtonsState();
+ }
+ else
+ {
+ System.Windows.MessageBox.Show($"解析钻带失败: {result.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ catch (Exception ex)
+ {
+ System.Windows.MessageBox.Show($"解析钻带时发生异常: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ ///
+ /// 重新排序刀具
+ ///
+ /// 原索引
+ /// 新索引
+ public void ReorderTools(int oldIndex, int newIndex)
+ {
+ if (oldIndex < 0 || oldIndex >= Tools.Count || newIndex < 0 || newIndex >= Tools.Count)
+ return;
+
+ var tool = Tools[oldIndex];
+
+ // 检查是否是机台码刀具,如果是则不允许移动
+ if (tool.ToolType == ToolType.MachineCode)
+ {
+ System.Windows.MessageBox.Show("机台码刀具不允许移动位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ // 检查目标位置是否是机台码刀具
+ var targetTool = Tools[newIndex];
+ if (targetTool.ToolType == ToolType.MachineCode)
+ {
+ System.Windows.MessageBox.Show("不能移动到机台码刀具位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ Tools.RemoveAt(oldIndex);
+ Tools.Insert(newIndex, tool);
+ }
+
+ ///
+ /// 上移选中的刀具
+ ///
+ public void MoveSelectedToolUp()
+ {
+ if (SelectedTool == null || !CanMoveUp)
+ return;
+
+ int currentIndex = Tools.IndexOf(SelectedTool);
+ System.Diagnostics.Debug.WriteLine($"[MoveUp] 开始上移操作,选中项索引: {currentIndex}, 刀具编号: T{SelectedTool.ToolNumber:D2}");
+
+ if (currentIndex > 0)
+ {
+ // 检查是否是机台码刀具
+ if (SelectedTool.ToolType == ToolType.MachineCode)
+ {
+ System.Windows.MessageBox.Show("机台码刀具不允许移动位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ // 检查目标位置是否是机台码刀具
+ var targetTool = Tools[currentIndex - 1];
+ if (targetTool.ToolType == ToolType.MachineCode)
+ {
+ System.Windows.MessageBox.Show("不能移动到机台码刀具位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ // 保存选中的刀具引用
+ var selectedTool = SelectedTool;
+ int newIndex = currentIndex - 1;
+
+ // 执行上移操作
+ Tools.RemoveAt(currentIndex);
+ Tools.Insert(newIndex, selectedTool);
+
+ System.Diagnostics.Debug.WriteLine($"[MoveUp] 上移完成,新索引: {newIndex}");
+
+ // 使用延迟方法重新选中移动后的项
+ System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ System.Diagnostics.Debug.WriteLine($"[MoveUp] 延迟设置选中项,刀具编号: T{selectedTool.ToolNumber:D2}");
+ SelectedTool = selectedTool;
+ UpdateMoveButtonsState();
+ }), System.Windows.Threading.DispatcherPriority.Background);
+ }
+ }
+
+ ///
+ /// 下移选中的刀具
+ ///
+ public void MoveSelectedToolDown()
+ {
+ if (SelectedTool == null || !CanMoveDown)
+ return;
+
+ int currentIndex = Tools.IndexOf(SelectedTool);
+ System.Diagnostics.Debug.WriteLine($"[MoveDown] 开始下移操作,选中项索引: {currentIndex}, 刀具编号: T{SelectedTool.ToolNumber:D2}");
+
+ if (currentIndex >= 0 && currentIndex < Tools.Count - 1)
+ {
+ // 检查是否是机台码刀具
+ if (SelectedTool.ToolType == ToolType.MachineCode)
+ {
+ System.Windows.MessageBox.Show("机台码刀具不允许移动位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ // 检查目标位置是否是机台码刀具
+ var targetTool = Tools[currentIndex + 1];
+ if (targetTool.ToolType == ToolType.MachineCode)
+ {
+ System.Windows.MessageBox.Show("不能移动到机台码刀具位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ // 保存选中的刀具引用
+ var selectedTool = SelectedTool;
+ int newIndex = currentIndex + 1;
+
+ // 执行下移操作
+ Tools.RemoveAt(currentIndex);
+ Tools.Insert(newIndex, selectedTool);
+
+ System.Diagnostics.Debug.WriteLine($"[MoveDown] 下移完成,新索引: {newIndex}");
+
+ // 使用延迟方法重新选中移动后的项
+ System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ System.Diagnostics.Debug.WriteLine($"[MoveDown] 延迟设置选中项,刀具编号: T{selectedTool.ToolNumber:D2}");
+ SelectedTool = selectedTool;
+ UpdateMoveButtonsState();
+ }), System.Windows.Threading.DispatcherPriority.Background);
+ }
+ }
+
+ ///
+ /// 更新上移/下移按钮的状态
+ ///
+ private void UpdateMoveButtonsState()
+ {
+ if (SelectedTool == null)
+ {
+ CanMoveUp = false;
+ CanMoveDown = false;
+ System.Diagnostics.Debug.WriteLine("[UpdateButtons] 没有选中项,禁用所有按钮");
+ return;
+ }
+
+ int index = Tools.IndexOf(SelectedTool);
+ CanMoveUp = index > 0;
+ CanMoveDown = index >= 0 && index < Tools.Count - 1;
+
+ System.Diagnostics.Debug.WriteLine($"[UpdateButtons] 选中项索引: {index}, CanMoveUp: {CanMoveUp}, CanMoveDown: {CanMoveDown}");
+ }
+
+ ///
+ /// 保存刀具顺序并应用到钻带处理
+ ///
+ /// 重新排序后的钻带内容
+ public string ApplyToolOrderToDrillTape()
+ {
+ if (string.IsNullOrEmpty(OriginalFilePath))
+ {
+ throw new InvalidOperationException("没有原始文件路径,请先加载钻带文件");
+ }
+
+ if (Tools.Count == 0)
+ {
+ throw new InvalidOperationException("没有刀具数据,请先加载钻带文件");
+ }
+
+ try
+ {
+ // 1. 使用现有的扩展方法生成重新排序后的钻带内容
+ string reorderedDrillTape = DrillTapeProcessorExtensions.GenerateReorderedDrillTape(DrillTapeContent, Tools.ToList());
+
+ // 2. 改进的备份逻辑
+ if (File.Exists(OriginalFilePath))
+ {
+ string backupFilePath = OriginalFilePath + ".bak";
+
+ // 检查备份文件是否已存在
+ if (File.Exists(backupFilePath))
+ {
+ var result = System.Windows.MessageBox.Show(
+ "备份文件已存在,请选择处理方式:\n\n" +
+ "是(Y):覆盖现有备份文件\n" +
+ "否(N):创建带时间戳的新备份文件\n" +
+ "取消:中止保存操作\n\n" +
+ "提示:选择'否'可以保留之前的备份历史",
+ "备份选项",
+ MessageBoxButton.YesNoCancel,
+ MessageBoxImage.Question);
+
+ switch (result)
+ {
+ case MessageBoxResult.Yes:
+ // 覆盖现有备份文件
+ File.Copy(OriginalFilePath, backupFilePath, true);
+ break;
+
+ case MessageBoxResult.No:
+ // 创建带时间戳的新备份文件
+ string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
+ string timestampBackupPath = $"{OriginalFilePath}.{timestamp}.bak";
+ File.Copy(OriginalFilePath, timestampBackupPath);
+ break;
+
+ case MessageBoxResult.Cancel:
+ // 用户取消操作
+ throw new OperationCanceledException("用户取消了保存操作");
+ }
+ }
+ else
+ {
+ // 备份文件不存在,直接创建
+ File.Copy(OriginalFilePath, backupFilePath);
+ }
+ }
+
+ // 3. 将重新排序后的钻带内容写入原始文件
+ File.WriteAllText(OriginalFilePath, reorderedDrillTape);
+
+ // 4. 更新当前钻带内容
+ DrillTapeContent = reorderedDrillTape;
+
+ return reorderedDrillTape;
+ }
+ catch (OperationCanceledException)
+ {
+ // 重新抛出取消异常,不包装
+ throw;
+ }
+ catch (Exception ex)
+ {
+ throw new InvalidOperationException($"保存钻带文件失败: {ex.Message}", ex);
+ }
+ }
+
+ ///
+ /// 重排刀序并重新编号
+ ///
+ /// 重排后的钻带内容
+ public string ReorderAndRenumberTools()
+ {
+ if (Tools.Count == 0)
+ {
+ throw new InvalidOperationException("没有可重排的刀具");
+ }
+
+ // 1. 创建原始刀具编号到新编号的映射
+ var toolNumberMapping = new Dictionary();
+ var originalToNewMapping = new Dictionary(); // 保存原始映射关系
+
+ // 2. 按当前列表顺序重新编号(T01, T02, T03...)
+ int newToolNumber = 1;
+ foreach (var tool in Tools.ToList())
+ {
+ // 机台码刀具不允许重新编号
+ if (tool.ToolType != ToolType.MachineCode)
+ {
+ originalToNewMapping[tool.ToolNumber] = newToolNumber;
+ toolNumberMapping[tool.ToolNumber] = newToolNumber;
+ tool.ToolNumber = newToolNumber++;
+ }
+ else
+ {
+ // 机台码刀具保持原始编号,但也要加入映射
+ toolNumberMapping[tool.ToolNumber] = tool.ToolNumber;
+ }
+ }
+
+ // 3. 更新钻带内容中的刀具编号和孔位数据
+ string updatedDrillTape = UpdateDrillTapeWithNewToolNumbers(DrillTapeContent, toolNumberMapping);
+
+ // 4. 更新钻带内容
+ DrillTapeContent = updatedDrillTape;
+
+ // 5. 更新界面显示
+ OnPropertyChanged(nameof(Tools));
+
+ return updatedDrillTape;
+ }
+
+ ///
+ /// 使用新的刀具编号更新钻带内容
+ ///
+ /// 原始钻带内容
+ /// 刀具编号映射
+ /// 更新后的钻带内容
+ private string UpdateDrillTapeWithNewToolNumbers(string originalDrillTape, Dictionary toolNumberMapping)
+ {
+ var lines = originalDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
+ var result = new List();
+
+ // 创建新编号到刀具对象的映射,以便获取对应的坐标数据
+ var newNumberToToolMap = new Dictionary();
+ foreach (var tool in Tools)
+ {
+ if (toolNumberMapping.ContainsValue(tool.ToolNumber))
+ {
+ newNumberToToolMap[tool.ToolNumber] = tool;
+ }
+ }
+
+ // 首先解析原始钻带中的刀具定义行,保存参数信息
+ var originalToolDefinitions = new Dictionary();
+ var headerLines = new List();
+
+ foreach (var line in lines)
+ {
+ string trimmedLine = line.Trim();
+
+ if (trimmedLine == "%")
+ {
+ //headerLines.Add(line);
+ break;
+ }
+
+ // 处理刀具定义行(如 T01C1.049H05000Z+0.000S060.00F105.0U0700.0)
+ if (Regex.IsMatch(trimmedLine, @"^T(\d+)C"))
+ {
+ var match = Regex.Match(trimmedLine, @"^T(\d+)C(.*)$");
+ if (match.Success)
+ {
+ int originalToolNumber = int.Parse(match.Groups[1].Value);
+ originalToolDefinitions[originalToolNumber] = match.Groups[2].Value;
+ }
+ }
+ else
+ {
+ if (line != "")
+ headerLines.Add(line);
+ }
+ }
+
+ // 添加头部信息
+ result.AddRange(headerLines);
+
+ // 按照新的刀具编号顺序输出刀具定义部分
+ var sortedTools = Tools.OrderBy(t => t.ToolNumber).ToList();
+ foreach (var tool in sortedTools)
+ {
+ // 查找原始刀具编号
+ int originalToolNumber = -1;
+ foreach (var kvp in toolNumberMapping)
+ {
+ if (kvp.Value == tool.ToolNumber)
+ {
+ originalToolNumber = kvp.Key;
+ break;
+ }
+ }
+
+ if (originalToolNumber != -1 && originalToolDefinitions.ContainsKey(originalToolNumber))
+ {
+ string toolDef = $"T{tool.ToolNumber:D2}C{originalToolDefinitions[originalToolNumber]}";
+ result.Add(toolDef);
+ }
+ }
+
+ // 添加 % 符号
+ result.Add("%");
+
+ // 处理刀具切换行和坐标数据部分
+ // 按新刀具编号顺序输出刀具切换行和对应的坐标数据
+ var sortedToolsForData = Tools.OrderBy(t => t.ToolNumber).ToList();
+
+ foreach (var tool in sortedToolsForData)
+ {
+ // 添加刀具切换行
+ result.Add($"T{tool.ToolNumber:D2}");
+
+ // 添加该刀具对应的所有坐标数据
+ if (tool.ToolType != ToolType.MachineCode && tool.HoleLocations != null && tool.HoleLocations.Count > 0)
+ {
+ foreach (var location in tool.HoleLocations)
+ {
+ result.Add(location);
+ }
+ }
+
+ // 如果是机台码刀具,添加机台码命令和坐标
+ if (tool.ToolType == ToolType.MachineCode)
+ {
+ if (!string.IsNullOrEmpty(tool.MachineCodeCommand) && !string.IsNullOrEmpty(tool.MachineCodeType))
+ {
+ result.Add($"{tool.MachineCodeCommand},{tool.MachineCodeType},$S $N");
+
+ // 添加机台码的坐标数据
+ if (tool.HoleLocations != null && tool.HoleLocations.Count > 0)
+ {
+ foreach (var location in tool.HoleLocations)
+ {
+ result.Add(location);
+ }
+ }
+ }
+ }
+ }
+
+ // 添加结束标记
+ result.Add("M30");
+
+ return string.Join("\r\n", result);
+ }
+
+ ///
+ /// 加载示例数据
+ ///
+ public void LoadSampleData()
+ {
+ // 清空原始文件路径,因为这是示例数据
+ OriginalFilePath = string.Empty;
+ Tools.Clear();
+
+ // 添加示例刀具数据
+ Tools.Add(new ToolItem
+ {
+ ToolNumber = 1,
+ Diameter = 1.049, // 尾号9,特殊孔径固定为圆孔
+ // 孔数相关属性已移除
+ // RegularHoles = 7,
+ // SlotHoles = 0,
+ // TotalHoles = 7,
+ ToolType = ToolType.Regular,
+ ToolSuffixType = ToolItem.GetToolSuffixType(1.049), // 特殊孔径
+ ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.049)),
+ HoleLocations = new List
+ {
+ "X-167525Y013500",
+ "X-167525Y018500",
+ "X-167525Y023500",
+ "X167525Y013500",
+ "X167525Y018500",
+ "X167525Y023500",
+ "X099366Y502000"
+ }
+ });
+ Tools.Add(new ToolItem
+ {
+ ToolNumber = 2,
+ Diameter = 1.550, // 尾号0 -> 钻针
+ // 孔数相关属性已移除
+ // RegularHoles = 5,
+ // SlotHoles = 0,
+ // TotalHoles = 5,
+ ToolType = ToolType.Regular,
+ ToolSuffixType = ToolItem.GetToolSuffixType(1.550), // 基于孔径计算
+ ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.550)),
+ HoleLocations = new List
+ {
+ "X-065975Y115250",
+ "X-085825Y122450",
+ "X-085825Y124550",
+ "X-097425Y115250",
+ "X103093Y502000"
+ }
+ });
+ Tools.Add(new ToolItem
+ {
+ ToolNumber = 3,
+ Diameter = 1.156, // 尾号6 -> EA型槽刀
+ // 孔数相关属性已移除
+ // RegularHoles = 1,
+ // SlotHoles = 528,
+ // TotalHoles = 529,
+ ToolType = ToolType.Slot,
+ ToolSuffixType = ToolItem.GetToolSuffixType(1.156), // 基于孔径计算
+ ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.156)),
+ HoleLocations = new List
+ {
+ "X-069659Y016450G85X-094159Y016450",
+ "X-181341Y195550G85X-156841Y195550",
+ "X-069659Y210450G85X-094159Y210450",
+ "X-181341Y389550G85X-156841Y389550",
+ "X-069659Y404450G85X-094159Y404450",
+ "X-181341Y583550G85X-156841Y583550",
+ "X162939Y596000"
+ }
+ });
+ Tools.Add(new ToolItem
+ {
+ ToolNumber = 4,
+ Diameter = 1.451, // 尾号1 -> 槽刀
+ // 孔数相关属性已移除
+ // RegularHoles = 57,
+ // SlotHoles = 0,
+ // TotalHoles = 57,
+ ToolType = ToolType.Regular,
+ ToolSuffixType = ToolItem.GetToolSuffixType(1.451), // 基于孔径计算
+ ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.451)),
+ HoleLocations = new List
+ {
+ "X-065975Y115250",
+ "X-085825Y122450",
+ "X-085825Y124550",
+ "X-097425Y115250",
+ "X103093Y502000"
+ }
+ });
+ Tools.Add(new ToolItem
+ {
+ ToolNumber = 5,
+ Diameter = 1.153, // 尾号3 -> 粉尘刀
+ // 孔数相关属性已移除
+ // RegularHoles = 10,
+ // SlotHoles = 0,
+ // TotalHoles = 10,
+ ToolType = ToolType.Regular,
+ ToolSuffixType = ToolItem.GetToolSuffixType(1.153), // 基于孔径计算
+ ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.153)),
+ HoleLocations = new List
+ {
+ "X-065975Y115250",
+ "X-085825Y122450",
+ "X-085825Y124550",
+ "X-097425Y115250",
+ "X103093Y502000"
+ }
+ });
+ Tools.Add(new ToolItem
+ {
+ ToolNumber = 6,
+ Diameter = 0.499, // 特殊孔径固定为圆孔(机台码)
+ // 孔数相关属性已移除
+ // RegularHoles = 57,
+ // SlotHoles = 0,
+ // TotalHoles = 57,
+ ToolType = ToolType.MachineCode,
+ MachineCodeCommand = "M97",
+ MachineCodeType = "A*",
+ ToolSuffixType = ToolItem.GetToolSuffixType(0.499), // 特殊孔径
+ ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(0.499)),
+ HoleLocations = new List { "X-194000Y002000" } // 机台码刀具的坐标数据
+ });
+
+ // 更新按钮状态
+ UpdateMoveButtonsState();
+
+ // 加载示例钻带内容
+ DrillTapeContent = @"M48
+;厚铜板参数-镀膜-EA-250618
+T01C1.049H05000Z+0.000S060.00F105.0U0700.0
+T02C1.550H01500Z+0.150S070.00F008.0U0800.0
+T03C1.156H03000Z-0.200S040.00F030.0U0900.0
+T04C1.451H01500Z+0.150S070.00F008.0U0800.0
+T05C1.153H01500Z+0.150S070.00F008.0U0800.0
+T06C0.499H01500Z+0.150S070.00F008.0U0800.0
+%
+T01
+X-167525Y013500
+X-167525Y018500
+X-167525Y023500
+X167525Y013500
+X167525Y018500
+X167525Y023500
+X099366Y502000
+T02
+X-065975Y115250
+X-085825Y122450
+X-085825Y124550
+X-097425Y115250
+X103093Y502000
+T03
+X-069659Y016450G85X-094159Y016450
+X-181341Y195550G85X-156841Y195550
+X-069659Y210450G85X-094159Y210450
+X-181341Y389550G85X-156841Y389550
+X-069659Y404450G85X-094159Y404450
+X-181341Y583550G85X-156841Y583550
+X162939Y596000
+T04
+X-065975Y115250
+X-085825Y122450
+X-085825Y124550
+X-097425Y115250
+X103093Y502000
+T05
+X-065975Y115250
+X-085825Y122450
+X-085825Y124550
+X-097425Y115250
+X103093Y502000
+T06
+M97,A*,$S $N
+X-194000Y002000
+M30";
+ }
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null)
+ {
+ if (EqualityComparer.Default.Equals(field, value))
+ return false;
+
+ field = value;
+ OnPropertyChanged(propertyName);
+ return true;
+ }
+
+ protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ ///
+ /// 测试机台码孔数计算功能
+ ///
+ public void TestMachineCodeHoleCalculation()
+ {
+ Console.WriteLine("=== 机台码孔数计算测试 ===");
+
+ // 测试钻带内容
+ string drillTapeContent = @"M48
+;厚铜板参数-镀膜-EA-250618
+T01C0.799H05000Z+0.000S060.00F105.0U0700.0
+T02C0.656H01500Z+0.150S070.00F008.0U0800.0
+T03C1.601H03000Z-0.200S040.00F030.0U0900.0
+T04C0.499
+%
+T01
+X-167525Y013500
+X-167525Y018500
+X-167525Y023500
+X167525Y013500
+X167525Y018500
+X167525Y023500
+X099366Y502000
+T02
+X-065975Y115250
+X-085825Y122450
+X-085825Y124550
+X-097425Y115250
+X103093Y502000
+T03
+X-069659Y016450G85X-094159Y016450
+X-181341Y195550G85X-156841Y195550
+X-069659Y210450G85X-094159Y210450
+X-181341Y389550G85X-156841Y389550
+X-069659Y404450G85X-094159Y404450
+X-181341Y583550G85X-156841Y583550
+X162939Y596000
+T04
+M97,A*,$S $N
+X-194000Y002000
+M30";
+
+ // 处理钻带
+ var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
+
+ // 输出结果
+ Console.WriteLine($"处理状态: {(result.Success ? "成功" : "失败")}");
+ if (!result.Success)
+ {
+ Console.WriteLine($"错误信息: {result.Message}");
+ return;
+ }
+
+ Console.WriteLine("\n刀具统计:");
+ Console.WriteLine("刀具\t孔径(mm)\t类型\t\t普通孔数\t槽孔数\t总孔数\t孔位数量");
+ Console.WriteLine("========================================================================");
+
+ foreach (var tool in result.ToolResults)
+ {
+ string toolTypeDisplay = tool.ToolType switch
+ {
+ ToolType.Regular => "圆孔",
+ ToolType.Slot => "槽孔",
+ ToolType.MachineCode => "机台码",
+ _ => "未知"
+ };
+
+ Console.WriteLine($"T{tool.ToolNumber:D2}\t{tool.Diameter:F3}\t\t{toolTypeDisplay}\t{tool.RegularHoles}\t\t{tool.SlotHoles}\t{tool.TotalHoles}\t{tool.Locations?.Count ?? 0}");
+ }
+
+ Console.WriteLine($"\n总孔数: {result.TotalHoles}");
+
+ // 验证结果
+ Console.WriteLine("\n=== 验证结果 ===");
+ VerifyResults(result);
+
+ // 测试孔位数据
+ Console.WriteLine("\n=== 孔位数据测试 ===");
+ TestHoleLocations(result);
+ }
+
+ ///
+ /// 测试孔位数据
+ ///
+ /// 钻带处理结果
+ private void TestHoleLocations(DrillTapeResult result)
+ {
+ foreach (var tool in result.ToolResults)
+ {
+ Console.WriteLine($"\nT{tool.ToolNumber:D2} 孔位数据 ({tool.Locations?.Count ?? 0} 个):");
+ if (tool.Locations != null && tool.Locations.Count > 0)
+ {
+ foreach (var location in tool.Locations.Take(5)) // 只显示前5个
+ {
+ Console.WriteLine($" {location}");
+ }
+ if (tool.Locations.Count > 5)
+ {
+ Console.WriteLine($" ... 还有 {tool.Locations.Count - 5} 个孔位");
+ }
+ }
+ else
+ {
+ Console.WriteLine(" 无孔位数据");
+ }
+ }
+ }
+
+ private void VerifyResults(DrillTapeResult result)
+ {
+ // CAM350的预期结果
+ var expectedResults = new[]
+ {
+ new { ToolNumber = 1, Diameter = 0.799, ExpectedHoles = 7 },
+ new { ToolNumber = 2, Diameter = 0.656, ExpectedHoles = 5 },
+ new { ToolNumber = 3, Diameter = 1.601, ExpectedHoles = 529 },
+ new { ToolNumber = 4, Diameter = 0.499, ExpectedHoles = 57 }
+ };
+
+ bool allMatch = true;
+
+ foreach (var expected in expectedResults)
+ {
+ var actual = result.ToolResults.Find(t => t.ToolNumber == expected.ToolNumber);
+ if (actual != null)
+ {
+ bool match = Math.Abs(actual.Diameter - expected.Diameter) < 0.001 &&
+ actual.TotalHoles == expected.ExpectedHoles;
+
+ Console.WriteLine($"T{expected.ToolNumber:D2} ({expected.Diameter:F3}mm): " +
+ $"预期={expected.ExpectedHoles}, 实际={actual.TotalHoles}, " +
+ $"{(match ? "✓" : "✗")}");
+
+ if (!match)
+ allMatch = false;
+ }
+ else
+ {
+ Console.WriteLine($"T{expected.ToolNumber:D2}: 未找到结果 ✗");
+ allMatch = false;
+ }
+ }
+
+ Console.WriteLine($"\n总体结果: {(allMatch ? "✓ 所有结果与CAM350一致" : "✗ 存在不一致的结果")}");
+ }
+
+ ///
+ /// 测试刀具尾号类型功能
+ ///
+ public void TestToolSuffixTypeFunctionality()
+ {
+ Console.WriteLine("=== 刀具尾号类型功能测试 ===");
+
+ // 测试不同孔径的尾号类型
+ double[] testDiameters = { 1.049, 1.550, 1.156, 1.451, 1.153, 1.255, 1.266, 1.277, 1.288, 1.299 };
+
+ Console.WriteLine("孔径(mm)\t尾号\t尾号类型\t\t大类");
+ Console.WriteLine("==============================================");
+
+ foreach (double diameter in testDiameters)
+ {
+ string diameterStr = diameter.ToString("F3");
+ char lastChar = diameterStr[diameterStr.Length - 1];
+ int suffix = int.Parse(lastChar.ToString());
+ var suffixType = ToolItem.GetToolSuffixType(diameter);
+ var category = ToolItem.GetToolCategory(suffixType);
+ var suffixDisplay = ToolItem.GetToolSuffixTypeDisplay(suffixType);
+ var categoryDisplay = ToolItem.GetToolCategoryDisplay(category);
+
+ Console.WriteLine($"{diameter:F3}\t{suffix}\t{suffixDisplay}\t{categoryDisplay}");
+ }
+
+ Console.WriteLine();
+ Console.WriteLine("=== 测试钻带处理功能 ===");
+
+ // 测试钻带处理
+ string drillTapeContent = @"M48
+T10C1.049
+T11C1.550
+T12C1.156
+T13C1.451
+T14C1.153
+T15C1.255
+T16C1.266
+T17C1.277
+%
+T10
+X01000Y01000
+T11
+X02000Y02000
+T12
+X03000Y03000
+T13
+X04000Y04000
+T14
+X05000Y05000
+T15
+X06000Y06000
+T16
+X07000Y07000
+T17
+X08000Y08000
+M30";
+
+ var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
+
+ if (result.Success)
+ {
+ Console.WriteLine("钻带处理成功!");
+ Console.WriteLine();
+ Console.WriteLine("刀具编号\t孔径(mm)\t类型\t\t尾号类型\t大类\t\t孔数");
+ Console.WriteLine("================================================================");
+
+ foreach (var tool in result.ToolResults)
+ {
+ string toolTypeDisplay = tool.ToolType switch
+ {
+ ToolType.Regular => "圆孔",
+ ToolType.Slot => "槽孔",
+ ToolType.MachineCode => "机台码",
+ _ => "未知"
+ };
+
+ string suffixTypeDisplay = tool.ToolSuffixType switch
+ {
+ ToolSuffixType.Drill => "钻针",
+ ToolSuffixType.Slot => "槽刀",
+ ToolSuffixType.EASlot => "EA型槽刀",
+ ToolSuffixType.DustSlot => "粉尘刀",
+ ToolSuffixType.DeburrSlot => "去毛刺刀",
+ ToolSuffixType.NonStandard => "非标刀",
+ ToolSuffixType.EASlot2 => "EA型槽刀",
+ ToolSuffixType.Special => "特殊刀具",
+ _ => "未知"
+ };
+
+ string categoryDisplay = tool.ToolCategory switch
+ {
+ ToolCategory.Drill => "钻针",
+ ToolCategory.Slot => "槽刀",
+ ToolCategory.EA => "EA刀",
+ ToolCategory.NonStandard => "非标刀",
+ ToolCategory.Special => "特殊刀",
+ _ => "未知"
+ };
+
+ Console.WriteLine($"T{tool.ToolNumber:D2}\t{tool.Diameter:F3}\t\t{toolTypeDisplay}\t{suffixTypeDisplay}\t{categoryDisplay}\t{tool.TotalHoles}");
+ }
+ }
+ else
+ {
+ Console.WriteLine($"钻带处理失败: {result.Message}");
+ }
+
+ Console.WriteLine();
+ Console.WriteLine("测试完成!");
+ }
+
+ ///
+ /// 测试孔位数据功能(可在应用启动时调用)
+ ///
+ public static void TestHoleLocationsFunctionality()
+ {
+ Console.WriteLine("=== 孔位数据功能测试 ===");
+ Console.WriteLine();
+
+ // 使用用户提供的钻带数据示例
+ string drillTapeContent = @"M48
+T01C0.799H05000Z+0.000S060.00F105.0U0700.0
+T02C1.049H05000Z+0.000S045.00F105.0U0700.0
+%
+T01
+X-281000Y003000
+X-276000Y003000
+X-271000Y003000
+X271000Y003000
+X276000Y003000
+X281000Y003000
+X-281000Y702500
+X-276000Y702500
+X-271000Y702500
+X271000Y703000
+X276000Y703000
+X281000Y703000
+X077370Y704000
+T02
+X-100000Y100000
+X-200000Y200000
+X-300000Y300000
+M30";
+
+ // 处理钻带
+ var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
+
+ // 输出结果
+ Console.WriteLine($"处理状态: {(result.Success ? "成功" : "失败")}");
+ if (!result.Success)
+ {
+ Console.WriteLine($"错误信息: {result.Message}");
+ return;
+ }
+
+ Console.WriteLine("\n刀具统计:");
+ Console.WriteLine("刀具\t孔径(mm)\t类型\t\t普通孔数\t槽孔数\t总孔数\t孔位数量");
+ Console.WriteLine("========================================================================");
+
+ foreach (var tool in result.ToolResults)
+ {
+ string toolTypeDisplay = tool.ToolType switch
+ {
+ ToolType.Regular => "圆孔",
+ ToolType.Slot => "槽孔",
+ ToolType.MachineCode => "机台码",
+ _ => "未知"
+ };
+
+ Console.WriteLine($"T{tool.ToolNumber:D2}\t{tool.Diameter:F3}\t\t{toolTypeDisplay}\t{tool.RegularHoles}\t\t{tool.SlotHoles}\t{tool.TotalHoles}\t{tool.Locations?.Count ?? 0}");
+ }
+
+ Console.WriteLine($"\n总孔数: {result.TotalHoles}");
+
+ // 详细显示孔位数据
+ Console.WriteLine("\n=== 详细孔位数据 ===");
+ foreach (var tool in result.ToolResults)
+ {
+ Console.WriteLine($"\nT{tool.ToolNumber:D2} 孔位数据 ({tool.Locations?.Count ?? 0} 个):");
+ if (tool.Locations != null && tool.Locations.Count > 0)
+ {
+ int count = 0;
+ foreach (var location in tool.Locations)
+ {
+ Console.WriteLine($" [{++count:D2}] {location}");
+ }
+ }
+ else
+ {
+ Console.WriteLine(" 无孔位数据");
+ }
+ }
+
+ // 验证T01的孔位数据是否符合预期
+ Console.WriteLine("\n=== 验证T01孔位数据 ===");
+ var t01Result = result.ToolResults.Find(t => t.ToolNumber == 1);
+ if (t01Result != null && t01Result.Locations != null)
+ {
+ var expectedLocations = new System.Collections.Generic.List
+ {
+ "X-281000Y003000",
+ "X-276000Y003000",
+ "X-271000Y003000",
+ "X271000Y003000",
+ "X276000Y003000",
+ "X281000Y003000",
+ "X-281000Y702500",
+ "X-276000Y702500",
+ "X-271000Y702500",
+ "X271000Y703000",
+ "X276000Y703000",
+ "X281000Y703000",
+ "X077370Y704000"
+ };
+
+ bool allMatch = true;
+ if (t01Result.Locations.Count == expectedLocations.Count)
+ {
+ for (int i = 0; i < expectedLocations.Count; i++)
+ {
+ if (t01Result.Locations[i] != expectedLocations[i])
+ {
+ Console.WriteLine($" 位置 {i + 1}: 预期 {expectedLocations[i]}, 实际 {t01Result.Locations[i]} ✗");
+ allMatch = false;
+ }
+ else
+ {
+ Console.WriteLine($" 位置 {i + 1}: {t01Result.Locations[i]} ✓");
+ }
+ }
+ }
+ else
+ {
+ Console.WriteLine($" 孔位数量不匹配: 预期 {expectedLocations.Count}, 实际 {t01Result.Locations.Count} ✗");
+ allMatch = false;
+ }
+
+ Console.WriteLine($"\nT01孔位数据验证结果: {(allMatch ? "✓ 全部匹配" : "✗ 存在不匹配")}");
+ }
+ else
+ {
+ Console.WriteLine("未找到T01刀具数据 ✗");
+ }
+
+ Console.WriteLine("\n孔位数据功能测试完成!");
+ }
+
+ ///
+ /// 显示刀具详情窗口
+ ///
+ /// 要显示详情的刀具
+ public void ShowToolDetail(ToolItem tool)
+ {
+ if (tool == null)
+ return;
+
+ try
+ {
+ var detailWindow = new ToolDetailWindow(tool);
+ detailWindow.Owner = System.Windows.Application.Current.MainWindow;
+ detailWindow.ShowDialog();
+ }
+ catch (Exception ex)
+ {
+ System.Windows.MessageBox.Show($"显示刀具详情失败: {ex.Message}", "错误",
+ System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
+ }
+ }
+
+ ///
+ /// 测试重排刀序功能
+ ///
+ public void TestReorderAndRenumberTools()
+ {
+ Console.WriteLine("=== 重排刀序功能测试 ===");
+
+ // 1. 加载测试数据
+ LoadSampleData();
+
+ // 2. 记录原始状态
+ var originalOrder = Tools.Select(t => new
+ {
+ t.ToolNumber,
+ t.Diameter,
+ LocationCount = t.HoleLocations?.Count ?? 0,
+ FirstLocation = t.HoleLocations?.FirstOrDefault() ?? ""
+ }).ToList();
+
+ Console.WriteLine("原始刀具顺序:");
+ foreach (var tool in originalOrder)
+ {
+ Console.WriteLine($"T{tool.ToolNumber:D2}({tool.Diameter:F3}): {tool.LocationCount}个坐标, 首个坐标: {tool.FirstLocation}");
+ }
+
+ // 3. 执行重排操作(将T02移到第一位)
+ if (Tools.Count >= 2)
+ {
+ var toolToMove = Tools.FirstOrDefault(t => t.ToolNumber == 2);
+ if (toolToMove != null && toolToMove.ToolType != ToolType.MachineCode)
+ {
+ int oldIndex = Tools.IndexOf(toolToMove);
+ ReorderTools(oldIndex, 0);
+ }
+ }
+
+ // 4. 执行重新编号
+ string reorderedDrillTape = ReorderAndRenumberTools();
+
+ // 5. 验证结果
+ Console.WriteLine("\n重排后刀具顺序:");
+ var reorderedOrder = Tools.Select(t => new
+ {
+ t.ToolNumber,
+ t.Diameter,
+ LocationCount = t.HoleLocations?.Count ?? 0,
+ FirstLocation = t.HoleLocations?.FirstOrDefault() ?? ""
+ }).ToList();
+
+ foreach (var tool in reorderedOrder)
+ {
+ Console.WriteLine($"T{tool.ToolNumber:D2}({tool.Diameter:F3}): {tool.LocationCount}个坐标, 首个坐标: {tool.FirstLocation}");
+ }
+
+ // 6. 验证钻带内容
+ Console.WriteLine("\n重排后的钻带内容:");
+ Console.WriteLine(reorderedDrillTape);
+
+ // 7. 验证坐标跟随
+ VerifyCoordinateBinding(originalOrder.ToList(), reorderedOrder.ToList());
+
+ Console.WriteLine("\n重排刀序功能测试完成!");
+ }
+
+ ///
+ /// 验证坐标绑定关系
+ ///
+ private void VerifyCoordinateBinding(List originalOrder, List reorderedOrder)
+ {
+ Console.WriteLine("\n=== 验证坐标绑定关系 ===");
+
+ // 创建直径到坐标的映射
+ var originalDiameterToLocation = new Dictionary();
+ foreach (var tool in originalOrder)
+ {
+ originalDiameterToLocation[tool.Diameter] = tool.FirstLocation;
+ }
+
+ // 验证重排后的坐标绑定
+ bool allMatch = true;
+ foreach (var tool in reorderedOrder)
+ {
+ if (originalDiameterToLocation.ContainsKey(tool.Diameter))
+ {
+ string originalLocation = originalDiameterToLocation[tool.Diameter];
+ if (tool.FirstLocation != originalLocation)
+ {
+ Console.WriteLine($"✗ 刀具{tool.Diameter:F3}的坐标不匹配: 原始{originalLocation}, 重排后{tool.FirstLocation}");
+ allMatch = false;
+ }
+ else
+ {
+ Console.WriteLine($"✓ 刀具{tool.Diameter:F3}的坐标正确跟随: {tool.FirstLocation}");
+ }
+ }
+ }
+
+ Console.WriteLine($"\n坐标绑定验证结果: {(allMatch ? "✓ 全部正确" : "✗ 存在问题")}");
+ }
+
+ ///
+ /// 测试修正后的重排刀序功能
+ ///
+ public void TestFixedReorderFunction()
+ {
+ Console.WriteLine("=== 测试修正后的重排刀序功能 ===");
+
+ // 1. 加载测试数据
+ LoadSampleData();
+
+ Console.WriteLine("原始刀具顺序:");
+ foreach (var tool in Tools)
+ {
+ Console.WriteLine($"T{tool.ToolNumber:D2}C{tool.Diameter:F3}");
+ }
+
+ // 2. 模拟用户重排操作:将T02移到第一位
+ if (Tools.Count >= 2)
+ {
+ var toolToMove = Tools.FirstOrDefault(t => t.ToolNumber == 2);
+ if (toolToMove != null && toolToMove.ToolType != ToolType.MachineCode)
+ {
+ int oldIndex = Tools.IndexOf(toolToMove);
+ ReorderTools(oldIndex, 0);
+
+ Console.WriteLine("\n重排后刀具顺序(重新编号前):");
+ foreach (var tool in Tools)
+ {
+ Console.WriteLine($"T{tool.ToolNumber:D2}C{tool.Diameter:F3}");
+ }
+
+ // 3. 执行重新编号
+ string reorderedDrillTape = ReorderAndRenumberTools();
+
+ Console.WriteLine("\n重排并重新编号后的刀具顺序:");
+ foreach (var tool in Tools)
+ {
+ Console.WriteLine($"T{tool.ToolNumber:D2}C{tool.Diameter:F3}");
+ }
+
+ // 4. 验证刀具定义部分是否按顺序排列
+ Console.WriteLine("\n=== 验证结果 ===");
+ var lines = reorderedDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
+ var toolDefinitionOrder = new List();
+
+ foreach (var line in lines)
+ {
+ if (line.Trim() == "%")
+ {
+ break;
+ }
+
+ if (Regex.IsMatch(line, @"^T(\d+)C"))
+ {
+ var match = Regex.Match(line, @"^T(\d+)C");
+ if (match.Success)
+ {
+ toolDefinitionOrder.Add(int.Parse(match.Groups[1].Value));
+ }
+ }
+ }
+
+ Console.WriteLine("刀具定义部分的顺序: " + string.Join(", ", toolDefinitionOrder.Select(t => $"T{t:D2}")));
+
+ bool isOrdered = true;
+ for (int i = 1; i < toolDefinitionOrder.Count; i++)
+ {
+ if (toolDefinitionOrder[i] < toolDefinitionOrder[i - 1])
+ {
+ isOrdered = false;
+ break;
+ }
+ }
+
+ Console.WriteLine($"刀具定义部分是否按顺序排列: {(isOrdered ? "是" : "否")}");
+
+ if (isOrdered)
+ {
+ Console.WriteLine("✓ 重排刀序功能修正成功!");
+ }
+ else
+ {
+ Console.WriteLine("✗ 重排刀序功能仍有问题!");
+ }
+
+ // 5. 显示完整的重排后钻带内容
+ Console.WriteLine("\n重排后的钻带内容:");
+ Console.WriteLine(reorderedDrillTape);
+ }
+ }
+ }
+
+ ///
+ /// 测试机台码坐标数据完整性
+ ///
+ public void TestMachineCodeCoordinateIntegrity()
+ {
+ Console.WriteLine("=== 机台码坐标数据完整性测试 ===");
+
+ // 1. 加载示例数据
+ LoadSampleData();
+
+ // 2. 执行重排刀序操作
+ string reorderedDrillTape = ReorderAndRenumberTools();
+
+ // 3. 验证机台码坐标数据
+ Console.WriteLine("重排后的钻带内容:");
+ Console.WriteLine(reorderedDrillTape);
+
+ // 4. 检查机台码部分是否包含坐标数据
+ var lines = reorderedDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
+ bool foundMachineCode = false;
+ bool foundCoordinate = false;
+ int machineCodeToolNumber = -1;
+
+ for (int i = 0; i < lines.Length; i++)
+ {
+ string line = lines[i].Trim();
+
+ // 查找机台码刀具
+ if (Regex.IsMatch(line, @"^T(\d+)"))
+ {
+ var match = Regex.Match(line, @"^T(\d+)");
+ if (match.Success)
+ {
+ int toolNumber = int.Parse(match.Groups[1].Value);
+ var tool = Tools.FirstOrDefault(t => t.ToolNumber == toolNumber);
+
+ if (tool != null && tool.ToolType == ToolType.MachineCode)
+ {
+ foundMachineCode = true;
+ machineCodeToolNumber = toolNumber;
+ Console.WriteLine($"\n找到机台码刀具 T{toolNumber:D2}");
+
+ // 检查下一行是否是机台码命令
+ if (i + 1 < lines.Length)
+ {
+ string nextLine = lines[i + 1].Trim();
+ if (Regex.IsMatch(nextLine, @"(M97|M98),(A\*|B\*),\$S \$N"))
+ {
+ Console.WriteLine($" 机台码命令: {nextLine}");
+
+ // 检查下下行是否是坐标数据
+ if (i + 2 < lines.Length)
+ {
+ string coordinateLine = lines[i + 2].Trim();
+ if (Regex.IsMatch(coordinateLine, @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)"))
+ {
+ foundCoordinate = true;
+ Console.WriteLine($" 坐标数据: {coordinateLine}");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 5. 输出测试结果
+ Console.WriteLine("\n=== 测试结果 ===");
+ Console.WriteLine($"找到机台码刀具: {(foundMachineCode ? "是" : "否")}");
+ Console.WriteLine($"找到坐标数据: {(foundCoordinate ? "是" : "否")}");
+
+ if (foundMachineCode && foundCoordinate)
+ {
+ Console.WriteLine("✓ 机台码坐标数据完整性测试通过!");
+ }
+ else
+ {
+ Console.WriteLine("✗ 机台码坐标数据完整性测试失败!");
+
+ if (!foundMachineCode)
+ Console.WriteLine(" 原因:未找到机台码刀具");
+ if (!foundCoordinate)
+ Console.WriteLine(" 原因:机台码刀具缺少坐标数据");
+ }
+
+ // 6. 验证ToolItem中的坐标数据
+ var machineCodeTool = Tools.FirstOrDefault(t => t.ToolType == ToolType.MachineCode);
+ if (machineCodeTool != null)
+ {
+ Console.WriteLine($"\nToolItem中的机台码坐标数据:");
+ Console.WriteLine($" 刀具编号: T{machineCodeTool.ToolNumber:D2}");
+ Console.WriteLine($" 机台码命令: {machineCodeTool.MachineCodeCommand}");
+ Console.WriteLine($" 机台码类型: {machineCodeTool.MachineCodeType}");
+ Console.WriteLine($" 坐标数量: {machineCodeTool.HoleLocations?.Count ?? 0}");
+
+ if (machineCodeTool.HoleLocations != null && machineCodeTool.HoleLocations.Count > 0)
+ {
+ foreach (var location in machineCodeTool.HoleLocations)
+ {
+ Console.WriteLine($" 坐标: {location}");
+ }
+ }
+ }
+ }
+
+ ///
+ /// 测试机台码处理修复效果
+ ///
+ public void TestMachineCodeProcessingFix()
+ {
+ Console.WriteLine("=== 测试机台码处理修复效果 ===");
+
+ // 测试钻带内容(包含机台码)
+ string testDrillTape = @"M48
+;厚铜板参数-镀膜-EA-250618
+T01C1.049H05000Z+0.000S060.00F105.0U0700.0
+T02C1.550H01500Z+0.150S070.00F008.0U0800.0
+T03C1.156H03000Z-0.200S040.00F030.0U0900.0
+T04C0.499H01500Z+0.150S070.00F008.0U0800.0
+%
+T01
+X-167525Y013500
+X-167525Y018500
+X-167525Y023500
+T02
+X-065975Y115250
+X-085825Y122450
+T03
+X-069659Y016450G85X-094159Y016450
+X-181341Y195550G85X-156841Y195550
+T04
+M97,A*,$S $N
+X-194000Y002000
+M30";
+
+ try
+ {
+ // 1. 使用DrillTapeProcessor处理钻带
+ Console.WriteLine("\n1. 使用DrillTapeProcessor处理钻带:");
+ var result = DrillTapeProcessor.ProcessDrillTape(testDrillTape);
+
+ if (!result.Success)
+ {
+ Console.WriteLine($"处理失败: {result.Message}");
+ return;
+ }
+
+ // 2. 检查ToolResult中的机台码信息
+ Console.WriteLine("\n2. 检查ToolResult中的机台码信息:");
+ foreach (var toolResult in result.ToolResults)
+ {
+ Console.WriteLine($"T{toolResult.ToolNumber:D2}: 类型={toolResult.ToolType}, 命令={toolResult.MachineCodeCommand}, 类型={toolResult.MachineCodeType}");
+ }
+
+ // 3. 使用LoadToolsFromDrillTape方法加载到ViewModel
+ Console.WriteLine("\n3. 加载到ViewModel并检查ToolItem中的机台码信息:");
+ DrillTapeContent = testDrillTape;
+ Tools.Clear();
+ LoadToolsFromDrillTape(testDrillTape);
+
+ foreach (var tool in Tools)
+ {
+ Console.WriteLine($"T{tool.ToolNumber:D2}: 类型={tool.ToolType}, 命令={tool.MachineCodeCommand}, 类型={tool.MachineCodeType}");
+ }
+
+ // 4. 测试GenerateReorderedDrillTape方法
+ Console.WriteLine("\n4. 测试GenerateReorderedDrillTape方法:");
+ string reorderedDrillTape = DrillTapeProcessorExtensions.GenerateReorderedDrillTape(testDrillTape, Tools.ToList());
+ Console.WriteLine("重排后的钻带内容:");
+ Console.WriteLine(reorderedDrillTape);
+
+ // 5. 验证机台码信息是否正确保留
+ Console.WriteLine("\n5. 验证机台码信息是否正确保留:");
+ bool machineCodeFound = false;
+ bool machineCodeCommandFound = false;
+ bool machineCodeTypeFound = false;
+
+ var lines = reorderedDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
+ foreach (var line in lines)
+ {
+ if (line.Contains("M97") || line.Contains("M98"))
+ {
+ machineCodeFound = true;
+ if (line.Contains("M97") || line.Contains("M98"))
+ {
+ machineCodeCommandFound = true;
+ }
+ if (line.Contains("A*") || line.Contains("B*"))
+ {
+ machineCodeTypeFound = true;
+ }
+ Console.WriteLine($"找到机台码命令行: {line}");
+ }
+ }
+
+ Console.WriteLine($"\n验证结果:");
+ Console.WriteLine($"机台码命令存在: {machineCodeFound}");
+ Console.WriteLine($"机台码命令类型正确: {machineCodeCommandFound}");
+ Console.WriteLine($"机台码类型正确: {machineCodeTypeFound}");
+
+ if (machineCodeFound && machineCodeCommandFound && machineCodeTypeFound)
+ {
+ Console.WriteLine("\n✓ 机台码处理修复效果验证成功!");
+ }
+ else
+ {
+ Console.WriteLine("\n✗ 机台码处理修复效果验证失败!");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"测试过程中发生异常: {ex.Message}");
+ Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/SlotHoleCalculator.cs b/SlotHoleCalculator.cs
new file mode 100644
index 0000000..fc3903a
--- /dev/null
+++ b/SlotHoleCalculator.cs
@@ -0,0 +1,406 @@
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace DrillTools
+{
+ ///
+ /// 二维点结构
+ ///
+ public struct Point2D
+ {
+ public double X { get; set; }
+ public double Y { get; set; }
+ public string OriginalString { get; set; } // 存储原始坐标字符串
+
+ public Point2D(double x, double y)
+ {
+ X = x;
+ Y = y;
+ OriginalString = "";
+ }
+
+ public Point2D(double x, double y, string originalString)
+ {
+ X = x;
+ Y = y;
+ OriginalString = originalString;
+ }
+
+ ///
+ /// 从钻带坐标字符串创建点(格式:X+/-数字Y+/-数字)
+ ///
+ public static Point2D ParseFromDrillString(string drillString)
+ {
+ var pattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
+ var match = Regex.Match(drillString, pattern);
+ if (match.Success)
+ {
+ double x = double.Parse(match.Groups[1].Value) / 1000.0; // 转换为mm
+ double y = double.Parse(match.Groups[2].Value) / 1000.0; // 转换为mm
+ return new Point2D(x, y, drillString); // 保存原始字符串
+ }
+ throw new ArgumentException($"无效的钻带坐标格式: {drillString}");
+ }
+
+ public static Point2D operator +(Point2D p1, Point2D p2) => new Point2D(p1.X + p2.X, p1.Y + p2.Y);
+ public static Point2D operator -(Point2D p1, Point2D p2) => new Point2D(p1.X - p2.X, p1.Y - p2.Y);
+ }
+
+ ///
+ /// 线段槽孔结构
+ ///
+ public struct LineSlot
+ {
+ public Point2D StartPoint { get; set; }
+ public Point2D EndPoint { get; set; }
+ public double Width { get; set; } // 槽孔宽度/孔径(单位:mm)
+
+ public LineSlot(Point2D startPoint, Point2D endPoint, double width)
+ {
+ StartPoint = startPoint;
+ EndPoint = endPoint;
+ Width = width;
+ }
+
+ ///
+ /// 获取槽孔长度
+ ///
+ public double Length => Math.Sqrt(Math.Pow(StartPoint.X - EndPoint.X, 2) + Math.Pow(StartPoint.Y - EndPoint.Y, 2));
+ }
+
+ ///
+ /// 弧段槽孔结构
+ ///
+ public struct ArcSlot
+ {
+ public Point2D StartPoint { get; set; }
+ public Point2D EndPoint { get; set; }
+ public Point2D CenterPoint { get; set; }
+ public double Width { get; set; } // 槽孔宽度/孔径(单位:mm)
+ public bool CounterClockwise { get; set; } // 是否逆时针方向
+
+ public ArcSlot(Point2D startPoint, Point2D endPoint, Point2D centerPoint, double width, bool counterClockwise = false)
+ {
+ StartPoint = startPoint;
+ EndPoint = endPoint;
+ CenterPoint = centerPoint;
+ Width = width;
+ CounterClockwise = counterClockwise;
+ }
+
+ ///
+ /// 获取弧段半径
+ ///
+ public double Radius => Math.Sqrt(Math.Pow(StartPoint.X - CenterPoint.X, 2) + Math.Pow(StartPoint.Y - CenterPoint.Y, 2));
+ }
+
+ ///
+ /// 槽孔钻孔数量计算工具类
+ /// 提供与CAM350一致的槽孔孔数计算方法
+ ///
+ public static class SlotHoleCalculator
+ {
+ ///
+ /// 默认凸位高度值(CAM350标准,单位:mm)
+ ///
+ private const double DEFAULT_TOLERANCE = 0.0127;
+
+ ///
+ /// 计算线段槽孔的钻孔数量
+ ///
+ /// 线段槽孔参数
+ /// 凸位高度值,默认为0.0127mm(CAM350标准)
+ /// 需要的钻孔数量
+ public static int CalculateLineSlotHoleCount(LineSlot slot, double tolerance = DEFAULT_TOLERANCE)
+ {
+ // 计算孔半径
+ double radius = slot.Width / 2.0;
+
+ // 计算槽孔长度
+ double slotLength = slot.Length;
+
+ // 计算孔中心距
+ double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance);
+
+ // 计算孔数
+ int holeCount = (int)Math.Abs(Math.Floor(-slotLength / holeCenterDistance)) + 1;
+
+ return holeCount;
+ }
+
+ ///
+ /// 计算弧段槽孔的钻孔数量
+ ///
+ /// 弧段槽孔参数
+ /// 凸位高度值,默认为0.0127mm(CAM350标准)
+ /// 需要的钻孔数量
+ public static int CalculateArcSlotHoleCount(ArcSlot slot, double tolerance = DEFAULT_TOLERANCE)
+ {
+ // 计算孔半径
+ double radius = slot.Width / 2.0;
+
+ // 计算弧段长度
+ double arcLength = CalculateArcLength(slot);
+
+ // 计算孔中心距
+ double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance);
+
+ // 计算孔数
+ int holeCount = (int)Math.Abs(Math.Floor(-arcLength / holeCenterDistance)) + 1;
+
+ return holeCount;
+ }
+
+ ///
+ /// 计算线段槽孔的钻孔位置
+ ///
+ /// 线段槽孔参数
+ /// 凸位高度值,默认为0.0127mm(CAM350标准)
+ /// 钻孔位置列表
+ public static List CalculateLineSlotHolePositions(LineSlot slot, double tolerance = DEFAULT_TOLERANCE)
+ {
+ List positions = new List();
+
+ // 计算孔半径
+ double radius = slot.Width / 2.0;
+
+ // 计算孔中心距
+ double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance);
+
+ // 计算槽孔长度
+ double slotLength = slot.Length;
+
+ // 计算孔数
+ int holeCount = CalculateLineSlotHoleCount(slot, tolerance);
+
+ // 计算方位角
+ double angle = CalculateAngle(slot.StartPoint, slot.EndPoint);
+
+ // 添加起点
+ positions.Add(slot.StartPoint);
+
+ // 计算中间点
+ if (holeCount > 2)
+ {
+ double avgDistance = slotLength / (holeCount - 1);
+ Point2D currentPoint = slot.StartPoint;
+
+ for (int i = 1; i < holeCount - 1; i++)
+ {
+ currentPoint = CalculateNextPoint(currentPoint, avgDistance, angle);
+ positions.Add(currentPoint);
+ }
+ }
+
+ // 添加终点
+ if (holeCount > 1)
+ {
+ positions.Add(slot.EndPoint);
+ }
+
+ return positions;
+ }
+
+ ///
+ /// 计算弧段槽孔的钻孔位置
+ ///
+ /// 弧段槽孔参数
+ /// 凸位高度值,默认为0.0127mm(CAM350标准)
+ /// 钻孔位置列表
+ public static List CalculateArcSlotHolePositions(ArcSlot slot, double tolerance = DEFAULT_TOLERANCE)
+ {
+ List positions = new List();
+
+ // 计算孔半径
+ double radius = slot.Width / 2.0;
+
+ // 计算孔中心距
+ double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance);
+
+ // 计算弧段半径
+ double arcRadius = slot.Radius;
+
+ // 计算弧段圆心角
+ double arcAngle = CalculateArcAngle(slot);
+
+ // 计算孔数
+ int holeCount = CalculateArcSlotHoleCount(slot, tolerance);
+
+ // 计算角度步长
+ double angleStep = arcAngle / (holeCount - 1);
+
+ // 计算起始角度
+ double startAngle = CalculateAngle(slot.CenterPoint, slot.StartPoint);
+
+ // 添加起点
+ positions.Add(slot.StartPoint);
+
+ // 计算中间点
+ if (holeCount > 2)
+ {
+ double currentAngle = startAngle;
+ if (slot.CounterClockwise)
+ {
+ currentAngle -= angleStep;
+ }
+ else
+ {
+ currentAngle += angleStep;
+ }
+
+ for (int i = 1; i < holeCount - 1; i++)
+ {
+ Point2D point = CalculatePointOnArc(slot.CenterPoint, arcRadius, currentAngle);
+ positions.Add(point);
+
+ if (slot.CounterClockwise)
+ {
+ currentAngle -= angleStep;
+ }
+ else
+ {
+ currentAngle += angleStep;
+ }
+ }
+ }
+
+ // 添加终点
+ if (holeCount > 1)
+ {
+ positions.Add(slot.EndPoint);
+ }
+
+ return positions;
+ }
+
+ ///
+ /// 从钻带G85命令解析线段槽孔
+ ///
+ /// G85命令字符串,格式:XxxxYxxxG85XxxxYxxx
+ /// 槽孔宽度
+ /// 解析出的线段槽孔
+ public static LineSlot ParseLineSlotFromG85(string g85Command, double width)
+ {
+ var pattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)G85X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
+ var match = Regex.Match(g85Command, pattern);
+ if (match.Success)
+ {
+ // 提取原始坐标字符串
+ string startX = match.Groups[1].Value;
+ string startY = match.Groups[2].Value;
+ string endX = match.Groups[3].Value;
+ string endY = match.Groups[4].Value;
+
+ Point2D startPoint = new Point2D(
+ double.Parse(startX) / 1000.0,
+ double.Parse(startY) / 1000.0,
+ $"X{startX}Y{startY}"
+ );
+ Point2D endPoint = new Point2D(
+ double.Parse(endX) / 1000.0,
+ double.Parse(endY) / 1000.0,
+ $"X{endX}Y{endY}"
+ );
+
+ return new LineSlot(startPoint, endPoint, width);
+ }
+ throw new ArgumentException($"无效的G85命令格式: {g85Command}");
+ }
+
+ // 辅助方法
+
+ ///
+ /// 计算两点间欧氏距离
+ ///
+ private static double CalculateDistance(Point2D p1, Point2D p2)
+ {
+ return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
+ }
+
+ ///
+ /// 计算方位角(度数)
+ ///
+ private static double CalculateAngle(Point2D startPoint, Point2D endPoint)
+ {
+ double angleRad = Math.Atan2(endPoint.Y - startPoint.Y, endPoint.X - startPoint.X);
+ double angleDeg = angleRad * 180.0 / Math.PI;
+
+ // 转换为0-360度范围
+ if (angleDeg < 0)
+ angleDeg += 360;
+
+ return angleDeg;
+ }
+
+ ///
+ /// 计算弧段长度
+ ///
+ public static double CalculateArcLength(ArcSlot arc)
+ {
+ double radius = arc.Radius;
+ double angleDeg = CalculateArcAngle(arc);
+ double angleRad = angleDeg * Math.PI / 180.0;
+ return radius * angleRad;
+ }
+
+ ///
+ /// 计算弧段圆心角(度数)
+ ///
+ private static double CalculateArcAngle(ArcSlot arc)
+ {
+ double startAngle = CalculateAngle(arc.CenterPoint, arc.StartPoint);
+ double endAngle = CalculateAngle(arc.CenterPoint, arc.EndPoint);
+
+ double angleSum;
+ if (arc.CounterClockwise)
+ {
+ if (endAngle >= startAngle)
+ angleSum = 360 - Math.Abs(startAngle - endAngle);
+ else
+ angleSum = Math.Abs(startAngle - endAngle);
+ }
+ else
+ {
+ if (startAngle >= endAngle)
+ angleSum = 360 - Math.Abs(startAngle - endAngle);
+ else
+ angleSum = Math.Abs(startAngle - endAngle);
+ }
+
+ return angleSum;
+ }
+
+ ///
+ /// 计算孔中心距
+ ///
+ private static double CalculateHoleCenterDistance(double radius, double tolerance)
+ {
+ return Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(radius - tolerance, 2)) * 2;
+ }
+
+ ///
+ /// 根据起点、距离和角度计算下一个点
+ ///
+ private static Point2D CalculateNextPoint(Point2D startPoint, double distance, double angleDeg)
+ {
+ double angleRad = angleDeg * Math.PI / 180.0;
+ return new Point2D(
+ startPoint.X + distance * Math.Cos(angleRad),
+ startPoint.Y + distance * Math.Sin(angleRad)
+ );
+ }
+
+ ///
+ /// 根据圆心、半径和角度计算圆弧上的点
+ ///
+ private static Point2D CalculatePointOnArc(Point2D centerPoint, double radius, double angleDeg)
+ {
+ double angleRad = angleDeg * Math.PI / 180.0;
+ return new Point2D(
+ centerPoint.X + radius * Math.Cos(angleRad),
+ centerPoint.Y + radius * Math.Sin(angleRad)
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/SlotHoleCalculatorExamples.cs b/SlotHoleCalculatorExamples.cs
new file mode 100644
index 0000000..ed4a9a3
--- /dev/null
+++ b/SlotHoleCalculatorExamples.cs
@@ -0,0 +1,241 @@
+using System;
+using DrillTools;
+
+namespace DrillTools.Examples
+{
+ ///
+ /// 槽孔计算器使用示例
+ ///
+ public class SlotHoleCalculatorExamples
+ {
+ ///
+ /// 示例1:计算线段槽孔孔数
+ ///
+ public static void CalculateLineSlotHoleCountExample()
+ {
+ Console.WriteLine("=== 线段槽孔孔数计算示例 ===");
+
+ // 创建线段槽孔(参考readme.md中的测试数据)
+ var slot = new LineSlot(
+ new Point2D(-69.659, 16.450), // 起点
+ new Point2D(-94.159, 16.450), // 终点
+ 1.601 // 孔径
+ );
+
+ // 计算孔数
+ int holeCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot);
+
+ Console.WriteLine($"槽孔长度: {slot.Length:F3} mm");
+ Console.WriteLine($"槽孔宽度: {slot.Width} mm");
+ Console.WriteLine($"计算孔数: {holeCount}");
+ Console.WriteLine($"预期孔数: 88 (CAM350标准)");
+ Console.WriteLine($"结果验证: {(holeCount == 88 ? "✓ 通过" : "✗ 失败")}");
+ Console.WriteLine();
+ }
+
+ ///
+ /// 示例2:从G85命令解析并计算
+ ///
+ public static void ParseFromG85Example()
+ {
+ Console.WriteLine("=== G85命令解析示例 ===");
+
+ // G85命令字符串(来自钻带文件)
+ string g85Command = "X-069659Y016450G85X-094159Y016450";
+ double width = 1.601;
+
+ try
+ {
+ // 解析G85命令
+ var slot = SlotHoleCalculator.ParseLineSlotFromG85(g85Command, width);
+
+ // 计算孔数
+ int holeCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot);
+
+ Console.WriteLine($"G85命令: {g85Command}");
+ Console.WriteLine($"解析起点: ({slot.StartPoint.X}, {slot.StartPoint.Y})");
+ Console.WriteLine($"解析终点: ({slot.EndPoint.X}, {slot.EndPoint.Y})");
+ Console.WriteLine($"槽孔宽度: {slot.Width} mm");
+ Console.WriteLine($"计算孔数: {holeCount}");
+ Console.WriteLine();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"解析失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 示例3:计算钻孔位置
+ ///
+ public static void CalculateHolePositionsExample()
+ {
+ Console.WriteLine("=== 钻孔位置计算示例 ===");
+
+ // 创建线段槽孔
+ var slot = new LineSlot(
+ new Point2D(0, 0),
+ new Point2D(10, 0),
+ 1.0
+ );
+
+ // 计算钻孔位置
+ var positions = SlotHoleCalculator.CalculateLineSlotHolePositions(slot);
+
+ Console.WriteLine($"槽孔长度: {slot.Length} mm");
+ Console.WriteLine($"钻孔数量: {positions.Count}");
+ Console.WriteLine("钻孔位置列表:");
+
+ for (int i = 0; i < positions.Count; i++)
+ {
+ Console.WriteLine($" 孔 {i + 1}: ({positions[i].X:F3}, {positions[i].Y:F3})");
+ }
+ Console.WriteLine();
+ }
+
+ ///
+ /// 示例4:弧段槽孔计算
+ ///
+ public static void CalculateArcSlotExample()
+ {
+ Console.WriteLine("=== 弧段槽孔计算示例 ===");
+
+ // 创建弧段槽孔(半圆)
+ var arcSlot = new ArcSlot(
+ new Point2D(10, 0), // 起点
+ new Point2D(0, 10), // 终点
+ new Point2D(0, 0), // 圆心
+ 1.0, // 宽度
+ false // 顺时针
+ );
+
+ // 计算孔数
+ int holeCount = SlotHoleCalculator.CalculateArcSlotHoleCount(arcSlot);
+
+ // 计算钻孔位置
+ var positions = SlotHoleCalculator.CalculateArcSlotHolePositions(arcSlot);
+
+ Console.WriteLine($"弧段半径: {arcSlot.Radius:F3} mm");
+ Console.WriteLine($"弧段长度: {SlotHoleCalculator.CalculateArcLength(arcSlot):F3} mm");
+ Console.WriteLine($"计算孔数: {holeCount}");
+ Console.WriteLine($"钻孔位置数量: {positions.Count}");
+ Console.WriteLine();
+ }
+
+ ///
+ /// 示例5:批量计算不同孔径的槽孔
+ ///
+ public static void BatchCalculationExample()
+ {
+ Console.WriteLine("=== 批量计算示例 ===");
+
+ // 不同孔径的槽孔(参考readme.md中的测试数据)
+ var diameters = new[] { 1.601, 1.701, 1.801, 1.901, 2.001, 1.501, 1.401, 1.301, 1.201, 1.101, 1.001, 0.706, 0.506 };
+ var expectedCounts = new[] { 88, 85, 83, 81, 79, 91, 94, 97, 101, 106, 111, 132, 156 };
+
+ Console.WriteLine("孔径(mm)\t计算孔数\t预期孔数\t验证结果");
+ Console.WriteLine("----------------------------------------");
+
+ for (int i = 0; i < diameters.Length; i++)
+ {
+ var slot = new LineSlot(
+ new Point2D(-69.659, 16.450),
+ new Point2D(-94.159, 16.450),
+ diameters[i]
+ );
+
+ int actualCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot);
+ int expectedCount = expectedCounts[i];
+ bool passed = actualCount == expectedCount;
+
+ Console.WriteLine($"{diameters[i]}\t{actualCount}\t{expectedCount}\t{(passed ? "✓" : "✗")}");
+ }
+ Console.WriteLine();
+ }
+
+ ///
+ /// 示例6:自定义凸位高度值
+ ///
+ public static void CustomToleranceExample()
+ {
+ Console.WriteLine("=== 自定义凸位高度值示例 ===");
+
+ var slot = new LineSlot(
+ new Point2D(0, 0),
+ new Point2D(10, 0),
+ 1.0
+ );
+
+ // 使用默认凸位高度值
+ int defaultHoleCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot);
+
+ // 使用自定义凸位高度值
+ double customTolerance = 0.01; // 0.01mm
+ int customHoleCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot, customTolerance);
+
+ Console.WriteLine($"默认凸位高度值 (0.0127mm): {defaultHoleCount} 个孔");
+ Console.WriteLine($"自定义凸位高度值 (0.01mm): {customHoleCount} 个孔");
+ Console.WriteLine($"差异: {Math.Abs(defaultHoleCount - customHoleCount)} 个孔");
+ Console.WriteLine();
+ }
+
+ ///
+ /// 示例7:处理实际钻带数据
+ ///
+ public static void ProcessRealDrillTapeExample()
+ {
+ Console.WriteLine("=== 处理实际钻带数据示例 ===");
+
+ // 模拟钻带数据中的槽孔命令
+ var g85Commands = new[]
+ {
+ "X-069659Y016450G85X-094159Y016450", // T01 - 1.601mm
+ "X-181341Y195550G85X-156841Y195550", // T02 - 1.601mm
+ "X-181341Y389550G85X-156841Y389550", // T03 - 1.601mm
+ };
+
+ var toolDiameters = new[] { 1.601, 1.601, 1.601 };
+ var expectedHoleCounts = new[] { 88, 88, 88 };
+
+ Console.WriteLine("刀具\t孔径(mm)\tG85命令\t\t\t\t计算孔数\t预期孔数\t验证结果");
+ Console.WriteLine("--------------------------------------------------------------------------------");
+
+ for (int i = 0; i < g85Commands.Length; i++)
+ {
+ try
+ {
+ var slot = SlotHoleCalculator.ParseLineSlotFromG85(g85Commands[i], toolDiameters[i]);
+ int holeCount = SlotHoleCalculator.CalculateLineSlotHoleCount(slot);
+ bool passed = holeCount == expectedHoleCounts[i];
+
+ Console.WriteLine($"T{i + 1:D2}\t{toolDiameters[i]}\t{g85Commands[i]}\t{holeCount}\t\t{expectedHoleCounts[i]}\t\t{(passed ? "✓" : "✗")}");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"T{i + 1:D2}\t{toolDiameters[i]}\t{g85Commands[i]}\t解析失败: {ex.Message}");
+ }
+ }
+ Console.WriteLine();
+ }
+
+ ///
+ /// 运行所有示例
+ ///
+ public static void RunAllExamples()
+ {
+ Console.WriteLine("槽孔计算器使用示例");
+ Console.WriteLine("==================");
+ Console.WriteLine();
+
+ CalculateLineSlotHoleCountExample();
+ ParseFromG85Example();
+ CalculateHolePositionsExample();
+ CalculateArcSlotExample();
+ BatchCalculationExample();
+ CustomToleranceExample();
+ ProcessRealDrillTapeExample();
+
+ Console.WriteLine("所有示例运行完成!");
+ }
+ }
+}
\ No newline at end of file
diff --git a/ToolDetailViewModel.cs b/ToolDetailViewModel.cs
new file mode 100644
index 0000000..6e956d9
--- /dev/null
+++ b/ToolDetailViewModel.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+namespace DrillTools
+{
+ ///
+ /// 刀具详情窗口视图模型
+ ///
+ public class ToolDetailViewModel : INotifyPropertyChanged
+ {
+ private ToolItem? _tool;
+
+ ///
+ /// 刀具对象
+ ///
+ public ToolItem? Tool
+ {
+ get => _tool;
+ set
+ {
+ if (SetProperty(ref _tool, value))
+ {
+ OnPropertyChanged(nameof(WindowTitle));
+ OnPropertyChanged(nameof(HoleLocationsHeader));
+ OnPropertyChanged(nameof(FormattedHoleLocations));
+ OnPropertyChanged(nameof(IsMachineCodeTool));
+ }
+ }
+ }
+
+ ///
+ /// 窗口标题
+ ///
+ public string WindowTitle => Tool != null ? $"刀具详情 - T{Tool.ToolNumber:D2}" : "刀具详情";
+
+ ///
+ /// 孔位信息标题
+ ///
+ public string HoleLocationsHeader => Tool != null ? $"孔位信息 (共{Tool.HoleLocations?.Count ?? 0}个)" : "孔位信息";
+
+ ///
+ /// 格式化后的孔位信息
+ ///
+ public string FormattedHoleLocations
+ {
+ get
+ {
+ if (Tool?.HoleLocations == null || Tool.HoleLocations.Count == 0)
+ {
+ return "无孔位数据";
+ }
+
+ return string.Join(Environment.NewLine, Tool.HoleLocations);
+ }
+ }
+
+ ///
+ /// 是否为机台码刀具
+ ///
+ public bool IsMachineCodeTool => Tool?.ToolType == ToolType.MachineCode;
+
+ ///
+ /// 构造函数
+ ///
+ public ToolDetailViewModel()
+ {
+ }
+
+ ///
+ /// 使用指定的刀具初始化视图模型
+ ///
+ /// 刀具对象
+ public ToolDetailViewModel(ToolItem tool) : this()
+ {
+ Tool = tool;
+ }
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null)
+ {
+ if (EqualityComparer.Default.Equals(field, value))
+ return false;
+
+ field = value;
+ OnPropertyChanged(propertyName);
+ return true;
+ }
+
+ protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+}
\ No newline at end of file
diff --git a/ToolDetailWindow.xaml b/ToolDetailWindow.xaml
new file mode 100644
index 0000000..ee74055
--- /dev/null
+++ b/ToolDetailWindow.xaml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ToolDetailWindow.xaml.cs b/ToolDetailWindow.xaml.cs
new file mode 100644
index 0000000..6267c00
--- /dev/null
+++ b/ToolDetailWindow.xaml.cs
@@ -0,0 +1,38 @@
+using System.Windows;
+
+namespace DrillTools
+{
+ ///
+ /// ToolDetailWindow.xaml 的交互逻辑
+ ///
+ public partial class ToolDetailWindow : Window
+ {
+ ///
+ /// 构造函数
+ ///
+ public ToolDetailWindow()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// 使用指定的刀具初始化窗口
+ ///
+ /// 刀具对象
+ public ToolDetailWindow(ToolItem tool) : this()
+ {
+ if (DataContext is ToolDetailViewModel viewModel)
+ {
+ viewModel.Tool = tool;
+ }
+ }
+
+ ///
+ /// 关闭按钮点击事件
+ ///
+ private void CloseButton_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ToolItem.cs b/ToolItem.cs
new file mode 100644
index 0000000..8982f50
--- /dev/null
+++ b/ToolItem.cs
@@ -0,0 +1,309 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace DrillTools
+{
+ ///
+ /// 刀具类型枚举
+ ///
+ public enum ToolType
+ {
+ Regular, // 圆孔刀具
+ Slot, // 槽孔刀具
+ MachineCode // 机台码刀具
+ }
+
+ ///
+ /// 刀具尾号类型枚举
+ ///
+ public enum ToolSuffixType
+ {
+ Drill, // 0 - 钻针
+ Slot, // 1 - 槽刀
+ EASlot, // 2 - EA型槽刀
+ DustSlot, // 3 - 粉尘刀(槽刀)
+ DeburrSlot, // 4 - 去毛刺刀(槽刀)
+ NonStandard, // 5 - 非标刀
+ EASlot2, // 6 - EA型槽刀
+ Special // 7 - 特殊刀具
+ }
+
+ ///
+ /// 刀具大类枚举
+ ///
+ public enum ToolCategory
+ {
+ Drill, // 钻针
+ Slot, // 槽刀(包含槽刀、粉尘刀、去毛刺刀)
+ EA, // EA刀(EA型槽刀)
+ NonStandard,// 非标刀
+ Special // 特殊刀具
+ }
+
+ ///
+ /// 刀具信息数据模型
+ ///
+ public class ToolItem : INotifyPropertyChanged
+ {
+ private int _toolNumber;
+ private double _diameter;
+
+ // private int _regularHoles; // 孔数功能已移除
+ // private int _slotHoles; // 孔数功能已移除
+ // private int _totalHoles; // 孔数功能已移除
+ private string _parameters = string.Empty;
+
+ private ToolType _toolType;
+ private string _machineCodeType = string.Empty;
+ private string _machineCodeCommand = string.Empty;
+ private ToolSuffixType _toolSuffixType;
+ private ToolCategory _toolCategory;
+ private List _holeLocations = new();
+
+ ///
+ /// 刀具编号
+ ///
+ public int ToolNumber
+ {
+ get => _toolNumber;
+ set => SetProperty(ref _toolNumber, value);
+ }
+
+ ///
+ /// 孔径(mm)
+ ///
+ public double Diameter
+ {
+ get => _diameter;
+ set => SetProperty(ref _diameter, value);
+ }
+
+ // ///
+ // /// 普通孔数
+ // ///
+ // public int RegularHoles
+ // {
+ // get => _regularHoles;
+ // set => SetProperty(ref _regularHoles, value);
+ // }
+
+ // ///
+ // /// 槽孔数
+ // ///
+ // public int SlotHoles
+ // {
+ // get => _slotHoles;
+ // set => SetProperty(ref _slotHoles, value);
+ // }
+
+ // ///
+ // /// 总孔数
+ // ///
+ // public int TotalHoles
+ // {
+ // get => _totalHoles;
+ // set => SetProperty(ref _totalHoles, value);
+ // }
+
+ ///
+ /// 钻机参数
+ ///
+ public string Parameters
+ {
+ get => _parameters;
+ set => SetProperty(ref _parameters, value);
+ }
+
+ ///
+ /// 刀具类型
+ ///
+ public ToolType ToolType
+ {
+ get => _toolType;
+ set => SetProperty(ref _toolType, value);
+ }
+
+ ///
+ /// 机台码类型 (A或B)
+ ///
+ public string MachineCodeType
+ {
+ get => _machineCodeType;
+ set => SetProperty(ref _machineCodeType, value);
+ }
+
+ ///
+ /// 机台码命令 (M97或M98)
+ ///
+ public string MachineCodeCommand
+ {
+ get => _machineCodeCommand;
+ set => SetProperty(ref _machineCodeCommand, value);
+ }
+
+ ///
+ /// 刀具尾号类型
+ ///
+ public ToolSuffixType ToolSuffixType
+ {
+ get => _toolSuffixType;
+ set => SetProperty(ref _toolSuffixType, value);
+ }
+
+ ///
+ /// 刀具大类
+ ///
+ public ToolCategory ToolCategory
+ {
+ get => _toolCategory;
+ set => SetProperty(ref _toolCategory, value);
+ }
+
+ ///
+ /// 孔位数据列表
+ ///
+ public List HoleLocations
+ {
+ get => _holeLocations;
+ set => SetProperty(ref _holeLocations, value);
+ }
+
+ ///
+ /// 刀具类型显示文本
+ ///
+ public string ToolTypeDisplay => ToolType switch
+ {
+ ToolType.Regular => "圆孔",
+ ToolType.Slot => "槽孔",
+ ToolType.MachineCode => "机台码",
+ _ => "未知"
+ };
+
+ ///
+ /// 刀具尾号类型显示文本
+ ///
+ public string ToolSuffixTypeDisplay => GetToolSuffixTypeDisplay(ToolSuffixType);
+
+ ///
+ /// 刀具大类显示文本
+ ///
+ public string ToolCategoryDisplay => GetToolCategoryDisplay(ToolCategory);
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null)
+ {
+ if (EqualityComparer.Default.Equals(field, value))
+ return false;
+
+ field = value;
+ OnPropertyChanged(propertyName);
+ return true;
+ }
+
+ protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ ///
+ /// 根据孔径尾号判断刀具尾号类型
+ ///
+ /// 孔径
+ /// 刀具尾号类型
+ public static ToolSuffixType GetToolSuffixType(double diameter)
+ {
+ // 特殊孔径优先判断
+ if (Math.Abs(diameter - 1.049) < 0.001 ||
+ Math.Abs(diameter - 3.175) < 0.001 ||
+ Math.Abs(diameter - 0.499) < 0.001)
+ {
+ return ToolSuffixType.Drill; // 固定为圆孔
+ }
+
+ // 获取孔径的小数部分最后一位
+ string diameterStr = diameter.ToString("F3");
+ if (diameterStr.Length >= 4 && diameterStr.Contains('.'))
+ {
+ char lastChar = diameterStr[diameterStr.Length - 1];
+ int suffix = int.Parse(lastChar.ToString());
+
+ return suffix switch
+ {
+ 0 => ToolSuffixType.Drill,
+ 1 => ToolSuffixType.Slot,
+ 2 => ToolSuffixType.EASlot,
+ 3 => ToolSuffixType.DustSlot,
+ 4 => ToolSuffixType.DeburrSlot,
+ 5 => ToolSuffixType.NonStandard,
+ 6 => ToolSuffixType.EASlot2,
+ 7 => ToolSuffixType.Special,
+ 8 => ToolSuffixType.Drill,
+ 9 => ToolSuffixType.Drill,
+ _ => ToolSuffixType.NonStandard
+ };
+ }
+
+ return ToolSuffixType.NonStandard; // 默认为非标刀
+ }
+
+ ///
+ /// 根据刀具尾号类型获取刀具大类
+ ///
+ /// 刀具尾号类型
+ /// 刀具大类
+ public static ToolCategory GetToolCategory(ToolSuffixType suffixType)
+ {
+ return suffixType switch
+ {
+ ToolSuffixType.Drill => ToolCategory.Drill,
+ ToolSuffixType.Slot or ToolSuffixType.DustSlot or ToolSuffixType.DeburrSlot => ToolCategory.Slot,
+ ToolSuffixType.EASlot or ToolSuffixType.EASlot2 => ToolCategory.EA,
+ ToolSuffixType.NonStandard => ToolCategory.NonStandard,
+ ToolSuffixType.Special => ToolCategory.Special,
+ _ => ToolCategory.NonStandard
+ };
+ }
+
+ ///
+ /// 获取刀具尾号类型的显示文本
+ ///
+ /// 刀具尾号类型
+ /// 显示文本
+ public static string GetToolSuffixTypeDisplay(ToolSuffixType suffixType)
+ {
+ return suffixType switch
+ {
+ ToolSuffixType.Drill => "钻针",
+ ToolSuffixType.Slot => "槽刀",
+ ToolSuffixType.EASlot => "EA型槽刀",
+ ToolSuffixType.DustSlot => "粉尘刀",
+ ToolSuffixType.DeburrSlot => "去毛刺刀",
+ ToolSuffixType.NonStandard => "非标刀",
+ ToolSuffixType.EASlot2 => "EA型槽刀",
+ ToolSuffixType.Special => "特殊刀具",
+ _ => "未知"
+ };
+ }
+
+ ///
+ /// 获取刀具大类的显示文本
+ ///
+ /// 刀具大类
+ /// 显示文本
+ public static string GetToolCategoryDisplay(ToolCategory category)
+ {
+ return category switch
+ {
+ ToolCategory.Drill => "钻针",
+ ToolCategory.Slot => "槽刀",
+ ToolCategory.EA => "EA刀",
+ ToolCategory.NonStandard => "非标刀",
+ ToolCategory.Special => "特殊刀",
+ _ => "未知"
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/demo_drl_files/p20030722a1-cs.dpin b/demo_drl_files/p20030722a1-cs.dpin
new file mode 100644
index 0000000..e09f9a0
--- /dev/null
+++ b/demo_drl_files/p20030722a1-cs.dpin
@@ -0,0 +1,12 @@
+M48
+T01C3.050
+T02C1.900
+%
+T01
+X-154500Y549000
+X154500Y562000
+X154500Y038000
+X-154500Y038000
+T02
+X045112Y593500
+M30
diff --git a/demo_drl_files/p20033811c0-a2-cs.drl b/demo_drl_files/p20033811c0-a2-cs.drl
new file mode 100644
index 0000000..4880d29
--- /dev/null
+++ b/demo_drl_files/p20033811c0-a2-cs.drl
@@ -0,0 +1,6580 @@
+M48
+;600V-Ĥ-EA-250610
+T01C1.049H05000Z+0.000S055.00F110.0U0700.0
+T02C3.175H00200Z-0.305S020.00F035.0U0700.0
+T03C0.650H01200Z+0.200S065.00F098.0U1000.0
+T04C0.800H01200Z+0.000S060.00F087.0U1000.0
+T05C1.050H01200Z+0.000S055.00F087.0U1000.0
+T06C1.150H01200Z+0.000S050.00F087.0U1000.0
+T07C1.200H01200Z+0.000S050.00F087.0U1000.0
+T08C1.250H01200Z+0.000S045.00F059.0U1000.0
+T09C1.350H01200Z+0.000S045.00F059.0U1000.0
+T10C1.450H01200Z+0.000S045.00F059.0U1000.0
+T11C1.550H01200Z+0.000S030.00F047.0U1000.0
+T12C1.650H01200Z-0.201S028.00F047.0U1000.0
+T13C1.950H01200Z-0.201S025.00F035.0U1000.0
+T14C2.050H00800Z-0.254S025.00F035.0U0600.0
+T15C2.250H00800Z-0.254S022.00F031.0U0600.0
+T16C2.350H00800Z-0.254S022.00F031.0U0600.0
+T17C3.350H00500Z-0.305S020.00F028.0U0600.0
+T18C4.550H00500Z-0.305S020.00F024.0U0600.0
+T19C0.499H05000Z+0.254S110.00F090.0U0700.0
+%
+T01
+X250814Y607644
+X252186Y607644
+X251500Y608837
+X252186Y622594
+X251500Y623787
+X250814Y622594
+X038614Y622500
+X037420Y621814
+X037420Y623186
+X015686Y621094
+X015000Y622287
+X014314Y621094
+X-250814Y622594
+X-251500Y623787
+X-252186Y622594
+X-251500Y583787
+X-250814Y582594
+X-252186Y582594
+X-252500Y443287
+X-251814Y442094
+X-253186Y442094
+X-252500Y188287
+X-251814Y187094
+X-253186Y187094
+X-252186Y016544
+X-250814Y016544
+X-251500Y017737
+X-252186Y001594
+X-251500Y002787
+X-250814Y001594
+X014314Y003094
+X015000Y004287
+X015686Y003094
+X250814Y001594
+X252186Y001594
+X251500Y002787
+X252186Y016544
+X250814Y016544
+X251500Y017737
+X032714Y622500
+T02
+X251500Y608050
+X251500Y623000
+X015000Y621500
+X-251500Y623000
+X-251500Y583000
+X-252500Y442500
+X-252500Y187500
+X-251500Y016950
+X-251500Y002000
+X015000Y003500
+X251500Y002000
+X251500Y016950
+X037826Y622500
+T03
+X-156200Y195500
+X-157600Y195500
+X-170200Y195500
+X-171600Y195500
+X-184200Y195500
+X-185400Y195500
+X-198200Y195500
+X-199400Y195500
+X-241300Y150750
+X-240270Y150750
+X-227000Y143500
+X-226000Y143500
+X-220870Y143500
+X-219850Y143500
+X-205900Y143500
+X-204900Y143500
+X-192600Y143500
+X-191600Y143500
+X-179600Y143500
+X-178600Y143500
+X-166400Y143500
+X-165400Y143500
+X-153000Y143500
+X-152000Y143500
+X-134950Y150400
+X-127250Y150400
+X-119650Y150200
+X-111750Y149800
+X-109400Y147500
+X-108000Y147500
+X-105500Y148150
+X-093000Y155500
+X-090000Y155500
+X-087000Y155500
+X-084000Y155500
+X-081000Y155500
+X-078000Y155500
+X-078000Y151500
+X-081000Y151500
+X-081000Y147500
+X-078000Y147500
+X-075000Y147500
+X-072000Y147500
+X-072000Y143500
+X-075000Y143500
+X-078000Y143500
+X-081000Y143500
+X-084000Y143500
+X-087000Y143500
+X-087000Y147500
+X-084000Y147500
+X-084000Y151500
+X-087000Y151500
+X-090000Y151500
+X-093000Y151500
+X-090000Y147500
+X-093000Y147500
+X-093000Y143500
+X-090000Y143500
+X-090000Y139500
+X-087000Y139500
+X-084000Y139500
+X-081000Y139500
+X-078000Y139500
+X-075000Y139500
+X-072000Y139500
+X-067000Y143500
+X-063500Y143500
+X-060000Y143500
+X-056500Y143500
+X-056500Y147500
+X-060000Y147500
+X-063500Y147500
+X-067000Y147500
+X-072000Y151500
+X-075000Y151500
+X-072000Y155500
+X-075000Y155500
+X-075000Y159500
+X-078000Y159500
+X-081000Y159500
+X-084000Y159500
+X-087000Y159500
+X-090000Y159500
+X-093000Y159500
+X-093000Y163500
+X-090000Y163500
+X-090000Y167500
+X-087000Y167500
+X-087000Y163500
+X-084000Y163500
+X-081000Y163500
+X-078000Y163500
+X-075000Y163500
+X-072000Y163500
+X-072000Y159500
+X-069000Y159500
+X-062400Y161500
+X-058850Y164000
+X-058750Y161530
+X-055850Y164500
+X-054400Y166650
+X-052000Y167950
+X-052100Y170000
+X-054650Y170500
+X-058300Y168950
+X-056150Y171850
+X-056150Y172850
+X-058000Y173500
+X-058000Y175500
+X-061000Y175500
+X-061000Y173500
+X-064000Y175500
+X-064000Y173500
+X-068000Y173500
+X-068000Y175500
+X-072000Y175500
+X-075000Y175500
+X-078000Y175500
+X-081000Y175500
+X-081000Y171500
+X-078000Y171500
+X-075000Y171500
+X-072000Y171500
+X-072000Y167500
+X-075000Y167500
+X-078000Y167500
+X-081000Y167500
+X-084000Y171500
+X-084000Y175500
+X-087000Y175500
+X-087000Y171500
+X-090000Y171500
+X-093000Y167500
+X-093000Y171500
+X-093000Y175500
+X-090000Y175500
+X-093000Y179500
+X-090000Y179500
+X-087000Y179500
+X-084000Y179500
+X-081000Y179500
+X-078000Y183500
+X-081000Y183500
+X-079000Y186500
+X-082000Y186500
+X-084000Y183500
+X-087000Y186500
+X-087000Y183500
+X-090000Y183500
+X-093000Y183500
+X-090000Y186500
+X-093000Y186500
+X-093000Y189500
+X-098100Y196800
+X-096800Y196800
+X-090000Y189500
+X-087600Y191900
+X-087000Y189500
+X-084600Y191900
+X-082000Y189500
+X-081600Y191900
+X-079000Y189500
+X-078500Y191900
+X-076000Y189500
+X-075500Y191900
+X-068800Y196800
+X-067500Y196800
+X-072500Y191900
+X-070000Y189500
+X-073000Y189500
+X-076000Y186500
+X-073000Y186500
+X-075000Y183500
+X-078000Y179500
+X-075000Y179500
+X-072000Y179500
+X-072000Y183500
+X-070000Y186500
+X-067000Y189500
+X-067000Y186500
+X-064000Y189500
+X-064000Y186500
+X-061000Y186500
+X-061000Y183500
+X-064000Y183500
+X-068000Y183500
+X-068000Y179500
+X-064000Y179500
+X-061000Y179500
+X-058000Y179500
+X-058000Y183500
+X-054000Y190500
+X-054000Y192500
+X-054000Y194500
+X-056000Y192500
+X-058000Y189500
+X-061000Y189500
+X-058000Y186500
+X-054000Y182500
+X-054000Y179500
+X-054000Y176500
+X-054000Y173500
+X-051000Y173500
+X-051000Y176500
+X-051000Y179500
+X-051000Y182500
+X-051000Y185500
+X-048000Y185500
+X-048000Y182500
+X-048000Y179500
+X-048000Y176500
+X-048000Y173500
+X-049500Y170050
+X-049500Y167950
+X-050550Y166400
+X-049350Y166400
+X-048100Y166400
+X-047000Y167950
+X-045000Y168000
+X-047000Y170000
+X-045000Y170000
+X-042850Y169950
+X-042850Y170950
+X-042500Y173500
+X-045000Y173500
+X-045000Y176500
+X-042500Y176500
+X-042500Y179500
+X-045000Y179500
+X-045000Y182500
+X-042000Y185500
+X-045000Y185500
+X-042500Y182500
+X-037000Y178800
+X-037000Y180800
+X-037000Y182800
+X-037000Y184800
+X-033200Y184800
+X-033200Y182800
+X-033200Y180800
+X-033200Y178800
+X-034200Y176800
+X-033200Y176800
+X-034000Y175500
+X-036000Y173500
+X-038000Y173500
+X-038000Y175500
+X-036000Y175500
+X-034000Y173500
+X-032000Y171000
+X-032000Y169000
+X-034000Y171000
+X-036000Y171000
+X-038000Y171000
+X-037000Y169000
+X-034500Y169000
+X-032000Y166500
+X-032000Y163500
+X-037400Y163400
+X-041200Y168000
+X-043150Y166850
+X-042500Y165700
+X-042000Y164450
+X-042000Y163150
+X-042800Y160250
+X-043900Y160250
+X-043900Y159250
+X-045350Y158500
+X-045350Y157450
+X-046400Y158500
+X-048800Y159800
+X-049800Y159800
+X-052150Y158250
+X-055100Y160400
+X-052150Y157250
+X-051050Y157250
+X-040500Y147500
+X-044500Y147500
+X-048500Y147500
+X-052500Y147500
+X-052500Y143500
+X-048500Y143500
+X-044500Y143500
+X-040500Y143500
+X-036000Y147500
+X-036000Y143500
+X-031500Y147500
+X-031500Y143500
+X-028300Y139900
+X-029400Y139900
+X-030500Y139900
+X-031600Y139900
+X-031600Y138800
+X-030500Y138800
+X-029400Y138800
+X-027200Y139900
+X-027200Y138800
+X-028300Y138800
+X-004050Y083900
+X-023000Y060500
+X-023000Y057500
+X-023000Y064500
+X-023000Y067500
+X-024000Y070500
+X-026000Y070500
+X-026000Y072500
+X-030000Y072500
+X-030000Y070500
+X-033000Y068500
+X-033000Y070500
+X-033000Y072500
+X-029400Y083900
+X-030800Y083900
+X-035700Y083900
+X-042100Y083900
+X-047100Y083900
+X-036000Y072500
+X-036000Y070500
+X-036000Y068500
+X-039000Y068500
+X-039000Y070500
+X-039000Y072500
+X-042000Y072500
+X-042000Y070500
+X-042000Y068500
+X-045000Y068500
+X-045000Y070500
+X-045000Y072500
+X-048000Y072500
+X-048000Y070500
+X-048000Y068500
+X-051000Y068500
+X-051000Y070500
+X-051000Y072500
+X-054000Y072500
+X-054000Y070500
+X-054000Y068500
+X-056000Y070500
+X-058000Y067500
+X-058000Y064500
+X-058000Y061500
+X-061000Y064500
+X-061000Y067500
+X-064000Y067500
+X-064000Y064500
+X-064000Y061500
+X-061000Y061500
+X-061000Y057500
+X-064000Y057500
+X-068000Y057500
+X-068000Y053500
+X-068000Y051500
+X-072000Y053500
+X-075000Y053500
+X-072000Y057500
+X-075000Y057500
+X-078000Y057500
+X-081000Y053500
+X-078000Y053500
+X-078000Y049500
+X-075000Y049500
+X-072000Y049500
+X-072000Y045500
+X-075000Y045500
+X-078000Y045500
+X-081000Y045500
+X-078000Y041500
+X-081000Y041500
+X-084000Y041500
+X-087000Y041500
+X-090000Y041500
+X-093000Y041500
+X-093000Y045500
+X-090000Y045500
+X-087000Y045500
+X-081000Y049500
+X-084000Y049500
+X-087000Y049500
+X-090000Y049500
+X-093000Y049500
+X-093000Y053500
+X-090000Y053500
+X-087000Y053500
+X-084000Y053500
+X-081000Y057500
+X-084000Y057500
+X-087000Y057500
+X-090000Y057500
+X-093000Y057500
+X-093000Y061500
+X-093000Y064500
+X-093000Y067500
+X-090000Y064500
+X-090000Y061500
+X-087000Y064500
+X-087000Y061500
+X-084000Y061500
+X-082000Y064500
+X-081000Y061500
+X-078000Y061500
+X-079000Y064500
+X-076000Y064500
+X-073000Y064500
+X-075000Y061500
+X-072000Y061500
+X-070000Y064500
+X-068000Y061500
+X-067000Y064500
+X-067000Y067500
+X-070000Y067500
+X-073000Y067500
+X-072500Y069900
+X-067500Y074800
+X-068800Y074800
+X-075500Y069900
+X-076000Y067500
+X-078500Y069900
+X-079000Y067500
+X-081600Y069900
+X-082000Y067500
+X-084600Y069900
+X-087000Y067500
+X-087600Y069900
+X-090000Y067500
+X-096800Y074800
+X-098100Y074800
+X-156200Y073500
+X-157600Y073500
+X-170200Y073500
+X-171600Y073500
+X-184200Y073500
+X-185400Y073500
+X-198200Y073500
+X-199400Y073500
+X-241300Y028750
+X-240270Y028750
+X-227000Y021500
+X-226000Y021500
+X-220870Y021500
+X-219850Y021500
+X-205900Y021500
+X-204900Y021500
+X-192600Y021500
+X-191600Y021500
+X-179600Y021500
+X-178600Y021500
+X-166400Y021500
+X-165400Y021500
+X-153000Y021500
+X-152000Y021500
+X-134950Y028400
+X-127250Y028400
+X-119650Y028200
+X-111750Y027800
+X-109400Y025500
+X-108000Y025500
+X-105500Y026150
+X-093000Y037500
+X-090000Y037500
+X-087000Y037500
+X-084000Y037500
+X-081000Y037500
+X-081000Y033500
+X-084000Y033500
+X-087000Y033500
+X-090000Y033500
+X-093000Y033500
+X-093000Y029500
+X-090000Y029500
+X-087000Y029500
+X-084000Y029500
+X-081000Y029500
+X-084000Y025500
+X-081000Y025500
+X-081000Y021500
+X-084000Y021500
+X-087000Y021500
+X-087000Y025500
+X-090000Y025500
+X-093000Y025500
+X-090000Y021500
+X-093000Y021500
+X-090000Y017500
+X-087000Y017500
+X-084000Y017500
+X-081000Y017500
+X-078000Y017500
+X-078000Y021500
+X-075000Y021500
+X-075000Y017500
+X-072000Y017500
+X-072000Y021500
+X-072000Y025500
+X-075000Y025500
+X-078000Y025500
+X-078000Y029500
+X-075000Y029500
+X-072000Y029500
+X-072000Y033500
+X-075000Y033500
+X-078000Y033500
+X-078000Y037500
+X-075000Y037500
+X-075000Y041500
+X-072000Y041500
+X-072000Y037500
+X-069000Y037500
+X-062400Y039500
+X-058850Y042000
+X-058750Y039530
+X-055100Y038400
+X-055850Y042500
+X-054400Y044650
+X-052000Y045950
+X-050550Y044400
+X-049350Y044400
+X-049500Y045950
+X-048100Y044400
+X-047000Y045950
+X-047000Y048000
+X-045000Y048000
+X-045000Y046000
+X-043150Y044850
+X-042500Y043700
+X-042000Y042450
+X-042000Y041150
+X-042800Y038250
+X-043900Y038250
+X-043900Y037250
+X-045350Y036500
+X-045350Y035450
+X-046400Y036500
+X-048800Y037800
+X-049800Y037800
+X-052150Y036250
+X-052150Y035250
+X-051050Y035250
+X-044500Y025500
+X-048500Y025500
+X-052500Y025500
+X-056500Y025500
+X-060000Y025500
+X-063500Y025500
+X-067000Y025500
+X-067000Y021500
+X-063500Y021500
+X-060000Y021500
+X-056500Y021500
+X-052500Y021500
+X-048500Y021500
+X-044500Y021500
+X-040500Y025500
+X-040500Y021500
+X-036000Y021500
+X-036000Y025500
+X-031500Y025500
+X-031500Y021500
+X-031600Y017900
+X-031600Y016800
+X-030500Y016800
+X-030500Y017900
+X-029400Y017900
+X-028300Y017900
+X-029400Y016800
+X-028300Y016800
+X-027200Y016800
+X-027200Y017900
+X-024000Y021500
+X-027500Y021500
+X-027500Y025500
+X-023500Y025500
+X-029000Y041500
+X-032000Y041500
+X-037400Y041400
+X-041200Y046000
+X-042850Y047950
+X-042850Y048950
+X-042500Y051500
+X-045000Y051500
+X-048000Y054500
+X-048000Y051500
+X-049500Y048050
+X-052100Y048000
+X-054650Y048500
+X-058300Y046950
+X-056150Y049850
+X-056150Y050850
+X-058000Y051500
+X-058000Y053500
+X-061000Y051500
+X-064000Y051500
+X-064000Y053500
+X-061000Y053500
+X-058000Y057500
+X-054000Y060500
+X-054000Y057500
+X-054000Y054500
+X-054000Y051500
+X-051000Y051500
+X-051000Y054500
+X-051000Y057500
+X-051000Y060500
+X-051000Y063500
+X-048000Y063500
+X-048000Y060500
+X-048000Y057500
+X-042000Y063500
+X-045000Y063500
+X-042500Y060500
+X-045000Y060500
+X-045000Y057500
+X-042500Y057500
+X-045000Y054500
+X-042500Y054500
+X-038000Y053500
+X-036000Y053500
+X-037000Y056800
+X-037000Y058800
+X-037000Y060800
+X-037000Y062800
+X-033200Y062800
+X-033200Y060800
+X-033200Y058800
+X-033200Y056800
+X-034200Y054800
+X-033200Y054800
+X-034000Y053500
+X-034000Y051500
+X-036000Y051500
+X-038000Y051500
+X-038000Y049000
+X-037000Y047000
+X-036000Y049000
+X-034000Y049000
+X-034500Y047000
+X-032000Y044500
+X-032000Y047000
+X-032000Y049000
+X-029000Y047000
+X-029000Y044500
+X-026000Y041500
+X-026000Y044500
+X-026000Y047000
+X-023000Y049500
+X-023000Y047000
+X-023000Y044500
+X-023000Y041500
+X006700Y028750
+X007730Y028750
+X021000Y021500
+X022000Y021500
+X027130Y021500
+X028150Y021500
+X042100Y021500
+X043100Y021500
+X055400Y021500
+X056400Y021500
+X068400Y021500
+X069400Y021500
+X081600Y021500
+X082600Y021500
+X095000Y021500
+X096000Y021500
+X113050Y028400
+X120750Y028400
+X128350Y028200
+X136250Y027800
+X138600Y025500
+X140000Y025500
+X142500Y026150
+X155000Y037500
+X158000Y037500
+X161000Y037500
+X164000Y037500
+X167000Y037500
+X170000Y037500
+X170000Y033500
+X167000Y033500
+X164000Y033500
+X161000Y033500
+X158000Y033500
+X155000Y033500
+X155000Y029500
+X155000Y025500
+X155000Y021500
+X158000Y021500
+X158000Y017500
+X161000Y017500
+X164000Y017500
+X167000Y017500
+X161000Y021500
+X161000Y025500
+X158000Y025500
+X158000Y029500
+X161000Y029500
+X164000Y029500
+X167000Y029500
+X170000Y029500
+X170000Y025500
+X167000Y025500
+X164000Y025500
+X164000Y021500
+X167000Y021500
+X170000Y021500
+X173000Y021500
+X170000Y017500
+X173000Y017500
+X176000Y017500
+X176000Y021500
+X173000Y025500
+X176000Y025500
+X173000Y029500
+X176000Y029500
+X176000Y033500
+X173000Y033500
+X173000Y037500
+X176000Y037500
+X179000Y037500
+X176000Y041500
+X173000Y041500
+X170000Y041500
+X170000Y045500
+X173000Y045500
+X176000Y045500
+X176000Y049500
+X173000Y049500
+X170000Y049500
+X167000Y049500
+X164000Y049500
+X167000Y045500
+X167000Y041500
+X164000Y041500
+X161000Y041500
+X158000Y041500
+X155000Y041500
+X155000Y045500
+X155000Y049500
+X158000Y049500
+X161000Y045500
+X158000Y045500
+X161000Y049500
+X161000Y053500
+X158000Y053500
+X155000Y053500
+X155000Y057500
+X158000Y057500
+X161000Y057500
+X164000Y053500
+X167000Y053500
+X170000Y053500
+X173000Y053500
+X176000Y053500
+X176000Y057500
+X176000Y061500
+X178000Y064500
+X175000Y064500
+X172000Y064500
+X169000Y067500
+X166000Y064500
+X169000Y064500
+X167000Y061500
+X170000Y061500
+X173000Y061500
+X173000Y057500
+X170000Y057500
+X167000Y057500
+X164000Y057500
+X164000Y061500
+X161000Y061500
+X161000Y064500
+X158000Y064500
+X158000Y061500
+X155000Y061500
+X155000Y064500
+X155000Y067500
+X149900Y074800
+X151200Y074800
+X158000Y067500
+X160400Y069900
+X161000Y067500
+X163400Y069900
+X166000Y067500
+X166400Y069900
+X169500Y069900
+X172000Y067500
+X172500Y069900
+X175000Y067500
+X175500Y069900
+X179200Y074800
+X180500Y074800
+X181000Y067500
+X178000Y067500
+X181000Y064500
+X184000Y061500
+X184000Y064500
+X180000Y061500
+X180000Y057500
+X180000Y053500
+X180000Y051500
+X184000Y051500
+X184000Y053500
+X187000Y053500
+X187000Y051500
+X189700Y046950
+X189150Y042000
+X185600Y039500
+X189250Y039530
+X192900Y038400
+X195850Y036250
+X195850Y035250
+X196950Y035250
+X191500Y025500
+X188000Y025500
+X184500Y025500
+X181000Y025500
+X181000Y021500
+X184500Y021500
+X188000Y021500
+X191500Y021500
+X195500Y021500
+X195500Y025500
+X199500Y025500
+X203500Y025500
+X199500Y021500
+X203500Y021500
+X207500Y025500
+X207500Y021500
+X212000Y021500
+X212000Y025500
+X216500Y025500
+X220500Y025500
+X216500Y021500
+X219700Y017900
+X218600Y017900
+X217500Y017900
+X216400Y017900
+X216400Y016800
+X217500Y016800
+X218600Y016800
+X219700Y016800
+X220800Y016800
+X220800Y017900
+X220500Y021500
+X224000Y021500
+X224500Y025500
+X252000Y063500
+X252000Y066000
+X252000Y068500
+X252000Y071000
+X252000Y073500
+X252000Y076000
+X243950Y083900
+X218600Y083900
+X222000Y072500
+X224000Y070500
+X225000Y067500
+X225000Y064500
+X225000Y060500
+X225000Y057500
+X225000Y049500
+X225000Y047000
+X225000Y044500
+X225000Y041500
+X222000Y041500
+X222000Y044500
+X222000Y047000
+X219000Y047000
+X219000Y044500
+X216000Y041500
+X219000Y041500
+X216000Y044500
+X216000Y047000
+X216000Y049000
+X214000Y051500
+X214000Y049000
+X212000Y049000
+X211000Y047000
+X213500Y047000
+X210600Y041400
+X206000Y042450
+X206000Y041150
+X205200Y038250
+X204100Y038250
+X204100Y037250
+X202650Y036500
+X202650Y035450
+X201600Y036500
+X199200Y037800
+X198200Y037800
+X192150Y042500
+X193600Y044650
+X196000Y045950
+X197450Y044400
+X198650Y044400
+X199900Y044400
+X201000Y045950
+X198500Y048050
+X198500Y045950
+X195900Y048000
+X193350Y048500
+X191850Y049850
+X194000Y051500
+X191850Y050850
+X190000Y051500
+X190000Y053500
+X194000Y054500
+X194000Y057500
+X197000Y060500
+X197000Y057500
+X197000Y054500
+X197000Y051500
+X200000Y051500
+X200000Y054500
+X200000Y057500
+X200000Y060500
+X200000Y063500
+X203000Y063500
+X206000Y063500
+X205500Y060500
+X203000Y060500
+X205500Y057500
+X203000Y057500
+X203000Y054500
+X205500Y054500
+X205500Y051500
+X203000Y051500
+X205150Y048950
+X205150Y047950
+X203000Y048000
+X201000Y048000
+X203000Y046000
+X204850Y044850
+X205500Y043700
+X206800Y046000
+X210000Y049000
+X210000Y051500
+X210000Y053500
+X212000Y051500
+X212000Y053500
+X211000Y056800
+X211000Y058800
+X214800Y054800
+X214000Y053500
+X213800Y054800
+X214800Y056800
+X214800Y058800
+X214800Y060800
+X211000Y062800
+X211000Y060800
+X214800Y062800
+X222000Y070500
+X218000Y072500
+X218000Y070500
+X215000Y068500
+X215000Y070500
+X215000Y072500
+X212000Y072500
+X212000Y070500
+X212000Y068500
+X209000Y068500
+X209000Y070500
+X209000Y072500
+X206000Y072500
+X206000Y070500
+X206000Y068500
+X203000Y068500
+X203000Y070500
+X203000Y072500
+X200000Y072500
+X200000Y070500
+X200000Y068500
+X197000Y072500
+X197000Y070500
+X197000Y068500
+X197000Y063500
+X194000Y060500
+X190000Y057500
+X187000Y057500
+X184000Y057500
+X187000Y061500
+X190000Y061500
+X187000Y064500
+X184000Y067500
+X187000Y067500
+X190000Y064500
+X190000Y067500
+X192000Y070500
+X194000Y068500
+X194000Y070500
+X194000Y072500
+X200900Y083900
+X205900Y083900
+X212300Y083900
+X217200Y083900
+X199500Y143500
+X203500Y143500
+X207500Y143500
+X203500Y147500
+X207500Y147500
+X212000Y147500
+X212000Y143500
+X216500Y143500
+X216400Y139900
+X217500Y139900
+X216400Y138800
+X217500Y138800
+X218600Y138800
+X219700Y138800
+X220800Y139900
+X220800Y138800
+X219700Y139900
+X218600Y139900
+X220500Y143500
+X224000Y143500
+X224500Y147500
+X220500Y147500
+X216500Y147500
+X205200Y160250
+X204100Y160250
+X204100Y159250
+X202650Y158500
+X202650Y157450
+X201600Y158500
+X199200Y159800
+X198200Y159800
+X196950Y157250
+X195850Y157250
+X195850Y158250
+X192900Y160400
+X189250Y161530
+X185600Y161500
+X189150Y164000
+X192150Y164500
+X193600Y166650
+X196000Y167950
+X195900Y170000
+X198500Y170050
+X198500Y167950
+X197450Y166400
+X198650Y166400
+X199900Y166400
+X201000Y167950
+X203000Y168000
+X201000Y170000
+X203000Y170000
+X205150Y170950
+X205150Y169950
+X206800Y168000
+X204850Y166850
+X205500Y165700
+X206000Y164450
+X206000Y163150
+X210600Y163400
+X199500Y147500
+X195500Y147500
+X195500Y143500
+X191500Y143500
+X188000Y143500
+X191500Y147500
+X188000Y147500
+X184500Y147500
+X181000Y147500
+X184500Y143500
+X181000Y143500
+X176000Y139500
+X173000Y139500
+X170000Y139500
+X167000Y139500
+X164000Y139500
+X161000Y139500
+X158000Y139500
+X155000Y143500
+X158000Y143500
+X161000Y143500
+X164000Y143500
+X167000Y143500
+X170000Y143500
+X173000Y143500
+X176000Y143500
+X176000Y147500
+X173000Y147500
+X170000Y147500
+X167000Y147500
+X164000Y147500
+X161000Y147500
+X158000Y147500
+X155000Y147500
+X155000Y151500
+X158000Y151500
+X161000Y151500
+X164000Y151500
+X167000Y151500
+X170000Y151500
+X173000Y151500
+X176000Y151500
+X176000Y155500
+X173000Y155500
+X170000Y155500
+X167000Y155500
+X164000Y155500
+X161000Y155500
+X158000Y155500
+X155000Y155500
+X158000Y159500
+X161000Y159500
+X164000Y159500
+X167000Y159500
+X170000Y159500
+X173000Y159500
+X176000Y159500
+X179000Y159500
+X176000Y163500
+X173000Y163500
+X176000Y167500
+X173000Y167500
+X170000Y167500
+X167000Y171500
+X170000Y171500
+X173000Y171500
+X176000Y171500
+X173000Y175500
+X176000Y175500
+X173000Y179500
+X176000Y179500
+X176000Y183500
+X173000Y183500
+X170000Y183500
+X169000Y186500
+X172000Y186500
+X175000Y186500
+X178000Y186500
+X178000Y189500
+X181000Y189500
+X181000Y186500
+X180000Y183500
+X180000Y179500
+X180000Y175500
+X180000Y173500
+X184000Y173500
+X184000Y175500
+X184000Y179500
+X187000Y179500
+X190000Y179500
+X190000Y175500
+X190000Y173500
+X187000Y175500
+X187000Y173500
+X189700Y168950
+X193350Y170500
+X191850Y171850
+X191850Y172850
+X194000Y173500
+X194000Y176500
+X197000Y176500
+X194000Y179500
+X194000Y182500
+X197000Y185500
+X197000Y182500
+X197000Y179500
+X200000Y179500
+X200000Y182500
+X203000Y185500
+X200000Y185500
+X197000Y190500
+X197000Y192500
+X197000Y194500
+X200000Y194500
+X200000Y192500
+X200000Y190500
+X203000Y194500
+X203000Y192500
+X203000Y190500
+X206000Y190500
+X206000Y192500
+X206000Y194500
+X209000Y194500
+X209000Y192500
+X209000Y190500
+X212000Y190500
+X212000Y192500
+X212000Y194500
+X215000Y194500
+X215000Y192500
+X218000Y194500
+X218000Y192500
+X215000Y190500
+X214800Y184800
+X214800Y182800
+X214800Y180800
+X214800Y178800
+X214800Y176800
+X214000Y175500
+X213800Y176800
+X211000Y178800
+X211000Y180800
+X211000Y182800
+X211000Y184800
+X206000Y185500
+X203000Y182500
+X205500Y182500
+X203000Y179500
+X205500Y179500
+X205500Y176500
+X203000Y176500
+X200000Y176500
+X197000Y173500
+X200000Y173500
+X203000Y173500
+X205500Y173500
+X210000Y175500
+X212000Y175500
+X214000Y173500
+X212000Y173500
+X210000Y173500
+X210000Y171000
+X211000Y169000
+X212000Y171000
+X213500Y169000
+X214000Y171000
+X216000Y171000
+X216000Y169000
+X216000Y166500
+X216000Y163500
+X219000Y163500
+X222000Y166500
+X222000Y169000
+X219000Y169000
+X219000Y166500
+X222000Y163500
+X225000Y163500
+X225000Y166500
+X225000Y169000
+X225000Y171500
+X225000Y179500
+X225000Y182500
+X225000Y186500
+X225000Y189500
+X222000Y192500
+X222000Y194500
+X224000Y192500
+X243950Y205900
+X218600Y205900
+X217200Y205900
+X212300Y205900
+X205900Y205900
+X200900Y205900
+X194000Y194500
+X192000Y192500
+X194000Y192500
+X194000Y190500
+X190000Y189500
+X190000Y186500
+X190000Y183500
+X187000Y186500
+X187000Y183500
+X184000Y183500
+X184000Y186500
+X184000Y189500
+X187000Y189500
+X180500Y196800
+X179200Y196800
+X175500Y191900
+X175000Y189500
+X172500Y191900
+X172000Y189500
+X169500Y191900
+X169000Y189500
+X166400Y191900
+X166000Y189500
+X163400Y191900
+X161000Y189500
+X160400Y191900
+X158000Y189500
+X151200Y196800
+X149900Y196800
+X155000Y189500
+X155000Y186500
+X155000Y183500
+X158000Y186500
+X158000Y183500
+X161000Y186500
+X161000Y183500
+X164000Y183500
+X166000Y186500
+X167000Y183500
+X167000Y179500
+X170000Y179500
+X170000Y175500
+X167000Y175500
+X164000Y175500
+X161000Y175500
+X164000Y179500
+X161000Y179500
+X158000Y179500
+X155000Y179500
+X155000Y175500
+X158000Y175500
+X158000Y171500
+X155000Y171500
+X155000Y167500
+X158000Y167500
+X161000Y167500
+X161000Y171500
+X164000Y171500
+X167000Y167500
+X170000Y163500
+X167000Y163500
+X164000Y163500
+X161000Y163500
+X158000Y163500
+X155000Y163500
+X155000Y159500
+X142500Y148150
+X140000Y147500
+X138600Y147500
+X136250Y149800
+X128350Y150200
+X120750Y150400
+X113050Y150400
+X096000Y143500
+X095000Y143500
+X082600Y143500
+X081600Y143500
+X069400Y143500
+X068400Y143500
+X056400Y143500
+X055400Y143500
+X043100Y143500
+X042100Y143500
+X091800Y073500
+X090400Y073500
+X077800Y073500
+X076400Y073500
+X063800Y073500
+X062600Y073500
+X049800Y073500
+X048600Y073500
+X028150Y143500
+X027130Y143500
+X022000Y143500
+X021000Y143500
+X007730Y150750
+X006700Y150750
+X-023500Y147500
+X-024000Y143500
+X-027500Y143500
+X-027500Y147500
+X-023000Y163500
+X-026000Y163500
+X-029000Y163500
+X-029000Y166500
+X-029000Y169000
+X-026000Y169000
+X-026000Y166500
+X-023000Y166500
+X-023000Y169000
+X-023000Y171500
+X-023000Y179500
+X-023000Y182500
+X-023000Y186500
+X-023000Y189500
+X-024000Y192500
+X-026000Y192500
+X-026000Y194500
+X-030000Y192500
+X-030000Y194500
+X-033000Y194500
+X-033000Y192500
+X-033000Y190500
+X-036000Y190500
+X-036000Y192500
+X-036000Y194500
+X-039000Y194500
+X-039000Y192500
+X-039000Y190500
+X-042000Y190500
+X-042000Y192500
+X-042000Y194500
+X-045000Y194500
+X-045000Y192500
+X-045000Y190500
+X-048000Y190500
+X-048000Y192500
+X-048000Y194500
+X-051000Y190500
+X-051000Y192500
+X-051000Y194500
+X-047100Y205900
+X-042100Y205900
+X-035700Y205900
+X-030800Y205900
+X-029400Y205900
+X-004050Y205900
+X048600Y195500
+X049800Y195500
+X062600Y195500
+X063800Y195500
+X076400Y195500
+X077800Y195500
+X090400Y195500
+X091800Y195500
+X021000Y265500
+X022000Y265500
+X027130Y265500
+X028150Y265500
+X042100Y265500
+X043100Y265500
+X055400Y265500
+X056400Y265500
+X068400Y265500
+X069400Y265500
+X091800Y317500
+X090400Y317500
+X077800Y317500
+X076400Y317500
+X063800Y317500
+X062600Y317500
+X081600Y265500
+X082600Y265500
+X095000Y265500
+X096000Y265500
+X113050Y272400
+X120750Y272400
+X128350Y272200
+X136250Y271800
+X138600Y269500
+X140000Y269500
+X142500Y270150
+X155000Y265500
+X158000Y261500
+X161000Y261500
+X164000Y261500
+X167000Y261500
+X170000Y261500
+X173000Y261500
+X176000Y261500
+X176000Y265500
+X173000Y265500
+X170000Y265500
+X167000Y265500
+X164000Y265500
+X161000Y265500
+X158000Y265500
+X155000Y269500
+X158000Y269500
+X161000Y269500
+X164000Y269500
+X167000Y269500
+X170000Y269500
+X173000Y269500
+X176000Y269500
+X173000Y273500
+X170000Y273500
+X167000Y273500
+X164000Y273500
+X161000Y273500
+X158000Y273500
+X155000Y273500
+X155000Y277500
+X158000Y277500
+X155000Y281500
+X158000Y281500
+X161000Y281500
+X161000Y277500
+X164000Y277500
+X167000Y277500
+X170000Y277500
+X173000Y277500
+X176000Y277500
+X176000Y273500
+X181000Y269500
+X181000Y265500
+X184500Y265500
+X188000Y265500
+X184500Y269500
+X188000Y269500
+X191500Y269500
+X191500Y265500
+X195500Y269500
+X199500Y269500
+X195500Y265500
+X199500Y265500
+X203500Y265500
+X203500Y269500
+X207500Y265500
+X207500Y269500
+X212000Y265500
+X216500Y265500
+X216400Y261900
+X217500Y260800
+X216400Y260800
+X217500Y261900
+X218600Y261900
+X218600Y260800
+X219700Y260800
+X219700Y261900
+X220800Y260800
+X220800Y261900
+X220500Y265500
+X224000Y265500
+X224500Y269500
+X220500Y269500
+X216500Y269500
+X212000Y269500
+X202650Y279450
+X202650Y280500
+X204100Y281250
+X205200Y282250
+X204100Y282250
+X201600Y280500
+X199200Y281800
+X198200Y281800
+X196950Y279250
+X195850Y279250
+X195850Y280250
+X192900Y282400
+X189250Y283530
+X185600Y283500
+X189150Y286000
+X192150Y286500
+X193600Y288650
+X189700Y290950
+X184000Y295500
+X180000Y295500
+X176000Y297500
+X173000Y297500
+X170000Y297500
+X167000Y297500
+X164000Y297500
+X164000Y293500
+X167000Y293500
+X170000Y293500
+X173000Y293500
+X176000Y293500
+X176000Y289500
+X173000Y289500
+X170000Y289500
+X167000Y289500
+X167000Y285500
+X170000Y285500
+X173000Y285500
+X176000Y285500
+X179000Y281500
+X176000Y281500
+X173000Y281500
+X170000Y281500
+X167000Y281500
+X164000Y281500
+X164000Y285500
+X161000Y285500
+X158000Y285500
+X155000Y285500
+X155000Y289500
+X158000Y289500
+X161000Y289500
+X161000Y293500
+X158000Y293500
+X155000Y293500
+X161000Y297500
+X158000Y297500
+X155000Y297500
+X155000Y301500
+X158000Y301500
+X161000Y301500
+X164000Y301500
+X167000Y301500
+X170000Y301500
+X173000Y301500
+X176000Y301500
+X180000Y301500
+X180000Y297500
+X184000Y301500
+X187000Y301500
+X190000Y301500
+X190000Y297500
+X187000Y297500
+X184000Y297500
+X187000Y295500
+X190000Y295500
+X191850Y294850
+X191850Y293850
+X193350Y292500
+X195900Y292000
+X196000Y289950
+X198500Y292050
+X198500Y289950
+X197450Y288400
+X198650Y288400
+X199900Y288400
+X201000Y289950
+X203000Y290000
+X201000Y292000
+X203000Y292000
+X205150Y292950
+X205150Y291950
+X206800Y290000
+X204850Y288850
+X205500Y287700
+X206000Y286450
+X206000Y285150
+X210600Y285400
+X216000Y285500
+X219000Y285500
+X222000Y285500
+X225000Y285500
+X222000Y288500
+X225000Y288500
+X225000Y291000
+X225000Y293500
+X222000Y291000
+X219000Y288500
+X219000Y291000
+X216000Y288500
+X216000Y291000
+X216000Y293000
+X214000Y295500
+X212000Y295500
+X210000Y295500
+X212000Y293000
+X214000Y293000
+X213500Y291000
+X211000Y291000
+X210000Y293000
+X205500Y295500
+X203000Y295500
+X200000Y295500
+X197000Y295500
+X194000Y295500
+X194000Y298500
+X194000Y301500
+X194000Y304500
+X190000Y305500
+X190000Y308500
+X187000Y308500
+X187000Y305500
+X184000Y305500
+X181000Y308500
+X180000Y305500
+X178000Y308500
+X176000Y305500
+X173000Y305500
+X175000Y308500
+X172000Y308500
+X170000Y305500
+X169000Y308500
+X166000Y308500
+X167000Y305500
+X164000Y305500
+X161000Y305500
+X161000Y308500
+X158000Y308500
+X158000Y305500
+X155000Y305500
+X155000Y308500
+X155000Y311500
+X149900Y318800
+X151200Y318800
+X158000Y311500
+X160400Y313900
+X161000Y311500
+X163400Y313900
+X166000Y311500
+X166400Y313900
+X169000Y311500
+X169500Y313900
+X172000Y311500
+X172500Y313900
+X179200Y318800
+X180500Y318800
+X175500Y313900
+X175000Y311500
+X178000Y311500
+X181000Y311500
+X184000Y308500
+X184000Y311500
+X187000Y311500
+X190000Y311500
+X192000Y314500
+X194000Y316500
+X194000Y314500
+X194000Y312500
+X197000Y312500
+X197000Y314500
+X197000Y316500
+X200900Y327900
+X205900Y327900
+X212300Y327900
+X217200Y327900
+X218600Y327900
+X215000Y316500
+X212000Y316500
+X212000Y314500
+X212000Y312500
+X209000Y312500
+X209000Y314500
+X209000Y316500
+X206000Y316500
+X206000Y314500
+X206000Y312500
+X203000Y312500
+X203000Y314500
+X203000Y316500
+X200000Y316500
+X200000Y314500
+X200000Y312500
+X203000Y307500
+X200000Y307500
+X197000Y307500
+X197000Y304500
+X197000Y301500
+X197000Y298500
+X200000Y298500
+X203000Y298500
+X205500Y298500
+X205500Y301500
+X203000Y301500
+X200000Y304500
+X200000Y301500
+X203000Y304500
+X205500Y304500
+X206000Y307500
+X211000Y306800
+X211000Y304800
+X211000Y302800
+X211000Y300800
+X210000Y297500
+X212000Y297500
+X214000Y297500
+X213800Y298800
+X214800Y298800
+X214800Y300800
+X214800Y302800
+X214800Y304800
+X214800Y306800
+X215000Y312500
+X215000Y314500
+X218000Y314500
+X218000Y316500
+X222000Y316500
+X224000Y314500
+X222000Y314500
+X225000Y311500
+X225000Y308500
+X225000Y301500
+X225000Y304500
+X243950Y327900
+X220800Y382800
+X219700Y382800
+X218600Y382800
+X217500Y382800
+X216400Y383900
+X216400Y382800
+X217500Y383900
+X218600Y383900
+X219700Y383900
+X220800Y383900
+X220500Y387500
+X224000Y387500
+X224500Y391500
+X220500Y391500
+X216500Y391500
+X216500Y387500
+X212000Y387500
+X212000Y391500
+X207500Y391500
+X207500Y387500
+X203500Y387500
+X199500Y387500
+X195500Y387500
+X191500Y387500
+X188000Y387500
+X184500Y387500
+X181000Y387500
+X181000Y391500
+X184500Y391500
+X188000Y391500
+X191500Y391500
+X195500Y391500
+X199500Y391500
+X203500Y391500
+X196950Y401250
+X195850Y401250
+X195850Y402250
+X198200Y403800
+X199200Y403800
+X201600Y402500
+X202650Y401450
+X202650Y402500
+X204100Y403250
+X204100Y404250
+X205200Y404250
+X206000Y407150
+X206000Y408450
+X205500Y409700
+X204850Y410850
+X203000Y412000
+X201000Y411950
+X203000Y414000
+X201000Y414000
+X198500Y414050
+X198500Y411950
+X199900Y410400
+X198650Y410400
+X197450Y410400
+X196000Y411950
+X195900Y414000
+X193350Y414500
+X197000Y417500
+X197000Y420500
+X197000Y423500
+X197000Y426500
+X197000Y429500
+X194000Y426500
+X194000Y423500
+X194000Y420500
+X194000Y417500
+X191850Y416850
+X191850Y415850
+X190000Y417500
+X190000Y419500
+X190000Y423500
+X187000Y423500
+X184000Y423500
+X180000Y423500
+X180000Y419500
+X180000Y417500
+X184000Y417500
+X184000Y419500
+X187000Y419500
+X187000Y417500
+X189700Y412950
+X193600Y410650
+X192150Y408500
+X192900Y404400
+X189250Y405530
+X189150Y408000
+X185600Y405500
+X179000Y403500
+X176000Y403500
+X176000Y399500
+X173000Y399500
+X170000Y399500
+X167000Y399500
+X164000Y399500
+X161000Y399500
+X167000Y403500
+X164000Y403500
+X161000Y403500
+X158000Y403500
+X155000Y403500
+X155000Y399500
+X158000Y399500
+X155000Y395500
+X158000Y395500
+X161000Y395500
+X164000Y395500
+X167000Y395500
+X170000Y395500
+X173000Y395500
+X176000Y395500
+X176000Y391500
+X173000Y391500
+X173000Y387500
+X176000Y387500
+X176000Y383500
+X173000Y383500
+X170000Y383500
+X167000Y383500
+X164000Y383500
+X161000Y383500
+X158000Y383500
+X155000Y387500
+X158000Y387500
+X161000Y387500
+X164000Y387500
+X167000Y387500
+X170000Y387500
+X170000Y391500
+X167000Y391500
+X164000Y391500
+X161000Y391500
+X158000Y391500
+X155000Y391500
+X142500Y392150
+X140000Y391500
+X138600Y391500
+X136250Y393800
+X155000Y411500
+X155000Y407500
+X158000Y407500
+X161000Y407500
+X164000Y407500
+X167000Y407500
+X170000Y407500
+X173000Y403500
+X170000Y403500
+X173000Y407500
+X176000Y407500
+X176000Y411500
+X173000Y411500
+X170000Y411500
+X167000Y411500
+X167000Y415500
+X170000Y415500
+X173000Y415500
+X176000Y415500
+X176000Y419500
+X173000Y419500
+X170000Y419500
+X167000Y419500
+X164000Y419500
+X164000Y415500
+X161000Y415500
+X158000Y415500
+X161000Y411500
+X158000Y411500
+X155000Y415500
+X155000Y419500
+X155000Y423500
+X158000Y427500
+X158000Y430500
+X161000Y427500
+X164000Y427500
+X161000Y430500
+X161000Y433500
+X163400Y435900
+X160400Y435900
+X158000Y433500
+X151200Y440800
+X149900Y440800
+X155000Y433500
+X155000Y430500
+X155000Y427500
+X158000Y423500
+X158000Y419500
+X161000Y419500
+X161000Y423500
+X164000Y423500
+X167000Y423500
+X170000Y423500
+X173000Y423500
+X176000Y423500
+X180000Y427500
+X178000Y430500
+X175000Y430500
+X176000Y427500
+X173000Y427500
+X170000Y427500
+X167000Y427500
+X166000Y430500
+X169000Y430500
+X166000Y433500
+X166400Y435900
+X169500Y435900
+X169000Y433500
+X172000Y430500
+X172000Y433500
+X172500Y435900
+X175000Y433500
+X175500Y435900
+X178000Y433500
+X181000Y433500
+X181000Y430500
+X184000Y427500
+X187000Y427500
+X184000Y430500
+X184000Y433500
+X187000Y433500
+X187000Y430500
+X190000Y427500
+X190000Y430500
+X190000Y433500
+X192000Y436500
+X194000Y434500
+X194000Y436500
+X194000Y438500
+X197000Y438500
+X197000Y436500
+X197000Y434500
+X200000Y434500
+X200000Y436500
+X200000Y438500
+X203000Y438500
+X203000Y436500
+X203000Y434500
+X206000Y434500
+X206000Y436500
+X206000Y438500
+X209000Y438500
+X209000Y436500
+X209000Y434500
+X212000Y434500
+X212000Y436500
+X215000Y436500
+X215000Y434500
+X211000Y428800
+X211000Y426800
+X211000Y424800
+X211000Y422800
+X205500Y420500
+X203000Y420500
+X203000Y423500
+X205500Y423500
+X205500Y426500
+X203000Y426500
+X206000Y429500
+X203000Y429500
+X200000Y429500
+X200000Y426500
+X200000Y423500
+X200000Y420500
+X200000Y417500
+X203000Y417500
+X205500Y417500
+X205150Y414950
+X205150Y413950
+X206800Y412000
+X210600Y407400
+X216000Y407500
+X219000Y407500
+X222000Y407500
+X225000Y407500
+X225000Y410500
+X225000Y413000
+X225000Y415500
+X222000Y413000
+X222000Y410500
+X219000Y413000
+X219000Y410500
+X216000Y410500
+X216000Y413000
+X216000Y415000
+X214000Y415000
+X213500Y413000
+X212000Y415000
+X211000Y413000
+X210000Y415000
+X210000Y417500
+X212000Y419500
+X210000Y419500
+X212000Y417500
+X214000Y417500
+X214000Y419500
+X213800Y420800
+X214800Y420800
+X214800Y422800
+X214800Y424800
+X214800Y426800
+X214800Y428800
+X225000Y423500
+X225000Y426500
+X225000Y430500
+X225000Y433500
+X222000Y436500
+X224000Y436500
+X222000Y438500
+X218000Y436500
+X218000Y438500
+X215000Y438500
+X212000Y438500
+X200900Y449900
+X205900Y449900
+X212300Y449900
+X217200Y449900
+X218600Y449900
+X243950Y449900
+X217500Y504800
+X218600Y504800
+X219700Y504800
+X220800Y504800
+X220800Y505900
+X219700Y505900
+X218600Y505900
+X217500Y505900
+X216400Y505900
+X216400Y504800
+X180500Y440800
+X179200Y440800
+X142500Y514150
+X140000Y513500
+X138600Y513500
+X136250Y515800
+X128350Y516200
+X120750Y516400
+X155000Y549500
+X155000Y552500
+X158000Y552500
+X158000Y549500
+X161000Y549500
+X161000Y545500
+X158000Y545500
+X155000Y545500
+X155000Y541500
+X155000Y537500
+X155000Y533500
+X155000Y529500
+X155000Y525500
+X158000Y525500
+X161000Y525500
+X161000Y521500
+X164000Y521500
+X167000Y521500
+X170000Y521500
+X173000Y521500
+X176000Y521500
+X176000Y517500
+X176000Y513500
+X176000Y509500
+X173000Y509500
+X170000Y509500
+X167000Y509500
+X164000Y509500
+X161000Y509500
+X158000Y509500
+X158000Y513500
+X161000Y513500
+X164000Y513500
+X167000Y513500
+X170000Y513500
+X173000Y513500
+X173000Y517500
+X170000Y517500
+X167000Y517500
+X164000Y517500
+X161000Y517500
+X158000Y521500
+X155000Y521500
+X155000Y517500
+X158000Y517500
+X155000Y513500
+X155000Y509500
+X158000Y505500
+X161000Y505500
+X164000Y505500
+X167000Y505500
+X170000Y505500
+X173000Y505500
+X176000Y505500
+X181000Y509500
+X181000Y513500
+X184500Y513500
+X188000Y513500
+X191500Y513500
+X184500Y509500
+X188000Y509500
+X191500Y509500
+X195500Y513500
+X199500Y513500
+X195500Y509500
+X199500Y509500
+X203500Y509500
+X203500Y513500
+X207500Y513500
+X207500Y509500
+X212000Y509500
+X212000Y513500
+X216500Y513500
+X216500Y509500
+X220500Y509500
+X224000Y509500
+X224500Y513500
+X220500Y513500
+X210600Y529400
+X216000Y529500
+X219000Y529500
+X222000Y529500
+X225000Y529500
+X222000Y532500
+X219000Y535000
+X219000Y532500
+X216000Y532500
+X216000Y535000
+X216000Y537000
+X214000Y537000
+X213500Y535000
+X212000Y537000
+X211000Y535000
+X210000Y537000
+X212000Y539500
+X214000Y539500
+X214000Y541500
+X213800Y542800
+X212000Y541500
+X210000Y539500
+X210000Y541500
+X211000Y544800
+X205500Y539500
+X203000Y539500
+X200000Y539500
+X200000Y542500
+X197000Y542500
+X197000Y545500
+X197000Y548500
+X200000Y548500
+X200000Y545500
+X203000Y542500
+X205500Y542500
+X205500Y545500
+X203000Y545500
+X203000Y548500
+X205500Y548500
+X206000Y551500
+X203000Y556500
+X203000Y558500
+X203000Y560500
+X200000Y560500
+X200000Y558500
+X200000Y556500
+X197000Y560500
+X197000Y558500
+X197000Y556500
+X194000Y556500
+X192000Y558500
+X194000Y558500
+X194000Y560500
+X200900Y571900
+X205900Y571900
+X212300Y571900
+X217200Y571900
+X218600Y571900
+X222000Y560500
+X224000Y558500
+X222000Y558500
+X225000Y555500
+X243950Y571900
+X225000Y552500
+X225000Y548500
+X225000Y545500
+X225000Y537500
+X225000Y535000
+X225000Y532500
+X222000Y535000
+X214800Y542800
+X214800Y544800
+X214800Y546800
+X214800Y548800
+X214800Y550800
+X211000Y546800
+X211000Y548800
+X211000Y550800
+X215000Y556500
+X215000Y558500
+X218000Y558500
+X218000Y560500
+X215000Y560500
+X212000Y560500
+X212000Y558500
+X212000Y556500
+X209000Y556500
+X209000Y558500
+X209000Y560500
+X206000Y560500
+X206000Y558500
+X206000Y556500
+X203000Y551500
+X200000Y551500
+X197000Y551500
+X194000Y548500
+X194000Y545500
+X194000Y542500
+X190000Y545500
+X187000Y545500
+X184000Y545500
+X187000Y549500
+X190000Y549500
+X190000Y552500
+X190000Y555500
+X187000Y555500
+X184000Y555500
+X181000Y555500
+X178000Y555500
+X180500Y562800
+X179200Y562800
+X175500Y557900
+X175000Y555500
+X172500Y557900
+X172000Y555500
+X169500Y557900
+X169000Y555500
+X166400Y557900
+X166000Y555500
+X166000Y552500
+X169000Y552500
+X172000Y552500
+X175000Y552500
+X178000Y552500
+X180000Y549500
+X181000Y552500
+X184000Y552500
+X187000Y552500
+X184000Y549500
+X180000Y545500
+X180000Y541500
+X180000Y539500
+X184000Y541500
+X184000Y539500
+X187000Y541500
+X187000Y539500
+X190000Y541500
+X190000Y539500
+X191850Y538850
+X194000Y539500
+X197000Y539500
+X198500Y536050
+X198500Y533950
+X197450Y532400
+X198650Y532400
+X199900Y532400
+X201000Y533950
+X203000Y534000
+X201000Y536000
+X203000Y536000
+X205150Y536950
+X205150Y535950
+X206800Y534000
+X204850Y532850
+X205500Y531700
+X206000Y530450
+X206000Y529150
+X205200Y526250
+X204100Y526250
+X204100Y525250
+X202650Y524500
+X202650Y523450
+X201600Y524500
+X199200Y525800
+X198200Y525800
+X196950Y523250
+X195850Y523250
+X195850Y524250
+X192900Y526400
+X189250Y527530
+X192150Y530500
+X193600Y532650
+X196000Y533950
+X195900Y536000
+X193350Y536500
+X191850Y537850
+X189700Y534950
+X189150Y530000
+X185600Y527500
+X179000Y525500
+X176000Y525500
+X173000Y525500
+X170000Y525500
+X167000Y525500
+X164000Y525500
+X164000Y529500
+X161000Y529500
+X158000Y529500
+X158000Y533500
+X161000Y533500
+X161000Y537500
+X158000Y537500
+X158000Y541500
+X161000Y541500
+X164000Y545500
+X167000Y545500
+X170000Y545500
+X170000Y541500
+X167000Y541500
+X164000Y541500
+X164000Y537500
+X167000Y537500
+X170000Y537500
+X170000Y533500
+X167000Y533500
+X167000Y529500
+X170000Y529500
+X173000Y529500
+X176000Y529500
+X176000Y533500
+X173000Y533500
+X173000Y537500
+X176000Y537500
+X176000Y541500
+X173000Y541500
+X173000Y545500
+X176000Y545500
+X176000Y549500
+X173000Y549500
+X170000Y549500
+X167000Y549500
+X164000Y549500
+X161000Y552500
+X161000Y555500
+X163400Y557900
+X160400Y557900
+X158000Y555500
+X155000Y555500
+X151200Y562800
+X149900Y562800
+X091800Y561500
+X090400Y561500
+X077800Y561500
+X076400Y561500
+X063800Y561500
+X062600Y561500
+X049800Y561500
+X048600Y561500
+X042100Y509500
+X043100Y509500
+X055400Y509500
+X056400Y509500
+X068400Y509500
+X069400Y509500
+X081600Y509500
+X082600Y509500
+X095000Y509500
+X096000Y509500
+X113050Y516400
+X048600Y439500
+X049800Y439500
+X062600Y439500
+X063800Y439500
+X076400Y439500
+X077800Y439500
+X090400Y439500
+X091800Y439500
+X128350Y394200
+X120750Y394400
+X113050Y394400
+X096000Y387500
+X095000Y387500
+X082600Y387500
+X081600Y387500
+X069400Y387500
+X068400Y387500
+X048600Y317500
+X049800Y317500
+X056400Y387500
+X055400Y387500
+X043100Y387500
+X042100Y387500
+X028150Y387500
+X027130Y387500
+X022000Y387500
+X021000Y387500
+X007730Y394750
+X006700Y394750
+X-023500Y391500
+X-027500Y391500
+X-027500Y387500
+X-024000Y387500
+X-027200Y383900
+X-027200Y382800
+X-028300Y382800
+X-029400Y382800
+X-030500Y382800
+X-031600Y382800
+X-031600Y383900
+X-030500Y383900
+X-029400Y383900
+X-028300Y383900
+X-031500Y387500
+X-031500Y391500
+X-036000Y391500
+X-036000Y387500
+X-040500Y387500
+X-040500Y391500
+X-045350Y401450
+X-046400Y402500
+X-045350Y402500
+X-043900Y403250
+X-043900Y404250
+X-042800Y404250
+X-042000Y407150
+X-042000Y408450
+X-042500Y409700
+X-043150Y410850
+X-041200Y412000
+X-037400Y407400
+X-032000Y407500
+X-029000Y407500
+X-026000Y407500
+X-023000Y407500
+X-023000Y410500
+X-023000Y413000
+X-023000Y415500
+X-026000Y413000
+X-026000Y410500
+X-029000Y410500
+X-029000Y413000
+X-032000Y410500
+X-032000Y413000
+X-032000Y415000
+X-034000Y415000
+X-034500Y413000
+X-036000Y415000
+X-037000Y413000
+X-038000Y415000
+X-038000Y417500
+X-038000Y419500
+X-036000Y419500
+X-036000Y417500
+X-034000Y417500
+X-034000Y419500
+X-033200Y420800
+X-034200Y420800
+X-033200Y422800
+X-033200Y424800
+X-033200Y426800
+X-033200Y428800
+X-037000Y428800
+X-037000Y426800
+X-037000Y424800
+X-037000Y422800
+X-042500Y423500
+X-045000Y420500
+X-042500Y420500
+X-042500Y417500
+X-045000Y417500
+X-042850Y414950
+X-042850Y413950
+X-045000Y414000
+X-047000Y414000
+X-045000Y412000
+X-047000Y411950
+X-048100Y410400
+X-049500Y411950
+X-049350Y410400
+X-050550Y410400
+X-048800Y403800
+X-049800Y403800
+X-051050Y401250
+X-052150Y401250
+X-052150Y402250
+X-055100Y404400
+X-058750Y405530
+X-062400Y405500
+X-058850Y408000
+X-055850Y408500
+X-054400Y410650
+X-052000Y411950
+X-052100Y414000
+X-049500Y414050
+X-048000Y417500
+X-048000Y420500
+X-045000Y423500
+X-045000Y426500
+X-042500Y426500
+X-042000Y429500
+X-045000Y429500
+X-048000Y429500
+X-048000Y426500
+X-048000Y423500
+X-051000Y423500
+X-051000Y426500
+X-051000Y429500
+X-054000Y426500
+X-054000Y423500
+X-054000Y420500
+X-051000Y420500
+X-051000Y417500
+X-054000Y417500
+X-054650Y414500
+X-058300Y412950
+X-056150Y415850
+X-056150Y416850
+X-058000Y417500
+X-058000Y419500
+X-061000Y417500
+X-061000Y419500
+X-058000Y423500
+X-061000Y423500
+X-064000Y423500
+X-064000Y419500
+X-064000Y417500
+X-068000Y417500
+X-068000Y419500
+X-072000Y419500
+X-075000Y419500
+X-078000Y419500
+X-078000Y423500
+X-075000Y423500
+X-072000Y423500
+X-068000Y423500
+X-072000Y427500
+X-075000Y427500
+X-078000Y427500
+X-081000Y427500
+X-084000Y427500
+X-082000Y430500
+X-079000Y430500
+X-082000Y433500
+X-081600Y435900
+X-079000Y433500
+X-078500Y435900
+X-075500Y435900
+X-076000Y433500
+X-076000Y430500
+X-073000Y430500
+X-073000Y433500
+X-072500Y435900
+X-068800Y440800
+X-067500Y440800
+X-067000Y433500
+X-070000Y433500
+X-070000Y430500
+X-068000Y427500
+X-067000Y430500
+X-064000Y427500
+X-064000Y430500
+X-064000Y433500
+X-061000Y433500
+X-061000Y430500
+X-061000Y427500
+X-058000Y427500
+X-058000Y430500
+X-058000Y433500
+X-056000Y436500
+X-054000Y438500
+X-054000Y436500
+X-054000Y434500
+X-051000Y434500
+X-051000Y436500
+X-048000Y434500
+X-048000Y436500
+X-048000Y438500
+X-051000Y438500
+X-047100Y449900
+X-042100Y449900
+X-035700Y449900
+X-030800Y449900
+X-029400Y449900
+X-026000Y438500
+X-030000Y438500
+X-033000Y438500
+X-036000Y438500
+X-039000Y438500
+X-042000Y438500
+X-045000Y438500
+X-045000Y436500
+X-045000Y434500
+X-042000Y434500
+X-042000Y436500
+X-039000Y434500
+X-039000Y436500
+X-036000Y434500
+X-036000Y436500
+X-033000Y434500
+X-033000Y436500
+X-030000Y436500
+X-026000Y436500
+X-024000Y436500
+X-023000Y433500
+X-023000Y430500
+X-023000Y426500
+X-023000Y423500
+X-004050Y449900
+X028150Y509500
+X027130Y509500
+X022000Y509500
+X021000Y509500
+X007730Y516750
+X006700Y516750
+X-023000Y545500
+X-023000Y548500
+X-023000Y552500
+X-023000Y555500
+X-004050Y571900
+X-029400Y571900
+X-030800Y571900
+X-035700Y571900
+X-042100Y571900
+X-047100Y571900
+X-048000Y560500
+X-048000Y558500
+X-048000Y556500
+X-045000Y556500
+X-045000Y558500
+X-045000Y560500
+X-042000Y556500
+X-042000Y558500
+X-042000Y560500
+X-039000Y560500
+X-039000Y558500
+X-039000Y556500
+X-036000Y556500
+X-036000Y558500
+X-036000Y560500
+X-033000Y560500
+X-030000Y560500
+X-026000Y558500
+X-024000Y558500
+X-026000Y560500
+X-030000Y558500
+X-033000Y558500
+X-033000Y556500
+X-033200Y550800
+X-033200Y548800
+X-033200Y546800
+X-033200Y544800
+X-033200Y542800
+X-034200Y542800
+X-037000Y544800
+X-037000Y546800
+X-037000Y548800
+X-037000Y550800
+X-042000Y551500
+X-045000Y551500
+X-045000Y548500
+X-042500Y548500
+X-042500Y545500
+X-045000Y545500
+X-042500Y542500
+X-045000Y542500
+X-048000Y545500
+X-048000Y548500
+X-048000Y551500
+X-051000Y551500
+X-051000Y548500
+X-051000Y545500
+X-051000Y542500
+X-051000Y539500
+X-048000Y542500
+X-048000Y539500
+X-045000Y539500
+X-042500Y539500
+X-042850Y536950
+X-042850Y535950
+X-041200Y534000
+X-043150Y532850
+X-042500Y531700
+X-042000Y530450
+X-042000Y529150
+X-037400Y529400
+X-032000Y532500
+X-034500Y535000
+X-036000Y537000
+X-037000Y535000
+X-038000Y537000
+X-038000Y539500
+X-038000Y541500
+X-036000Y541500
+X-034000Y541500
+X-034000Y539500
+X-036000Y539500
+X-034000Y537000
+X-032000Y535000
+X-032000Y537000
+X-029000Y535000
+X-026000Y535000
+X-023000Y537500
+X-023000Y535000
+X-023000Y532500
+X-026000Y532500
+X-029000Y532500
+X-032000Y529500
+X-029000Y529500
+X-026000Y529500
+X-023000Y529500
+X-023500Y513500
+X-027500Y509500
+X-024000Y509500
+X-027500Y513500
+X-031500Y513500
+X-031500Y509500
+X-029400Y505900
+X-028300Y505900
+X-027200Y505900
+X-027200Y504800
+X-028300Y504800
+X-029400Y504800
+X-030500Y504800
+X-031600Y504800
+X-030500Y505900
+X-031600Y505900
+X-036000Y509500
+X-036000Y513500
+X-045350Y523450
+X-045350Y524500
+X-043900Y525250
+X-042800Y526250
+X-043900Y526250
+X-046400Y524500
+X-048800Y525800
+X-050550Y532400
+X-049350Y532400
+X-049500Y533950
+X-048100Y532400
+X-047000Y533950
+X-045000Y534000
+X-045000Y536000
+X-047000Y536000
+X-049500Y536050
+X-052100Y536000
+X-052000Y533950
+X-054400Y532650
+X-058300Y534950
+X-054650Y536500
+X-056150Y537850
+X-058000Y539500
+X-058000Y541500
+X-056150Y538850
+X-054000Y539500
+X-054000Y542500
+X-054000Y545500
+X-054000Y548500
+X-054000Y556500
+X-051000Y556500
+X-051000Y558500
+X-051000Y560500
+X-054000Y560500
+X-054000Y558500
+X-056000Y558500
+X-058000Y555500
+X-058000Y552500
+X-058000Y549500
+X-058000Y545500
+X-061000Y545500
+X-061000Y541500
+X-061000Y539500
+X-064000Y541500
+X-064000Y539500
+X-068000Y539500
+X-068000Y541500
+X-064000Y545500
+X-068000Y545500
+X-068000Y549500
+X-067000Y552500
+X-064000Y552500
+X-061000Y549500
+X-064000Y549500
+X-061000Y552500
+X-061000Y555500
+X-064000Y555500
+X-067000Y555500
+X-070000Y555500
+X-073000Y552500
+X-070000Y552500
+X-072000Y549500
+X-075000Y549500
+X-072000Y545500
+X-075000Y545500
+X-078000Y545500
+X-081000Y545500
+X-081000Y541500
+X-078000Y541500
+X-075000Y541500
+X-072000Y541500
+X-072000Y537500
+X-075000Y537500
+X-078000Y537500
+X-075000Y533500
+X-072000Y533500
+X-075000Y529500
+X-072000Y529500
+X-069000Y525500
+X-062400Y527500
+X-058850Y530000
+X-058750Y527530
+X-055850Y530500
+X-055100Y526400
+X-052150Y524250
+X-049800Y525800
+X-051050Y523250
+X-052150Y523250
+X-044500Y513500
+X-040500Y513500
+X-040500Y509500
+X-044500Y509500
+X-048500Y509500
+X-048500Y513500
+X-052500Y513500
+X-052500Y509500
+X-056500Y509500
+X-060000Y509500
+X-056500Y513500
+X-060000Y513500
+X-063500Y513500
+X-063500Y509500
+X-067000Y509500
+X-067000Y513500
+X-072000Y509500
+X-075000Y509500
+X-078000Y509500
+X-081000Y509500
+X-081000Y513500
+X-078000Y513500
+X-075000Y513500
+X-072000Y513500
+X-072000Y517500
+X-075000Y517500
+X-078000Y517500
+X-078000Y521500
+X-075000Y521500
+X-072000Y521500
+X-072000Y525500
+X-075000Y525500
+X-078000Y525500
+X-081000Y525500
+X-084000Y525500
+X-087000Y525500
+X-087000Y521500
+X-084000Y521500
+X-081000Y521500
+X-081000Y517500
+X-084000Y517500
+X-087000Y517500
+X-087000Y513500
+X-084000Y513500
+X-084000Y509500
+X-087000Y509500
+X-090000Y509500
+X-093000Y509500
+X-093000Y513500
+X-090000Y513500
+X-090000Y517500
+X-093000Y517500
+X-093000Y521500
+X-090000Y521500
+X-090000Y525500
+X-093000Y525500
+X-093000Y529500
+X-090000Y529500
+X-090000Y533500
+X-093000Y533500
+X-093000Y537500
+X-090000Y537500
+X-087000Y537500
+X-084000Y537500
+X-087000Y533500
+X-087000Y529500
+X-084000Y529500
+X-081000Y529500
+X-078000Y529500
+X-078000Y533500
+X-081000Y533500
+X-081000Y537500
+X-084000Y541500
+X-087000Y541500
+X-084000Y545500
+X-087000Y545500
+X-090000Y545500
+X-093000Y541500
+X-090000Y541500
+X-093000Y545500
+X-093000Y549500
+X-090000Y549500
+X-093000Y552500
+X-090000Y552500
+X-087000Y552500
+X-087000Y549500
+X-084000Y549500
+X-081000Y549500
+X-082000Y552500
+X-079000Y552500
+X-078000Y549500
+X-076000Y552500
+X-073000Y555500
+X-072500Y557900
+X-067500Y562800
+X-068800Y562800
+X-075500Y557900
+X-076000Y555500
+X-078500Y557900
+X-079000Y555500
+X-081600Y557900
+X-082000Y555500
+X-084600Y557900
+X-087000Y555500
+X-087600Y557900
+X-090000Y555500
+X-093000Y555500
+X-096800Y562800
+X-098100Y562800
+X-156200Y561500
+X-157600Y561500
+X-170200Y561500
+X-171600Y561500
+X-184200Y561500
+X-185400Y561500
+X-198200Y561500
+X-199400Y561500
+X-241300Y516750
+X-240270Y516750
+X-227000Y509500
+X-226000Y509500
+X-220870Y509500
+X-219850Y509500
+X-205900Y509500
+X-204900Y509500
+X-192600Y509500
+X-191600Y509500
+X-179600Y509500
+X-178600Y509500
+X-166400Y509500
+X-165400Y509500
+X-153000Y509500
+X-152000Y509500
+X-134950Y516400
+X-127250Y516400
+X-119650Y516200
+X-111750Y515800
+X-109400Y513500
+X-108000Y513500
+X-105500Y514150
+X-090000Y505500
+X-087000Y505500
+X-084000Y505500
+X-081000Y505500
+X-078000Y505500
+X-075000Y505500
+X-072000Y505500
+X-098100Y440800
+X-096800Y440800
+X-093000Y433500
+X-093000Y430500
+X-090000Y433500
+X-087600Y435900
+X-084600Y435900
+X-087000Y433500
+X-087000Y430500
+X-087000Y427500
+X-090000Y427500
+X-090000Y430500
+X-093000Y427500
+X-090000Y423500
+X-093000Y423500
+X-093000Y419500
+X-090000Y419500
+X-093000Y415500
+X-090000Y415500
+X-093000Y411500
+X-090000Y411500
+X-087000Y411500
+X-087000Y415500
+X-084000Y415500
+X-084000Y419500
+X-087000Y419500
+X-087000Y423500
+X-084000Y423500
+X-081000Y423500
+X-081000Y419500
+X-081000Y415500
+X-081000Y411500
+X-078000Y411500
+X-078000Y415500
+X-075000Y415500
+X-072000Y415500
+X-072000Y411500
+X-075000Y411500
+X-072000Y407500
+X-075000Y407500
+X-078000Y407500
+X-081000Y407500
+X-084000Y407500
+X-087000Y407500
+X-090000Y407500
+X-093000Y407500
+X-093000Y403500
+X-090000Y403500
+X-087000Y403500
+X-084000Y403500
+X-081000Y403500
+X-078000Y403500
+X-075000Y403500
+X-072000Y403500
+X-069000Y403500
+X-072000Y399500
+X-075000Y395500
+X-078000Y395500
+X-081000Y395500
+X-084000Y395500
+X-087000Y395500
+X-090000Y395500
+X-093000Y395500
+X-093000Y391500
+X-090000Y391500
+X-087000Y391500
+X-084000Y391500
+X-081000Y391500
+X-078000Y391500
+X-075000Y391500
+X-072000Y391500
+X-072000Y387500
+X-075000Y387500
+X-078000Y387500
+X-081000Y387500
+X-084000Y387500
+X-087000Y387500
+X-090000Y387500
+X-093000Y387500
+X-090000Y383500
+X-087000Y383500
+X-084000Y383500
+X-081000Y383500
+X-078000Y383500
+X-075000Y383500
+X-072000Y383500
+X-067000Y387500
+X-063500Y387500
+X-060000Y387500
+X-056500Y387500
+X-052500Y387500
+X-048500Y387500
+X-044500Y387500
+X-044500Y391500
+X-048500Y391500
+X-052500Y391500
+X-056500Y391500
+X-060000Y391500
+X-063500Y391500
+X-067000Y391500
+X-072000Y395500
+X-075000Y399500
+X-078000Y399500
+X-081000Y399500
+X-084000Y399500
+X-087000Y399500
+X-090000Y399500
+X-093000Y399500
+X-105500Y392150
+X-108000Y391500
+X-109400Y391500
+X-111750Y393800
+X-119650Y394200
+X-127250Y394400
+X-134950Y394400
+X-152000Y387500
+X-153000Y387500
+X-156200Y439500
+X-157600Y439500
+X-170200Y439500
+X-171600Y439500
+X-184200Y439500
+X-185400Y439500
+X-198200Y439500
+X-199400Y439500
+X-241300Y394750
+X-240270Y394750
+X-227000Y387500
+X-226000Y387500
+X-220870Y387500
+X-219850Y387500
+X-205900Y387500
+X-204900Y387500
+X-192600Y387500
+X-191600Y387500
+X-179600Y387500
+X-178600Y387500
+X-166400Y387500
+X-165400Y387500
+X-199400Y317500
+X-198200Y317500
+X-185400Y317500
+X-184200Y317500
+X-171600Y317500
+X-170200Y317500
+X-157600Y317500
+X-156200Y317500
+X-098100Y318800
+X-096800Y318800
+X-093000Y311500
+X-093000Y308500
+X-093000Y305500
+X-093000Y301500
+X-090000Y301500
+X-087000Y301500
+X-084000Y301500
+X-081000Y301500
+X-078000Y301500
+X-075000Y301500
+X-072000Y301500
+X-068000Y297500
+X-068000Y295500
+X-064000Y295500
+X-064000Y297500
+X-061000Y297500
+X-061000Y295500
+X-058000Y297500
+X-058000Y295500
+X-064000Y301500
+X-061000Y301500
+X-058000Y301500
+X-054000Y304500
+X-054000Y301500
+X-054000Y298500
+X-054000Y295500
+X-056150Y294850
+X-056150Y293850
+X-054650Y292500
+X-058300Y290950
+X-055850Y286500
+X-054400Y288650
+X-052000Y289950
+X-050550Y288400
+X-049350Y288400
+X-049500Y289950
+X-048100Y288400
+X-047000Y289950
+X-045000Y290000
+X-043150Y288850
+X-042500Y287700
+X-042000Y286450
+X-042000Y285150
+X-037400Y285400
+X-042800Y282250
+X-043900Y282250
+X-043900Y281250
+X-045350Y280500
+X-045350Y279450
+X-046400Y280500
+X-048800Y281800
+X-049800Y281800
+X-051050Y279250
+X-052150Y279250
+X-052150Y280250
+X-055100Y282400
+X-058750Y283530
+X-058850Y286000
+X-062400Y283500
+X-069000Y281500
+X-072000Y281500
+X-075000Y281500
+X-078000Y281500
+X-081000Y281500
+X-081000Y277500
+X-078000Y277500
+X-075000Y277500
+X-072000Y277500
+X-072000Y273500
+X-075000Y273500
+X-078000Y273500
+X-081000Y273500
+X-084000Y273500
+X-087000Y273500
+X-090000Y273500
+X-093000Y273500
+X-093000Y277500
+X-090000Y277500
+X-087000Y277500
+X-084000Y277500
+X-084000Y281500
+X-087000Y281500
+X-090000Y281500
+X-093000Y281500
+X-093000Y285500
+X-090000Y285500
+X-087000Y285500
+X-084000Y285500
+X-081000Y285500
+X-078000Y285500
+X-081000Y289500
+X-078000Y289500
+X-075000Y285500
+X-072000Y285500
+X-072000Y289500
+X-075000Y289500
+X-072000Y293500
+X-075000Y293500
+X-078000Y293500
+X-081000Y293500
+X-084000Y293500
+X-087000Y293500
+X-087000Y289500
+X-090000Y289500
+X-093000Y289500
+X-093000Y293500
+X-090000Y293500
+X-093000Y297500
+X-090000Y297500
+X-087000Y297500
+X-084000Y297500
+X-081000Y297500
+X-078000Y297500
+X-075000Y297500
+X-072000Y297500
+X-068000Y301500
+X-068000Y305500
+X-067000Y308500
+X-067000Y311500
+X-070000Y311500
+X-070000Y308500
+X-073000Y308500
+X-072000Y305500
+X-075000Y305500
+X-076000Y308500
+X-078000Y305500
+X-081000Y305500
+X-084000Y305500
+X-087000Y308500
+X-087000Y305500
+X-090000Y305500
+X-090000Y308500
+X-090000Y311500
+X-087600Y313900
+X-087000Y311500
+X-084600Y313900
+X-081600Y313900
+X-082000Y311500
+X-082000Y308500
+X-079000Y308500
+X-079000Y311500
+X-078500Y313900
+X-076000Y311500
+X-075500Y313900
+X-073000Y311500
+X-072500Y313900
+X-068800Y318800
+X-067500Y318800
+X-064000Y311500
+X-064000Y308500
+X-064000Y305500
+X-061000Y305500
+X-058000Y305500
+X-061000Y308500
+X-061000Y311500
+X-058000Y308500
+X-058000Y311500
+X-056000Y314500
+X-054000Y316500
+X-054000Y314500
+X-054000Y312500
+X-051000Y312500
+X-051000Y314500
+X-051000Y316500
+X-048000Y316500
+X-048000Y314500
+X-048000Y312500
+X-045000Y312500
+X-045000Y314500
+X-045000Y316500
+X-042000Y316500
+X-042000Y314500
+X-042000Y312500
+X-039000Y312500
+X-039000Y314500
+X-039000Y316500
+X-036000Y316500
+X-036000Y314500
+X-036000Y312500
+X-033000Y312500
+X-033000Y314500
+X-033000Y316500
+X-047100Y327900
+X-042100Y327900
+X-035700Y327900
+X-030800Y327900
+X-029400Y327900
+X-030000Y316500
+X-030000Y314500
+X-026000Y314500
+X-026000Y316500
+X-024000Y314500
+X-023000Y311500
+X-004050Y327900
+X-023000Y308500
+X-023000Y304500
+X-023000Y301500
+X-033200Y306800
+X-033200Y304800
+X-033200Y302800
+X-033200Y300800
+X-033200Y298800
+X-034200Y298800
+X-034000Y297500
+X-036000Y297500
+X-038000Y297500
+X-037000Y300800
+X-037000Y302800
+X-037000Y304800
+X-037000Y306800
+X-042000Y307500
+X-045000Y307500
+X-045000Y304500
+X-042500Y304500
+X-042500Y301500
+X-045000Y301500
+X-045000Y298500
+X-042500Y298500
+X-042500Y295500
+X-045000Y295500
+X-048000Y295500
+X-048000Y298500
+X-048000Y301500
+X-048000Y304500
+X-048000Y307500
+X-051000Y307500
+X-051000Y304500
+X-051000Y301500
+X-051000Y298500
+X-051000Y295500
+X-052100Y292000
+X-049500Y292050
+X-047000Y292000
+X-045000Y292000
+X-042850Y292950
+X-042850Y291950
+X-041200Y290000
+X-038000Y293000
+X-037000Y291000
+X-036000Y293000
+X-038000Y295500
+X-036000Y295500
+X-034000Y295500
+X-032000Y293000
+X-032000Y291000
+X-034000Y293000
+X-034500Y291000
+X-032000Y288500
+X-032000Y285500
+X-029000Y285500
+X-026000Y285500
+X-023000Y285500
+X-026000Y288500
+X-029000Y288500
+X-029000Y291000
+X-026000Y291000
+X-023000Y288500
+X-023000Y291000
+X-023000Y293500
+X006700Y272750
+X007730Y272750
+X-023500Y269500
+X-027500Y269500
+X-024000Y265500
+X-027500Y265500
+X-027200Y261900
+X-027200Y260800
+X-028300Y260800
+X-029400Y260800
+X-030500Y260800
+X-031600Y260800
+X-031600Y261900
+X-030500Y261900
+X-029400Y261900
+X-028300Y261900
+X-031500Y265500
+X-031500Y269500
+X-036000Y269500
+X-036000Y265500
+X-040500Y265500
+X-040500Y269500
+X-044500Y269500
+X-044500Y265500
+X-048500Y265500
+X-052500Y265500
+X-048500Y269500
+X-052500Y269500
+X-056500Y269500
+X-056500Y265500
+X-060000Y265500
+X-063500Y265500
+X-060000Y269500
+X-063500Y269500
+X-067000Y269500
+X-067000Y265500
+X-072000Y261500
+X-075000Y261500
+X-078000Y261500
+X-081000Y261500
+X-084000Y261500
+X-087000Y261500
+X-090000Y261500
+X-093000Y265500
+X-090000Y265500
+X-087000Y265500
+X-084000Y265500
+X-081000Y265500
+X-078000Y265500
+X-075000Y265500
+X-072000Y265500
+X-072000Y269500
+X-075000Y269500
+X-078000Y269500
+X-081000Y269500
+X-084000Y269500
+X-087000Y269500
+X-090000Y269500
+X-093000Y269500
+X-105500Y270150
+X-108000Y269500
+X-109400Y269500
+X-111750Y271800
+X-119650Y272200
+X-127250Y272400
+X-134950Y272400
+X-152000Y265500
+X-153000Y265500
+X-165400Y265500
+X-166400Y265500
+X-178600Y265500
+X-179600Y265500
+X-191600Y265500
+X-192600Y265500
+X-204900Y265500
+X-205900Y265500
+X-219850Y265500
+X-220870Y265500
+X-226000Y265500
+X-227000Y265500
+X-240270Y272750
+X-241300Y272750
+X042739Y622500
+T04
+X-187663Y483000
+X-189338Y483000
+X-197950Y466700
+X-187050Y466700
+X-183950Y466700
+X-173050Y466700
+X-169950Y466700
+X-159050Y466700
+X-161338Y483000
+X-159663Y483000
+X-133138Y483000
+X-131463Y483000
+X-145050Y466700
+X-155950Y466700
+X-141550Y440150
+X-149250Y432450
+X-138100Y429700
+X-138100Y435100
+X-134200Y435350
+X-130200Y435350
+X-126300Y435350
+X-122300Y434850
+X-119640Y438140
+X-114760Y433260
+X-122300Y429950
+X-126300Y427450
+X-130200Y425450
+X-134200Y425450
+X-189338Y361000
+X-187663Y361000
+X-197950Y344700
+X-187050Y344700
+X-183950Y344700
+X-173050Y344700
+X-169950Y344700
+X-161338Y361000
+X-159663Y361000
+X-159050Y344700
+X-155950Y344700
+X-141550Y318150
+X-149250Y310450
+X-138100Y307700
+X-134200Y303450
+X-133138Y239000
+X-131463Y239000
+X-115750Y222600
+X-104850Y222600
+X-101750Y222600
+X-090850Y222600
+X-073250Y222700
+X-062350Y222700
+X-029600Y245300
+X-025600Y245300
+X-021640Y245250
+X-021640Y238750
+X-025600Y236300
+X-029600Y238300
+X-024350Y225000
+X-010950Y229400
+X050050Y222700
+X060338Y239000
+X058663Y239000
+X060950Y222700
+X064050Y222700
+X074950Y222700
+X078050Y222700
+X088338Y239000
+X086663Y239000
+X088950Y222700
+X092050Y222700
+X102950Y222700
+X114863Y239000
+X116538Y239000
+X132250Y222600
+X121700Y191350
+X117800Y191350
+X113800Y191350
+X109900Y191100
+X106450Y196150
+X098750Y188450
+X109900Y185700
+X113800Y181450
+X117800Y181450
+X121700Y183450
+X125700Y185950
+X125700Y190850
+X133240Y189260
+X128360Y194140
+X143150Y222600
+X146250Y222600
+X157150Y222600
+X174750Y222700
+X185650Y222700
+X218400Y245300
+X222400Y245300
+X226360Y245250
+X226360Y238750
+X222400Y236300
+X218400Y238300
+X223650Y225000
+X237050Y229400
+X218400Y123300
+X222400Y123300
+X226360Y123250
+X218400Y116300
+X222400Y114300
+X226360Y116750
+X237050Y107400
+X223650Y103000
+X185650Y100700
+X174750Y100700
+X254000Y001500
+X246500Y003500
+X241500Y003500
+X236500Y003500
+X157150Y100600
+X146250Y100600
+X143150Y100600
+X132250Y100600
+X116538Y117000
+X114863Y117000
+X102950Y100700
+X128360Y072140
+X133240Y067260
+X125700Y068850
+X125700Y063950
+X121700Y061450
+X117800Y059450
+X113800Y059450
+X109900Y063700
+X121700Y069350
+X117800Y069350
+X113800Y069350
+X109900Y069100
+X098750Y066450
+X106450Y074150
+X092050Y100700
+X088950Y100700
+X088338Y117000
+X086663Y117000
+X078050Y100700
+X074950Y100700
+X064050Y100700
+X060950Y100700
+X058663Y117000
+X060338Y117000
+X050050Y100700
+X-010950Y107400
+X-024350Y103000
+X-029600Y116300
+X-025600Y114300
+X-021640Y116750
+X-021640Y123250
+X-025600Y123300
+X-029600Y123300
+X-062350Y100700
+X-073250Y100700
+X-090850Y100600
+X-101750Y100600
+X-104850Y100600
+X-119640Y072140
+X-114760Y067260
+X-122300Y068850
+X-122300Y063950
+X-126300Y061450
+X-130200Y059450
+X-134200Y059450
+X-126300Y069350
+X-130200Y069350
+X-134200Y069350
+X-138100Y069100
+X-138100Y063700
+X-149250Y066450
+X-141550Y074150
+X-115750Y100600
+X-131463Y117000
+X-133138Y117000
+X-145050Y100700
+X-237000Y003500
+X-242000Y003500
+X-247000Y003500
+X-254000Y001500
+X-197950Y100700
+X-189338Y117000
+X-187663Y117000
+X-187050Y100700
+X-183950Y100700
+X-173050Y100700
+X-169950Y100700
+X-159050Y100700
+X-155950Y100700
+X-159663Y117000
+X-161338Y117000
+X-126300Y183450
+X-122300Y185950
+X-114760Y189260
+X-119640Y194140
+X-122300Y190850
+X-126300Y191350
+X-130200Y191350
+X-134200Y191350
+X-130200Y181450
+X-134200Y181450
+X-138100Y185700
+X-138100Y191100
+X-149250Y188450
+X-141550Y196150
+X-159050Y222700
+X-155950Y222700
+X-145050Y222700
+X-161338Y239000
+X-159663Y239000
+X-169950Y222700
+X-173050Y222700
+X-183950Y222700
+X-187050Y222700
+X-197950Y222700
+X-189338Y239000
+X-187663Y239000
+X-130200Y303450
+X-126300Y305450
+X-122300Y307950
+X-114760Y311260
+X-119640Y316140
+X-122300Y312850
+X-126300Y313350
+X-130200Y313350
+X-134200Y313350
+X-138100Y313100
+X-145050Y344700
+X-133138Y361000
+X-131463Y361000
+X-115750Y344600
+X-104850Y344600
+X-101750Y344600
+X-090850Y344600
+X-073250Y344700
+X-062350Y344700
+X-029600Y360300
+X-024350Y347000
+X-010950Y351400
+X-021640Y360750
+X-025600Y358300
+X-021640Y367250
+X-025600Y367300
+X-029600Y367300
+X-115750Y466600
+X-104850Y466600
+X-101750Y466600
+X-090850Y466600
+X-073250Y466700
+X-062350Y466700
+X-029600Y489300
+X-025600Y489300
+X-021640Y489250
+X-021640Y482750
+X-025600Y480300
+X-029600Y482300
+X-024350Y469000
+X-010950Y473400
+X050050Y466700
+X060950Y466700
+X064050Y466700
+X074950Y466700
+X058663Y483000
+X060338Y483000
+X086663Y483000
+X088338Y483000
+X114863Y483000
+X116538Y483000
+X102950Y466700
+X092050Y466700
+X088950Y466700
+X078050Y466700
+X106450Y440150
+X098750Y432450
+X109900Y429700
+X109900Y435100
+X113800Y435350
+X117800Y435350
+X121700Y435350
+X125700Y434850
+X128360Y438140
+X133240Y433260
+X125700Y429950
+X121700Y427450
+X117800Y425450
+X113800Y425450
+X086663Y361000
+X088338Y361000
+X092050Y344700
+X088950Y344700
+X078050Y344700
+X074950Y344700
+X060338Y361000
+X058663Y361000
+X050050Y344700
+X060950Y344700
+X064050Y344700
+X098750Y310450
+X109900Y307700
+X113800Y303450
+X117800Y303450
+X121700Y305450
+X125700Y307950
+X133240Y311260
+X128360Y316140
+X125700Y312850
+X121700Y313350
+X117800Y313350
+X113800Y313350
+X109900Y313100
+X106450Y318150
+X102950Y344700
+X114863Y361000
+X116538Y361000
+X132250Y344600
+X143150Y344600
+X146250Y344600
+X157150Y344600
+X174750Y344700
+X185650Y344700
+X218400Y367300
+X218400Y360300
+X222400Y358300
+X223650Y347000
+X237050Y351400
+X226360Y360750
+X226360Y367250
+X222400Y367300
+X132250Y466600
+X143150Y466600
+X146250Y466600
+X157150Y466600
+X174750Y466700
+X185650Y466700
+X223650Y469000
+X237050Y473400
+X226360Y482750
+X222400Y480300
+X218400Y482300
+X226360Y489250
+X222400Y489300
+X218400Y489300
+X223650Y591000
+X237050Y595400
+X254000Y623500
+X247000Y621500
+X242000Y621500
+X237000Y621500
+X218400Y611300
+X222400Y611300
+X226360Y611250
+X226360Y604750
+X222400Y602300
+X218400Y604300
+X185650Y588700
+X174750Y588700
+X157150Y588600
+X146250Y588600
+X143150Y588600
+X132250Y588600
+X128360Y560140
+X133240Y555260
+X125700Y556850
+X125700Y551950
+X121700Y549450
+X117800Y547450
+X113800Y547450
+X109900Y551700
+X109900Y557100
+X098750Y554450
+X106450Y562150
+X113800Y557350
+X117800Y557350
+X121700Y557350
+X102950Y588700
+X116538Y605000
+X114863Y605000
+X106789Y621663
+X106789Y623338
+X088338Y605000
+X086663Y605000
+X092050Y588700
+X088950Y588700
+X078050Y588700
+X074950Y588700
+X064050Y588700
+X060950Y588700
+X060338Y605000
+X058663Y605000
+X050050Y588700
+X-010950Y595400
+X-024350Y591000
+X-021640Y604750
+X-025600Y602300
+X-029600Y604300
+X-021640Y611250
+X-025600Y611300
+X-029600Y611300
+X-062350Y588700
+X-073250Y588700
+X-090850Y588600
+X-095424Y620200
+X-095424Y621283
+X-093255Y621924
+X-094336Y621924
+X-095424Y622366
+X-095424Y623449
+X-096662Y621924
+X-097743Y621924
+X-100011Y623449
+X-100011Y622366
+X-100011Y621283
+X-101093Y620200
+X-102174Y620200
+X-103256Y622366
+X-103256Y621283
+X-104337Y620200
+X-105419Y620200
+X-106500Y621283
+X-106500Y622366
+X-106500Y623449
+X-108011Y623449
+X-108011Y622366
+X-108011Y621283
+X-109093Y620200
+X-110174Y620200
+X-111256Y621283
+X-111256Y622366
+X-112337Y620200
+X-113419Y620200
+X-114500Y621283
+X-114500Y622366
+X-114500Y623449
+X-116011Y622366
+X-116011Y621283
+X-117093Y620200
+X-118174Y620200
+X-120337Y620200
+X-119256Y621283
+X-117093Y623449
+X-118174Y623449
+X-119256Y622366
+X-120337Y623449
+X-121419Y623449
+X-122500Y622366
+X-122500Y621283
+X-121419Y620200
+X-104850Y588600
+X-101750Y588600
+X-119640Y560140
+X-114760Y555260
+X-122300Y551950
+X-126300Y549450
+X-130200Y547450
+X-134200Y547450
+X-138100Y551700
+X-149250Y554450
+X-141550Y562150
+X-138100Y557100
+X-134200Y557350
+X-130200Y557350
+X-126300Y557350
+X-122300Y556850
+X-115750Y588600
+X-131463Y605000
+X-133138Y605000
+X-125093Y621283
+X-124011Y621283
+X-125093Y622366
+X-126174Y621283
+X-127256Y621283
+X-128337Y621283
+X-129419Y621283
+X-130500Y621283
+X-132011Y621283
+X-133093Y622366
+X-133093Y621283
+X-134174Y621283
+X-135256Y621283
+X-136337Y621283
+X-137419Y621283
+X-138500Y621283
+X-141093Y620200
+X-140011Y621283
+X-140011Y622366
+X-141093Y623449
+X-142174Y623449
+X-143256Y623449
+X-144337Y623449
+X-145419Y623449
+X-146500Y622366
+X-146500Y621283
+X-145419Y620200
+X-148011Y621283
+X-148011Y622366
+X-149093Y623449
+X-150174Y623449
+X-151256Y623449
+X-152337Y623449
+X-153419Y623449
+X-149093Y620200
+X-150174Y620200
+X-151256Y620200
+X-152337Y620200
+X-153419Y620200
+X-154500Y621283
+X-154500Y622366
+X-156356Y622185
+X-157439Y622185
+X-158522Y622185
+X-159604Y622185
+X-165093Y623449
+X-164011Y622366
+X-164011Y621283
+X-165093Y620200
+X-166174Y620200
+X-167256Y620200
+X-168337Y620200
+X-169419Y620200
+X-170500Y620200
+X-167256Y621283
+X-167256Y622366
+X-166174Y623449
+X-167256Y623449
+X-168337Y623449
+X-169419Y623449
+X-170500Y623449
+X-173093Y623449
+X-172011Y622366
+X-172011Y621283
+X-173093Y620200
+X-174174Y620200
+X-175256Y621283
+X-175256Y622366
+X-176337Y623449
+X-177419Y623449
+X-178500Y623449
+X-178500Y622366
+X-178500Y621283
+X-178500Y620200
+X-161338Y605000
+X-159663Y605000
+X-145050Y588700
+X-155950Y588700
+X-159050Y588700
+X-169950Y588700
+X-173050Y588700
+X-183950Y588700
+X-187050Y588700
+X-187663Y605000
+X-189338Y605000
+X-197950Y588700
+X-237000Y621000
+X-242000Y621000
+X-247000Y621000
+X-254000Y623500
+X046464Y622500
+T05
+X-013500Y057900
+X-013500Y059900
+X-013500Y061900
+X-013500Y063900
+X-013500Y065900
+X-013500Y067900
+X-013500Y069900
+X-013500Y071900
+X-013500Y073900
+X-013500Y075900
+X-008500Y075900
+X-008500Y073900
+X-008500Y071900
+X-008500Y069900
+X-008500Y067900
+X-008500Y065900
+X-008500Y063900
+X-008500Y061900
+X-008500Y059900
+X-008500Y057900
+X007700Y056450
+X007700Y063950
+X007700Y178450
+X007700Y185950
+X-008500Y191900
+X-008500Y189900
+X-008500Y187900
+X-008500Y185900
+X-008500Y183900
+X-008500Y181900
+X-008500Y179900
+X-013500Y179900
+X-013500Y181900
+X-013500Y183900
+X-013500Y185900
+X-013500Y187900
+X-013500Y189900
+X-013500Y191900
+X-013500Y193900
+X-013500Y195900
+X-013500Y197900
+X-008500Y193900
+X-008500Y195900
+X-008500Y197900
+X-013500Y301900
+X-013500Y303900
+X-013500Y305900
+X-013500Y307900
+X-013500Y309900
+X-013500Y311900
+X-013500Y313900
+X-013500Y315900
+X-013500Y317900
+X-013500Y319900
+X-008500Y319900
+X-008500Y317900
+X-008500Y315900
+X-008500Y313900
+X-008500Y311900
+X-008500Y309900
+X-008500Y307900
+X-008500Y305900
+X-008500Y303900
+X-008500Y301900
+X007700Y307950
+X007700Y300450
+X234500Y075900
+X234500Y073900
+X234500Y071900
+X234500Y069900
+X234500Y067900
+X234500Y065900
+X234500Y063900
+X234500Y061900
+X234500Y059900
+X234500Y057900
+X239500Y057900
+X239500Y059900
+X239500Y061900
+X239500Y063900
+X239500Y065900
+X239500Y067900
+X239500Y069900
+X239500Y071900
+X239500Y073900
+X239500Y075900
+X239500Y179900
+X239500Y181900
+X239500Y183900
+X239500Y185900
+X239500Y187900
+X239500Y189900
+X239500Y191900
+X239500Y193900
+X239500Y195900
+X239500Y197900
+X234500Y179900
+X234500Y181900
+X234500Y183900
+X234500Y185900
+X234500Y187900
+X234500Y189900
+X234500Y191900
+X234500Y193900
+X234500Y195900
+X234500Y197900
+X239500Y301900
+X239500Y303900
+X239500Y305900
+X239500Y307900
+X239500Y309900
+X239500Y311900
+X239500Y313900
+X239500Y315900
+X239500Y317900
+X239500Y319900
+X234500Y301900
+X234500Y303900
+X234500Y305900
+X234500Y307900
+X234500Y309900
+X234500Y311900
+X234500Y313900
+X234500Y315900
+X234500Y317900
+X234500Y319900
+X239500Y423900
+X239500Y425900
+X239500Y427900
+X239500Y429900
+X239500Y431900
+X239500Y433900
+X239500Y435900
+X239500Y437900
+X239500Y439900
+X239500Y441900
+X234500Y423900
+X234500Y425900
+X234500Y427900
+X234500Y429900
+X234500Y431900
+X234500Y433900
+X234500Y435900
+X234500Y437900
+X234500Y439900
+X234500Y441900
+X239500Y545900
+X239500Y547900
+X239500Y549900
+X239500Y551900
+X239500Y553900
+X239500Y555900
+X239500Y557900
+X239500Y559900
+X239500Y561900
+X239500Y563900
+X234500Y563900
+X234500Y561900
+X234500Y559900
+X234500Y557900
+X234500Y555900
+X234500Y553900
+X234500Y551900
+X234500Y549900
+X234500Y547900
+X234500Y545900
+X007700Y422450
+X007700Y429950
+X-008500Y441900
+X-008500Y439900
+X-008500Y437900
+X-008500Y435900
+X-008500Y433900
+X-008500Y431900
+X-008500Y429900
+X-008500Y427900
+X-008500Y425900
+X-008500Y423900
+X-013500Y423900
+X-013500Y425900
+X-013500Y427900
+X-013500Y429900
+X-013500Y431900
+X-013500Y433900
+X-013500Y435900
+X-013500Y437900
+X-013500Y439900
+X-013500Y441900
+X007700Y544450
+X007700Y551950
+X-008500Y563900
+X-008500Y561900
+X-008500Y559900
+X-008500Y557900
+X-008500Y555900
+X-008500Y553900
+X-008500Y551900
+X-008500Y549900
+X-008500Y547900
+X-008500Y545900
+X-013500Y545900
+X-013500Y547900
+X-013500Y549900
+X-013500Y551900
+X-013500Y553900
+X-013500Y555900
+X-013500Y557900
+X-013500Y559900
+X-013500Y561900
+X-013500Y563900
+X-240300Y551950
+X-240300Y544450
+X-240300Y429950
+X-240300Y422450
+X-240300Y307950
+X-240300Y300450
+X-240300Y185950
+X-240300Y178450
+X-240300Y063950
+X-240300Y056450
+X050389Y622500
+T06
+X240000Y023400
+X240000Y025400
+X240000Y027400
+X240000Y029400
+X240000Y031400
+X240000Y033400
+X240000Y035400
+X240000Y037400
+X240000Y039400
+X240000Y041400
+X240000Y043400
+X240000Y045400
+X240000Y047400
+X240000Y049400
+X240000Y051400
+X232950Y056450
+X240000Y145400
+X240000Y147400
+X240000Y149400
+X240000Y151400
+X240000Y153400
+X240000Y155400
+X240000Y157400
+X240000Y159400
+X240000Y161400
+X240000Y163400
+X240000Y165400
+X240000Y167400
+X240000Y169400
+X240000Y171400
+X240000Y173400
+X232950Y178450
+X240000Y267400
+X240000Y269400
+X240000Y271400
+X240000Y273400
+X240000Y275400
+X240000Y277400
+X240000Y279400
+X240000Y281400
+X240000Y283400
+X240000Y285400
+X240000Y287400
+X240000Y289400
+X240000Y291400
+X240000Y293400
+X240000Y295400
+X232950Y300450
+X240000Y389400
+X240000Y391400
+X240000Y393400
+X240000Y395400
+X240000Y397400
+X240000Y399400
+X240000Y401400
+X240000Y403400
+X240000Y405400
+X240000Y407400
+X240000Y409400
+X240000Y411400
+X240000Y413400
+X240000Y415400
+X240000Y417400
+X232950Y422450
+X240000Y511400
+X240000Y513400
+X240000Y515400
+X240000Y517400
+X240000Y519400
+X240000Y521400
+X240000Y523400
+X240000Y525400
+X240000Y527400
+X240000Y529400
+X240000Y531400
+X240000Y533400
+X240000Y535400
+X240000Y537400
+X240000Y539400
+X232950Y544450
+X-008000Y539400
+X-015050Y544450
+X-008000Y537400
+X-008000Y535400
+X-008000Y533400
+X-008000Y531400
+X-008000Y529400
+X-008000Y527400
+X-008000Y525400
+X-008000Y523400
+X-008000Y521400
+X-008000Y519400
+X-008000Y517400
+X-008000Y515400
+X-008000Y513400
+X-008000Y511400
+X-015050Y422450
+X-008000Y417400
+X-008000Y415400
+X-008000Y413400
+X-008000Y411400
+X-008000Y409400
+X-008000Y407400
+X-008000Y405400
+X-008000Y403400
+X-008000Y401400
+X-008000Y399400
+X-008000Y397400
+X-008000Y395400
+X-008000Y393400
+X-008000Y391400
+X-008000Y389400
+X-015050Y300450
+X-008000Y295400
+X-008000Y293400
+X-008000Y291400
+X-008000Y289400
+X-008000Y287400
+X-008000Y285400
+X-008000Y283400
+X-008000Y281400
+X-008000Y279400
+X-008000Y277400
+X-008000Y275400
+X-008000Y273400
+X-008000Y271400
+X-008000Y269400
+X-008000Y267400
+X-015050Y178450
+X-008000Y173400
+X-008000Y171400
+X-008000Y169400
+X-008000Y167400
+X-008000Y165400
+X-008000Y163400
+X-008000Y161400
+X-008000Y159400
+X-008000Y157400
+X-008000Y155400
+X-008000Y153400
+X-008000Y151400
+X-008000Y149400
+X-008000Y147400
+X-008000Y145400
+X-015050Y056450
+X-008000Y051400
+X-008000Y049400
+X-008000Y047400
+X-008000Y045400
+X-008000Y043400
+X-008000Y041400
+X-008000Y039400
+X-008000Y037400
+X-008000Y035400
+X-008000Y033400
+X-008000Y031400
+X-008000Y029400
+X-008000Y027400
+X-008000Y025400
+X-008000Y023400
+X054489Y622500
+T07
+X241015Y610931
+X242000Y612638
+X242985Y610931
+X242000Y502638
+X242985Y500931
+X241015Y500931
+X242000Y490638
+X242985Y488931
+X241015Y488931
+X242000Y380638
+X242985Y378931
+X241015Y378931
+X242000Y368638
+X242985Y366931
+X241015Y366931
+X242000Y258638
+X241015Y256931
+X242985Y256931
+X242000Y246638
+X241015Y244931
+X242985Y244931
+X242000Y136638
+X242985Y134931
+X241015Y134931
+X242000Y124638
+X242985Y122931
+X241015Y122931
+X242000Y014638
+X242985Y012931
+X241015Y012931
+X124985Y012931
+X123015Y012931
+X124000Y014638
+X123015Y122931
+X124985Y122931
+X124000Y124638
+X123015Y134931
+X124985Y134931
+X124000Y136638
+X124985Y244931
+X123015Y244931
+X124000Y246638
+X124985Y256931
+X123015Y256931
+X124000Y258638
+X123015Y366931
+X124985Y366931
+X124000Y368638
+X124985Y378931
+X124000Y380638
+X123015Y378931
+X006985Y378931
+X006000Y380638
+X005015Y378931
+X-005015Y378931
+X-006000Y380638
+X-006985Y378931
+X-006000Y368638
+X-006985Y366931
+X-005015Y366931
+X005015Y366931
+X006000Y368638
+X006985Y366931
+X-006000Y258638
+X-006985Y256931
+X-005015Y256931
+X005015Y256931
+X006000Y258638
+X006985Y256931
+X006000Y246638
+X006985Y244931
+X005015Y244931
+X-005015Y244931
+X-006000Y246638
+X-006985Y244931
+X-006000Y136638
+X-006985Y134931
+X-005015Y134931
+X005015Y134931
+X006000Y136638
+X006985Y134931
+X006000Y124638
+X006985Y122931
+X005015Y122931
+X-005015Y122931
+X-006000Y124638
+X-006985Y122931
+X006000Y014638
+X006985Y012931
+X005015Y012931
+X-005015Y012931
+X-006985Y012931
+X-006000Y014638
+X-123015Y012931
+X-124985Y012931
+X-124000Y014638
+X-124985Y122931
+X-123015Y122931
+X-124000Y124638
+X-123015Y134931
+X-124000Y136638
+X-124985Y134931
+X-241015Y012931
+X-242985Y012931
+X-242000Y014638
+X-242985Y122931
+X-241015Y122931
+X-242000Y124638
+X-241015Y134931
+X-242985Y134931
+X-242000Y136638
+X-124985Y244931
+X-123015Y244931
+X-124000Y246638
+X-123015Y256931
+X-124000Y258638
+X-124985Y256931
+X-241015Y244931
+X-242985Y244931
+X-242000Y246638
+X-242985Y256931
+X-241015Y256931
+X-242000Y258638
+X-242985Y366931
+X-241015Y366931
+X-242000Y368638
+X-242985Y378931
+X-242000Y380638
+X-241015Y378931
+X-124985Y366931
+X-123015Y366931
+X-124000Y368638
+X-124985Y378931
+X-123015Y378931
+X-124000Y380638
+X-123015Y488931
+X-124985Y488931
+X-124000Y490638
+X-123015Y500931
+X-124000Y502638
+X-124985Y500931
+X-241015Y488931
+X-242985Y488931
+X-242000Y490638
+X-242985Y500931
+X-241015Y500931
+X-242000Y502638
+X-242985Y610931
+X-242000Y612638
+X-241015Y610931
+X-124985Y610931
+X-124000Y612638
+X-123015Y610931
+X-006985Y610931
+X-006000Y612638
+X-005015Y610931
+X005015Y610931
+X006000Y612638
+X006985Y610931
+X006000Y502638
+X006985Y500931
+X005015Y500931
+X-006000Y502638
+X-006985Y500931
+X-005015Y500931
+X-006000Y490638
+X-006985Y488931
+X-005015Y488931
+X005015Y488931
+X006000Y490638
+X006985Y488931
+X123015Y488931
+X124985Y488931
+X124000Y490638
+X124985Y500931
+X123015Y500931
+X124000Y502638
+X124985Y610931
+X124000Y612638
+X123015Y610931
+X113170Y622015
+X113170Y623985
+X114876Y623000
+X058664Y622500
+T08
+X-234800Y201340
+X-224640Y201340
+X-217000Y188950
+X-223000Y188950
+X-223000Y181450
+X-217000Y181450
+X-216900Y174250
+X-216900Y167250
+X-237900Y174250
+X-237900Y167250
+X-182500Y103150
+X-182500Y098150
+X-188900Y098150
+X-188900Y103150
+X-196500Y103150
+X-196500Y098150
+X-196500Y078150
+X-217000Y066950
+X-224640Y079340
+X-234800Y079340
+X-223000Y066950
+X-223000Y059450
+X-237900Y052250
+X-237900Y045250
+X-216900Y045250
+X-216900Y052250
+X-217000Y059450
+X-188900Y078150
+X-182500Y078150
+X-174900Y078150
+X-168500Y078150
+X-160900Y078150
+X-154500Y078150
+X-146900Y078150
+X-168500Y098150
+X-174900Y098150
+X-174900Y103150
+X-168500Y103150
+X-160900Y103150
+X-160900Y098150
+X-154500Y098150
+X-154500Y103150
+X-146900Y098150
+X-146900Y103150
+X-113800Y078150
+X-099800Y078150
+X-092200Y078150
+X-106200Y078150
+X-136300Y050050
+X-136300Y043050
+X-128600Y043050
+X-128600Y050050
+X-120900Y050050
+X-120900Y043050
+X-113200Y043050
+X-113200Y050050
+X-105500Y050050
+X-105500Y043050
+X-063850Y030100
+X-063850Y035100
+X-071300Y078150
+X-063700Y078150
+X-049600Y098250
+X-049600Y105250
+X-063700Y103150
+X-063700Y098150
+X-071300Y098150
+X-071300Y103150
+X-092200Y103150
+X-092200Y098150
+X-099800Y098150
+X-099800Y103150
+X-106200Y103150
+X-106200Y098150
+X-113800Y098150
+X-113800Y103150
+X-063850Y157100
+X-063850Y152100
+X-041900Y105250
+X-041900Y098250
+X-034200Y105250
+X-034200Y098250
+X-026500Y105250
+X-026500Y098250
+X010100Y052250
+X010100Y045250
+X031100Y045250
+X031100Y052250
+X031000Y059450
+X025000Y059450
+X025000Y066950
+X031000Y066950
+X023360Y079340
+X013200Y079340
+X-005150Y098250
+X-014150Y102900
+X-005150Y105250
+X010100Y167250
+X010100Y174250
+X031100Y167250
+X031100Y174250
+X025000Y181450
+X031000Y181450
+X031000Y188950
+X025000Y188950
+X023360Y201340
+X013200Y201340
+X-005150Y220250
+X-005150Y227250
+X-014150Y224900
+X-026500Y220250
+X-026500Y227250
+X-034200Y227250
+X-034200Y220250
+X-041900Y220250
+X-041900Y227250
+X-049600Y227250
+X-049600Y220250
+X-063700Y220150
+X-063700Y225150
+X-071300Y225150
+X-071300Y220150
+X-063700Y200150
+X-071300Y200150
+X-092200Y220150
+X-092200Y225150
+X-099800Y220150
+X-099800Y225150
+X-106200Y220150
+X-106200Y225150
+X-113800Y225150
+X-113800Y220150
+X-113800Y200150
+X-106200Y200150
+X-099800Y200150
+X-092200Y200150
+X-105500Y172050
+X-105500Y165050
+X-113200Y172050
+X-113200Y165050
+X-120900Y165050
+X-120900Y172050
+X-128600Y172050
+X-128600Y165050
+X-136300Y165050
+X-136300Y172050
+X-160900Y200150
+X-154500Y200150
+X-146900Y200150
+X-146900Y220150
+X-146900Y225150
+X-154500Y220150
+X-154500Y225150
+X-160900Y225150
+X-160900Y220150
+X-168500Y225150
+X-168500Y220150
+X-174900Y225150
+X-174900Y220150
+X-182500Y225150
+X-182500Y220150
+X-188900Y220150
+X-168500Y200150
+X-174900Y200150
+X-182500Y200150
+X-188900Y200150
+X-196500Y200150
+X-196500Y220150
+X-196500Y225150
+X-188900Y225150
+X-216900Y289250
+X-216900Y296250
+X-223000Y303450
+X-217000Y303450
+X-196500Y322150
+X-188900Y322150
+X-182500Y322150
+X-174900Y322150
+X-168500Y322150
+X-168500Y342150
+X-174900Y342150
+X-174900Y347150
+X-168500Y347150
+X-160900Y342150
+X-160900Y347150
+X-154500Y342150
+X-154500Y347150
+X-146900Y347150
+X-146900Y342150
+X-160900Y322150
+X-154500Y322150
+X-146900Y322150
+X-136300Y294050
+X-136300Y287050
+X-128600Y294050
+X-128600Y287050
+X-120900Y294050
+X-120900Y287050
+X-113200Y287050
+X-113200Y294050
+X-105500Y294050
+X-105500Y287050
+X-063850Y274100
+X-063850Y279100
+X-063700Y322150
+X-071300Y322150
+X-063700Y342150
+X-063700Y347150
+X-071300Y347150
+X-071300Y342150
+X-092200Y322150
+X-099800Y322150
+X-106200Y322150
+X-113800Y322150
+X-092200Y342150
+X-092200Y347150
+X-099800Y342150
+X-099800Y347150
+X-106200Y347150
+X-106200Y342150
+X-113800Y342150
+X-113800Y347150
+X-136300Y409050
+X-136300Y416050
+X-128600Y416050
+X-128600Y409050
+X-120900Y409050
+X-120900Y416050
+X-113200Y416050
+X-113200Y409050
+X-105500Y409050
+X-105500Y416050
+X-063850Y401100
+X-063850Y396100
+X-014150Y346900
+X-005150Y349250
+X-005150Y342250
+X-026500Y349250
+X-026500Y342250
+X-034200Y349250
+X-041900Y349250
+X-049600Y349250
+X-049600Y342250
+X-041900Y342250
+X-034200Y342250
+X010100Y296250
+X010100Y289250
+X025000Y303450
+X013200Y323340
+X023360Y323340
+X025000Y310950
+X031000Y310950
+X031000Y303450
+X051500Y322150
+X051500Y342150
+X051500Y347150
+X059100Y347150
+X059100Y342150
+X065500Y342150
+X065500Y347150
+X073100Y347150
+X073100Y342150
+X079500Y342150
+X079500Y347150
+X087100Y342150
+X087100Y347150
+X093500Y347150
+X093500Y342150
+X101100Y347150
+X101100Y342150
+X101100Y322150
+X093500Y322150
+X087100Y322150
+X079500Y322150
+X073100Y322150
+X065500Y322150
+X059100Y322150
+X031100Y296250
+X031100Y289250
+X093500Y225150
+X101100Y225150
+X101100Y220150
+X093500Y220150
+X087100Y225150
+X087100Y220150
+X079500Y220150
+X079500Y225150
+X073100Y220150
+X073100Y225150
+X065500Y225150
+X065500Y220150
+X059100Y220150
+X059100Y225150
+X051500Y225150
+X051500Y220150
+X051500Y200150
+X059100Y200150
+X065500Y200150
+X073100Y200150
+X079500Y200150
+X087100Y200150
+X093500Y200150
+X101100Y200150
+X111700Y172050
+X111700Y165050
+X119400Y165050
+X119400Y172050
+X127100Y172050
+X127100Y165050
+X134800Y165050
+X134800Y172050
+X142500Y172050
+X142500Y165050
+X101100Y103150
+X101100Y098150
+X093500Y098150
+X093500Y103150
+X087100Y103150
+X087100Y098150
+X079500Y098150
+X079500Y103150
+X073100Y103150
+X073100Y098150
+X065500Y098150
+X065500Y103150
+X059100Y103150
+X059100Y098150
+X051500Y103150
+X051500Y098150
+X051500Y078150
+X059100Y078150
+X065500Y078150
+X073100Y078150
+X079500Y078150
+X087100Y078150
+X093500Y078150
+X101100Y078150
+X134200Y103150
+X134200Y098150
+X141800Y103150
+X141800Y098150
+X148200Y098150
+X148200Y103150
+X155800Y103150
+X155800Y098150
+X155800Y078150
+X148200Y078150
+X141800Y078150
+X134200Y078150
+X134800Y050050
+X127100Y050050
+X119400Y050050
+X111700Y050050
+X111700Y043050
+X119400Y043050
+X127100Y043050
+X134800Y043050
+X142500Y043050
+X142500Y050050
+X184150Y030100
+X184150Y035100
+X176700Y078150
+X184300Y078150
+X184300Y098150
+X176700Y098150
+X176700Y103150
+X184300Y103150
+X198400Y098250
+X198400Y105250
+X206100Y105250
+X206100Y098250
+X213800Y098250
+X213800Y105250
+X221500Y105250
+X221500Y098250
+X233850Y102900
+X242850Y105250
+X242850Y098250
+X184150Y152100
+X184150Y157100
+X155800Y200150
+X148200Y200150
+X141800Y200150
+X134200Y200150
+X134200Y220150
+X134200Y225150
+X141800Y220150
+X141800Y225150
+X148200Y225150
+X148200Y220150
+X155800Y220150
+X155800Y225150
+X176700Y225150
+X176700Y220150
+X184300Y225150
+X184300Y220150
+X176700Y200150
+X184300Y200150
+X198400Y220250
+X198400Y227250
+X206100Y227250
+X206100Y220250
+X213800Y220250
+X213800Y227250
+X221500Y227250
+X221500Y220250
+X233850Y224900
+X242850Y227250
+X242850Y220250
+X184150Y274100
+X184150Y279100
+X142500Y294050
+X142500Y287050
+X134800Y287050
+X134800Y294050
+X127100Y294050
+X127100Y287050
+X119400Y287050
+X119400Y294050
+X111700Y287050
+X111700Y294050
+X134200Y322150
+X134200Y342150
+X134200Y347150
+X141800Y347150
+X141800Y342150
+X148200Y347150
+X148200Y342150
+X155800Y347150
+X155800Y342150
+X141800Y322150
+X148200Y322150
+X155800Y322150
+X176700Y322150
+X184300Y322150
+X176700Y342150
+X176700Y347150
+X184300Y342150
+X184300Y347150
+X198400Y349250
+X198400Y342250
+X206100Y349250
+X206100Y342250
+X213800Y342250
+X213800Y349250
+X221500Y349250
+X221500Y342250
+X233850Y346900
+X242850Y349250
+X242850Y342250
+X184150Y396100
+X184150Y401100
+X142500Y409050
+X142500Y416050
+X134800Y409050
+X134800Y416050
+X127100Y416050
+X127100Y409050
+X119400Y416050
+X119400Y409050
+X111700Y409050
+X111700Y416050
+X134200Y444150
+X141800Y444150
+X148200Y444150
+X155800Y444150
+X176700Y444150
+X184300Y444150
+X198400Y464250
+X206100Y464250
+X213800Y464250
+X221500Y464250
+X242850Y471250
+X242850Y464250
+X233850Y468900
+X221500Y471250
+X213800Y471250
+X206100Y471250
+X198400Y471250
+X184300Y464150
+X184300Y469150
+X176700Y469150
+X176700Y464150
+X155800Y464150
+X155800Y469150
+X148200Y464150
+X148200Y469150
+X141800Y469150
+X141800Y464150
+X134200Y464150
+X134200Y469150
+X184150Y518100
+X184150Y523100
+X242850Y586250
+X242850Y593250
+X233850Y590900
+X221500Y593250
+X221500Y586250
+X213800Y586250
+X213800Y593250
+X206100Y593250
+X206100Y586250
+X198400Y586250
+X198400Y593250
+X184300Y591150
+X184300Y586150
+X176700Y591150
+X176700Y586150
+X184300Y566150
+X176700Y566150
+X155800Y566150
+X148200Y566150
+X141800Y566150
+X134200Y566150
+X155800Y586150
+X155800Y591150
+X148200Y591150
+X148200Y586150
+X141800Y586150
+X141800Y591150
+X134200Y591150
+X134200Y586150
+X101100Y586150
+X101100Y591150
+X093500Y586150
+X093500Y591150
+X087100Y591150
+X087100Y586150
+X079500Y591150
+X079500Y586150
+X073100Y591150
+X073100Y586150
+X065500Y591150
+X065500Y586150
+X059100Y586150
+X059100Y591150
+X051500Y591150
+X051500Y586150
+X051500Y566150
+X059100Y566150
+X065500Y566150
+X073100Y566150
+X079500Y566150
+X087100Y566150
+X093500Y566150
+X101100Y566150
+X134800Y538050
+X142500Y538050
+X142500Y531050
+X134800Y531050
+X127100Y531050
+X127100Y538050
+X119400Y538050
+X119400Y531050
+X111700Y538050
+X111700Y531050
+X051500Y469150
+X051500Y464150
+X059100Y464150
+X059100Y469150
+X065500Y469150
+X065500Y464150
+X073100Y464150
+X073100Y469150
+X079500Y464150
+X079500Y469150
+X087100Y469150
+X087100Y464150
+X093500Y464150
+X093500Y469150
+X101100Y469150
+X101100Y464150
+X101100Y444150
+X093500Y444150
+X087100Y444150
+X079500Y444150
+X073100Y444150
+X065500Y444150
+X059100Y444150
+X051500Y444150
+X031000Y425450
+X025000Y425450
+X031100Y418250
+X031100Y411250
+X010100Y411250
+X010100Y418250
+X025000Y432950
+X031000Y432950
+X023360Y445340
+X013200Y445340
+X-005150Y464250
+X-005150Y471250
+X-014150Y468900
+X-026500Y471250
+X-026500Y464250
+X-034200Y464250
+X-034200Y471250
+X-041900Y471250
+X-041900Y464250
+X-049600Y471250
+X-049600Y464250
+X-063700Y464150
+X-063700Y469150
+X-071300Y469150
+X-071300Y464150
+X-063700Y444150
+X-071300Y444150
+X-092200Y444150
+X-099800Y444150
+X-106200Y444150
+X-113800Y444150
+X-113800Y464150
+X-113800Y469150
+X-106200Y469150
+X-106200Y464150
+X-099800Y469150
+X-099800Y464150
+X-092200Y464150
+X-092200Y469150
+X-063850Y518100
+X-063850Y523100
+X-105500Y531050
+X-105500Y538050
+X-113200Y538050
+X-113200Y531050
+X-120900Y531050
+X-120900Y538050
+X-128600Y538050
+X-128600Y531050
+X-136300Y531050
+X-136300Y538050
+X-113800Y566150
+X-106200Y566150
+X-099800Y566150
+X-092200Y566150
+X-071300Y566150
+X-063700Y566150
+X-049600Y586250
+X-041900Y593250
+X-034200Y593250
+X-026500Y593250
+X-026500Y586250
+X-014150Y590900
+X-005150Y593250
+X-005150Y586250
+X013200Y567340
+X023360Y567340
+X025000Y554950
+X031000Y554950
+X031000Y547450
+X025000Y547450
+X031100Y540250
+X031100Y533250
+X010100Y533250
+X010100Y540250
+X-034200Y586250
+X-041900Y586250
+X-049600Y593250
+X-063700Y591150
+X-063700Y586150
+X-071300Y586150
+X-071300Y591150
+X-092200Y586150
+X-092200Y591150
+X-099800Y591150
+X-099800Y586150
+X-106200Y586150
+X-106200Y591150
+X-113800Y586150
+X-113800Y591150
+X-146900Y591150
+X-146900Y586150
+X-154500Y591150
+X-154500Y586150
+X-160900Y591150
+X-160900Y586150
+X-146900Y566150
+X-154500Y566150
+X-160900Y566150
+X-168500Y566150
+X-174900Y566150
+X-168500Y586150
+X-168500Y591150
+X-174900Y586150
+X-174900Y591150
+X-182500Y591150
+X-182500Y586150
+X-188900Y586150
+X-188900Y591150
+X-196500Y591150
+X-196500Y586150
+X-182500Y566150
+X-188900Y566150
+X-196500Y566150
+X-217000Y554950
+X-224640Y567340
+X-234800Y567340
+X-223000Y554950
+X-217000Y547450
+X-223000Y547450
+X-216900Y540250
+X-216900Y533250
+X-237900Y540250
+X-237900Y533250
+X-196500Y469150
+X-196500Y464150
+X-188900Y464150
+X-188900Y469150
+X-182500Y469150
+X-182500Y464150
+X-174900Y464150
+X-174900Y469150
+X-168500Y464150
+X-168500Y469150
+X-160900Y469150
+X-160900Y464150
+X-154500Y469150
+X-154500Y464150
+X-146900Y469150
+X-146900Y464150
+X-146900Y444150
+X-154500Y444150
+X-160900Y444150
+X-168500Y444150
+X-174900Y444150
+X-182500Y444150
+X-188900Y444150
+X-196500Y444150
+X-224640Y445340
+X-234800Y445340
+X-223000Y432950
+X-217000Y432950
+X-223000Y425450
+X-217000Y425450
+X-216900Y418250
+X-216900Y411250
+X-237900Y418250
+X-237900Y411250
+X-188900Y347150
+X-182500Y347150
+X-182500Y342150
+X-188900Y342150
+X-196500Y342150
+X-196500Y347150
+X-224640Y323340
+X-234800Y323340
+X-217000Y310950
+X-223000Y310950
+X-237900Y296250
+X-237900Y289250
+X062889Y622500
+T09
+X-141000Y153550
+X-136300Y153550
+X-133300Y153550
+X-128600Y153550
+X-125600Y153550
+X-120900Y153550
+X-117900Y153550
+X-113200Y153550
+X-110200Y153550
+X-105500Y153550
+X-054300Y208750
+X-049600Y208750
+X-046600Y208750
+X-041900Y208750
+X-038900Y208750
+X-034200Y208750
+X-031200Y208750
+X-026500Y208750
+X-018850Y213400
+X-014150Y213400
+X-009850Y208750
+X-005150Y208750
+X031100Y155750
+X026400Y155750
+X010100Y155750
+X005400Y155750
+X-054300Y086750
+X-049600Y086750
+X-046600Y086750
+X-041900Y086750
+X-038900Y086750
+X-034200Y086750
+X-031200Y086750
+X-026500Y086750
+X-018850Y091400
+X-014150Y091400
+X-009850Y086750
+X-005150Y086750
+X005400Y033750
+X010100Y033750
+X026400Y033750
+X031100Y033750
+X107000Y031550
+X111700Y031550
+X114700Y031550
+X119400Y031550
+X122400Y031550
+X127100Y031550
+X130100Y031550
+X134800Y031550
+X137800Y031550
+X142500Y031550
+X193700Y086750
+X198400Y086750
+X201400Y086750
+X206100Y086750
+X209100Y086750
+X216800Y086750
+X221500Y086750
+X229150Y091400
+X233850Y091400
+X242850Y086750
+X238150Y086750
+X213800Y086750
+X142500Y153550
+X134800Y153550
+X130100Y153550
+X122400Y153550
+X111700Y153550
+X107000Y153550
+X114700Y153550
+X119400Y153550
+X127100Y153550
+X137800Y153550
+X193700Y208750
+X198400Y208750
+X201400Y208750
+X206100Y208750
+X209100Y208750
+X213800Y208750
+X216800Y208750
+X221500Y208750
+X229150Y213400
+X238150Y208750
+X242850Y208750
+X233850Y213400
+X142500Y275550
+X137800Y275550
+X134800Y275550
+X130100Y275550
+X127100Y275550
+X122400Y275550
+X119400Y275550
+X114700Y275550
+X111700Y275550
+X107000Y275550
+X031100Y277750
+X026400Y277750
+X010100Y277750
+X005400Y277750
+X107000Y397550
+X111700Y397550
+X114700Y397550
+X119400Y397550
+X122400Y397550
+X127100Y397550
+X130100Y397550
+X134800Y397550
+X137800Y397550
+X142500Y397550
+X193700Y330750
+X198400Y330750
+X201400Y330750
+X206100Y330750
+X209100Y330750
+X213800Y330750
+X216800Y330750
+X221500Y330750
+X229150Y335400
+X233850Y335400
+X238150Y330750
+X242850Y330750
+X242850Y452750
+X238150Y452750
+X233850Y457400
+X229150Y457400
+X221500Y452750
+X216800Y452750
+X213800Y452750
+X209100Y452750
+X206100Y452750
+X201400Y452750
+X198400Y452750
+X193700Y452750
+X242850Y574750
+X238150Y574750
+X233850Y579400
+X229150Y579400
+X221500Y574750
+X216800Y574750
+X213800Y574750
+X209100Y574750
+X206100Y574750
+X201400Y574750
+X198400Y574750
+X193700Y574750
+X142500Y519550
+X137800Y519550
+X134800Y519550
+X130100Y519550
+X127100Y519550
+X122400Y519550
+X119400Y519550
+X114700Y519550
+X111700Y519550
+X107000Y519550
+X031100Y521750
+X026400Y521750
+X010100Y521750
+X005400Y521750
+X-005150Y574750
+X-009850Y574750
+X-014150Y579400
+X-018850Y579400
+X-026500Y574750
+X-031200Y574750
+X-034200Y574750
+X-038900Y574750
+X-041900Y574750
+X-046600Y574750
+X-049600Y574750
+X-054300Y574750
+X-105500Y519550
+X-110200Y519550
+X-113200Y519550
+X-117900Y519550
+X-120900Y519550
+X-125600Y519550
+X-128600Y519550
+X-133300Y519550
+X-136300Y519550
+X-141000Y519550
+X-216900Y521750
+X-221600Y521750
+X-237900Y521750
+X-242600Y521750
+X-242600Y399750
+X-237900Y399750
+X-221600Y399750
+X-216900Y399750
+X-141000Y397550
+X-136300Y397550
+X-133300Y397550
+X-128600Y397550
+X-125600Y397550
+X-120900Y397550
+X-117900Y397550
+X-113200Y397550
+X-110200Y397550
+X-105500Y397550
+X-054300Y452750
+X-049600Y452750
+X-046600Y452750
+X-041900Y452750
+X-038900Y452750
+X-034200Y452750
+X-031200Y452750
+X-026500Y452750
+X-018850Y457400
+X-014150Y457400
+X-009850Y452750
+X-005150Y452750
+X005400Y399750
+X010100Y399750
+X026400Y399750
+X031100Y399750
+X-005150Y330750
+X-009850Y330750
+X-014150Y335400
+X-018850Y335400
+X-026500Y330750
+X-031200Y330750
+X-034200Y330750
+X-038900Y330750
+X-041900Y330750
+X-046600Y330750
+X-049600Y330750
+X-054300Y330750
+X-105500Y275550
+X-110200Y275550
+X-113200Y275550
+X-117900Y275550
+X-120900Y275550
+X-125600Y275550
+X-128600Y275550
+X-133300Y275550
+X-136300Y275550
+X-141000Y275550
+X-216900Y277750
+X-221600Y277750
+X-237900Y277750
+X-242600Y277750
+X-216900Y155750
+X-221600Y155750
+X-237900Y155750
+X-242600Y155750
+X-242600Y033750
+X-237900Y033750
+X-221600Y033750
+X-216900Y033750
+X-105500Y031550
+X-110200Y031550
+X-113200Y031550
+X-117900Y031550
+X-120900Y031550
+X-125600Y031550
+X-128600Y031550
+X-133300Y031550
+X-136300Y031550
+X-141000Y031550
+X067189Y622500
+T10
+X-014150Y084900
+X-021750Y084900
+X-014150Y104900
+X-014150Y109900
+X-021750Y104900
+X-021750Y109900
+X-021750Y206900
+X-014150Y206900
+X-021750Y226900
+X-021750Y231900
+X-014150Y226900
+X-014150Y231900
+X-021750Y328900
+X-014150Y328900
+X-014150Y348900
+X-014150Y353900
+X-021750Y348900
+X-021750Y353900
+X-021750Y450900
+X-014150Y450900
+X-021750Y470900
+X-014150Y470900
+X-014150Y475900
+X-021750Y475900
+X-014150Y572900
+X-021750Y572900
+X-014150Y592900
+X-021750Y592900
+X-021750Y597900
+X-014150Y597900
+X226250Y592900
+X226250Y597900
+X233850Y597900
+X233850Y592900
+X233850Y572900
+X226250Y572900
+X233850Y475900
+X226250Y475900
+X226250Y470900
+X233850Y470900
+X226250Y450900
+X233850Y450900
+X233850Y353900
+X233850Y348900
+X226250Y353900
+X226250Y348900
+X233850Y328900
+X226250Y328900
+X233850Y231900
+X233850Y226900
+X226250Y231900
+X226250Y226900
+X226250Y206900
+X233850Y206900
+X226250Y109900
+X226250Y104900
+X233850Y109900
+X233850Y104900
+X233850Y084900
+X226250Y084900
+X071589Y622500
+T11
+X177500Y363540
+X177500Y358460
+X169500Y358460
+X169500Y363540
+X150500Y358460
+X150500Y363540
+X139500Y358360
+X139500Y363440
+X095900Y391400
+X088300Y391400
+X082700Y391400
+X075100Y391400
+X069500Y391400
+X061900Y391400
+X056300Y391400
+X048700Y391400
+X043100Y391400
+X035500Y391400
+X021900Y391400
+X014300Y391400
+X025800Y359840
+X025800Y354760
+X015800Y359840
+X015800Y354760
+X035500Y269400
+X021900Y269400
+X014300Y269400
+X015800Y237840
+X015800Y232760
+X025800Y232760
+X025800Y237840
+X043100Y269400
+X048700Y269400
+X056300Y269400
+X061900Y269400
+X069500Y269400
+X075100Y269400
+X082700Y269400
+X088300Y269400
+X095900Y269400
+X139500Y236360
+X139500Y241440
+X150500Y236460
+X150500Y241540
+X169500Y236460
+X169500Y241540
+X177500Y241540
+X177500Y236460
+X177500Y119540
+X177500Y114460
+X169500Y119540
+X169500Y114460
+X150500Y114460
+X150500Y119540
+X139500Y114360
+X139500Y119440
+X095900Y147400
+X088300Y147400
+X082700Y147400
+X075100Y147400
+X069500Y147400
+X061900Y147400
+X056300Y147400
+X048700Y147400
+X043100Y147400
+X035500Y147400
+X021900Y147400
+X014300Y147400
+X015800Y115840
+X015800Y110760
+X025800Y115840
+X025800Y110760
+X095900Y025400
+X088300Y025400
+X082700Y025400
+X075100Y025400
+X069500Y025400
+X061900Y025400
+X056300Y025400
+X048700Y025400
+X043100Y025400
+X035500Y025400
+X021900Y025400
+X014300Y025400
+X-070500Y114460
+X-070500Y119540
+X-078500Y119540
+X-078500Y114460
+X-097500Y119540
+X-097500Y114460
+X-108500Y119440
+X-108500Y114360
+X-152100Y025400
+X-159700Y025400
+X-165300Y025400
+X-172900Y025400
+X-178500Y025400
+X-186100Y025400
+X-191700Y025400
+X-199300Y025400
+X-204900Y025400
+X-212500Y025400
+X-226100Y025400
+X-233700Y025400
+X-232200Y110760
+X-232200Y115840
+X-222200Y110760
+X-222200Y115840
+X-233700Y147400
+X-226100Y147400
+X-212500Y147400
+X-204900Y147400
+X-199300Y147400
+X-191700Y147400
+X-186100Y147400
+X-178500Y147400
+X-172900Y147400
+X-165300Y147400
+X-159700Y147400
+X-152100Y147400
+X-222200Y232760
+X-222200Y237840
+X-232200Y232760
+X-232200Y237840
+X-233700Y269400
+X-226100Y269400
+X-212500Y269400
+X-204900Y269400
+X-199300Y269400
+X-191700Y269400
+X-186100Y269400
+X-178500Y269400
+X-172900Y269400
+X-165300Y269400
+X-159700Y269400
+X-152100Y269400
+X-108500Y236360
+X-097500Y236460
+X-078500Y241540
+X-070500Y241540
+X-070500Y236460
+X-078500Y236460
+X-097500Y241540
+X-108500Y241440
+X-222200Y354760
+X-222200Y359840
+X-232200Y354760
+X-232200Y359840
+X-233700Y391400
+X-226100Y391400
+X-212500Y391400
+X-204900Y391400
+X-199300Y391400
+X-191700Y391400
+X-186100Y391400
+X-178500Y391400
+X-172900Y391400
+X-165300Y391400
+X-159700Y391400
+X-152100Y391400
+X-108500Y358360
+X-108500Y363440
+X-097500Y363540
+X-097500Y358460
+X-078500Y358460
+X-078500Y363540
+X-070500Y358460
+X-070500Y363540
+X-070500Y480460
+X-070500Y485540
+X-078500Y485540
+X-078500Y480460
+X-097500Y480460
+X-097500Y485540
+X-108500Y485440
+X-108500Y480360
+X-152100Y513400
+X-159700Y513400
+X-165300Y513400
+X-172900Y513400
+X-178500Y513400
+X-186100Y513400
+X-191700Y513400
+X-199300Y513400
+X-204900Y513400
+X-212500Y513400
+X-222200Y481840
+X-222200Y476760
+X-232200Y476760
+X-232200Y481840
+X-226100Y513400
+X-233700Y513400
+X-232200Y598760
+X-232200Y603840
+X-222200Y598760
+X-222200Y603840
+X-108500Y607440
+X-108500Y602360
+X-097500Y607540
+X-097500Y602460
+X-078500Y602460
+X-078500Y607540
+X-070500Y607540
+X-070500Y602460
+X015800Y603840
+X015800Y598760
+X025800Y598760
+X025800Y603840
+X139500Y602360
+X139500Y607440
+X150500Y607540
+X169500Y602460
+X177500Y607540
+X177500Y602460
+X169500Y607540
+X150500Y602460
+X056300Y513400
+X048700Y513400
+X043100Y513400
+X035500Y513400
+X021900Y513400
+X014300Y513400
+X015800Y481840
+X015800Y476760
+X025800Y476760
+X025800Y481840
+X061900Y513400
+X069500Y513400
+X075100Y513400
+X082700Y513400
+X088300Y513400
+X095900Y513400
+X139500Y480360
+X139500Y485440
+X150500Y485540
+X150500Y480460
+X169500Y480460
+X169500Y485540
+X177500Y485540
+X177500Y480460
+X076089Y622500
+T12
+X014300Y533400
+X021900Y536900
+X035500Y533400
+X043100Y536900
+X048700Y533400
+X056300Y536900
+X061900Y533400
+X069500Y536900
+X075100Y533400
+X082700Y536900
+X088300Y533400
+X095900Y536900
+X095900Y414900
+X088300Y411400
+X082700Y414900
+X075100Y411400
+X069500Y414900
+X061900Y411400
+X056300Y414900
+X048700Y411400
+X043100Y414900
+X035500Y411400
+X021900Y414900
+X014300Y411400
+X095900Y292900
+X088300Y289400
+X082700Y292900
+X075100Y289400
+X069500Y292900
+X061900Y289400
+X056300Y292900
+X048700Y289400
+X043100Y292900
+X035500Y289400
+X021900Y292900
+X014300Y289400
+X095900Y170900
+X088300Y167400
+X082700Y170900
+X075100Y167400
+X069500Y170900
+X061900Y167400
+X056300Y170900
+X048700Y167400
+X043100Y170900
+X035500Y167400
+X021900Y170900
+X014300Y167400
+X095900Y048900
+X088300Y045400
+X082700Y048900
+X075100Y045400
+X069500Y048900
+X061900Y045400
+X056300Y048900
+X048700Y045400
+X043100Y048900
+X035500Y045400
+X021900Y048900
+X014300Y045400
+X-152100Y048900
+X-165300Y048900
+X-172900Y045400
+X-178500Y048900
+X-159700Y045400
+X-204900Y048900
+X-199300Y045400
+X-191700Y048900
+X-186100Y045400
+X-212500Y045400
+X-226100Y048900
+X-233700Y045400
+X-233700Y167400
+X-226100Y170900
+X-212500Y167400
+X-204900Y170900
+X-199300Y167400
+X-191700Y170900
+X-186100Y167400
+X-178500Y170900
+X-172900Y167400
+X-165300Y170900
+X-159700Y167400
+X-152100Y170900
+X-233700Y289400
+X-226100Y292900
+X-212500Y289400
+X-204900Y292900
+X-199300Y289400
+X-191700Y292900
+X-186100Y289400
+X-178500Y292900
+X-172900Y289400
+X-165300Y292900
+X-159700Y289400
+X-152100Y292900
+X-233700Y411400
+X-226100Y414900
+X-212500Y411400
+X-204900Y414900
+X-199300Y411400
+X-191700Y414900
+X-186100Y411400
+X-178500Y414900
+X-172900Y411400
+X-165300Y414900
+X-159700Y411400
+X-152100Y414900
+X-233700Y533400
+X-226100Y536900
+X-212500Y533400
+X-204900Y536900
+X-199300Y533400
+X-191700Y536900
+X-186100Y533400
+X-178500Y536900
+X-172900Y533400
+X-165300Y536900
+X-159700Y533400
+X-152100Y536900
+X080689Y622500
+T13
+X-026800Y159760
+X-026800Y155800
+X-026800Y151840
+X-054320Y119600
+X-046400Y119600
+X-038480Y119600
+X-031540Y119600
+X-027580Y119600
+X-023620Y119600
+X-019660Y119600
+X-026800Y037760
+X-026800Y033800
+X-026800Y029840
+X-120300Y065800
+X-124260Y065800
+X-128220Y065800
+X-132180Y065800
+X-136140Y065800
+X-140100Y065800
+X-140100Y187800
+X-136140Y187800
+X-132180Y187800
+X-128220Y187800
+X-124260Y187800
+X-120300Y187800
+X-054320Y241600
+X-046400Y241600
+X-038480Y241600
+X-031540Y241600
+X-027580Y241600
+X-023620Y241600
+X-019660Y241600
+X-026800Y273840
+X-026800Y277800
+X-026800Y281760
+X-120300Y309800
+X-124260Y309800
+X-128220Y309800
+X-132180Y309800
+X-136140Y309800
+X-140100Y309800
+X-054320Y363600
+X-046400Y363600
+X-038480Y363600
+X-031540Y363600
+X-027580Y363600
+X-023620Y363600
+X-019660Y363600
+X-026800Y395840
+X-026800Y399800
+X-026800Y403760
+X-120300Y431800
+X-124260Y431800
+X-128220Y431800
+X-132180Y431800
+X-136140Y431800
+X-140100Y431800
+X-140100Y553800
+X-136140Y553800
+X-132180Y553800
+X-128220Y553800
+X-124260Y553800
+X-120300Y553800
+X-054320Y607600
+X-046400Y607600
+X-038480Y607600
+X-031540Y607600
+X-027580Y607600
+X-023620Y607600
+X-019660Y607600
+X-026800Y525760
+X-026800Y521800
+X-026800Y517840
+X-054320Y485600
+X-046400Y485600
+X-038480Y485600
+X-031540Y485600
+X-027580Y485600
+X-023620Y485600
+X-019660Y485600
+X107900Y553800
+X111860Y553800
+X115820Y553800
+X119780Y553800
+X123740Y553800
+X127700Y553800
+X193680Y607600
+X201600Y607600
+X209520Y607600
+X216460Y607600
+X220420Y607600
+X224380Y607600
+X228340Y607600
+X221200Y525760
+X221200Y521800
+X221200Y517840
+X228340Y485600
+X224380Y485600
+X220420Y485600
+X216460Y485600
+X209520Y485600
+X201600Y485600
+X193680Y485600
+X127700Y431800
+X123740Y431800
+X119780Y431800
+X115820Y431800
+X107900Y431800
+X111860Y431800
+X193680Y363600
+X201600Y363600
+X209520Y363600
+X216460Y363600
+X220420Y363600
+X224380Y363600
+X228340Y363600
+X221200Y395840
+X221200Y399800
+X221200Y403760
+X107900Y309800
+X111860Y309800
+X115820Y309800
+X119780Y309800
+X123740Y309800
+X127700Y309800
+X221200Y281760
+X221200Y277800
+X221200Y273840
+X228340Y241600
+X224380Y241600
+X220420Y241600
+X216460Y241600
+X209520Y241600
+X201600Y241600
+X193680Y241600
+X127700Y187800
+X123740Y187800
+X119780Y187800
+X115820Y187800
+X107900Y187800
+X111860Y187800
+X221200Y159760
+X221200Y155800
+X221200Y151840
+X193680Y119600
+X201600Y119600
+X209520Y119600
+X216460Y119600
+X220420Y119600
+X224380Y119600
+X228340Y119600
+X221200Y037760
+X221200Y033800
+X221200Y029840
+X127700Y065800
+X123740Y065800
+X119780Y065800
+X115820Y065800
+X111860Y065800
+X107900Y065800
+X085489Y622500
+T14
+X042300Y114500
+X042300Y119500
+X053300Y119500
+X053300Y114500
+X070300Y114500
+X070300Y119500
+X081300Y114500
+X081300Y119500
+X098500Y119500
+X098500Y114500
+X109500Y114500
+X109500Y119500
+X042300Y236500
+X042300Y241500
+X053300Y236500
+X053300Y241500
+X070300Y241500
+X070300Y236500
+X081300Y241500
+X081300Y236500
+X098500Y236500
+X098500Y241500
+X109500Y236500
+X109500Y241500
+X042300Y358500
+X042300Y363500
+X053300Y358500
+X053300Y363500
+X070300Y363500
+X070300Y358500
+X081300Y358500
+X081300Y363500
+X098500Y358500
+X098500Y363500
+X109500Y358500
+X109500Y363500
+X042300Y480500
+X042300Y485500
+X053300Y485500
+X053300Y480500
+X070300Y485500
+X070300Y480500
+X081300Y480500
+X081300Y485500
+X098500Y485500
+X098500Y480500
+X109500Y480500
+X109500Y485500
+X109500Y602500
+X109500Y607500
+X098500Y602500
+X098500Y607500
+X081300Y607500
+X081300Y602500
+X070300Y602500
+X070300Y607500
+X053300Y602500
+X053300Y607500
+X042300Y602500
+X042300Y607500
+X-138500Y607500
+X-138500Y602500
+X-149500Y602500
+X-149500Y607500
+X-166700Y607500
+X-166700Y602500
+X-177700Y602500
+X-177700Y607500
+X-194700Y602500
+X-194700Y607500
+X-205700Y607500
+X-205700Y602500
+X-138500Y485500
+X-138500Y480500
+X-149500Y480500
+X-149500Y485500
+X-166700Y485500
+X-166700Y480500
+X-177700Y480500
+X-177700Y485500
+X-194700Y480500
+X-194700Y485500
+X-205700Y485500
+X-205700Y480500
+X-138500Y363500
+X-138500Y358500
+X-149500Y358500
+X-149500Y363500
+X-166700Y363500
+X-166700Y358500
+X-177700Y363500
+X-177700Y358500
+X-194700Y358500
+X-194700Y363500
+X-205700Y363500
+X-205700Y358500
+X-138500Y241500
+X-138500Y236500
+X-149500Y236500
+X-149500Y241500
+X-166700Y241500
+X-166700Y236500
+X-177700Y236500
+X-177700Y241500
+X-194700Y236500
+X-194700Y241500
+X-205700Y241500
+X-205700Y236500
+X-205700Y119500
+X-205700Y114500
+X-194700Y114500
+X-194700Y119500
+X-177700Y114500
+X-177700Y119500
+X-166700Y119500
+X-166700Y114500
+X-149500Y119500
+X-149500Y114500
+X-138500Y119500
+X-138500Y114500
+X090489Y622500
+T15
+X009390Y580040
+X027170Y582580
+X027170Y460580
+X009390Y458040
+X027170Y338580
+X009390Y336040
+X027170Y216580
+X009390Y214040
+X027170Y094580
+X009390Y092040
+X-220830Y094580
+X-238610Y092040
+X-238610Y214040
+X-220830Y216580
+X-238610Y336040
+X-220830Y338580
+X-238610Y458040
+X-220830Y460580
+X-238610Y580040
+X-220830Y582580
+X095639Y622500
+T16
+X037460Y117000
+X065460Y117000
+X093660Y117000
+X093660Y239000
+X065460Y239000
+X037460Y239000
+X093660Y361000
+X065460Y361000
+X037460Y361000
+X093660Y483000
+X065460Y483000
+X037460Y483000
+X093660Y605000
+X065460Y605000
+X037460Y605000
+X-154340Y605000
+X-182540Y605000
+X-210540Y605000
+X-210540Y483000
+X-182540Y483000
+X-154340Y483000
+X-210540Y361000
+X-182540Y361000
+X-154340Y361000
+X-210540Y239000
+X-182540Y239000
+X-154340Y239000
+X-210540Y117000
+X-182540Y117000
+X-154340Y117000
+X100939Y622500
+T17
+X059500Y117000
+X087500Y117000
+X115700Y117000
+X115700Y239000
+X087500Y239000
+X059500Y239000
+X115700Y361000
+X087500Y361000
+X059500Y361000
+X115700Y483000
+X087500Y483000
+X059500Y483000
+X115700Y605000
+X087500Y605000
+X059500Y605000
+X-132300Y605000
+X-160500Y605000
+X-188500Y605000
+X-188500Y483000
+X-160500Y483000
+X-132300Y483000
+X-188500Y361000
+X-160500Y361000
+X-132300Y361000
+X-188500Y239000
+X-160500Y239000
+X-132300Y239000
+X-188500Y117000
+X-160500Y117000
+X-132300Y117000
+X106789Y622500
+T18
+X-124000Y013500
+X-242000Y013500
+X-242000Y123500
+X-242000Y135500
+X-124000Y123500
+X-124000Y135500
+X-124000Y245500
+X-124000Y257500
+X-242000Y245500
+X-242000Y257500
+X-242000Y367500
+X-242000Y379500
+X-124000Y367500
+X-124000Y379500
+X-124000Y489500
+X-124000Y501500
+X-242000Y489500
+X-242000Y501500
+X-242000Y611500
+X-124000Y611500
+X-006000Y611500
+X006000Y611500
+X006000Y501500
+X006000Y489500
+X-006000Y501500
+X-006000Y489500
+X-006000Y379500
+X-006000Y367500
+X006000Y379500
+X006000Y367500
+X124000Y367500
+X124000Y379500
+X124000Y489500
+X124000Y501500
+X124000Y611500
+X242000Y611500
+X242000Y501500
+X242000Y489500
+X242000Y379500
+X242000Y367500
+X242000Y257500
+X242000Y245500
+X242000Y135500
+X242000Y123500
+X242000Y013500
+X124000Y013500
+X124000Y123500
+X124000Y135500
+X124000Y245500
+X124000Y257500
+X006000Y257500
+X-006000Y257500
+X-006000Y245500
+X006000Y245500
+X006000Y135500
+X-006000Y135500
+X006000Y123500
+X-006000Y123500
+X006000Y013500
+X-006000Y013500
+X113739Y623000
+T19
+M97,B*,$S $N
+X-191000Y000500
+M30
diff --git a/demo_drl_files/p20033995a0-cs.drl b/demo_drl_files/p20033995a0-cs.drl
new file mode 100644
index 0000000..e671aad
--- /dev/null
+++ b/demo_drl_files/p20033995a0-cs.drl
@@ -0,0 +1,3359 @@
+M48
+;ͭ-Ĥ-EA-250618
+T01C1.049H05000Z+0.000S045.00F105.0U0700.0
+T02C3.175H00200Z-0.305S020.00F035.0U0600.0
+T03C0.400H01500Z+0.400S090.00F087.0U0700.0
+T04C0.800H00800Z+0.000S060.00F105.0U0700.0
+T05C0.850H00800Z+0.000S060.00F105.0U0700.0
+T06C1.050H00800Z+0.000S045.00F105.0U0700.0
+T07C1.100H00800Z+0.000S045.00F105.0U0700.0
+T08C1.200H01000Z+0.000S040.00F100.0U0700.0
+T09C1.300H01000Z+0.000S036.00F099.0U0700.0
+T10C1.600H01000Z+0.000S030.00F077.0U0700.0
+T11C1.700H01000Z-0.201S028.00F077.0U0700.0
+T12C1.900H01000Z-0.201S026.00F071.0U0700.0
+T13C2.500H01000Z-0.254S022.00F060.0U0700.0
+T14C2.600H00500Z-0.254S021.00F057.0U0600.0
+T15C3.100H00500Z-0.305S020.00F047.0U0600.0
+T16C4.100H00300Z-0.305S020.00F030.0U0600.0
+T17C0.706H01500Z+0.000S070.00F011.0U0800.0
+T18C1.001H02000Z+0.000S060.00F025.0U1000.0
+T19C1.006H01500Z+0.000S065.00F012.0U0900.0
+T20C1.106H01500Z+0.000S062.00F012.0U1000.0
+T21C1.206H01500Z+0.000S056.00F012.0U1000.0
+T22C4.101H00500Z-0.305S020.00F020.0U0700.0
+T23C0.703H15000Z+0.000S055.00F030.0U1000.0
+T24C1.003H15000Z+0.000S055.00F060.0U1000.0
+T25C1.103H15000Z+0.000S055.00F060.0U1000.0
+T26C1.203H15000Z+0.000S055.00F060.0U1000.0
+T27C0.499H05000Z+0.350S072.00F087.0U0700.0
+%
+T01
+X161686Y329848
+X160314Y329848
+X161000Y331042
+X158186Y471344
+X156814Y471344
+X157500Y472537
+X162686Y494644
+X161314Y494644
+X162000Y495837
+X162686Y504594
+X162000Y505787
+X161314Y504594
+X015686Y506844
+X015000Y508037
+X014314Y506844
+X-161314Y504594
+X-162000Y505787
+X-162686Y504594
+X-162000Y482787
+X-162686Y481594
+X-161314Y481594
+X-162000Y472787
+X-162686Y471594
+X-161314Y471594
+X-157500Y452537
+X-156814Y451344
+X-158186Y451344
+X-162000Y384287
+X-162686Y383094
+X-161314Y383094
+X-162000Y129287
+X-161314Y128094
+X-162686Y128094
+X-157500Y036037
+X-158186Y034844
+X-156814Y034844
+X-162000Y012737
+X-162686Y011544
+X-161314Y011544
+X-162000Y002787
+X-162686Y001594
+X-161314Y001594
+X015000Y000537
+X014314Y-000656
+X015686Y-000656
+X161314Y001594
+X162686Y001594
+X162000Y002787
+X161314Y011544
+X162686Y011544
+X162000Y012737
+X156814Y034844
+X158186Y034844
+X157500Y036037
+X161000Y325143
+T02
+X157500Y035250
+X162000Y011950
+X162000Y002000
+X015000Y-000250
+X-162000Y002000
+X-162000Y011950
+X-157500Y035250
+X-162000Y128500
+X-162000Y383500
+X-157500Y451750
+X-162000Y472000
+X-162000Y482000
+X-162000Y505000
+X015000Y507250
+X162000Y505000
+X162000Y495050
+X157500Y471750
+X161000Y330255
+T03
+X-059124Y393874
+X-048875Y401875
+X-049375Y409251
+X-054625Y412251
+X-058374Y410750
+X-059375Y410750
+X-058374Y411750
+X-058374Y412751
+X-059375Y412751
+X-059375Y411750
+X-068374Y418751
+X-069375Y418751
+X-069375Y417750
+X-069375Y416749
+X-083499Y410249
+X-083499Y411250
+X-084499Y410249
+X-085500Y411250
+X-084499Y411250
+X-085500Y410249
+X-091624Y411250
+X-091624Y412375
+X-092749Y412375
+X-093875Y412375
+X-092749Y411250
+X-093875Y411250
+X-094375Y406876
+X-093374Y406876
+X-092376Y406876
+X-101751Y394001
+X-100750Y394001
+X-099750Y394001
+X-099750Y393000
+X-100750Y393000
+X-101751Y393000
+X-106250Y384750
+X-119000Y396876
+X-131124Y393874
+X-120875Y401875
+X-126625Y412251
+X-130374Y412751
+X-130374Y411750
+X-130374Y410750
+X-131375Y410750
+X-131375Y411750
+X-131375Y412751
+X-141375Y416749
+X-141375Y417750
+X-141375Y418751
+X-140374Y418751
+X-127799Y423051
+X-125625Y421750
+X-120250Y417874
+X-118375Y413500
+X-114499Y416376
+X-112625Y413249
+X-113875Y411499
+X-114624Y412375
+X-117499Y410750
+X-118624Y411250
+X-121375Y409251
+X-115249Y403500
+X-114126Y407000
+X-108500Y408751
+X-108500Y409876
+X-107250Y410874
+X-108124Y411626
+X-108124Y412751
+X-107499Y414501
+X-108624Y415624
+X-110001Y418375
+X-108876Y419500
+X-104375Y419251
+X-103374Y414750
+X-103499Y412375
+X-100875Y410000
+X-097875Y417625
+X-099125Y424250
+X-102376Y423500
+X-106750Y426376
+X-099000Y430625
+X-092500Y427750
+X-091500Y427750
+X-090499Y427750
+X-090499Y428875
+X-091500Y428875
+X-092500Y428875
+X-089501Y437501
+X-096999Y441626
+X-139249Y477874
+X-140250Y477874
+X-140875Y480500
+X-139874Y480500
+X-140875Y481501
+X-139874Y481501
+X-134875Y486375
+X-140374Y491125
+X-137875Y490749
+X-133875Y486375
+X-134875Y485375
+X-132874Y482624
+X-131876Y482624
+X-130875Y482624
+X-132874Y483625
+X-131876Y483625
+X-130875Y483625
+X-132874Y486749
+X-131751Y486749
+X-130001Y486624
+X-125500Y491750
+X-124499Y491750
+X-124499Y490749
+X-125500Y490749
+X-125500Y488499
+X-125500Y487501
+X-124499Y488499
+X-124499Y487501
+X-125500Y484625
+X-124624Y481501
+X-120374Y482624
+X-119374Y482624
+X-119374Y481626
+X-118375Y482624
+X-118375Y481626
+X-119399Y480600
+X-119374Y479500
+X-093374Y465375
+X-085124Y450501
+X-084126Y450501
+X-083125Y450501
+X-068250Y477874
+X-067249Y477874
+X-067874Y480500
+X-068875Y480500
+X-068875Y481501
+X-067874Y481501
+X-060874Y482624
+X-059876Y482624
+X-058875Y482624
+X-058875Y483625
+X-059876Y483625
+X-060874Y483625
+X-062875Y485375
+X-062875Y486375
+X-068374Y491125
+X-065875Y490749
+X-061875Y486375
+X-060874Y486749
+X-059751Y486749
+X-058001Y486624
+X-053500Y490749
+X-053500Y491750
+X-052499Y491750
+X-052499Y490749
+X-053500Y488499
+X-053500Y487501
+X-052499Y488499
+X-052499Y487501
+X-053500Y484625
+X-052624Y481501
+X-048374Y482624
+X-047374Y482624
+X-046375Y482624
+X-046375Y481626
+X-047374Y481626
+X-047399Y480600
+X-047374Y479500
+X-021374Y465375
+X-011125Y450501
+X-012126Y450501
+X-013124Y450501
+X-024999Y441626
+X-017501Y437501
+X-020500Y428875
+X-019500Y428875
+X-018499Y428875
+X-018499Y427750
+X-019500Y427750
+X-020500Y427750
+X-027000Y430625
+X-034750Y426376
+X-030376Y423500
+X-027125Y424250
+X-032375Y419251
+X-036876Y419500
+X-038001Y418375
+X-042499Y416376
+X-046375Y413500
+X-048250Y417874
+X-053625Y421750
+X-055799Y423051
+X-046624Y411250
+X-045499Y410750
+X-042624Y412375
+X-041875Y411499
+X-040625Y413249
+X-036624Y415624
+X-035499Y414501
+X-036124Y412751
+X-036124Y411626
+X-035250Y410874
+X-036500Y409876
+X-036500Y408751
+X-042126Y407000
+X-043249Y403500
+X-047000Y396876
+X-034250Y384750
+X-029751Y393000
+X-029751Y394001
+X-028750Y393000
+X-027750Y394001
+X-027750Y393000
+X-028750Y394001
+X-020376Y406876
+X-021374Y406876
+X-022375Y406876
+X-028875Y410000
+X-031499Y412375
+X-031374Y414750
+X-025875Y417625
+X-019624Y412375
+X-020749Y412375
+X-021875Y412375
+X-021875Y411250
+X-020749Y411250
+X-019624Y411250
+X-013500Y411250
+X-012499Y410249
+X-013500Y410249
+X-012499Y411250
+X-011499Y411250
+X-011499Y410249
+X011625Y416749
+X011625Y417750
+X011625Y418751
+X012626Y418751
+X021625Y412751
+X021625Y411750
+X022626Y412751
+X022626Y411750
+X021625Y410750
+X022626Y410750
+X026375Y412251
+X032750Y417874
+X027375Y421750
+X025201Y423051
+X012750Y477874
+X013751Y477874
+X013126Y480500
+X012125Y480500
+X012125Y481501
+X013126Y481501
+X012626Y491125
+X015125Y490749
+X019126Y486375
+X018125Y486375
+X018125Y485375
+X020126Y483625
+X020126Y482624
+X021125Y482624
+X022125Y482624
+X021125Y483625
+X022125Y483625
+X020126Y486749
+X021249Y486749
+X022999Y486624
+X027500Y491750
+X028501Y491750
+X028501Y490749
+X027500Y490749
+X027500Y488499
+X027500Y487501
+X028501Y488499
+X028501Y487501
+X027500Y484625
+X028376Y481501
+X032626Y482624
+X033626Y482624
+X034625Y482624
+X034625Y481626
+X033626Y481626
+X033601Y480600
+X033626Y479500
+X059626Y465375
+X084626Y491125
+X087125Y490749
+X090125Y486375
+X090125Y485375
+X091126Y486375
+X092126Y486749
+X093249Y486749
+X094999Y486624
+X099500Y490749
+X099500Y491750
+X100501Y491750
+X100501Y490749
+X100501Y488499
+X100501Y487501
+X099500Y488499
+X099500Y487501
+X099500Y484625
+X104626Y482624
+X105626Y481626
+X105626Y482624
+X106625Y482624
+X106625Y481626
+X105601Y480600
+X105626Y479500
+X100376Y481501
+X094125Y483625
+X094125Y482624
+X093125Y482624
+X092126Y482624
+X093125Y483625
+X092126Y483625
+X085126Y481501
+X084125Y481501
+X085126Y480500
+X084125Y480500
+X085751Y477874
+X084750Y477874
+X069875Y450501
+X068874Y450501
+X067876Y450501
+X056001Y441626
+X063499Y437501
+X060500Y428875
+X061500Y428875
+X062501Y428875
+X062501Y427750
+X061500Y427750
+X060500Y427750
+X054000Y430625
+X046250Y426376
+X050624Y423500
+X053875Y424250
+X048625Y419251
+X055125Y417625
+X049626Y414750
+X052125Y410000
+X049501Y412375
+X045750Y410874
+X044876Y411626
+X044876Y412751
+X045501Y414501
+X044376Y415624
+X042999Y418375
+X044124Y419500
+X038501Y416376
+X034625Y413500
+X038376Y412375
+X039126Y411499
+X040375Y413249
+X044500Y409876
+X044500Y408751
+X037751Y403500
+X038874Y407000
+X035501Y410750
+X034376Y411250
+X031625Y409251
+X032125Y401875
+X021876Y393874
+X034000Y396876
+X046751Y384750
+X053250Y393000
+X052250Y393000
+X051249Y393000
+X051249Y394001
+X052250Y394001
+X053250Y394001
+X058625Y406876
+X059626Y406876
+X060624Y406876
+X061376Y411250
+X060251Y411250
+X059125Y411250
+X059125Y412375
+X060251Y412375
+X061376Y412375
+X067500Y410249
+X067500Y411250
+X068501Y411250
+X069501Y410249
+X068501Y410249
+X069501Y411250
+X083625Y416749
+X083625Y417750
+X083625Y418751
+X084626Y418751
+X093625Y412751
+X094626Y412751
+X094626Y411750
+X093625Y410750
+X093625Y411750
+X094626Y410750
+X098375Y412251
+X103625Y409251
+X106376Y411250
+X106625Y413500
+X104750Y417874
+X099375Y421750
+X097201Y423051
+X131626Y465375
+X141875Y450501
+X140874Y450501
+X139876Y450501
+X128001Y441626
+X135499Y437501
+X132500Y428875
+X133500Y428875
+X134501Y428875
+X134501Y427750
+X133500Y427750
+X132500Y427750
+X126000Y430625
+X125875Y424250
+X122624Y423500
+X118250Y426376
+X116124Y419500
+X114999Y418375
+X110501Y416376
+X112375Y413249
+X111126Y411499
+X110376Y412375
+X107501Y410750
+X110874Y407000
+X104125Y401875
+X093876Y393874
+X106000Y396876
+X109751Y403500
+X116500Y408751
+X116500Y409876
+X117750Y410874
+X116876Y411626
+X116876Y412751
+X121501Y412375
+X124125Y410000
+X121626Y414750
+X117501Y414501
+X116376Y415624
+X120625Y419251
+X127125Y417625
+X131125Y412375
+X131125Y411250
+X132251Y411250
+X133376Y411250
+X132251Y412375
+X133376Y412375
+X139500Y411250
+X140501Y411250
+X141501Y410249
+X141501Y411250
+X140501Y410249
+X139500Y410249
+X132624Y406876
+X131626Y406876
+X130625Y406876
+X125250Y394001
+X124250Y393000
+X123249Y393000
+X123249Y394001
+X124250Y394001
+X125250Y393000
+X118751Y384750
+X099500Y325250
+X099500Y324249
+X100501Y325250
+X100501Y324249
+X099500Y321999
+X099500Y321001
+X100501Y321999
+X100501Y321001
+X099500Y318125
+X104626Y316124
+X105626Y316124
+X106625Y315126
+X106625Y316124
+X105626Y315126
+X105601Y314100
+X105626Y313000
+X100376Y315001
+X094125Y316124
+X093125Y316124
+X092126Y316124
+X092126Y317125
+X093125Y317125
+X094125Y317125
+X094999Y320124
+X093249Y320249
+X092126Y320249
+X091126Y319875
+X087125Y324249
+X084626Y324625
+X090125Y319875
+X090125Y318875
+X085126Y315001
+X084125Y315001
+X084125Y314000
+X085126Y314000
+X085751Y311374
+X084750Y311374
+X059626Y298875
+X104750Y251374
+X118250Y259876
+X128001Y275126
+X131626Y298875
+X139876Y284001
+X140874Y284001
+X141875Y284001
+X135499Y271001
+X132500Y262375
+X133500Y262375
+X134501Y262375
+X134501Y261250
+X133500Y261250
+X132500Y261250
+X126000Y264125
+X125875Y257750
+X122624Y257000
+X120625Y252751
+X121626Y248250
+X127125Y251125
+X131125Y245875
+X133376Y245875
+X132251Y245875
+X131125Y244750
+X132251Y244750
+X133376Y244750
+X139500Y243749
+X140501Y243749
+X141501Y244750
+X141501Y243749
+X140501Y244750
+X139500Y244750
+X132624Y240376
+X131626Y240376
+X130625Y240376
+X124125Y243500
+X121501Y245875
+X117501Y248001
+X116376Y249124
+X114999Y251875
+X116124Y253000
+X110501Y249876
+X110376Y245875
+X111126Y244999
+X112375Y246749
+X116876Y246251
+X116876Y245126
+X117750Y244374
+X116500Y243376
+X116500Y242251
+X124250Y227501
+X123249Y227501
+X123249Y226500
+X124250Y226500
+X125250Y227501
+X125250Y226500
+X118751Y218250
+X106000Y230376
+X093876Y227374
+X104125Y235375
+X109751Y237000
+X110874Y240500
+X107501Y244250
+X106376Y244750
+X106625Y247000
+X103625Y242751
+X098375Y245751
+X094626Y244250
+X094626Y245250
+X094626Y246251
+X093625Y246251
+X093625Y245250
+X093625Y244250
+X084626Y252251
+X083625Y252251
+X083625Y251250
+X083625Y250249
+X069501Y243749
+X069501Y244750
+X068501Y243749
+X067500Y243749
+X068501Y244750
+X067500Y244750
+X061376Y244750
+X060251Y244750
+X061376Y245875
+X060251Y245875
+X059125Y245875
+X059125Y244750
+X060624Y240376
+X059626Y240376
+X058625Y240376
+X051249Y227501
+X052250Y227501
+X053250Y226500
+X053250Y227501
+X052250Y226500
+X051249Y226500
+X046751Y218250
+X034000Y230376
+X021876Y227374
+X032125Y235375
+X037751Y237000
+X038874Y240500
+X039126Y244999
+X040375Y246749
+X038376Y245875
+X035501Y244250
+X034376Y244750
+X031625Y242751
+X026375Y245751
+X022626Y246251
+X021625Y245250
+X021625Y244250
+X022626Y244250
+X022626Y245250
+X021625Y246251
+X012626Y252251
+X011625Y252251
+X011625Y251250
+X011625Y250249
+X025201Y256551
+X027375Y255250
+X032750Y251374
+X034625Y247000
+X038501Y249876
+X042999Y251875
+X044124Y253000
+X048625Y252751
+X044376Y249124
+X045501Y248001
+X044876Y246251
+X044876Y245126
+X045750Y244374
+X044500Y243376
+X044500Y242251
+X049501Y245875
+X052125Y243500
+X049626Y248250
+X055125Y251125
+X053875Y257750
+X050624Y257000
+X046250Y259876
+X054000Y264125
+X060500Y261250
+X061500Y261250
+X062501Y261250
+X062501Y262375
+X061500Y262375
+X060500Y262375
+X063499Y271001
+X056001Y275126
+X067876Y284001
+X068874Y284001
+X069875Y284001
+X099375Y255250
+X097201Y256551
+X033626Y313000
+X033601Y314100
+X034625Y315126
+X034625Y316124
+X033626Y315126
+X033626Y316124
+X032626Y316124
+X028376Y315001
+X027500Y318125
+X028501Y321001
+X028501Y321999
+X027500Y321001
+X027500Y321999
+X028501Y324249
+X027500Y325250
+X028501Y325250
+X027500Y324249
+X022999Y320124
+X021249Y320249
+X020126Y320249
+X019126Y319875
+X015125Y324249
+X012626Y324625
+X018125Y319875
+X018125Y318875
+X020126Y317125
+X021125Y317125
+X022125Y317125
+X022125Y316124
+X021125Y316124
+X020126Y316124
+X013126Y315001
+X012125Y315001
+X012125Y314000
+X013126Y314000
+X013751Y311374
+X012750Y311374
+X-013124Y284001
+X-012126Y284001
+X-011125Y284001
+X-021374Y298875
+X-047374Y313000
+X-047399Y314100
+X-046375Y315126
+X-047374Y316124
+X-046375Y316124
+X-047374Y315126
+X-048374Y316124
+X-052624Y315001
+X-053500Y318125
+X-053500Y321001
+X-052499Y321001
+X-052499Y321999
+X-053500Y321999
+X-052499Y324249
+X-052499Y325250
+X-053500Y325250
+X-053500Y324249
+X-058001Y320124
+X-059751Y320249
+X-060874Y320249
+X-061875Y319875
+X-062875Y318875
+X-060874Y317125
+X-059876Y317125
+X-058875Y317125
+X-058875Y316124
+X-059876Y316124
+X-060874Y316124
+X-067249Y311374
+X-068250Y311374
+X-068875Y314000
+X-067874Y314000
+X-068875Y315001
+X-067874Y315001
+X-062875Y319875
+X-065875Y324249
+X-068374Y324625
+X-093374Y298875
+X-085124Y284001
+X-084126Y284001
+X-083125Y284001
+X-089501Y271001
+X-069375Y250249
+X-069375Y251250
+X-069375Y252251
+X-068374Y252251
+X-055799Y256551
+X-053625Y255250
+X-048250Y251374
+X-042499Y249876
+X-038001Y251875
+X-036876Y253000
+X-032375Y252751
+X-031374Y248250
+X-025875Y251125
+X-027125Y257750
+X-030376Y257000
+X-034750Y259876
+X-027000Y264125
+X-024999Y275126
+X-017501Y271001
+X-020500Y262375
+X-020500Y261250
+X-019500Y262375
+X-018499Y262375
+X-018499Y261250
+X-019500Y261250
+X-013500Y244750
+X-012499Y244750
+X-011499Y244750
+X-011499Y243749
+X-012499Y243749
+X-013500Y243749
+X-019624Y245875
+X-020749Y245875
+X-019624Y244750
+X-020749Y244750
+X-021875Y245875
+X-021875Y244750
+X-020376Y240376
+X-021374Y240376
+X-022375Y240376
+X-028875Y243500
+X-031499Y245875
+X-035499Y248001
+X-036624Y249124
+X-036124Y246251
+X-036124Y245126
+X-035250Y244374
+X-036500Y243376
+X-036500Y242251
+X-040625Y246749
+X-041875Y244999
+X-042624Y245875
+X-046375Y247000
+X-046624Y244750
+X-045499Y244250
+X-042126Y240500
+X-043249Y237000
+X-049375Y242751
+X-054625Y245751
+X-058374Y244250
+X-058374Y245250
+X-059375Y246251
+X-058374Y246251
+X-059375Y245250
+X-059375Y244250
+X-059124Y227374
+X-048875Y235375
+X-047000Y230376
+X-029751Y226500
+X-029751Y227501
+X-028750Y227501
+X-027750Y227501
+X-027750Y226500
+X-028750Y226500
+X-034250Y218250
+X015125Y157749
+X012626Y158125
+X-021374Y132375
+X025201Y090051
+X027375Y088750
+X032750Y084874
+X034625Y080500
+X038501Y083376
+X042999Y085375
+X044124Y086500
+X048625Y086251
+X053875Y091250
+X050624Y090500
+X046250Y093376
+X054000Y097625
+X060500Y094750
+X061500Y094750
+X062501Y094750
+X062501Y095875
+X061500Y095875
+X060500Y095875
+X063499Y104501
+X056001Y108626
+X013751Y144874
+X012750Y144874
+X013126Y147500
+X012125Y147500
+X012125Y148501
+X013126Y148501
+X018125Y152375
+X018125Y153375
+X019126Y153375
+X020126Y153749
+X021249Y153749
+X022125Y150625
+X021125Y150625
+X022125Y149624
+X021125Y149624
+X020126Y149624
+X020126Y150625
+X022999Y153624
+X027500Y157749
+X027500Y158750
+X028501Y158750
+X028501Y157749
+X027500Y155499
+X027500Y154501
+X028501Y155499
+X028501Y154501
+X027500Y151625
+X028376Y148501
+X032626Y149624
+X033626Y149624
+X034625Y149624
+X034625Y148626
+X033626Y148626
+X033601Y147600
+X033626Y146500
+X059626Y132375
+X067876Y117501
+X068874Y117501
+X069875Y117501
+X085751Y144874
+X084750Y144874
+X085126Y147500
+X084125Y147500
+X084125Y148501
+X085126Y148501
+X084626Y158125
+X087125Y157749
+X091126Y153375
+X090125Y153375
+X090125Y152375
+X092126Y150625
+X092126Y149624
+X093125Y149624
+X094125Y149624
+X093125Y150625
+X094125Y150625
+X092126Y153749
+X093249Y153749
+X094999Y153624
+X099500Y157749
+X099500Y158750
+X100501Y158750
+X100501Y157749
+X099500Y155499
+X099500Y154501
+X100501Y155499
+X100501Y154501
+X099500Y151625
+X100376Y148501
+X104626Y149624
+X105626Y148626
+X105626Y149624
+X106625Y149624
+X106625Y148626
+X105601Y147600
+X105626Y146500
+X131626Y132375
+X141875Y117501
+X140874Y117501
+X139876Y117501
+X128001Y108626
+X135499Y104501
+X132500Y095875
+X133500Y095875
+X134501Y095875
+X134501Y094750
+X133500Y094750
+X132500Y094750
+X126000Y097625
+X118250Y093376
+X122624Y090500
+X125875Y091250
+X120625Y086251
+X116124Y086500
+X114999Y085375
+X110501Y083376
+X106625Y080500
+X104750Y084874
+X099375Y088750
+X097201Y090051
+X084626Y085751
+X083625Y085751
+X083625Y084750
+X083625Y083749
+X093625Y078750
+X093625Y077750
+X094626Y077750
+X094626Y078750
+X093625Y079751
+X094626Y079751
+X098375Y079251
+X103625Y076251
+X106376Y078250
+X107501Y077750
+X110376Y079375
+X112375Y080249
+X111126Y078499
+X110874Y074000
+X104125Y068875
+X093876Y060874
+X106000Y063876
+X109751Y070500
+X116500Y075751
+X116500Y076876
+X117750Y077874
+X116876Y078626
+X116876Y079751
+X116376Y082624
+X117501Y081501
+X121501Y079375
+X124125Y077000
+X121626Y081750
+X127125Y084625
+X131125Y079375
+X132251Y079375
+X131125Y078250
+X132251Y078250
+X133376Y078250
+X133376Y079375
+X139500Y078250
+X140501Y078250
+X141501Y078250
+X141501Y077249
+X140501Y077249
+X139500Y077249
+X132624Y073876
+X131626Y073876
+X130625Y073876
+X125250Y061001
+X125250Y060000
+X124250Y061001
+X123249Y061001
+X123249Y060000
+X124250Y060000
+X118751Y051750
+X108000Y-000250
+X105500Y-000250
+X103000Y-000250
+X100500Y-000250
+X098000Y-000250
+X095500Y-000250
+X046751Y051750
+X053250Y060000
+X053250Y061001
+X052250Y061001
+X051249Y060000
+X052250Y060000
+X051249Y061001
+X058625Y073876
+X059626Y073876
+X060624Y073876
+X067500Y077249
+X068501Y077249
+X069501Y077249
+X069501Y078250
+X068501Y078250
+X067500Y078250
+X061376Y078250
+X060251Y078250
+X061376Y079375
+X060251Y079375
+X059125Y078250
+X059125Y079375
+X055125Y084625
+X049626Y081750
+X052125Y077000
+X049501Y079375
+X045750Y077874
+X045501Y081501
+X044376Y082624
+X044876Y079751
+X044876Y078626
+X044500Y076876
+X044500Y075751
+X037751Y070500
+X038874Y074000
+X039126Y078499
+X040375Y080249
+X038376Y079375
+X035501Y077750
+X034376Y078250
+X031625Y076251
+X021876Y060874
+X034000Y063876
+X032125Y068875
+X026375Y079251
+X022626Y079751
+X022626Y078750
+X022626Y077750
+X021625Y077750
+X021625Y078750
+X021625Y079751
+X012626Y085751
+X011625Y085751
+X011625Y084750
+X011625Y083749
+X-011499Y077249
+X-011499Y078250
+X-012499Y078250
+X-013500Y077249
+X-012499Y077249
+X-013500Y078250
+X-020376Y073876
+X-021374Y073876
+X-022375Y073876
+X-019624Y078250
+X-019624Y079375
+X-020749Y078250
+X-021875Y078250
+X-020749Y079375
+X-021875Y079375
+X-025875Y084625
+X-027125Y091250
+X-020500Y094750
+X-019500Y094750
+X-018499Y094750
+X-018499Y095875
+X-019500Y095875
+X-020500Y095875
+X-017501Y104501
+X-011125Y117501
+X-012126Y117501
+X-013124Y117501
+X-024999Y108626
+X-027000Y097625
+X-034750Y093376
+X-030376Y090500
+X-032375Y086251
+X-036876Y086500
+X-038001Y085375
+X-036624Y082624
+X-035499Y081501
+X-031374Y081750
+X-031499Y079375
+X-028875Y077000
+X-028750Y061001
+X-027750Y061001
+X-027750Y060000
+X-028750Y060000
+X-029751Y061001
+X-029751Y060000
+X-034250Y051750
+X-047000Y063876
+X-059124Y060874
+X-048875Y068875
+X-043249Y070500
+X-042126Y074000
+X-036500Y075751
+X-036500Y076876
+X-035250Y077874
+X-036124Y078626
+X-036124Y079751
+X-040625Y080249
+X-041875Y078499
+X-042624Y079375
+X-042499Y083376
+X-046375Y080500
+X-045499Y077750
+X-046624Y078250
+X-049375Y076251
+X-054625Y079251
+X-058374Y077750
+X-058374Y078750
+X-059375Y077750
+X-059375Y078750
+X-059375Y079751
+X-058374Y079751
+X-048250Y084874
+X-053625Y088750
+X-055799Y090051
+X-068374Y085751
+X-069375Y085751
+X-069375Y084750
+X-069375Y083749
+X-083499Y078250
+X-083499Y077249
+X-084499Y077249
+X-085500Y077249
+X-084499Y078250
+X-085500Y078250
+X-091624Y079375
+X-092749Y079375
+X-091624Y078250
+X-092749Y078250
+X-093875Y078250
+X-093875Y079375
+X-097875Y084625
+X-103374Y081750
+X-103499Y079375
+X-100875Y077000
+X-094375Y073876
+X-093374Y073876
+X-092376Y073876
+X-101751Y061001
+X-100750Y061001
+X-099750Y061001
+X-099750Y060000
+X-100750Y060000
+X-101751Y060000
+X-106250Y051750
+X-119000Y063876
+X-131124Y060874
+X-120875Y068875
+X-115249Y070500
+X-114126Y074000
+X-117499Y077750
+X-118624Y078250
+X-121375Y076251
+X-126625Y079251
+X-130374Y079751
+X-130374Y078750
+X-130374Y077750
+X-131375Y077750
+X-131375Y078750
+X-131375Y079751
+X-141375Y083749
+X-141375Y084750
+X-141375Y085751
+X-140374Y085751
+X-127799Y090051
+X-125625Y088750
+X-120250Y084874
+X-118375Y080500
+X-114499Y083376
+X-114624Y079375
+X-113875Y078499
+X-112625Y080249
+X-108500Y075751
+X-108500Y076876
+X-107250Y077874
+X-108124Y078626
+X-108124Y079751
+X-107499Y081501
+X-108624Y082624
+X-110001Y085375
+X-108876Y086500
+X-104375Y086251
+X-099125Y091250
+X-102376Y090500
+X-106750Y093376
+X-099000Y097625
+X-092500Y094750
+X-091500Y094750
+X-090499Y094750
+X-090499Y095875
+X-091500Y095875
+X-092500Y095875
+X-089501Y104501
+X-096999Y108626
+X-084126Y117501
+X-083125Y117501
+X-085124Y117501
+X-118375Y149624
+X-119374Y149624
+X-119374Y148626
+X-120374Y149624
+X-124624Y148501
+X-130875Y150625
+X-131876Y150625
+X-132874Y150625
+X-130875Y149624
+X-131876Y149624
+X-132874Y149624
+X-139249Y144874
+X-140250Y144874
+X-140875Y147500
+X-139874Y147500
+X-139874Y148501
+X-140875Y148501
+X-140374Y158125
+X-137875Y157749
+X-133875Y153375
+X-134875Y153375
+X-134875Y152375
+X-132874Y153749
+X-131751Y153749
+X-130001Y153624
+X-125500Y158750
+X-124499Y158750
+X-124499Y157749
+X-125500Y157749
+X-125500Y155499
+X-124499Y155499
+X-124499Y154501
+X-125500Y154501
+X-125500Y151625
+X-119374Y146500
+X-119399Y147600
+X-118375Y148626
+X-093374Y132375
+X-068250Y144874
+X-067249Y144874
+X-067874Y147500
+X-068875Y147500
+X-068875Y148501
+X-067874Y148501
+X-062875Y152375
+X-060874Y150625
+X-059876Y150625
+X-058875Y150625
+X-060874Y149624
+X-059876Y149624
+X-058875Y149624
+X-052624Y148501
+X-048374Y149624
+X-047374Y149624
+X-046375Y149624
+X-046375Y148626
+X-047374Y148626
+X-047399Y147600
+X-047374Y146500
+X-053500Y151625
+X-053500Y154501
+X-053500Y155499
+X-052499Y154501
+X-052499Y155499
+X-052499Y157749
+X-052499Y158750
+X-053500Y158750
+X-053500Y157749
+X-058001Y153624
+X-059751Y153749
+X-060874Y153749
+X-061875Y153375
+X-062875Y153375
+X-065875Y157749
+X-068374Y158125
+X-106250Y218250
+X-099750Y226500
+X-099750Y227501
+X-100750Y227501
+X-101751Y226500
+X-100750Y226500
+X-101751Y227501
+X-094375Y240376
+X-093374Y240376
+X-092376Y240376
+X-085500Y244750
+X-084499Y244750
+X-083499Y244750
+X-083499Y243749
+X-084499Y243749
+X-085500Y243749
+X-091624Y244750
+X-092749Y244750
+X-093875Y244750
+X-091624Y245875
+X-092749Y245875
+X-093875Y245875
+X-100875Y243500
+X-103499Y245875
+X-108124Y245126
+X-108124Y246251
+X-107499Y248001
+X-108624Y249124
+X-110001Y251875
+X-108876Y253000
+X-114499Y249876
+X-120250Y251374
+X-125625Y255250
+X-127799Y256551
+X-140374Y252251
+X-141375Y252251
+X-141375Y251250
+X-141375Y250249
+X-131375Y244250
+X-131375Y245250
+X-131375Y246251
+X-130374Y246251
+X-130374Y245250
+X-130374Y244250
+X-126625Y245751
+X-121375Y242751
+X-120875Y235375
+X-131124Y227374
+X-119000Y230376
+X-115249Y237000
+X-114126Y240500
+X-117499Y244250
+X-118624Y244750
+X-118375Y247000
+X-114624Y245875
+X-113875Y244999
+X-112625Y246749
+X-108500Y242251
+X-108500Y243376
+X-107250Y244374
+X-103374Y248250
+X-097875Y251125
+X-104375Y252751
+X-099125Y257750
+X-102376Y257000
+X-106750Y259876
+X-099000Y264125
+X-092500Y261250
+X-091500Y261250
+X-090499Y261250
+X-090499Y262375
+X-091500Y262375
+X-092500Y262375
+X-096999Y275126
+X-139249Y311374
+X-140250Y311374
+X-140875Y314000
+X-140875Y315001
+X-139874Y315001
+X-139874Y314000
+X-134875Y318875
+X-134875Y319875
+X-140374Y324625
+X-137875Y324249
+X-133875Y319875
+X-132874Y320249
+X-131751Y320249
+X-130875Y317125
+X-130875Y316124
+X-131876Y316124
+X-132874Y316124
+X-132874Y317125
+X-131876Y317125
+X-130001Y320124
+X-125500Y325250
+X-125500Y324249
+X-124499Y321999
+X-119374Y316124
+X-118375Y315126
+X-118375Y316124
+X-119374Y315126
+X-119374Y313000
+X-119399Y314100
+X-120374Y316124
+X-124624Y315001
+X-125500Y318125
+X-124499Y321001
+X-125500Y321001
+X-125500Y321999
+X-124499Y324249
+X-124499Y325250
+X161000Y335042
+T04
+X-002500Y025525
+X-002500Y023975
+X002500Y028975
+X002500Y030525
+X143000Y-000250
+X148000Y-000250
+X153000Y-000250
+X160000Y-000750
+X150500Y023975
+X150500Y025525
+X103674Y110140
+X103674Y111690
+X103674Y130140
+X103674Y131690
+X150500Y148475
+X150500Y150025
+X150500Y190475
+X150500Y192025
+X031674Y110140
+X031674Y111690
+X031674Y130140
+X031674Y131690
+X002500Y143475
+X002500Y145025
+X-002500Y150025
+X-002500Y148475
+X-049327Y110140
+X-049327Y111690
+X-049327Y130140
+X-049327Y131690
+X-002500Y190475
+X-002500Y192025
+X002500Y195475
+X002500Y197025
+X-049327Y276640
+X-049327Y278190
+X-049327Y296640
+X-049327Y298190
+X-002500Y316525
+X-002500Y314975
+X002500Y311525
+X002500Y309975
+X031674Y298190
+X031674Y296640
+X031674Y278190
+X031674Y276640
+X103674Y298190
+X103674Y296640
+X103674Y278190
+X103674Y276640
+X150500Y314975
+X150500Y316525
+X150500Y356975
+X150500Y358525
+X161775Y389392
+X160225Y389392
+X159975Y395992
+X162025Y395992
+X162025Y423118
+X159975Y423118
+X150500Y481475
+X150500Y483025
+X160000Y507750
+X153000Y507250
+X148000Y507250
+X143000Y507250
+X103674Y464690
+X103674Y463140
+X103674Y444690
+X103674Y443140
+X002500Y361975
+X-002500Y356975
+X-002500Y358525
+X002500Y363525
+X-049327Y443140
+X-049327Y444690
+X-049327Y463140
+X-049327Y464690
+X031674Y443140
+X031674Y444690
+X031674Y463140
+X031674Y464690
+X002500Y476475
+X002500Y478025
+X-002500Y481475
+X-002500Y483025
+X-029755Y507567
+X-030837Y507567
+X-031918Y505950
+X-031918Y507033
+X-031918Y508116
+X-031918Y509199
+X-033000Y507567
+X-034081Y507567
+X-035544Y508116
+X-035544Y507033
+X-035544Y505950
+X-036626Y505950
+X-037707Y505950
+X-038789Y505950
+X-038789Y507033
+X-035544Y509199
+X-036626Y509199
+X-037707Y509199
+X-038789Y509199
+X-038789Y508116
+X-040300Y509199
+X-040300Y508116
+X-040300Y507033
+X-041381Y505950
+X-042463Y505950
+X-043544Y508116
+X-043544Y507033
+X-044626Y505950
+X-045707Y505950
+X-046789Y507033
+X-046789Y508116
+X-046789Y509199
+X-048300Y509199
+X-048300Y508116
+X-048300Y507033
+X-049381Y505950
+X-050463Y505950
+X-051544Y507033
+X-051544Y508116
+X-052626Y505950
+X-053707Y505950
+X-054789Y507033
+X-054789Y508116
+X-054789Y509199
+X-056300Y507033
+X-057381Y505950
+X-056300Y508116
+X-057381Y509199
+X-058463Y509199
+X-059544Y508116
+X-059544Y507033
+X-058463Y505950
+X-059544Y505950
+X-060626Y505950
+X-061707Y507033
+X-062789Y508116
+X-062789Y509199
+X-064300Y508116
+X-065381Y509199
+X-066463Y509199
+X-067544Y508116
+X-067544Y507033
+X-064300Y507033
+X-065381Y505950
+X-066463Y505950
+X-067544Y505950
+X-068626Y505950
+X-069707Y507033
+X-070789Y508116
+X-072300Y505950
+X-072300Y507033
+X-072300Y508116
+X-070789Y509199
+X-072300Y509199
+X-073381Y509199
+X-074463Y509199
+X-074463Y508116
+X-074463Y507033
+X-075544Y505950
+X-076626Y505950
+X-077707Y505950
+X-078789Y507033
+X-078789Y508116
+X-078789Y509199
+X-080300Y508116
+X-080300Y507033
+X-081381Y505950
+X-082463Y505950
+X-083544Y505950
+X-084626Y505950
+X-085707Y505950
+X-086789Y505950
+X-083544Y507033
+X-083544Y508116
+X-081381Y509199
+X-082463Y509199
+X-083544Y509199
+X-084626Y509199
+X-085707Y509199
+X-086789Y509199
+X-088300Y508116
+X-088300Y507033
+X-089381Y505950
+X-090463Y505950
+X-091544Y505950
+X-092626Y505950
+X-093707Y505950
+X-089381Y509199
+X-090463Y509199
+X-091544Y509199
+X-092626Y509199
+X-093707Y509199
+X-094789Y508116
+X-094789Y507033
+X-143000Y506750
+X-148000Y506750
+X-153000Y506750
+X-160000Y507750
+X-148000Y498275
+X-148000Y496225
+X-150500Y478025
+X-150500Y476475
+X-121327Y464690
+X-121327Y463140
+X-121327Y444690
+X-121327Y443140
+X-150500Y363525
+X-150500Y361975
+X-148000Y331775
+X-148000Y329725
+X-150500Y311525
+X-150500Y309975
+X-121327Y298190
+X-121327Y296640
+X-121327Y278190
+X-121327Y276640
+X-150500Y197025
+X-150500Y195475
+X-148000Y165275
+X-148000Y163225
+X-150500Y145025
+X-150500Y143475
+X-121327Y131690
+X-121327Y130140
+X-121327Y111690
+X-121327Y110140
+X-150500Y030525
+X-150500Y028975
+X-160000Y-000750
+X-153000Y-000250
+X-148000Y-000250
+X-143000Y-000250
+X161000Y338642
+T05
+X-065600Y010250
+X-072500Y010250
+X-079501Y055251
+X-079498Y059251
+X-073502Y072748
+X-073499Y076751
+X-137600Y010250
+X-144500Y010250
+X-145502Y072748
+X-145499Y076751
+X-145502Y132748
+X-145499Y136751
+X-137369Y136874
+X-120400Y160300
+X-124600Y160300
+X-127500Y160750
+X-136500Y160750
+X-144500Y160750
+X-137600Y176750
+X-144500Y176750
+X-145502Y239248
+X-145499Y243251
+X-145502Y299248
+X-145499Y303251
+X-137369Y303374
+X-136500Y327250
+X-144500Y327250
+X-144500Y343250
+X-137600Y343250
+X-127500Y327250
+X-124600Y326800
+X-120400Y326800
+X-105629Y303374
+X-073499Y303251
+X-065369Y303374
+X-073502Y299248
+X-079498Y295251
+X-079501Y291251
+X-073499Y243251
+X-073502Y239248
+X-079498Y225751
+X-079501Y221751
+X-072500Y176750
+X-065600Y176750
+X-048400Y160300
+X-052600Y160300
+X-055500Y160750
+X-064500Y160750
+X-072500Y160750
+X-080500Y160750
+X-105629Y136874
+X-079501Y124751
+X-079498Y128751
+X-073502Y132748
+X-073499Y136751
+X-065369Y136874
+X-033629Y136874
+X-007501Y124751
+X-007498Y128751
+X007498Y132748
+X007501Y136751
+X015631Y136874
+X032600Y160300
+X028400Y160300
+X025500Y160750
+X016500Y160750
+X008500Y160750
+X-008500Y160750
+X008500Y176750
+X015400Y176750
+X-007501Y221751
+X-007498Y225751
+X007498Y239248
+X007501Y243251
+X-007501Y291251
+X-007498Y295251
+X007498Y299248
+X007501Y303251
+X015631Y303374
+X-008500Y327250
+X-033629Y303374
+X-048400Y326800
+X-052600Y326800
+X-055500Y327250
+X-064500Y327250
+X-072500Y327250
+X-080500Y327250
+X-065600Y343250
+X-072500Y343250
+X-079501Y388251
+X-079498Y392251
+X-073502Y405748
+X-073499Y409751
+X-145502Y405748
+X-145499Y409751
+X-145502Y465748
+X-145499Y469751
+X-137369Y469874
+X-144500Y493750
+X-136500Y493750
+X-127500Y493750
+X-124600Y493300
+X-120400Y493300
+X-105629Y469874
+X-079501Y457751
+X-079498Y461751
+X-073502Y465748
+X-073499Y469751
+X-065369Y469874
+X-080500Y493750
+X-072500Y493750
+X-064500Y493750
+X-055500Y493750
+X-052600Y493300
+X-048400Y493300
+X-033629Y469874
+X-007501Y457751
+X-007498Y461751
+X007498Y465748
+X007501Y469751
+X015631Y469874
+X-008500Y493750
+X008500Y493750
+X016500Y493750
+X025500Y493750
+X028400Y493300
+X032600Y493300
+X047371Y469874
+X073499Y457751
+X073502Y461751
+X079498Y465748
+X079501Y469751
+X087631Y469874
+X072500Y493750
+X080500Y493750
+X088500Y493750
+X097500Y493750
+X100400Y493300
+X104600Y493300
+X119371Y469874
+X144500Y493750
+X145502Y461751
+X145499Y457751
+X145502Y392251
+X145499Y388251
+X079501Y409751
+X079498Y405748
+X073502Y392251
+X073499Y388251
+X007501Y409751
+X007498Y405748
+X-007498Y392251
+X-007501Y388251
+X008500Y343250
+X015400Y343250
+X008500Y327250
+X016500Y327250
+X025500Y327250
+X028400Y326800
+X032600Y326800
+X047371Y303374
+X073499Y291251
+X073502Y295251
+X079498Y299248
+X079501Y303251
+X087631Y303374
+X072500Y327250
+X080500Y327250
+X088500Y327250
+X080500Y343250
+X087400Y343250
+X097500Y327250
+X100400Y326800
+X104600Y326800
+X119371Y303374
+X144500Y327250
+X145502Y295251
+X145499Y291251
+X145502Y225751
+X145499Y221751
+X079501Y243251
+X079498Y239248
+X073502Y225751
+X073499Y221751
+X080500Y176750
+X087400Y176750
+X104600Y160300
+X100400Y160300
+X097500Y160750
+X088500Y160750
+X080500Y160750
+X072500Y160750
+X047371Y136874
+X073499Y124751
+X073502Y128751
+X079498Y132748
+X079501Y136751
+X087631Y136874
+X119371Y136874
+X144500Y160750
+X145502Y128751
+X145499Y124751
+X145502Y059251
+X145499Y055251
+X087400Y010250
+X080500Y010250
+X073499Y055251
+X073502Y059251
+X079498Y072748
+X079501Y076751
+X015400Y010250
+X008500Y010250
+X-007501Y055251
+X-007498Y059251
+X007498Y072748
+X007501Y076751
+X161000Y342467
+T06
+X-145500Y241250
+X-145500Y301250
+X-073500Y301250
+X-079500Y293250
+X-073500Y241250
+X-079500Y223750
+X-007500Y223750
+X007500Y241250
+X-007500Y293250
+X007500Y301250
+X-007500Y390250
+X007500Y407750
+X-073500Y407750
+X-079500Y390250
+X-145500Y407750
+X-145500Y467750
+X-079500Y459750
+X-073500Y467750
+X-007500Y459750
+X007500Y467750
+X073500Y390250
+X079500Y407750
+X073500Y459750
+X079500Y467750
+X145500Y459750
+X145500Y390250
+X079500Y301250
+X073500Y293250
+X145500Y293250
+X145500Y223750
+X079500Y241250
+X073500Y223750
+X145500Y126750
+X145500Y057250
+X073500Y057250
+X079500Y074750
+X073500Y126750
+X079500Y134750
+X007500Y134750
+X-007500Y126750
+X007500Y074750
+X-007500Y057250
+X-073500Y134750
+X-079500Y126750
+X-073500Y074750
+X-079500Y057250
+X-145500Y074750
+X-145500Y134750
+X161000Y346417
+T07
+X-017750Y278499
+X-022751Y278499
+X-026876Y273124
+X-028644Y274892
+X-017000Y286749
+X-017000Y296749
+X-010249Y313749
+X-010249Y324750
+X-022751Y307750
+X-022751Y312751
+X-029500Y319751
+X-033035Y316215
+X-042499Y318499
+X-042499Y323500
+X-068499Y351126
+X-068499Y356124
+X-054501Y369624
+X-054501Y375624
+X-057315Y387046
+X-049952Y383920
+X-047501Y375624
+X-047501Y369624
+X-060500Y356124
+X-060500Y351126
+X-082249Y324750
+X-082249Y313749
+X-089000Y296749
+X-089000Y286749
+X-089750Y278499
+X-094751Y278499
+X-098876Y273124
+X-100644Y274892
+X-094751Y307750
+X-094751Y312751
+X-101500Y319751
+X-105035Y316215
+X-114499Y318499
+X-114499Y323500
+X-140499Y351126
+X-140499Y356124
+X-132500Y351126
+X-132500Y356124
+X-126501Y369624
+X-126501Y375624
+X-119501Y369624
+X-119501Y375624
+X-121952Y383920
+X-129315Y387046
+X-098876Y439624
+X-100644Y441392
+X-094751Y444999
+X-089750Y444999
+X-089000Y453249
+X-089000Y463249
+X-114499Y484999
+X-114499Y490000
+X-105035Y482715
+X-101500Y486251
+X-094751Y479251
+X-094751Y474250
+X-082249Y480249
+X-082249Y491250
+X-042499Y490000
+X-042499Y484999
+X-033035Y482715
+X-029500Y486251
+X-022751Y479251
+X-022751Y474250
+X-010249Y491250
+X-010249Y480249
+X-017000Y463249
+X-017000Y453249
+X-028644Y441392
+X-026876Y439624
+X-022751Y444999
+X-017750Y444999
+X038501Y484999
+X038501Y490000
+X047965Y482715
+X051500Y486251
+X058249Y479251
+X058249Y474250
+X064000Y463249
+X052356Y441392
+X054124Y439624
+X058249Y444999
+X063250Y444999
+X064000Y453249
+X070751Y480249
+X070751Y491250
+X110501Y490000
+X110501Y484999
+X119965Y482715
+X123500Y486251
+X130249Y479251
+X142751Y491250
+X142751Y480249
+X130249Y474250
+X136000Y463249
+X136000Y453249
+X135250Y444999
+X130249Y444999
+X124356Y441392
+X126124Y439624
+X095685Y387046
+X103048Y383920
+X098499Y375624
+X098499Y369624
+X105499Y375624
+X105499Y369624
+X092500Y356124
+X092500Y351126
+X084501Y351126
+X084501Y356124
+X031048Y383920
+X023685Y387046
+X026499Y375624
+X026499Y369624
+X033499Y375624
+X033499Y369624
+X020500Y356124
+X020500Y351126
+X012501Y356124
+X012501Y351126
+X038501Y323500
+X038501Y318499
+X047965Y316215
+X051500Y319751
+X058249Y312751
+X058249Y307750
+X064000Y296749
+X070751Y313749
+X070751Y324750
+X110501Y323500
+X110501Y318499
+X119965Y316215
+X123500Y319751
+X130249Y312751
+X142751Y324750
+X142751Y313749
+X130249Y307750
+X136000Y296749
+X136000Y286749
+X135250Y278499
+X130249Y278499
+X124356Y274892
+X126124Y273124
+X095685Y220546
+X103048Y217420
+X098499Y209124
+X105499Y209124
+X105499Y203124
+X098499Y203124
+X092500Y189624
+X092500Y184626
+X084501Y189624
+X084501Y184626
+X051500Y153251
+X038501Y151999
+X038501Y157000
+X047965Y149715
+X058249Y141250
+X058249Y146251
+X070751Y158250
+X070751Y147249
+X064000Y130249
+X064000Y120249
+X052356Y108392
+X054124Y106624
+X058249Y111999
+X063250Y111999
+X110501Y157000
+X110501Y151999
+X119965Y149715
+X123500Y153251
+X130249Y146251
+X142751Y158250
+X142751Y147249
+X130249Y141250
+X136000Y130249
+X136000Y120249
+X135250Y111999
+X130249Y111999
+X124356Y108392
+X126124Y106624
+X095685Y054046
+X103048Y050920
+X105499Y042624
+X105499Y036624
+X098499Y042624
+X098499Y036624
+X092500Y023124
+X092500Y018126
+X084501Y018126
+X084501Y023124
+X033499Y036624
+X020500Y023124
+X020500Y018126
+X012501Y018126
+X012501Y023124
+X026499Y036624
+X026499Y042624
+X033499Y042624
+X031048Y050920
+X023685Y054046
+X-017750Y111999
+X-017000Y120249
+X-022751Y111999
+X-028644Y108392
+X-026876Y106624
+X-057315Y054046
+X-049952Y050920
+X-047501Y042624
+X-047501Y036624
+X-054501Y042624
+X-054501Y036624
+X-060500Y023124
+X-060500Y018126
+X-068499Y018126
+X-068499Y023124
+X-119501Y036624
+X-132500Y023124
+X-132500Y018126
+X-140499Y018126
+X-140499Y023124
+X-126501Y036624
+X-126501Y042624
+X-119501Y042624
+X-121952Y050920
+X-129315Y054046
+X-098876Y106624
+X-100644Y108392
+X-094751Y111999
+X-089750Y111999
+X-089000Y120249
+X-089000Y130249
+X-094751Y141250
+X-082249Y147249
+X-082249Y158250
+X-094751Y146251
+X-101500Y153251
+X-105035Y149715
+X-114499Y151999
+X-114499Y157000
+X-140499Y184626
+X-140499Y189624
+X-132500Y184626
+X-132500Y189624
+X-126501Y203124
+X-126501Y209124
+X-121952Y217420
+X-129315Y220546
+X-119501Y209124
+X-119501Y203124
+X-057315Y220546
+X-049952Y217420
+X-047501Y209124
+X-047501Y203124
+X-054501Y209124
+X-054501Y203124
+X-060500Y189624
+X-060500Y184626
+X-068499Y189624
+X-068499Y184626
+X-042499Y157000
+X-042499Y151999
+X-033035Y149715
+X-029500Y153251
+X-022751Y146251
+X-022751Y141250
+X-017000Y130249
+X-010249Y147249
+X-010249Y158250
+X012501Y184626
+X012501Y189624
+X020500Y184626
+X020500Y189624
+X026499Y203124
+X026499Y209124
+X033499Y203124
+X033499Y209124
+X031048Y217420
+X023685Y220546
+X063250Y278499
+X064000Y286749
+X058249Y278499
+X054124Y273124
+X052356Y274892
+X161000Y350492
+T08
+X042875Y200376
+X047955Y200376
+X062501Y223124
+X069999Y223124
+X114875Y200376
+X119955Y200376
+X134501Y223124
+X141999Y223124
+X119955Y366876
+X141999Y389624
+X134501Y389624
+X114875Y366876
+X069999Y389624
+X062501Y389624
+X047955Y366876
+X042875Y366876
+X-011001Y389624
+X-018499Y389624
+X-033046Y366876
+X-038126Y366876
+X-083001Y389624
+X-090499Y389624
+X-110126Y366876
+X-105046Y366876
+X-011001Y223124
+X-018499Y223124
+X-033046Y200376
+X-038126Y200376
+X-083001Y223124
+X-090499Y223124
+X-105046Y200376
+X-110126Y200376
+X-090499Y056624
+X-110126Y033876
+X-105046Y033876
+X-083001Y056624
+X-038126Y033876
+X-033046Y033876
+X-018499Y056624
+X-011001Y056624
+X042875Y033876
+X047955Y033876
+X062501Y056624
+X069999Y056624
+X114875Y033876
+X119955Y033876
+X141999Y056624
+X134501Y056624
+X161000Y354642
+T09
+X113000Y394001
+X118001Y394001
+X128001Y394001
+X138126Y389375
+X138126Y397374
+X143749Y464001
+X143749Y471501
+X071749Y471501
+X071749Y464001
+X066126Y397374
+X066126Y389375
+X056001Y394001
+X046001Y394001
+X041000Y394001
+X-014874Y389375
+X-024999Y394001
+X-014874Y397374
+X-009251Y464001
+X-009251Y471501
+X-081251Y471501
+X-081251Y464001
+X-112000Y394001
+X-106999Y394001
+X-096999Y394001
+X-086874Y397374
+X-086874Y389375
+X-040000Y394001
+X-034999Y394001
+X-009251Y305001
+X-009251Y297501
+X-081251Y305001
+X-081251Y297501
+X-112000Y227501
+X-106999Y227501
+X-096999Y227501
+X-086874Y222875
+X-086874Y230874
+X-040000Y227501
+X-034999Y227501
+X-024999Y227501
+X-014874Y230874
+X-014874Y222875
+X-009251Y138501
+X-009251Y131001
+X-081251Y138501
+X-081251Y131001
+X-112000Y061001
+X-106999Y061001
+X-096999Y061001
+X-086874Y056375
+X-086874Y064374
+X-040000Y061001
+X-034999Y061001
+X-024999Y061001
+X-014874Y056375
+X-014874Y064374
+X041000Y061001
+X046001Y061001
+X056001Y061001
+X066126Y056375
+X066126Y064374
+X113000Y061001
+X118001Y061001
+X128001Y061001
+X138126Y056375
+X138126Y064374
+X143749Y131001
+X143749Y138501
+X071749Y131001
+X071749Y138501
+X138126Y222875
+X138126Y230874
+X128001Y227501
+X118001Y227501
+X113000Y227501
+X066126Y230874
+X066126Y222875
+X056001Y227501
+X046001Y227501
+X041000Y227501
+X071749Y297501
+X071749Y305001
+X143749Y297501
+X143749Y305001
+X161000Y358892
+T10
+X115499Y263899
+X109500Y263899
+X103500Y263899
+X097501Y263899
+X091499Y263899
+X043499Y263899
+X037500Y263899
+X031500Y263899
+X025501Y263899
+X019499Y263899
+X-133501Y430399
+X-127499Y430399
+X-121500Y430399
+X-115500Y430399
+X-109501Y430399
+X-061501Y430399
+X-055499Y430399
+X-049500Y430399
+X-043500Y430399
+X-037501Y430399
+X019499Y430399
+X025501Y430399
+X031500Y430399
+X037500Y430399
+X043499Y430399
+X091499Y430399
+X097501Y430399
+X103500Y430399
+X109500Y430399
+X115499Y430399
+X-037501Y263899
+X-043500Y263899
+X-049500Y263899
+X-055499Y263899
+X-061501Y263899
+X-109501Y263899
+X-115500Y263899
+X-121500Y263899
+X-127499Y263899
+X-133501Y263899
+X-133501Y097399
+X-127499Y097399
+X-121500Y097399
+X-115500Y097399
+X-109501Y097399
+X-061501Y097399
+X-055499Y097399
+X-049500Y097399
+X-043500Y097399
+X-037501Y097399
+X019499Y097399
+X025501Y097399
+X031500Y097399
+X037500Y097399
+X043499Y097399
+X091499Y097399
+X097501Y097399
+X103500Y097399
+X109500Y097399
+X115499Y097399
+X161000Y363342
+T11
+X103500Y312301
+X097501Y312301
+X031500Y312301
+X025501Y312301
+X-127499Y478801
+X-121500Y478801
+X-055499Y478801
+X-049500Y478801
+X025501Y478801
+X031500Y478801
+X097501Y478801
+X103500Y478801
+X-049500Y312301
+X-055499Y312301
+X-121500Y312301
+X-127499Y312301
+X-127499Y145801
+X-121500Y145801
+X-055499Y145801
+X-049500Y145801
+X025501Y145801
+X031500Y145801
+X097501Y145801
+X103500Y145801
+X161000Y367992
+T12
+X142500Y143749
+X124501Y201001
+X110501Y203500
+X070500Y143749
+X052501Y201001
+X038501Y203500
+X142500Y310249
+X124501Y367501
+X110501Y370000
+X070500Y310249
+X052501Y367501
+X038501Y370000
+X142500Y476749
+X070500Y476749
+X-010501Y476749
+X-082501Y476749
+X-114499Y370000
+X-100499Y367501
+X-082501Y310249
+X-042499Y370000
+X-028499Y367501
+X-010501Y310249
+X-114499Y203500
+X-100499Y201001
+X-082501Y143749
+X-028499Y201001
+X-042499Y203500
+X-010501Y143749
+X-114499Y037000
+X-100499Y034501
+X-042499Y037000
+X-028499Y034501
+X038501Y037000
+X052501Y034501
+X110501Y037000
+X124501Y034501
+X161000Y372792
+T13
+X109500Y312301
+X037500Y312301
+X-115500Y478801
+X-043500Y478801
+X037500Y478801
+X109500Y478801
+X-043500Y312301
+X-115500Y312301
+X-115500Y145801
+X-043500Y145801
+X037500Y145801
+X109500Y145801
+X161000Y377992
+T14
+X138250Y313500
+X138250Y319251
+X066250Y313500
+X066250Y319251
+X-086750Y480000
+X-086750Y485751
+X-014750Y480000
+X-014750Y485751
+X066250Y480000
+X066250Y485751
+X138250Y485751
+X138250Y480000
+X-014750Y319251
+X-014750Y313500
+X-086750Y319251
+X-086750Y313500
+X-086750Y152751
+X-086750Y147000
+X-014750Y147000
+X-014750Y152751
+X066250Y152751
+X066250Y147000
+X138250Y147000
+X138250Y152751
+X161000Y383542
+T15
+X150500Y024750
+X103674Y110915
+X103674Y130915
+X150500Y149250
+X150500Y191250
+X103674Y277415
+X103674Y297415
+X150500Y315750
+X150500Y357750
+X103674Y443915
+X150500Y482250
+X103674Y463915
+X031674Y443915
+X031674Y463915
+X002500Y477250
+X-002500Y482250
+X-049327Y443915
+X-049327Y463915
+X-121327Y463915
+X-150500Y477250
+X-121327Y443915
+X-150500Y362750
+X-150500Y310750
+X-121327Y297415
+X-121327Y277415
+X-049327Y277415
+X-049327Y297415
+X-002500Y357750
+X002500Y362750
+X-002500Y315750
+X002500Y310750
+X031674Y297415
+X031674Y277415
+X002500Y196250
+X-002500Y191250
+X002500Y144250
+X031674Y130915
+X031674Y110915
+X-002500Y149250
+X-049327Y130915
+X-150500Y196250
+X-150500Y144250
+X-121327Y130915
+X-121327Y110915
+X-150500Y029750
+X-049327Y110915
+X-002500Y024750
+X002500Y029750
+X161000Y389392
+T16
+X-148000Y164250
+X-148000Y330750
+X-148000Y497250
+X161000Y395992
+T17
+X083351Y203836G85X083351Y203236
+X083351Y207646G85X083351Y207046
+X083351Y211456G85X083351Y210856
+X083351Y215266G85X083351Y214666
+X083351Y220335G85X083351Y219736
+X083351Y224145G85X083351Y223546
+X083351Y227955G85X083351Y227356
+X083351Y231765G85X083351Y231166
+X011351Y203836G85X011351Y203236
+X011351Y207646G85X011351Y207046
+X011351Y211456G85X011351Y210856
+X011351Y215266G85X011351Y214666
+X011351Y220335G85X011351Y219736
+X011351Y224145G85X011351Y223546
+X011351Y227955G85X011351Y227356
+X011351Y231765G85X011351Y231166
+X083351Y370336G85X083351Y369736
+X083351Y374146G85X083351Y373546
+X083351Y377956G85X083351Y377356
+X083351Y381766G85X083351Y381166
+X083351Y386835G85X083351Y386236
+X083351Y390645G85X083351Y390046
+X083351Y394455G85X083351Y393856
+X083351Y398265G85X083351Y397666
+X011351Y370336G85X011351Y369736
+X011351Y374146G85X011351Y373546
+X011351Y377956G85X011351Y377356
+X011351Y381766G85X011351Y381166
+X011351Y386835G85X011351Y386236
+X011351Y390645G85X011351Y390046
+X011351Y394455G85X011351Y393856
+X011351Y398265G85X011351Y397666
+X-069649Y398265G85X-069649Y397666
+X-069649Y394455G85X-069649Y393856
+X-069649Y390645G85X-069649Y390046
+X-069649Y386835G85X-069649Y386236
+X-069649Y381766G85X-069649Y381166
+X-069649Y377956G85X-069649Y377356
+X-069649Y374146G85X-069649Y373546
+X-069649Y370336G85X-069649Y369736
+X-141649Y398265G85X-141649Y397666
+X-141649Y394455G85X-141649Y393856
+X-141649Y390645G85X-141649Y390046
+X-141649Y386835G85X-141649Y386236
+X-141649Y381766G85X-141649Y381166
+X-141649Y377956G85X-141649Y377356
+X-141649Y374146G85X-141649Y373546
+X-141649Y370336G85X-141649Y369736
+X-069649Y231765G85X-069649Y231166
+X-069649Y227955G85X-069649Y227356
+X-069649Y224145G85X-069649Y223546
+X-069649Y220335G85X-069649Y219736
+X-069649Y215266G85X-069649Y214666
+X-069649Y211456G85X-069649Y210856
+X-069649Y207646G85X-069649Y207046
+X-069649Y203836G85X-069649Y203236
+X-141649Y231765G85X-141649Y231166
+X-141649Y227955G85X-141649Y227356
+X-141649Y224145G85X-141649Y223546
+X-141649Y220335G85X-141649Y219736
+X-141649Y215266G85X-141649Y214666
+X-141649Y211456G85X-141649Y210856
+X-141649Y207646G85X-141649Y207046
+X-141649Y203836G85X-141649Y203236
+X-141649Y065265G85X-141649Y064666
+X-141649Y061455G85X-141649Y060856
+X-141649Y057645G85X-141649Y057046
+X-141649Y053835G85X-141649Y053236
+X-141649Y037336G85X-141649Y036736
+X-141649Y041146G85X-141649Y040546
+X-141649Y044956G85X-141649Y044356
+X-141649Y048766G85X-141649Y048166
+X-069649Y037336G85X-069649Y036736
+X-069649Y041146G85X-069649Y040546
+X-069649Y044956G85X-069649Y044356
+X-069649Y048766G85X-069649Y048166
+X-069649Y053835G85X-069649Y053236
+X-069649Y057645G85X-069649Y057046
+X-069649Y061455G85X-069649Y060856
+X-069649Y065265G85X-069649Y064666
+X011351Y037336G85X011351Y036736
+X011351Y041146G85X011351Y040546
+X011351Y044956G85X011351Y044356
+X011351Y048766G85X011351Y048166
+X011351Y053835G85X011351Y053236
+X011351Y057645G85X011351Y057046
+X011351Y061455G85X011351Y060856
+X011351Y065265G85X011351Y064666
+X083351Y037336G85X083351Y036736
+X083351Y041146G85X083351Y040546
+X083351Y044956G85X083351Y044356
+X083351Y048766G85X083351Y048166
+X083351Y053835G85X083351Y053236
+X083351Y057645G85X083351Y057046
+X083351Y061455G85X083351Y060856
+X083351Y065265G85X083351Y064666
+X161000Y401395
+T18
+X071701Y283099G85X071701Y281999
+X081301Y277800G85X081301Y276701
+X143701Y283099G85X143701Y281999
+X143701Y449599G85X143701Y448499
+X081301Y444300G85X081301Y443201
+X071701Y449599G85X071701Y448499
+X009301Y444300G85X009301Y443201
+X-009299Y449599G85X-009299Y448499
+X-071699Y444300G85X-071699Y443201
+X-081299Y449599G85X-081299Y448499
+X-143699Y444300G85X-143699Y443201
+X-143699Y277800G85X-143699Y276701
+X-081299Y283099G85X-081299Y281999
+X-071699Y277800G85X-071699Y276701
+X-009299Y283099G85X-009299Y281999
+X009301Y277800G85X009301Y276701
+X-143699Y111300G85X-143699Y110201
+X-081299Y116599G85X-081299Y115499
+X-071699Y111300G85X-071699Y110201
+X-009299Y116599G85X-009299Y115499
+X009301Y111300G85X009301Y110201
+X071701Y116599G85X071701Y115499
+X081301Y111300G85X081301Y110201
+X143701Y116599G85X143701Y115499
+X161000Y405249
+T19
+X081250Y198751G85X081250Y197750
+X143749Y251250G85X143749Y250249
+X071749Y251250G85X071749Y250249
+X009250Y198751G85X009250Y197750
+X-009251Y251250G85X-009251Y250249
+X081250Y365251G85X081250Y364250
+X143749Y417750G85X143749Y416749
+X071749Y417750G85X071749Y416749
+X009250Y365251G85X009250Y364250
+X-009251Y417750G85X-009251Y416749
+X-071750Y365251G85X-071750Y364250
+X-081251Y417750G85X-081251Y416749
+X-143750Y365251G85X-143750Y364250
+X-081251Y251250G85X-081251Y250249
+X-071750Y198751G85X-071750Y197750
+X-143750Y198751G85X-143750Y197750
+X-081251Y084750G85X-081251Y083749
+X-143750Y032251G85X-143750Y031250
+X-071750Y032251G85X-071750Y031250
+X-009251Y084750G85X-009251Y083749
+X009250Y032251G85X009250Y031250
+X071749Y084750G85X071749Y083749
+X081250Y032251G85X081250Y031250
+X143749Y084750G85X143749Y083749
+X161000Y409252
+T20
+X-083900Y258560G85X-083900Y259360
+X-083900Y261100G85X-083900Y261900
+X-083900Y263640G85X-083900Y264440
+X-083900Y270810G85X-083900Y271610
+X-083900Y273350G85X-083900Y274150
+X-083900Y275890G85X-083900Y276690
+X-011900Y258560G85X-011900Y259360
+X-011900Y261100G85X-011900Y261900
+X-011900Y263640G85X-011900Y264440
+X-011900Y270810G85X-011900Y271610
+X-011900Y273350G85X-011900Y274150
+X-011900Y275890G85X-011900Y276690
+X-083900Y425060G85X-083900Y425860
+X-083900Y427600G85X-083900Y428400
+X-083900Y430140G85X-083900Y430940
+X-083900Y437310G85X-083900Y438110
+X-083900Y439850G85X-083900Y440650
+X-083900Y442390G85X-083900Y443190
+X-011900Y425060G85X-011900Y425860
+X-011900Y427600G85X-011900Y428400
+X-011900Y430140G85X-011900Y430940
+X-011900Y437310G85X-011900Y438110
+X-011900Y439850G85X-011900Y440650
+X-011900Y442390G85X-011900Y443190
+X069100Y442390G85X069100Y443190
+X069100Y439850G85X069100Y440650
+X069100Y437310G85X069100Y438110
+X069100Y430140G85X069100Y430940
+X069100Y427600G85X069100Y428400
+X069100Y425060G85X069100Y425860
+X141100Y442390G85X141100Y443190
+X141100Y439850G85X141100Y440650
+X141100Y437310G85X141100Y438110
+X141100Y430140G85X141100Y430940
+X141100Y427600G85X141100Y428400
+X141100Y425060G85X141100Y425860
+X069100Y275890G85X069100Y276690
+X069100Y273350G85X069100Y274150
+X069100Y270810G85X069100Y271610
+X069100Y263640G85X069100Y264440
+X069100Y261100G85X069100Y261900
+X069100Y258560G85X069100Y259360
+X141100Y275890G85X141100Y276690
+X141100Y273350G85X141100Y274150
+X141100Y270810G85X141100Y271610
+X141100Y263640G85X141100Y264440
+X141100Y261100G85X141100Y261900
+X141100Y258560G85X141100Y259360
+X141100Y109390G85X141100Y110190
+X141100Y106850G85X141100Y107650
+X141100Y104310G85X141100Y105110
+X141100Y097140G85X141100Y097940
+X141100Y094600G85X141100Y095400
+X141100Y092060G85X141100Y092860
+X069100Y109390G85X069100Y110190
+X069100Y106850G85X069100Y107650
+X069100Y104310G85X069100Y105110
+X069100Y092060G85X069100Y092860
+X069100Y094600G85X069100Y095400
+X069100Y097140G85X069100Y097940
+X-011900Y092060G85X-011900Y092860
+X-011900Y094600G85X-011900Y095400
+X-011900Y097140G85X-011900Y097940
+X-011900Y104310G85X-011900Y105110
+X-011900Y106850G85X-011900Y107650
+X-011900Y109390G85X-011900Y110190
+X-083900Y092060G85X-083900Y092860
+X-083900Y094600G85X-083900Y095400
+X-083900Y097140G85X-083900Y097940
+X-083900Y104310G85X-083900Y105110
+X-083900Y106850G85X-083900Y107650
+X-083900Y109390G85X-083900Y110190
+X161000Y413308
+T21
+X-099600Y209751G85X-099400Y209737
+X-099600Y217249G85X-099400Y217235
+X-114601Y217249G85X-114401Y217235
+X-114601Y209751G85X-114401Y209737
+X-133501Y198151G85X-133487Y198349
+X-133501Y213150G85X-133487Y213350
+X-135876Y218400G85X-135862Y218600
+X-135876Y233401G85X-135862Y233599
+X-126600Y258750G85X-126400Y258736
+X-141599Y258750G85X-141401Y258737
+X-133501Y364651G85X-133487Y364849
+X-133501Y379650G85X-133487Y379850
+X-135876Y384900G85X-135862Y385100
+X-135876Y399901G85X-135862Y400099
+X-126600Y425250G85X-126400Y425236
+X-141599Y425250G85X-141401Y425237
+X-114601Y383749G85X-114401Y383735
+X-114601Y376251G85X-114401Y376237
+X-099600Y376251G85X-099400Y376237
+X-099600Y383749G85X-099400Y383735
+X-069599Y425250G85X-069401Y425237
+X-054600Y425250G85X-054400Y425236
+X-063876Y399901G85X-063862Y400099
+X-063876Y384900G85X-063862Y385100
+X-061501Y379650G85X-061487Y379850
+X-061501Y364651G85X-061487Y364849
+X-042601Y376251G85X-042401Y376237
+X-042601Y383749G85X-042401Y383735
+X-027600Y376251G85X-027400Y376237
+X-027600Y383749G85X-027400Y383735
+X011401Y425250G85X011599Y425237
+X026400Y425250G85X026600Y425236
+X017124Y399901G85X017138Y400099
+X017124Y384900G85X017138Y385100
+X019499Y379650G85X019513Y379850
+X019499Y364651G85X019513Y364849
+X038399Y376251G85X038599Y376237
+X038399Y383749G85X038599Y383735
+X053400Y376251G85X053601Y376237
+X053400Y383749G85X053601Y383735
+X083401Y425250G85X083599Y425237
+X098400Y425250G85X098600Y425236
+X089124Y399901G85X089138Y400099
+X089124Y384900G85X089138Y385100
+X091499Y379650G85X091513Y379850
+X110399Y383749G85X110599Y383735
+X125400Y383749G85X125601Y383735
+X125400Y376251G85X125601Y376237
+X110399Y376251G85X110599Y376237
+X091499Y364651G85X091513Y364849
+X083401Y258750G85X083599Y258737
+X098400Y258750G85X098600Y258736
+X125400Y217249G85X125601Y217235
+X125400Y209751G85X125601Y209737
+X110399Y217249G85X110599Y217235
+X110399Y209751G85X110599Y209737
+X091499Y198151G85X091513Y198349
+X091499Y213150G85X091513Y213350
+X089124Y218400G85X089138Y218600
+X089124Y233401G85X089138Y233599
+X053400Y209751G85X053601Y209737
+X053400Y217249G85X053601Y217235
+X038399Y217249G85X038599Y217235
+X038399Y209751G85X038599Y209737
+X019499Y198151G85X019513Y198349
+X019499Y213150G85X019513Y213350
+X017124Y218400G85X017138Y218600
+X017124Y233401G85X017138Y233599
+X026400Y258750G85X026600Y258736
+X011401Y258750G85X011599Y258737
+X-054600Y258750G85X-054400Y258736
+X-069599Y258750G85X-069401Y258737
+X-063876Y233401G85X-063862Y233599
+X-063876Y218400G85X-063862Y218600
+X-061501Y213150G85X-061487Y213350
+X-061501Y198151G85X-061487Y198349
+X-042601Y209751G85X-042401Y209737
+X-042601Y217249G85X-042401Y217235
+X-027600Y217249G85X-027400Y217235
+X-027600Y209751G85X-027400Y209737
+X083401Y092250G85X083599Y092237
+X098400Y092250G85X098600Y092236
+X110399Y050749G85X110599Y050735
+X125400Y050749G85X125601Y050735
+X125400Y043251G85X125601Y043237
+X110399Y043251G85X110599Y043237
+X091499Y031651G85X091513Y031849
+X091499Y046650G85X091513Y046850
+X089124Y051900G85X089138Y052100
+X089124Y066901G85X089138Y067099
+X053400Y043251G85X053601Y043237
+X053400Y050749G85X053601Y050735
+X038399Y050749G85X038599Y050735
+X038399Y043251G85X038599Y043237
+X019499Y031651G85X019513Y031849
+X019499Y046650G85X019513Y046850
+X017124Y051900G85X017138Y052100
+X017124Y066901G85X017138Y067099
+X026400Y092250G85X026600Y092236
+X011401Y092250G85X011599Y092237
+X-027600Y050749G85X-027400Y050735
+X-027600Y043251G85X-027400Y043237
+X-042601Y050749G85X-042401Y050735
+X-042601Y043251G85X-042401Y043237
+X-061501Y031651G85X-061487Y031849
+X-061501Y046650G85X-061487Y046850
+X-063876Y051900G85X-063862Y052100
+X-063876Y066901G85X-063862Y067099
+X-054600Y092250G85X-054400Y092236
+X-069599Y092250G85X-069401Y092237
+X-099600Y050749G85X-099400Y050735
+X-099600Y043251G85X-099400Y043237
+X-114601Y050749G85X-114401Y050735
+X-114601Y043251G85X-114401Y043237
+X-133501Y031651G85X-133487Y031849
+X-133501Y046650G85X-133487Y046850
+X-135876Y051900G85X-135862Y052100
+X-135876Y066901G85X-135862Y067099
+X-141599Y092250G85X-141401Y092237
+X-126600Y092250G85X-126400Y092236
+X161000Y417464
+T22
+X091500Y164250G85X092537Y164195
+X091500Y330750G85X092537Y330695
+X091500Y497250G85X092537Y497195
+X161000Y423118
+T23
+X083351Y203836G85X083351Y203236
+X083351Y207646G85X083351Y207046
+X083351Y211456G85X083351Y210856
+X083351Y215266G85X083351Y214666
+X083351Y220335G85X083351Y219736
+X083351Y224145G85X083351Y223546
+X083351Y227955G85X083351Y227356
+X083351Y231765G85X083351Y231166
+X011351Y203836G85X011351Y203236
+X011351Y207646G85X011351Y207046
+X011351Y211456G85X011351Y210856
+X011351Y215266G85X011351Y214666
+X011351Y220335G85X011351Y219736
+X011351Y224145G85X011351Y223546
+X011351Y227955G85X011351Y227356
+X011351Y231765G85X011351Y231166
+X083351Y370336G85X083351Y369736
+X083351Y374146G85X083351Y373546
+X083351Y377956G85X083351Y377356
+X083351Y381766G85X083351Y381166
+X083351Y386835G85X083351Y386236
+X083351Y390645G85X083351Y390046
+X083351Y394455G85X083351Y393856
+X083351Y398265G85X083351Y397666
+X011351Y370336G85X011351Y369736
+X011351Y374146G85X011351Y373546
+X011351Y377956G85X011351Y377356
+X011351Y381766G85X011351Y381166
+X011351Y386835G85X011351Y386236
+X011351Y390645G85X011351Y390046
+X011351Y394455G85X011351Y393856
+X011351Y398265G85X011351Y397666
+X-069649Y398265G85X-069649Y397666
+X-069649Y394455G85X-069649Y393856
+X-069649Y390645G85X-069649Y390046
+X-069649Y386835G85X-069649Y386236
+X-069649Y381766G85X-069649Y381166
+X-069649Y377956G85X-069649Y377356
+X-069649Y374146G85X-069649Y373546
+X-069649Y370336G85X-069649Y369736
+X-141649Y398265G85X-141649Y397666
+X-141649Y394455G85X-141649Y393856
+X-141649Y390645G85X-141649Y390046
+X-141649Y386835G85X-141649Y386236
+X-141649Y381766G85X-141649Y381166
+X-141649Y377956G85X-141649Y377356
+X-141649Y374146G85X-141649Y373546
+X-141649Y370336G85X-141649Y369736
+X-069649Y231765G85X-069649Y231166
+X-069649Y227955G85X-069649Y227356
+X-069649Y224145G85X-069649Y223546
+X-069649Y220335G85X-069649Y219736
+X-069649Y215266G85X-069649Y214666
+X-069649Y211456G85X-069649Y210856
+X-069649Y207646G85X-069649Y207046
+X-069649Y203836G85X-069649Y203236
+X-141649Y231765G85X-141649Y231166
+X-141649Y227955G85X-141649Y227356
+X-141649Y224145G85X-141649Y223546
+X-141649Y220335G85X-141649Y219736
+X-141649Y215266G85X-141649Y214666
+X-141649Y211456G85X-141649Y210856
+X-141649Y207646G85X-141649Y207046
+X-141649Y203836G85X-141649Y203236
+X-141649Y065265G85X-141649Y064666
+X-141649Y061455G85X-141649Y060856
+X-141649Y057645G85X-141649Y057046
+X-141649Y053835G85X-141649Y053236
+X-141649Y037336G85X-141649Y036736
+X-141649Y041146G85X-141649Y040546
+X-141649Y044956G85X-141649Y044356
+X-141649Y048766G85X-141649Y048166
+X-069649Y037336G85X-069649Y036736
+X-069649Y041146G85X-069649Y040546
+X-069649Y044956G85X-069649Y044356
+X-069649Y048766G85X-069649Y048166
+X-069649Y053835G85X-069649Y053236
+X-069649Y057645G85X-069649Y057046
+X-069649Y061455G85X-069649Y060856
+X-069649Y065265G85X-069649Y064666
+X011351Y037336G85X011351Y036736
+X011351Y041146G85X011351Y040546
+X011351Y044956G85X011351Y044356
+X011351Y048766G85X011351Y048166
+X011351Y053835G85X011351Y053236
+X011351Y057645G85X011351Y057046
+X011351Y061455G85X011351Y060856
+X011351Y065265G85X011351Y064666
+X083351Y037336G85X083351Y036736
+X083351Y041146G85X083351Y040546
+X083351Y044956G85X083351Y044356
+X083351Y048766G85X083351Y048166
+X083351Y053835G85X083351Y053236
+X083351Y057645G85X083351Y057046
+X083351Y061455G85X083351Y060856
+X083351Y065265G85X083351Y064666
+X161000Y428520
+T24
+X-143699Y277800G85X-143699Y276701
+X-081299Y283099G85X-081299Y281999
+X-071699Y277800G85X-071699Y276701
+X-081251Y251250G85X-081251Y250249
+X-071750Y198751G85X-071750Y197750
+X-143750Y198751G85X-143750Y197750
+X-143699Y111300G85X-143699Y110201
+X-143750Y032251G85X-143750Y031250
+X-071750Y032251G85X-071750Y031250
+X-081251Y084750G85X-081251Y083749
+X-081299Y116599G85X-081299Y115499
+X-071699Y111300G85X-071699Y110201
+X-009299Y116599G85X-009299Y115499
+X009301Y111300G85X009301Y110201
+X-009251Y084750G85X-009251Y083749
+X009250Y032251G85X009250Y031250
+X071749Y084750G85X071749Y083749
+X081250Y032251G85X081250Y031250
+X143749Y084750G85X143749Y083749
+X143701Y116599G85X143701Y115499
+X081301Y111300G85X081301Y110201
+X071701Y116599G85X071701Y115499
+X009250Y198751G85X009250Y197750
+X-009251Y251250G85X-009251Y250249
+X-009299Y283099G85X-009299Y281999
+X009301Y277800G85X009301Y276701
+X071701Y283099G85X071701Y281999
+X081301Y277800G85X081301Y276701
+X071749Y251250G85X071749Y250249
+X081250Y198751G85X081250Y197750
+X143749Y251250G85X143749Y250249
+X143701Y283099G85X143701Y281999
+X081250Y365251G85X081250Y364250
+X143749Y417750G85X143749Y416749
+X143701Y449599G85X143701Y448499
+X081301Y444300G85X081301Y443201
+X071701Y449599G85X071701Y448499
+X071749Y417750G85X071749Y416749
+X009250Y365251G85X009250Y364250
+X-009251Y417750G85X-009251Y416749
+X009301Y444300G85X009301Y443201
+X-009299Y449599G85X-009299Y448499
+X-071699Y444300G85X-071699Y443201
+X-081299Y449599G85X-081299Y448499
+X-081251Y417750G85X-081251Y416749
+X-071750Y365251G85X-071750Y364250
+X-143699Y444300G85X-143699Y443201
+X-143750Y365251G85X-143750Y364250
+X161000Y432373
+T25
+X-083900Y258560G85X-083900Y259360
+X-083900Y261100G85X-083900Y261900
+X-083900Y263640G85X-083900Y264440
+X-083900Y270810G85X-083900Y271610
+X-083900Y273350G85X-083900Y274150
+X-083900Y275890G85X-083900Y276690
+X-011900Y258560G85X-011900Y259360
+X-011900Y261100G85X-011900Y261900
+X-011900Y263640G85X-011900Y264440
+X-011900Y270810G85X-011900Y271610
+X-011900Y273350G85X-011900Y274150
+X-011900Y275890G85X-011900Y276690
+X-083900Y425060G85X-083900Y425860
+X-083900Y427600G85X-083900Y428400
+X-083900Y430140G85X-083900Y430940
+X-083900Y437310G85X-083900Y438110
+X-083900Y439850G85X-083900Y440650
+X-083900Y442390G85X-083900Y443190
+X-011900Y425060G85X-011900Y425860
+X-011900Y427600G85X-011900Y428400
+X-011900Y430140G85X-011900Y430940
+X-011900Y437310G85X-011900Y438110
+X-011900Y439850G85X-011900Y440650
+X-011900Y442390G85X-011900Y443190
+X069100Y442390G85X069100Y443190
+X069100Y439850G85X069100Y440650
+X069100Y437310G85X069100Y438110
+X069100Y430140G85X069100Y430940
+X069100Y427600G85X069100Y428400
+X069100Y425060G85X069100Y425860
+X141100Y442390G85X141100Y443190
+X141100Y439850G85X141100Y440650
+X141100Y437310G85X141100Y438110
+X141100Y430140G85X141100Y430940
+X141100Y427600G85X141100Y428400
+X141100Y425060G85X141100Y425860
+X069100Y275890G85X069100Y276690
+X069100Y273350G85X069100Y274150
+X069100Y270810G85X069100Y271610
+X069100Y263640G85X069100Y264440
+X069100Y261100G85X069100Y261900
+X069100Y258560G85X069100Y259360
+X141100Y275890G85X141100Y276690
+X141100Y273350G85X141100Y274150
+X141100Y270810G85X141100Y271610
+X141100Y263640G85X141100Y264440
+X141100Y261100G85X141100Y261900
+X141100Y258560G85X141100Y259360
+X141100Y109390G85X141100Y110190
+X141100Y106850G85X141100Y107650
+X141100Y104310G85X141100Y105110
+X141100Y097140G85X141100Y097940
+X141100Y094600G85X141100Y095400
+X141100Y092060G85X141100Y092860
+X069100Y109390G85X069100Y110190
+X069100Y106850G85X069100Y107650
+X069100Y104310G85X069100Y105110
+X069100Y092060G85X069100Y092860
+X069100Y094600G85X069100Y095400
+X069100Y097140G85X069100Y097940
+X-011900Y092060G85X-011900Y092860
+X-011900Y094600G85X-011900Y095400
+X-011900Y097140G85X-011900Y097940
+X-011900Y104310G85X-011900Y105110
+X-011900Y106850G85X-011900Y107650
+X-011900Y109390G85X-011900Y110190
+X-083900Y092060G85X-083900Y092860
+X-083900Y094600G85X-083900Y095400
+X-083900Y097140G85X-083900Y097940
+X-083900Y104310G85X-083900Y105110
+X-083900Y106850G85X-083900Y107650
+X-083900Y109390G85X-083900Y110190
+X161000Y436426
+T26
+X-099600Y209751G85X-099399Y209751
+X-099600Y217249G85X-099399Y217249
+X-114601Y217249G85X-114400Y217249
+X-114601Y209751G85X-114400Y209751
+X-133501Y198151G85X-133501Y198349
+X-133501Y213150G85X-133501Y213350
+X-135876Y218400G85X-135876Y218601
+X-135876Y233401G85X-135876Y233599
+X-126600Y258750G85X-126399Y258750
+X-141599Y258750G85X-141401Y258750
+X-133501Y364651G85X-133501Y364849
+X-133501Y379650G85X-133501Y379850
+X-135876Y384900G85X-135876Y385101
+X-135876Y399901G85X-135876Y400099
+X-126600Y425250G85X-126399Y425250
+X-141599Y425250G85X-141401Y425250
+X-114601Y383749G85X-114400Y383749
+X-114601Y376251G85X-114400Y376251
+X-099600Y376251G85X-099399Y376251
+X-099600Y383749G85X-099399Y383749
+X-069599Y425250G85X-069401Y425250
+X-054600Y425250G85X-054399Y425250
+X-063876Y399901G85X-063876Y400099
+X-063876Y384900G85X-063876Y385101
+X-061501Y379650G85X-061501Y379850
+X-061501Y364651G85X-061501Y364849
+X-042601Y376251G85X-042400Y376251
+X-042601Y383749G85X-042400Y383749
+X-027600Y376251G85X-027399Y376251
+X-027600Y383749G85X-027399Y383749
+X011401Y425250G85X011600Y425250
+X026400Y425250G85X026601Y425250
+X017124Y399901G85X017124Y400099
+X017124Y384900G85X017124Y385101
+X019499Y379650G85X019499Y379850
+X019499Y364651G85X019499Y364849
+X038399Y376251G85X038600Y376251
+X038399Y383749G85X038600Y383749
+X053400Y376251G85X053601Y376251
+X053400Y383749G85X053601Y383749
+X083401Y425250G85X083600Y425250
+X098400Y425250G85X098601Y425250
+X089124Y399901G85X089124Y400099
+X089124Y384900G85X089124Y385101
+X091499Y379650G85X091499Y379850
+X110399Y383749G85X110600Y383749
+X125400Y383749G85X125601Y383749
+X125400Y376251G85X125601Y376251
+X110399Y376251G85X110600Y376251
+X091499Y364651G85X091499Y364849
+X083401Y258750G85X083600Y258750
+X098400Y258750G85X098601Y258750
+X125400Y217249G85X125601Y217249
+X125400Y209751G85X125601Y209751
+X110399Y217249G85X110600Y217249
+X110399Y209751G85X110600Y209751
+X091499Y198151G85X091499Y198349
+X091499Y213150G85X091499Y213350
+X089124Y218400G85X089124Y218601
+X089124Y233401G85X089124Y233599
+X053400Y209751G85X053601Y209751
+X053400Y217249G85X053601Y217249
+X038399Y217249G85X038600Y217249
+X038399Y209751G85X038600Y209751
+X019499Y198151G85X019499Y198349
+X019499Y213150G85X019499Y213350
+X017124Y218400G85X017124Y218601
+X017124Y233401G85X017124Y233599
+X026400Y258750G85X026601Y258750
+X011401Y258750G85X011600Y258750
+X-054600Y258750G85X-054399Y258750
+X-069599Y258750G85X-069401Y258750
+X-063876Y233401G85X-063876Y233599
+X-063876Y218400G85X-063876Y218601
+X-061501Y213150G85X-061501Y213350
+X-061501Y198151G85X-061501Y198349
+X-042601Y209751G85X-042400Y209751
+X-042601Y217249G85X-042400Y217249
+X-027600Y217249G85X-027399Y217249
+X-027600Y209751G85X-027399Y209751
+X083401Y092250G85X083600Y092250
+X098400Y092250G85X098601Y092250
+X110399Y050749G85X110600Y050749
+X125400Y050749G85X125601Y050749
+X125400Y043251G85X125601Y043251
+X110399Y043251G85X110600Y043251
+X091499Y031651G85X091499Y031849
+X091499Y046650G85X091499Y046850
+X089124Y051900G85X089124Y052101
+X089124Y066901G85X089124Y067099
+X053400Y043251G85X053601Y043251
+X053400Y050749G85X053601Y050749
+X038399Y050749G85X038600Y050749
+X038399Y043251G85X038600Y043251
+X019499Y031651G85X019499Y031849
+X019499Y046650G85X019499Y046850
+X017124Y051900G85X017124Y052101
+X017124Y066901G85X017124Y067099
+X026400Y092250G85X026601Y092250
+X011401Y092250G85X011600Y092250
+X-027600Y050749G85X-027399Y050749
+X-027600Y043251G85X-027399Y043251
+X-042601Y050749G85X-042400Y050749
+X-042601Y043251G85X-042400Y043251
+X-061501Y031651G85X-061501Y031849
+X-061501Y046650G85X-061501Y046850
+X-063876Y051900G85X-063876Y052101
+X-063876Y066901G85X-063876Y067099
+X-054600Y092250G85X-054399Y092250
+X-069599Y092250G85X-069401Y092250
+X-099600Y050749G85X-099399Y050749
+X-099600Y043251G85X-099399Y043251
+X-114601Y050749G85X-114400Y050749
+X-114601Y043251G85X-114400Y043251
+X-133501Y031651G85X-133501Y031849
+X-133501Y046650G85X-133501Y046850
+X-135876Y051900G85X-135876Y052101
+X-135876Y066901G85X-135876Y067099
+X-141599Y092250G85X-141401Y092250
+X-126600Y092250G85X-126399Y092250
+X161000Y440579
+T27
+M98,A*,$S $N
+X-157000Y058420
+M30