This commit is contained in:
Jonathan Jenne
2023-11-13 09:26:48 +01:00
parent 2c936c2629
commit 3874bc742d
14 changed files with 273 additions and 77 deletions

View File

@@ -19,6 +19,10 @@ Partial Public Class frmFieldEditor
Public Property SelectedReceiver As EnvelopeReceiver = Nothing Public Property SelectedReceiver As EnvelopeReceiver = Nothing
Public Property State As State Public Property State As State
Private Const SIGNATURE_LABEL = "Signatur"
Private Const SIGNATURE_WIDTH As Single = 1
Private Const SIGNATURE_HEIGHT As Single = 0.5
Public Sub New() Public Sub New()
InitializeComponent() InitializeComponent()
End Sub End Sub
@@ -118,7 +122,7 @@ Partial Public Class frmFieldEditor
AddHandler GDViewer.BeforeAnnotationAddedByUser, AddressOf Viewer_BeforeAnnotationAddedByUser AddHandler GDViewer.BeforeAnnotationAddedByUser, AddressOf Viewer_BeforeAnnotationAddedByUser
AddHandler GDViewer.AnnotationAddedByUser, AddressOf Viewer_AnnotationAddedByUser AddHandler GDViewer.AnnotationAddedByUser, AddressOf Viewer_AnnotationAddedByUser
GDViewer.AddStickyNoteAnnotationInteractive("SIGNATUR", Color.Black, "Arial", FontStyle.Regular, 10, 1, 0) GDViewer.AddStickyNoteAnnotationInteractive(SIGNATURE_LABEL, Color.Black, "Arial", FontStyle.Regular, 10, 1, 0)
End If End If
@@ -131,8 +135,8 @@ Partial Public Class frmFieldEditor
If TypeOf oAnnotation Is AnnotationStickyNote Then If TypeOf oAnnotation Is AnnotationStickyNote Then
Dim oStickyNote As AnnotationStickyNote = oAnnotation Dim oStickyNote As AnnotationStickyNote = oAnnotation
oStickyNote.Width = 1 oStickyNote.Width = SIGNATURE_WIDTH
oStickyNote.Height = 1 oStickyNote.Height = SIGNATURE_HEIGHT
oStickyNote.Tag = oTag oStickyNote.Tag = oTag
ApplyAnnotationStyle(oAnnotation) ApplyAnnotationStyle(oAnnotation)
@@ -213,19 +217,6 @@ Partial Public Class frmFieldEditor
Next Next
End Sub End Sub
Private Sub ApplyAnnotationStyle(ByRef pAnnotation As Annotation)
If TypeOf pAnnotation Is AnnotationStickyNote Then
Dim oStickyNote As AnnotationStickyNote = pAnnotation
oStickyNote.Fill = True
oStickyNote.FillColor = Color.LightGoldenrodYellow
oStickyNote.Text = "SIGNATUR"
oStickyNote.Alignment = StringAlignment.Center
oStickyNote.LineAlignment = StringAlignment.Center
End If
End Sub
Private Sub btnDelete_ItemClick(sender As Object, e As ItemClickEventArgs) Handles btnDelete.ItemClick Private Sub btnDelete_ItemClick(sender As Object, e As ItemClickEventArgs) Handles btnDelete.ItemClick
Dim oSelected = GDViewer.GetSelectedAnnotationIdx() Dim oSelected = GDViewer.GetSelectedAnnotationIdx()
@@ -264,8 +255,9 @@ Partial Public Class frmFieldEditor
oAnnotation.Left = CSng(pElement.X) oAnnotation.Left = CSng(pElement.X)
oAnnotation.Top = CSng(pElement.Y) oAnnotation.Top = CSng(pElement.Y)
oAnnotation.Fill = True oAnnotation.Fill = True
oAnnotation.FillColor = Color.DarkRed oAnnotation.FillColor = Color.Gainsboro
oAnnotation.Text = "SIGNATUR" oAnnotation.BorderWidth = 0.01
oAnnotation.Text = SIGNATURE_LABEL
oAnnotation.Tag = GetAnnotationTag(pReceiverId, oPage, pElement.Id) oAnnotation.Tag = GetAnnotationTag(pReceiverId, oPage, pElement.Id)
Else Else
Dim oStatus = Manager.GetStat() Dim oStatus = Manager.GetStat()
@@ -274,6 +266,18 @@ Partial Public Class frmFieldEditor
End If End If
End Sub End Sub
Private Sub ApplyAnnotationStyle(ByRef pAnnotation As Annotation)
If TypeOf pAnnotation Is AnnotationStickyNote Then
Dim oAnnotation As AnnotationStickyNote = pAnnotation
oAnnotation.Fill = True
oAnnotation.FillColor = Color.Gainsboro
oAnnotation.Text = SIGNATURE_LABEL
oAnnotation.Alignment = StringAlignment.Center
oAnnotation.LineAlignment = StringAlignment.Center
oAnnotation.BorderWidth = 0.01
End If
End Sub
Private Sub ClearAnnotations() Private Sub ClearAnnotations()
Dim oPageCount = GDViewer.PageCount Dim oPageCount = GDViewer.PageCount

