This commit is contained in:
Stephane Delcroix 2018-06-15 09:18:33 +02:00
Родитель 5203f6649e 9e528a4892
Коммит 09daa89cae
13 изменённых файлов: 270 добавлений и 43 удалений

Просмотреть файл

@ -38,7 +38,7 @@
</GetTasksAbi >
<PropertyGroup>
<_XFTasksExpectedAbi>4</_XFTasksExpectedAbi>
<_XFTasksExpectedAbi>5</_XFTasksExpectedAbi>
</PropertyGroup>
<Error
@ -112,17 +112,23 @@
$(CoreCompileDependsOn);
</CoreCompileDependsOn>
</PropertyGroup>
<Target Name="CssG" BeforeTargets="BeforeCompile" DependsOnTargets="PrepareResourceNames" Condition="'$(_CssGAlreadyExecuted)'!='true'">
<PropertyGroup>
<_CssGAlreadyExecuted>true</_CssGAlreadyExecuted>
</PropertyGroup>
<Target Name="_FindCSSFiles" DependsOnTargets="PrepareResourceNames">
<ItemGroup>
<_CSSInputs Include="@(EmbeddedResource)" Condition="'%(Extension)' == '.css' AND '$(DefaultLanguageSourceExtension)' == '.cs' AND '%(TargetPath)' != ''" />
<_CSSOutputs Include="@(_CSSInputs->'$(IntermediateOutputPath)%(TargetPath).g.cs')" />
</ItemGroup>
</Target>
<Target Name="CssG" BeforeTargets="BeforeCompile" DependsOnTargets="_FindCSSFiles" Inputs="@(_CSSInputs)" Outputs="@(_CSSOutputs)">
<CssGTask
XamlFiles="@(EmbeddedResource)" Condition="'%(Extension)' == '.css' AND '$(DefaultLanguageSourceExtension)' == '.cs'"
CSSFiles="@(_CSSInputs)"
OutputFiles="@(_CSSOutputs)"
Language = "$(Language)"
AssemblyName = "$(AssemblyName)"
OutputPath = "$(IntermediateOutputPath)">
<Output ItemName="FileWrites" TaskParameter="GeneratedCodeFiles" />
<Output ItemName="Compile" TaskParameter="GeneratedCodeFiles" />
</CssGTask>
AssemblyName = "$(AssemblyName)" />
<ItemGroup>
<FileWrites Include="@(_CSSOutputs)" />
<Compile Include="@(_CSSOutputs)" />
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -10,41 +10,47 @@ namespace Xamarin.Forms.Build.Tasks
{
public class CssGTask : Task
{
readonly List<ITaskItem> _generatedCodeFiles = new List<ITaskItem>();
[Required]
public ITaskItem[] CSSFiles { get; set; }
[Required]
public ITaskItem[] XamlFiles { get; set; }
[Output]
public ITaskItem[] GeneratedCodeFiles => _generatedCodeFiles.ToArray();
public ITaskItem[] OutputFiles { get; set; }
public string Language { get; set; }
public string AssemblyName { get; set; }
public string OutputPath { get; set; }
public override bool Execute()
{
bool success = true;
Log.LogMessage(MessageImportance.Normal, "Generating assembly attributes for CSS files");
if (XamlFiles == null) {
if (CSSFiles == null || OutputFiles == null) {
Log.LogMessage(MessageImportance.Low, "Skipping CssG");
return true;
}
foreach (var xamlFile in XamlFiles) {
var outputFile = Path.Combine(OutputPath, $"{xamlFile.GetMetadata("TargetPath")}.g.cs");
var generator = new CssGenerator(xamlFile, Language, AssemblyName, outputFile, Log);
if (CSSFiles.Length != OutputFiles.Length) {
Log.LogError("\"{2}\" refers to {0} item(s), and \"{3}\" refers to {1} item(s). They must have the same number of items.", CSSFiles.Length, OutputFiles.Length, "CSSFiles", "OutputFiles");
return false;
}
for (var i = 0; i < CSSFiles.Length;i++) {
var cssFile = CSSFiles[i];
var outputFile = OutputFiles[i].ItemSpec;
var generator = new CssGenerator(cssFile, Language, AssemblyName, outputFile, Log);
try {
if (generator.Execute())
_generatedCodeFiles.Add(new TaskItem(Microsoft.Build.Evaluation.ProjectCollection.Escape(outputFile)));
if (!generator.Execute()) {
//If Execute() fails, the file still needs to exist because it is added to the <Compile/> ItemGroup
File.WriteAllText(outputFile, string.Empty);
}
}
catch (XmlException xe) {
Log.LogError(null, null, null, xamlFile.ItemSpec, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source);
Log.LogError(null, null, null, cssFile.ItemSpec, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source);
success = false;
}
catch (Exception e) {
Log.LogError(null, null, null, xamlFile.ItemSpec, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source);
Log.LogError(null, null, null, cssFile.ItemSpec, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source);
success = false;
}
}

Просмотреть файл

@ -6,7 +6,7 @@ namespace Xamarin.Forms.Build.Tasks
public class GetTasksAbi : Task
{
[Output]
public string AbiVersion { get; } = "4";
public string AbiVersion { get; } = "5";
public override bool Execute()
=> true;

Просмотреть файл

@ -0,0 +1,109 @@
using System.Collections.Generic;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.ScrollView)]
[Category(UITestCategories.ListView)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 1931,
"Xamarin Forms on Android: ScrollView on ListView header crashes app when closing page",
PlatformAffected.Android)]
public class Issue1931 : TestNavigationPage
{
const string Go = "Go";
const string Back = "Back";
const string Success = "Success";
Label _result;
Label _instructions2;
ContentPage RootPage()
{
var page = new ContentPage();
page.Title = "GH1931 Root";
var button = new Button { Text = Go };
button.Clicked += (sender, args) => PushAsync(ListViewPage());
var instructions = new Label { Text = $"Tap the {Go} button" };
_result = new Label { Text = Success, IsVisible = false };
_instructions2 = new Label { Text = "If you can see this, the test has passed", IsVisible = false };
var layout = new StackLayout();
layout.Children.Add(instructions);
layout.Children.Add(button);
layout.Children.Add(_result);
layout.Children.Add(_instructions2);
page.Content = layout;
return page;
}
ContentPage ListViewPage()
{
var page = new ContentPage();
var layout = new StackLayout();
var listView = new ListView();
var scrollView = new ScrollView { Content = new BoxView { Color = Color.Green } };
listView.Header = scrollView;
listView.ItemsSource = new List<string> { "One", "Two", "Three" };
page.Title = "GH1931 Test";
var instructions = new Label { Text = $"Tap the {Back} button" };
var button = new Button { Text = Back };
button.Clicked += (sender, args) => PopAsync();
layout.Children.Add(instructions);
layout.Children.Add(button);
layout.Children.Add(listView);
page.Content = layout;
page.Appearing += (sender, args) =>
{
_instructions2.IsVisible = true;
_result.IsVisible = true;
};
return page;
}
protected override void Init()
{
PushAsync(RootPage());
}
#if UITEST
[Test]
public void ScrollViewInHeaderDisposesProperly()
{
RunningApp.WaitForElement(Go);
RunningApp.Tap(Go);
RunningApp.WaitForElement(Back);
RunningApp.Tap(Back);
RunningApp.WaitForElement(Success);
}
#endif
}
}

Просмотреть файл

@ -0,0 +1,49 @@
using System.Collections.Generic;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
#if UITEST
using Xamarin.UITest;
using Xamarin.UITest.Queries;
using NUnit.Framework;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 2499, "Binding Context set to Null in Picker", PlatformAffected.All)]
public class Issue2499 : TestContentPage
{
protected override void Init()
{
var _picker = new Picker()
{
ItemsSource = new List<string> { "cat", "mouse", "rabbit" },
AutomationId = "picker",
};
_picker.SelectedIndexChanged += (_, __) => _picker.ItemsSource = null;
Content = new StackLayout()
{
Children =
{
_picker
}
};
}
#if UITEST
[Test]
public void Issue2499Test ()
{
RunningApp.Tap ("picker");
AppResult[] items = RunningApp.Query("cat");
Assert.AreNotEqual(items.Length, 0);
RunningApp.Tap ("cat");
items = RunningApp.Query("cat");
Assert.AreEqual(items.Length, 0);
}
#endif
}
}

Просмотреть файл

@ -242,7 +242,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Effects\AttachedStateEffectList.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GitHub1702.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GitHub2598.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue1931.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2767.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2499.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GitHub1878.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ISampleNativeControl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ViewHelper.cs" />

Просмотреть файл

@ -23,7 +23,7 @@ namespace Xamarin.Forms.Core.UITests
if (Session == null)
{
DesiredCapabilities appCapabilities = new DesiredCapabilities();
appCapabilities.SetCapability("app", "0d4424f6-1e29-4476-ac00-ba22c3789cb6_wzjw7qdpbr1br!App");
appCapabilities.SetCapability("app", "0d4424f6-1e29-4476-ac00-ba22c3789cb6_ph1m9x8skttmg!App");
appCapabilities.SetCapability("deviceName", "WindowsPC");
Session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
Assert.IsNotNull(Session);

Просмотреть файл

@ -150,8 +150,11 @@ namespace Xamarin.Forms
void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
SelectedIndex = SelectedIndex.Clamp(-1, Items.Count - 1);
UpdateSelectedItem();
var oldIndex = SelectedIndex;
var newIndex = SelectedIndex = SelectedIndex.Clamp(-1, Items.Count - 1);
// If the index has not changed, still need to change the selected item
if (newIndex == oldIndex)
UpdateSelectedItem(newIndex);
}
static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
@ -214,13 +217,13 @@ namespace Xamarin.Forms
((LockableObservableListWrapper)Items).InternalClear();
foreach (object item in ItemsSource)
((LockableObservableListWrapper)Items).InternalAdd(GetDisplayMember(item));
UpdateSelectedItem();
UpdateSelectedItem(SelectedIndex);
}
static void OnSelectedIndexChanged(object bindable, object oldValue, object newValue)
{
var picker = (Picker)bindable;
picker.UpdateSelectedItem();
picker.UpdateSelectedItem(picker.SelectedIndex);
picker.SelectedIndexChanged?.Invoke(bindable, EventArgs.Empty);
}
@ -239,19 +242,19 @@ namespace Xamarin.Forms
SelectedIndex = Items.IndexOf(selectedItem);
}
void UpdateSelectedItem()
void UpdateSelectedItem(int index)
{
if (SelectedIndex == -1) {
if (index == -1) {
SelectedItem = null;
return;
}
if (ItemsSource != null) {
SelectedItem = ItemsSource [SelectedIndex];
SelectedItem = ItemsSource [index];
return;
}
SelectedItem = Items [SelectedIndex];
SelectedItem = Items [index];
}
public IPlatformElementConfiguration<T, Picker> On<T>() where T : IConfigPlatform

Просмотреть файл

@ -50,7 +50,7 @@ namespace Xamarin.Forms
_platformConfigurationRegistry = new Lazy<PlatformConfigurationRegistry<Stepper>>(() => new PlatformConfigurationRegistry<Stepper>(this));
}
public Stepper(double min, double max, double val, double increment)
public Stepper(double min, double max, double val, double increment) : this()
{
if (min >= max)
throw new ArgumentOutOfRangeException("min");

Просмотреть файл

@ -24,6 +24,7 @@ namespace Xamarin.Forms.Platform.Android
ScrollView _view;
int _previousBottom;
bool _isEnabled;
bool _disposed;
public ScrollViewRenderer(Context context) : base(context)
{
@ -176,18 +177,24 @@ namespace Xamarin.Forms.Platform.Android
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (_disposed)
{
return;
}
SetElement(null);
_disposed = true;
if (disposing)
{
Tracker.Dispose();
SetElement(null);
Tracker?.Dispose();
Tracker = null;
RemoveAllViews();
_container.Dispose();
_container?.Dispose();
_container = null;
}
base.Dispose(disposing);
}
protected override void OnAttachedToWindow()

Просмотреть файл

@ -36,6 +36,7 @@ namespace Xamarin.Forms.Platform.Android
if (e.OldElement == null)
{
_downButton = new AButton(Context) { Text = "-", Gravity = GravityFlags.Center, Tag = this };
_downButton.SetHeight((int)Context.ToPixels(10.0));
_downButton.SetOnClickListener(StepperListener.Instance);

Просмотреть файл

@ -45,6 +45,15 @@ namespace Xamarin.Forms.Xaml.UnitTests
</ContentView>";
}
class Css
{
public const string Foo = @"
label {
color: azure;
background-color: aliceblue;
}";
}
string testDirectory;
string tempDirectory;
string intermediateDirectory;
@ -139,6 +148,9 @@ namespace Xamarin.Forms.Xaml.UnitTests
//Let's enable XamlC assembly-wide
project.Add (AddFile ("AssemblyInfo.cs", "Compile", "[assembly: Xamarin.Forms.Xaml.XamlCompilation (Xamarin.Forms.Xaml.XamlCompilationOptions.Compile)]"));
//Add a single CSS file
project.Add (AddFile ("Foo.css", "EmbeddedResource", Css.Foo));
if (!sdkStyle)
project.Add (NewElement ("Import").WithAttribute ("Project", @"$(MSBuildBinPath)\Microsoft.CSharp.targets"));
@ -229,6 +241,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
AssertExists (Path.Combine (intermediateDirectory, "test.dll"), nonEmpty: true);
AssertExists (Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs"), nonEmpty: true);
AssertExists (Path.Combine (intermediateDirectory, "Foo.css.g.cs"), nonEmpty: true);
AssertExists (Path.Combine (intermediateDirectory, "XamlC.stamp"));
}
@ -246,11 +259,14 @@ namespace Xamarin.Forms.Xaml.UnitTests
Build (projectFile);
var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs");
var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs");
var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp");
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (fooCssG, nonEmpty: true);
AssertExists (xamlCStamp);
var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var expectdCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
//Build again
@ -259,8 +275,10 @@ namespace Xamarin.Forms.Xaml.UnitTests
AssertExists (xamlCStamp);
var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
Assert.AreEqual (expectedXamlG, actualXamlG, $"Timestamps should match for {mainPageXamlG}.");
Assert.AreEqual (expectdCssG, actualCssG, $"Timestamps should match for {fooCssG}.");
Assert.AreEqual (expectedXamlC, actualXamlC, $"Timestamps should match for {xamlCStamp}.");
}
@ -278,13 +296,16 @@ namespace Xamarin.Forms.Xaml.UnitTests
Build (projectFile);
var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs");
var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs");
var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp");
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (fooCssG, nonEmpty: true);
AssertExists (xamlCStamp);
//Clean
Build (projectFile, "Clean");
AssertDoesNotExist (mainPageXamlG);
AssertDoesNotExist (fooCssG);
AssertDoesNotExist (xamlCStamp);
}
@ -328,25 +349,31 @@ namespace Xamarin.Forms.Xaml.UnitTests
var assembly = Path.Combine (intermediateDirectory, "test.dll");
var mainPageXamlG = Path.Combine (intermediateDirectory, "Pages", "MainPage.xaml.g.cs");
var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs");
var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp");
//The assembly should not be compiled
AssertDoesNotExist (assembly);
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (fooCssG, nonEmpty: true);
AssertExists (xamlCStamp);
var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var expectedCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
//Build again, a full build
Build (projectFile);
AssertExists (assembly, nonEmpty: true);
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (fooCssG, nonEmpty: true);
AssertExists (xamlCStamp);
var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
Assert.AreEqual (expectedXamlG, actualXamlG, $"Timestamps should match for {mainPageXamlG}.");
Assert.AreEqual (expectedCssG, actualCssG, $"Timestamps should match for {fooCssG}.");
Assert.AreNotEqual (expectedXamlC, actualXamlC, $"Timestamps should *not* match for {xamlCStamp}.");
}
@ -362,6 +389,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
Build (projectFile, "UpdateDesignTimeXaml");
AssertExists (Path.Combine (intermediateDirectory, "Pages", "MainPage.xaml.g.cs"), nonEmpty: true);
AssertDoesNotExist (Path.Combine (intermediateDirectory, "Foo.css.g.cs"));
AssertDoesNotExist (Path.Combine (intermediateDirectory, "XamlC.stamp"));
}
@ -377,14 +405,16 @@ namespace Xamarin.Forms.Xaml.UnitTests
var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs");
var customViewXamlG = Path.Combine (intermediateDirectory, "CustomView.xaml.g.cs");
var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs");
var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp");
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (xamlCStamp);
var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var expectedCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
//Build again, after adding a file, this triggers a full XamlG and XamlC
//Build again, after adding a file, this triggers a full XamlG and XamlC -- *not* CssG
project.Add (AddFile ("CustomView.xaml", "EmbeddedResource", Xaml.CustomView));
project.Save (projectFile);
Build (projectFile);
@ -393,10 +423,12 @@ namespace Xamarin.Forms.Xaml.UnitTests
AssertExists (xamlCStamp);
var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
var actualNewFile = new FileInfo (customViewXamlG).LastAccessTimeUtc;
Assert.AreNotEqual (expectedXamlG, actualXamlG, $"Timestamps should *not* match for {mainPageXamlG}.");
Assert.AreNotEqual (expectedXamlG, actualNewFile, $"Timestamps should *not* match for {actualNewFile}.");
Assert.AreNotEqual (expectedXamlG, actualNewFile, $"Timestamps should *not* match for {customViewXamlG}.");
Assert.AreEqual (expectedCssG, actualCssG, $"Timestamps should match for {fooCssG}.");
Assert.AreNotEqual (expectedXamlC, actualXamlC, $"Timestamps should *not* match for {xamlCStamp}.");
}

Просмотреть файл

@ -174,7 +174,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.Maps.Design",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.Xaml.Design", "Xamarin.Forms.Xaml.Design\Xamarin.Forms.Xaml.Design.csproj", "{65BC4888-CC59-428A-9B75-540CF1C09480}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XFCorePostProcessor.Tasks", "XFCorePostProcessor.Tasks\XFCorePostProcessor.Tasks.csproj", "{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XFCorePostProcessor.Tasks", "XFCorePostProcessor.Tasks\XFCorePostProcessor.Tasks.csproj", "{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
@ -1574,6 +1574,18 @@ Global
{65BC4888-CC59-428A-9B75-540CF1C09480}.Release|x64.Build.0 = Release|Any CPU
{65BC4888-CC59-428A-9B75-540CF1C09480}.Release|x86.ActiveCfg = Release|Any CPU
{65BC4888-CC59-428A-9B75-540CF1C09480}.Release|x86.Build.0 = Release|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|x64.ActiveCfg = Debug|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|x86.ActiveCfg = Debug|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|ARM.ActiveCfg = Release|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|iPhone.ActiveCfg = Release|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|x64.ActiveCfg = Release|Any CPU
{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE