diff --git a/Emby.Drawing.Skia/SkiaEncoder.cs b/Emby.Drawing.Skia/SkiaEncoder.cs
index 2c7dc58c23..35a9bd8aa1 100644
--- a/Emby.Drawing.Skia/SkiaEncoder.cs
+++ b/Emby.Drawing.Skia/SkiaEncoder.cs
@@ -63,15 +63,15 @@ namespace Emby.Drawing.Skia
private void LogVersion()
{
+ // test an operation that requires the native library
+ SKPMColor.PreMultiply(SKColors.Black);
+
_logger.Info("SkiaSharp version: " + GetVersion());
}
public static string GetVersion()
{
- using (var bitmap = new SKBitmap())
- {
- return typeof(SKBitmap).GetTypeInfo().Assembly.GetName().Version.ToString();
- }
+ return typeof(SKBitmap).GetTypeInfo().Assembly.GetName().Version.ToString();
}
private static bool IsWhiteSpace(SKColor color)
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index eb5e0d82a9..be45912235 100644
--- a/Emby.Drawing/ImageProcessor.cs
+++ b/Emby.Drawing/ImageProcessor.cs
@@ -410,6 +410,11 @@ namespace Emby.Drawing
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());
}
+ public ImageSize GetImageSize(ItemImageInfo info, bool allowSlowMethods)
+ {
+ return GetImageSize(info.Path, info.DateModified, allowSlowMethods);
+ }
+
public ImageSize GetImageSize(ItemImageInfo info)
{
return GetImageSize(info.Path, info.DateModified, false);
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index e999f57532..1144bd3c66 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -4297,12 +4297,9 @@ namespace Emby.Server.Implementations.Data
}
}
- if (query.HasDeadParentId.HasValue)
+ if (query.HasDeadParentId.HasValue && query.HasDeadParentId.Value)
{
- if (query.HasDeadParentId.Value)
- {
- whereClauses.Add("ParentId NOT NULL AND ParentId NOT IN (select guid from TypedBaseItems)");
- }
+ whereClauses.Add("ParentId NOT NULL AND ParentId NOT IN (select guid from TypedBaseItems)");
}
if (query.Years.Length == 1)
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 9bf9f140d4..fb8308cda5 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -49,8 +49,13 @@ namespace Emby.Server.Implementations.LiveTv.Listings
get { return "xmltv"; }
}
- private string GetLanguage()
+ private string GetLanguage(ListingsProviderInfo info)
{
+ if (!string.IsNullOrWhiteSpace(info.PreferredLanguage))
+ {
+ return info.PreferredLanguage;
+ }
+
return _config.Configuration.PreferredMetadataLanguage;
}
@@ -152,7 +157,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
_logger.Debug("Getting xmltv programs for channel {0}", channelId);
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
- var reader = new XmlTvReader(path, GetLanguage());
+ var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetProgrammes(channelId, startDateUtc, endDateUtc, cancellationToken);
return results.Select(p => GetProgramInfo(p, info));
@@ -254,7 +259,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, CancellationToken.None).ConfigureAwait(false);
- var reader = new XmlTvReader(path, GetLanguage());
+ var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
// Should this method be async?
@@ -265,7 +270,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
- var reader = new XmlTvReader(path, GetLanguage());
+ var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
// Should this method be async?
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index 12b7901f93..8bf7a052e9 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -148,7 +148,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
},
RequiresOpening = true,
RequiresClosing = true,
- RequiresLooping = true,
+ RequiresLooping = info.EnableStreamLooping,
ReadAtNativeFramerate = false,
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index e4abe96f3a..34d0bd413a 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -265,7 +265,8 @@ namespace MediaBrowser.Api
Height = state.OutputHeight,
AudioChannels = state.OutputAudioChannels,
IsAudioDirect = string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase),
- IsVideoDirect = string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)
+ IsVideoDirect = string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase),
+ TranscodeReasons = state.TranscodeReasons
});
}
}
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 882967a53c..221755916b 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -326,7 +326,7 @@ namespace MediaBrowser.Api.Images
var fileInfo = _fileSystem.GetFileInfo(info.Path);
length = fileInfo.Length;
- var size = _imageProcessor.GetImageSize(info);
+ var size = _imageProcessor.GetImageSize(info, true);
width = Convert.ToInt32(size.Width);
height = Convert.ToInt32(size.Height);
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index bbee361995..e4ef294d17 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -583,6 +583,10 @@ namespace MediaBrowser.Api.Playback
videoRequest.DeInterlace = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
}
}
+ else if (i == 33)
+ {
+ request.TranscodeReasons = val;
+ }
}
}
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index ddd2d8cd29..c6282bbad5 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -541,6 +541,11 @@ namespace MediaBrowser.Api.Playback.Hls
{
queryString += "&SegmentContainer=" + state.Request.SegmentContainer;
}
+ // from universal audio service
+ if (!string.IsNullOrWhiteSpace(state.Request.TranscodeReasons) && queryString.IndexOf("TranscodeReasons=", StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ queryString += "&TranscodeReasons=" + state.Request.TranscodeReasons;
+ }
// Main stream
var playlistUrl = isLiveStream ? "live.m3u8" : "main.m3u8";
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index bba8094b64..6853ddbebf 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/MediaBrowser.Api/Playback/MediaInfoService.cs
@@ -513,6 +513,8 @@ namespace MediaBrowser.Api.Playback
var profiles = info.GetSubtitleProfiles(false, "-", accessToken);
mediaSource.DefaultSubtitleStreamIndex = info.SubtitleStreamIndex;
+ mediaSource.TranscodeReasons = info.TranscodeReasons;
+
foreach (var profile in profiles)
{
foreach (var stream in mediaSource.MediaStreams)
diff --git a/MediaBrowser.Api/Playback/UniversalAudioService.cs b/MediaBrowser.Api/Playback/UniversalAudioService.cs
index fffec69489..b9bcd106e1 100644
--- a/MediaBrowser.Api/Playback/UniversalAudioService.cs
+++ b/MediaBrowser.Api/Playback/UniversalAudioService.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Api.Playback.Hls;
using MediaBrowser.Api.Playback.Progressive;
@@ -265,7 +266,8 @@ namespace MediaBrowser.Api.Playback
Static = isStatic,
SegmentContainer = request.TranscodingContainer,
AudioSampleRate = request.MaxAudioSampleRate,
- BreakOnNonKeyFrames = transcodingProfile.BreakOnNonKeyFrames
+ BreakOnNonKeyFrames = transcodingProfile.BreakOnNonKeyFrames,
+ TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray())
};
if (isHeadRequest)
@@ -307,7 +309,8 @@ namespace MediaBrowser.Api.Playback
PlaySessionId = playbackInfoResult.PlaySessionId,
StartTimeTicks = request.StartTimeTicks,
Static = isStatic,
- AudioSampleRate = request.MaxAudioSampleRate
+ AudioSampleRate = request.MaxAudioSampleRate,
+ TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray())
};
if (isHeadRequest)
diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
index d98638d556..2832462a8d 100644
--- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs
+++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
@@ -33,6 +33,8 @@ namespace MediaBrowser.Controller.Drawing
/// ImageSize.
ImageSize GetImageSize(ItemImageInfo info);
+ ImageSize GetImageSize(ItemImageInfo info, bool allowSlowMethods);
+
///
/// Gets the size of the image.
///
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 34b33fde0d..ea442ba1ec 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -487,7 +487,7 @@ namespace MediaBrowser.Controller.Entities
var folder = this;
innerProgress.RegisterAction(p =>
{
- double newPct = .70 * p + 10;
+ double newPct = .80 * p + 10;
progress.Report(newPct);
ProviderManager.OnRefreshProgress(folder, newPct);
});
@@ -498,11 +498,11 @@ namespace MediaBrowser.Controller.Entities
if (refreshChildMetadata)
{
- progress.Report(80);
+ progress.Report(90);
if (recursive)
{
- ProviderManager.OnRefreshProgress(this, 80);
+ ProviderManager.OnRefreshProgress(this, 90);
}
var container = this as IMetadataContainer;
@@ -512,7 +512,7 @@ namespace MediaBrowser.Controller.Entities
var folder = this;
innerProgress.RegisterAction(p =>
{
- double newPct = .20 * p + 80;
+ double newPct = .10 * p + 90;
progress.Report(newPct);
if (recursive)
{
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index 57c81ddf76..a83a6a15ea 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Linq;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
@@ -9,6 +10,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Drawing;
+using MediaBrowser.Model.Session;
namespace MediaBrowser.Controller.MediaEncoding
{
@@ -40,6 +42,24 @@ namespace MediaBrowser.Controller.MediaEncoding
public bool ReadInputAtNativeFramerate { get; set; }
+ private List _transcodeReasons = null;
+ public List TranscodeReasons
+ {
+ get
+ {
+ if (_transcodeReasons == null)
+ {
+ _transcodeReasons = (BaseRequest.TranscodeReasons ?? string.Empty)
+ .Split(',')
+ .Where(i => !string.IsNullOrWhiteSpace(i))
+ .Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true))
+ .ToList();
+ }
+
+ return _transcodeReasons;
+ }
+ }
+
public bool IgnoreInputDts
{
get
@@ -251,7 +271,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
return AudioStream.SampleRate;
}
- }
+ }
else if (BaseRequest.AudioSampleRate.HasValue)
{
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
index 632c350ad0..28ef665669 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
@@ -204,6 +204,8 @@ namespace MediaBrowser.Controller.MediaEncoding
public string SubtitleCodec { get; set; }
+ public string TranscodeReasons { get; set; }
+
///
/// Gets or sets the index of the audio stream.
///
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index 5567063fe3..30b5f384fb 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -55,7 +55,6 @@ namespace MediaBrowser.Model.Configuration
HidePlayedInLatest = true;
PlayDefaultAudioTrack = true;
- DisplayMissingEpisodes = true;
LatestItemsExcludes = new string[] { };
OrderedViews = new string[] { };
diff --git a/MediaBrowser.Model/Dlna/ProfileCondition.cs b/MediaBrowser.Model/Dlna/ProfileCondition.cs
index 3d104f9c41..9234a27136 100644
--- a/MediaBrowser.Model/Dlna/ProfileCondition.cs
+++ b/MediaBrowser.Model/Dlna/ProfileCondition.cs
@@ -1,5 +1,4 @@
using System.Xml.Serialization;
-using MediaBrowser.Model.Dlna;
namespace MediaBrowser.Model.Dlna
{
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 0ecc413f24..b758d5ed53 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -105,8 +105,99 @@ namespace MediaBrowser.Model.Dlna
return null;
}
+ private TranscodeReason? GetTranscodeReasonForFailedCondition(ProfileCondition condition)
+ {
+ switch (condition.Property)
+ {
+ case ProfileConditionValue.AudioBitrate:
+ if (condition.Condition == ProfileConditionType.LessThanEqual)
+ {
+ return TranscodeReason.AudioBitrateNotSupported;
+ }
+ return TranscodeReason.AudioBitrateNotSupported;
+
+ case ProfileConditionValue.AudioChannels:
+ if (condition.Condition == ProfileConditionType.LessThanEqual)
+ {
+ return TranscodeReason.AudioChannelsNotSupported;
+ }
+ return TranscodeReason.AudioChannelsNotSupported;
+
+ case ProfileConditionValue.AudioProfile:
+ return TranscodeReason.AudioProfileNotSupported;
+
+ case ProfileConditionValue.AudioSampleRate:
+ return TranscodeReason.AudioSampleRateNotSupported;
+
+ case ProfileConditionValue.Has64BitOffsets:
+ // TODO
+ return null;
+
+ case ProfileConditionValue.Height:
+ return TranscodeReason.VideoResolutionNotSupported;
+
+ case ProfileConditionValue.IsAnamorphic:
+ return TranscodeReason.AnamorphicVideoNotSupported;
+
+ case ProfileConditionValue.IsAvc:
+ // TODO
+ return null;
+
+ case ProfileConditionValue.IsInterlaced:
+ return TranscodeReason.InterlacedVideoNotSupported;
+
+ case ProfileConditionValue.IsSecondaryAudio:
+ return TranscodeReason.SecondaryAudioNotSupported;
+
+ case ProfileConditionValue.NumAudioStreams:
+ // TODO
+ return null;
+
+ case ProfileConditionValue.NumVideoStreams:
+ // TODO
+ return null;
+
+ case ProfileConditionValue.PacketLength:
+ // TODO
+ return null;
+
+ case ProfileConditionValue.RefFrames:
+ return TranscodeReason.RefFramesNotSupported;
+
+ case ProfileConditionValue.VideoBitDepth:
+ return TranscodeReason.VideoBitDepthNotSupported;
+
+ case ProfileConditionValue.VideoBitrate:
+ return TranscodeReason.VideoBitrateNotSupported;
+
+ case ProfileConditionValue.VideoCodecTag:
+ return TranscodeReason.VideoCodecNotSupported;
+
+ case ProfileConditionValue.VideoFramerate:
+ return TranscodeReason.VideoFramerateNotSupported;
+
+ case ProfileConditionValue.VideoLevel:
+ return TranscodeReason.VideoLevelNotSupported;
+
+ case ProfileConditionValue.VideoProfile:
+ return TranscodeReason.VideoProfileNotSupported;
+
+ case ProfileConditionValue.VideoTimestamp:
+ // TODO
+ return null;
+
+ case ProfileConditionValue.Width:
+ return TranscodeReason.VideoResolutionNotSupported;
+
+ default:
+ return null;
+ }
+ }
+
private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options)
{
+ List transcodeReasons = new List();
+
StreamInfo playlistItem = new StreamInfo
{
ItemId = options.ItemId,
@@ -133,7 +224,10 @@ namespace MediaBrowser.Model.Dlna
MediaStream audioStream = item.GetDefaultAudioStream(null);
- List directPlayMethods = GetAudioDirectPlayMethods(item, audioStream, options);
+ var directPlayInfo = GetAudioDirectPlayMethods(item, audioStream, options);
+
+ List directPlayMethods = directPlayInfo.Item1;
+ transcodeReasons.AddRange(directPlayInfo.Item2);
ConditionProcessor conditionProcessor = new ConditionProcessor();
@@ -180,6 +274,11 @@ namespace MediaBrowser.Model.Dlna
if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate))
{
LogConditionFailure(options.Profile, "AudioCodecProfile", c, item);
+ var transcodeReason = GetTranscodeReasonForFailedCondition(c);
+ if (transcodeReason.HasValue)
+ {
+ transcodeReasons.Add(transcodeReason.Value);
+ }
all = false;
break;
}
@@ -292,9 +391,9 @@ namespace MediaBrowser.Model.Dlna
var longBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate);
playlistItem.AudioBitrate = longBitrate > int.MaxValue ? int.MaxValue : Convert.ToInt32(longBitrate);
-
}
+ playlistItem.TranscodeReasons = transcodeReasons;
return playlistItem;
}
@@ -308,8 +407,10 @@ namespace MediaBrowser.Model.Dlna
return options.GetMaxBitrate(isAudio);
}
- private List GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options)
+ private Tuple, List> GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options)
{
+ List transcodeReasons = new List();
+
DirectPlayProfile directPlayProfile = null;
foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles)
{
@@ -325,27 +426,134 @@ namespace MediaBrowser.Model.Dlna
if (directPlayProfile != null)
{
// While options takes the network and other factors into account. Only applies to direct stream
- if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true), PlayMethod.DirectStream) && options.EnableDirectStream)
+ if (item.SupportsDirectStream)
{
- playMethods.Add(PlayMethod.DirectStream);
+ if (IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true), PlayMethod.DirectStream))
+ {
+ if (options.EnableDirectStream)
+ {
+ playMethods.Add(PlayMethod.DirectStream);
+ }
+ }
+ else
+ {
+ transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit);
+ }
}
// The profile describes what the device supports
// If device requirements are satisfied then allow both direct stream and direct play
- if (item.SupportsDirectPlay &&
- IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), PlayMethod.DirectPlay) && options.EnableDirectPlay)
+ if (item.SupportsDirectPlay)
{
- playMethods.Add(PlayMethod.DirectPlay);
+ if (IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), PlayMethod.DirectPlay))
+ {
+ if (options.EnableDirectPlay)
+ {
+ playMethods.Add(PlayMethod.DirectPlay);
+ }
+ }
+ else
+ {
+ transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit);
+ }
}
}
else
{
+ transcodeReasons.InsertRange(0, GetTranscodeReasonsFromDirectPlayProfile(item, null, audioStream, options.Profile.DirectPlayProfiles));
+
_logger.Info("Profile: {0}, No direct play profiles found for Path: {1}",
options.Profile.Name ?? "Unknown Profile",
item.Path ?? "Unknown path");
}
- return playMethods;
+ if (playMethods.Count > 0)
+ {
+ transcodeReasons.Clear();
+ }
+ else
+ {
+ transcodeReasons = transcodeReasons.Distinct().ToList();
+ }
+
+ return new Tuple, List>(playMethods, transcodeReasons);
+ }
+
+ private List GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable directPlayProfiles)
+ {
+ var list = new List();
+ var containerSupported = false;
+ var audioSupported = false;
+ var videoSupported = false;
+
+ foreach (var profile in directPlayProfiles)
+ {
+ if (profile.Container.Length > 0)
+ {
+ // Check container type
+ string mediaContainer = item.Container ?? string.Empty;
+ foreach (string i in profile.GetContainers())
+ {
+ if (StringHelper.EqualsIgnoreCase(i, mediaContainer))
+ {
+ containerSupported = true;
+
+ if (videoStream != null)
+ {
+ // Check video codec
+ List videoCodecs = profile.GetVideoCodecs();
+ if (videoCodecs.Count > 0)
+ {
+ string videoCodec = videoStream.Codec;
+ if (!string.IsNullOrEmpty(videoCodec) && ListHelper.ContainsIgnoreCase(videoCodecs, videoCodec))
+ {
+ videoSupported = true;
+ }
+ }
+ else
+ {
+ videoSupported = true;
+ }
+ }
+
+ if (audioStream != null)
+ {
+ // Check audio codec
+ List audioCodecs = profile.GetAudioCodecs();
+ if (audioCodecs.Count > 0)
+ {
+ string audioCodec = audioStream.Codec;
+ if (!string.IsNullOrEmpty(audioCodec) && ListHelper.ContainsIgnoreCase(audioCodecs, audioCodec))
+ {
+ audioSupported = true;
+ }
+ }
+ else
+ {
+ audioSupported = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!containerSupported)
+ {
+ list.Add(TranscodeReason.ContainerNotSupported);
+ }
+
+ if (videoStream != null && !videoSupported)
+ {
+ list.Add(TranscodeReason.VideoCodecNotSupported);
+ }
+
+ if (audioStream != null && !audioSupported)
+ {
+ list.Add(TranscodeReason.VideoCodecNotSupported);
+ }
+
+ return list;
}
private int? GetDefaultSubtitleStreamIndex(MediaSourceInfo item, SubtitleProfile[] subtitleProfiles)
@@ -393,6 +601,8 @@ namespace MediaBrowser.Model.Dlna
private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options)
{
+ List transcodeReasons = new List();
+
StreamInfo playlistItem = new StreamInfo
{
ItemId = options.ItemId,
@@ -428,7 +638,8 @@ namespace MediaBrowser.Model.Dlna
if (isEligibleForDirectPlay || isEligibleForDirectStream)
{
// See if it can be direct played
- PlayMethod? directPlay = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
+ var directPlayInfo = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
+ var directPlay = directPlayInfo.Item1;
if (directPlay != null)
{
@@ -445,6 +656,8 @@ namespace MediaBrowser.Model.Dlna
return playlistItem;
}
+
+ transcodeReasons.AddRange(directPlayInfo.Item2);
}
// Can't direct play, find the transcoding profile
@@ -618,6 +831,8 @@ namespace MediaBrowser.Model.Dlna
}
}
+ playlistItem.TranscodeReasons = transcodeReasons;
+
return playlistItem;
}
@@ -677,7 +892,7 @@ namespace MediaBrowser.Model.Dlna
return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
}
- private PlayMethod? GetVideoDirectPlayProfile(VideoOptions options,
+ private Tuple> GetVideoDirectPlayProfile(VideoOptions options,
MediaSourceInfo mediaSource,
MediaStream videoStream,
MediaStream audioStream,
@@ -688,11 +903,11 @@ namespace MediaBrowser.Model.Dlna
if (options.ForceDirectPlay)
{
- return PlayMethod.DirectPlay;
+ return new Tuple>(PlayMethod.DirectPlay, new List());
}
if (options.ForceDirectStream)
{
- return PlayMethod.DirectStream;
+ return new Tuple>(PlayMethod.DirectStream, new List());
}
if (videoStream == null)
@@ -701,7 +916,7 @@ namespace MediaBrowser.Model.Dlna
profile.Name ?? "Unknown Profile",
mediaSource.Path ?? "Unknown path");
- return null;
+ return new Tuple>(null, new List { TranscodeReason.UnknownVideoStreamInfo });
}
// See if it can be direct played
@@ -721,7 +936,7 @@ namespace MediaBrowser.Model.Dlna
profile.Name ?? "Unknown Profile",
mediaSource.Path ?? "Unknown path");
- return null;
+ return new Tuple>(null, GetTranscodeReasonsFromDirectPlayProfile(mediaSource, videoStream, audioStream, profile.DirectPlayProfiles));
}
string container = mediaSource.Container;
@@ -784,7 +999,7 @@ namespace MediaBrowser.Model.Dlna
profile.Name ?? "Unknown Profile",
mediaSource.Path ?? "Unknown path");
- return null;
+ return new Tuple>(null, new List { TranscodeReason.UnknownVideoStreamInfo });
}
conditions = new List();
@@ -819,7 +1034,12 @@ namespace MediaBrowser.Model.Dlna
{
LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource);
- return null;
+ var transcodeReason = GetTranscodeReasonForFailedCondition(i);
+ var transcodeReasons = transcodeReason.HasValue
+ ? new List { transcodeReason.Value }
+ : new List { };
+
+ return new Tuple>(null, transcodeReasons);
}
}
@@ -833,7 +1053,7 @@ namespace MediaBrowser.Model.Dlna
profile.Name ?? "Unknown Profile",
mediaSource.Path ?? "Unknown path");
- return null;
+ return new Tuple>(null, new List { TranscodeReason.UnknownAudioStreamInfo });
}
conditions = new List();
@@ -870,17 +1090,22 @@ namespace MediaBrowser.Model.Dlna
{
LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource);
- return null;
+ var transcodeReason = GetTranscodeReasonForFailedCondition(i);
+ var transcodeReasons = transcodeReason.HasValue
+ ? new List { transcodeReason.Value }
+ : new List { };
+
+ return new Tuple>(null, transcodeReasons);
}
}
}
if (isEligibleForDirectStream && mediaSource.SupportsDirectStream)
{
- return PlayMethod.DirectStream;
+ return new Tuple>(PlayMethod.DirectStream, new List());
}
- return null;
+ return new Tuple>(null, new List { TranscodeReason.ContainerBitrateExceedsLimit });
}
private void LogConditionFailure(DeviceProfile profile, string type, ProfileCondition condition, MediaSourceInfo mediaSource)
@@ -1047,12 +1272,12 @@ namespace MediaBrowser.Model.Dlna
// Don't restrict by bitrate if coming from an external domain
if (item.IsRemote)
{
- return true;
+ return true;
}
if (!maxBitrate.HasValue)
{
- _logger.Info("Cannot "+ playMethod + " due to unknown supported bitrate");
+ _logger.Info("Cannot " + playMethod + " due to unknown supported bitrate");
return false;
}
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index ba5251e8c9..d70d89cf75 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -21,6 +21,7 @@ namespace MediaBrowser.Model.Dlna
AudioCodecs = new string[] { };
VideoCodecs = new string[] { };
SubtitleCodecs = new string[] { };
+ TranscodeReasons = new List();
}
public string ItemId { get; set; }
@@ -89,6 +90,7 @@ namespace MediaBrowser.Model.Dlna
public string PlaySessionId { get; set; }
public List AllMediaSources { get; set; }
+ public List TranscodeReasons { get; set; }
public string MediaSourceId
{
@@ -231,22 +233,11 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxWidth.Value) : string.Empty));
list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty));
- var forceStartPosition = false;
long startPositionTicks = item.StartPositionTicks;
- //if (item.MediaSource.DateLiveStreamOpened.HasValue && startPositionTicks == 0)
- //{
- // var elapsed = DateTime.UtcNow - item.MediaSource.DateLiveStreamOpened.Value;
- // elapsed -= TimeSpan.FromSeconds(20);
- // if (elapsed.TotalSeconds >= 0)
- // {
- // startPositionTicks = elapsed.Ticks + startPositionTicks;
- // forceStartPosition = true;
- // }
- //}
var isHls = StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls");
- if (isHls && !forceStartPosition)
+ if (isHls)
{
list.Add(new NameValuePair("StartTimeTicks", string.Empty));
}
@@ -310,6 +301,11 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("BreakOnNonKeyFrames", item.BreakOnNonKeyFrames.ToString()));
}
+ if (isDlna || !item.IsDirectStream)
+ {
+ list.Add(new NameValuePair("TranscodeReasons", string.Join(",", item.TranscodeReasons.Distinct().Select(i => i.ToString()).ToArray())));
+ }
+
return list;
}
diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
index c93eca0e79..08824913f8 100644
--- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs
+++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Model.MediaInfo;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Session;
namespace MediaBrowser.Model.Dto
{
@@ -110,6 +111,9 @@ namespace MediaBrowser.Model.Dto
}
}
+ [IgnoreDataMember]
+ public List TranscodeReasons { get; set; }
+
public int? DefaultAudioStreamIndex { get; set; }
public int? DefaultSubtitleStreamIndex { get; set; }
diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs
index 37a5541666..99f69e2030 100644
--- a/MediaBrowser.Model/Dto/UserDto.cs
+++ b/MediaBrowser.Model/Dto/UserDto.cs
@@ -122,16 +122,6 @@ namespace MediaBrowser.Model.Dto
/// The primary image aspect ratio.
public double? PrimaryImageAspectRatio { get; set; }
- ///
- /// Gets a value indicating whether this instance has primary image.
- ///
- /// true if this instance has primary image; otherwise, false.
- [IgnoreDataMember]
- public bool HasPrimaryImage
- {
- get { return PrimaryImageTag != null; }
- }
-
///
/// Initializes a new instance of the class.
///
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index 32153a11ca..fb8c34034e 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -47,6 +47,7 @@ namespace MediaBrowser.Model.LiveTv
public bool ImportFavoritesOnly { get; set; }
public bool AllowHWTranscoding { get; set; }
public bool EnableTvgId { get; set; }
+ public bool EnableStreamLooping { get; set; }
public TunerHostInfo()
{
@@ -74,6 +75,7 @@ namespace MediaBrowser.Model.LiveTv
public NameValuePair[] ChannelMappings { get; set; }
public string MoviePrefix { get; set; }
public bool EnableNewProgramIds { get; set; }
+ public string PreferredLanguage { get; set; }
public ListingsProviderInfo()
{
diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs
index 3c3c2bbc78..2f132cb373 100644
--- a/MediaBrowser.Model/Net/MimeTypes.cs
+++ b/MediaBrowser.Model/Net/MimeTypes.cs
@@ -72,6 +72,7 @@ namespace MediaBrowser.Model.Net
dict.Add(".tbn", "image/jpeg");
dict.Add(".png", "image/png");
dict.Add(".gif", "image/gif");
+ dict.Add(".tiff", "image/tiff");
dict.Add(".webp", "image/webp");
dict.Add(".ico", "image/vnd.microsoft.icon");
dict.Add(".mpg", "video/mpeg");
diff --git a/MediaBrowser.Model/Session/TranscodingInfo.cs b/MediaBrowser.Model/Session/TranscodingInfo.cs
index e646d80d35..67eac6fd57 100644
--- a/MediaBrowser.Model/Session/TranscodingInfo.cs
+++ b/MediaBrowser.Model/Session/TranscodingInfo.cs
@@ -1,3 +1,5 @@
+using System.Collections.Generic;
+
namespace MediaBrowser.Model.Session
{
public class TranscodingInfo
@@ -15,5 +17,36 @@ namespace MediaBrowser.Model.Session
public int? Width { get; set; }
public int? Height { get; set; }
public int? AudioChannels { get; set; }
+
+ public List TranscodeReasons { get; set; }
+
+ public TranscodingInfo()
+ {
+ TranscodeReasons = new List();
+ }
+ }
+
+ public enum TranscodeReason
+ {
+ ContainerNotSupported = 0,
+ VideoCodecNotSupported = 1,
+ AudioCodecNotSupported = 2,
+ ContainerBitrateExceedsLimit = 3,
+ AudioBitrateNotSupported = 4,
+ AudioChannelsNotSupported = 5,
+ VideoResolutionNotSupported = 6,
+ UnknownVideoStreamInfo = 7,
+ UnknownAudioStreamInfo = 8,
+ AudioProfileNotSupported = 9,
+ AudioSampleRateNotSupported = 10,
+ AnamorphicVideoNotSupported = 11,
+ InterlacedVideoNotSupported = 12,
+ SecondaryAudioNotSupported = 13,
+ RefFramesNotSupported = 14,
+ VideoBitDepthNotSupported = 15,
+ VideoBitrateNotSupported = 16,
+ VideoFramerateNotSupported = 17,
+ VideoLevelNotSupported = 18,
+ VideoProfileNotSupported = 19
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Server.Mono/ImageEncoderHelper.cs b/MediaBrowser.Server.Mono/ImageEncoderHelper.cs
index 12df23c1e0..36f11a52b1 100644
--- a/MediaBrowser.Server.Mono/ImageEncoderHelper.cs
+++ b/MediaBrowser.Server.Mono/ImageEncoderHelper.cs
@@ -31,7 +31,7 @@ namespace MediaBrowser.Server.Startup.Common
}
catch (Exception ex)
{
- logger.Info("Error loading Skia: {0}. Will revert to ImageMagick.", ex.Message);
+ logger.Error("Skia not available. Will try next image processor. {0}", ex.Message);
}
try
@@ -40,7 +40,7 @@ namespace MediaBrowser.Server.Startup.Common
}
catch
{
- logger.Error("Error loading ImageMagick. Will revert to GDI.");
+ logger.Error("ImageMagick not available. Will try next image processor.");
}
}
diff --git a/MediaBrowser.ServerApplication/ImageEncoderHelper.cs b/MediaBrowser.ServerApplication/ImageEncoderHelper.cs
index 56729e74ca..77e6c65fec 100644
--- a/MediaBrowser.ServerApplication/ImageEncoderHelper.cs
+++ b/MediaBrowser.ServerApplication/ImageEncoderHelper.cs
@@ -14,10 +14,10 @@ namespace MediaBrowser.Server.Startup.Common
{
public class ImageEncoderHelper
{
- public static IImageEncoder GetImageEncoder(ILogger logger,
- ILogManager logManager,
- IFileSystem fileSystem,
- StartupOptions startupOptions,
+ public static IImageEncoder GetImageEncoder(ILogger logger,
+ ILogManager logManager,
+ IFileSystem fileSystem,
+ StartupOptions startupOptions,
Func httpClient,
IApplicationPaths appPaths)
{
@@ -27,7 +27,7 @@ namespace MediaBrowser.Server.Startup.Common
}
catch
{
- logger.Error("Error loading Skia. Will revert to ImageMagick.");
+ logger.Error("Skia not available. Will try next image processor.");
}
return new NullImageEncoder();
diff --git a/MediaBrowser.ServerApplication/MainForm.Designer.cs b/MediaBrowser.ServerApplication/MainForm.Designer.cs
deleted file mode 100644
index 855a64899c..0000000000
--- a/MediaBrowser.ServerApplication/MainForm.Designer.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-namespace MediaBrowser.ServerApplication
-{
- partial class MainForm
- {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows Form Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
- this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
- this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
- this.cmdBrowse = new System.Windows.Forms.ToolStripMenuItem();
- this.cmdConfigure = new System.Windows.Forms.ToolStripMenuItem();
- this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
- this.cmdRestart = new System.Windows.Forms.ToolStripMenuItem();
- this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
- this.cmdCommunity = new System.Windows.Forms.ToolStripMenuItem();
- this.cmdExit = new System.Windows.Forms.ToolStripMenuItem();
- this.contextMenuStrip1.SuspendLayout();
- this.SuspendLayout();
- //
- // notifyIcon1
- //
- this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
- this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));
- this.notifyIcon1.Text = "Emby";
- this.notifyIcon1.Visible = true;
- //
- // contextMenuStrip1
- //
- this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.cmdBrowse,
- this.cmdConfigure,
- this.toolStripSeparator2,
- this.cmdRestart,
- this.toolStripSeparator1,
- this.cmdCommunity,
- this.cmdExit});
- this.contextMenuStrip1.Name = "contextMenuStrip1";
- this.contextMenuStrip1.ShowCheckMargin = true;
- this.contextMenuStrip1.ShowImageMargin = false;
- this.contextMenuStrip1.Size = new System.Drawing.Size(209, 192);
- //
- // cmdBrowse
- //
- this.cmdBrowse.Name = "cmdBrowse";
- this.cmdBrowse.Size = new System.Drawing.Size(208, 22);
- this.cmdBrowse.Text = "Browse Library";
- //
- // cmdConfigure
- //
- this.cmdConfigure.Name = "cmdConfigure";
- this.cmdConfigure.Size = new System.Drawing.Size(208, 22);
- this.cmdConfigure.Text = "Configure Media Browser";
- //
- // toolStripSeparator2
- //
- this.toolStripSeparator2.Name = "toolStripSeparator2";
- this.toolStripSeparator2.Size = new System.Drawing.Size(205, 6);
- //
- // cmdRestart
- //
- this.cmdRestart.Name = "cmdRestart";
- this.cmdRestart.Size = new System.Drawing.Size(208, 22);
- this.cmdRestart.Text = "Restart Server";
- //
- // toolStripSeparator1
- //
- this.toolStripSeparator1.Name = "toolStripSeparator1";
- this.toolStripSeparator1.Size = new System.Drawing.Size(205, 6);
- //
- // cmdCommunity
- //
- this.cmdCommunity.Name = "cmdCommunity";
- this.cmdCommunity.Size = new System.Drawing.Size(208, 22);
- this.cmdCommunity.Text = "Visit Community";
- //
- // cmdExit
- //
- this.cmdExit.Name = "cmdExit";
- this.cmdExit.Size = new System.Drawing.Size(208, 22);
- this.cmdExit.Text = "Exit";
- //
- // MainForm
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(284, 261);
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
- this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
- this.Name = "MainForm";
- this.ShowInTaskbar = false;
- this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
- this.Text = "MainForm";
- this.contextMenuStrip1.ResumeLayout(false);
- this.ResumeLayout(false);
-
- }
-
- #endregion
-
- private System.Windows.Forms.NotifyIcon notifyIcon1;
- private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
- private System.Windows.Forms.ToolStripMenuItem cmdExit;
- private System.Windows.Forms.ToolStripMenuItem cmdBrowse;
- private System.Windows.Forms.ToolStripMenuItem cmdConfigure;
- private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
- private System.Windows.Forms.ToolStripMenuItem cmdRestart;
- private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
- private System.Windows.Forms.ToolStripMenuItem cmdCommunity;
- }
-}
\ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/MainForm.cs b/MediaBrowser.ServerApplication/MainForm.cs
deleted file mode 100644
index d549507177..0000000000
--- a/MediaBrowser.ServerApplication/MainForm.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Windows.Forms;
-
-namespace MediaBrowser.ServerApplication
-{
- public partial class MainForm : Form
- {
- public MainForm()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/MediaBrowser.ServerApplication/MainForm.resx b/MediaBrowser.ServerApplication/MainForm.resx
deleted file mode 100644
index fb089f594c..0000000000
--- a/MediaBrowser.ServerApplication/MainForm.resx
+++ /dev/null
@@ -1,576 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
-
- 17, 17
-
-
- 130, 17
-
-
-
- AAABAAgAMDAAAAEAIACoJQAAhgAAADAwAAABAAgAqA4AAC4mAAAgIAAAAQAgAKgQAADWNAAAICAAAAEA
- CACoCAAAfkUAABgYAAABACAAiAkAACZOAAAYGAAAAQAIAMgGAACuVwAAEBAAAAEAIABoBAAAdl4AABAQ
- AAABAAgAaAUAAN5iAAAoAAAAMAAAAGAAAAABACAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu2UkpItlMxAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7RQM0u1Uv9LtVL/S7NSJQAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABKtFIfS7VS/0u1
- Uv9LtVL/S7VS/0i2SAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEuz
- Uz1LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9ItkgHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAS7NRTku1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7NSJQAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAABLs1FOS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0i2
- UzEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEuzUz1LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv/OtgAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASrRSH0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/xsYACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtFAzS7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqqAAMAAAAAAAAAAEu2UkpLtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv/atgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv/MuwAPTLVSUEu1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/0rwAFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/9K8ABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/atgAOAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/8Dkwf9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////bsBk/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS//////////////////////9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////
- /////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////
- ///////////////////////////////////d6sP/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/////////////////////////////////////////////////0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////////////////////////////
- ////////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////////////
- //////////////////////////////////9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////
- ////////////////////////////////////////////////////////0uOr/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAA/wABS7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////
- ////////////////////////////////////////////////////////////////////////V7lZ/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/////////////////////////////////////////////////////////////////7Dd
- rP9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////////////////////////////
- ////////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9ItlMxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////////////
- /////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0uzUiUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////
- //////////////////9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/SLZIBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAD/AAFLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////
- ////////////////////////+fff/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9ItkgHAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS//////////////////////9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/9S4ABIAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/1L8AGAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/1q6Xf9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv/OtgAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/8bGAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/atgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/9K8ABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtFHOAAAAAEu1Uv9LtVL/0rwAFwAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0q0UdQAAAAAAAAAAAAAAADatgAOAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/SrVS7AAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0q0
- UuIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/SrVS0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9KtVLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0q0UuIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9KtVLsAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEq0UdQAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///+f//8AAP///w///wAA///+B///
- AAD///wD//8AAP//+AH//wAA///wAP//AAD//+AAf/8AAP//wAA//wAA//+AAB//AAD/8wAAD/8AAP/g
- AAAH/wAA/8AAAAP/AAD/gAAAA/8AAP8AAAAH/wAA/gAAAAP/AAD8AAAAAf8AAPgAAAAA/wAA8AAAAAB/
- AADgAAAAAD8AAMAAAAAAHwAAgAAAAAAPAACAAAAAAAcAAMAAAAAAAwAA4AAAAAABAADwAAAAAAAAAPgA
- AAAAAQAA/AAAAAADAAD+AAAAAAcAAP8AAAAADwAA/4AAAAAfAAD/wAAAAD8AAP/gAAAAfwAA/+AAAAD/
- AAD/wAAAAf8AAP/AAAAD/wAA/+AAAAf/AAD/8AAAT/8AAP/4AAD//wAA//wAAf//AAD//gAD//8AAP//
- AAf//wAA//+AD///AAD//8Af//8AAP//4D///wAA///wf///AAD///j///8AAP///f///wAAKAAAADAA
- AABgAAAAAQAIAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAP9vtzz/cLc8/1+2Rv9RtU//S7VS/0y1
- Uf9NtVH/TrVQ/0+1UP9NtlP/TbZU/062VP9Rt1f/VLla/1W5W/9WuVz/Y7ZD/2C2Rf9htkX/YrZE/2O2
- RP9otkD/Yb5m/2S/aP9mv2j/aMBq/3jHef95x3z/e8h8/3zIfP9+yX//f8qD/4PMiP+R0ZL/ktGS/5TS
- lP+V0pX/mdSY/6jaqP+s3Kv/r92t/7Ddrv/G5sL/xufF/8jnxv/L6cj/3fDb/9/x3f/g8d3/4/Pg/+/4
- 7f/x+e//8vnv//r8+P/7/fn//v/+/////v8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAABQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQUFAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBQUFBQAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFBQUFBQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAUFBQUFBQUFBQUFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUF
- BQUFBQUFBQUFBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFBQUFBQUFBQUFBQMA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQUFBQUFBQUFBQUFBQYDAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAUFBQUFBQUFBQUFBQUFBQUGAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAUEgAABQUFBQUFBQUFBQUFBQUFBQUFBgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUHBhIFBQUFBQUF
- BQUFBQUFBQUFBQUFBQYDAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQcFBQYFBQUFBQUFBQUFBQUFBQUFBQUF
- BQUGAwAAAAAAAAAAAAAAAAAAAAAAAAAVBwUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBhIAAAAAAAAA
- AAAAAAAAAAAAABUHBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCBUAAAAAAAAAAAAAAAAAAAAAFQcF
- BQUFBQUFBQUGBQUFBQUFBQUFBQUFBQUFBQUFEwAAAAAAAAAAAAAAAAAAAAAVBwUFBQUFBQUFBQUgKg8F
- BQUFBQUFBQUFBQUFBQUFBQUAAAAAAAAAAAAAAAAAABUHBQUFBQUFBQUFBQUhOTUkDAUFBQUFBQUFBQUF
- BQUFBQUFAAAAAAAAAAAAAAAAFQcFBQUFBQUFBQUFBQUhOTk5MR4FBQUFBQUFBQUFBQUFBQUFBQAAAAAA
- AAAAAAASBwUFBQUFBQUFBQUFBQUhOTk5OTgsGAUFBQUFBQUFBQUFBQUFBQUAAAAAAAAAAAUFBQUFBQUF
- BQUFBQUFBQUhOTk5OTk5NygOBQUFBQUFBQUFBQUFBQUFAAAAAAAABQUFBQUFBQUFBQUFBQUFBQUhOTk5
- OTk5OTkzIwsFBQUFBQUFBQUFBQUFBQAAAAAFBQUFBQUFBQUFBQUFBQUFBQUhOTk5OTk5OTk5OS8bBQUF
- BQUFBQUFBQUFBQUAAAAFBQUFBQUFBQUFBQUFBQUFBQUhOTk5OTk5OTk5OTk4KxcFBQUFBQUFBQUFBQUF
- AAAABQUFBQUFBQUFBQUFBQUFBQUhOTk5OTk5OTk5OTk5OTYnDQUFBQUFBQUFBQUFBQAAAAUFBQUFBQUF
- BQUFBQUFBQUhOTk5OTk5OTk5OTk5OTMiCwUFBQUFBQUFBQUFBQUAAAAFBQUFBQUFBQUFBQUFBQUhOTk5
- OTk5OTk5OTk2KQ4FBQUFBQUFBQUFBQUFBQUAAAAABQUFBQUFBQUFBQUFBQUhOTk5OTk5OTk5OS0ZBQUF
- BQUFBQUFBQUFBQUFBQUAAAAAAAUFBQUFBQUFBQUFBQUhOTk5OTk5OTkwHQUFBQUFBQUFBQUFBQUFBQUF
- BQAAAAAAAAAFBQUFBQUFBQUFBQUhOTk5OTk5NCUKBQUFBQUFBQUFBQUFBQUFBQUFAAAAAAAAAAAABQUF
- BQUFBQUFBQUhOTk5OTcpEAUFBQUFBQUFBQUFBQUFBQUFBQUAAAAAAAAAAAAAAAUFBQUFBQUFBQUhOTk5
- LhoFBQUFBQUFBQUFBQUFBQUFBQUGAwAAAAAAAAAAAAAAAAAFBQUFBQUFBQUhOTIfBQUFBQUFBQUFBQUF
- BQUFBQUFBQYDAAAAAAAAAAAAAAAAAAAABQUFBQUFBQUcJgsFBQUFBQUFBQUFBQUFBQUFBQUFBgMAAAAA
- AAAAAAAAAAAAAAAAFgcFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUGAwAAAAAAAAAAAAAAAAAAAAAW
- CQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQYDAAAAAAAAAAAAAAAAAAAAAAARBwUFBQUFBQUFBQUF
- BQUFBQUFBQUFBQUFBQUFBgMAAAAAAAAAAAAAAAAAAAAAAAAAFQcFBQUFBQUFBQUFBQUFBQUFBQUFBQUH
- BQUGAwAAAAAAAAAAAAAAAAAAAAAAAAAAABUHBQUFBQUFBQUFBQUFBQUFBQUFBQUBBAYDAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAUBwUFBQUFBQUFBQUFBQUFBQUFBQUAAhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAFAcFBQUFBQUFBQUFBQUFBQUFBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQHBQUFBQUF
- BQUFBQUFBQUFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVBwUFBQUFBQUFBQUFBQUAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQcFBQUFBQUFBQUFBQAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAABQHBQUFBQUFBQUFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAVBwUFBQUFBQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQcF
- BQUFBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUHBQUFAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVBwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAD///////8AAP///5///wAA////D///AAD///4H//8AAP///AP//wAA///4Af//AAD///AA//8AAP//
- 4AB//wAA///AAD//AAD//4AAH/8AAP/zAAAP/wAA/+AAAAf/AAD/wAAAA/8AAP+AAAAD/wAA/wAAAAf/
- AAD+AAAAA/8AAPwAAAAB/wAA+AAAAAD/AADwAAAAAH8AAOAAAAAAPwAAwAAAAAAfAACAAAAAAA8AAIAA
- AAAABwAAwAAAAAADAADgAAAAAAEAAPAAAAAAAAAA+AAAAAABAAD8AAAAAAMAAP4AAAAABwAA/wAAAAAP
- AAD/gAAAAB8AAP/AAAAAPwAA/+AAAAB/AAD/4AAAAP8AAP/AAAAB/wAA/8AAAAP/AAD/4AAAB/8AAP/w
- AABP/wAA//gAAP//AAD//AAB//8AAP/+AAP//wAA//8AB///AAD//4AP//8AAP//wB///wAA///gP///
- AAD///B///8AAP//+P///wAA///9////AAAoAAAAIAAAAEAAAAABACAAAAAAAAAgAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAABLtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/AAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtFH+S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv/8/fz/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS//z9/P///////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVH/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL//P38//////////////////////9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/8/fz/////////////////////////
- ///q8dP/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS//z9/P//////////////
- ////////////////////////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL//P38////
- /////////////////////////////////////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv/8/fz/////////////////////////////////////////////////S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS//z9/P//////////////////////////////////////S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL//P38////////////////////////////mspu/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/8/fz//////////////////v7+/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS//z9/P///////////0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL//P38/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAEu1
- Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAEu0Uf5LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uf9LtVL/S7VS/0u1
- Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//v////x////4P///8B///+AP///AB//9gAP/+AAB//AAAP/gA
- AH/wAAB/4AAAP8AAAB+AAAAPAAAAB4AAAAPAAAAB4AAAAPAAAAH4AAAD/AAAB/4AAA/+AAAf/AAAP/4A
- AH//AAb//4AP///AH///4D////B////4/////f//KAAAACAAAABAAAAAAQAIAAAAAAAACAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAP95tzb/erc2/3u3Nf9wtzz/VrZL/1C1T/9RtU7/UrVO/1O1Tf9VtUz/VbZM/0u1
- Uv9NtVH/TrVQ/0+1UP9NtlT/ULdW/1a5W/9gtkb/Y7ZE/2i2QP9bu2D/Zb9p/2vCb/9vw3L/d8d6/33J
- fv+NuCr/jrgq/4+4Kf+SuSf/k7kn/5C5Kf+SuSj/hcyG/4fNif+U0pX/l9OY/5bUmf+e15//n9eh/63d
- rv+s3bD/uOG5/8jox//Q68//0+zS/97x3f/h8t//5vTl//D47//1+/T/+/36//3+/f//////AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAADAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAADAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAYCAAAAAAAAAAAAAAAAAAAA
- AAAAAAAMDAwMDAwMDAwMDAcBAAAAAAAAAAAAAAAAAAAAIAsTDAwMDAwMDAwMDAwMDAcDAAAAAAAAAAAA
- AAAAACAJDA4MDAwMDAwMDAwMDAwMDAcDAAAAAAAAAAAAAAAdCQwMDAwMDAwMDAwMDAwMDAwMDAoAAAAA
- AAAAAAAAHgkMDAwMDAwMDAwMDAwMDAwMDAwNFAAAAAAAAAAAACAJDAwMDAwMDCkmEAwMDAwMDAwMDAwM
- AAAAAAAAAAAhCQwMDAwMDAwMKzcxGwwMDAwMDAwMDAwMAAAAAAAADAcMDAwMDAwMDAwrNzc3LRcMDAwM
- DAwMDAwMAAAAAAwMDAwMDAwMDAwMDCs3Nzc3NSoSDAwMDAwMDAwMAAAADAwMDAwMDAwMDAwMKzc3Nzc3
- NzMlEAwMDAwMDAwMAAAMDAwMDAwMDAwMDAwrNzc3Nzc3NzcwGgwMDAwMDAwMAAAMDAwMDAwMDAwMDCs3
- Nzc3Nzc3Ny4YDAwMDAwMDAwMAAAMDAwMDAwMDAwMKzc3Nzc3NzIjDAwMDAwMDAwMDAwAAAAMDAwMDAwM
- DAwrNzc3NzQoEQwMDAwMDAwMDAwMDAAAAAAMDAwMDAwMDCs3NzYsFgwMDAwMDAwMDAwMDAwAAAAAAAAM
- DAwMDAwMKzcvGQwMDAwMDAwMDAwMDAcCAAAAAAAAAAAMDAwMDAwnJAwMDAwMDAwMDAwMDAwHAwAAAAAA
- AAAAABUPDAwMDAwMDAwMDAwMDAwMDAwMBwIAAAAAAAAAAAAABQwMDAwMDAwMDAwMDAwMDAwMDAcBAAAA
- AAAAAAAAAAAfCQwMDAwMDAwMDAwMDAwMDwwHAgAAAAAAAAAAAAAAAAAfCQwMDAwMDAwMDAwMDAwEBQIA
- AAAAAAAAAAAAAAAAAAAcCQwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAeCQwMDAwMDAwMDAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAgCQwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeCQwMDAwM
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdCQwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi
- CAwAAAAAAAAAAAAAAAAAAAAA//+/////H////g////wH///4A///8AH//2AA//4AAH/8AAA/+AAAf/AA
- AH/gAAA/wAAAH4AAAA8AAAAHgAAAA8AAAAHgAAAA8AAAAfgAAAP8AAAH/gAAD/4AAB/8AAA//gAAf/8A
- Bv//gA///8Af///gP///8H////j////9//8oAAAAGAAAADAAAAABACAAAAAAAAASAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASrRSQUm1
- Ty0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJtU8tS7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEuz
- UVFLtVL/S7VS/0u1Uv9LtVL/SbVPLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASbVPLUu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/8+/
- ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AABKtFJBS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/UqgAGAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/2S1QV5LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/1L8AGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL///////////9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL//////////////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/////////////////////////
- ///29+b/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL//////////////////////////////////////0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/////////
- /////////////////////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL///////////////////////////+l1ZP/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9JtU8tAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
- Uv9LtVL//////////////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL///////////9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/0LkAFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv/PvwAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/9SqAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u0
- UtJLtVL/1L8AGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/SrVR3gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9KtVLyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u0Uc4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
- Uv9LtVL/SrVS8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABKtVHeAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP/z/wD/4f8A/8D/AP+AfwD9AD8A+AAfAPAA
- HwDgAA8AwAAHAIAAAwCAAAEAwAAAAOAAAQDwAAMA+AAHAPwADwD4AB8A/AA/AP4A/wD/Af8A/4P/AP/H
- /wD/7/8AKAAAABgAAAAwAAAAAQAIAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9UtUz/VbZM/0u1
- Uv9MtVH/TbVR/061UP9PtVD/TLZT/062VP9SuFj/Vrlc/2W2Qv9htkX/Xr1j/2XAav9qwW7/ccR1/3LF
- dv99yYD/iM6L/5PSlv+j2aX/r92w/73kvv/B5sP/yejJ/9ju1//h8uD/6vbp//H58P/3/Pb/+/36//7+
- /v//////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAA
- AAADAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAAAAAAAA
- AAAAAAAAAAAAAAADAwMDAwMDAQAAAAAAAAAAAAAAAAANAAMDAwMDAwMDAwEAAAAAAAAAAAAAAAIEBgMD
- AwMDAwMDAwMBAAAAAAAAAAAAAgQDAwMDAwMDAwMDAwMEDQAAAAAAAAACBAMDAwMRCQMDAwMDAwMFAwAA
- AAAAAAIEAwMDAwMZHBMDAwMDAwMDAwMAAAAABwQDAwMDAwMZIiIaDwMDAwMDAwMDAAADAwMDAwMDAwMZ
- IiIiIBcLAwMDAwMDAwADAwMDAwMDAwMZIiIiIiIeFQgDAwMDAwMAAwMDAwMDAwMZIiIiIiIdFAMDAwMD
- AwMAAAMDAwMDAwMZIiIiHxYKAwMDAwMDAwMAAAADAwMDAwMZIiEYDgMDAwMDAwMDAwAAAAAAAwMDAwMZ
- GxIDAwMDAwMDAwMBAAAAAAAAAAYDAwMQBAMDAwMDAwMDAwEAAAAAAAAADAUDAwMDAwMDAwMDAwMDAQAA
- AAAAAAAAAAIEAwMDAwMDAwMDBQUBAAAAAAAAAAAAAAACBAMDAwMDAwMDAwwAAAAAAAAAAAAAAAAAAgQD
- AwMDAwMDAAAAAAAAAAAAAAAAAAAAAAIEAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAACBAMDAwAAAAAAAAAA
- AAAAAAAAAAAAAAAAAgQDAAAAAAAAAAAAAAD///8A//P/AP/h/wD/wP8A/4B/AP0APwD4AB8A8AAfAOAA
- DwDAAAcAgAADAIAAAQDAAAAA4AABAPAAAwD4AAcA/AAPAPgAHwD8AD8A/gD/AP8B/wD/g/8A/8f/AP/v
- /wAoAAAAEAAAACAAAAABACAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAABLtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv//////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
- AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/////////////////S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv8AAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////S7VS/0u1
- Uv9LtVL/S7VS/wAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv//////////////////////sN2s/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/////////////////S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS//////9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
- Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1
- Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AABLtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAEu1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9/AAD+PwAA/B8AAPAP
- AADgBwAAwAcAAIADAAAAAQAAgAAAAMABAADgAwAA4AcAAPAPAAD4PwAA/H8AAP7/AAAoAAAAEAAAACAA
- AAABAAgAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAA/0+1T/9QtU//VLVM/1W2TP9LtVL/TLVR/021
- Uf9PtVD/U7hZ/1a5XP9hvmb/ZsBr/3bGev99yYH/qNuq/6/esf+y37T/uOK6/8Lmw//K6cr/1u7X//n8
- +f/7/fv////+/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
- AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAFBQUAAAAAAAAAAAAAAAAFBQUF
- BQAAAAAAAAAAAAAFBQUFBQYDAAAAAAAAAAQBBQUFBQUFBgMAAAAAAAQGBQUFBQUFBQUIAAAAAAQGBQUF
- Eg4FBQUFBQUAAAUGBQUFBRUYFAwFBQUFBQAFBQUFBQUVGBgXEAoFBQUFBQUFBQUFFRgYFg8JBQUFBQAF
- BQUFBRUYEwsFBQUFBQUAAAUFBQURDQUFBQUFBgMAAAAAAgUFBQUFBQUFBgMAAAAAAAQGBQUFBQUFAQMA
- AAAAAAAABAYFBQUFBQAAAAAAAAAAAAAEBgUFBQAAAAAAAAAAAAAAAAQHBQAAAAAAAAD/fwAA/j8AAPwf
- AADwDwAA4AcAAMAHAACAAwAAAAEAAIAAAADAAQAA4AMAAOAHAADwDwAA+D8AAPx/AAD+/wAA
-
-
-
\ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index a0494b3e5c..8cd8138fdd 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -53,31 +53,10 @@ namespace MediaBrowser.ServerApplication
private static IFileSystem FileSystem;
- public static bool TryGetLocalFromUncDirectory(string local, out string unc)
- {
- if ((local == null) || (local == ""))
- {
- unc = "";
- throw new ArgumentNullException("local");
- }
-
- ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_share WHERE path ='" + local.Replace("\\", "\\\\") + "'");
- ManagementObjectCollection coll = searcher.Get();
- if (coll.Count == 1)
- {
- foreach (ManagementObject share in searcher.Get())
- {
- unc = share["Name"] as String;
- unc = "\\\\" + SystemInformation.ComputerName + "\\" + unc;
- return true;
- }
- }
- unc = "";
- return false;
- }
///
/// Defines the entry point of the application.
///
+ [STAThread]
public static void Main()
{
var options = new StartupOptions(Environment.GetCommandLineArgs());
@@ -321,8 +300,6 @@ namespace MediaBrowser.ServerApplication
}
}
- private static readonly TaskCompletionSource ApplicationTaskCompletionSource = new TaskCompletionSource();
-
///
/// Runs the application.
///
@@ -394,9 +371,6 @@ namespace MediaBrowser.ServerApplication
HideSplashScreen();
ShowTrayIcon();
-
- task = ApplicationTaskCompletionSource.Task;
- Task.WaitAll(task);
}
}
@@ -487,7 +461,6 @@ namespace MediaBrowser.ServerApplication
/// The instance containing the event data.
static void service_Disposed(object sender, EventArgs e)
{
- ApplicationTaskCompletionSource.SetResult(true);
OnServiceShutdown();
}
@@ -706,14 +679,10 @@ namespace MediaBrowser.ServerApplication
_serverNotifyIcon = null;
}
- //_logger.Info("Calling Application.Exit");
+ _logger.Info("Calling Application.Exit");
//Application.Exit();
-
- _logger.Info("Calling Environment.Exit");
+
Environment.Exit(0);
-
- _logger.Info("Calling ApplicationTaskCompletionSource.SetResult");
- ApplicationTaskCompletionSource.SetResult(true);
}
private static void ShutdownWindowsService()
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index 1c82a3c8d9..19f4921d3b 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -130,12 +130,6 @@
Component
-
- Form
-
-
- MainForm.cs
-
@@ -167,9 +161,6 @@
-
- MainForm.cs
-
ResXFileCodeGenerator
Resources.Designer.cs
@@ -197,7 +188,7 @@
PreserveNewest
-
+
PreserveNewest
diff --git a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs
index c421dd9ebd..cc8656f23d 100644
--- a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs
+++ b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs
@@ -45,7 +45,6 @@ namespace MediaBrowser.ServerApplication
components = new System.ComponentModel.Container();
- var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
contextMenuStrip1 = new ContextMenuStrip(components);
notifyIcon1 = new NotifyIcon(components);
@@ -62,7 +61,7 @@ namespace MediaBrowser.ServerApplication
// notifyIcon1
//
notifyIcon1.ContextMenuStrip = contextMenuStrip1;
- notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ notifyIcon1.Icon = new System.Drawing.Icon(GetType().Assembly.GetManifestResourceStream(GetType().Namespace + ".Icon.ico"));
notifyIcon1.Text = "Emby";
notifyIcon1.Visible = true;
//
diff --git a/Mono.Nat/NatUtility.cs b/Mono.Nat/NatUtility.cs
index bcbe5d8d0e..983e868336 100644
--- a/Mono.Nat/NatUtility.cs
+++ b/Mono.Nat/NatUtility.cs
@@ -41,26 +41,25 @@ using MediaBrowser.Model.Logging;
namespace Mono.Nat
{
- public static class NatUtility
- {
- private static ManualResetEvent searching;
- public static event EventHandler DeviceFound;
- public static event EventHandler DeviceLost;
-
- private static List controllers;
- private static bool verbose;
+ public static class NatUtility
+ {
+ public static event EventHandler DeviceFound;
+ public static event EventHandler DeviceLost;
+
+ private static List controllers;
+ private static bool verbose;
public static List EnabledProtocols { get; set; }
- public static ILogger Logger { get; set; }
+ public static ILogger Logger { get; set; }
public static IHttpClient HttpClient { get; set; }
public static bool Verbose
- {
- get { return verbose; }
- set { verbose = value; }
- }
-
+ {
+ get { return verbose; }
+ set { verbose = value; }
+ }
+
static NatUtility()
{
EnabledProtocols = new List
@@ -68,8 +67,6 @@ namespace Mono.Nat
NatProtocol.Pmp
};
- searching = new ManualResetEvent(false);
-
controllers = new List();
controllers.Add(PmpSearcher.Instance);
@@ -86,23 +83,19 @@ namespace Mono.Nat
DeviceLost(sender, args);
};
});
-
- Task.Factory.StartNew(SearchAndListen, TaskCreationOptions.LongRunning);
}
- internal static void Log(string format, params object[] args)
- {
- var logger = Logger;
- if (logger != null)
- logger.Debug(format, args);
- }
-
- private static async Task SearchAndListen()
+ internal static void Log(string format, params object[] args)
{
- while (true)
- {
- searching.WaitOne();
+ var logger = Logger;
+ if (logger != null)
+ logger.Debug(format, args);
+ }
+ private static async Task SearchAndListen(CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
try
{
var enabledProtocols = EnabledProtocols.ToList();
@@ -123,67 +116,99 @@ namespace Mono.Nat
}
catch (Exception e)
{
-
+
}
await Task.Delay(100).ConfigureAwait(false);
}
- }
+ }
- static async Task Receive (ISearcher searcher, List clients)
- {
- foreach (UdpClient client in clients)
- {
- if (client.Available > 0)
- {
- IPAddress localAddress = ((IPEndPoint)client.Client.LocalEndPoint).Address;
- var result = await client.ReceiveAsync().ConfigureAwait(false);
- var data = result.Buffer;
- var received = result.RemoteEndPoint;
- searcher.Handle(localAddress, data, received);
- }
+ static async Task Receive(ISearcher searcher, List clients)
+ {
+ foreach (UdpClient client in clients)
+ {
+ if (client.Available > 0)
+ {
+ IPAddress localAddress = ((IPEndPoint)client.Client.LocalEndPoint).Address;
+ var result = await client.ReceiveAsync().ConfigureAwait(false);
+ var data = result.Buffer;
+ var received = result.RemoteEndPoint;
+ searcher.Handle(localAddress, data, received);
+ }
}
}
-
- public static void StartDiscovery ()
- {
- searching.Set();
- }
- public static void StopDiscovery ()
- {
- searching.Reset();
- }
-
- //checks if an IP address is a private address space as defined by RFC 1918
- public static bool IsPrivateAddressSpace (IPAddress address)
- {
- byte[] ba = address.GetAddressBytes ();
+ private static CancellationTokenSource _currentCancellationTokenSource;
+ private static object _runSyncLock = new object();
+ public static void StartDiscovery()
+ {
+ lock (_runSyncLock)
+ {
+ if (_currentCancellationTokenSource == null)
+ {
+ return;
+ }
- switch ((int)ba[0]) {
- case 10:
- return true; //10.x.x.x
- case 172:
- return ((int)ba[1] & 16) != 0; //172.16-31.x.x
- case 192:
- return (int)ba[1] == 168; //192.168.x.x
- default:
- return false;
- }
- }
+ var tokenSource = new CancellationTokenSource();
- public static void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint, NatProtocol protocol)
- {
- switch (protocol)
- {
+ _currentCancellationTokenSource = tokenSource;
+ //Task.Factory.StartNew(() => SearchAndListen(tokenSource.Token), tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+ }
+ }
+
+ public static void StopDiscovery()
+ {
+ lock (_runSyncLock)
+ {
+ var tokenSource = _currentCancellationTokenSource;
+
+ if (tokenSource != null)
+ {
+ try
+ {
+ tokenSource.Cancel();
+ tokenSource.Dispose();
+ }
+ catch
+ {
+
+ }
+
+ _currentCancellationTokenSource = null;
+ }
+ }
+ }
+
+ //checks if an IP address is a private address space as defined by RFC 1918
+ public static bool IsPrivateAddressSpace(IPAddress address)
+ {
+ byte[] ba = address.GetAddressBytes();
+
+ switch ((int)ba[0])
+ {
+ case 10:
+ return true; //10.x.x.x
+ case 172:
+ return ((int)ba[1] & 16) != 0; //172.16-31.x.x
+ case 192:
+ return (int)ba[1] == 168; //192.168.x.x
+ default:
+ return false;
+ }
+ }
+
+ public static void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint, NatProtocol protocol)
+ {
+ switch (protocol)
+ {
case NatProtocol.Upnp:
- //UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
- break;
+ //UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
+ break;
case NatProtocol.Pmp:
- PmpSearcher.Instance.Handle(localAddress, response, endpoint);
- break;
- default:
- throw new ArgumentException("Unexpected protocol: " + protocol);
- }
+ PmpSearcher.Instance.Handle(localAddress, response, endpoint);
+ break;
+ default:
+ throw new ArgumentException("Unexpected protocol: " + protocol);
+ }
}
public static void Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint, NatProtocol protocol)
diff --git a/SharedVersion.cs b/SharedVersion.cs
index ec801ba7fe..6aaf3af830 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,3 +1,3 @@
using System.Reflection;
-[assembly: AssemblyVersion("3.2.20.11")]
+[assembly: AssemblyVersion("3.2.20.12")]