View File

@@ -9,7 +9,7 @@ namespace EnvelopeGenerator.Web.Controllers
{ {
internal DatabaseService database; internal DatabaseService database;
internal LogConfig logConfig; internal LogConfig logConfig;
internal Logger logger; public Logger logger;
public BaseController(DatabaseService database, LoggingService logging) public BaseController(DatabaseService database, LoggingService logging)
{ {

View File

@@ -1,8 +1,6 @@
using DigitalData.Modules.Logging; using EnvelopeGenerator.Common;
using EnvelopeGenerator.Common;
using EnvelopeGenerator.Web.Services; using EnvelopeGenerator.Web.Services;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using static EnvelopeGenerator.Web.Constants;
namespace EnvelopeGenerator.Web.Controllers namespace EnvelopeGenerator.Web.Controllers
{ {

View File

@@ -2,8 +2,6 @@
using EnvelopeGenerator.Web.Services; using EnvelopeGenerator.Web.Services;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using static EnvelopeGenerator.Common.Constants; using static EnvelopeGenerator.Common.Constants;
using System;
using static System.Collections.Specialized.BitVector32;
namespace EnvelopeGenerator.Web.Controllers namespace EnvelopeGenerator.Web.Controllers
{ {

View File

@@ -6,21 +6,19 @@ using System.Diagnostics;
namespace EnvelopeGenerator.Web.Controllers namespace EnvelopeGenerator.Web.Controllers
{ {
public class HomeController : Controller public class HomeController : BaseController
{ {
private readonly EnvelopeService _envelopeService; private readonly EnvelopeService _envelopeService;
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger, EnvelopeService envelopeService) public HomeController(DatabaseService database, LoggingService logging, EnvelopeService envelopeService): base(database, logging)
{ {
_envelopeService = envelopeService; _envelopeService = envelopeService;
_logger = logger;
} }
[HttpGet] [HttpGet]
[Route("/")] [Route("/")]
public IActionResult Index() public IActionResult Index()
{ {
var receiverId = 1; var receiverId = 1;
List<Envelope> envelopes = _envelopeService.LoadEnvelopes(receiverId); List<Envelope> envelopes = _envelopeService.LoadEnvelopes(receiverId);
@@ -29,13 +27,23 @@ namespace EnvelopeGenerator.Web.Controllers
[HttpGet] [HttpGet]
[Route("/EnvelopeKey/{EnvelopeReceiverId}")] [Route("/EnvelopeKey/{EnvelopeReceiverId}")]
public IActionResult Show() public IActionResult ShowEnvelope()
{ {
ViewData["EnvelopeKey"] = HttpContext.Request.RouteValues["EnvelopeReceiverId"]; ViewData["EnvelopeKey"] = HttpContext.Request.RouteValues["EnvelopeReceiverId"];
return View(); return View();
} }
[HttpGet]
[Route("/EnvelopeKey/{EnvelopeReceiverId}/Success")]
public IActionResult EnvelopeSigned()
{
ViewData["EnvelopeKey"] = HttpContext.Request.RouteValues["EnvelopeReceiverId"];
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error() public IActionResult Error()
{ {

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
@@ -12,21 +12,22 @@
<PackageReference Include="System.Drawing.Common" Version="7.0.0" /> <PackageReference Include="System.Drawing.Common" Version="7.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EnvelopeGenerator.Common\EnvelopeGenerator.Common.vbproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="DigitalData.Modules.Base"> <Reference Include="DigitalData.Modules.Base">
<HintPath>..\DDModules\Base\bin\Debug\DigitalData.Modules.Base.dll</HintPath> <HintPath>..\..\DDModules\Base\bin\Debug\DigitalData.Modules.Base.dll</HintPath>
</Reference> </Reference>
<Reference Include="DigitalData.Modules.Config"> <Reference Include="DigitalData.Modules.Config">
<HintPath>..\DDModules\Config\bin\Debug\DigitalData.Modules.Config.dll</HintPath> <HintPath>..\..\DDModules\Config\bin\Debug\DigitalData.Modules.Config.dll</HintPath>
</Reference> </Reference>
<Reference Include="DigitalData.Modules.Database"> <Reference Include="DigitalData.Modules.Database">
<HintPath>..\DDModules\Database\bin\Debug\DigitalData.Modules.Database.dll</HintPath> <HintPath>..\..\DDModules\Database\bin\Debug\DigitalData.Modules.Database.dll</HintPath>
</Reference> </Reference>
<Reference Include="DigitalData.Modules.Logging"> <Reference Include="DigitalData.Modules.Logging">
<HintPath>..\DDModules\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath> <HintPath>..\..\DDModules\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
</Reference>
<Reference Include="EnvelopeGenerator.Common">
<HintPath>..\EnvelopeGenerator\EnvelopeGenerator.Common\bin\Debug\EnvelopeGenerator.Common.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>

View File

@@ -0,0 +1,21 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<div id="page-success" class="container p-5">
<header class="text-center">
<div class="icon bg-success text-light">
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" fill="currentColor" class="bi bi-check2-circle" viewBox="0 0 16 16">
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z" />
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z" />
</svg>
</div>
<h1>Umschlag erfolgreich signiert!</h1>
</header>
<section class="text-center">
<p>Sie haben das Dokument erfolgreich signiert. Im Anschluss erhalten Sie eine schriftliche Bestätigung.</p>
</section>
</div>

View File

@@ -11,8 +11,27 @@
} }
} }
@foreach (Envelope envelope in @Model) <div class="container">
{ <section>
<li><a href="/EnvelopeKey/@encodeEnvelopeKey(envelope)">@envelope.Title</a></li> <ul>
} @foreach (Envelope envelope in @Model)
{
<li><a href="/EnvelopeKey/@encodeEnvelopeKey(envelope)">@envelope.Title</a></li>
}
</ul>
</section>
<section>
<a href="#" id="url" target="_blank">Show image</a>
<img src="#" id="img" />
</section>
<script>
document.addEventListener("DOMContentLoaded", function() {
const anno = new Annotation()
anno.createAnnotationFrameBlob("Deine Mudda", 200, 80).then(url => document.getElementById("img").src = url)
})
</script>
</div>

View File

@@ -0,0 +1,34 @@
/*
Colors taken from:
https://tailwindcss.com/docs/customizing-colors#default-color-palette
*/
.button-finish {
transition: background-color linear 300ms;
background-color: #059669;
color: white;
border-left: none;
}
.button-finish:hover, .button-finish:focus, .button-finish:active {
background-color: #10b981;
color: white;
}
.button-reset {
transition: background-color linear 300ms;
background-color: #2563eb;
color: white;
}
.button-reset:hover, .button-reset:focus, .button-reset:active {
background-color: #3b82f6;
color: white;
}
#page-success header .icon {
display: inline-block;
border-radius: 100px;
padding: 15px;
margin-bottom: 2rem;
}

View File

@@ -20,7 +20,7 @@
)) ))
).flatMap((annotations) => ).flatMap((annotations) =>
annotations.reduce((acc, annotation) => acc.concat(annotation), []) annotations.reduce((acc, annotation) => acc.concat(annotation), [])
).filter((annotation) => !!annotation.isSignature); ).filter((annotation) => !!annotation.isSignature || annotation.description == "FRAME");
//deleting all Annotations //deleting all Annotations
return await instance.delete(pageAnnotations); return await instance.delete(pageAnnotations);
} }
@@ -50,9 +50,9 @@
const annotation = this.createSignatureAnnotation(id, width, height, top, left, page) const annotation = this.createSignatureAnnotation(id, width, height, top, left, page)
console.log(annotation) console.log(annotation)
const formField = new SignatureFormField({ const formField = new PSPDFKit.FormFields.SignatureFormField({
name: id, name: id,
annotationIds: List([annotation.id]) annotationIds: PSPDFKit.Immutable.List([annotation.id])
}) })
console.log(formField) console.log(formField)
@@ -64,12 +64,54 @@
id: id, id: id,
pageIndex: pageIndex, pageIndex: pageIndex,
formFieldName: id, formFieldName: id,
boundingBox: new Rect({ width, height, top, left }) boundingBox: new PSPDFKit.Geometry.Rect({ width, height, top, left })
}) })
return annotation return annotation
} }
async createAnnotationFrameBlob(receiverName, width, height) {
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
const date = new Date();
const dateString = date.toLocaleDateString("de-DE");
const signatureLength = 100;
ctx.beginPath();
ctx.moveTo(30, 10);
ctx.lineTo(signatureLength, 10);
ctx.moveTo(30, 10);
ctx.arcTo(10, 10, 10, 30, 20);
ctx.moveTo(10, 30);
ctx.arcTo(10, 50, 30, 50, 20);
ctx.moveTo(30, 50);
ctx.lineTo(signatureLength, 50);
ctx.strokeStyle = "darkblue";
ctx.stroke();
ctx.fillStyle = "black";
ctx.font = "10px serif";
ctx.fillText("Signed by", 30, 10)
ctx.fillText(receiverName + ", " + dateString, 15, 60)
return new Promise(resolve => {
canvas.toBlob((blob) => {
const url = URL.createObjectURL(blob);
resolve(url)
})
})
}
inchToPoint(inch) { inchToPoint(inch) {
return inch * 72; return inch * 72;
} }

View File

@@ -22,6 +22,7 @@ class App {
this.Instance = null; this.Instance = null;
this.currentDocument = null; this.currentDocument = null;
this.currentReceiver = null;
} }
// This function will be called in the ShowEnvelope.razor page // This function will be called in the ShowEnvelope.razor page
@@ -32,6 +33,9 @@ class App {
console.debug("Loading envelope from database..") console.debug("Loading envelope from database..")
const envelopeObject = await this.Network.getEnvelope(this.envelopeKey); const envelopeObject = await this.Network.getEnvelope(this.envelopeKey);
this.currentDocument = envelopeObject.envelope.documents[0]; this.currentDocument = envelopeObject.envelope.documents[0];
this.currentReceiver = envelopeObject.receiver;
console.log(envelopeObject)
// Load the document from the filestore // Load the document from the filestore
console.debug("Loading document from filestore") console.debug("Loading document from filestore")
@@ -47,13 +51,85 @@ class App {
this.Instance = await this.UI.loadPSPDFKit(arrayBuffer, this.container) this.Instance = await this.UI.loadPSPDFKit(arrayBuffer, this.container)
this.UI.configurePSPDFKit(this.Instance, this.handleClick.bind(this)) this.UI.configurePSPDFKit(this.Instance, this.handleClick.bind(this))
this.Instance.addEventListener("annotations.load", this.handleAnnotationsLoad)
this.Instance.addEventListener("annotations.change", this.handleAnnotationsChange)
this.Instance.addEventListener("annotations.create", this.handleAnnotationsCreate.bind(this))
// Load annotations into PSPDFKit // Load annotations into PSPDFKit
console.debug("Loading annotations..") console.debug("Loading annotations..")
const annotations = this.Annotation.createAnnotations(this.currentDocument)
const createdAnnotations = await this.Instance.create(annotations)
const description = "Umschlag wurde geöffnet" try {
await this.Network.postHistory(this.envelopeKey, ActionType.Seen, description); const annotations = this.Annotation.createAnnotations(this.currentDocument)
const createdAnnotations = await this.Instance.create(annotations)
const description = "Umschlag wurde geöffnet"
await this.Network.postHistory(this.envelopeKey, ActionType.Seen, description);
} catch (e) {
console.error(e)
}
}
handleAnnotationsLoad(loadedAnnotations) {
console.log("annotations loaded", loadedAnnotations.toJS());
}
handleAnnotationsChange() {}
async handleAnnotationsCreate(createdAnnotations) {
console.log("annotations created");
console.log(createdAnnotations.toJS())
const annotation = createdAnnotations.toJS()[0];
const isFormField = !!annotation.formFieldName;
const isSignature = !!annotation.isSignature;
console.log("form field", isFormField, "signature", isSignature)
//if (!isSignature) {
// return;
//}
//if (!(isFormField && isSignature)) {
// return;
//}
if (isFormField === false && isSignature === true) {
const left = annotation.boundingBox.left - 25;
const top = annotation.boundingBox.top - 25;
const width = 150;
const height = 75;
console.log(annotation.boundingBox)
const imageUrl = await this.Annotation.createAnnotationFrameBlob(this.currentReceiver.name, width, height);
const request = await fetch(imageUrl);
const blob = await request.blob();
const imageAttachmentId = await this.Instance.createAttachment(blob);
const frameAnnotation = new PSPDFKit.Annotations.ImageAnnotation({
pageIndex: annotation.pageIndex,
isSignature: false,
readOnly: true,
locked: true,
lockedContents: true,
contentType: 'image/png',
imageAttachmentId,
description: 'FRAME',
boundingBox: new PSPDFKit.Geometry.Rect({
left: left,
top: top,
width: width,
height: height,
}),
});
this.Instance.create(frameAnnotation);
}
} }
async handleClick(eventType) { async handleClick(eventType) {

View File

@@ -16,6 +16,7 @@
// and a arraybuffer which represents the document that should be displayed. // and a arraybuffer which represents the document that should be displayed.
loadPSPDFKit(arrayBuffer, container) { loadPSPDFKit(arrayBuffer, container) {
return PSPDFKit.load({ return PSPDFKit.load({
styleSheets: ['/css/site.css'],
container: container, container: container,
document: arrayBuffer, document: arrayBuffer,
autoSaveMode: "DISABLED", autoSaveMode: "DISABLED",
@@ -26,24 +27,20 @@
isEditableAnnotation: function (annotation) { isEditableAnnotation: function (annotation) {
// Check if the annotation is a signature // Check if the annotation is a signature
// This will allow new signatures, but not allow edits. // This will allow new signatures, but not allow edits.
return !annotation.isSignature; console.log(annotation.isSignature, annotation.description)
if (annotation.isSignature || annotation.description == "FRAME") {
return false;
}
return true;
//return !annotation.isSignature;
} }
}) })
} }
configurePSPDFKit(instance, handler) { configurePSPDFKit(instance, handler) {
instance.addEventListener("annotations.load", (loadedAnnotations) => {
console.log("annotations loaded", loadedAnnotations.toJS());
})
instance.addEventListener("annotations.change", () => {
console.log("annotations changed")
})
instance.addEventListener("annotations.create", async (createdAnnotations) => {
console.log("annotations created");
})
const toolbarItems = this.getToolbarItems(instance, handler) const toolbarItems = this.getToolbarItems(instance, handler)
instance.setToolbarItems(toolbarItems) instance.setToolbarItems(toolbarItems)
@@ -56,14 +53,22 @@
return defaultItems.concat(customItems) return defaultItems.concat(customItems)
} }
createElementFromHTML(html) {
const el = document.createElement('div')
el.innerHTML = html.trim()
return el.firstChild
}
getCustomItems = function (callback) { getCustomItems = function (callback) {
const customItems = [ return [
{ {
type: "custom", type: "custom",
id: "button-reset", id: "button-reset",
className: "button-reset", className: "button-reset",
title: "Zurücksetzen", title: "Zurücksetzen",
onPress() { onPress() {
console.log("RESET")
callback("RESET") callback("RESET")
}, },
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16"> icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
@@ -77,15 +82,11 @@
className: "button-finish", className: "button-finish",
title: "Abschließen", title: "Abschließen",
onPress() { onPress() {
console.log("FINISH")
callback("FINISH") callback("FINISH")
}, }
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-check2-circle" viewBox="0 0 16 16">
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z"/>
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z" />
</svg>`
} }
] ]
return customItems
} }
getDefaultItems(items) { getDefaultItems(items) {

View File

@@ -9,9 +9,7 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EnvelopeGenerator.Form", "E
EndProject EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EnvelopeGenerator.Common", "EnvelopeGenerator.Common\EnvelopeGenerator.Common.vbproj", "{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}" Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EnvelopeGenerator.Common", "EnvelopeGenerator.Common\EnvelopeGenerator.Common.vbproj", "{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvelopeGenerator.WebOld", "EnvelopeGenerator.WebOld\EnvelopeGenerator.WebOld.csproj", "{43F5983D-FCA5-4DC8-A42D-150766966A62}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvelopeGenerator.Web", "EnvelopeGenerator.Web\EnvelopeGenerator.Web.csproj", "{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Web", "EnvelopeGenerator.Web\EnvelopeGenerator.Web.csproj", "{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -31,10 +29,6 @@ Global
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Debug|Any CPU.Build.0 = Debug|Any CPU {6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Release|Any CPU.ActiveCfg = Release|Any CPU {6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Release|Any CPU.Build.0 = Release|Any CPU {6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Release|Any CPU.Build.0 = Release|Any CPU
{43F5983D-FCA5-4DC8-A42D-150766966A62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43F5983D-FCA5-4DC8-A42D-150766966A62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43F5983D-FCA5-4DC8-A42D-150766966A62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43F5983D-FCA5-4DC8-A42D-150766966A62}.Release|Any CPU.Build.0 = Release|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Debug|Any CPU.Build.0 = Debug|Any CPU {5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Release|Any CPU.ActiveCfg = Release|Any CPU {5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Release|Any CPU.ActiveCfg = Release|Any CPU