diff --git a/README.md b/README.md
index 63a03bc2..65acf582 100644
--- a/README.md
+++ b/README.md
@@ -80,14 +80,18 @@ Add the `ReactNativeVideo` project to your solution.
1. Open the solution in Visual Studio 2015
2. Right-click Solution icon in Solution Explorer > Add > Existing Project...
-3. Select `node_modules\react-native-video\windows\ReactNativeVideo\ReactNativeVideo.csproj`
+3.
+ UWP: Select `node_modules\react-native-video\windows\ReactNativeVideo\ReactNativeVideo.csproj`
+ WPF: Select `node_modules\react-native-video\windows\ReactNativeVideo.Net46\ReactNativeVideo.Net46.csproj`
**windows/myapp/myapp.csproj**
Add a reference to `ReactNativeVideo` to your main application project. From Visual Studio 2015:
1. Right-click main application project > Add > Reference...
-2. Check `ReactNativeVideo` from Solution Projects.
+2.
+ UWP: Check `ReactNativeVideo` from Solution Projects.
+ WPF: Check `ReactNativeVideo.Net46` from Solution Projects.
**MainPage.cs**
diff --git a/package.json b/package.json
index 38d798e0..fb7bde6e 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,8 @@
"eslint-config-airbnb": "4.0.0"
},
"dependencies": {
- "keymirror": "0.1.1"
+ "keymirror": "0.1.1",
+ "react-native-windows": "0.41.0-rc.0"
},
"scripts": {
"test": "node_modules/.bin/eslint *.js"
diff --git a/windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs b/windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..ca102d8a
--- /dev/null
+++ b/windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ReactNativeVideo.Net46")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ReactNativeVideo.Net46")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("2d8406ab-0674-42d3-8fe3-41d251403df8")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj b/windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj
new file mode 100644
index 00000000..df351c95
--- /dev/null
+++ b/windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj
@@ -0,0 +1,74 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}
+ Library
+ Properties
+ ReactNativeVideo.Net46
+ ReactNativeVideo.Net46
+ v4.6
+ 512
+
+
+ x64
+ bin\x64\Debug\
+
+
+ x64
+ bin\x64\Release\
+
+
+ x86
+ bin\x86\Debug\
+
+
+ x86
+ bin\x86\Release\
+
+
+
+ $(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}
+ ReactNative.Net46
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/windows/ReactNativeVideo.Net46/ReactVideoEventType.cs b/windows/ReactNativeVideo.Net46/ReactVideoEventType.cs
new file mode 100644
index 00000000..dd3f3feb
--- /dev/null
+++ b/windows/ReactNativeVideo.Net46/ReactVideoEventType.cs
@@ -0,0 +1,15 @@
+namespace ReactNativeVideo
+{
+ enum ReactVideoEventType
+ {
+ LoadStart,
+ Load,
+ Error,
+ Progress,
+ Seek,
+ End,
+ Stalled,
+ Resume,
+ ReadyForDisplay,
+ }
+}
diff --git a/windows/ReactNativeVideo.Net46/ReactVideoEventTypeExtensions.cs b/windows/ReactNativeVideo.Net46/ReactVideoEventTypeExtensions.cs
new file mode 100644
index 00000000..5f2b63db
--- /dev/null
+++ b/windows/ReactNativeVideo.Net46/ReactVideoEventTypeExtensions.cs
@@ -0,0 +1,36 @@
+using System;
+using static System.FormattableString;
+
+namespace ReactNativeVideo
+{
+ static class ReactVideoEventTypeExtensions
+ {
+ public static string GetEventName(this ReactVideoEventType eventType)
+ {
+ switch (eventType)
+ {
+ case ReactVideoEventType.LoadStart:
+ return "onVideoLoadStart";
+ case ReactVideoEventType.Load:
+ return "onVideoLoad";
+ case ReactVideoEventType.Error:
+ return "onVideoError";
+ case ReactVideoEventType.Progress:
+ return "onVideoProgress";
+ case ReactVideoEventType.Seek:
+ return "onVideoSeek";
+ case ReactVideoEventType.End:
+ return "onVideoEnd";
+ case ReactVideoEventType.Stalled:
+ return "onPlaybackStalled";
+ case ReactVideoEventType.Resume:
+ return "onPlaybackResume";
+ case ReactVideoEventType.ReadyForDisplay:
+ return "onReadyForDisplay";
+ default:
+ throw new NotSupportedException(
+ Invariant($"No event name added for event type '{eventType}'."));
+ }
+ }
+ }
+}
diff --git a/windows/ReactNativeVideo.Net46/ReactVideoPackage.cs b/windows/ReactNativeVideo.Net46/ReactVideoPackage.cs
new file mode 100644
index 00000000..b8cc654b
--- /dev/null
+++ b/windows/ReactNativeVideo.Net46/ReactVideoPackage.cs
@@ -0,0 +1,30 @@
+using ReactNative.Bridge;
+using ReactNative.Modules.Core;
+using ReactNative.UIManager;
+using System;
+using System.Collections.Generic;
+
+namespace ReactNativeVideo
+{
+ public class ReactVideoPackage : IReactPackage
+ {
+ public IReadOnlyList CreateJavaScriptModulesConfig()
+ {
+ return Array.Empty();
+ }
+
+ public IReadOnlyList CreateNativeModules(ReactContext reactContext)
+ {
+ return Array.Empty();
+
+ }
+
+ public IReadOnlyList CreateViewManagers(ReactContext reactContext)
+ {
+ return new List
+ {
+ new ReactVideoViewManager(),
+ };
+ }
+ }
+}
diff --git a/windows/ReactNativeVideo.Net46/ReactVideoView.cs b/windows/ReactNativeVideo.Net46/ReactVideoView.cs
new file mode 100644
index 00000000..8a8b1b29
--- /dev/null
+++ b/windows/ReactNativeVideo.Net46/ReactVideoView.cs
@@ -0,0 +1,359 @@
+using Newtonsoft.Json.Linq;
+using ReactNative.Bridge;
+using ReactNative.UIManager;
+using ReactNative.UIManager.Events;
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Threading;
+
+namespace ReactNativeVideo
+{
+ class ReactVideoView : Border, IDisposable
+ {
+ public const string EVENT_PROP_SEEK_TIME = "seekTime";
+
+ private readonly DispatcherTimer _timer;
+
+ private bool _isLoopingEnabled;
+ private bool _isPaused;
+ private bool _isMuted;
+ private bool _isCompleted;
+ private double _volume;
+ private double _rate;
+
+ private MediaPlayer _player;
+ private VideoDrawing _drawing;
+ private MediaTimeline _timeline;
+ private MediaClock _clock;
+ private DrawingBrush _brush;
+
+ public ReactVideoView()
+ {
+ _timer = new DispatcherTimer();
+ _timer.Interval = TimeSpan.FromMilliseconds(250.0);
+ _timer.Start();
+ _player = new MediaPlayer();
+ _drawing = new VideoDrawing();
+ _drawing.Rect = new Rect(0, 0, 100, 100); // Set the initial viewing area
+ _drawing.Player = _player;
+ _brush = new DrawingBrush(_drawing);
+ this.Background = _brush;
+ }
+
+ public string Source
+ {
+ set
+ {
+ var uri = new Uri(value);
+
+ _player.Open(uri);
+
+ this.GetReactContext()
+ .GetNativeModule()
+ .EventDispatcher
+ .DispatchEvent(
+ new ReactVideoEvent(
+ ReactVideoEventType.LoadStart.GetEventName(),
+ this.GetTag(),
+ new JObject
+ {
+ {"src", uri}
+ }));
+
+ ApplyModifiers();
+ SubscribeEvents();
+ }
+ }
+
+ public bool IsLoopingEnabled
+ {
+ set
+ {
+ _isLoopingEnabled = value;
+ }
+ }
+
+ public bool IsMuted
+ {
+ set
+ {
+ _isMuted = value;
+ if (_player != null)
+ {
+ _player.IsMuted = _isMuted;
+ }
+ }
+ }
+
+ public bool IsPaused
+ {
+ set
+ {
+ _isPaused = value;
+ if (_player != null)
+ {
+ if (_isPaused)
+ {
+ _player.Pause();
+ }
+ else
+ {
+ _player.Play();
+ }
+ }
+ }
+ }
+
+ public double Volume
+ {
+ set
+ {
+ _volume = value;
+ if (_player != null)
+ {
+ _player.Volume = _volume;
+ }
+ }
+ }
+
+ public double Rate
+ {
+ set
+ {
+ _rate = value;
+ if (_player != null)
+ {
+ _player.SpeedRatio = _rate;
+ }
+ }
+ }
+
+ public double ProgressUpdateInterval
+ {
+ set
+ {
+ _timer.Interval = TimeSpan.FromSeconds(value);
+ }
+ }
+
+ public void Seek(double seek)
+ {
+ if (_player != null)
+ {
+ _player.Position = TimeSpan.FromSeconds(seek);
+ }
+ }
+
+ public void Dispose()
+ {
+ if (_player != null)
+ {
+ _timer.Tick -= OnTick;
+ _player.MediaOpened -= OnMediaOpened;
+ _player.MediaFailed -= OnMediaFailed;
+ _player.MediaEnded -= OnMediaEnded;
+ _player.BufferingStarted -= OnBufferingStarted;
+ _player.BufferingEnded -= OnBufferingEnded;
+ // _player.SeekCompleted -= OnSeekCompleted;
+ }
+
+ _timer.Stop();
+ }
+
+ private void ApplyModifiers()
+ {
+ IsLoopingEnabled = _isLoopingEnabled;
+ IsMuted = _isMuted;
+ IsPaused = _isPaused;
+ Volume = _volume;
+ Rate = _rate;
+ }
+
+ private void SubscribeEvents()
+ {
+ _timer.Tick += OnTick;
+ _player.MediaOpened += OnMediaOpened;
+ _player.MediaFailed += OnMediaFailed;
+ _player.MediaEnded += OnMediaEnded;
+ _player.BufferingStarted += OnBufferingStarted;
+ _player.BufferingEnded += OnBufferingEnded;
+ //_player.SeekCompleted += OnSeekCompleted;
+ }
+
+ private void OnTick(object sender, object e)
+ {
+ if (_player != null && !_isCompleted && !_isPaused)
+ {
+ this.GetReactContext()
+ .GetNativeModule()
+ .EventDispatcher
+ .DispatchEvent(
+ new ReactVideoEvent(
+ ReactVideoEventType.Progress.GetEventName(),
+ this.GetTag(),
+ new JObject
+ {
+ { "currentTime", _player.Position.TotalSeconds },
+ { "playableDuration", 0.0 /* TODO */ }
+ }));
+ }
+ }
+
+ private void OnMediaOpened(object sender, EventArgs args)
+ {
+ RunOnDispatcher(delegate
+ {
+ var width = _player.NaturalVideoWidth;
+ var height = _player.NaturalVideoHeight;
+ var orientation = (width > height) ? "landscape" : "portrait";
+ var size = new JObject
+ {
+ { "width", width },
+ { "height", height },
+ { "orientation", orientation }
+ };
+
+ _drawing.Rect = new Rect(new Size(width, height));
+
+ this.GetReactContext()
+ .GetNativeModule()
+ .EventDispatcher
+ .DispatchEvent(
+ new ReactVideoEvent(
+ ReactVideoEventType.Load.GetEventName(),
+ this.GetTag(),
+ new JObject
+ {
+ { "duration", _player.NaturalDuration.TimeSpan.TotalSeconds },
+ { "currentTime", _player.Position.TotalSeconds },
+ { "naturalSize", size },
+ { "canPlayFastForward", false },
+ { "canPlaySlowForward", false },
+ { "canPlaySlow", false },
+ { "canPlayReverse", false },
+ { "canStepBackward", false },
+ { "canStepForward", false }
+ }));
+ });
+ }
+
+ private void OnMediaFailed(object sender, ExceptionEventArgs args)
+ {
+ var errorData = new JObject
+ {
+ { "what", args.ErrorException.HResult.ToString() },
+ { "extra", args.ErrorException.Message }
+ };
+
+ this.GetReactContext()
+ .GetNativeModule()
+ .EventDispatcher
+ .DispatchEvent(
+ new ReactVideoEvent(
+ ReactVideoEventType.Error.GetEventName(),
+ this.GetTag(),
+ new JObject
+ {
+ { "error", errorData }
+ }));
+ }
+
+ private void OnMediaEnded(object sender, EventArgs args)
+ {
+ if (_isLoopingEnabled)
+ {
+ _player.Position = TimeSpan.Zero;
+ _player.Play();
+ }
+ else
+ {
+ _isCompleted = true;
+ this.GetReactContext()
+ .GetNativeModule()
+ .EventDispatcher
+ .DispatchEvent(
+ new ReactVideoEvent(
+ ReactVideoEventType.End.GetEventName(),
+ this.GetTag(),
+ null));
+ }
+ }
+
+ private void OnBufferingStarted(object sender, EventArgs args)
+ {
+ this.GetReactContext()
+ .GetNativeModule()
+ .EventDispatcher
+ .DispatchEvent(
+ new ReactVideoEvent(
+ ReactVideoEventType.Stalled.GetEventName(),
+ this.GetTag(),
+ new JObject()));
+ }
+
+ private void OnBufferingEnded(object sender, EventArgs args)
+ {
+ this.GetReactContext()
+ .GetNativeModule()
+ .EventDispatcher
+ .DispatchEvent(
+ new ReactVideoEvent(
+ ReactVideoEventType.Resume.GetEventName(),
+ this.GetTag(),
+ new JObject()));
+ }
+
+ private void OnSeekCompleted(object sender, EventArgs args)
+ {
+ this.GetReactContext()
+ .GetNativeModule()
+ .EventDispatcher.DispatchEvent(
+ new ReactVideoEvent(
+ ReactVideoEventType.Seek.GetEventName(),
+ this.GetTag(),
+ new JObject()));
+ }
+
+ private static async void RunOnDispatcher(Action action)
+ {
+ await Application.Current.Dispatcher.InvokeAsync(action).Task.ConfigureAwait(false);
+ }
+
+ class ReactVideoEvent : Event
+ {
+ private readonly string _eventName;
+ private readonly JObject _eventData;
+
+ public ReactVideoEvent(string eventName, int viewTag, JObject eventData)
+ : base(viewTag, TimeSpan.FromTicks(Environment.TickCount))
+ {
+ _eventName = eventName;
+ _eventData = eventData;
+ }
+
+ public override string EventName
+ {
+ get
+ {
+ return _eventName;
+ }
+ }
+
+ public override bool CanCoalesce
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override void Dispatch(RCTEventEmitter eventEmitter)
+ {
+ eventEmitter.receiveEvent(ViewTag, EventName, _eventData);
+ }
+ }
+ }
+}
diff --git a/windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs b/windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs
new file mode 100644
index 00000000..e71f22c1
--- /dev/null
+++ b/windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs
@@ -0,0 +1,139 @@
+using Newtonsoft.Json.Linq;
+using ReactNative.UIManager;
+using ReactNative.UIManager.Annotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+
+namespace ReactNativeVideo
+{
+ class ReactVideoViewManager : SimpleViewManager
+ {
+ public override string Name
+ {
+ get
+ {
+ return "RCTVideo";
+ }
+ }
+
+ public override IReadOnlyDictionary ExportedViewConstants
+ {
+ get
+ {
+ return new Dictionary
+ {
+ { "ScaleNone", ((int)Stretch.None).ToString() },
+ { "ScaleToFill", ((int)Stretch.UniformToFill).ToString() },
+ { "ScaleAspectFit", ((int)Stretch.Uniform).ToString() },
+ { "ScaleAspectFill", ((int)Stretch.Fill).ToString() },
+ };
+ }
+ }
+
+ public override IReadOnlyDictionary ExportedCustomDirectEventTypeConstants
+ {
+ get
+ {
+ var events = new Dictionary();
+ var eventTypes = Enum.GetValues(typeof(ReactVideoEventType)).OfType();
+ foreach (var eventType in eventTypes)
+ {
+ events.Add(eventType.GetEventName(), new Dictionary
+ {
+ { "registrationName", eventType.GetEventName() },
+ });
+ }
+
+ return events;
+ }
+ }
+
+ [ReactProp("src")]
+ public void SetSource(ReactVideoView view, JObject source)
+ {
+ view.Source = source.Value("uri");
+ }
+
+ [ReactProp("resizeMode")]
+ public void SetResizeMode(ReactVideoView view, string resizeMode)
+ {
+ throw new NotImplementedException("Resize Mode has not been implemented for WPF.");
+ // view.Stretch = (Stretch)int.Parse(resizeMode);
+ }
+
+ [ReactProp("repeat")]
+ public void SetRepeat(ReactVideoView view, bool repeat)
+ {
+ view.IsLoopingEnabled = repeat;
+ }
+
+ [ReactProp("paused")]
+ public void SetPaused(ReactVideoView view, bool paused)
+ {
+ view.IsPaused = paused;
+ }
+
+ [ReactProp("muted")]
+ public void SetMuted(ReactVideoView view, bool muted)
+ {
+ view.IsMuted = muted;
+ }
+
+ [ReactProp("volume", DefaultDouble = 1.0)]
+ public void SetVolume(ReactVideoView view, double volume)
+ {
+ view.Volume = volume;
+ }
+
+ [ReactProp("seek")]
+ public void SetSeek(ReactVideoView view, double? seek)
+ {
+ if (seek.HasValue)
+ {
+ view.Seek(seek.Value);
+ }
+ }
+
+ [ReactProp("rate", DefaultDouble = 1.0)]
+ public void SetPlaybackRate(ReactVideoView view, double rate)
+ {
+ view.Rate = rate;
+ }
+
+ [ReactProp("playInBackground")]
+ public void SetPlayInBackground(ReactVideoView view, bool playInBackground)
+ {
+ throw new NotImplementedException("Play in background has not been implemented on Windows.");
+ }
+
+ // TODO: Utilize MediaElement when user control enabled and MediaPlayer + VideoDrawing when disabled
+ [ReactProp("controls")]
+ public void SetControls(ReactVideoView view, bool controls)
+ {
+ throw new NotImplementedException("User controls have not been implemented on WPF.");
+ }
+
+ [ReactProp("progressUpdateInterval")]
+ public void SetProgressUpdateInterval(ReactVideoView view, double progressUpdateInterval)
+ {
+ view.ProgressUpdateInterval = progressUpdateInterval;
+ }
+
+ public override void OnDropViewInstance(ThemedReactContext reactContext, ReactVideoView view)
+ {
+ base.OnDropViewInstance(reactContext, view);
+ view.Dispose();
+ }
+
+ protected override ReactVideoView CreateViewInstance(ThemedReactContext reactContext)
+ {
+ return new ReactVideoView
+ {
+ HorizontalAlignment = HorizontalAlignment.Stretch,
+ };
+ }
+ }
+}
diff --git a/windows/ReactNativeVideo.Net46/packages.config b/windows/ReactNativeVideo.Net46/packages.config
new file mode 100644
index 00000000..90aba300
--- /dev/null
+++ b/windows/ReactNativeVideo.Net46/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/windows/ReactNativeVideo.sln b/windows/ReactNativeVideo.sln
new file mode 100644
index 00000000..fe86ec07
--- /dev/null
+++ b/windows/ReactNativeVideo.sln
@@ -0,0 +1,49 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactNativeVideo.Net46", "ReactNativeVideo.Net46\ReactNativeVideo.Net46.csproj", "{2D8406AB-0674-42D3-8FE3-41D251403DF8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactNative.Net46", "..\node_modules\react-native-windows\ReactWindows\ReactNative.Net46\ReactNative.Net46.csproj", "{22CBFF9C-FE36-43E8-A246-266C7635E662}"
+EndProject
+Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ ..\node_modules\react-native-windows\ReactWindows\ReactNative.Shared\ReactNative.Shared.projitems*{22cbff9c-fe36-43e8-a246-266c7635e662}*SharedItemsImports = 4
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|ARM.ActiveCfg = Debug|x86
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|x64.ActiveCfg = Debug|x64
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|x64.Build.0 = Debug|x64
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|x86.ActiveCfg = Debug|x64
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|x86.Build.0 = Debug|x64
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|ARM.ActiveCfg = Release|x86
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|x64.ActiveCfg = Release|x64
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|x64.Build.0 = Release|x64
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|x86.ActiveCfg = Release|x86
+ {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|x86.Build.0 = Release|x86
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|ARM.ActiveCfg = Debug|ARM
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|ARM.Build.0 = Debug|ARM
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|x64.ActiveCfg = Debug|x64
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|x64.Build.0 = Debug|x64
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|x86.ActiveCfg = Debug|x86
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|x86.Build.0 = Debug|x86
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|ARM.ActiveCfg = Release|ARM
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|ARM.Build.0 = Release|ARM
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|x64.ActiveCfg = Release|x64
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|x64.Build.0 = Release|x64
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|x86.ActiveCfg = Release|x86
+ {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal