新增XP.ReportEngine空项目

This commit is contained in:
QI Mingxuan
2026-05-11 13:09:23 +08:00
parent c80d3e2037
commit 18111b8468
9 changed files with 875 additions and 1364 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,328 @@
# XP.ReportEngine 模板定义规范
## **一、模板结构总览**
模板使用JSON格式定义,分为以下几个核心部分:
1. 
`document`:文档基础配置(页面尺寸、边距等)。
2. 
`pages`:页面列表,每个页面包含元素列表。
3. 
`elements`:页面中的具体元素(文本、表格、图片等)。
4. 
`styles`:预定义的样式,可复用。
5. 
`dataKey`:数据绑定字段,关联业务数据。
## **二、首页布局规范**
**模板路径**`Templates/Homepage.json`
代码<title>图标/24_new/复制</title>
```
{
"document": {
"pageSize": "A4",
"orientation": "Portrait",
"margins": { "top": 30, "right": 20, "bottom": 20, "left": 20 }
},
"pages": [
{
"type": "homepage",
"elements": [
{ "type": "text", "content": "平面CT检测报告", "style": "title", "position": [10, 10] },
{ "type": "text", "content": "报告编号:${reportId}", "style": "subtitle", "position": [10, 40] },
{ "type": "text", "content": "检测日期:${inspectionDate}", "style": "subtitle", "position": [10, 60] },
{ "type": "text", "content": "样品名称:${sampleName}", "style": "subtitle", "position": [10, 80] },
{ "type": "divider", "position": [10, 100], "width": 190 },
{ "type": "table", "dataKey": "summaryData", "columns": [...], "position": [10, 120], "size": [190, 60] }
]
}
],
"styles": {
// ... 样式定义(见下文)
}
}
```
**关键要素说明**
1. 
**标题与元数据**:顶部显示报告标题、编号、日期和样品名称。
2. 
**摘要表格**:显示关键统计信息(如缺陷数量、合格率等),通过`summaryData`绑定数据。
3. 
**分隔线**:视觉分隔标题与主体内容。
## **三、测量数据布局规范**
**模板路径**`Templates/MetricData.json`
代码<title>图标/24_new/复制</title>
```
{
"pages": [
{
"type": "metricData",
"elements": [
{ "type": "text", "content": "测量数据详情", "style": "sectionTitle", "position": [10, 10] },
{ "type": "table", "dataKey": "measurements", "columns": [
{ "header": "参数名称", "field": "parameter" },
{ "header": "测量值", "field": "value" },
{ "header": "单位", "field": "unit" }
], "position": [10, 30], "size": [190, 100] }
]
}
],
"styles": {
// ... 样式定义(见下文)
}
}
```
**关键要素说明**
● 
表格绑定`measurements`数据,列通过`field`属性绑定数据字段。
● 
支持动态行数,自动调整表格高度。
## **四、缺陷检测布局规范**
**模板路径**`Templates/DefectDetails.json`
代码<title>图标/24_new/复制</title>
```
{
"pages": [
{
"type": "defectDetails",
"elements": [
{ "type": "text", "content": "缺陷检测结果", "style": "sectionTitle", "position": [10, 10] },
{
"type": "grid", "dataKey": "defects",
"columns": [
{ "type": "image", "dataKey": "imagePath", "size": [90, 90], "border": true },
{ "type": "text", "content": "缺陷类型:${type}", "style": "gridText", "width": 100 },
{ "type": "text", "content": "位置:X=${x}, Y=${y}", "style": "gridText", "width": 100 }
],
"position": [10, 30], "colWidth": 100, "rowHeight": 100
}
]
}
],
"styles": {
"gridText": { "font": "Arial", "size": 10, "align": "left" }
}
}
```
**关键要素说明**
1. 
**网格布局**:每行显示缺陷图片、类型和位置信息。
2. 
使用`grid`元素自动排版多缺陷数据,支持水平滚动或分页。
3. 
图片路径通过`imagePath`字段绑定,文本使用数据绑定语法(如`X=${x}`)。
## **五、BGA检测布局规范**
**模板路径**`Templates/BGAInspection.json`
代码<title>图标/24_new/复制</title>
```
{
"pages": [
{
"type": "bgaDetails",
"elements": [
{ "type": "text", "content": "BGA焊点检测结果", "style": "sectionTitle", "position": [10, 10] },
{
"type": "image", "dataKey": "bgaTopViewImage", "position": [10, 30], "size": [190, 150], "border": true,
"annotations": [
{ "type": "point", "x": ${defectX}, "y": ${defectY}, "color": "red", "size": 5 }
]
},
{
"type": "table", "dataKey": "bgaMetrics",
"columns": [ "引脚编号", "焊锡高度", "偏移量" ],
"position": [10, 190], "size": [190, 80]
}
]
}
]
}
```
**关键要素说明**
1. 
**图片标注**:在BGA俯视图上标记缺陷位置(通过`annotations`)。
2. 
**表格显示参数**:焊锡高度、偏移量等数据。
3. 
支持动态标注点,绑定缺陷坐标数据。
## **六、气泡检测布局规范**
**模板路径**`Templates/VoidInspection.json`
代码<title>图标/24_new/复制</title>
```
{
"pages": [
{
"type": "voidDetails",
"elements": [
{ "type": "text", "content": "气泡检测结果", "style": "sectionTitle", "position": [10, 10] },
{
"type": "image", "dataKey": "voidImage", "position": [10, 30], "size": [190, 150], "border": true,
"annotations": [
{ "type": "circle", "x": ${bubbleX}, "y": ${bubbleY}, "radius": ${bubbleRadius}, "color": "blue" }
]
},
{ "type": "text", "content": "总气泡数:${voidCount}", "style": "resultText", "position": [10, 190] },
{ "type": "text", "content": "最大气泡体积:${maxVoidVolume} mm³", "style": "resultText", "position": [10, 210] }
]
}
],
"styles": {
"resultText": { "font": "Arial", "size": 14, "bold": true }
}
}
```
**关键要素说明**
1. 
**气泡可视化**:在图像上用圆形标注气泡位置、半径。
2. 
**统计结果**:显示总数量、最大体积等关键指标。
3. 
支持多气泡标注,数据绑定气泡坐标和尺寸。
## **七、通孔填锡率检测布局规范**
**模板路径**`Templates/ViaFillInspection.json`
代码<title>图标/24_new/复制</title>
```
{
"pages": [
{
"type": "viaFillDetails",
"elements": [
{ "type": "text", "content": "通孔填锡率检测结果", "style": "sectionTitle", "position": [10, 10] },
{
"type": "image", "dataKey": "viaImage", "position": [10, 30], "size": [190, 150], "border": true,
"annotations": [
{ "type": "rectangle", "x": ${viaX}, "y": ${viaY}, "width": ${viaWidth}, "height": ${viaHeight}, "color": "green" }
]
},
{ "type": "text", "content": "平均填锡率:${avgFillRate}%", "style": "resultText", "position": [10, 190] },
{ "type": "progressBar", "value": ${avgFillRate}, "position": [10, 220], "size": [190, 20], "color": "${fillRateColor(avgFillRate)}" }
]
}
],
"functions": {
"fillRateColor(value)": "return value >= 90 ? 'green' : value >= 70 ? 'orange' : 'red';"
}
}
```
**关键要素说明**
1. 
**填锡率图示**:用矩形标注通孔位置,进度条显示填锡率。
2. 
**颜色条件绑定**:通过函数`fillRateColor`根据数值动态设置颜色。
3. 
支持多通孔标注,绑定位置和尺寸数据。
## **八、样式定义示例**
代码<title>图标/24_new/复制</title>
```
"styles": {
"title": { "font": "Arial", "size": 24, "bold": true, "color": "#000000" },
"subtitle": { "font": "Arial", "size": 16, "italic": true, "color": "#666666" },
"gridText": { "font": "Arial", "size": 10, "align": "left" },
"resultText": { "font": "Arial", "size": 14, "bold": true }
}
```
**关键要素说明**
● 
样式可复用,通过`style`属性引用。
● 
支持字体、大小、颜色、对齐等属性配置。
**# 总结**
● 
**模块化设计**:各检测模块独立为单独模板文件,可灵活组合。
● 
**数据绑定**:通过`${}`语法绑定业务数据(如`measurements``defects`等对象)。
● 
**动态布局**:支持表格自适应高度、图片标注、条件样式等高级功能。
● 
**可扩展性**:新增检测类型只需定义对应模板文件即可。
**备注**:实际使用时,需根据具体业务数据模型调整`dataKey`和字段名称,确保模板与输入数据匹配。
@@ -0,0 +1,422 @@
# XP.ReportEngine 项目规划
## 一、项目结构优化
**1. 完整目录结构**
```
XP.ReportEngine/
├── Interfaces/
│ ├── IReportGenerator.cs // 报告生成器核心接口
│ ├── ITemplateEngine.cs // 模板引擎接口
│ └── IDataBinder.cs // 数据绑定接口
├── Models/
│ ├── ReportContext.cs // 报告上下文(包含测量数据、图片列表)
│ ├── ReportTemplate.cs // 报告模板定义
│ ├── TemplateElement.cs // 模板元素定义
│ └── LayoutSettings.cs // 布局配置参数
├── Services/
│ ├── MeasurementReportBuilder.cs // 测量报告构建器
│ ├── ImageLayoutService.cs // 图片排版服务(计算坐标、缩放)
│ ├── TemplateEngine.cs // 模板引擎实现
│ ├── DataBinder.cs // 数据绑定实现
│ └── PdfGenerationService.cs // PDF生成核心服务
├── Templates/
│ └── StandardReportTemplate.json // 标准报告模板配置
└── Extensions/
└── ImageExtensions.cs // 图像处理扩展方法
```
## 二、核心模块设计
### 1. 报告模板引擎
**1.1 模板定义规范**
- **JSON模板结构**:
```json
{
"document": {
"pageSize": "A4",
"margins": { "top": 20, "bottom": 20, "left": 20, "right": 20 }
},
"pages": [
{
"type": "title",
"elements": [
{ "type": "text", "content": "工业CT检测报告", "style": "title", "position": [10, 10] },
{ "type": "text", "content": "报告日期: ${reportDate}", "style": "subtitle", "position": [10, 30] }
]
},
{
"type": "measurement",
"elements": [
{ "type": "table", "dataKey": "measurements", "position": [10, 10], "size": [190, 100] },
{ "type": "image", "dataKey": "overviewImage", "position": [10, 120], "size": [190, 100] }
]
},
{
"type": "defectDetail",
"elements": [
{ "type": "image", "dataKey": "defectImage", "position": [10, 10], "size": [90, 90] },
{ "type": "text", "content": "缺陷类型: ${defectType}", "style": "normal", "position": [10, 100] }
]
}
],
"styles": {
"title": { "font": "Arial", "size": 24, "bold": true, "color": "#000000" },
"subtitle": { "font": "Arial", "size": 16, "italic": true, "color": "#666666" },
"normal": { "font": "Arial", "size": 12, "color": "#000000" }
}
}
```
**1.2 模板引擎实现**
- **模板加载与解析**:
```csharp
public class TemplateEngine : ITemplateEngine
{
public ReportTemplate LoadTemplate(string templatePath)
{
var json = File.ReadAllText(templatePath);
return JsonConvert.DeserializeObject<ReportTemplate>(json);
}
public List<PageElement> ParseTemplate(ReportTemplate template, ReportContext context)
{
var elements = new List<PageElement>();
foreach (var page in template.Pages)
{
foreach (var element in page.Elements)
{
// 处理数据绑定
var boundElement = BindData(element, context);
elements.Add(boundElement);
}
}
return elements;
}
private PageElement BindData(PageElement element, ReportContext context)
{
// 实现数据绑定逻辑
if (element.Type == "text" && element.Content.Contains("${"))
{
element.Content = DataBinder.Bind(element.Content, context);
}
return element;
}
}
```
### 2. 数据绑定系统
**2.1 数据绑定机制**
- **支持的绑定语法**:
- `${propertyName}` - 基本属性绑定
- `${object.property}` - 对象属性绑定
- `${list[index]}` - 列表索引访问
- `${function(param)}` - 函数调用(如日期格式化)
**2.2 数据绑定实现**
```csharp
public class DataBinder : IDataBinder
{
public string Bind(string template, ReportContext context)
{
// 使用正则表达式匹配绑定表达式
var pattern = @"\$\{([^\}]+)\}";
return Regex.Replace(template, pattern, match =>
{
var expression = match.Groups[1].Value;
return EvaluateExpression(expression, context);
});
}
private string EvaluateExpression(string expression, ReportContext context)
{
// 解析表达式并获取值
if (expression.Contains("."))
{
// 处理对象属性
var parts = expression.Split('.');
var obj = context.GetType().GetProperty(parts[0])?.GetValue(context);
return obj?.GetType().GetProperty(parts[1])?.GetValue(obj)?.ToString() ?? string.Empty;
}
else if (expression.Contains("["))
{
// 处理列表索引
var index = int.Parse(expression.Split('[')[1].TrimEnd(']'));
return context.Images.Count > index ? "Image" : string.Empty;
}
else
{
// 处理基本属性
return context.GetType().GetProperty(expression)?.GetValue(context)?.ToString() ?? string.Empty;
}
}
}
```
### 3. 自动排版功能
**3.1 布局引擎设计**
- **核心功能**:
- **页面分隔**: 当内容超出一页时自动创建新页
- **元素定位**: 根据模板定义计算元素在页面上的精确位置
- **尺寸计算**: 自动调整元素大小以适应内容
- **响应式布局**: 根据页面尺寸动态调整元素位置
**3.2 排版服务实现**
```csharp
public class ImageLayoutService
{
public LayoutResult CalculateLayout(ReportTemplate template, ReportContext context)
{
var result = new LayoutResult();
var currentPage = 0;
var currentY = template.Document.Margins.Top;
foreach (var page in template.Pages)
{
foreach (var element in page.Elements)
{
// 计算元素位置
var position = new Point(
template.Document.Margins.Left + element.Position[0],
currentY + element.Position[1]
);
// 计算元素尺寸
var size = new Size(element.Size[0], element.Size[1]);
// 检查是否需要换页
if (position.Y + size.Height > PageSize.A4.Height - template.Document.Margins.Bottom)
{
currentPage++;
currentY = template.Document.Margins.Top;
position = new Point(
template.Document.Margins.Left + element.Position[0],
currentY + element.Position[1]
);
}
// 添加到布局结果
result.Elements.Add(new LayoutElement
{
Page = currentPage,
Element = element,
Position = position,
Size = size
});
// 更新当前Y位置
currentY = position.Y + size.Height;
}
}
return result;
}
}
```
### 4. 图表嵌入实现
**4.1 WPF图表转PDF图像**
- **实现方案**:
- 使用`RenderTargetBitmap`将WPF控件渲染为位图
- 支持高质量图像输出(300 DPI)
- 提供图像压缩选项,平衡质量与文件大小
**4.2 图像转换服务**
```csharp
public static class ImageExtensions
{
public static byte[] ToPdfImage(this ImageSource image, double width, double height)
{
var renderTarget = new RenderTargetBitmap(
(int)width, (int)height,
96, 96, PixelFormats.Pbgra32);
renderTarget.Render(image);
using (var stream = new MemoryStream())
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTarget));
encoder.Save(stream);
return stream.ToArray();
}
}
public static byte[] ToPdfImage(this FrameworkElement element, double width, double height)
{
var renderTarget = new RenderTargetBitmap(
(int)width, (int)height,
96, 96, PixelFormats.Pbgra32);
renderTarget.Render(element);
using (var stream = new MemoryStream())
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTarget));
encoder.Save(stream);
return stream.ToArray();
}
}
}
```
## 三、PDF生成核心流程
### 1. 生成步骤
1. **加载模板**: 从Templates目录加载JSON模板
2. **解析上下文**: 将MeasurementData和图片列表转换为ReportContext
3. **数据绑定**: 将上下文数据绑定到模板中的占位符
4. **计算布局**: 确定每个元素在PDF页面上的精确位置
5. **生成PDF**: 使用iTextSharp绘制内容到PDF文档
6. **输出结果**: 返回MemoryStream或保存为文件
### 2. 核心生成服务
```csharp
public class PdfGenerationService
{
public MemoryStream GeneratePdf(ReportContext context, string templatePath)
{
// 1. 加载模板
var templateEngine = new TemplateEngine();
var template = templateEngine.LoadTemplate(templatePath);
// 2. 解析模板元素
var elements = templateEngine.ParseTemplate(template, context);
// 3. 计算布局
var layoutService = new ImageLayoutService();
var layout = layoutService.CalculateLayout(template, context);
// 4. 创建PDF文档
var document = new Document(PageSize.A4,
template.Document.Margins.Left,
template.Document.Margins.Right,
template.Document.Margins.Top,
template.Document.Margins.Bottom);
var stream = new MemoryStream();
var writer = PdfWriter.GetInstance(document, stream);
document.Open();
// 5. 绘制内容
DrawContent(document, layout, context);
// 6. 关闭文档
document.Close();
return stream;
}
private void DrawContent(Document document, LayoutResult layout, ReportContext context)
{
// 实现内容绘制逻辑
foreach (var element in layout.Elements)
{
switch (element.Element.Type)
{
case "text":
DrawText(document, element);
break;
case "image":
DrawImage(document, element, context);
break;
case "table":
DrawTable(document, element, context);
break;
}
}
}
private void DrawText(Document document, LayoutElement element)
{
var paragraph = new Paragraph(element.Element.Content);
paragraph.SetLocation(element.Position.X, document.PageSize.Height - element.Position.Y);
document.Add(paragraph);
}
private void DrawImage(Document document, LayoutElement element, ReportContext context)
{
// 获取图像数据
var imageData = context.Images.FirstOrDefault();
if (imageData == null) return;
// 创建iTextSharp图像对象
var image = Image.GetInstance(imageData);
image.SetAbsolutePosition(element.Position.X, document.PageSize.Height - element.Position.Y - element.Size.Height);
image.ScaleToFit(element.Size.Width, element.Size.Height);
document.Add(image);
}
private void DrawTable(Document document, LayoutElement element, ReportContext context)
{
// 创建表格
var table = new PdfPTable(3); // 假设3列
table.WidthPercentage = 100;
// 添加表头
table.AddCell(new PdfPCell(new Phrase("参数", new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD))));
table.AddCell(new PdfPCell(new Phrase("测量值", new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD))));
table.AddCell(new PdfPCell(new Phrase("标准值", new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD))));
// 添加数据行
foreach (var measurement in context.Measurements)
{
table.AddCell(new PdfPCell(new Phrase(measurement.Parameter)));
table.AddCell(new PdfPCell(new Phrase(measurement.Value.ToString())));
table.AddCell(new PdfPCell(new Phrase(measurement.StandardValue.ToString())));
}
document.Add(table);
}
}
```
## 四、最佳实践与建议
### 1. 性能优化
- **图像处理**: 对大尺寸图像进行**压缩和缩放**,避免PDF文件过大
- **内存管理**: 使用`using`语句确保资源及时释放
- **批量处理**: 对大量数据采用**分批处理**策略,避免UI冻结
### 2. 错误处理
- 实现**完善的异常捕获**机制,特别是图像转换和PDF生成环节
- 提供**友好的错误提示**,便于问题排查
- 添加**日志记录**功能,跟踪报告生成过程
### 3. 样式管理
- 创建**样式库**,统一字体、颜色、间距等
- 支持**主题切换**,适应不同客户的品牌要求
- 确保**打印友好**,考虑黑白打印时的可读性
### 4. 扩展性考虑
- **插件架构**: 设计可扩展的插件系统,便于添加新功能
- **多格式输出**: 基于相同架构,扩展支持Word、Excel等格式输出
- **云服务集成**: 考虑与云存储集成,自动上传生成的报告
通过以上设计,XP.ReportEngine将成为一个**灵活、高效、可维护**的PDF报告生成系统,满足工业CT检测报告的专业需求,同时保持系统的扩展性和易用性。
+19
View File
@@ -0,0 +1,19 @@
using Prism.Ioc;
using Prism.Modularity;
using XP.ReportEngine.Views;
namespace XP.ReportEngine
{
public class ReportEngineModule : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
}
}
}
@@ -0,0 +1,25 @@
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XP.ReportEngine.ViewModels
{
public class ViewAViewModel : BindableBase
{
private string _message;
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value); }
}
public ViewAViewModel()
{
Message = "View A from your Prism Module";
}
}
}
+16
View File
@@ -0,0 +1,16 @@
<UserControl x:Class="XP.ReportEngine.Views.ViewA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:XP.ReportEngine.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True" >
<Grid>
<TextBlock Text="{Binding Message}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</UserControl>
+28
View File
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace XP.ReportEngine.Views
{
/// <summary>
/// Interaction logic for ViewA.xaml
/// </summary>
public partial class ViewA : UserControl
{
public ViewA()
{
InitializeComponent();
}
}
}
+16
View File
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Prism.Wpf" Version="9.0.537" />
<PackageReference Include="Telerik.UI.for.Wpf.NetCore.Xaml" Version="2024.1.408" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\XP.Common\XP.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Documents\" />
</ItemGroup>
</Project>
+16 -2
View File
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36811.4
# Visual Studio Version 18
VisualStudioVersion = 18.5.11723.231 stable
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XplorePlane", "XplorePlane\XplorePlane.csproj", "{07978DB9-4B88-4F42-9054-73992742BD6A}"
EndProject
@@ -66,6 +66,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XP.Calibration", "XP.Calibr
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "XP.Calibration", "XP.Calibration", "{D4E5F6A7-B8C9-0123-4567-89ABCDEF0123}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XP.ReportEngine", "XP.ReportEngine\XP.ReportEngine.csproj", "{809A8588-F64C-4738-8827-CFBC59943DBF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -268,6 +270,18 @@ Global
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x64.Build.0 = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x86.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x86.Build.0 = Release|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Debug|x64.ActiveCfg = Debug|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Debug|x64.Build.0 = Debug|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Debug|x86.ActiveCfg = Debug|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Debug|x86.Build.0 = Debug|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Release|Any CPU.Build.0 = Release|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Release|x64.ActiveCfg = Release|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Release|x64.Build.0 = Release|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Release|x86.ActiveCfg = Release|Any CPU
{809A8588-F64C-4738-8827-CFBC59943DBF}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE