From 15792d20b0e4947a208b80fb66b9f4fd77d1595e Mon Sep 17 00:00:00 2001 From: Ian Houghton Date: Fri, 10 Mar 2017 12:35:45 +0000 Subject: [PATCH 01/85] Added new LogActivityAsync, GetActivityLogsList, GetHeartRate methods --- Fitbit.Portable/Fitbit.Portable.csproj | 1 + Fitbit.Portable/FitbitClient.cs | 180 ++++++++++++++++++ Fitbit.Portable/IFitbitClient.cs | 15 +- Fitbit.Portable/Models/ActivityList.cs | 116 +++++++++++ .../Models/HeartActivitiesIntraday.cs | 118 +----------- .../Models/HeartActivitiesTimeSeries.cs | 23 ++- Fitbit.Portable/Models/HeartRateZone.cs | 13 +- 7 files changed, 352 insertions(+), 114 deletions(-) create mode 100644 Fitbit.Portable/Models/ActivityList.cs diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index 93d7e140..d0c33bc5 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -44,6 +44,7 @@ + diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index a5cba0d6..2732e713 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Fitbit.Api.Portable.OAuth2; using System.Net.Http.Headers; +using Fitbit.Api.Portable.Models; using Fitbit.Models; namespace Fitbit.Api.Portable @@ -762,6 +763,185 @@ public async Task DeleteSubscriptionAsync(APICollectionType collection, string u } } + /// + /// Logs the specified Activity item for the current logged in user - https://dev.fitbit.com/docs/activity/#activity-logging + /// + /// + /// ActivityLog + public async Task LogActivityAsync(ActivityLog model) + { + var url = "/1/user/-/activities.json"; + string apiCall = FitbitClientHelperExtensions.ToFullUrl(url); + + var items = new Dictionary + { + {"activityId", model.ActivityId.ToString()}, + {"manualCalories", model.Calories.ToString()}, + {"startTime", model.StartTime}, + {"durationMillis", model.Duration.ToString()}, + {"date", DateTime.Now.ToFitbitFormat()}, + {"distance", model.Distance.ToString()} + }; + + apiCall = $"{apiCall}?{string.Join("&", items.Select(x => $"{x.Key}={x.Value}"))}"; + + HttpResponseMessage response = await HttpClient.PostAsync(apiCall, new StringContent(string.Empty)); + await HandleResponse(response); + var responseBody = await response.Content.ReadAsStringAsync(); + return (new JsonDotNetSerializer() { RootProperty = "activityLog" }).Deserialize(responseBody); + } + + /// + /// The Get Activity Logs List endpoint retrieves a list of a user's activity log entries before or after a given day with offset and limit using units in the unit system which corresponds to the Accept-Language header provided. - https://dev.fitbit.com/docs/activity/#get-activity-logs-list + /// + /// The date in the format yyyy-MM-ddTHH:mm:ss. Only yyyy-MM-dd is required. Either beforeDate or afterDate must be specified. Set sort to desc when using beforeDate. + /// The date in the format yyyy-MM-ddTHH:mm:ss. Only yyyy-MM-dd is required. Either beforeDate or afterDate must be specified. Set sort to asc when using afterDate. + /// The max of the number of entries returned (maximum: 20) + /// encoded user id, can be null for current logged in user + /// ActivityLog + public async Task> GetActivityLogsList(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) + { + var apiCall = string.Empty; + limit = limit > 20 ? 20 : limit; + const int offset = 0; + var sort = string.Empty; + var dateString = string.Empty; + var date = string.Empty; + + if (beforeDate != null && afterDate != null) + { + throw new ArgumentException("Please only specify a beforeDate or afterDate, not both: https://dev.fitbit.com/docs/activity/#get-activity-logs-list"); + } + + if (beforeDate != null) + { + dateString = "beforeDate"; + date = beforeDate.Value.ToString("yyyy-MM-ddTHH:mm:ss"); + sort = "desc"; + } + if (afterDate != null) + { + dateString = "afterDate"; + date = afterDate.Value.ToString("yyyy-MM-ddTHH:mm:ss"); + sort = "asc"; + } + + apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/list.json?{1}={2}&sort={3}&limit={4}&offset={5}", encodedUserId, dateString, date, sort, limit, offset); + + HttpResponseMessage response = await HttpClient.GetAsync(apiCall); + await HandleResponse(response); + var responseBody = await response.Content.ReadAsStringAsync(); + return (new JsonDotNetSerializer() { RootProperty = "activities" }).Deserialize>(responseBody); + } + + /// + /// The Get Heart Rate Time Series endpoint returns time series data in the specified range for a given resource in the format requested using units in the unit systems that corresponds to the Accept-Language header provided. - https://dev.fitbit.com/docs/heart-rate/#get-heart-rate-time-series + /// + /// The end date of the period specified in the format yyyy-MM-dd or today. + /// The range for which data will be returned. Options are 1d, 7d, 30d, 1w, 1m. + /// encoded user id, can be null for current logged in user + /// List of HeartActivitiesTimeSeries + public async Task> GetHeartRateTimeSeries(string date, string period, string encodedUserId = default(string)) + { + string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/heart/date/{1}/{2}.json", encodedUserId, date, period); + + HttpResponseMessage response = await HttpClient.GetAsync(apiCall); + await HandleResponse(response); + var responseBody = await response.Content.ReadAsStringAsync(); + return (new JsonDotNetSerializer() { RootProperty = "activities-heart" }).Deserialize>(responseBody); + } + + /// + /// The Get Heart Rate Time Series endpoint returns time series data in the specified range for a given resource in the format requested using units in the unit systems that corresponds to the Accept-Language header provided. - https://dev.fitbit.com/docs/heart-rate/#get-heart-rate-time-series + /// + /// The range start date, in the format yyyy-MM-dd or today. + /// The end date of the range. + /// encoded user id, can be null for current logged in user + /// List of HeartActivitiesTimeSeries + public async Task> GetHeartRateTimeSeries(string baseDate, DateTime endDate, string encodedUserId = default(string)) + { + string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/heart/date/{1}/{2}.json", encodedUserId, baseDate, endDate.ToFitbitFormat()); + + HttpResponseMessage response = await HttpClient.GetAsync(apiCall); + await HandleResponse(response); + var responseBody = await response.Content.ReadAsStringAsync(); + return (new JsonDotNetSerializer() { RootProperty = "activities-heart" }).Deserialize>(responseBody); + } + + /// + /// The Get Heart Rate Intraday Time Series endpoint returns the intraday time series for a given resource in the format requested. - https://dev.fitbit.com/docs/heart-rate/#get-heart-rate-intraday-time-series + /// + /// The date, in the format yyyy-MM-dd or today. + /// The end date of the range. + /// Number of data points to include. Either 1sec or 1min. + /// encoded user id, can be null for current logged in user + /// List of HeartActivitiesIntraday + public async Task GetHeartRateIntradayTimeSeries(string date, DateTime endDate, string detailLevel, string encodedUserId = default(string)) + { + string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/heart/date/{1}/{2}/{3}.json", encodedUserId, date, endDate.ToFitbitFormat(), detailLevel); + + HttpResponseMessage response = await HttpClient.GetAsync(apiCall); + await HandleResponse(response); + var responseBody = await response.Content.ReadAsStringAsync(); + return (new JsonDotNetSerializer() { RootProperty = "activities-heart-intraday" }).Deserialize(responseBody); + } + + /// + /// The Get Heart Rate Intraday Time Series endpoint returns the intraday time series for a given resource in the format requested. - https://dev.fitbit.com/docs/heart-rate/#get-heart-rate-intraday-time-series + /// + /// The date, in the format yyyy-MM-dd or today. + /// The end date of the range. + /// Number of data points to include. Either 1sec or 1min. + /// The start of the period, in the format HH:mm. + /// The end of the period, in the format HH:mm. + /// encoded user id, can be null for current logged in user + /// List of HeartActivitiesIntraday + public async Task GetHeartRateIntradayTimeSeries(string date, DateTime endDate, string detailLevel, TimeSpan startTime, TimeSpan endTime, string encodedUserId = default(string)) + { + string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/heart/date/{1}/{2}/{3}/time/{4}/{5}.json", encodedUserId, date, endDate.ToFitbitFormat(), detailLevel, startTime.ToString("HH:mm"), endTime.ToString("HH:mm")); + + HttpResponseMessage response = await HttpClient.GetAsync(apiCall); + await HandleResponse(response); + var responseBody = await response.Content.ReadAsStringAsync(); + return (new JsonDotNetSerializer() { RootProperty = "activities-heart-intraday" }).Deserialize(responseBody); + } + + /// + /// The Get Heart Rate Intraday Time Series endpoint returns the intraday time series for a given resource in the format requested. - https://dev.fitbit.com/docs/heart-rate/#get-heart-rate-intraday-time-series + /// + /// The date, in the format yyyy-MM-dd or today. + /// Number of data points to include. Either 1sec or 1min. + /// encoded user id, can be null for current logged in user + /// List of HeartActivitiesIntraday + public async Task GetHeartRateIntradayTimeSeries(string date, string detailLevel, string encodedUserId = default(string)) + { + string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/heart/date/{1}/1d/{2}.json", encodedUserId, date, detailLevel); + + HttpResponseMessage response = await HttpClient.GetAsync(apiCall); + await HandleResponse(response); + var responseBody = await response.Content.ReadAsStringAsync(); + return (new JsonDotNetSerializer() { RootProperty = "activities-heart-intraday" }).Deserialize(responseBody); + } + + /// + /// The Get Heart Rate Intraday Time Series endpoint returns the intraday time series for a given resource in the format requested. - https://dev.fitbit.com/docs/heart-rate/#get-heart-rate-intraday-time-series + /// + /// The date, in the format yyyy-MM-dd or today. + /// Number of data points to include. Either 1sec or 1min. + /// The start of the period, in the format HH:mm. + /// The end of the period, in the format HH:mm. + /// encoded user id, can be null for current logged in user + /// List of HeartActivitiesIntraday + public async Task GetHeartRateIntradayTimeSeries(string date, string detailLevel, TimeSpan startTime, TimeSpan endTime, string encodedUserId = default(string)) + { + string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/heart/date/{1}/1d/{2}/time/{3}/{4}.json", encodedUserId, date, detailLevel, startTime.ToString("HH:mm"), endTime.ToString("HH:mm")); + + HttpResponseMessage response = await HttpClient.GetAsync(apiCall); + await HandleResponse(response); + var responseBody = await response.Content.ReadAsStringAsync(); + return (new JsonDotNetSerializer() { RootProperty = "activities-heart-intraday" }).Deserialize(responseBody); + } + private string FormatKey(APICollectionType apiCollectionType, string format) { string strValue = apiCollectionType == APICollectionType.user ? string.Empty : apiCollectionType.ToString(); diff --git a/Fitbit.Portable/IFitbitClient.cs b/Fitbit.Portable/IFitbitClient.cs index e25593f6..62fba735 100644 --- a/Fitbit.Portable/IFitbitClient.cs +++ b/Fitbit.Portable/IFitbitClient.cs @@ -30,9 +30,22 @@ public interface IFitbitClient Task GetWaterAsync(DateTime date); Task LogWaterAsync(DateTime date, WaterLog log); Task DeleteWaterLogAsync(long logId); - Task> GetSubscriptionsAsync(); Task AddSubscriptionAsync(APICollectionType apiCollectionType, string uniqueSubscriptionId, string subscriberId = default(string)); Task DeleteSubscriptionAsync(APICollectionType collection, string uniqueSubscriptionId, string subscriberId = null); + Task LogActivityAsync(ActivityLog model); + Task> GetHeartRateTimeSeries(string date, string period, + string encodedUserId = default(string)); + Task> GetHeartRateTimeSeries(string baseDate, DateTime endDate, + string encodedUserId = default(string)); + Task GetHeartRateIntradayTimeSeries(string date, DateTime endDate, string detailLevel, + string encodedUserId = default(string)); + Task GetHeartRateIntradayTimeSeries(string date, DateTime endDate, string detailLevel, + TimeSpan startTime, TimeSpan endTime, string encodedUserId = default(string)); + Task GetHeartRateIntradayTimeSeries(string date, string detailLevel, + string encodedUserId = default(string)); + Task GetHeartRateIntradayTimeSeries(string date, string detailLevel, TimeSpan startTime, + TimeSpan endTime, string encodedUserId = default(string)); + Task> GetActivityLogsList(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)); } } \ No newline at end of file diff --git a/Fitbit.Portable/Models/ActivityList.cs b/Fitbit.Portable/Models/ActivityList.cs new file mode 100644 index 00000000..6f3b6b1c --- /dev/null +++ b/Fitbit.Portable/Models/ActivityList.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Fitbit.Models +{ + public class ActivityList + { + [JsonProperty(PropertyName = "activeDuration")] + public double ActiveDuration { get; set; } + + [JsonProperty(PropertyName = "activityLevel")] + public List ActivityLevel { get; set; } + + [JsonProperty(PropertyName = "activityName")] + public string ActivityName { get; set; } + + [JsonProperty(PropertyName = "activityTypeId")] + public double ActivityTypeId { get; set; } + + //public int averageHeartRate { get; set; } + + [JsonProperty(PropertyName = "calories")] + public double Calories { get; set; } + + //public string caloriesLink { get; set; } + + [JsonProperty(PropertyName = "distance")] + public double Distance { get; set; } + + [JsonProperty(PropertyName = "distanceUnit")] + public string DistanceUnit { get; set; } + + [JsonProperty(PropertyName = "duration")] + public double Duration { get; set; } + + //public string heartRateLink { get; set; } + + [JsonProperty(PropertyName = "lastModified")] + public DateTime LastModified { get; set; } + + [JsonProperty(PropertyName = "logId")] + public double LogId { get; set; } + + [JsonProperty(PropertyName = "logType")] + public string LogType { get; set; } + + [JsonProperty(PropertyName = "manualValuesSpecified")] + public ManualValuesSpecified ManualValuesSpecified { get; set; } + + [JsonProperty(PropertyName = "originalDuration")] + public double OriginalDuration { get; set; } + + [JsonProperty(PropertyName = "originalStartTime")] + public DateTime OriginalStartTime { get; set; } + + [JsonProperty(PropertyName = "source")] + public Source Source { get; set; } + + [JsonProperty(PropertyName = "speed")] + public double Speed { get; set; } + + [JsonProperty(PropertyName = "startTime")] + public DateTime StartTime { get; set; } + + //public int steps { get; set; } + //public List heartRateZones { get; set; } + + [JsonProperty(PropertyName = "tcxLink")] + public string TcxLink { get; set; } + } + + public class ActivityLevel + { + [JsonProperty(PropertyName = "minutes")] + public double Minutes { get; set; } + + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + } + + //public class HeartRateZone + //{ + // public int max { get; set; } + // public int min { get; set; } + // public int minutes { get; set; } + // public string name { get; set; } + //} + + public class ManualValuesSpecified + { + [JsonProperty(PropertyName = "calories")] + public bool Calories { get; set; } + + [JsonProperty(PropertyName = "distance")] + public bool Distance { get; set; } + + [JsonProperty(PropertyName = "steps")] + public bool Steps { get; set; } + } + + public class Source + { + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } + + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + + [JsonProperty(PropertyName = "type")] + public string Type { get; set; } + + [JsonProperty(PropertyName = "url")] + public string Url { get; set; } + } +} diff --git a/Fitbit.Portable/Models/HeartActivitiesIntraday.cs b/Fitbit.Portable/Models/HeartActivitiesIntraday.cs index 3352ffac..e3e847bb 100644 --- a/Fitbit.Portable/Models/HeartActivitiesIntraday.cs +++ b/Fitbit.Portable/Models/HeartActivitiesIntraday.cs @@ -1,129 +1,27 @@ using System; using System.Collections.Generic; -using System.Linq; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace Fitbit.Models { - //[JsonConverter(typeof(HeartActivitiesIntradayConverter))] public class HeartActivitiesIntraday { + [JsonProperty(PropertyName = "dataset")] public List Dataset { get; set; } + [JsonProperty(PropertyName = "datasetInterval")] public int DatasetInterval { get; set; } + + [JsonProperty(PropertyName = "datasetType")] public string DatasetType { get; set; } } - //[JsonConverter(typeof(DatasetIntervalConverter))] public class DatasetInterval { + [JsonProperty(PropertyName = "time")] public DateTime Time { get; set; } - public int Value { get; set;} - } - - public class HeartActivitiesIntradayConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var heartActivitiesIntraday = value as HeartActivitiesIntraday; - - //{ - writer.WriteStartObject(); - - // "DatasetInterval" : "1" - writer.WritePropertyName("DatasetInterval"); - writer.WriteValue(heartActivitiesIntraday.DatasetInterval); - - // "DatasetType" : "SecondsHeartrate" - writer.WritePropertyName("DatasetType"); - writer.WriteValue(heartActivitiesIntraday.DatasetType); - - writer.WritePropertyName("Dataset"); - writer.WriteStartArray(); - foreach (var datasetInverval in heartActivitiesIntraday.Dataset) - { - // "Time" : "2008-09-22T14:01:54.9571247Z" - writer.WritePropertyName("Time"); - writer.WriteValue(datasetInverval.Time.ToString("o")); - - // "Value": 1 - writer.WritePropertyName("Value"); - writer.WriteValue(datasetInverval.Value); - - } - writer.WriteEndArray(); - - //} - writer.WriteEndObject(); - - } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - JObject jsonObject = JObject.Load(reader); - var properties = jsonObject.Properties().ToList(); - - HeartActivitiesIntraday result = new HeartActivitiesIntraday(); - result.DatasetInterval = Convert.ToInt32(jsonObject["DatasetInterval"]); - result.DatasetType = jsonObject["DatasetType"].ToString(); - result.Dataset = new List(); - - foreach(JToken item in jsonObject["Dataset"].Children()) - { - result.Dataset.Add(new DatasetInterval() - { - Time = DateTime.Parse(item["Time"].ToString()), - Value = Convert.ToInt32(item["Value"]) - }); - }; - - return result; - } - - public override bool CanConvert(Type objectType) - { - return typeof(HeartActivitiesIntraday).IsAssignableFrom(objectType); - } + [JsonProperty(PropertyName = "value")] + public int Value { get; set;} } - - /* - public class DatasetIntervalConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var datasetInverval = value as DatasetInterval; - - //{ - writer.WriteStartObject(); - - // "Time" : "2008-09-22T14:01:54.9571247Z" - writer.WritePropertyName("Time"); - writer.WriteValue(datasetInverval.Time.ToString("o")); - - // "Value": 1 - writer.WritePropertyName("Value"); - writer.WriteValue(datasetInverval.Value); - - //} - writer.WriteEndObject(); - - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - JObject jsonObject = JObject.Load(reader); - var properties = jsonObject.Properties().ToList(); - return new DatasetInterval - { - Time = DateTime.Parse(jsonObject["Time"].ToString()), - Value = Convert.ToInt32(jsonObject["Value"]) - }; - } - - public override bool CanConvert(Type objectType) - { - return typeof(DatasetInterval).IsAssignableFrom(objectType); - } - } */ -} +} \ No newline at end of file diff --git a/Fitbit.Portable/Models/HeartActivitiesTimeSeries.cs b/Fitbit.Portable/Models/HeartActivitiesTimeSeries.cs index 143ff27f..2ad9dbc0 100644 --- a/Fitbit.Portable/Models/HeartActivitiesTimeSeries.cs +++ b/Fitbit.Portable/Models/HeartActivitiesTimeSeries.cs @@ -1,9 +1,28 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using Newtonsoft.Json; namespace Fitbit.Models { public class HeartActivitiesTimeSeries { - public List HeartActivities { get; set; } + [JsonProperty(PropertyName = "dateTime")] + public DateTime DateTime { get; set; } + + [JsonProperty(PropertyName = "value")] + public Value Value { get; set; } } + + public class Value + { + [JsonProperty(PropertyName = "customHeartRateZones")] + public List CustomHeartRateZones { get; set; } + + [JsonProperty(PropertyName = "heartRateZones")] + public List HeartRateZones { get; set; } + + [JsonProperty(PropertyName = "restingHeartRate")] + public int RestingHeartRate { get; set; } + } + } diff --git a/Fitbit.Portable/Models/HeartRateZone.cs b/Fitbit.Portable/Models/HeartRateZone.cs index ebf306dc..0c7e23cd 100644 --- a/Fitbit.Portable/Models/HeartRateZone.cs +++ b/Fitbit.Portable/Models/HeartRateZone.cs @@ -1,11 +1,22 @@ -namespace Fitbit.Models +using Newtonsoft.Json; + +namespace Fitbit.Models { public class HeartRateZone { + [JsonProperty(PropertyName = "caloriesOut")] public float CaloriesOut { get; set; } + + [JsonProperty(PropertyName = "max")] public int Max { get; set; } + + [JsonProperty(PropertyName = "min")] public int Min { get; set; } + + [JsonProperty(PropertyName = "minutes")] public int Minutes { get; set; } + + [JsonProperty(PropertyName = "name")] public string Name { get; set; } } } From c090a6cc2fa2cf9503192cd2e45314cdf1577791 Mon Sep 17 00:00:00 2001 From: Ian Houghton Date: Fri, 10 Mar 2017 15:59:05 +0000 Subject: [PATCH 02/85] Removed url string --- Fitbit.Portable/FitbitClient.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 2732e713..061ade5a 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -770,8 +770,7 @@ public async Task DeleteSubscriptionAsync(APICollectionType collection, string u /// ActivityLog public async Task LogActivityAsync(ActivityLog model) { - var url = "/1/user/-/activities.json"; - string apiCall = FitbitClientHelperExtensions.ToFullUrl(url); + string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/-/activities.json"); var items = new Dictionary { From 2be4b3df564ea0d3881cd98816a9684269a28917 Mon Sep 17 00:00:00 2001 From: Ian Houghton Date: Wed, 22 Mar 2017 16:48:34 +0000 Subject: [PATCH 03/85] Update to Newtownsoft --- Fitbit.Portable/Fitbit.Portable.csproj | 4 ++-- Fitbit.Portable/FitbitClient.cs | 9 +++++++-- Fitbit.Portable/Models/ActivityLog.cs | 1 + Fitbit.Portable/packages.config | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index d0c33bc5..95b41d5f 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -134,8 +134,8 @@ ..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\portable-net40+sl4+win8+wp71+wpa81\Microsoft.Threading.Tasks.Extensions.dll - - ..\Fitbit\packages\Newtonsoft.Json.8.0.2\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll + + ..\Fitbit\packages\Newtonsoft.Json.6.0.8\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll True diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 061ade5a..fc363c5f 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -774,14 +774,19 @@ public async Task LogActivityAsync(ActivityLog model) var items = new Dictionary { - {"activityId", model.ActivityId.ToString()}, + {"activityName", Uri.EscapeDataString(model.Name)}, {"manualCalories", model.Calories.ToString()}, {"startTime", model.StartTime}, {"durationMillis", model.Duration.ToString()}, - {"date", DateTime.Now.ToFitbitFormat()}, + {"date", model.Date}, {"distance", model.Distance.ToString()} }; + if (!string.IsNullOrEmpty(model.ActivityId.ToString()) && model.ActivityId != 0) + { + items.Add("activityId", model.ActivityId.ToString()); + } + apiCall = $"{apiCall}?{string.Join("&", items.Select(x => $"{x.Key}={x.Value}"))}"; HttpResponseMessage response = await HttpClient.PostAsync(apiCall, new StringContent(string.Empty)); diff --git a/Fitbit.Portable/Models/ActivityLog.cs b/Fitbit.Portable/Models/ActivityLog.cs index 15c0c137..94ac2a4a 100644 --- a/Fitbit.Portable/Models/ActivityLog.cs +++ b/Fitbit.Portable/Models/ActivityLog.cs @@ -27,6 +27,7 @@ public class ActivityLog public bool IsFavorite { get; set; } public long LogId { get; set; } public string Name { get; set; } + public string Date { get; set; } public string StartTime { get; set; } public int Steps { get; set; } } diff --git a/Fitbit.Portable/packages.config b/Fitbit.Portable/packages.config index 9887f119..4a217917 100644 --- a/Fitbit.Portable/packages.config +++ b/Fitbit.Portable/packages.config @@ -4,5 +4,5 @@ - + \ No newline at end of file From 5fcce94aaa291b6e81f330a879803a05382f7801 Mon Sep 17 00:00:00 2001 From: Ian Houghton Date: Wed, 28 Jun 2017 22:39:12 +0100 Subject: [PATCH 04/85] Start of adding some unit tests for new methods --- Fitbit.Portable.Tests/ActivityLogTests.cs | 70 +++ .../Fitbit.Portable.Tests.csproj | 5 + Fitbit.Portable.Tests/HeartRateTests.cs | 121 +++++ .../SampleData/GetActivityLogsList.json | 441 ++++++++++++++++++ .../GetHeartRateIntradayTimeSeries.json | 3 + .../SampleData/GetHeartRateTimeSeries.json | 3 + Fitbit.Portable/Fitbit.Portable.csproj | 4 +- Fitbit.Portable/packages.config | 2 +- 8 files changed, 646 insertions(+), 3 deletions(-) create mode 100644 Fitbit.Portable.Tests/ActivityLogTests.cs create mode 100644 Fitbit.Portable.Tests/HeartRateTests.cs create mode 100644 Fitbit.Portable.Tests/SampleData/GetActivityLogsList.json create mode 100644 Fitbit.Portable.Tests/SampleData/GetHeartRateIntradayTimeSeries.json create mode 100644 Fitbit.Portable.Tests/SampleData/GetHeartRateTimeSeries.json diff --git a/Fitbit.Portable.Tests/ActivityLogTests.cs b/Fitbit.Portable.Tests/ActivityLogTests.cs new file mode 100644 index 00000000..d73b69ef --- /dev/null +++ b/Fitbit.Portable.Tests/ActivityLogTests.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Fitbit.Api.Portable; +using Fitbit.Models; +using FluentAssertions; +using NUnit.Framework; + +namespace Fitbit.Portable.Tests +{ + [TestFixture] + public class ActivityLogTests + { + [Test] + [Category("Portable")] + public async void GetActivityLogsListAsync_Success() + { + string content = SampleDataHelper.GetContent("GetActivityLogsList.json"); + + var responseMessage = new Func(() => + { + return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(content) }; + }); + + var verification = new Action((message, token) => + { + Assert.AreEqual(HttpMethod.Get, message.Method); + Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/list.json?afterDate=2017-01-01T00:00:00&sort=asc&limit=20&offset=0", message.RequestUri.AbsoluteUri); + }); + + var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); + + var response = await fitbitClient.GetActivityLogsList(null, new DateTime(2017, 1, 1)); + //ValidateBloodPressureData(response); + } + + [Test] + [Category("Portable")] + public void GetActivityLogsListAsync_Errors() + { + var responseMessage = Helper.CreateErrorResponse(HttpStatusCode.BadRequest); + var verification = new Action((message, token) => + { + Assert.AreEqual(HttpMethod.Get, message.Method); + }); + + var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); + + Func>> result = () => fitbitClient.GetActivityLogsList(null, new DateTime(2017, 1, 1)); + + result.ShouldThrow().Which.ApiErrors.Count.Should().Be(1); + } + + [Test] + [Category("Portable")] + public void Can_Deserialize_ActivityLogsList() + { + string content = SampleDataHelper.GetContent("GetActivityLogsList.json"); + var deserializer = new JsonDotNetSerializer(); + + List stats = deserializer.Deserialize>(content); + + //ValidateActivity(stats); + } + } +} + diff --git a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj index abd353e7..f7c8136d 100644 --- a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj +++ b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj @@ -109,6 +109,7 @@ + @@ -124,6 +125,7 @@ + @@ -220,6 +222,9 @@ + + + diff --git a/Fitbit.Portable.Tests/HeartRateTests.cs b/Fitbit.Portable.Tests/HeartRateTests.cs new file mode 100644 index 00000000..0c85407d --- /dev/null +++ b/Fitbit.Portable.Tests/HeartRateTests.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Fitbit.Api.Portable; +using Fitbit.Models; +using FluentAssertions; +using NUnit.Framework; + +namespace Fitbit.Portable.Tests +{ + [TestFixture] + public class HeartRateTests + { + [Test] + [Category("Portable")] + public async void GetHeartRateTimeSeriesAsync_Success() + { + string content = SampleDataHelper.GetContent("GetHeartRateTimeSeries.json"); + + var responseMessage = new Func(() => + { + return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(content) }; + }); + + var verification = new Action((message, token) => + { + Assert.AreEqual(HttpMethod.Get, message.Method); + Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/heart/date/{1}/{2}.json", message.RequestUri.AbsoluteUri); + }); + + var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); + + var response = await fitbitClient.GetHeartRateTimeSeries("", ""); + //ValidateBloodPressureData(response); + } + + [Test] + [Category("Portable")] + public void GetHeartRateTimeSeriesAsync_Errors() + { + var responseMessage = Helper.CreateErrorResponse(HttpStatusCode.BadRequest); + var verification = new Action((message, token) => + { + Assert.AreEqual(HttpMethod.Get, message.Method); + }); + + var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); + + Func>> result = () => fitbitClient.GetHeartRateTimeSeries("", ""); + + result.ShouldThrow().Which.ApiErrors.Count.Should().Be(1); + } + + [Test] + [Category("Portable")] + public void Can_Deserialize_HeartRateTimeSeries() + { + string content = SampleDataHelper.GetContent("GetHeartRateTimeSeries.json"); + var deserializer = new JsonDotNetSerializer(); + + List stats = deserializer.Deserialize>(content); + + //ValidateActivity(stats); + } + + [Test] + [Category("Portable")] + public async void GetHeartRateIntradayTimeSeriesAsync_Success() + { + string content = SampleDataHelper.GetContent("GetHeartRateIntradayTimeSeries.json"); + + var responseMessage = new Func(() => + { + return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(content) }; + }); + + var verification = new Action((message, token) => + { + Assert.AreEqual(HttpMethod.Get, message.Method); + Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/heart/date/{1}/{2}/{3}.json", message.RequestUri.AbsoluteUri); + }); + + var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); + + var response = await fitbitClient.GetHeartRateTimeSeries("", ""); + //ValidateBloodPressureData(response); + } + + [Test] + [Category("Portable")] + public void GetHeartRateIntradayTimeSeriesAsync_Errors() + { + var responseMessage = Helper.CreateErrorResponse(HttpStatusCode.BadRequest); + var verification = new Action((message, token) => + { + Assert.AreEqual(HttpMethod.Get, message.Method); + }); + + var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); + + Func> result = () => fitbitClient.GetHeartRateIntradayTimeSeries("", ""); + + result.ShouldThrow().Which.ApiErrors.Count.Should().Be(1); + } + + [Test] + [Category("Portable")] + public void Can_Deserialize_HeartRateIntradayTimeSeries() + { + string content = SampleDataHelper.GetContent("GetHeartRateIntradayTimeSeries.json"); + var deserializer = new JsonDotNetSerializer(); + + HeartActivitiesIntraday stats = deserializer.Deserialize(content); + + //ValidateActivity(stats); + } + } +} diff --git a/Fitbit.Portable.Tests/SampleData/GetActivityLogsList.json b/Fitbit.Portable.Tests/SampleData/GetActivityLogsList.json new file mode 100644 index 00000000..cc40aed2 --- /dev/null +++ b/Fitbit.Portable.Tests/SampleData/GetActivityLogsList.json @@ -0,0 +1,441 @@ +{ + "activities": [ + { + "activeDuration": 1734000, + "activityLevel": [ + { + "minutes": 4, + "name": "sedentary" + }, + { + "minutes": 14, + "name": "lightly" + }, + { + "minutes": 4, + "name": "fairly" + }, + { + "minutes": 6, + "name": "very" + } + ], + "activityName": "FitStar: Personal Trainer", + "activityTypeId": 17589491, + "averageHeartRate": 94, + "calories": 136, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-03-29/2016-03-29/1min/time/8:45/9:13.json", + "distance": 1.071811, + "distanceUnit": "Kilometer", + "duration": 1734000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-03-29/2016-03-29/1sec/time/08:45:00/09:13:54.json", + "heartRateZones": [ + { + "max": 94, + "min": 30, + "minutes": 16, + "name": "Out of Range" + }, + { + "max": 131, + "min": 94, + "minutes": 9, + "name": "Fat Burn" + }, + { + "max": 159, + "min": 131, + "minutes": 1, + "name": "Cardio" + }, + { + "max": 220, + "min": 159, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2016-03-29T17:41:53.000Z", + "logId": 2067350363, + "logType": "fitstar", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "source": { + "id": "228T4Z", + "name": "FitStar", + "type": "app", + "url": "http://www.fitstar.com" + }, + "speed": 2.2252131487889275, + "startTime": "2016-03-29T08:45:00.000-07:00", + "steps": 1354 + }, + { + "activeDuration": 1001000, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 0, + "name": "lightly" + }, + { + "minutes": 17, + "name": "fairly" + }, + { + "minutes": 0, + "name": "very" + } + ], + "activityName": "Bike", + "activityTypeId": 90001, + "averageHeartRate": 93, + "calories": 77, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-03-28/2016-03-28/1min/time/19:05/19:22.json", + "distance": 4.1978, + "distanceUnit": "Kilometer", + "duration": 1001000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-03-28/2016-03-28/1sec/time/19:05:31/19:22:12.json", + "heartRateZones": [ + { + "max": 94, + "min": 30, + "minutes": 7, + "name": "Out of Range" + }, + { + "max": 131, + "min": 94, + "minutes": 10, + "name": "Fat Burn" + }, + { + "max": 159, + "min": 131, + "minutes": 0, + "name": "Cardio" + }, + { + "max": 220, + "min": 159, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2016-03-29T03:03:12.000Z", + "logId": 2068007929, + "logType": "manual", + "manualValuesSpecified": { + "calories": true, + "distance": true, + "steps": true + }, + "source": { + "id": "22997K", + "name": "Fitbit + Strava", + "type": "app", + "url": "https://strava.fitbit.com/" + }, + "speed": 15.096983016983017, + "startTime": "2016-03-28T19:05:31.000-07:00", + "steps": 0 + }, + { + "activeDuration": 1503000, + "activityLevel": [ + { + "minutes": 4, + "name": "sedentary" + }, + { + "minutes": 11, + "name": "lightly" + }, + { + "minutes": 3, + "name": "fairly" + }, + { + "minutes": 7, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 96, + "calories": 134, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-03-26/2016-03-26/1min/time/14:49/15:14.json", + "duration": 1503000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-03-26/2016-03-26/1sec/time/14:49:05/15:14:08.json", + "heartRateZones": [ + { + "max": 94, + "min": 30, + "minutes": 8, + "name": "Out of Range" + }, + { + "max": 131, + "min": 94, + "minutes": 17, + "name": "Fat Burn" + }, + { + "max": 159, + "min": 131, + "minutes": 0, + "name": "Cardio" + }, + { + "max": 220, + "min": 159, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2016-03-26T22:34:17.000Z", + "logId": 2047712815, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "startTime": "2016-03-26T14:49:05.000-07:00", + "steps": 1662 + }, + { + "activeDuration": 2766000, + "activityLevel": [ + { + "minutes": 5, + "name": "sedentary" + }, + { + "minutes": 6, + "name": "lightly" + }, + { + "minutes": 2, + "name": "fairly" + }, + { + "minutes": 33, + "name": "very" + } + ], + "activityName": "Workout", + "activityTypeId": 3000, + "averageHeartRate": 147, + "calories": 416, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-03-05/2016-03-05/1min/time/15:31/16:17.json", + "duration": 2766000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-03-05/2016-03-05/1sec/time/15:31:17/16:17:23.json", + "heartRateZones": [ + { + "max": 94, + "min": 30, + "minutes": 3, + "name": "Out of Range" + }, + { + "max": 131, + "min": 94, + "minutes": 8, + "name": "Fat Burn" + }, + { + "max": 159, + "min": 131, + "minutes": 4, + "name": "Cardio" + }, + { + "max": 220, + "min": 159, + "minutes": 30, + "name": "Peak" + } + ], + "lastModified": "2016-03-06T00:20:21.000Z", + "logId": 1846159807, + "logType": "tracker", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "source": { + "id": "47086726", + "name": "Charge HR", + "type": "tracker", + "url": "https://www.fitbit.com/" + }, + "startTime": "2016-03-05T15:31:17.000-08:00", + "steps": 683, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/1846159807.json" + }, + { + "activeDuration": 784739, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 1, + "name": "lightly" + }, + { + "minutes": 0, + "name": "fairly" + }, + { + "minutes": 12, + "name": "very" + } + ], + "activityName": "Run", + "activityTypeId": 90009, + "averageHeartRate": 125, + "calories": 124, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-01-31/2016-01-31/1min/time/19:11/19:24.json", + "distance": 2.534752, + "distanceUnit": "Kilometer", + "duration": 784000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-01-31/2016-01-31/1sec/time/19:11:49/19:24:53.json", + "heartRateZones": [ + { + "max": 94, + "min": 30, + "minutes": 2, + "name": "Out of Range" + }, + { + "max": 131, + "min": 94, + "minutes": 1, + "name": "Fat Burn" + }, + { + "max": 159, + "min": 131, + "minutes": 10, + "name": "Cardio" + }, + { + "max": 220, + "min": 159, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2016-02-01T03:25:03.000Z", + "logId": 1546680089, + "logType": "mobile_run", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "pace": 309.30047594399764, + "source": { + "id": "2295XJ", + "name": "Fitbit for Windows Phone", + "type": "app", + "url": "https://www.fitbit.com/" + }, + "speed": 11.628206575689497, + "startTime": "2016-01-31T19:11:49.000-08:00", + "steps": 1827, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/1546680089.json" + }, + { + "activeDuration": 6226000, + "activityLevel": [ + { + "minutes": 6, + "name": "sedentary" + }, + { + "minutes": 37, + "name": "lightly" + }, + { + "minutes": 28, + "name": "fairly" + }, + { + "minutes": 32, + "name": "very" + } + ], + "activityName": "Hike", + "activityTypeId": 90012, + "averageHeartRate": 102, + "calories": 582, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2015-05-25/2015-05-25/1min/time/14:08/16:09.json", + "distance": 5.600688, + "distanceUnit": "Kilometer", + "duration": 7272000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2015-05-25/2015-05-25/1sec/time/14:08:12/16:09:24.json", + "heartRateZones": [ + { + "max": 94, + "min": 30, + "minutes": 24, + "name": "Out of Range" + }, + { + "max": 132, + "min": 94, + "minutes": 79, + "name": "Fat Burn" + }, + { + "max": 160, + "min": 132, + "minutes": 0, + "name": "Cardio" + }, + { + "max": 220, + "min": 160, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2015-07-15T23:45:47.000Z", + "logId": 228167717, + "logType": "tracker", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "pace": 1111.6491402484837, + "source": { + "id": "18834976", + "name": "Surge", + "type": "tracker", + "url": "https://www.fitbit.com/" + }, + "speed": 3.2384318663668488, + "startTime": "2015-05-25T14:08:12.000-07:00", + "steps": 7295, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/228167717.json" + } + ], + "pagination": { + "beforeDate": "2016-03-30", + "limit": 10, + "next": "https://api.fitbit.com/1/user/-/activities/list.json?limit=10&sort=desc&beforeDate=2015-07-15T23:45:47.000Z", + "sort": "desc" + } +} \ No newline at end of file diff --git a/Fitbit.Portable.Tests/SampleData/GetHeartRateIntradayTimeSeries.json b/Fitbit.Portable.Tests/SampleData/GetHeartRateIntradayTimeSeries.json new file mode 100644 index 00000000..d177980a --- /dev/null +++ b/Fitbit.Portable.Tests/SampleData/GetHeartRateIntradayTimeSeries.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/Fitbit.Portable.Tests/SampleData/GetHeartRateTimeSeries.json b/Fitbit.Portable.Tests/SampleData/GetHeartRateTimeSeries.json new file mode 100644 index 00000000..d177980a --- /dev/null +++ b/Fitbit.Portable.Tests/SampleData/GetHeartRateTimeSeries.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index 95b41d5f..d0c33bc5 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -134,8 +134,8 @@ ..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\portable-net40+sl4+win8+wp71+wpa81\Microsoft.Threading.Tasks.Extensions.dll - - ..\Fitbit\packages\Newtonsoft.Json.6.0.8\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll + + ..\Fitbit\packages\Newtonsoft.Json.8.0.2\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll True diff --git a/Fitbit.Portable/packages.config b/Fitbit.Portable/packages.config index 4a217917..9887f119 100644 --- a/Fitbit.Portable/packages.config +++ b/Fitbit.Portable/packages.config @@ -4,5 +4,5 @@ - + \ No newline at end of file From c0d332a918686982aa2cbbb7729788100cce4e51 Mon Sep 17 00:00:00 2001 From: Ian Houghton Date: Thu, 29 Jun 2017 22:19:11 +0100 Subject: [PATCH 05/85] Added unit tests for new methods --- Fitbit.Portable.Tests/ActivityLogTests.cs | 41 +- Fitbit.Portable.Tests/HeartRateTests.cs | 43 +- .../SampleData/GetActivityLogsList.json | 1376 ++++- .../GetHeartRateIntradayTimeSeries.json | 4676 ++++++++++++++++- .../SampleData/GetHeartRateTimeSeries.json | 4676 ++++++++++++++++- 5 files changed, 10612 insertions(+), 200 deletions(-) diff --git a/Fitbit.Portable.Tests/ActivityLogTests.cs b/Fitbit.Portable.Tests/ActivityLogTests.cs index d73b69ef..accb5975 100644 --- a/Fitbit.Portable.Tests/ActivityLogTests.cs +++ b/Fitbit.Portable.Tests/ActivityLogTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.Http; using System.Threading; @@ -34,7 +35,7 @@ public async void GetActivityLogsListAsync_Success() var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); var response = await fitbitClient.GetActivityLogsList(null, new DateTime(2017, 1, 1)); - //ValidateBloodPressureData(response); + ValidateActivity(response); } [Test] @@ -59,11 +60,45 @@ public void GetActivityLogsListAsync_Errors() public void Can_Deserialize_ActivityLogsList() { string content = SampleDataHelper.GetContent("GetActivityLogsList.json"); - var deserializer = new JsonDotNetSerializer(); + var deserializer = new JsonDotNetSerializer {RootProperty = "activities"}; List stats = deserializer.Deserialize>(content); - //ValidateActivity(stats); + ValidateActivity(stats); + } + + private void ValidateActivity(List stats) + { + var stat = stats.First(); + + stat.ActiveDuration.Should().Be(2764000); + + stat.ActivityLevel.First().Minutes.Should().Be(0); + stat.ActivityLevel.First().Name.Should().Be("sedentary"); + + stat.ActivityName.Should().Be("Walk"); + stat.ActivityTypeId.Should().Be(90013); + //stat.AverageHeartRate + + stat.Calories.Should().Be(375); + //stat.CaloriesLink + stat.Duration.Should().Be(2764000); + //stat.ElevationGain + //stat.HeartRateLink + //stat.HeartRateZones + stat.LastModified.Should().Be(new DateTime(2017, 01, 01, 5, 3, 50)); + stat.LogId.Should().Be(5390522508); + stat.LogType.Should().Be("auto_detected"); + + stat.ManualValuesSpecified.Calories.Should().Be(false); + stat.ManualValuesSpecified.Distance.Should().Be(false); + stat.ManualValuesSpecified.Steps.Should().Be(false); + + stat.OriginalDuration.Should().Be(2764000); + stat.OriginalStartTime.Should().Be(new DateTime(2017, 1, 1, 4, 14, 06)); + stat.StartTime.Should().Be(new DateTime(2017, 1, 1, 4, 14, 06)); + //stat.Steps + stat.TcxLink.Should().Be("https://api.fitbit.com/1/user/-/activities/5390522508.tcx"); } } } diff --git a/Fitbit.Portable.Tests/HeartRateTests.cs b/Fitbit.Portable.Tests/HeartRateTests.cs index 0c85407d..16190f0e 100644 --- a/Fitbit.Portable.Tests/HeartRateTests.cs +++ b/Fitbit.Portable.Tests/HeartRateTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.Http; using System.Threading; @@ -28,13 +29,13 @@ public async void GetHeartRateTimeSeriesAsync_Success() var verification = new Action((message, token) => { Assert.AreEqual(HttpMethod.Get, message.Method); - Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/heart/date/{1}/{2}.json", message.RequestUri.AbsoluteUri); + Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/heart/date/today/1d.json", message.RequestUri.AbsoluteUri); }); var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); - var response = await fitbitClient.GetHeartRateTimeSeries("", ""); - //ValidateBloodPressureData(response); + var response = await fitbitClient.GetHeartRateTimeSeries("today", "1d"); + ValidateHeartRateTimeSeriesData(response); } [Test] @@ -59,11 +60,11 @@ public void GetHeartRateTimeSeriesAsync_Errors() public void Can_Deserialize_HeartRateTimeSeries() { string content = SampleDataHelper.GetContent("GetHeartRateTimeSeries.json"); - var deserializer = new JsonDotNetSerializer(); + var deserializer = new JsonDotNetSerializer { RootProperty = "activities-heart" }; List stats = deserializer.Deserialize>(content); - //ValidateActivity(stats); + ValidateHeartRateTimeSeriesData(stats); } [Test] @@ -80,13 +81,13 @@ public async void GetHeartRateIntradayTimeSeriesAsync_Success() var verification = new Action((message, token) => { Assert.AreEqual(HttpMethod.Get, message.Method); - Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/heart/date/{1}/{2}/{3}.json", message.RequestUri.AbsoluteUri); + Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/heart/date/today/1d.json", message.RequestUri.AbsoluteUri); }); var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); - var response = await fitbitClient.GetHeartRateTimeSeries("", ""); - //ValidateBloodPressureData(response); + var response = await fitbitClient.GetHeartRateTimeSeries("today", "1d"); + ValidateHeartRateTimeSeriesData(response); } [Test] @@ -111,11 +112,33 @@ public void GetHeartRateIntradayTimeSeriesAsync_Errors() public void Can_Deserialize_HeartRateIntradayTimeSeries() { string content = SampleDataHelper.GetContent("GetHeartRateIntradayTimeSeries.json"); - var deserializer = new JsonDotNetSerializer(); + var deserializer = new JsonDotNetSerializer {RootProperty = "activities-heart-intraday"}; HeartActivitiesIntraday stats = deserializer.Deserialize(content); - //ValidateActivity(stats); + ValidateHeartRateTimeSeriesData(stats); + } + + private void ValidateHeartRateTimeSeriesData(HeartActivitiesIntraday activity) + { + activity.Dataset.First().Time.TimeOfDay.Should().Be(new TimeSpan(0,0,0,0)); + activity.Dataset.First().Value.Should().Be(58); + } + + private void ValidateHeartRateTimeSeriesData(List activities) + { + var activity = activities.First(); + + activity.DateTime.Should().Be(new DateTime(2017, 6, 29)); + //activity.Value.CustomHeartRateZones + + //activity.Value.HeartRateZones.First().CaloriesOut.Should().Be(1693.83222); + activity.Value.HeartRateZones.First().Max.Should().Be(95); + activity.Value.HeartRateZones.First().Min.Should().Be(30); + activity.Value.HeartRateZones.First().Minutes.Should().Be(1122); + activity.Value.HeartRateZones.First().Name.Should().Be("Out of Range"); + + activity.Value.RestingHeartRate.Should().Be(59); } } } diff --git a/Fitbit.Portable.Tests/SampleData/GetActivityLogsList.json b/Fitbit.Portable.Tests/SampleData/GetActivityLogsList.json index cc40aed2..eb896410 100644 --- a/Fitbit.Portable.Tests/SampleData/GetActivityLogsList.json +++ b/Fitbit.Portable.Tests/SampleData/GetActivityLogsList.json @@ -1,80 +1,868 @@ { "activities": [ { - "activeDuration": 1734000, + "activeDuration": 2764000, "activityLevel": [ { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 1, + "name": "lightly" + }, + { + "minutes": 1, + "name": "fairly" + }, + { + "minutes": 44, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 108, + "calories": 375, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-01/2017-01-01/1min/time/4:14/5:00.json", + "duration": 2764000, + "elevationGain": 3.048, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-01/2017-01-01/1sec/time/04:14:06/05:00:10.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 3, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 43, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 0, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-01-01T05:03:50.000Z", + "logId": 5390522508, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 2764000, + "originalStartTime": "2017-01-01T04:14:06.000Z", + "startTime": "2017-01-01T04:14:06.000Z", + "steps": 5138, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5390522508.tcx" + }, + { + "activeDuration": 1938000, + "activityLevel": [ + { + "minutes": 1, + "name": "sedentary" + }, + { + "minutes": 2, + "name": "lightly" + }, + { + "minutes": 5, + "name": "fairly" + }, + { + "minutes": 24, + "name": "very" + } + ], + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 139, + "calories": 330, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-02/2017-01-02/1min/time/8:42/9:14.json", + "duration": 1938000, + "elevationGain": 3.048, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-02/2017-01-02/1sec/time/08:42:26/09:14:44.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 0, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 11, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 17, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, "minutes": 4, + "name": "Peak" + } + ], + "lastModified": "2017-01-02T09:24:18.000Z", + "logId": 5397828686, + "logType": "tracker", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1938000, + "originalStartTime": "2017-01-02T08:42:26.000Z", + "source": { + "id": "82473273", + "name": "Charge 2", + "type": "tracker", + "url": "https://www.fitbit.com/" + }, + "startTime": "2017-01-02T08:42:26.000Z", + "steps": 42, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5397828686.tcx" + }, + { + "activeDuration": 1920000, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 0, + "name": "lightly" + }, + { + "minutes": 0, + "name": "fairly" + }, + { + "minutes": 32, + "name": "very" + } + ], + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 96, + "calories": 330, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-03/2017-01-03/1min/time/7:46/8:18.json", + "duration": 1920000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-03/2017-01-03/1sec/time/07:46:00/08:18:00.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 15, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 16, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 1, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-01-03T08:32:19.000Z", + "logId": 5411224742, + "logType": "manual", + "manualValuesSpecified": { + "calories": true, + "distance": true, + "steps": true + }, + "originalDuration": 1920000, + "originalStartTime": "2017-01-03T07:46:00.000Z", + "source": { + "id": "228TSL", + "name": "Fitbit for iPhone", + "type": "app", + "url": "https://www.fitbit.com/iphone" + }, + "startTime": "2017-01-03T07:46:00.000Z", + "steps": 43, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5411224742.tcx" + }, + { + "activeDuration": 2541000, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 1, + "name": "lightly" + }, + { + "minutes": 5, + "name": "fairly" + }, + { + "minutes": 37, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 87, + "calories": 349, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-05/2017-01-05/1min/time/8:16/8:59.json", + "detailsLink": "https://api.fitbit.com/1/user/-/activities/5442151842.json", + "distance": 3.386578, + "distanceUnit": "Kilometer", + "duration": 2541000, + "elevationGain": 3.048, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-05/2017-01-05/1sec/time/08:16:52/08:59:13.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 34, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 8, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 0, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-01-05T08:59:23.000Z", + "logId": 5442151842, + "logType": "mobile_run", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 2541000, + "originalStartTime": "2017-01-05T08:16:52.000Z", + "pace": 750.3149196622667, + "source": { + "id": "228TSL", + "name": "Fitbit for iPhone", + "type": "app", + "url": "https://www.fitbit.com/iphone" + }, + "speed": 4.797985360094451, + "startTime": "2017-01-05T08:16:52.000Z", + "steps": 4798, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5442151842.tcx" + }, + { + "activeDuration": 4403000, + "activityLevel": [ + { + "minutes": 1, + "name": "sedentary" + }, + { + "minutes": 8, + "name": "lightly" + }, + { + "minutes": 12, + "name": "fairly" + }, + { + "minutes": 52, + "name": "very" + } + ], + "activityName": "Bike", + "activityTypeId": 90001, + "averageHeartRate": 91, + "calories": 591, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-05/2017-01-05/1min/time/17:54/19:07.json", + "duration": 4403000, + "elevationGain": 329.184, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-05/2017-01-05/1sec/time/17:54:13/19:07:36.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 51, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 17, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 3, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-01-10T16:23:14.000Z", + "logId": 5449195844, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 4403000, + "originalStartTime": "2017-01-05T17:54:13.000Z", + "startTime": "2017-01-05T17:54:13.000Z", + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5449195844.tcx" + }, + { + "activeDuration": 666000, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 3, + "name": "lightly" + }, + { + "minutes": 7, + "name": "fairly" + }, + { + "minutes": 1, + "name": "very" + } + ], + "activityName": "Bike", + "activityTypeId": 90001, + "averageHeartRate": 89, + "calories": 65, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-05/2017-01-05/1min/time/20:23/20:34.json", + "duration": 666000, + "elevationGain": 9.144, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-05/2017-01-05/1sec/time/20:23:32/20:34:38.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 9, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 2, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 0, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-01-10T16:23:26.000Z", + "logId": 5450925199, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 666000, + "originalStartTime": "2017-01-05T20:23:32.000Z", + "startTime": "2017-01-05T20:23:32.000Z", + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5450925199.tcx" + }, + { + "activeDuration": 12697000, + "activityLevel": [ + { + "minutes": 6, + "name": "sedentary" + }, + { + "minutes": 17, + "name": "lightly" + }, + { + "minutes": 33, + "name": "fairly" + }, + { + "minutes": 155, + "name": "very" + } + ], + "activityName": "Bike", + "activityTypeId": 90001, + "averageHeartRate": 116, + "calories": 1963, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-07/2017-01-07/1min/time/6:51/10:22.json", + "duration": 12697000, + "elevationGain": 749.808, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-07/2017-01-07/1sec/time/06:51:12/10:22:49.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 31, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 104, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 50, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 6, + "name": "Peak" + } + ], + "lastModified": "2017-01-10T16:23:32.000Z", + "logId": 5471148749, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 12697000, + "originalStartTime": "2017-01-07T06:51:12.000Z", + "startTime": "2017-01-07T06:51:12.000Z", + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5471148749.tcx" + }, + { + "activeDuration": 4402000, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 3, + "name": "lightly" + }, + { + "minutes": 11, + "name": "fairly" + }, + { + "minutes": 59, + "name": "very" + } + ], + "activityName": "Bike", + "activityTypeId": 90001, + "averageHeartRate": 116, + "calories": 683, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-07/2017-01-07/1min/time/11:04/12:18.json", + "duration": 4402000, + "elevationGain": 243.84, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-07/2017-01-07/1sec/time/11:04:38/12:18:00.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 8, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 42, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 15, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 3, + "name": "Peak" + } + ], + "lastModified": "2017-01-10T16:23:38.000Z", + "logId": 5471704390, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 4402000, + "originalStartTime": "2017-01-07T11:04:38.000Z", + "startTime": "2017-01-07T11:04:38.000Z", + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5471704390.tcx" + }, + { + "activeDuration": 1994000, + "activityLevel": [ + { + "minutes": 6, + "name": "sedentary" + }, + { + "minutes": 2, + "name": "lightly" + }, + { + "minutes": 3, + "name": "fairly" + }, + { + "minutes": 22, + "name": "very" + } + ], + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 128, + "calories": 296, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-09/2017-01-09/1min/time/6:39/7:12.json", + "duration": 1994000, + "elevationGain": 5.791, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-09/2017-01-09/1sec/time/06:39:04/07:12:18.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 5, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 8, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 17, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 2, + "name": "Peak" + } + ], + "lastModified": "2017-01-09T07:17:55.000Z", + "logId": 5492615686, + "logType": "tracker", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1994000, + "originalStartTime": "2017-01-09T06:39:04.000Z", + "source": { + "id": "82473273", + "name": "Charge 2", + "type": "tracker", + "url": "https://www.fitbit.com/" + }, + "startTime": "2017-01-09T06:39:04.000Z", + "steps": 8, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5492615686.tcx" + }, + { + "activeDuration": 2100000, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 0, + "name": "lightly" + }, + { + "minutes": 0, + "name": "fairly" + }, + { + "minutes": 35, + "name": "very" + } + ], + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 99, + "calories": 275, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-10/2017-01-10/1min/time/6:35/7:10.json", + "duration": 2100000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-10/2017-01-10/1sec/time/06:35:00/07:10:00.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 14, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 14, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 3, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-01-10T16:24:20.000Z", + "logId": 5510209898, + "logType": "manual", + "manualValuesSpecified": { + "calories": false, + "distance": true, + "steps": true + }, + "originalDuration": 2100000, + "originalStartTime": "2017-01-10T06:35:00.000Z", + "source": { + "id": "228TSL", + "name": "Fitbit for iPhone", + "type": "app", + "url": "https://www.fitbit.com/iphone" + }, + "startTime": "2017-01-10T06:35:00.000Z", + "steps": 75, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5510209898.tcx" + }, + { + "activeDuration": 1000, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 0, + "name": "lightly" + }, + { + "minutes": 0, + "name": "fairly" + }, + { + "minutes": 0, + "name": "very" + } + ], + "activityName": "Run", + "activityTypeId": 90009, + "averageHeartRate": 59, + "calories": 0, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-10/2017-01-10/1min/time/20:52/20:52.json", + "detailsLink": "https://api.fitbit.com/1/user/-/activities/5515193190.json", + "distance": 0, + "distanceUnit": "Kilometer", + "duration": 1000, + "elevationGain": 0, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-10/2017-01-10/1sec/time/20:52:27/20:52:28.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 0, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 0, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 0, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-01-10T21:05:18.000Z", + "logId": 5515193190, + "logType": "tracker", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1000, + "originalStartTime": "2017-01-10T20:52:27.000Z", + "source": { + "id": "82473273", + "name": "Charge 2", + "type": "tracker", + "url": "https://www.fitbit.com/" + }, + "speed": 0, + "startTime": "2017-01-10T20:52:27.000Z", + "steps": 0, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5515193190.tcx" + }, + { + "activeDuration": 3341000, + "activityLevel": [ + { + "minutes": 0, "name": "sedentary" }, { - "minutes": 14, + "minutes": 1, "name": "lightly" }, { - "minutes": 4, + "minutes": 1, "name": "fairly" }, { - "minutes": 6, + "minutes": 53, "name": "very" } ], - "activityName": "FitStar: Personal Trainer", - "activityTypeId": 17589491, - "averageHeartRate": 94, - "calories": 136, - "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-03-29/2016-03-29/1min/time/8:45/9:13.json", - "distance": 1.071811, - "distanceUnit": "Kilometer", - "duration": 1734000, - "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-03-29/2016-03-29/1sec/time/08:45:00/09:13:54.json", + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 153, + "calories": 676, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-12/2017-01-12/1min/time/6:34/7:30.json", + "duration": 3341000, + "elevationGain": 8.534, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-12/2017-01-12/1sec/time/06:34:42/07:30:23.json", "heartRateZones": [ { - "max": 94, + "max": 95, "min": 30, - "minutes": 16, + "minutes": 0, "name": "Out of Range" }, { - "max": 131, - "min": 94, - "minutes": 9, + "max": 133, + "min": 95, + "minutes": 4, "name": "Fat Burn" }, { - "max": 159, - "min": 131, - "minutes": 1, + "max": 162, + "min": 133, + "minutes": 39, "name": "Cardio" }, { "max": 220, - "min": 159, - "minutes": 0, + "min": 162, + "minutes": 13, "name": "Peak" } ], - "lastModified": "2016-03-29T17:41:53.000Z", - "logId": 2067350363, - "logType": "fitstar", + "lastModified": "2017-01-12T07:31:29.000Z", + "logId": 5539312165, + "logType": "tracker", "manualValuesSpecified": { "calories": false, "distance": false, "steps": false }, + "originalDuration": 3341000, + "originalStartTime": "2017-01-12T06:34:42.000Z", "source": { - "id": "228T4Z", - "name": "FitStar", - "type": "app", - "url": "http://www.fitstar.com" + "id": "82473273", + "name": "Charge 2", + "type": "tracker", + "url": "https://www.fitbit.com/" }, - "speed": 2.2252131487889275, - "startTime": "2016-03-29T08:45:00.000-07:00", - "steps": 1354 + "startTime": "2017-01-12T06:34:42.000Z", + "steps": 64, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5539312165.tcx" }, { - "activeDuration": 1001000, + "activeDuration": 1800000, "activityLevel": [ { "minutes": 0, @@ -85,211 +873,221 @@ "name": "lightly" }, { - "minutes": 17, + "minutes": 0, "name": "fairly" }, { - "minutes": 0, + "minutes": 30, "name": "very" } ], - "activityName": "Bike", - "activityTypeId": 90001, - "averageHeartRate": 93, - "calories": 77, - "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-03-28/2016-03-28/1min/time/19:05/19:22.json", - "distance": 4.1978, - "distanceUnit": "Kilometer", - "duration": 1001000, - "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-03-28/2016-03-28/1sec/time/19:05:31/19:22:12.json", + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 104, + "calories": 228, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-12/2017-01-12/1min/time/17:25/17:55.json", + "duration": 1800000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-12/2017-01-12/1sec/time/17:25:00/17:55:00.json", "heartRateZones": [ { - "max": 94, + "max": 95, "min": 30, - "minutes": 7, + "minutes": 8, "name": "Out of Range" }, { - "max": 131, - "min": 94, - "minutes": 10, + "max": 133, + "min": 95, + "minutes": 8, "name": "Fat Burn" }, { - "max": 159, - "min": 131, - "minutes": 0, + "max": 162, + "min": 133, + "minutes": 4, "name": "Cardio" }, { "max": 220, - "min": 159, + "min": 162, "minutes": 0, "name": "Peak" } ], - "lastModified": "2016-03-29T03:03:12.000Z", - "logId": 2068007929, + "lastModified": "2017-01-12T18:08:58.000Z", + "logId": 5548314782, "logType": "manual", "manualValuesSpecified": { - "calories": true, + "calories": false, "distance": true, "steps": true }, + "originalDuration": 1800000, + "originalStartTime": "2017-01-12T17:25:00.000Z", "source": { - "id": "22997K", - "name": "Fitbit + Strava", + "id": "228TSL", + "name": "Fitbit for iPhone", "type": "app", - "url": "https://strava.fitbit.com/" + "url": "https://www.fitbit.com/iphone" }, - "speed": 15.096983016983017, - "startTime": "2016-03-28T19:05:31.000-07:00", - "steps": 0 + "startTime": "2017-01-12T17:25:00.000Z", + "steps": 141, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5548314782.tcx" }, { - "activeDuration": 1503000, + "activeDuration": 768000, "activityLevel": [ { - "minutes": 4, + "minutes": 0, "name": "sedentary" }, { - "minutes": 11, + "minutes": 12, "name": "lightly" }, { - "minutes": 3, + "minutes": 0, "name": "fairly" }, { - "minutes": 7, + "minutes": 0, "name": "very" } ], "activityName": "Walk", "activityTypeId": 90013, - "averageHeartRate": 96, - "calories": 134, - "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-03-26/2016-03-26/1min/time/14:49/15:14.json", - "duration": 1503000, - "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-03-26/2016-03-26/1sec/time/14:49:05/15:14:08.json", + "averageHeartRate": 86, + "calories": 81, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-13/2017-01-13/1min/time/13:33/13:45.json", + "duration": 768000, + "elevationGain": 21.336, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-13/2017-01-13/1sec/time/13:33:11/13:45:59.json", "heartRateZones": [ { - "max": 94, + "max": 95, "min": 30, - "minutes": 8, + "minutes": 7, "name": "Out of Range" }, { - "max": 131, - "min": 94, - "minutes": 17, + "max": 133, + "min": 95, + "minutes": 5, "name": "Fat Burn" }, { - "max": 159, - "min": 131, + "max": 162, + "min": 133, "minutes": 0, "name": "Cardio" }, { "max": 220, - "min": 159, + "min": 162, "minutes": 0, "name": "Peak" } ], - "lastModified": "2016-03-26T22:34:17.000Z", - "logId": 2047712815, + "lastModified": "2017-01-13T14:23:41.000Z", + "logId": 5561886374, "logType": "auto_detected", "manualValuesSpecified": { "calories": false, "distance": false, "steps": false }, - "startTime": "2016-03-26T14:49:05.000-07:00", - "steps": 1662 + "originalDuration": 768000, + "originalStartTime": "2017-01-13T13:33:11.000Z", + "startTime": "2017-01-13T13:33:11.000Z", + "steps": 958, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5561886374.tcx" }, { - "activeDuration": 2766000, + "activeDuration": 10557000, "activityLevel": [ { - "minutes": 5, + "minutes": 0, "name": "sedentary" }, { - "minutes": 6, + "minutes": 3, "name": "lightly" }, { - "minutes": 2, + "minutes": 9, "name": "fairly" }, { - "minutes": 33, + "minutes": 164, "name": "very" } ], - "activityName": "Workout", - "activityTypeId": 3000, - "averageHeartRate": 147, - "calories": 416, - "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-03-05/2016-03-05/1min/time/15:31/16:17.json", - "duration": 2766000, - "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-03-05/2016-03-05/1sec/time/15:31:17/16:17:23.json", + "activityName": "Bike", + "activityTypeId": 90001, + "averageHeartRate": 150, + "calories": 2100, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-14/2017-01-14/1min/time/6:52/9:48.json", + "detailsLink": "https://api.fitbit.com/1/user/-/activities/5568699492.json", + "distance": 70.555069, + "distanceUnit": "Kilometer", + "duration": 10559000, + "elevationGain": 426.72, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-14/2017-01-14/1sec/time/06:52:25/09:48:24.json", "heartRateZones": [ { - "max": 94, + "max": 95, "min": 30, - "minutes": 3, + "minutes": 4, "name": "Out of Range" }, { - "max": 131, - "min": 94, - "minutes": 8, + "max": 133, + "min": 95, + "minutes": 22, "name": "Fat Burn" }, { - "max": 159, - "min": 131, - "minutes": 4, + "max": 162, + "min": 133, + "minutes": 94, "name": "Cardio" }, { "max": 220, - "min": 159, - "minutes": 30, + "min": 162, + "minutes": 56, "name": "Peak" } ], - "lastModified": "2016-03-06T00:20:21.000Z", - "logId": 1846159807, + "lastModified": "2017-01-14T09:48:39.000Z", + "logId": 5568699492, "logType": "tracker", "manualValuesSpecified": { "calories": false, "distance": false, "steps": false }, + "originalDuration": 10559000, + "originalStartTime": "2017-01-14T06:52:25.000Z", "source": { - "id": "47086726", - "name": "Charge HR", + "id": "82473273", + "name": "Charge 2", "type": "tracker", "url": "https://www.fitbit.com/" }, - "startTime": "2016-03-05T15:31:17.000-08:00", - "steps": 683, - "tcxLink": "https://api.fitbit.com/1/user/-/activities/1846159807.json" + "speed": 24.05969957374254, + "startTime": "2017-01-14T06:52:25.000Z", + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5568699492.tcx" }, { - "activeDuration": 784739, + "activeDuration": 3600000, "activityLevel": [ { "minutes": 0, "name": "sedentary" }, { - "minutes": 1, + "minutes": 0, "name": "lightly" }, { @@ -297,145 +1095,357 @@ "name": "fairly" }, { - "minutes": 12, + "minutes": 60, "name": "very" } ], - "activityName": "Run", - "activityTypeId": 90009, - "averageHeartRate": 125, - "calories": 124, - "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2016-01-31/2016-01-31/1min/time/19:11/19:24.json", - "distance": 2.534752, - "distanceUnit": "Kilometer", - "duration": 784000, - "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2016-01-31/2016-01-31/1sec/time/19:11:49/19:24:53.json", + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 149, + "calories": 462, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-16/2017-01-16/1min/time/6:40/7:40.json", + "duration": 3600000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-16/2017-01-16/1sec/time/06:40:00/07:40:00.json", "heartRateZones": [ { - "max": 94, + "max": 95, "min": 30, "minutes": 2, "name": "Out of Range" }, { - "max": 131, - "min": 94, - "minutes": 1, + "max": 133, + "min": 95, + "minutes": 5, "name": "Fat Burn" }, { - "max": 159, - "min": 131, - "minutes": 10, + "max": 162, + "min": 133, + "minutes": 30, "name": "Cardio" }, { "max": 220, - "min": 159, - "minutes": 0, + "min": 162, + "minutes": 8, "name": "Peak" } ], - "lastModified": "2016-02-01T03:25:03.000Z", - "logId": 1546680089, - "logType": "mobile_run", + "lastModified": "2017-01-16T08:17:16.000Z", + "logId": 5597625685, + "logType": "manual", "manualValuesSpecified": { "calories": false, - "distance": false, - "steps": false + "distance": true, + "steps": true }, - "pace": 309.30047594399764, + "originalDuration": 3600000, + "originalStartTime": "2017-01-16T06:40:00.000Z", "source": { - "id": "2295XJ", - "name": "Fitbit for Windows Phone", + "id": "228TSL", + "name": "Fitbit for iPhone", "type": "app", - "url": "https://www.fitbit.com/" + "url": "https://www.fitbit.com/iphone" }, - "speed": 11.628206575689497, - "startTime": "2016-01-31T19:11:49.000-08:00", - "steps": 1827, - "tcxLink": "https://api.fitbit.com/1/user/-/activities/1546680089.json" + "startTime": "2017-01-16T06:40:00.000Z", + "steps": 220, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5597625685.tcx" }, { - "activeDuration": 6226000, + "activeDuration": 3600000, "activityLevel": [ { - "minutes": 6, + "minutes": 0, "name": "sedentary" }, { - "minutes": 37, + "minutes": 0, "name": "lightly" }, { - "minutes": 28, + "minutes": 0, "name": "fairly" }, { - "minutes": 32, + "minutes": 60, "name": "very" } ], - "activityName": "Hike", - "activityTypeId": 90012, - "averageHeartRate": 102, - "calories": 582, - "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2015-05-25/2015-05-25/1min/time/14:08/16:09.json", - "distance": 5.600688, - "distanceUnit": "Kilometer", - "duration": 7272000, - "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2015-05-25/2015-05-25/1sec/time/14:08:12/16:09:24.json", + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 142, + "calories": 462, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-17/2017-01-17/1min/time/6:33/7:33.json", + "duration": 3600000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-17/2017-01-17/1sec/time/06:33:00/07:33:00.json", "heartRateZones": [ { - "max": 94, + "max": 95, "min": 30, - "minutes": 24, + "minutes": 5, "name": "Out of Range" }, { - "max": 132, - "min": 94, - "minutes": 79, + "max": 133, + "min": 95, + "minutes": 4, "name": "Fat Burn" }, { - "max": 160, - "min": 132, + "max": 162, + "min": 133, + "minutes": 39, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 1, + "name": "Peak" + } + ], + "lastModified": "2017-01-17T07:34:26.000Z", + "logId": 5611002233, + "logType": "manual", + "manualValuesSpecified": { + "calories": false, + "distance": true, + "steps": true + }, + "originalDuration": 3600000, + "originalStartTime": "2017-01-17T06:33:00.000Z", + "source": { + "id": "228TSL", + "name": "Fitbit for iPhone", + "type": "app", + "url": "https://www.fitbit.com/iphone" + }, + "startTime": "2017-01-17T06:33:00.000Z", + "steps": 21, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5611002233.tcx" + }, + { + "activeDuration": 2130000, + "activityLevel": [ + { + "minutes": 0, + "name": "sedentary" + }, + { + "minutes": 0, + "name": "lightly" + }, + { "minutes": 0, + "name": "fairly" + }, + { + "minutes": 36, + "name": "very" + } + ], + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 101, + "calories": 273, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-18/2017-01-18/1min/time/12:55/13:30.json", + "duration": 2130000, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-18/2017-01-18/1sec/time/12:55:00/13:30:30.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 14, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 8, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 6, "name": "Cardio" }, { "max": 220, - "min": 160, + "min": 162, "minutes": 0, "name": "Peak" } ], - "lastModified": "2015-07-15T23:45:47.000Z", - "logId": 228167717, + "lastModified": "2017-01-18T16:14:10.000Z", + "logId": 5634769316, + "logType": "manual", + "manualValuesSpecified": { + "calories": false, + "distance": true, + "steps": true + }, + "originalDuration": 2130000, + "originalStartTime": "2017-01-18T12:55:00.000Z", + "source": { + "id": "228TSL", + "name": "Fitbit for iPhone", + "type": "app", + "url": "https://www.fitbit.com/iphone" + }, + "startTime": "2017-01-18T12:55:00.000Z", + "steps": 105, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5634769316.tcx" + }, + { + "activeDuration": 4813000, + "activityLevel": [ + { + "minutes": 1, + "name": "sedentary" + }, + { + "minutes": 15, + "name": "lightly" + }, + { + "minutes": 16, + "name": "fairly" + }, + { + "minutes": 48, + "name": "very" + } + ], + "activityName": "Outdoor Bike", + "activityTypeId": 1071, + "averageHeartRate": 107, + "calories": 692, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-19/2017-01-19/1min/time/17:49/19:09.json", + "duration": 4813000, + "elevationGain": 283.464, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-19/2017-01-19/1sec/time/17:49:14/19:09:27.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 16, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 38, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 14, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 1, + "name": "Peak" + } + ], + "lastModified": "2017-01-19T19:18:24.000Z", + "logId": 5657171581, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 4813000, + "originalStartTime": "2017-01-19T17:49:14.000Z", + "startTime": "2017-01-19T17:49:14.000Z", + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5657171581.tcx" + }, + { + "activeDuration": 8284000, + "activityLevel": [ + { + "minutes": 30, + "name": "sedentary" + }, + { + "minutes": 14, + "name": "lightly" + }, + { + "minutes": 5, + "name": "fairly" + }, + { + "minutes": 89, + "name": "very" + } + ], + "activityName": "Spinning", + "activityTypeId": 55001, + "averageHeartRate": 125, + "calories": 1143, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-01-21/2017-01-21/1min/time/8:27/10:45.json", + "duration": 8284000, + "elevationGain": 16.154, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-01-21/2017-01-21/1sec/time/08:27:06/10:45:10.json", + "heartRateZones": [ + { + "max": 95, + "min": 30, + "minutes": 28, + "name": "Out of Range" + }, + { + "max": 133, + "min": 95, + "minutes": 24, + "name": "Fat Burn" + }, + { + "max": 162, + "min": 133, + "minutes": 84, + "name": "Cardio" + }, + { + "max": 220, + "min": 162, + "minutes": 1, + "name": "Peak" + } + ], + "lastModified": "2017-01-21T10:48:50.000Z", + "logId": 5681232699, "logType": "tracker", "manualValuesSpecified": { "calories": false, "distance": false, "steps": false }, - "pace": 1111.6491402484837, + "originalDuration": 8284000, + "originalStartTime": "2017-01-21T08:27:06.000Z", "source": { - "id": "18834976", - "name": "Surge", + "id": "82473273", + "name": "Charge 2", "type": "tracker", "url": "https://www.fitbit.com/" }, - "speed": 3.2384318663668488, - "startTime": "2015-05-25T14:08:12.000-07:00", - "steps": 7295, - "tcxLink": "https://api.fitbit.com/1/user/-/activities/228167717.json" + "startTime": "2017-01-21T08:27:06.000Z", + "steps": 272, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/5681232699.tcx" } ], "pagination": { - "beforeDate": "2016-03-30", - "limit": 10, - "next": "https://api.fitbit.com/1/user/-/activities/list.json?limit=10&sort=desc&beforeDate=2015-07-15T23:45:47.000Z", - "sort": "desc" + "afterDate": "2017-01-01T00:00:00", + "limit": 20, + "next": "https://api.fitbit.com/1/user/-/activities/list.json?offset=20&limit=20&sort=asc&afterDate=2017-01-01T00%3A00%3A00", + "offset": 0, + "previous": "", + "sort": "asc" } } \ No newline at end of file diff --git a/Fitbit.Portable.Tests/SampleData/GetHeartRateIntradayTimeSeries.json b/Fitbit.Portable.Tests/SampleData/GetHeartRateIntradayTimeSeries.json index d177980a..40af65cf 100644 --- a/Fitbit.Portable.Tests/SampleData/GetHeartRateIntradayTimeSeries.json +++ b/Fitbit.Portable.Tests/SampleData/GetHeartRateIntradayTimeSeries.json @@ -1,3 +1,4675 @@ { - -} + "activities-heart": [ + { + "dateTime": "2017-06-29", + "value": { + "customHeartRateZones": [], + "heartRateZones": [ + { + "caloriesOut": 1693.83222, + "max": 95, + "min": 30, + "minutes": 1122, + "name": "Out of Range" + }, + { + "caloriesOut": 211.22723, + "max": 133, + "min": 95, + "minutes": 35, + "name": "Fat Burn" + }, + { + "caloriesOut": 0, + "max": 162, + "min": 133, + "minutes": 0, + "name": "Cardio" + }, + { + "caloriesOut": 0, + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "restingHeartRate": 59 + } + } + ], + "activities-heart-intraday": { + "dataset": [ + { + "time": "00:00:00", + "value": 58 + }, + { + "time": "00:01:00", + "value": 58 + }, + { + "time": "00:02:00", + "value": 56 + }, + { + "time": "00:03:00", + "value": 55 + }, + { + "time": "00:04:00", + "value": 56 + }, + { + "time": "00:05:00", + "value": 54 + }, + { + "time": "00:06:00", + "value": 55 + }, + { + "time": "00:07:00", + "value": 54 + }, + { + "time": "00:08:00", + "value": 55 + }, + { + "time": "00:09:00", + "value": 55 + }, + { + "time": "00:10:00", + "value": 58 + }, + { + "time": "00:11:00", + "value": 56 + }, + { + "time": "00:12:00", + "value": 57 + }, + { + "time": "00:13:00", + "value": 57 + }, + { + "time": "00:14:00", + "value": 56 + }, + { + "time": "00:15:00", + "value": 55 + }, + { + "time": "00:16:00", + "value": 56 + }, + { + "time": "00:17:00", + "value": 57 + }, + { + "time": "00:18:00", + "value": 56 + }, + { + "time": "00:19:00", + "value": 58 + }, + { + "time": "00:20:00", + "value": 58 + }, + { + "time": "00:21:00", + "value": 58 + }, + { + "time": "00:22:00", + "value": 58 + }, + { + "time": "00:23:00", + "value": 58 + }, + { + "time": "00:24:00", + "value": 58 + }, + { + "time": "00:25:00", + "value": 58 + }, + { + "time": "00:26:00", + "value": 60 + }, + { + "time": "00:27:00", + "value": 58 + }, + { + "time": "00:28:00", + "value": 58 + }, + { + "time": "00:29:00", + "value": 62 + }, + { + "time": "00:30:00", + "value": 59 + }, + { + "time": "00:31:00", + "value": 59 + }, + { + "time": "00:32:00", + "value": 59 + }, + { + "time": "00:33:00", + "value": 60 + }, + { + "time": "00:34:00", + "value": 59 + }, + { + "time": "00:35:00", + "value": 60 + }, + { + "time": "00:36:00", + "value": 60 + }, + { + "time": "00:37:00", + "value": 61 + }, + { + "time": "00:38:00", + "value": 62 + }, + { + "time": "00:39:00", + "value": 64 + }, + { + "time": "00:40:00", + "value": 58 + }, + { + "time": "00:41:00", + "value": 60 + }, + { + "time": "00:42:00", + "value": 61 + }, + { + "time": "00:43:00", + "value": 61 + }, + { + "time": "00:44:00", + "value": 61 + }, + { + "time": "00:45:00", + "value": 61 + }, + { + "time": "00:46:00", + "value": 63 + }, + { + "time": "00:47:00", + "value": 63 + }, + { + "time": "00:48:00", + "value": 63 + }, + { + "time": "00:49:00", + "value": 64 + }, + { + "time": "00:50:00", + "value": 62 + }, + { + "time": "00:51:00", + "value": 61 + }, + { + "time": "00:52:00", + "value": 62 + }, + { + "time": "00:53:00", + "value": 61 + }, + { + "time": "00:54:00", + "value": 61 + }, + { + "time": "00:55:00", + "value": 61 + }, + { + "time": "00:56:00", + "value": 61 + }, + { + "time": "00:57:00", + "value": 61 + }, + { + "time": "00:58:00", + "value": 61 + }, + { + "time": "00:59:00", + "value": 63 + }, + { + "time": "01:00:00", + "value": 63 + }, + { + "time": "01:01:00", + "value": 60 + }, + { + "time": "01:02:00", + "value": 66 + }, + { + "time": "01:03:00", + "value": 71 + }, + { + "time": "01:04:00", + "value": 63 + }, + { + "time": "01:05:00", + "value": 69 + }, + { + "time": "01:06:00", + "value": 62 + }, + { + "time": "01:07:00", + "value": 62 + }, + { + "time": "01:08:00", + "value": 63 + }, + { + "time": "01:09:00", + "value": 67 + }, + { + "time": "01:10:00", + "value": 61 + }, + { + "time": "01:11:00", + "value": 57 + }, + { + "time": "01:12:00", + "value": 58 + }, + { + "time": "01:13:00", + "value": 58 + }, + { + "time": "01:14:00", + "value": 55 + }, + { + "time": "01:15:00", + "value": 55 + }, + { + "time": "01:16:00", + "value": 60 + }, + { + "time": "01:17:00", + "value": 60 + }, + { + "time": "01:18:00", + "value": 59 + }, + { + "time": "01:19:00", + "value": 57 + }, + { + "time": "01:20:00", + "value": 55 + }, + { + "time": "01:21:00", + "value": 60 + }, + { + "time": "01:22:00", + "value": 57 + }, + { + "time": "01:23:00", + "value": 57 + }, + { + "time": "01:24:00", + "value": 55 + }, + { + "time": "01:25:00", + "value": 56 + }, + { + "time": "01:26:00", + "value": 57 + }, + { + "time": "01:27:00", + "value": 60 + }, + { + "time": "01:28:00", + "value": 64 + }, + { + "time": "01:29:00", + "value": 60 + }, + { + "time": "01:30:00", + "value": 62 + }, + { + "time": "01:31:00", + "value": 60 + }, + { + "time": "01:32:00", + "value": 62 + }, + { + "time": "01:33:00", + "value": 62 + }, + { + "time": "01:34:00", + "value": 63 + }, + { + "time": "01:35:00", + "value": 62 + }, + { + "time": "01:36:00", + "value": 63 + }, + { + "time": "01:37:00", + "value": 64 + }, + { + "time": "01:38:00", + "value": 62 + }, + { + "time": "01:39:00", + "value": 63 + }, + { + "time": "01:40:00", + "value": 64 + }, + { + "time": "01:41:00", + "value": 65 + }, + { + "time": "01:42:00", + "value": 66 + }, + { + "time": "01:43:00", + "value": 62 + }, + { + "time": "01:44:00", + "value": 61 + }, + { + "time": "01:45:00", + "value": 62 + }, + { + "time": "01:46:00", + "value": 64 + }, + { + "time": "01:47:00", + "value": 63 + }, + { + "time": "01:48:00", + "value": 63 + }, + { + "time": "01:49:00", + "value": 64 + }, + { + "time": "01:50:00", + "value": 64 + }, + { + "time": "01:51:00", + "value": 65 + }, + { + "time": "01:52:00", + "value": 64 + }, + { + "time": "01:53:00", + "value": 64 + }, + { + "time": "01:54:00", + "value": 64 + }, + { + "time": "01:55:00", + "value": 65 + }, + { + "time": "01:56:00", + "value": 67 + }, + { + "time": "01:57:00", + "value": 62 + }, + { + "time": "01:58:00", + "value": 63 + }, + { + "time": "01:59:00", + "value": 61 + }, + { + "time": "02:00:00", + "value": 61 + }, + { + "time": "02:01:00", + "value": 63 + }, + { + "time": "02:02:00", + "value": 62 + }, + { + "time": "02:03:00", + "value": 61 + }, + { + "time": "02:04:00", + "value": 60 + }, + { + "time": "02:05:00", + "value": 61 + }, + { + "time": "02:06:00", + "value": 61 + }, + { + "time": "02:07:00", + "value": 63 + }, + { + "time": "02:08:00", + "value": 63 + }, + { + "time": "02:09:00", + "value": 63 + }, + { + "time": "02:10:00", + "value": 65 + }, + { + "time": "02:11:00", + "value": 62 + }, + { + "time": "02:12:00", + "value": 62 + }, + { + "time": "02:13:00", + "value": 62 + }, + { + "time": "02:14:00", + "value": 60 + }, + { + "time": "02:15:00", + "value": 61 + }, + { + "time": "02:16:00", + "value": 62 + }, + { + "time": "02:17:00", + "value": 59 + }, + { + "time": "02:18:00", + "value": 60 + }, + { + "time": "02:19:00", + "value": 60 + }, + { + "time": "02:20:00", + "value": 60 + }, + { + "time": "02:21:00", + "value": 61 + }, + { + "time": "02:22:00", + "value": 61 + }, + { + "time": "02:23:00", + "value": 61 + }, + { + "time": "02:24:00", + "value": 61 + }, + { + "time": "02:25:00", + "value": 61 + }, + { + "time": "02:26:00", + "value": 61 + }, + { + "time": "02:27:00", + "value": 62 + }, + { + "time": "02:28:00", + "value": 59 + }, + { + "time": "02:29:00", + "value": 60 + }, + { + "time": "02:30:00", + "value": 61 + }, + { + "time": "02:31:00", + "value": 62 + }, + { + "time": "02:32:00", + "value": 60 + }, + { + "time": "02:33:00", + "value": 61 + }, + { + "time": "02:34:00", + "value": 61 + }, + { + "time": "02:35:00", + "value": 61 + }, + { + "time": "02:36:00", + "value": 61 + }, + { + "time": "02:37:00", + "value": 66 + }, + { + "time": "02:38:00", + "value": 68 + }, + { + "time": "02:39:00", + "value": 64 + }, + { + "time": "02:40:00", + "value": 58 + }, + { + "time": "02:41:00", + "value": 58 + }, + { + "time": "02:42:00", + "value": 57 + }, + { + "time": "02:43:00", + "value": 57 + }, + { + "time": "02:44:00", + "value": 58 + }, + { + "time": "02:45:00", + "value": 55 + }, + { + "time": "02:46:00", + "value": 59 + }, + { + "time": "02:47:00", + "value": 59 + }, + { + "time": "02:48:00", + "value": 56 + }, + { + "time": "02:49:00", + "value": 55 + }, + { + "time": "02:50:00", + "value": 58 + }, + { + "time": "02:51:00", + "value": 57 + }, + { + "time": "02:52:00", + "value": 55 + }, + { + "time": "02:53:00", + "value": 57 + }, + { + "time": "02:54:00", + "value": 61 + }, + { + "time": "02:55:00", + "value": 54 + }, + { + "time": "02:56:00", + "value": 59 + }, + { + "time": "02:57:00", + "value": 54 + }, + { + "time": "02:58:00", + "value": 56 + }, + { + "time": "02:59:00", + "value": 57 + }, + { + "time": "03:00:00", + "value": 57 + }, + { + "time": "03:01:00", + "value": 53 + }, + { + "time": "03:02:00", + "value": 54 + }, + { + "time": "03:03:00", + "value": 57 + }, + { + "time": "03:04:00", + "value": 54 + }, + { + "time": "03:05:00", + "value": 59 + }, + { + "time": "03:06:00", + "value": 59 + }, + { + "time": "03:07:00", + "value": 62 + }, + { + "time": "03:08:00", + "value": 62 + }, + { + "time": "03:09:00", + "value": 60 + }, + { + "time": "03:10:00", + "value": 68 + }, + { + "time": "03:11:00", + "value": 63 + }, + { + "time": "03:12:00", + "value": 57 + }, + { + "time": "03:13:00", + "value": 58 + }, + { + "time": "03:14:00", + "value": 57 + }, + { + "time": "03:15:00", + "value": 56 + }, + { + "time": "03:16:00", + "value": 59 + }, + { + "time": "03:17:00", + "value": 59 + }, + { + "time": "03:18:00", + "value": 58 + }, + { + "time": "03:19:00", + "value": 57 + }, + { + "time": "03:20:00", + "value": 55 + }, + { + "time": "03:21:00", + "value": 57 + }, + { + "time": "03:22:00", + "value": 57 + }, + { + "time": "03:23:00", + "value": 56 + }, + { + "time": "03:24:00", + "value": 56 + }, + { + "time": "03:25:00", + "value": 60 + }, + { + "time": "03:26:00", + "value": 58 + }, + { + "time": "03:27:00", + "value": 58 + }, + { + "time": "03:28:00", + "value": 60 + }, + { + "time": "03:29:00", + "value": 62 + }, + { + "time": "03:30:00", + "value": 58 + }, + { + "time": "03:31:00", + "value": 61 + }, + { + "time": "03:32:00", + "value": 61 + }, + { + "time": "03:33:00", + "value": 62 + }, + { + "time": "03:34:00", + "value": 61 + }, + { + "time": "03:35:00", + "value": 62 + }, + { + "time": "03:36:00", + "value": 61 + }, + { + "time": "03:37:00", + "value": 62 + }, + { + "time": "03:38:00", + "value": 61 + }, + { + "time": "03:39:00", + "value": 62 + }, + { + "time": "03:40:00", + "value": 63 + }, + { + "time": "03:41:00", + "value": 62 + }, + { + "time": "03:42:00", + "value": 64 + }, + { + "time": "03:43:00", + "value": 59 + }, + { + "time": "03:44:00", + "value": 59 + }, + { + "time": "03:45:00", + "value": 61 + }, + { + "time": "03:46:00", + "value": 61 + }, + { + "time": "03:47:00", + "value": 58 + }, + { + "time": "03:48:00", + "value": 60 + }, + { + "time": "03:49:00", + "value": 60 + }, + { + "time": "03:50:00", + "value": 61 + }, + { + "time": "03:51:00", + "value": 63 + }, + { + "time": "03:52:00", + "value": 61 + }, + { + "time": "03:53:00", + "value": 60 + }, + { + "time": "03:54:00", + "value": 58 + }, + { + "time": "03:55:00", + "value": 58 + }, + { + "time": "03:56:00", + "value": 60 + }, + { + "time": "03:57:00", + "value": 60 + }, + { + "time": "03:58:00", + "value": 61 + }, + { + "time": "03:59:00", + "value": 60 + }, + { + "time": "04:00:00", + "value": 60 + }, + { + "time": "04:01:00", + "value": 60 + }, + { + "time": "04:02:00", + "value": 60 + }, + { + "time": "04:03:00", + "value": 62 + }, + { + "time": "04:04:00", + "value": 60 + }, + { + "time": "04:05:00", + "value": 61 + }, + { + "time": "04:06:00", + "value": 61 + }, + { + "time": "04:07:00", + "value": 60 + }, + { + "time": "04:08:00", + "value": 60 + }, + { + "time": "04:09:00", + "value": 60 + }, + { + "time": "04:10:00", + "value": 60 + }, + { + "time": "04:11:00", + "value": 60 + }, + { + "time": "04:12:00", + "value": 60 + }, + { + "time": "04:13:00", + "value": 60 + }, + { + "time": "04:14:00", + "value": 59 + }, + { + "time": "04:15:00", + "value": 63 + }, + { + "time": "04:16:00", + "value": 57 + }, + { + "time": "04:17:00", + "value": 58 + }, + { + "time": "04:18:00", + "value": 58 + }, + { + "time": "04:19:00", + "value": 58 + }, + { + "time": "04:20:00", + "value": 57 + }, + { + "time": "04:21:00", + "value": 58 + }, + { + "time": "04:22:00", + "value": 58 + }, + { + "time": "04:23:00", + "value": 58 + }, + { + "time": "04:24:00", + "value": 59 + }, + { + "time": "04:25:00", + "value": 57 + }, + { + "time": "04:26:00", + "value": 56 + }, + { + "time": "04:27:00", + "value": 58 + }, + { + "time": "04:28:00", + "value": 58 + }, + { + "time": "04:29:00", + "value": 58 + }, + { + "time": "04:30:00", + "value": 59 + }, + { + "time": "04:31:00", + "value": 59 + }, + { + "time": "04:32:00", + "value": 58 + }, + { + "time": "04:33:00", + "value": 58 + }, + { + "time": "04:34:00", + "value": 59 + }, + { + "time": "04:35:00", + "value": 59 + }, + { + "time": "04:36:00", + "value": 59 + }, + { + "time": "04:37:00", + "value": 60 + }, + { + "time": "04:38:00", + "value": 60 + }, + { + "time": "04:39:00", + "value": 58 + }, + { + "time": "04:40:00", + "value": 58 + }, + { + "time": "04:41:00", + "value": 57 + }, + { + "time": "04:42:00", + "value": 60 + }, + { + "time": "04:43:00", + "value": 59 + }, + { + "time": "04:44:00", + "value": 57 + }, + { + "time": "04:45:00", + "value": 59 + }, + { + "time": "04:46:00", + "value": 59 + }, + { + "time": "04:47:00", + "value": 60 + }, + { + "time": "04:48:00", + "value": 56 + }, + { + "time": "04:49:00", + "value": 55 + }, + { + "time": "04:50:00", + "value": 58 + }, + { + "time": "04:51:00", + "value": 55 + }, + { + "time": "04:52:00", + "value": 54 + }, + { + "time": "04:53:00", + "value": 56 + }, + { + "time": "04:54:00", + "value": 56 + }, + { + "time": "04:55:00", + "value": 57 + }, + { + "time": "04:56:00", + "value": 55 + }, + { + "time": "04:57:00", + "value": 53 + }, + { + "time": "04:58:00", + "value": 58 + }, + { + "time": "04:59:00", + "value": 55 + }, + { + "time": "05:00:00", + "value": 59 + }, + { + "time": "05:01:00", + "value": 56 + }, + { + "time": "05:02:00", + "value": 56 + }, + { + "time": "05:03:00", + "value": 55 + }, + { + "time": "05:04:00", + "value": 57 + }, + { + "time": "05:05:00", + "value": 56 + }, + { + "time": "05:06:00", + "value": 56 + }, + { + "time": "05:07:00", + "value": 57 + }, + { + "time": "05:08:00", + "value": 58 + }, + { + "time": "05:09:00", + "value": 56 + }, + { + "time": "05:10:00", + "value": 56 + }, + { + "time": "05:11:00", + "value": 57 + }, + { + "time": "05:12:00", + "value": 58 + }, + { + "time": "05:13:00", + "value": 58 + }, + { + "time": "05:14:00", + "value": 58 + }, + { + "time": "05:15:00", + "value": 58 + }, + { + "time": "05:16:00", + "value": 60 + }, + { + "time": "05:17:00", + "value": 60 + }, + { + "time": "05:18:00", + "value": 63 + }, + { + "time": "05:19:00", + "value": 55 + }, + { + "time": "05:20:00", + "value": 57 + }, + { + "time": "05:21:00", + "value": 61 + }, + { + "time": "05:22:00", + "value": 57 + }, + { + "time": "05:23:00", + "value": 59 + }, + { + "time": "05:24:00", + "value": 59 + }, + { + "time": "05:25:00", + "value": 61 + }, + { + "time": "05:26:00", + "value": 59 + }, + { + "time": "05:27:00", + "value": 59 + }, + { + "time": "05:28:00", + "value": 60 + }, + { + "time": "05:29:00", + "value": 61 + }, + { + "time": "05:30:00", + "value": 61 + }, + { + "time": "05:31:00", + "value": 62 + }, + { + "time": "05:32:00", + "value": 62 + }, + { + "time": "05:33:00", + "value": 59 + }, + { + "time": "05:34:00", + "value": 59 + }, + { + "time": "05:35:00", + "value": 60 + }, + { + "time": "05:36:00", + "value": 60 + }, + { + "time": "05:37:00", + "value": 63 + }, + { + "time": "05:38:00", + "value": 62 + }, + { + "time": "05:39:00", + "value": 61 + }, + { + "time": "05:40:00", + "value": 62 + }, + { + "time": "05:41:00", + "value": 62 + }, + { + "time": "05:42:00", + "value": 62 + }, + { + "time": "05:43:00", + "value": 61 + }, + { + "time": "05:44:00", + "value": 62 + }, + { + "time": "05:45:00", + "value": 62 + }, + { + "time": "05:46:00", + "value": 62 + }, + { + "time": "05:47:00", + "value": 62 + }, + { + "time": "05:48:00", + "value": 63 + }, + { + "time": "05:49:00", + "value": 59 + }, + { + "time": "05:50:00", + "value": 60 + }, + { + "time": "05:51:00", + "value": 60 + }, + { + "time": "05:52:00", + "value": 61 + }, + { + "time": "05:53:00", + "value": 60 + }, + { + "time": "05:54:00", + "value": 63 + }, + { + "time": "05:55:00", + "value": 64 + }, + { + "time": "05:56:00", + "value": 60 + }, + { + "time": "05:57:00", + "value": 60 + }, + { + "time": "05:58:00", + "value": 59 + }, + { + "time": "05:59:00", + "value": 58 + }, + { + "time": "06:00:00", + "value": 57 + }, + { + "time": "06:01:00", + "value": 56 + }, + { + "time": "06:02:00", + "value": 57 + }, + { + "time": "06:03:00", + "value": 56 + }, + { + "time": "06:04:00", + "value": 56 + }, + { + "time": "06:05:00", + "value": 60 + }, + { + "time": "06:06:00", + "value": 55 + }, + { + "time": "06:07:00", + "value": 56 + }, + { + "time": "06:08:00", + "value": 55 + }, + { + "time": "06:09:00", + "value": 53 + }, + { + "time": "06:10:00", + "value": 56 + }, + { + "time": "06:11:00", + "value": 58 + }, + { + "time": "06:12:00", + "value": 61 + }, + { + "time": "06:13:00", + "value": 61 + }, + { + "time": "06:14:00", + "value": 58 + }, + { + "time": "06:15:00", + "value": 56 + }, + { + "time": "06:16:00", + "value": 57 + }, + { + "time": "06:17:00", + "value": 55 + }, + { + "time": "06:18:00", + "value": 57 + }, + { + "time": "06:19:00", + "value": 55 + }, + { + "time": "06:20:00", + "value": 60 + }, + { + "time": "06:21:00", + "value": 57 + }, + { + "time": "06:22:00", + "value": 56 + }, + { + "time": "06:23:00", + "value": 57 + }, + { + "time": "06:24:00", + "value": 57 + }, + { + "time": "06:25:00", + "value": 53 + }, + { + "time": "06:26:00", + "value": 54 + }, + { + "time": "06:27:00", + "value": 56 + }, + { + "time": "06:28:00", + "value": 54 + }, + { + "time": "06:29:00", + "value": 52 + }, + { + "time": "06:30:00", + "value": 53 + }, + { + "time": "06:31:00", + "value": 60 + }, + { + "time": "06:32:00", + "value": 60 + }, + { + "time": "06:33:00", + "value": 53 + }, + { + "time": "06:34:00", + "value": 56 + }, + { + "time": "06:35:00", + "value": 59 + }, + { + "time": "06:36:00", + "value": 59 + }, + { + "time": "06:37:00", + "value": 60 + }, + { + "time": "06:38:00", + "value": 60 + }, + { + "time": "06:39:00", + "value": 64 + }, + { + "time": "06:40:00", + "value": 64 + }, + { + "time": "06:41:00", + "value": 65 + }, + { + "time": "06:42:00", + "value": 59 + }, + { + "time": "06:43:00", + "value": 64 + }, + { + "time": "06:44:00", + "value": 62 + }, + { + "time": "06:45:00", + "value": 59 + }, + { + "time": "06:46:00", + "value": 59 + }, + { + "time": "06:47:00", + "value": 63 + }, + { + "time": "06:48:00", + "value": 75 + }, + { + "time": "06:49:00", + "value": 71 + }, + { + "time": "06:50:00", + "value": 65 + }, + { + "time": "07:00:00", + "value": 72 + }, + { + "time": "07:01:00", + "value": 78 + }, + { + "time": "07:02:00", + "value": 82 + }, + { + "time": "07:03:00", + "value": 71 + }, + { + "time": "07:04:00", + "value": 63 + }, + { + "time": "07:05:00", + "value": 63 + }, + { + "time": "07:06:00", + "value": 64 + }, + { + "time": "07:07:00", + "value": 64 + }, + { + "time": "07:08:00", + "value": 66 + }, + { + "time": "07:09:00", + "value": 71 + }, + { + "time": "07:10:00", + "value": 79 + }, + { + "time": "07:11:00", + "value": 85 + }, + { + "time": "07:12:00", + "value": 84 + }, + { + "time": "07:13:00", + "value": 83 + }, + { + "time": "07:14:00", + "value": 83 + }, + { + "time": "07:15:00", + "value": 82 + }, + { + "time": "07:16:00", + "value": 83 + }, + { + "time": "07:17:00", + "value": 86 + }, + { + "time": "07:18:00", + "value": 86 + }, + { + "time": "07:19:00", + "value": 88 + }, + { + "time": "07:20:00", + "value": 84 + }, + { + "time": "07:21:00", + "value": 90 + }, + { + "time": "07:22:00", + "value": 97 + }, + { + "time": "07:23:00", + "value": 84 + }, + { + "time": "07:24:00", + "value": 72 + }, + { + "time": "07:25:00", + "value": 71 + }, + { + "time": "07:26:00", + "value": 71 + }, + { + "time": "07:27:00", + "value": 83 + }, + { + "time": "07:28:00", + "value": 95 + }, + { + "time": "07:29:00", + "value": 109 + }, + { + "time": "07:30:00", + "value": 113 + }, + { + "time": "07:31:00", + "value": 114 + }, + { + "time": "07:32:00", + "value": 109 + }, + { + "time": "07:33:00", + "value": 120 + }, + { + "time": "07:34:00", + "value": 103 + }, + { + "time": "07:36:00", + "value": 87 + }, + { + "time": "07:37:00", + "value": 86 + }, + { + "time": "07:38:00", + "value": 86 + }, + { + "time": "07:39:00", + "value": 87 + }, + { + "time": "07:40:00", + "value": 88 + }, + { + "time": "07:41:00", + "value": 80 + }, + { + "time": "07:42:00", + "value": 80 + }, + { + "time": "07:43:00", + "value": 82 + }, + { + "time": "07:44:00", + "value": 90 + }, + { + "time": "07:45:00", + "value": 87 + }, + { + "time": "07:46:00", + "value": 86 + }, + { + "time": "07:47:00", + "value": 82 + }, + { + "time": "07:48:00", + "value": 96 + }, + { + "time": "07:49:00", + "value": 97 + }, + { + "time": "07:50:00", + "value": 100 + }, + { + "time": "07:51:00", + "value": 100 + }, + { + "time": "07:52:00", + "value": 89 + }, + { + "time": "07:53:00", + "value": 86 + }, + { + "time": "07:54:00", + "value": 79 + }, + { + "time": "07:55:00", + "value": 79 + }, + { + "time": "07:56:00", + "value": 78 + }, + { + "time": "07:57:00", + "value": 83 + }, + { + "time": "07:58:00", + "value": 90 + }, + { + "time": "07:59:00", + "value": 93 + }, + { + "time": "08:00:00", + "value": 100 + }, + { + "time": "08:01:00", + "value": 104 + }, + { + "time": "08:02:00", + "value": 104 + }, + { + "time": "08:03:00", + "value": 105 + }, + { + "time": "08:04:00", + "value": 107 + }, + { + "time": "08:05:00", + "value": 105 + }, + { + "time": "08:06:00", + "value": 102 + }, + { + "time": "08:07:00", + "value": 101 + }, + { + "time": "08:08:00", + "value": 101 + }, + { + "time": "08:42:00", + "value": 79 + }, + { + "time": "08:43:00", + "value": 75 + }, + { + "time": "08:44:00", + "value": 72 + }, + { + "time": "08:45:00", + "value": 73 + }, + { + "time": "08:46:00", + "value": 79 + }, + { + "time": "08:47:00", + "value": 66 + }, + { + "time": "08:48:00", + "value": 69 + }, + { + "time": "08:49:00", + "value": 71 + }, + { + "time": "08:50:00", + "value": 72 + }, + { + "time": "08:51:00", + "value": 75 + }, + { + "time": "08:52:00", + "value": 76 + }, + { + "time": "08:53:00", + "value": 75 + }, + { + "time": "08:54:00", + "value": 74 + }, + { + "time": "08:55:00", + "value": 72 + }, + { + "time": "08:56:00", + "value": 74 + }, + { + "time": "08:57:00", + "value": 76 + }, + { + "time": "08:58:00", + "value": 71 + }, + { + "time": "08:59:00", + "value": 69 + }, + { + "time": "09:00:00", + "value": 67 + }, + { + "time": "09:01:00", + "value": 69 + }, + { + "time": "09:02:00", + "value": 71 + }, + { + "time": "09:03:00", + "value": 72 + }, + { + "time": "09:04:00", + "value": 74 + }, + { + "time": "09:05:00", + "value": 75 + }, + { + "time": "09:06:00", + "value": 72 + }, + { + "time": "09:07:00", + "value": 70 + }, + { + "time": "09:08:00", + "value": 70 + }, + { + "time": "09:09:00", + "value": 69 + }, + { + "time": "09:10:00", + "value": 71 + }, + { + "time": "09:11:00", + "value": 73 + }, + { + "time": "09:12:00", + "value": 72 + }, + { + "time": "09:13:00", + "value": 67 + }, + { + "time": "09:14:00", + "value": 65 + }, + { + "time": "09:15:00", + "value": 73 + }, + { + "time": "09:16:00", + "value": 72 + }, + { + "time": "09:17:00", + "value": 67 + }, + { + "time": "09:18:00", + "value": 68 + }, + { + "time": "09:19:00", + "value": 73 + }, + { + "time": "09:20:00", + "value": 74 + }, + { + "time": "09:21:00", + "value": 75 + }, + { + "time": "09:22:00", + "value": 74 + }, + { + "time": "09:23:00", + "value": 74 + }, + { + "time": "09:24:00", + "value": 76 + }, + { + "time": "09:25:00", + "value": 73 + }, + { + "time": "09:26:00", + "value": 77 + }, + { + "time": "09:27:00", + "value": 77 + }, + { + "time": "09:28:00", + "value": 78 + }, + { + "time": "09:29:00", + "value": 77 + }, + { + "time": "09:30:00", + "value": 75 + }, + { + "time": "09:31:00", + "value": 74 + }, + { + "time": "09:32:00", + "value": 76 + }, + { + "time": "09:33:00", + "value": 76 + }, + { + "time": "09:34:00", + "value": 73 + }, + { + "time": "09:35:00", + "value": 73 + }, + { + "time": "09:36:00", + "value": 70 + }, + { + "time": "09:37:00", + "value": 68 + }, + { + "time": "09:38:00", + "value": 70 + }, + { + "time": "09:39:00", + "value": 68 + }, + { + "time": "09:40:00", + "value": 67 + }, + { + "time": "09:41:00", + "value": 65 + }, + { + "time": "09:42:00", + "value": 68 + }, + { + "time": "09:43:00", + "value": 71 + }, + { + "time": "09:44:00", + "value": 71 + }, + { + "time": "09:45:00", + "value": 74 + }, + { + "time": "09:46:00", + "value": 72 + }, + { + "time": "09:47:00", + "value": 74 + }, + { + "time": "09:48:00", + "value": 74 + }, + { + "time": "09:49:00", + "value": 72 + }, + { + "time": "09:50:00", + "value": 72 + }, + { + "time": "09:51:00", + "value": 73 + }, + { + "time": "09:52:00", + "value": 74 + }, + { + "time": "09:53:00", + "value": 71 + }, + { + "time": "09:54:00", + "value": 73 + }, + { + "time": "09:55:00", + "value": 73 + }, + { + "time": "09:56:00", + "value": 73 + }, + { + "time": "09:57:00", + "value": 74 + }, + { + "time": "09:58:00", + "value": 73 + }, + { + "time": "09:59:00", + "value": 74 + }, + { + "time": "10:00:00", + "value": 74 + }, + { + "time": "10:01:00", + "value": 73 + }, + { + "time": "10:02:00", + "value": 74 + }, + { + "time": "10:03:00", + "value": 72 + }, + { + "time": "10:04:00", + "value": 70 + }, + { + "time": "10:05:00", + "value": 74 + }, + { + "time": "10:06:00", + "value": 73 + }, + { + "time": "10:07:00", + "value": 75 + }, + { + "time": "10:08:00", + "value": 74 + }, + { + "time": "10:09:00", + "value": 73 + }, + { + "time": "10:10:00", + "value": 74 + }, + { + "time": "10:11:00", + "value": 74 + }, + { + "time": "10:12:00", + "value": 75 + }, + { + "time": "10:13:00", + "value": 74 + }, + { + "time": "10:14:00", + "value": 74 + }, + { + "time": "10:15:00", + "value": 74 + }, + { + "time": "10:16:00", + "value": 74 + }, + { + "time": "10:17:00", + "value": 74 + }, + { + "time": "10:18:00", + "value": 74 + }, + { + "time": "10:19:00", + "value": 75 + }, + { + "time": "10:20:00", + "value": 74 + }, + { + "time": "10:21:00", + "value": 73 + }, + { + "time": "10:22:00", + "value": 69 + }, + { + "time": "10:23:00", + "value": 67 + }, + { + "time": "10:24:00", + "value": 69 + }, + { + "time": "10:25:00", + "value": 73 + }, + { + "time": "10:26:00", + "value": 71 + }, + { + "time": "10:27:00", + "value": 67 + }, + { + "time": "10:28:00", + "value": 72 + }, + { + "time": "10:29:00", + "value": 71 + }, + { + "time": "10:30:00", + "value": 72 + }, + { + "time": "10:31:00", + "value": 71 + }, + { + "time": "10:32:00", + "value": 72 + }, + { + "time": "10:33:00", + "value": 73 + }, + { + "time": "10:34:00", + "value": 67 + }, + { + "time": "10:35:00", + "value": 67 + }, + { + "time": "10:36:00", + "value": 62 + }, + { + "time": "10:37:00", + "value": 72 + }, + { + "time": "10:38:00", + "value": 75 + }, + { + "time": "10:39:00", + "value": 74 + }, + { + "time": "10:40:00", + "value": 74 + }, + { + "time": "10:41:00", + "value": 78 + }, + { + "time": "10:42:00", + "value": 76 + }, + { + "time": "10:43:00", + "value": 75 + }, + { + "time": "10:44:00", + "value": 74 + }, + { + "time": "10:45:00", + "value": 74 + }, + { + "time": "10:46:00", + "value": 72 + }, + { + "time": "10:47:00", + "value": 72 + }, + { + "time": "10:48:00", + "value": 71 + }, + { + "time": "10:49:00", + "value": 71 + }, + { + "time": "10:50:00", + "value": 75 + }, + { + "time": "10:51:00", + "value": 78 + }, + { + "time": "10:52:00", + "value": 78 + }, + { + "time": "10:53:00", + "value": 73 + }, + { + "time": "10:54:00", + "value": 75 + }, + { + "time": "10:55:00", + "value": 69 + }, + { + "time": "10:56:00", + "value": 70 + }, + { + "time": "10:57:00", + "value": 74 + }, + { + "time": "10:58:00", + "value": 74 + }, + { + "time": "10:59:00", + "value": 70 + }, + { + "time": "11:00:00", + "value": 71 + }, + { + "time": "11:01:00", + "value": 72 + }, + { + "time": "11:02:00", + "value": 73 + }, + { + "time": "11:03:00", + "value": 76 + }, + { + "time": "11:04:00", + "value": 79 + }, + { + "time": "11:05:00", + "value": 79 + }, + { + "time": "11:06:00", + "value": 72 + }, + { + "time": "11:07:00", + "value": 74 + }, + { + "time": "11:08:00", + "value": 74 + }, + { + "time": "11:09:00", + "value": 73 + }, + { + "time": "11:10:00", + "value": 70 + }, + { + "time": "11:11:00", + "value": 78 + }, + { + "time": "11:12:00", + "value": 74 + }, + { + "time": "11:13:00", + "value": 70 + }, + { + "time": "11:14:00", + "value": 70 + }, + { + "time": "11:15:00", + "value": 68 + }, + { + "time": "11:16:00", + "value": 68 + }, + { + "time": "11:17:00", + "value": 68 + }, + { + "time": "11:18:00", + "value": 71 + }, + { + "time": "11:19:00", + "value": 70 + }, + { + "time": "11:20:00", + "value": 73 + }, + { + "time": "11:21:00", + "value": 72 + }, + { + "time": "11:22:00", + "value": 72 + }, + { + "time": "11:23:00", + "value": 70 + }, + { + "time": "11:24:00", + "value": 70 + }, + { + "time": "11:25:00", + "value": 71 + }, + { + "time": "11:26:00", + "value": 71 + }, + { + "time": "11:27:00", + "value": 73 + }, + { + "time": "11:28:00", + "value": 73 + }, + { + "time": "11:29:00", + "value": 71 + }, + { + "time": "11:30:00", + "value": 68 + }, + { + "time": "11:31:00", + "value": 63 + }, + { + "time": "11:32:00", + "value": 64 + }, + { + "time": "11:33:00", + "value": 65 + }, + { + "time": "11:34:00", + "value": 66 + }, + { + "time": "11:35:00", + "value": 68 + }, + { + "time": "11:36:00", + "value": 78 + }, + { + "time": "11:37:00", + "value": 79 + }, + { + "time": "11:38:00", + "value": 80 + }, + { + "time": "11:39:00", + "value": 75 + }, + { + "time": "11:40:00", + "value": 73 + }, + { + "time": "11:41:00", + "value": 73 + }, + { + "time": "11:42:00", + "value": 73 + }, + { + "time": "11:43:00", + "value": 73 + }, + { + "time": "11:44:00", + "value": 74 + }, + { + "time": "11:45:00", + "value": 75 + }, + { + "time": "11:46:00", + "value": 75 + }, + { + "time": "11:47:00", + "value": 74 + }, + { + "time": "11:48:00", + "value": 74 + }, + { + "time": "11:49:00", + "value": 75 + }, + { + "time": "11:50:00", + "value": 75 + }, + { + "time": "11:51:00", + "value": 75 + }, + { + "time": "11:52:00", + "value": 76 + }, + { + "time": "11:53:00", + "value": 80 + }, + { + "time": "11:54:00", + "value": 80 + }, + { + "time": "11:55:00", + "value": 79 + }, + { + "time": "11:56:00", + "value": 80 + }, + { + "time": "11:57:00", + "value": 80 + }, + { + "time": "11:58:00", + "value": 81 + }, + { + "time": "11:59:00", + "value": 86 + }, + { + "time": "12:00:00", + "value": 67 + }, + { + "time": "12:01:00", + "value": 67 + }, + { + "time": "12:02:00", + "value": 71 + }, + { + "time": "12:03:00", + "value": 69 + }, + { + "time": "12:04:00", + "value": 72 + }, + { + "time": "12:05:00", + "value": 76 + }, + { + "time": "12:06:00", + "value": 78 + }, + { + "time": "12:07:00", + "value": 71 + }, + { + "time": "12:08:00", + "value": 72 + }, + { + "time": "12:09:00", + "value": 74 + }, + { + "time": "12:10:00", + "value": 76 + }, + { + "time": "12:11:00", + "value": 77 + }, + { + "time": "12:12:00", + "value": 75 + }, + { + "time": "12:13:00", + "value": 76 + }, + { + "time": "12:14:00", + "value": 77 + }, + { + "time": "12:15:00", + "value": 78 + }, + { + "time": "12:16:00", + "value": 79 + }, + { + "time": "12:17:00", + "value": 78 + }, + { + "time": "12:18:00", + "value": 77 + }, + { + "time": "12:19:00", + "value": 77 + }, + { + "time": "12:20:00", + "value": 79 + }, + { + "time": "12:21:00", + "value": 80 + }, + { + "time": "12:22:00", + "value": 79 + }, + { + "time": "12:23:00", + "value": 76 + }, + { + "time": "12:24:00", + "value": 77 + }, + { + "time": "12:25:00", + "value": 78 + }, + { + "time": "12:26:00", + "value": 79 + }, + { + "time": "12:27:00", + "value": 77 + }, + { + "time": "12:28:00", + "value": 78 + }, + { + "time": "12:29:00", + "value": 78 + }, + { + "time": "12:30:00", + "value": 79 + }, + { + "time": "12:31:00", + "value": 77 + }, + { + "time": "12:32:00", + "value": 78 + }, + { + "time": "12:33:00", + "value": 78 + }, + { + "time": "12:34:00", + "value": 78 + }, + { + "time": "12:35:00", + "value": 77 + }, + { + "time": "12:36:00", + "value": 77 + }, + { + "time": "12:37:00", + "value": 77 + }, + { + "time": "12:38:00", + "value": 77 + }, + { + "time": "12:39:00", + "value": 76 + }, + { + "time": "12:40:00", + "value": 77 + }, + { + "time": "12:41:00", + "value": 76 + }, + { + "time": "12:42:00", + "value": 77 + }, + { + "time": "12:43:00", + "value": 77 + }, + { + "time": "12:44:00", + "value": 75 + }, + { + "time": "12:45:00", + "value": 76 + }, + { + "time": "12:46:00", + "value": 74 + }, + { + "time": "12:47:00", + "value": 77 + }, + { + "time": "12:48:00", + "value": 75 + }, + { + "time": "12:49:00", + "value": 71 + }, + { + "time": "12:50:00", + "value": 75 + }, + { + "time": "12:51:00", + "value": 76 + }, + { + "time": "12:52:00", + "value": 78 + }, + { + "time": "12:53:00", + "value": 76 + }, + { + "time": "12:54:00", + "value": 77 + }, + { + "time": "12:55:00", + "value": 76 + }, + { + "time": "12:56:00", + "value": 71 + }, + { + "time": "12:57:00", + "value": 67 + }, + { + "time": "12:58:00", + "value": 65 + }, + { + "time": "12:59:00", + "value": 66 + }, + { + "time": "13:00:00", + "value": 66 + }, + { + "time": "13:01:00", + "value": 67 + }, + { + "time": "13:02:00", + "value": 68 + }, + { + "time": "13:03:00", + "value": 69 + }, + { + "time": "13:04:00", + "value": 75 + }, + { + "time": "13:05:00", + "value": 71 + }, + { + "time": "13:06:00", + "value": 70 + }, + { + "time": "13:07:00", + "value": 74 + }, + { + "time": "13:08:00", + "value": 72 + }, + { + "time": "13:09:00", + "value": 71 + }, + { + "time": "13:10:00", + "value": 72 + }, + { + "time": "13:11:00", + "value": 70 + }, + { + "time": "13:12:00", + "value": 69 + }, + { + "time": "13:13:00", + "value": 75 + }, + { + "time": "13:14:00", + "value": 76 + }, + { + "time": "13:15:00", + "value": 76 + }, + { + "time": "13:16:00", + "value": 80 + }, + { + "time": "13:17:00", + "value": 78 + }, + { + "time": "13:18:00", + "value": 80 + }, + { + "time": "13:19:00", + "value": 79 + }, + { + "time": "13:20:00", + "value": 79 + }, + { + "time": "13:21:00", + "value": 81 + }, + { + "time": "13:22:00", + "value": 80 + }, + { + "time": "13:23:00", + "value": 79 + }, + { + "time": "13:24:00", + "value": 80 + }, + { + "time": "13:25:00", + "value": 80 + }, + { + "time": "13:26:00", + "value": 79 + }, + { + "time": "13:27:00", + "value": 77 + }, + { + "time": "13:28:00", + "value": 72 + }, + { + "time": "13:29:00", + "value": 72 + }, + { + "time": "13:30:00", + "value": 71 + }, + { + "time": "13:31:00", + "value": 76 + }, + { + "time": "13:32:00", + "value": 83 + }, + { + "time": "13:33:00", + "value": 76 + }, + { + "time": "13:34:00", + "value": 73 + }, + { + "time": "13:35:00", + "value": 73 + }, + { + "time": "13:36:00", + "value": 75 + }, + { + "time": "13:37:00", + "value": 72 + }, + { + "time": "13:38:00", + "value": 71 + }, + { + "time": "13:39:00", + "value": 71 + }, + { + "time": "13:40:00", + "value": 74 + }, + { + "time": "13:41:00", + "value": 72 + }, + { + "time": "13:42:00", + "value": 73 + }, + { + "time": "13:43:00", + "value": 72 + }, + { + "time": "13:44:00", + "value": 70 + }, + { + "time": "13:45:00", + "value": 70 + }, + { + "time": "13:46:00", + "value": 71 + }, + { + "time": "13:47:00", + "value": 74 + }, + { + "time": "13:48:00", + "value": 72 + }, + { + "time": "13:49:00", + "value": 71 + }, + { + "time": "13:50:00", + "value": 71 + }, + { + "time": "13:51:00", + "value": 75 + }, + { + "time": "13:52:00", + "value": 75 + }, + { + "time": "13:53:00", + "value": 74 + }, + { + "time": "13:54:00", + "value": 82 + }, + { + "time": "13:55:00", + "value": 90 + }, + { + "time": "13:56:00", + "value": 94 + }, + { + "time": "13:57:00", + "value": 98 + }, + { + "time": "13:58:00", + "value": 102 + }, + { + "time": "14:00:00", + "value": 75 + }, + { + "time": "14:01:00", + "value": 68 + }, + { + "time": "14:02:00", + "value": 66 + }, + { + "time": "14:03:00", + "value": 64 + }, + { + "time": "14:04:00", + "value": 62 + }, + { + "time": "14:05:00", + "value": 63 + }, + { + "time": "14:06:00", + "value": 62 + }, + { + "time": "14:07:00", + "value": 63 + }, + { + "time": "14:08:00", + "value": 64 + }, + { + "time": "14:09:00", + "value": 64 + }, + { + "time": "14:10:00", + "value": 68 + }, + { + "time": "14:11:00", + "value": 72 + }, + { + "time": "14:12:00", + "value": 70 + }, + { + "time": "14:13:00", + "value": 66 + }, + { + "time": "14:14:00", + "value": 71 + }, + { + "time": "14:15:00", + "value": 71 + }, + { + "time": "14:16:00", + "value": 73 + }, + { + "time": "14:17:00", + "value": 72 + }, + { + "time": "14:18:00", + "value": 73 + }, + { + "time": "14:19:00", + "value": 73 + }, + { + "time": "14:20:00", + "value": 73 + }, + { + "time": "14:21:00", + "value": 74 + }, + { + "time": "14:22:00", + "value": 75 + }, + { + "time": "14:23:00", + "value": 75 + }, + { + "time": "14:24:00", + "value": 75 + }, + { + "time": "14:25:00", + "value": 74 + }, + { + "time": "14:26:00", + "value": 73 + }, + { + "time": "14:27:00", + "value": 71 + }, + { + "time": "14:28:00", + "value": 70 + }, + { + "time": "14:29:00", + "value": 75 + }, + { + "time": "14:30:00", + "value": 71 + }, + { + "time": "14:31:00", + "value": 63 + }, + { + "time": "14:32:00", + "value": 66 + }, + { + "time": "14:33:00", + "value": 69 + }, + { + "time": "14:34:00", + "value": 70 + }, + { + "time": "14:35:00", + "value": 72 + }, + { + "time": "14:36:00", + "value": 67 + }, + { + "time": "14:37:00", + "value": 65 + }, + { + "time": "14:38:00", + "value": 70 + }, + { + "time": "14:39:00", + "value": 72 + }, + { + "time": "14:40:00", + "value": 68 + }, + { + "time": "14:41:00", + "value": 65 + }, + { + "time": "14:42:00", + "value": 68 + }, + { + "time": "14:43:00", + "value": 74 + }, + { + "time": "14:44:00", + "value": 75 + }, + { + "time": "14:45:00", + "value": 75 + }, + { + "time": "14:46:00", + "value": 75 + }, + { + "time": "14:47:00", + "value": 80 + }, + { + "time": "14:48:00", + "value": 81 + }, + { + "time": "14:49:00", + "value": 74 + }, + { + "time": "14:50:00", + "value": 73 + }, + { + "time": "14:51:00", + "value": 73 + }, + { + "time": "14:52:00", + "value": 78 + }, + { + "time": "14:53:00", + "value": 70 + }, + { + "time": "14:54:00", + "value": 64 + }, + { + "time": "14:55:00", + "value": 67 + }, + { + "time": "14:56:00", + "value": 71 + }, + { + "time": "14:57:00", + "value": 71 + }, + { + "time": "14:58:00", + "value": 70 + }, + { + "time": "14:59:00", + "value": 70 + }, + { + "time": "15:00:00", + "value": 68 + }, + { + "time": "15:01:00", + "value": 67 + }, + { + "time": "15:02:00", + "value": 71 + }, + { + "time": "15:03:00", + "value": 71 + }, + { + "time": "15:04:00", + "value": 65 + }, + { + "time": "15:05:00", + "value": 63 + }, + { + "time": "15:06:00", + "value": 64 + }, + { + "time": "15:07:00", + "value": 63 + }, + { + "time": "15:08:00", + "value": 72 + }, + { + "time": "15:09:00", + "value": 73 + }, + { + "time": "15:10:00", + "value": 75 + }, + { + "time": "15:11:00", + "value": 71 + }, + { + "time": "15:12:00", + "value": 71 + }, + { + "time": "15:13:00", + "value": 75 + }, + { + "time": "15:14:00", + "value": 71 + }, + { + "time": "15:15:00", + "value": 71 + }, + { + "time": "15:16:00", + "value": 73 + }, + { + "time": "15:17:00", + "value": 74 + }, + { + "time": "15:18:00", + "value": 73 + }, + { + "time": "15:19:00", + "value": 73 + }, + { + "time": "15:20:00", + "value": 70 + }, + { + "time": "15:21:00", + "value": 69 + }, + { + "time": "15:22:00", + "value": 67 + }, + { + "time": "15:23:00", + "value": 68 + }, + { + "time": "15:24:00", + "value": 66 + }, + { + "time": "15:25:00", + "value": 63 + }, + { + "time": "15:26:00", + "value": 62 + }, + { + "time": "15:27:00", + "value": 63 + }, + { + "time": "15:28:00", + "value": 74 + }, + { + "time": "15:29:00", + "value": 73 + }, + { + "time": "15:30:00", + "value": 69 + }, + { + "time": "15:31:00", + "value": 70 + }, + { + "time": "15:32:00", + "value": 73 + }, + { + "time": "15:33:00", + "value": 73 + }, + { + "time": "15:34:00", + "value": 73 + }, + { + "time": "15:35:00", + "value": 75 + }, + { + "time": "15:36:00", + "value": 74 + }, + { + "time": "15:37:00", + "value": 73 + }, + { + "time": "15:38:00", + "value": 72 + }, + { + "time": "15:39:00", + "value": 74 + }, + { + "time": "15:40:00", + "value": 73 + }, + { + "time": "15:41:00", + "value": 73 + }, + { + "time": "15:42:00", + "value": 76 + }, + { + "time": "15:43:00", + "value": 77 + }, + { + "time": "15:44:00", + "value": 77 + }, + { + "time": "15:45:00", + "value": 77 + }, + { + "time": "15:46:00", + "value": 79 + }, + { + "time": "15:47:00", + "value": 73 + }, + { + "time": "15:48:00", + "value": 70 + }, + { + "time": "15:49:00", + "value": 68 + }, + { + "time": "15:50:00", + "value": 73 + }, + { + "time": "15:51:00", + "value": 72 + }, + { + "time": "15:52:00", + "value": 69 + }, + { + "time": "15:53:00", + "value": 69 + }, + { + "time": "15:54:00", + "value": 67 + }, + { + "time": "15:55:00", + "value": 66 + }, + { + "time": "15:56:00", + "value": 65 + }, + { + "time": "15:57:00", + "value": 64 + }, + { + "time": "15:58:00", + "value": 64 + }, + { + "time": "15:59:00", + "value": 67 + }, + { + "time": "16:00:00", + "value": 68 + }, + { + "time": "16:01:00", + "value": 69 + }, + { + "time": "16:02:00", + "value": 70 + }, + { + "time": "16:03:00", + "value": 71 + }, + { + "time": "16:04:00", + "value": 71 + }, + { + "time": "16:05:00", + "value": 67 + }, + { + "time": "16:06:00", + "value": 62 + }, + { + "time": "16:07:00", + "value": 61 + }, + { + "time": "16:08:00", + "value": 70 + }, + { + "time": "16:09:00", + "value": 74 + }, + { + "time": "16:10:00", + "value": 77 + }, + { + "time": "16:11:00", + "value": 74 + }, + { + "time": "16:12:00", + "value": 74 + }, + { + "time": "16:13:00", + "value": 72 + }, + { + "time": "16:14:00", + "value": 75 + }, + { + "time": "16:15:00", + "value": 77 + }, + { + "time": "16:16:00", + "value": 76 + }, + { + "time": "16:17:00", + "value": 75 + }, + { + "time": "16:18:00", + "value": 71 + }, + { + "time": "16:19:00", + "value": 72 + }, + { + "time": "16:20:00", + "value": 73 + }, + { + "time": "16:21:00", + "value": 66 + }, + { + "time": "16:22:00", + "value": 65 + }, + { + "time": "16:23:00", + "value": 63 + }, + { + "time": "16:24:00", + "value": 68 + }, + { + "time": "16:25:00", + "value": 72 + }, + { + "time": "16:26:00", + "value": 70 + }, + { + "time": "16:27:00", + "value": 64 + }, + { + "time": "16:28:00", + "value": 67 + }, + { + "time": "16:29:00", + "value": 72 + }, + { + "time": "16:30:00", + "value": 72 + }, + { + "time": "16:31:00", + "value": 70 + }, + { + "time": "16:32:00", + "value": 67 + }, + { + "time": "16:33:00", + "value": 69 + }, + { + "time": "16:34:00", + "value": 67 + }, + { + "time": "16:35:00", + "value": 67 + }, + { + "time": "16:36:00", + "value": 67 + }, + { + "time": "16:37:00", + "value": 70 + }, + { + "time": "16:38:00", + "value": 70 + }, + { + "time": "16:39:00", + "value": 72 + }, + { + "time": "16:40:00", + "value": 69 + }, + { + "time": "16:41:00", + "value": 70 + }, + { + "time": "16:42:00", + "value": 74 + }, + { + "time": "16:43:00", + "value": 74 + }, + { + "time": "16:44:00", + "value": 74 + }, + { + "time": "16:45:00", + "value": 71 + }, + { + "time": "16:46:00", + "value": 70 + }, + { + "time": "16:47:00", + "value": 71 + }, + { + "time": "16:48:00", + "value": 74 + }, + { + "time": "16:49:00", + "value": 74 + }, + { + "time": "16:50:00", + "value": 73 + }, + { + "time": "16:51:00", + "value": 74 + }, + { + "time": "16:52:00", + "value": 73 + }, + { + "time": "16:53:00", + "value": 70 + }, + { + "time": "16:54:00", + "value": 70 + }, + { + "time": "16:55:00", + "value": 70 + }, + { + "time": "16:56:00", + "value": 70 + }, + { + "time": "16:57:00", + "value": 74 + }, + { + "time": "16:58:00", + "value": 70 + }, + { + "time": "16:59:00", + "value": 67 + }, + { + "time": "17:00:00", + "value": 64 + }, + { + "time": "17:01:00", + "value": 60 + }, + { + "time": "17:02:00", + "value": 68 + }, + { + "time": "17:03:00", + "value": 70 + }, + { + "time": "17:04:00", + "value": 70 + }, + { + "time": "17:05:00", + "value": 69 + }, + { + "time": "17:06:00", + "value": 64 + }, + { + "time": "17:07:00", + "value": 63 + }, + { + "time": "17:08:00", + "value": 66 + }, + { + "time": "17:09:00", + "value": 66 + }, + { + "time": "17:10:00", + "value": 65 + }, + { + "time": "17:11:00", + "value": 68 + }, + { + "time": "17:12:00", + "value": 70 + }, + { + "time": "17:13:00", + "value": 70 + }, + { + "time": "17:14:00", + "value": 66 + }, + { + "time": "17:15:00", + "value": 66 + }, + { + "time": "17:16:00", + "value": 67 + }, + { + "time": "17:17:00", + "value": 71 + }, + { + "time": "17:18:00", + "value": 72 + }, + { + "time": "17:19:00", + "value": 71 + }, + { + "time": "17:20:00", + "value": 70 + }, + { + "time": "17:21:00", + "value": 69 + }, + { + "time": "17:22:00", + "value": 73 + }, + { + "time": "17:23:00", + "value": 68 + }, + { + "time": "17:24:00", + "value": 59 + }, + { + "time": "17:25:00", + "value": 63 + }, + { + "time": "17:26:00", + "value": 66 + }, + { + "time": "17:27:00", + "value": 71 + }, + { + "time": "17:28:00", + "value": 71 + }, + { + "time": "17:29:00", + "value": 71 + }, + { + "time": "17:30:00", + "value": 69 + }, + { + "time": "17:31:00", + "value": 68 + }, + { + "time": "17:32:00", + "value": 67 + }, + { + "time": "17:33:00", + "value": 70 + }, + { + "time": "17:34:00", + "value": 70 + }, + { + "time": "17:35:00", + "value": 68 + }, + { + "time": "17:36:00", + "value": 67 + }, + { + "time": "17:37:00", + "value": 70 + }, + { + "time": "17:38:00", + "value": 70 + }, + { + "time": "17:39:00", + "value": 69 + }, + { + "time": "17:40:00", + "value": 71 + }, + { + "time": "17:41:00", + "value": 70 + }, + { + "time": "17:42:00", + "value": 67 + }, + { + "time": "17:43:00", + "value": 70 + }, + { + "time": "17:44:00", + "value": 69 + }, + { + "time": "17:45:00", + "value": 69 + }, + { + "time": "17:46:00", + "value": 68 + }, + { + "time": "17:47:00", + "value": 67 + }, + { + "time": "17:48:00", + "value": 66 + }, + { + "time": "17:49:00", + "value": 63 + }, + { + "time": "17:50:00", + "value": 70 + }, + { + "time": "17:51:00", + "value": 71 + }, + { + "time": "17:52:00", + "value": 70 + }, + { + "time": "17:53:00", + "value": 69 + }, + { + "time": "17:54:00", + "value": 71 + }, + { + "time": "17:55:00", + "value": 72 + }, + { + "time": "17:56:00", + "value": 77 + }, + { + "time": "17:57:00", + "value": 72 + }, + { + "time": "17:58:00", + "value": 70 + }, + { + "time": "17:59:00", + "value": 73 + }, + { + "time": "18:00:00", + "value": 80 + }, + { + "time": "18:01:00", + "value": 81 + }, + { + "time": "18:02:00", + "value": 80 + }, + { + "time": "18:03:00", + "value": 84 + }, + { + "time": "18:04:00", + "value": 80 + }, + { + "time": "18:05:00", + "value": 77 + }, + { + "time": "18:06:00", + "value": 69 + }, + { + "time": "18:07:00", + "value": 67 + }, + { + "time": "18:08:00", + "value": 62 + }, + { + "time": "18:09:00", + "value": 64 + }, + { + "time": "18:10:00", + "value": 61 + }, + { + "time": "18:11:00", + "value": 61 + }, + { + "time": "18:12:00", + "value": 59 + }, + { + "time": "18:13:00", + "value": 62 + }, + { + "time": "18:14:00", + "value": 65 + }, + { + "time": "18:15:00", + "value": 67 + }, + { + "time": "18:16:00", + "value": 65 + }, + { + "time": "18:17:00", + "value": 62 + }, + { + "time": "18:18:00", + "value": 61 + }, + { + "time": "18:19:00", + "value": 60 + }, + { + "time": "18:20:00", + "value": 65 + }, + { + "time": "18:21:00", + "value": 63 + }, + { + "time": "18:22:00", + "value": 59 + }, + { + "time": "18:23:00", + "value": 65 + }, + { + "time": "18:24:00", + "value": 68 + }, + { + "time": "18:25:00", + "value": 64 + }, + { + "time": "18:26:00", + "value": 64 + }, + { + "time": "18:27:00", + "value": 67 + }, + { + "time": "18:28:00", + "value": 67 + }, + { + "time": "18:29:00", + "value": 68 + }, + { + "time": "18:30:00", + "value": 70 + }, + { + "time": "18:31:00", + "value": 68 + }, + { + "time": "18:32:00", + "value": 67 + }, + { + "time": "18:33:00", + "value": 67 + }, + { + "time": "18:34:00", + "value": 67 + }, + { + "time": "18:35:00", + "value": 68 + }, + { + "time": "18:36:00", + "value": 68 + }, + { + "time": "18:37:00", + "value": 67 + }, + { + "time": "18:38:00", + "value": 71 + }, + { + "time": "18:39:00", + "value": 72 + }, + { + "time": "18:40:00", + "value": 76 + }, + { + "time": "18:41:00", + "value": 79 + }, + { + "time": "18:42:00", + "value": 90 + }, + { + "time": "18:43:00", + "value": 101 + }, + { + "time": "18:44:00", + "value": 104 + }, + { + "time": "18:45:00", + "value": 99 + }, + { + "time": "18:46:00", + "value": 101 + }, + { + "time": "18:47:00", + "value": 108 + }, + { + "time": "18:48:00", + "value": 108 + }, + { + "time": "18:49:00", + "value": 109 + }, + { + "time": "18:50:00", + "value": 113 + }, + { + "time": "18:51:00", + "value": 112 + }, + { + "time": "18:52:00", + "value": 113 + }, + { + "time": "18:53:00", + "value": 108 + }, + { + "time": "18:54:00", + "value": 101 + }, + { + "time": "18:55:00", + "value": 87 + }, + { + "time": "18:56:00", + "value": 85 + }, + { + "time": "18:57:00", + "value": 84 + }, + { + "time": "18:58:00", + "value": 88 + }, + { + "time": "18:59:00", + "value": 92 + }, + { + "time": "19:00:00", + "value": 89 + }, + { + "time": "19:01:00", + "value": 86 + }, + { + "time": "19:02:00", + "value": 79 + }, + { + "time": "19:03:00", + "value": 67 + }, + { + "time": "19:04:00", + "value": 64 + }, + { + "time": "19:05:00", + "value": 66 + }, + { + "time": "19:06:00", + "value": 70 + }, + { + "time": "19:07:00", + "value": 70 + }, + { + "time": "19:08:00", + "value": 70 + }, + { + "time": "19:09:00", + "value": 70 + }, + { + "time": "19:10:00", + "value": 69 + }, + { + "time": "19:11:00", + "value": 70 + }, + { + "time": "19:12:00", + "value": 74 + }, + { + "time": "19:13:00", + "value": 64 + }, + { + "time": "19:14:00", + "value": 65 + }, + { + "time": "19:15:00", + "value": 67 + }, + { + "time": "19:16:00", + "value": 62 + }, + { + "time": "19:17:00", + "value": 62 + }, + { + "time": "19:18:00", + "value": 60 + }, + { + "time": "19:19:00", + "value": 61 + }, + { + "time": "19:20:00", + "value": 61 + }, + { + "time": "19:21:00", + "value": 63 + }, + { + "time": "19:22:00", + "value": 65 + }, + { + "time": "19:23:00", + "value": 61 + }, + { + "time": "19:24:00", + "value": 60 + }, + { + "time": "19:25:00", + "value": 61 + }, + { + "time": "19:26:00", + "value": 62 + }, + { + "time": "19:27:00", + "value": 62 + }, + { + "time": "19:28:00", + "value": 64 + }, + { + "time": "19:29:00", + "value": 62 + }, + { + "time": "19:30:00", + "value": 68 + }, + { + "time": "19:31:00", + "value": 64 + }, + { + "time": "19:32:00", + "value": 61 + }, + { + "time": "19:33:00", + "value": 63 + }, + { + "time": "19:34:00", + "value": 67 + }, + { + "time": "19:35:00", + "value": 65 + }, + { + "time": "19:36:00", + "value": 61 + }, + { + "time": "19:37:00", + "value": 62 + }, + { + "time": "19:38:00", + "value": 67 + }, + { + "time": "19:39:00", + "value": 68 + }, + { + "time": "19:40:00", + "value": 65 + }, + { + "time": "19:41:00", + "value": 65 + }, + { + "time": "19:42:00", + "value": 61 + }, + { + "time": "19:43:00", + "value": 61 + }, + { + "time": "19:44:00", + "value": 64 + }, + { + "time": "19:45:00", + "value": 60 + }, + { + "time": "19:46:00", + "value": 60 + }, + { + "time": "19:47:00", + "value": 61 + }, + { + "time": "19:48:00", + "value": 61 + }, + { + "time": "19:49:00", + "value": 63 + }, + { + "time": "19:50:00", + "value": 61 + }, + { + "time": "19:51:00", + "value": 59 + }, + { + "time": "19:52:00", + "value": 63 + }, + { + "time": "19:53:00", + "value": 62 + }, + { + "time": "19:54:00", + "value": 62 + }, + { + "time": "19:55:00", + "value": 62 + }, + { + "time": "19:56:00", + "value": 66 + }, + { + "time": "19:57:00", + "value": 65 + }, + { + "time": "19:58:00", + "value": 60 + }, + { + "time": "19:59:00", + "value": 63 + }, + { + "time": "20:00:00", + "value": 62 + } + ], + "datasetInterval": 1, + "datasetType": "minute" + } +} \ No newline at end of file diff --git a/Fitbit.Portable.Tests/SampleData/GetHeartRateTimeSeries.json b/Fitbit.Portable.Tests/SampleData/GetHeartRateTimeSeries.json index d177980a..40af65cf 100644 --- a/Fitbit.Portable.Tests/SampleData/GetHeartRateTimeSeries.json +++ b/Fitbit.Portable.Tests/SampleData/GetHeartRateTimeSeries.json @@ -1,3 +1,4675 @@ { - -} + "activities-heart": [ + { + "dateTime": "2017-06-29", + "value": { + "customHeartRateZones": [], + "heartRateZones": [ + { + "caloriesOut": 1693.83222, + "max": 95, + "min": 30, + "minutes": 1122, + "name": "Out of Range" + }, + { + "caloriesOut": 211.22723, + "max": 133, + "min": 95, + "minutes": 35, + "name": "Fat Burn" + }, + { + "caloriesOut": 0, + "max": 162, + "min": 133, + "minutes": 0, + "name": "Cardio" + }, + { + "caloriesOut": 0, + "max": 220, + "min": 162, + "minutes": 0, + "name": "Peak" + } + ], + "restingHeartRate": 59 + } + } + ], + "activities-heart-intraday": { + "dataset": [ + { + "time": "00:00:00", + "value": 58 + }, + { + "time": "00:01:00", + "value": 58 + }, + { + "time": "00:02:00", + "value": 56 + }, + { + "time": "00:03:00", + "value": 55 + }, + { + "time": "00:04:00", + "value": 56 + }, + { + "time": "00:05:00", + "value": 54 + }, + { + "time": "00:06:00", + "value": 55 + }, + { + "time": "00:07:00", + "value": 54 + }, + { + "time": "00:08:00", + "value": 55 + }, + { + "time": "00:09:00", + "value": 55 + }, + { + "time": "00:10:00", + "value": 58 + }, + { + "time": "00:11:00", + "value": 56 + }, + { + "time": "00:12:00", + "value": 57 + }, + { + "time": "00:13:00", + "value": 57 + }, + { + "time": "00:14:00", + "value": 56 + }, + { + "time": "00:15:00", + "value": 55 + }, + { + "time": "00:16:00", + "value": 56 + }, + { + "time": "00:17:00", + "value": 57 + }, + { + "time": "00:18:00", + "value": 56 + }, + { + "time": "00:19:00", + "value": 58 + }, + { + "time": "00:20:00", + "value": 58 + }, + { + "time": "00:21:00", + "value": 58 + }, + { + "time": "00:22:00", + "value": 58 + }, + { + "time": "00:23:00", + "value": 58 + }, + { + "time": "00:24:00", + "value": 58 + }, + { + "time": "00:25:00", + "value": 58 + }, + { + "time": "00:26:00", + "value": 60 + }, + { + "time": "00:27:00", + "value": 58 + }, + { + "time": "00:28:00", + "value": 58 + }, + { + "time": "00:29:00", + "value": 62 + }, + { + "time": "00:30:00", + "value": 59 + }, + { + "time": "00:31:00", + "value": 59 + }, + { + "time": "00:32:00", + "value": 59 + }, + { + "time": "00:33:00", + "value": 60 + }, + { + "time": "00:34:00", + "value": 59 + }, + { + "time": "00:35:00", + "value": 60 + }, + { + "time": "00:36:00", + "value": 60 + }, + { + "time": "00:37:00", + "value": 61 + }, + { + "time": "00:38:00", + "value": 62 + }, + { + "time": "00:39:00", + "value": 64 + }, + { + "time": "00:40:00", + "value": 58 + }, + { + "time": "00:41:00", + "value": 60 + }, + { + "time": "00:42:00", + "value": 61 + }, + { + "time": "00:43:00", + "value": 61 + }, + { + "time": "00:44:00", + "value": 61 + }, + { + "time": "00:45:00", + "value": 61 + }, + { + "time": "00:46:00", + "value": 63 + }, + { + "time": "00:47:00", + "value": 63 + }, + { + "time": "00:48:00", + "value": 63 + }, + { + "time": "00:49:00", + "value": 64 + }, + { + "time": "00:50:00", + "value": 62 + }, + { + "time": "00:51:00", + "value": 61 + }, + { + "time": "00:52:00", + "value": 62 + }, + { + "time": "00:53:00", + "value": 61 + }, + { + "time": "00:54:00", + "value": 61 + }, + { + "time": "00:55:00", + "value": 61 + }, + { + "time": "00:56:00", + "value": 61 + }, + { + "time": "00:57:00", + "value": 61 + }, + { + "time": "00:58:00", + "value": 61 + }, + { + "time": "00:59:00", + "value": 63 + }, + { + "time": "01:00:00", + "value": 63 + }, + { + "time": "01:01:00", + "value": 60 + }, + { + "time": "01:02:00", + "value": 66 + }, + { + "time": "01:03:00", + "value": 71 + }, + { + "time": "01:04:00", + "value": 63 + }, + { + "time": "01:05:00", + "value": 69 + }, + { + "time": "01:06:00", + "value": 62 + }, + { + "time": "01:07:00", + "value": 62 + }, + { + "time": "01:08:00", + "value": 63 + }, + { + "time": "01:09:00", + "value": 67 + }, + { + "time": "01:10:00", + "value": 61 + }, + { + "time": "01:11:00", + "value": 57 + }, + { + "time": "01:12:00", + "value": 58 + }, + { + "time": "01:13:00", + "value": 58 + }, + { + "time": "01:14:00", + "value": 55 + }, + { + "time": "01:15:00", + "value": 55 + }, + { + "time": "01:16:00", + "value": 60 + }, + { + "time": "01:17:00", + "value": 60 + }, + { + "time": "01:18:00", + "value": 59 + }, + { + "time": "01:19:00", + "value": 57 + }, + { + "time": "01:20:00", + "value": 55 + }, + { + "time": "01:21:00", + "value": 60 + }, + { + "time": "01:22:00", + "value": 57 + }, + { + "time": "01:23:00", + "value": 57 + }, + { + "time": "01:24:00", + "value": 55 + }, + { + "time": "01:25:00", + "value": 56 + }, + { + "time": "01:26:00", + "value": 57 + }, + { + "time": "01:27:00", + "value": 60 + }, + { + "time": "01:28:00", + "value": 64 + }, + { + "time": "01:29:00", + "value": 60 + }, + { + "time": "01:30:00", + "value": 62 + }, + { + "time": "01:31:00", + "value": 60 + }, + { + "time": "01:32:00", + "value": 62 + }, + { + "time": "01:33:00", + "value": 62 + }, + { + "time": "01:34:00", + "value": 63 + }, + { + "time": "01:35:00", + "value": 62 + }, + { + "time": "01:36:00", + "value": 63 + }, + { + "time": "01:37:00", + "value": 64 + }, + { + "time": "01:38:00", + "value": 62 + }, + { + "time": "01:39:00", + "value": 63 + }, + { + "time": "01:40:00", + "value": 64 + }, + { + "time": "01:41:00", + "value": 65 + }, + { + "time": "01:42:00", + "value": 66 + }, + { + "time": "01:43:00", + "value": 62 + }, + { + "time": "01:44:00", + "value": 61 + }, + { + "time": "01:45:00", + "value": 62 + }, + { + "time": "01:46:00", + "value": 64 + }, + { + "time": "01:47:00", + "value": 63 + }, + { + "time": "01:48:00", + "value": 63 + }, + { + "time": "01:49:00", + "value": 64 + }, + { + "time": "01:50:00", + "value": 64 + }, + { + "time": "01:51:00", + "value": 65 + }, + { + "time": "01:52:00", + "value": 64 + }, + { + "time": "01:53:00", + "value": 64 + }, + { + "time": "01:54:00", + "value": 64 + }, + { + "time": "01:55:00", + "value": 65 + }, + { + "time": "01:56:00", + "value": 67 + }, + { + "time": "01:57:00", + "value": 62 + }, + { + "time": "01:58:00", + "value": 63 + }, + { + "time": "01:59:00", + "value": 61 + }, + { + "time": "02:00:00", + "value": 61 + }, + { + "time": "02:01:00", + "value": 63 + }, + { + "time": "02:02:00", + "value": 62 + }, + { + "time": "02:03:00", + "value": 61 + }, + { + "time": "02:04:00", + "value": 60 + }, + { + "time": "02:05:00", + "value": 61 + }, + { + "time": "02:06:00", + "value": 61 + }, + { + "time": "02:07:00", + "value": 63 + }, + { + "time": "02:08:00", + "value": 63 + }, + { + "time": "02:09:00", + "value": 63 + }, + { + "time": "02:10:00", + "value": 65 + }, + { + "time": "02:11:00", + "value": 62 + }, + { + "time": "02:12:00", + "value": 62 + }, + { + "time": "02:13:00", + "value": 62 + }, + { + "time": "02:14:00", + "value": 60 + }, + { + "time": "02:15:00", + "value": 61 + }, + { + "time": "02:16:00", + "value": 62 + }, + { + "time": "02:17:00", + "value": 59 + }, + { + "time": "02:18:00", + "value": 60 + }, + { + "time": "02:19:00", + "value": 60 + }, + { + "time": "02:20:00", + "value": 60 + }, + { + "time": "02:21:00", + "value": 61 + }, + { + "time": "02:22:00", + "value": 61 + }, + { + "time": "02:23:00", + "value": 61 + }, + { + "time": "02:24:00", + "value": 61 + }, + { + "time": "02:25:00", + "value": 61 + }, + { + "time": "02:26:00", + "value": 61 + }, + { + "time": "02:27:00", + "value": 62 + }, + { + "time": "02:28:00", + "value": 59 + }, + { + "time": "02:29:00", + "value": 60 + }, + { + "time": "02:30:00", + "value": 61 + }, + { + "time": "02:31:00", + "value": 62 + }, + { + "time": "02:32:00", + "value": 60 + }, + { + "time": "02:33:00", + "value": 61 + }, + { + "time": "02:34:00", + "value": 61 + }, + { + "time": "02:35:00", + "value": 61 + }, + { + "time": "02:36:00", + "value": 61 + }, + { + "time": "02:37:00", + "value": 66 + }, + { + "time": "02:38:00", + "value": 68 + }, + { + "time": "02:39:00", + "value": 64 + }, + { + "time": "02:40:00", + "value": 58 + }, + { + "time": "02:41:00", + "value": 58 + }, + { + "time": "02:42:00", + "value": 57 + }, + { + "time": "02:43:00", + "value": 57 + }, + { + "time": "02:44:00", + "value": 58 + }, + { + "time": "02:45:00", + "value": 55 + }, + { + "time": "02:46:00", + "value": 59 + }, + { + "time": "02:47:00", + "value": 59 + }, + { + "time": "02:48:00", + "value": 56 + }, + { + "time": "02:49:00", + "value": 55 + }, + { + "time": "02:50:00", + "value": 58 + }, + { + "time": "02:51:00", + "value": 57 + }, + { + "time": "02:52:00", + "value": 55 + }, + { + "time": "02:53:00", + "value": 57 + }, + { + "time": "02:54:00", + "value": 61 + }, + { + "time": "02:55:00", + "value": 54 + }, + { + "time": "02:56:00", + "value": 59 + }, + { + "time": "02:57:00", + "value": 54 + }, + { + "time": "02:58:00", + "value": 56 + }, + { + "time": "02:59:00", + "value": 57 + }, + { + "time": "03:00:00", + "value": 57 + }, + { + "time": "03:01:00", + "value": 53 + }, + { + "time": "03:02:00", + "value": 54 + }, + { + "time": "03:03:00", + "value": 57 + }, + { + "time": "03:04:00", + "value": 54 + }, + { + "time": "03:05:00", + "value": 59 + }, + { + "time": "03:06:00", + "value": 59 + }, + { + "time": "03:07:00", + "value": 62 + }, + { + "time": "03:08:00", + "value": 62 + }, + { + "time": "03:09:00", + "value": 60 + }, + { + "time": "03:10:00", + "value": 68 + }, + { + "time": "03:11:00", + "value": 63 + }, + { + "time": "03:12:00", + "value": 57 + }, + { + "time": "03:13:00", + "value": 58 + }, + { + "time": "03:14:00", + "value": 57 + }, + { + "time": "03:15:00", + "value": 56 + }, + { + "time": "03:16:00", + "value": 59 + }, + { + "time": "03:17:00", + "value": 59 + }, + { + "time": "03:18:00", + "value": 58 + }, + { + "time": "03:19:00", + "value": 57 + }, + { + "time": "03:20:00", + "value": 55 + }, + { + "time": "03:21:00", + "value": 57 + }, + { + "time": "03:22:00", + "value": 57 + }, + { + "time": "03:23:00", + "value": 56 + }, + { + "time": "03:24:00", + "value": 56 + }, + { + "time": "03:25:00", + "value": 60 + }, + { + "time": "03:26:00", + "value": 58 + }, + { + "time": "03:27:00", + "value": 58 + }, + { + "time": "03:28:00", + "value": 60 + }, + { + "time": "03:29:00", + "value": 62 + }, + { + "time": "03:30:00", + "value": 58 + }, + { + "time": "03:31:00", + "value": 61 + }, + { + "time": "03:32:00", + "value": 61 + }, + { + "time": "03:33:00", + "value": 62 + }, + { + "time": "03:34:00", + "value": 61 + }, + { + "time": "03:35:00", + "value": 62 + }, + { + "time": "03:36:00", + "value": 61 + }, + { + "time": "03:37:00", + "value": 62 + }, + { + "time": "03:38:00", + "value": 61 + }, + { + "time": "03:39:00", + "value": 62 + }, + { + "time": "03:40:00", + "value": 63 + }, + { + "time": "03:41:00", + "value": 62 + }, + { + "time": "03:42:00", + "value": 64 + }, + { + "time": "03:43:00", + "value": 59 + }, + { + "time": "03:44:00", + "value": 59 + }, + { + "time": "03:45:00", + "value": 61 + }, + { + "time": "03:46:00", + "value": 61 + }, + { + "time": "03:47:00", + "value": 58 + }, + { + "time": "03:48:00", + "value": 60 + }, + { + "time": "03:49:00", + "value": 60 + }, + { + "time": "03:50:00", + "value": 61 + }, + { + "time": "03:51:00", + "value": 63 + }, + { + "time": "03:52:00", + "value": 61 + }, + { + "time": "03:53:00", + "value": 60 + }, + { + "time": "03:54:00", + "value": 58 + }, + { + "time": "03:55:00", + "value": 58 + }, + { + "time": "03:56:00", + "value": 60 + }, + { + "time": "03:57:00", + "value": 60 + }, + { + "time": "03:58:00", + "value": 61 + }, + { + "time": "03:59:00", + "value": 60 + }, + { + "time": "04:00:00", + "value": 60 + }, + { + "time": "04:01:00", + "value": 60 + }, + { + "time": "04:02:00", + "value": 60 + }, + { + "time": "04:03:00", + "value": 62 + }, + { + "time": "04:04:00", + "value": 60 + }, + { + "time": "04:05:00", + "value": 61 + }, + { + "time": "04:06:00", + "value": 61 + }, + { + "time": "04:07:00", + "value": 60 + }, + { + "time": "04:08:00", + "value": 60 + }, + { + "time": "04:09:00", + "value": 60 + }, + { + "time": "04:10:00", + "value": 60 + }, + { + "time": "04:11:00", + "value": 60 + }, + { + "time": "04:12:00", + "value": 60 + }, + { + "time": "04:13:00", + "value": 60 + }, + { + "time": "04:14:00", + "value": 59 + }, + { + "time": "04:15:00", + "value": 63 + }, + { + "time": "04:16:00", + "value": 57 + }, + { + "time": "04:17:00", + "value": 58 + }, + { + "time": "04:18:00", + "value": 58 + }, + { + "time": "04:19:00", + "value": 58 + }, + { + "time": "04:20:00", + "value": 57 + }, + { + "time": "04:21:00", + "value": 58 + }, + { + "time": "04:22:00", + "value": 58 + }, + { + "time": "04:23:00", + "value": 58 + }, + { + "time": "04:24:00", + "value": 59 + }, + { + "time": "04:25:00", + "value": 57 + }, + { + "time": "04:26:00", + "value": 56 + }, + { + "time": "04:27:00", + "value": 58 + }, + { + "time": "04:28:00", + "value": 58 + }, + { + "time": "04:29:00", + "value": 58 + }, + { + "time": "04:30:00", + "value": 59 + }, + { + "time": "04:31:00", + "value": 59 + }, + { + "time": "04:32:00", + "value": 58 + }, + { + "time": "04:33:00", + "value": 58 + }, + { + "time": "04:34:00", + "value": 59 + }, + { + "time": "04:35:00", + "value": 59 + }, + { + "time": "04:36:00", + "value": 59 + }, + { + "time": "04:37:00", + "value": 60 + }, + { + "time": "04:38:00", + "value": 60 + }, + { + "time": "04:39:00", + "value": 58 + }, + { + "time": "04:40:00", + "value": 58 + }, + { + "time": "04:41:00", + "value": 57 + }, + { + "time": "04:42:00", + "value": 60 + }, + { + "time": "04:43:00", + "value": 59 + }, + { + "time": "04:44:00", + "value": 57 + }, + { + "time": "04:45:00", + "value": 59 + }, + { + "time": "04:46:00", + "value": 59 + }, + { + "time": "04:47:00", + "value": 60 + }, + { + "time": "04:48:00", + "value": 56 + }, + { + "time": "04:49:00", + "value": 55 + }, + { + "time": "04:50:00", + "value": 58 + }, + { + "time": "04:51:00", + "value": 55 + }, + { + "time": "04:52:00", + "value": 54 + }, + { + "time": "04:53:00", + "value": 56 + }, + { + "time": "04:54:00", + "value": 56 + }, + { + "time": "04:55:00", + "value": 57 + }, + { + "time": "04:56:00", + "value": 55 + }, + { + "time": "04:57:00", + "value": 53 + }, + { + "time": "04:58:00", + "value": 58 + }, + { + "time": "04:59:00", + "value": 55 + }, + { + "time": "05:00:00", + "value": 59 + }, + { + "time": "05:01:00", + "value": 56 + }, + { + "time": "05:02:00", + "value": 56 + }, + { + "time": "05:03:00", + "value": 55 + }, + { + "time": "05:04:00", + "value": 57 + }, + { + "time": "05:05:00", + "value": 56 + }, + { + "time": "05:06:00", + "value": 56 + }, + { + "time": "05:07:00", + "value": 57 + }, + { + "time": "05:08:00", + "value": 58 + }, + { + "time": "05:09:00", + "value": 56 + }, + { + "time": "05:10:00", + "value": 56 + }, + { + "time": "05:11:00", + "value": 57 + }, + { + "time": "05:12:00", + "value": 58 + }, + { + "time": "05:13:00", + "value": 58 + }, + { + "time": "05:14:00", + "value": 58 + }, + { + "time": "05:15:00", + "value": 58 + }, + { + "time": "05:16:00", + "value": 60 + }, + { + "time": "05:17:00", + "value": 60 + }, + { + "time": "05:18:00", + "value": 63 + }, + { + "time": "05:19:00", + "value": 55 + }, + { + "time": "05:20:00", + "value": 57 + }, + { + "time": "05:21:00", + "value": 61 + }, + { + "time": "05:22:00", + "value": 57 + }, + { + "time": "05:23:00", + "value": 59 + }, + { + "time": "05:24:00", + "value": 59 + }, + { + "time": "05:25:00", + "value": 61 + }, + { + "time": "05:26:00", + "value": 59 + }, + { + "time": "05:27:00", + "value": 59 + }, + { + "time": "05:28:00", + "value": 60 + }, + { + "time": "05:29:00", + "value": 61 + }, + { + "time": "05:30:00", + "value": 61 + }, + { + "time": "05:31:00", + "value": 62 + }, + { + "time": "05:32:00", + "value": 62 + }, + { + "time": "05:33:00", + "value": 59 + }, + { + "time": "05:34:00", + "value": 59 + }, + { + "time": "05:35:00", + "value": 60 + }, + { + "time": "05:36:00", + "value": 60 + }, + { + "time": "05:37:00", + "value": 63 + }, + { + "time": "05:38:00", + "value": 62 + }, + { + "time": "05:39:00", + "value": 61 + }, + { + "time": "05:40:00", + "value": 62 + }, + { + "time": "05:41:00", + "value": 62 + }, + { + "time": "05:42:00", + "value": 62 + }, + { + "time": "05:43:00", + "value": 61 + }, + { + "time": "05:44:00", + "value": 62 + }, + { + "time": "05:45:00", + "value": 62 + }, + { + "time": "05:46:00", + "value": 62 + }, + { + "time": "05:47:00", + "value": 62 + }, + { + "time": "05:48:00", + "value": 63 + }, + { + "time": "05:49:00", + "value": 59 + }, + { + "time": "05:50:00", + "value": 60 + }, + { + "time": "05:51:00", + "value": 60 + }, + { + "time": "05:52:00", + "value": 61 + }, + { + "time": "05:53:00", + "value": 60 + }, + { + "time": "05:54:00", + "value": 63 + }, + { + "time": "05:55:00", + "value": 64 + }, + { + "time": "05:56:00", + "value": 60 + }, + { + "time": "05:57:00", + "value": 60 + }, + { + "time": "05:58:00", + "value": 59 + }, + { + "time": "05:59:00", + "value": 58 + }, + { + "time": "06:00:00", + "value": 57 + }, + { + "time": "06:01:00", + "value": 56 + }, + { + "time": "06:02:00", + "value": 57 + }, + { + "time": "06:03:00", + "value": 56 + }, + { + "time": "06:04:00", + "value": 56 + }, + { + "time": "06:05:00", + "value": 60 + }, + { + "time": "06:06:00", + "value": 55 + }, + { + "time": "06:07:00", + "value": 56 + }, + { + "time": "06:08:00", + "value": 55 + }, + { + "time": "06:09:00", + "value": 53 + }, + { + "time": "06:10:00", + "value": 56 + }, + { + "time": "06:11:00", + "value": 58 + }, + { + "time": "06:12:00", + "value": 61 + }, + { + "time": "06:13:00", + "value": 61 + }, + { + "time": "06:14:00", + "value": 58 + }, + { + "time": "06:15:00", + "value": 56 + }, + { + "time": "06:16:00", + "value": 57 + }, + { + "time": "06:17:00", + "value": 55 + }, + { + "time": "06:18:00", + "value": 57 + }, + { + "time": "06:19:00", + "value": 55 + }, + { + "time": "06:20:00", + "value": 60 + }, + { + "time": "06:21:00", + "value": 57 + }, + { + "time": "06:22:00", + "value": 56 + }, + { + "time": "06:23:00", + "value": 57 + }, + { + "time": "06:24:00", + "value": 57 + }, + { + "time": "06:25:00", + "value": 53 + }, + { + "time": "06:26:00", + "value": 54 + }, + { + "time": "06:27:00", + "value": 56 + }, + { + "time": "06:28:00", + "value": 54 + }, + { + "time": "06:29:00", + "value": 52 + }, + { + "time": "06:30:00", + "value": 53 + }, + { + "time": "06:31:00", + "value": 60 + }, + { + "time": "06:32:00", + "value": 60 + }, + { + "time": "06:33:00", + "value": 53 + }, + { + "time": "06:34:00", + "value": 56 + }, + { + "time": "06:35:00", + "value": 59 + }, + { + "time": "06:36:00", + "value": 59 + }, + { + "time": "06:37:00", + "value": 60 + }, + { + "time": "06:38:00", + "value": 60 + }, + { + "time": "06:39:00", + "value": 64 + }, + { + "time": "06:40:00", + "value": 64 + }, + { + "time": "06:41:00", + "value": 65 + }, + { + "time": "06:42:00", + "value": 59 + }, + { + "time": "06:43:00", + "value": 64 + }, + { + "time": "06:44:00", + "value": 62 + }, + { + "time": "06:45:00", + "value": 59 + }, + { + "time": "06:46:00", + "value": 59 + }, + { + "time": "06:47:00", + "value": 63 + }, + { + "time": "06:48:00", + "value": 75 + }, + { + "time": "06:49:00", + "value": 71 + }, + { + "time": "06:50:00", + "value": 65 + }, + { + "time": "07:00:00", + "value": 72 + }, + { + "time": "07:01:00", + "value": 78 + }, + { + "time": "07:02:00", + "value": 82 + }, + { + "time": "07:03:00", + "value": 71 + }, + { + "time": "07:04:00", + "value": 63 + }, + { + "time": "07:05:00", + "value": 63 + }, + { + "time": "07:06:00", + "value": 64 + }, + { + "time": "07:07:00", + "value": 64 + }, + { + "time": "07:08:00", + "value": 66 + }, + { + "time": "07:09:00", + "value": 71 + }, + { + "time": "07:10:00", + "value": 79 + }, + { + "time": "07:11:00", + "value": 85 + }, + { + "time": "07:12:00", + "value": 84 + }, + { + "time": "07:13:00", + "value": 83 + }, + { + "time": "07:14:00", + "value": 83 + }, + { + "time": "07:15:00", + "value": 82 + }, + { + "time": "07:16:00", + "value": 83 + }, + { + "time": "07:17:00", + "value": 86 + }, + { + "time": "07:18:00", + "value": 86 + }, + { + "time": "07:19:00", + "value": 88 + }, + { + "time": "07:20:00", + "value": 84 + }, + { + "time": "07:21:00", + "value": 90 + }, + { + "time": "07:22:00", + "value": 97 + }, + { + "time": "07:23:00", + "value": 84 + }, + { + "time": "07:24:00", + "value": 72 + }, + { + "time": "07:25:00", + "value": 71 + }, + { + "time": "07:26:00", + "value": 71 + }, + { + "time": "07:27:00", + "value": 83 + }, + { + "time": "07:28:00", + "value": 95 + }, + { + "time": "07:29:00", + "value": 109 + }, + { + "time": "07:30:00", + "value": 113 + }, + { + "time": "07:31:00", + "value": 114 + }, + { + "time": "07:32:00", + "value": 109 + }, + { + "time": "07:33:00", + "value": 120 + }, + { + "time": "07:34:00", + "value": 103 + }, + { + "time": "07:36:00", + "value": 87 + }, + { + "time": "07:37:00", + "value": 86 + }, + { + "time": "07:38:00", + "value": 86 + }, + { + "time": "07:39:00", + "value": 87 + }, + { + "time": "07:40:00", + "value": 88 + }, + { + "time": "07:41:00", + "value": 80 + }, + { + "time": "07:42:00", + "value": 80 + }, + { + "time": "07:43:00", + "value": 82 + }, + { + "time": "07:44:00", + "value": 90 + }, + { + "time": "07:45:00", + "value": 87 + }, + { + "time": "07:46:00", + "value": 86 + }, + { + "time": "07:47:00", + "value": 82 + }, + { + "time": "07:48:00", + "value": 96 + }, + { + "time": "07:49:00", + "value": 97 + }, + { + "time": "07:50:00", + "value": 100 + }, + { + "time": "07:51:00", + "value": 100 + }, + { + "time": "07:52:00", + "value": 89 + }, + { + "time": "07:53:00", + "value": 86 + }, + { + "time": "07:54:00", + "value": 79 + }, + { + "time": "07:55:00", + "value": 79 + }, + { + "time": "07:56:00", + "value": 78 + }, + { + "time": "07:57:00", + "value": 83 + }, + { + "time": "07:58:00", + "value": 90 + }, + { + "time": "07:59:00", + "value": 93 + }, + { + "time": "08:00:00", + "value": 100 + }, + { + "time": "08:01:00", + "value": 104 + }, + { + "time": "08:02:00", + "value": 104 + }, + { + "time": "08:03:00", + "value": 105 + }, + { + "time": "08:04:00", + "value": 107 + }, + { + "time": "08:05:00", + "value": 105 + }, + { + "time": "08:06:00", + "value": 102 + }, + { + "time": "08:07:00", + "value": 101 + }, + { + "time": "08:08:00", + "value": 101 + }, + { + "time": "08:42:00", + "value": 79 + }, + { + "time": "08:43:00", + "value": 75 + }, + { + "time": "08:44:00", + "value": 72 + }, + { + "time": "08:45:00", + "value": 73 + }, + { + "time": "08:46:00", + "value": 79 + }, + { + "time": "08:47:00", + "value": 66 + }, + { + "time": "08:48:00", + "value": 69 + }, + { + "time": "08:49:00", + "value": 71 + }, + { + "time": "08:50:00", + "value": 72 + }, + { + "time": "08:51:00", + "value": 75 + }, + { + "time": "08:52:00", + "value": 76 + }, + { + "time": "08:53:00", + "value": 75 + }, + { + "time": "08:54:00", + "value": 74 + }, + { + "time": "08:55:00", + "value": 72 + }, + { + "time": "08:56:00", + "value": 74 + }, + { + "time": "08:57:00", + "value": 76 + }, + { + "time": "08:58:00", + "value": 71 + }, + { + "time": "08:59:00", + "value": 69 + }, + { + "time": "09:00:00", + "value": 67 + }, + { + "time": "09:01:00", + "value": 69 + }, + { + "time": "09:02:00", + "value": 71 + }, + { + "time": "09:03:00", + "value": 72 + }, + { + "time": "09:04:00", + "value": 74 + }, + { + "time": "09:05:00", + "value": 75 + }, + { + "time": "09:06:00", + "value": 72 + }, + { + "time": "09:07:00", + "value": 70 + }, + { + "time": "09:08:00", + "value": 70 + }, + { + "time": "09:09:00", + "value": 69 + }, + { + "time": "09:10:00", + "value": 71 + }, + { + "time": "09:11:00", + "value": 73 + }, + { + "time": "09:12:00", + "value": 72 + }, + { + "time": "09:13:00", + "value": 67 + }, + { + "time": "09:14:00", + "value": 65 + }, + { + "time": "09:15:00", + "value": 73 + }, + { + "time": "09:16:00", + "value": 72 + }, + { + "time": "09:17:00", + "value": 67 + }, + { + "time": "09:18:00", + "value": 68 + }, + { + "time": "09:19:00", + "value": 73 + }, + { + "time": "09:20:00", + "value": 74 + }, + { + "time": "09:21:00", + "value": 75 + }, + { + "time": "09:22:00", + "value": 74 + }, + { + "time": "09:23:00", + "value": 74 + }, + { + "time": "09:24:00", + "value": 76 + }, + { + "time": "09:25:00", + "value": 73 + }, + { + "time": "09:26:00", + "value": 77 + }, + { + "time": "09:27:00", + "value": 77 + }, + { + "time": "09:28:00", + "value": 78 + }, + { + "time": "09:29:00", + "value": 77 + }, + { + "time": "09:30:00", + "value": 75 + }, + { + "time": "09:31:00", + "value": 74 + }, + { + "time": "09:32:00", + "value": 76 + }, + { + "time": "09:33:00", + "value": 76 + }, + { + "time": "09:34:00", + "value": 73 + }, + { + "time": "09:35:00", + "value": 73 + }, + { + "time": "09:36:00", + "value": 70 + }, + { + "time": "09:37:00", + "value": 68 + }, + { + "time": "09:38:00", + "value": 70 + }, + { + "time": "09:39:00", + "value": 68 + }, + { + "time": "09:40:00", + "value": 67 + }, + { + "time": "09:41:00", + "value": 65 + }, + { + "time": "09:42:00", + "value": 68 + }, + { + "time": "09:43:00", + "value": 71 + }, + { + "time": "09:44:00", + "value": 71 + }, + { + "time": "09:45:00", + "value": 74 + }, + { + "time": "09:46:00", + "value": 72 + }, + { + "time": "09:47:00", + "value": 74 + }, + { + "time": "09:48:00", + "value": 74 + }, + { + "time": "09:49:00", + "value": 72 + }, + { + "time": "09:50:00", + "value": 72 + }, + { + "time": "09:51:00", + "value": 73 + }, + { + "time": "09:52:00", + "value": 74 + }, + { + "time": "09:53:00", + "value": 71 + }, + { + "time": "09:54:00", + "value": 73 + }, + { + "time": "09:55:00", + "value": 73 + }, + { + "time": "09:56:00", + "value": 73 + }, + { + "time": "09:57:00", + "value": 74 + }, + { + "time": "09:58:00", + "value": 73 + }, + { + "time": "09:59:00", + "value": 74 + }, + { + "time": "10:00:00", + "value": 74 + }, + { + "time": "10:01:00", + "value": 73 + }, + { + "time": "10:02:00", + "value": 74 + }, + { + "time": "10:03:00", + "value": 72 + }, + { + "time": "10:04:00", + "value": 70 + }, + { + "time": "10:05:00", + "value": 74 + }, + { + "time": "10:06:00", + "value": 73 + }, + { + "time": "10:07:00", + "value": 75 + }, + { + "time": "10:08:00", + "value": 74 + }, + { + "time": "10:09:00", + "value": 73 + }, + { + "time": "10:10:00", + "value": 74 + }, + { + "time": "10:11:00", + "value": 74 + }, + { + "time": "10:12:00", + "value": 75 + }, + { + "time": "10:13:00", + "value": 74 + }, + { + "time": "10:14:00", + "value": 74 + }, + { + "time": "10:15:00", + "value": 74 + }, + { + "time": "10:16:00", + "value": 74 + }, + { + "time": "10:17:00", + "value": 74 + }, + { + "time": "10:18:00", + "value": 74 + }, + { + "time": "10:19:00", + "value": 75 + }, + { + "time": "10:20:00", + "value": 74 + }, + { + "time": "10:21:00", + "value": 73 + }, + { + "time": "10:22:00", + "value": 69 + }, + { + "time": "10:23:00", + "value": 67 + }, + { + "time": "10:24:00", + "value": 69 + }, + { + "time": "10:25:00", + "value": 73 + }, + { + "time": "10:26:00", + "value": 71 + }, + { + "time": "10:27:00", + "value": 67 + }, + { + "time": "10:28:00", + "value": 72 + }, + { + "time": "10:29:00", + "value": 71 + }, + { + "time": "10:30:00", + "value": 72 + }, + { + "time": "10:31:00", + "value": 71 + }, + { + "time": "10:32:00", + "value": 72 + }, + { + "time": "10:33:00", + "value": 73 + }, + { + "time": "10:34:00", + "value": 67 + }, + { + "time": "10:35:00", + "value": 67 + }, + { + "time": "10:36:00", + "value": 62 + }, + { + "time": "10:37:00", + "value": 72 + }, + { + "time": "10:38:00", + "value": 75 + }, + { + "time": "10:39:00", + "value": 74 + }, + { + "time": "10:40:00", + "value": 74 + }, + { + "time": "10:41:00", + "value": 78 + }, + { + "time": "10:42:00", + "value": 76 + }, + { + "time": "10:43:00", + "value": 75 + }, + { + "time": "10:44:00", + "value": 74 + }, + { + "time": "10:45:00", + "value": 74 + }, + { + "time": "10:46:00", + "value": 72 + }, + { + "time": "10:47:00", + "value": 72 + }, + { + "time": "10:48:00", + "value": 71 + }, + { + "time": "10:49:00", + "value": 71 + }, + { + "time": "10:50:00", + "value": 75 + }, + { + "time": "10:51:00", + "value": 78 + }, + { + "time": "10:52:00", + "value": 78 + }, + { + "time": "10:53:00", + "value": 73 + }, + { + "time": "10:54:00", + "value": 75 + }, + { + "time": "10:55:00", + "value": 69 + }, + { + "time": "10:56:00", + "value": 70 + }, + { + "time": "10:57:00", + "value": 74 + }, + { + "time": "10:58:00", + "value": 74 + }, + { + "time": "10:59:00", + "value": 70 + }, + { + "time": "11:00:00", + "value": 71 + }, + { + "time": "11:01:00", + "value": 72 + }, + { + "time": "11:02:00", + "value": 73 + }, + { + "time": "11:03:00", + "value": 76 + }, + { + "time": "11:04:00", + "value": 79 + }, + { + "time": "11:05:00", + "value": 79 + }, + { + "time": "11:06:00", + "value": 72 + }, + { + "time": "11:07:00", + "value": 74 + }, + { + "time": "11:08:00", + "value": 74 + }, + { + "time": "11:09:00", + "value": 73 + }, + { + "time": "11:10:00", + "value": 70 + }, + { + "time": "11:11:00", + "value": 78 + }, + { + "time": "11:12:00", + "value": 74 + }, + { + "time": "11:13:00", + "value": 70 + }, + { + "time": "11:14:00", + "value": 70 + }, + { + "time": "11:15:00", + "value": 68 + }, + { + "time": "11:16:00", + "value": 68 + }, + { + "time": "11:17:00", + "value": 68 + }, + { + "time": "11:18:00", + "value": 71 + }, + { + "time": "11:19:00", + "value": 70 + }, + { + "time": "11:20:00", + "value": 73 + }, + { + "time": "11:21:00", + "value": 72 + }, + { + "time": "11:22:00", + "value": 72 + }, + { + "time": "11:23:00", + "value": 70 + }, + { + "time": "11:24:00", + "value": 70 + }, + { + "time": "11:25:00", + "value": 71 + }, + { + "time": "11:26:00", + "value": 71 + }, + { + "time": "11:27:00", + "value": 73 + }, + { + "time": "11:28:00", + "value": 73 + }, + { + "time": "11:29:00", + "value": 71 + }, + { + "time": "11:30:00", + "value": 68 + }, + { + "time": "11:31:00", + "value": 63 + }, + { + "time": "11:32:00", + "value": 64 + }, + { + "time": "11:33:00", + "value": 65 + }, + { + "time": "11:34:00", + "value": 66 + }, + { + "time": "11:35:00", + "value": 68 + }, + { + "time": "11:36:00", + "value": 78 + }, + { + "time": "11:37:00", + "value": 79 + }, + { + "time": "11:38:00", + "value": 80 + }, + { + "time": "11:39:00", + "value": 75 + }, + { + "time": "11:40:00", + "value": 73 + }, + { + "time": "11:41:00", + "value": 73 + }, + { + "time": "11:42:00", + "value": 73 + }, + { + "time": "11:43:00", + "value": 73 + }, + { + "time": "11:44:00", + "value": 74 + }, + { + "time": "11:45:00", + "value": 75 + }, + { + "time": "11:46:00", + "value": 75 + }, + { + "time": "11:47:00", + "value": 74 + }, + { + "time": "11:48:00", + "value": 74 + }, + { + "time": "11:49:00", + "value": 75 + }, + { + "time": "11:50:00", + "value": 75 + }, + { + "time": "11:51:00", + "value": 75 + }, + { + "time": "11:52:00", + "value": 76 + }, + { + "time": "11:53:00", + "value": 80 + }, + { + "time": "11:54:00", + "value": 80 + }, + { + "time": "11:55:00", + "value": 79 + }, + { + "time": "11:56:00", + "value": 80 + }, + { + "time": "11:57:00", + "value": 80 + }, + { + "time": "11:58:00", + "value": 81 + }, + { + "time": "11:59:00", + "value": 86 + }, + { + "time": "12:00:00", + "value": 67 + }, + { + "time": "12:01:00", + "value": 67 + }, + { + "time": "12:02:00", + "value": 71 + }, + { + "time": "12:03:00", + "value": 69 + }, + { + "time": "12:04:00", + "value": 72 + }, + { + "time": "12:05:00", + "value": 76 + }, + { + "time": "12:06:00", + "value": 78 + }, + { + "time": "12:07:00", + "value": 71 + }, + { + "time": "12:08:00", + "value": 72 + }, + { + "time": "12:09:00", + "value": 74 + }, + { + "time": "12:10:00", + "value": 76 + }, + { + "time": "12:11:00", + "value": 77 + }, + { + "time": "12:12:00", + "value": 75 + }, + { + "time": "12:13:00", + "value": 76 + }, + { + "time": "12:14:00", + "value": 77 + }, + { + "time": "12:15:00", + "value": 78 + }, + { + "time": "12:16:00", + "value": 79 + }, + { + "time": "12:17:00", + "value": 78 + }, + { + "time": "12:18:00", + "value": 77 + }, + { + "time": "12:19:00", + "value": 77 + }, + { + "time": "12:20:00", + "value": 79 + }, + { + "time": "12:21:00", + "value": 80 + }, + { + "time": "12:22:00", + "value": 79 + }, + { + "time": "12:23:00", + "value": 76 + }, + { + "time": "12:24:00", + "value": 77 + }, + { + "time": "12:25:00", + "value": 78 + }, + { + "time": "12:26:00", + "value": 79 + }, + { + "time": "12:27:00", + "value": 77 + }, + { + "time": "12:28:00", + "value": 78 + }, + { + "time": "12:29:00", + "value": 78 + }, + { + "time": "12:30:00", + "value": 79 + }, + { + "time": "12:31:00", + "value": 77 + }, + { + "time": "12:32:00", + "value": 78 + }, + { + "time": "12:33:00", + "value": 78 + }, + { + "time": "12:34:00", + "value": 78 + }, + { + "time": "12:35:00", + "value": 77 + }, + { + "time": "12:36:00", + "value": 77 + }, + { + "time": "12:37:00", + "value": 77 + }, + { + "time": "12:38:00", + "value": 77 + }, + { + "time": "12:39:00", + "value": 76 + }, + { + "time": "12:40:00", + "value": 77 + }, + { + "time": "12:41:00", + "value": 76 + }, + { + "time": "12:42:00", + "value": 77 + }, + { + "time": "12:43:00", + "value": 77 + }, + { + "time": "12:44:00", + "value": 75 + }, + { + "time": "12:45:00", + "value": 76 + }, + { + "time": "12:46:00", + "value": 74 + }, + { + "time": "12:47:00", + "value": 77 + }, + { + "time": "12:48:00", + "value": 75 + }, + { + "time": "12:49:00", + "value": 71 + }, + { + "time": "12:50:00", + "value": 75 + }, + { + "time": "12:51:00", + "value": 76 + }, + { + "time": "12:52:00", + "value": 78 + }, + { + "time": "12:53:00", + "value": 76 + }, + { + "time": "12:54:00", + "value": 77 + }, + { + "time": "12:55:00", + "value": 76 + }, + { + "time": "12:56:00", + "value": 71 + }, + { + "time": "12:57:00", + "value": 67 + }, + { + "time": "12:58:00", + "value": 65 + }, + { + "time": "12:59:00", + "value": 66 + }, + { + "time": "13:00:00", + "value": 66 + }, + { + "time": "13:01:00", + "value": 67 + }, + { + "time": "13:02:00", + "value": 68 + }, + { + "time": "13:03:00", + "value": 69 + }, + { + "time": "13:04:00", + "value": 75 + }, + { + "time": "13:05:00", + "value": 71 + }, + { + "time": "13:06:00", + "value": 70 + }, + { + "time": "13:07:00", + "value": 74 + }, + { + "time": "13:08:00", + "value": 72 + }, + { + "time": "13:09:00", + "value": 71 + }, + { + "time": "13:10:00", + "value": 72 + }, + { + "time": "13:11:00", + "value": 70 + }, + { + "time": "13:12:00", + "value": 69 + }, + { + "time": "13:13:00", + "value": 75 + }, + { + "time": "13:14:00", + "value": 76 + }, + { + "time": "13:15:00", + "value": 76 + }, + { + "time": "13:16:00", + "value": 80 + }, + { + "time": "13:17:00", + "value": 78 + }, + { + "time": "13:18:00", + "value": 80 + }, + { + "time": "13:19:00", + "value": 79 + }, + { + "time": "13:20:00", + "value": 79 + }, + { + "time": "13:21:00", + "value": 81 + }, + { + "time": "13:22:00", + "value": 80 + }, + { + "time": "13:23:00", + "value": 79 + }, + { + "time": "13:24:00", + "value": 80 + }, + { + "time": "13:25:00", + "value": 80 + }, + { + "time": "13:26:00", + "value": 79 + }, + { + "time": "13:27:00", + "value": 77 + }, + { + "time": "13:28:00", + "value": 72 + }, + { + "time": "13:29:00", + "value": 72 + }, + { + "time": "13:30:00", + "value": 71 + }, + { + "time": "13:31:00", + "value": 76 + }, + { + "time": "13:32:00", + "value": 83 + }, + { + "time": "13:33:00", + "value": 76 + }, + { + "time": "13:34:00", + "value": 73 + }, + { + "time": "13:35:00", + "value": 73 + }, + { + "time": "13:36:00", + "value": 75 + }, + { + "time": "13:37:00", + "value": 72 + }, + { + "time": "13:38:00", + "value": 71 + }, + { + "time": "13:39:00", + "value": 71 + }, + { + "time": "13:40:00", + "value": 74 + }, + { + "time": "13:41:00", + "value": 72 + }, + { + "time": "13:42:00", + "value": 73 + }, + { + "time": "13:43:00", + "value": 72 + }, + { + "time": "13:44:00", + "value": 70 + }, + { + "time": "13:45:00", + "value": 70 + }, + { + "time": "13:46:00", + "value": 71 + }, + { + "time": "13:47:00", + "value": 74 + }, + { + "time": "13:48:00", + "value": 72 + }, + { + "time": "13:49:00", + "value": 71 + }, + { + "time": "13:50:00", + "value": 71 + }, + { + "time": "13:51:00", + "value": 75 + }, + { + "time": "13:52:00", + "value": 75 + }, + { + "time": "13:53:00", + "value": 74 + }, + { + "time": "13:54:00", + "value": 82 + }, + { + "time": "13:55:00", + "value": 90 + }, + { + "time": "13:56:00", + "value": 94 + }, + { + "time": "13:57:00", + "value": 98 + }, + { + "time": "13:58:00", + "value": 102 + }, + { + "time": "14:00:00", + "value": 75 + }, + { + "time": "14:01:00", + "value": 68 + }, + { + "time": "14:02:00", + "value": 66 + }, + { + "time": "14:03:00", + "value": 64 + }, + { + "time": "14:04:00", + "value": 62 + }, + { + "time": "14:05:00", + "value": 63 + }, + { + "time": "14:06:00", + "value": 62 + }, + { + "time": "14:07:00", + "value": 63 + }, + { + "time": "14:08:00", + "value": 64 + }, + { + "time": "14:09:00", + "value": 64 + }, + { + "time": "14:10:00", + "value": 68 + }, + { + "time": "14:11:00", + "value": 72 + }, + { + "time": "14:12:00", + "value": 70 + }, + { + "time": "14:13:00", + "value": 66 + }, + { + "time": "14:14:00", + "value": 71 + }, + { + "time": "14:15:00", + "value": 71 + }, + { + "time": "14:16:00", + "value": 73 + }, + { + "time": "14:17:00", + "value": 72 + }, + { + "time": "14:18:00", + "value": 73 + }, + { + "time": "14:19:00", + "value": 73 + }, + { + "time": "14:20:00", + "value": 73 + }, + { + "time": "14:21:00", + "value": 74 + }, + { + "time": "14:22:00", + "value": 75 + }, + { + "time": "14:23:00", + "value": 75 + }, + { + "time": "14:24:00", + "value": 75 + }, + { + "time": "14:25:00", + "value": 74 + }, + { + "time": "14:26:00", + "value": 73 + }, + { + "time": "14:27:00", + "value": 71 + }, + { + "time": "14:28:00", + "value": 70 + }, + { + "time": "14:29:00", + "value": 75 + }, + { + "time": "14:30:00", + "value": 71 + }, + { + "time": "14:31:00", + "value": 63 + }, + { + "time": "14:32:00", + "value": 66 + }, + { + "time": "14:33:00", + "value": 69 + }, + { + "time": "14:34:00", + "value": 70 + }, + { + "time": "14:35:00", + "value": 72 + }, + { + "time": "14:36:00", + "value": 67 + }, + { + "time": "14:37:00", + "value": 65 + }, + { + "time": "14:38:00", + "value": 70 + }, + { + "time": "14:39:00", + "value": 72 + }, + { + "time": "14:40:00", + "value": 68 + }, + { + "time": "14:41:00", + "value": 65 + }, + { + "time": "14:42:00", + "value": 68 + }, + { + "time": "14:43:00", + "value": 74 + }, + { + "time": "14:44:00", + "value": 75 + }, + { + "time": "14:45:00", + "value": 75 + }, + { + "time": "14:46:00", + "value": 75 + }, + { + "time": "14:47:00", + "value": 80 + }, + { + "time": "14:48:00", + "value": 81 + }, + { + "time": "14:49:00", + "value": 74 + }, + { + "time": "14:50:00", + "value": 73 + }, + { + "time": "14:51:00", + "value": 73 + }, + { + "time": "14:52:00", + "value": 78 + }, + { + "time": "14:53:00", + "value": 70 + }, + { + "time": "14:54:00", + "value": 64 + }, + { + "time": "14:55:00", + "value": 67 + }, + { + "time": "14:56:00", + "value": 71 + }, + { + "time": "14:57:00", + "value": 71 + }, + { + "time": "14:58:00", + "value": 70 + }, + { + "time": "14:59:00", + "value": 70 + }, + { + "time": "15:00:00", + "value": 68 + }, + { + "time": "15:01:00", + "value": 67 + }, + { + "time": "15:02:00", + "value": 71 + }, + { + "time": "15:03:00", + "value": 71 + }, + { + "time": "15:04:00", + "value": 65 + }, + { + "time": "15:05:00", + "value": 63 + }, + { + "time": "15:06:00", + "value": 64 + }, + { + "time": "15:07:00", + "value": 63 + }, + { + "time": "15:08:00", + "value": 72 + }, + { + "time": "15:09:00", + "value": 73 + }, + { + "time": "15:10:00", + "value": 75 + }, + { + "time": "15:11:00", + "value": 71 + }, + { + "time": "15:12:00", + "value": 71 + }, + { + "time": "15:13:00", + "value": 75 + }, + { + "time": "15:14:00", + "value": 71 + }, + { + "time": "15:15:00", + "value": 71 + }, + { + "time": "15:16:00", + "value": 73 + }, + { + "time": "15:17:00", + "value": 74 + }, + { + "time": "15:18:00", + "value": 73 + }, + { + "time": "15:19:00", + "value": 73 + }, + { + "time": "15:20:00", + "value": 70 + }, + { + "time": "15:21:00", + "value": 69 + }, + { + "time": "15:22:00", + "value": 67 + }, + { + "time": "15:23:00", + "value": 68 + }, + { + "time": "15:24:00", + "value": 66 + }, + { + "time": "15:25:00", + "value": 63 + }, + { + "time": "15:26:00", + "value": 62 + }, + { + "time": "15:27:00", + "value": 63 + }, + { + "time": "15:28:00", + "value": 74 + }, + { + "time": "15:29:00", + "value": 73 + }, + { + "time": "15:30:00", + "value": 69 + }, + { + "time": "15:31:00", + "value": 70 + }, + { + "time": "15:32:00", + "value": 73 + }, + { + "time": "15:33:00", + "value": 73 + }, + { + "time": "15:34:00", + "value": 73 + }, + { + "time": "15:35:00", + "value": 75 + }, + { + "time": "15:36:00", + "value": 74 + }, + { + "time": "15:37:00", + "value": 73 + }, + { + "time": "15:38:00", + "value": 72 + }, + { + "time": "15:39:00", + "value": 74 + }, + { + "time": "15:40:00", + "value": 73 + }, + { + "time": "15:41:00", + "value": 73 + }, + { + "time": "15:42:00", + "value": 76 + }, + { + "time": "15:43:00", + "value": 77 + }, + { + "time": "15:44:00", + "value": 77 + }, + { + "time": "15:45:00", + "value": 77 + }, + { + "time": "15:46:00", + "value": 79 + }, + { + "time": "15:47:00", + "value": 73 + }, + { + "time": "15:48:00", + "value": 70 + }, + { + "time": "15:49:00", + "value": 68 + }, + { + "time": "15:50:00", + "value": 73 + }, + { + "time": "15:51:00", + "value": 72 + }, + { + "time": "15:52:00", + "value": 69 + }, + { + "time": "15:53:00", + "value": 69 + }, + { + "time": "15:54:00", + "value": 67 + }, + { + "time": "15:55:00", + "value": 66 + }, + { + "time": "15:56:00", + "value": 65 + }, + { + "time": "15:57:00", + "value": 64 + }, + { + "time": "15:58:00", + "value": 64 + }, + { + "time": "15:59:00", + "value": 67 + }, + { + "time": "16:00:00", + "value": 68 + }, + { + "time": "16:01:00", + "value": 69 + }, + { + "time": "16:02:00", + "value": 70 + }, + { + "time": "16:03:00", + "value": 71 + }, + { + "time": "16:04:00", + "value": 71 + }, + { + "time": "16:05:00", + "value": 67 + }, + { + "time": "16:06:00", + "value": 62 + }, + { + "time": "16:07:00", + "value": 61 + }, + { + "time": "16:08:00", + "value": 70 + }, + { + "time": "16:09:00", + "value": 74 + }, + { + "time": "16:10:00", + "value": 77 + }, + { + "time": "16:11:00", + "value": 74 + }, + { + "time": "16:12:00", + "value": 74 + }, + { + "time": "16:13:00", + "value": 72 + }, + { + "time": "16:14:00", + "value": 75 + }, + { + "time": "16:15:00", + "value": 77 + }, + { + "time": "16:16:00", + "value": 76 + }, + { + "time": "16:17:00", + "value": 75 + }, + { + "time": "16:18:00", + "value": 71 + }, + { + "time": "16:19:00", + "value": 72 + }, + { + "time": "16:20:00", + "value": 73 + }, + { + "time": "16:21:00", + "value": 66 + }, + { + "time": "16:22:00", + "value": 65 + }, + { + "time": "16:23:00", + "value": 63 + }, + { + "time": "16:24:00", + "value": 68 + }, + { + "time": "16:25:00", + "value": 72 + }, + { + "time": "16:26:00", + "value": 70 + }, + { + "time": "16:27:00", + "value": 64 + }, + { + "time": "16:28:00", + "value": 67 + }, + { + "time": "16:29:00", + "value": 72 + }, + { + "time": "16:30:00", + "value": 72 + }, + { + "time": "16:31:00", + "value": 70 + }, + { + "time": "16:32:00", + "value": 67 + }, + { + "time": "16:33:00", + "value": 69 + }, + { + "time": "16:34:00", + "value": 67 + }, + { + "time": "16:35:00", + "value": 67 + }, + { + "time": "16:36:00", + "value": 67 + }, + { + "time": "16:37:00", + "value": 70 + }, + { + "time": "16:38:00", + "value": 70 + }, + { + "time": "16:39:00", + "value": 72 + }, + { + "time": "16:40:00", + "value": 69 + }, + { + "time": "16:41:00", + "value": 70 + }, + { + "time": "16:42:00", + "value": 74 + }, + { + "time": "16:43:00", + "value": 74 + }, + { + "time": "16:44:00", + "value": 74 + }, + { + "time": "16:45:00", + "value": 71 + }, + { + "time": "16:46:00", + "value": 70 + }, + { + "time": "16:47:00", + "value": 71 + }, + { + "time": "16:48:00", + "value": 74 + }, + { + "time": "16:49:00", + "value": 74 + }, + { + "time": "16:50:00", + "value": 73 + }, + { + "time": "16:51:00", + "value": 74 + }, + { + "time": "16:52:00", + "value": 73 + }, + { + "time": "16:53:00", + "value": 70 + }, + { + "time": "16:54:00", + "value": 70 + }, + { + "time": "16:55:00", + "value": 70 + }, + { + "time": "16:56:00", + "value": 70 + }, + { + "time": "16:57:00", + "value": 74 + }, + { + "time": "16:58:00", + "value": 70 + }, + { + "time": "16:59:00", + "value": 67 + }, + { + "time": "17:00:00", + "value": 64 + }, + { + "time": "17:01:00", + "value": 60 + }, + { + "time": "17:02:00", + "value": 68 + }, + { + "time": "17:03:00", + "value": 70 + }, + { + "time": "17:04:00", + "value": 70 + }, + { + "time": "17:05:00", + "value": 69 + }, + { + "time": "17:06:00", + "value": 64 + }, + { + "time": "17:07:00", + "value": 63 + }, + { + "time": "17:08:00", + "value": 66 + }, + { + "time": "17:09:00", + "value": 66 + }, + { + "time": "17:10:00", + "value": 65 + }, + { + "time": "17:11:00", + "value": 68 + }, + { + "time": "17:12:00", + "value": 70 + }, + { + "time": "17:13:00", + "value": 70 + }, + { + "time": "17:14:00", + "value": 66 + }, + { + "time": "17:15:00", + "value": 66 + }, + { + "time": "17:16:00", + "value": 67 + }, + { + "time": "17:17:00", + "value": 71 + }, + { + "time": "17:18:00", + "value": 72 + }, + { + "time": "17:19:00", + "value": 71 + }, + { + "time": "17:20:00", + "value": 70 + }, + { + "time": "17:21:00", + "value": 69 + }, + { + "time": "17:22:00", + "value": 73 + }, + { + "time": "17:23:00", + "value": 68 + }, + { + "time": "17:24:00", + "value": 59 + }, + { + "time": "17:25:00", + "value": 63 + }, + { + "time": "17:26:00", + "value": 66 + }, + { + "time": "17:27:00", + "value": 71 + }, + { + "time": "17:28:00", + "value": 71 + }, + { + "time": "17:29:00", + "value": 71 + }, + { + "time": "17:30:00", + "value": 69 + }, + { + "time": "17:31:00", + "value": 68 + }, + { + "time": "17:32:00", + "value": 67 + }, + { + "time": "17:33:00", + "value": 70 + }, + { + "time": "17:34:00", + "value": 70 + }, + { + "time": "17:35:00", + "value": 68 + }, + { + "time": "17:36:00", + "value": 67 + }, + { + "time": "17:37:00", + "value": 70 + }, + { + "time": "17:38:00", + "value": 70 + }, + { + "time": "17:39:00", + "value": 69 + }, + { + "time": "17:40:00", + "value": 71 + }, + { + "time": "17:41:00", + "value": 70 + }, + { + "time": "17:42:00", + "value": 67 + }, + { + "time": "17:43:00", + "value": 70 + }, + { + "time": "17:44:00", + "value": 69 + }, + { + "time": "17:45:00", + "value": 69 + }, + { + "time": "17:46:00", + "value": 68 + }, + { + "time": "17:47:00", + "value": 67 + }, + { + "time": "17:48:00", + "value": 66 + }, + { + "time": "17:49:00", + "value": 63 + }, + { + "time": "17:50:00", + "value": 70 + }, + { + "time": "17:51:00", + "value": 71 + }, + { + "time": "17:52:00", + "value": 70 + }, + { + "time": "17:53:00", + "value": 69 + }, + { + "time": "17:54:00", + "value": 71 + }, + { + "time": "17:55:00", + "value": 72 + }, + { + "time": "17:56:00", + "value": 77 + }, + { + "time": "17:57:00", + "value": 72 + }, + { + "time": "17:58:00", + "value": 70 + }, + { + "time": "17:59:00", + "value": 73 + }, + { + "time": "18:00:00", + "value": 80 + }, + { + "time": "18:01:00", + "value": 81 + }, + { + "time": "18:02:00", + "value": 80 + }, + { + "time": "18:03:00", + "value": 84 + }, + { + "time": "18:04:00", + "value": 80 + }, + { + "time": "18:05:00", + "value": 77 + }, + { + "time": "18:06:00", + "value": 69 + }, + { + "time": "18:07:00", + "value": 67 + }, + { + "time": "18:08:00", + "value": 62 + }, + { + "time": "18:09:00", + "value": 64 + }, + { + "time": "18:10:00", + "value": 61 + }, + { + "time": "18:11:00", + "value": 61 + }, + { + "time": "18:12:00", + "value": 59 + }, + { + "time": "18:13:00", + "value": 62 + }, + { + "time": "18:14:00", + "value": 65 + }, + { + "time": "18:15:00", + "value": 67 + }, + { + "time": "18:16:00", + "value": 65 + }, + { + "time": "18:17:00", + "value": 62 + }, + { + "time": "18:18:00", + "value": 61 + }, + { + "time": "18:19:00", + "value": 60 + }, + { + "time": "18:20:00", + "value": 65 + }, + { + "time": "18:21:00", + "value": 63 + }, + { + "time": "18:22:00", + "value": 59 + }, + { + "time": "18:23:00", + "value": 65 + }, + { + "time": "18:24:00", + "value": 68 + }, + { + "time": "18:25:00", + "value": 64 + }, + { + "time": "18:26:00", + "value": 64 + }, + { + "time": "18:27:00", + "value": 67 + }, + { + "time": "18:28:00", + "value": 67 + }, + { + "time": "18:29:00", + "value": 68 + }, + { + "time": "18:30:00", + "value": 70 + }, + { + "time": "18:31:00", + "value": 68 + }, + { + "time": "18:32:00", + "value": 67 + }, + { + "time": "18:33:00", + "value": 67 + }, + { + "time": "18:34:00", + "value": 67 + }, + { + "time": "18:35:00", + "value": 68 + }, + { + "time": "18:36:00", + "value": 68 + }, + { + "time": "18:37:00", + "value": 67 + }, + { + "time": "18:38:00", + "value": 71 + }, + { + "time": "18:39:00", + "value": 72 + }, + { + "time": "18:40:00", + "value": 76 + }, + { + "time": "18:41:00", + "value": 79 + }, + { + "time": "18:42:00", + "value": 90 + }, + { + "time": "18:43:00", + "value": 101 + }, + { + "time": "18:44:00", + "value": 104 + }, + { + "time": "18:45:00", + "value": 99 + }, + { + "time": "18:46:00", + "value": 101 + }, + { + "time": "18:47:00", + "value": 108 + }, + { + "time": "18:48:00", + "value": 108 + }, + { + "time": "18:49:00", + "value": 109 + }, + { + "time": "18:50:00", + "value": 113 + }, + { + "time": "18:51:00", + "value": 112 + }, + { + "time": "18:52:00", + "value": 113 + }, + { + "time": "18:53:00", + "value": 108 + }, + { + "time": "18:54:00", + "value": 101 + }, + { + "time": "18:55:00", + "value": 87 + }, + { + "time": "18:56:00", + "value": 85 + }, + { + "time": "18:57:00", + "value": 84 + }, + { + "time": "18:58:00", + "value": 88 + }, + { + "time": "18:59:00", + "value": 92 + }, + { + "time": "19:00:00", + "value": 89 + }, + { + "time": "19:01:00", + "value": 86 + }, + { + "time": "19:02:00", + "value": 79 + }, + { + "time": "19:03:00", + "value": 67 + }, + { + "time": "19:04:00", + "value": 64 + }, + { + "time": "19:05:00", + "value": 66 + }, + { + "time": "19:06:00", + "value": 70 + }, + { + "time": "19:07:00", + "value": 70 + }, + { + "time": "19:08:00", + "value": 70 + }, + { + "time": "19:09:00", + "value": 70 + }, + { + "time": "19:10:00", + "value": 69 + }, + { + "time": "19:11:00", + "value": 70 + }, + { + "time": "19:12:00", + "value": 74 + }, + { + "time": "19:13:00", + "value": 64 + }, + { + "time": "19:14:00", + "value": 65 + }, + { + "time": "19:15:00", + "value": 67 + }, + { + "time": "19:16:00", + "value": 62 + }, + { + "time": "19:17:00", + "value": 62 + }, + { + "time": "19:18:00", + "value": 60 + }, + { + "time": "19:19:00", + "value": 61 + }, + { + "time": "19:20:00", + "value": 61 + }, + { + "time": "19:21:00", + "value": 63 + }, + { + "time": "19:22:00", + "value": 65 + }, + { + "time": "19:23:00", + "value": 61 + }, + { + "time": "19:24:00", + "value": 60 + }, + { + "time": "19:25:00", + "value": 61 + }, + { + "time": "19:26:00", + "value": 62 + }, + { + "time": "19:27:00", + "value": 62 + }, + { + "time": "19:28:00", + "value": 64 + }, + { + "time": "19:29:00", + "value": 62 + }, + { + "time": "19:30:00", + "value": 68 + }, + { + "time": "19:31:00", + "value": 64 + }, + { + "time": "19:32:00", + "value": 61 + }, + { + "time": "19:33:00", + "value": 63 + }, + { + "time": "19:34:00", + "value": 67 + }, + { + "time": "19:35:00", + "value": 65 + }, + { + "time": "19:36:00", + "value": 61 + }, + { + "time": "19:37:00", + "value": 62 + }, + { + "time": "19:38:00", + "value": 67 + }, + { + "time": "19:39:00", + "value": 68 + }, + { + "time": "19:40:00", + "value": 65 + }, + { + "time": "19:41:00", + "value": 65 + }, + { + "time": "19:42:00", + "value": 61 + }, + { + "time": "19:43:00", + "value": 61 + }, + { + "time": "19:44:00", + "value": 64 + }, + { + "time": "19:45:00", + "value": 60 + }, + { + "time": "19:46:00", + "value": 60 + }, + { + "time": "19:47:00", + "value": 61 + }, + { + "time": "19:48:00", + "value": 61 + }, + { + "time": "19:49:00", + "value": 63 + }, + { + "time": "19:50:00", + "value": 61 + }, + { + "time": "19:51:00", + "value": 59 + }, + { + "time": "19:52:00", + "value": 63 + }, + { + "time": "19:53:00", + "value": 62 + }, + { + "time": "19:54:00", + "value": 62 + }, + { + "time": "19:55:00", + "value": 62 + }, + { + "time": "19:56:00", + "value": 66 + }, + { + "time": "19:57:00", + "value": 65 + }, + { + "time": "19:58:00", + "value": 60 + }, + { + "time": "19:59:00", + "value": 63 + }, + { + "time": "20:00:00", + "value": 62 + } + ], + "datasetInterval": 1, + "datasetType": "minute" + } +} \ No newline at end of file From 09dc2f7f021a3843c28891869957cdf5c351a041 Mon Sep 17 00:00:00 2001 From: bdrupieski Date: Mon, 24 Jul 2017 08:02:22 -0400 Subject: [PATCH 06/85] add heart rate methods to IFitBitClient interface --- Fitbit.Portable/FitbitClient.cs | 10 +--------- Fitbit.Portable/IFitbitClient.cs | 2 ++ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 1b303221..2ca91a5f 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -137,7 +137,7 @@ public FitbitClient(Func customFactory, IFitbitI private void ConfigureTokenManager(ITokenManager tokenManager) { TokenManager = tokenManager ?? new DefaultTokenManager(); - } + } private void CreateHttpClientForOAuth2() { @@ -386,8 +386,6 @@ public async Task> GetDevicesAsync() return serializer.GetFriends(responseBody); } - - /// /// Request to get heart rate in specific in a range time /// @@ -415,7 +413,6 @@ public async Task GetHeartRateTimeSeries(DateTime dat return fitbitResponse; } - /// /// Request to get heart rate in a day /// @@ -445,11 +442,6 @@ public async Task GetHeartRateIntraday(DateTime date, H return seralizer.GetHeartRateIntraday(date, responseBody); } - - - - - /// /// Requests the user profile of the encoded user id or if none specified the current logged in user /// diff --git a/Fitbit.Portable/IFitbitClient.cs b/Fitbit.Portable/IFitbitClient.cs index 6d97ef56..80d89719 100644 --- a/Fitbit.Portable/IFitbitClient.cs +++ b/Fitbit.Portable/IFitbitClient.cs @@ -18,6 +18,8 @@ public interface IFitbitClient Task PostLogSleepAsync(string startTime, int duration, DateTime date, string encodedUserId = default(string)); Task> GetDevicesAsync(); Task> GetFriendsAsync(string encodedUserId = default(string)); + Task GetHeartRateTimeSeries(DateTime date, DateRangePeriod dateRangePeriod, string userId = null); + Task GetHeartRateIntraday(DateTime date, HeartRateResolution resolution); Task GetUserProfileAsync(string encodedUserId = default(string)); Task GetTimeSeriesAsync(TimeSeriesResourceType timeSeriesResourceType, DateTime startDate, DateTime endDate, string encodedUserId = default(string)); Task GetTimeSeriesAsync(TimeSeriesResourceType timeSeriesResourceType, DateTime endDate, DateRangePeriod period, string encodedUserId = default(string)); From 57814914fdf0553086f43a59f58c307c6422c46f Mon Sep 17 00:00:00 2001 From: Alex Ghiondea Date: Wed, 26 Jul 2017 21:12:22 -0700 Subject: [PATCH 07/85] Update the version for the NUnit framework used to test Updated all the tests that check exception to the new model for validating exceptions. --- Fitbit.Portable.Tests/ActivitiesStatsTests.cs | 3 +- Fitbit.Portable.Tests/AddSubscriptionTests.cs | 29 ++-- Fitbit.Portable.Tests/BloodPressureTests.cs | 2 +- Fitbit.Portable.Tests/BodyMeasurementTests.cs | 2 +- Fitbit.Portable.Tests/DayActivityTests.cs | 4 +- Fitbit.Portable.Tests/DeviceTests.cs | 4 +- Fitbit.Portable.Tests/FatTests.cs | 137 +++++++++++------- .../Fitbit.Portable.Tests.csproj | 73 ++++------ Fitbit.Portable.Tests/FoodTests.cs | 2 +- Fitbit.Portable.Tests/FriendsTests.cs | 109 ++++++++------ Fitbit.Portable.Tests/GoalsTests.cs | 21 +-- .../FitbitHttpErrorHandlerTests.cs | 12 +- .../IntradayTimeSeriesTests.cs | 7 +- Fitbit.Portable.Tests/SleepTests.cs | 4 +- .../TimeSeriesDataListIntTests.cs | 27 ++-- .../TimeSeriesDataListTests.cs | 12 +- Fitbit.Portable.Tests/UserProfileTests.cs | 2 +- Fitbit.Portable.Tests/WaterTests.cs | 6 +- Fitbit.Portable.Tests/WeightTests.cs | 134 +++++++++++------ Fitbit.Portable.Tests/app.config | 10 +- Fitbit.Portable.Tests/packages.config | 15 +- Fitbit.Portable/Fitbit.Portable.csproj | 33 +++-- Fitbit.Portable/app.config | 4 +- Fitbit.Portable/packages.config | 6 +- 24 files changed, 380 insertions(+), 278 deletions(-) diff --git a/Fitbit.Portable.Tests/ActivitiesStatsTests.cs b/Fitbit.Portable.Tests/ActivitiesStatsTests.cs index 0914ee1b..85d90848 100644 --- a/Fitbit.Portable.Tests/ActivitiesStatsTests.cs +++ b/Fitbit.Portable.Tests/ActivitiesStatsTests.cs @@ -6,6 +6,7 @@ using Fitbit.Models; using FluentAssertions; using NUnit.Framework; +using System.Threading.Tasks; namespace Fitbit.Portable.Tests { @@ -13,7 +14,7 @@ public class ActivitiesStatsTests { [Test] [Category("Portable")] - public async void GetActivityStatsAsync_Success() + public async Task GetActivityStatsAsync_Success() { string content = SampleDataHelper.GetContent("ActivitiesStats.json"); diff --git a/Fitbit.Portable.Tests/AddSubscriptionTests.cs b/Fitbit.Portable.Tests/AddSubscriptionTests.cs index 0571a858..67072319 100644 --- a/Fitbit.Portable.Tests/AddSubscriptionTests.cs +++ b/Fitbit.Portable.Tests/AddSubscriptionTests.cs @@ -7,6 +7,7 @@ using Fitbit.Api.Portable; using Fitbit.Models; using NUnit.Framework; +using System.Threading.Tasks; namespace Fitbit.Portable.Tests { @@ -26,7 +27,7 @@ public class AddSubscriptionTests [Test] [Category("PubSub")] [Category("Portable")] - public async void AddSubscription_UserEndPoint_WithoutSubscriberId() + public async Task AddSubscription_UserEndPoint_WithoutSubscriberId() { Action additionalChecks = message => { @@ -42,7 +43,7 @@ public async void AddSubscription_UserEndPoint_WithoutSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_UserEndPoint_WithSubscriberId() + public async Task AddSubscription_UserEndPoint_WithSubscriberId() { Action additionalChecks = message => { @@ -64,7 +65,7 @@ public async void AddSubscription_UserEndPoint_WithSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_ActivitiesEndPoint_WithoutSubscriberId() + public async Task AddSubscription_ActivitiesEndPoint_WithoutSubscriberId() { Action additionalChecks = message => { @@ -80,7 +81,7 @@ public async void AddSubscription_ActivitiesEndPoint_WithoutSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_ActivitiesEndPoint_WithSubscriberId() + public async Task AddSubscription_ActivitiesEndPoint_WithSubscriberId() { Action additionalChecks = message => { @@ -102,7 +103,7 @@ public async void AddSubscription_ActivitiesEndPoint_WithSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_BodyEndPoint_WithoutSubscriberId() + public async Task AddSubscription_BodyEndPoint_WithoutSubscriberId() { Action additionalChecks = message => { @@ -118,7 +119,7 @@ public async void AddSubscription_BodyEndPoint_WithoutSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_BodyEndPoint_WithSubscriberId() + public async Task AddSubscription_BodyEndPoint_WithSubscriberId() { Action additionalChecks = message => { @@ -140,7 +141,7 @@ public async void AddSubscription_BodyEndPoint_WithSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_FoodEndPoint_WithoutSubscriberId() + public async Task AddSubscription_FoodEndPoint_WithoutSubscriberId() { Action additionalChecks = message => { @@ -156,7 +157,7 @@ public async void AddSubscription_FoodEndPoint_WithoutSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_FoodEndPoint_WithSubscriberId() + public async Task AddSubscription_FoodEndPoint_WithSubscriberId() { Action additionalChecks = message => { @@ -178,7 +179,7 @@ public async void AddSubscription_FoodEndPoint_WithSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_MealsEndPoint_WithoutSubscriberId() + public async Task AddSubscription_MealsEndPoint_WithoutSubscriberId() { Action additionalChecks = message => { @@ -194,7 +195,7 @@ public async void AddSubscription_MealsEndPoint_WithoutSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_MealsEndPoint_WithSubscriberId() + public async Task AddSubscription_MealsEndPoint_WithSubscriberId() { Action additionalChecks = message => { @@ -216,7 +217,7 @@ public async void AddSubscription_MealsEndPoint_WithSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_SleepEndPoint_WithoutSubscriberId() + public async Task AddSubscription_SleepEndPoint_WithoutSubscriberId() { Action additionalChecks = message => { @@ -232,7 +233,7 @@ public async void AddSubscription_SleepEndPoint_WithoutSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_SleepEndPoint_WithSubscriberId() + public async Task AddSubscription_SleepEndPoint_WithSubscriberId() { Action additionalChecks = message => { @@ -254,7 +255,7 @@ public async void AddSubscription_SleepEndPoint_WithSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_WeightEndPoint_WithoutSubscriberId() + public async Task AddSubscription_WeightEndPoint_WithoutSubscriberId() { Action additionalChecks = message => { @@ -270,7 +271,7 @@ public async void AddSubscription_WeightEndPoint_WithoutSubscriberId() [Category("PubSub")] [Test] [Category("Portable")] - public async void AddSubscription_WeightEndPoint_WithSubscriberId() + public async Task AddSubscription_WeightEndPoint_WithSubscriberId() { Action additionalChecks = message => { diff --git a/Fitbit.Portable.Tests/BloodPressureTests.cs b/Fitbit.Portable.Tests/BloodPressureTests.cs index 33b09c09..a259248c 100644 --- a/Fitbit.Portable.Tests/BloodPressureTests.cs +++ b/Fitbit.Portable.Tests/BloodPressureTests.cs @@ -15,7 +15,7 @@ namespace Fitbit.Portable.Tests public class BloodPressureTests { [Test] [Category("Portable")] - public async void GetBloodPressureAsync_Success() + public async Task GetBloodPressureAsync_Success() { string content = SampleDataHelper.GetContent("GetBloodPressure.json"); diff --git a/Fitbit.Portable.Tests/BodyMeasurementTests.cs b/Fitbit.Portable.Tests/BodyMeasurementTests.cs index 559c4d79..b5bf4e68 100644 --- a/Fitbit.Portable.Tests/BodyMeasurementTests.cs +++ b/Fitbit.Portable.Tests/BodyMeasurementTests.cs @@ -14,7 +14,7 @@ namespace Fitbit.Portable.Tests public class BodyMeasurementTests { [Test] [Category("Portable")] - public async void GetBodyMeasurementsAsync_Success() + public async Task GetBodyMeasurementsAsync_Success() { string content = SampleDataHelper.GetContent("GetBodyMeasurements.json"); diff --git a/Fitbit.Portable.Tests/DayActivityTests.cs b/Fitbit.Portable.Tests/DayActivityTests.cs index 3cafc3da..114b76cb 100644 --- a/Fitbit.Portable.Tests/DayActivityTests.cs +++ b/Fitbit.Portable.Tests/DayActivityTests.cs @@ -15,7 +15,7 @@ namespace Fitbit.Portable.Tests public class DayActivityTests { [Test] [Category("Portable")] - public async void GetDayActivityAsync_Success() + public async Task GetDayActivityAsync_Success() { string content = SampleDataHelper.GetContent("GetActivities.json"); @@ -54,7 +54,7 @@ public void GetDayActivityAsync_Errors() } [Test] [Category("Portable")] - public async void GetDayActivitySummaryAsync_Success() + public async Task GetDayActivitySummaryAsync_Success() { string content = SampleDataHelper.GetContent("GetActivities.json"); diff --git a/Fitbit.Portable.Tests/DeviceTests.cs b/Fitbit.Portable.Tests/DeviceTests.cs index ddf33515..382b446a 100644 --- a/Fitbit.Portable.Tests/DeviceTests.cs +++ b/Fitbit.Portable.Tests/DeviceTests.cs @@ -16,7 +16,7 @@ namespace Fitbit.Portable.Tests public class DeviceTests { [Test] [Category("Portable")] - public async void GetDevicesAsync_Success() + public async Task GetDevicesAsync_Success() { string content = SampleDataHelper.GetContent("GetDevices-Single.json"); @@ -41,7 +41,7 @@ public async void GetDevicesAsync_Success() } [Test] [Category("Portable")] - public async void GetDevicesAsync_Success_Mulitiple() + public async Task GetDevicesAsync_Success_Mulitiple() { string content = SampleDataHelper.GetContent("GetDevices-Double.json"); diff --git a/Fitbit.Portable.Tests/FatTests.cs b/Fitbit.Portable.Tests/FatTests.cs index 66c0fecc..67468dc5 100644 --- a/Fitbit.Portable.Tests/FatTests.cs +++ b/Fitbit.Portable.Tests/FatTests.cs @@ -7,6 +7,7 @@ using Fitbit.Models; using NUnit.Framework; using Ploeh.AutoFixture; +using System.Threading.Tasks; namespace Fitbit.Portable.Tests { @@ -21,143 +22,173 @@ public void Init() fixture = new Fixture(); } - [Test] [Category("Portable")] - [ExpectedException(typeof(ArgumentException))] - public async void GetFatAsync_DateRangePeriod_ThreeMonths() + [Test] + [Category("Portable")] + public void GetFatAsync_DateRangePeriod_ThreeMonths() { var client = fixture.Create(); - await client.GetFatAsync(DateTime.Now, DateRangePeriod.ThreeMonths); + + Assert.That(new AsyncTestDelegate(async () => await client.GetFatAsync(DateTime.Now, DateRangePeriod.ThreeMonths)), Throws.ArgumentException); } - [Test] [Category("Portable")] - [ExpectedException(typeof(ArgumentException))] - public async void GetFatAsync_DateRangePeriod_SixMonths() + [Test] + [Category("Portable")] + public async Task GetFatAsync_DateRangePeriod_SixMonths() { var client = fixture.Create(); - await client.GetFatAsync(DateTime.Now, DateRangePeriod.SixMonths); + Assert.That( + new AsyncTestDelegate(async () => await client.GetFatAsync(DateTime.Now, DateRangePeriod.SixMonths)), + Throws.ArgumentException + ); } - [Test] [Category("Portable")] - [ExpectedException(typeof(ArgumentException))] - public async void GetFatAsync_DateRangePeriod_OneYear() + [Test] + [Category("Portable")] + public void GetFatAsync_DateRangePeriod_OneYear() { var client = fixture.Create(); - await client.GetFatAsync(DateTime.Now, DateRangePeriod.OneYear); + Assert.That( + new AsyncTestDelegate(async () => await client.GetFatAsync(DateTime.Now, DateRangePeriod.OneYear)), + Throws.ArgumentException + ); } - [Test] [Category("Portable")] - [ExpectedException(typeof(ArgumentException))] - public async void GetFatAsync_DateRangePeriod_Max() + [Test] + [Category("Portable")] + public void GetFatAsync_DateRangePeriod_Max() { var client = fixture.Create(); - await client.GetFatAsync(DateTime.Now, DateRangePeriod.Max); + Assert.That(new AsyncTestDelegate(async () => await client.GetFatAsync(DateTime.Now, DateRangePeriod.Max)), + Throws.ArgumentException + ); } - [Test] [Category("Portable")] - public async void GetFatAsync_OneDay_Success() + [Test] + [Category("Portable")] + public async Task GetFatAsync_OneDay_Success() { var fitbitClient = SetupFitbitClient("https://api.fitbit.com/1/user/-/body/log/fat/date/2012-03-05/1d.json"); var response = await fitbitClient.GetFatAsync(new DateTime(2012, 3, 5), DateRangePeriod.OneDay); - + ValidateFat(response); } - [Test] [Category("Portable")] - public async void GetFatAsync_SevenDay_Success() + [Test] + [Category("Portable")] + public async Task GetFatAsync_SevenDay_Success() { var fitbitClient = SetupFitbitClient("https://api.fitbit.com/1/user/-/body/log/fat/date/2012-03-05/7d.json"); var response = await fitbitClient.GetFatAsync(new DateTime(2012, 3, 5), DateRangePeriod.SevenDays); - + ValidateFat(response); } - [Test] [Category("Portable")] - public async void GetFatAsync_OneWeek_Success() + [Test] + [Category("Portable")] + public async Task GetFatAsync_OneWeek_Success() { var fitbitClient = SetupFitbitClient("https://api.fitbit.com/1/user/-/body/log/fat/date/2012-03-05/1w.json"); var response = await fitbitClient.GetFatAsync(new DateTime(2012, 3, 5), DateRangePeriod.OneWeek); - + ValidateFat(response); } - [Test] [Category("Portable")] - public async void GetFatAsync_ThirtyDays_Success() + [Test] + [Category("Portable")] + public async Task GetFatAsync_ThirtyDays_Success() { var fitbitClient = SetupFitbitClient("https://api.fitbit.com/1/user/-/body/log/fat/date/2012-03-05/30d.json"); var response = await fitbitClient.GetFatAsync(new DateTime(2012, 3, 5), DateRangePeriod.ThirtyDays); - + ValidateFat(response); } - [Test] [Category("Portable")] - public async void GetFatAsync_OneMonth_Success() + [Test] + [Category("Portable")] + public async Task GetFatAsync_OneMonth_Success() { var fitbitClient = SetupFitbitClient("https://api.fitbit.com/1/user/-/body/log/fat/date/2012-03-05/1m.json"); var response = await fitbitClient.GetFatAsync(new DateTime(2012, 3, 5), DateRangePeriod.OneMonth); - + ValidateFat(response); } - [Test] [Category("Portable")] - public async void GetFatAsync_Success() + [Test] + [Category("Portable")] + public async Task GetFatAsync_Success() { var fitbitClient = SetupFitbitClient("https://api.fitbit.com/1/user/-/body/log/fat/date/2012-03-05.json"); var response = await fitbitClient.GetFatAsync(new DateTime(2012, 3, 5)); - + ValidateFat(response); } - [Test] [Category("Portable")] - public async void GetFatAsync_TimeSpan_Success() + [Test] + [Category("Portable")] + public async Task GetFatAsync_TimeSpan_Success() { var fitbitClient = SetupFitbitClient("https://api.fitbit.com/1/user/-/body/log/fat/date/2012-03-05/2012-03-06.json"); var response = await fitbitClient.GetFatAsync(new DateTime(2012, 3, 5), new DateTime(2012, 3, 6)); - + ValidateFat(response); } - [Test] [Category("Portable")] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public async void GetFatAsync_DateRange_Span_Too_Large() + [Test] + [Category("Portable")] + public void GetFatAsync_DateRange_Span_Too_Large() { var fitbitClient = Helper.CreateFitbitClient(() => new HttpResponseMessage(), (r, c) => { }); var basedate = DateTime.Now; - - await fitbitClient.GetFatAsync(basedate.AddDays(-35), basedate); + + Assert.That( + new AsyncTestDelegate(async () => await fitbitClient.GetFatAsync(basedate.AddDays(-35), basedate)), + Throws.InstanceOf() + ); + } - [Test] [Category("Portable")] - [ExpectedException(typeof(ArgumentNullException))] + [Test] + [Category("Portable")] public void Throws_Exception_With_Empty_String() { var deserializer = new JsonDotNetSerializer(); - deserializer.GetFat(string.Empty); + Assert.That( + new TestDelegate(()=>deserializer.GetFat(string.Empty)), + Throws.ArgumentNullException) + ; } - [Test] [Category("Portable")] - [ExpectedException(typeof(ArgumentNullException))] + [Test] + [Category("Portable")] public void Throws_Exception_With_Null_String() { var deserializer = new JsonDotNetSerializer(); - deserializer.GetFat(null); + Assert.That( + new TestDelegate(() => deserializer.GetFat(null)), + Throws.ArgumentNullException + ); } - [Test] [Category("Portable")] - [ExpectedException(typeof(ArgumentNullException))] + [Test] + [Category("Portable")] public void Throws_Exception_With_WhiteSpace() { var deserializer = new JsonDotNetSerializer(); - deserializer.GetFat(" "); + Assert.That( + new TestDelegate(() => deserializer.GetFat(" ")), + Throws.ArgumentNullException + ); } - [Test] [Category("Portable")] + [Test] + [Category("Portable")] public void Can_Deserialize_Fat() { string content = SampleDataHelper.GetContent("GetFat.json"); @@ -198,7 +229,7 @@ private void ValidateFat(Fat fat) Assert.AreEqual(new DateTime(2012, 3, 5), log.Date); Assert.AreEqual(1330991999000, log.LogId); Assert.AreEqual(14, log.Fat); - Assert.AreEqual(new DateTime(2012, 3,5,23,59,59).TimeOfDay, log.Time.TimeOfDay); + Assert.AreEqual(new DateTime(2012, 3, 5, 23, 59, 59).TimeOfDay, log.Time.TimeOfDay); fat.FatLogs.Remove(log); log = fat.FatLogs.First(); diff --git a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj index 36486400..4d3ba64f 100644 --- a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj +++ b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj @@ -1,5 +1,6 @@  + Debug AnyCPU @@ -17,6 +18,8 @@ False UnitTest ..\Fitbit\ + + true @@ -36,65 +39,39 @@ 4 - - ..\Fitbit\packages\FluentAssertions.4.2.1\lib\net45\FluentAssertions.dll - True - - - ..\Fitbit\packages\FluentAssertions.4.2.1\lib\net45\FluentAssertions.Core.dll - True + + ..\Fitbit\packages\Castle.Core.4.1.1\lib\net45\Castle.Core.dll - - False - ..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll + + ..\Fitbit\packages\FluentAssertions.4.19.3\lib\net45\FluentAssertions.dll - - False - ..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll + + ..\Fitbit\packages\FluentAssertions.4.19.3\lib\net45\FluentAssertions.Core.dll - - ..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - - - ..\Fitbit\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll - True + + ..\Fitbit\packages\Moq.4.7.99\lib\net45\Moq.dll ..\Fitbit\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll True - - ..\Fitbit\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll - False - - - ..\Fitbit\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll - False + + ..\Fitbit\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll - - ..\Fitbit\packages\NUnit.2.6.4\lib\nunit.framework.dll - True - - - ..\Fitbit\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll - False - - - ..\Fitbit\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll - False - - - ..\Fitbit\packages\AutoFixture.3.40.0\lib\net40\Ploeh.AutoFixture.dll - True + + ..\Fitbit\packages\AutoFixture.3.50.3\lib\net40\Ploeh.AutoFixture.dll - - ..\Fitbit\packages\Microsoft.Net.Http.2.2.22\lib\net45\System.Net.Http.Extensions.dll + + ..\Fitbit\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll + + + ..\Fitbit\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll - - ..\Fitbit\packages\Microsoft.Net.Http.2.2.22\lib\net45\System.Net.Http.Primitives.dll + + ..\Fitbit\packages\Microsoft.Bcl.1.1.10\lib\portable-net40+sl5+win8+wp8+wpa81\System.Threading.Tasks.dll @@ -308,6 +285,12 @@ + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + From 5c70c79466502abb0b9120a29c24856dc2f2623b Mon Sep 17 00:00:00 2001 From: dwayne Date: Tue, 29 Aug 2017 18:11:09 -0700 Subject: [PATCH 37/85] Added System.Threading.Tasks back into CSPROJ --- Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj index 49d21241..ad49fe48 100644 --- a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj +++ b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj @@ -70,9 +70,9 @@ ..\Fitbit\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll - + From 4c3143f38cfafe8790ee690c973af43e836fac80 Mon Sep 17 00:00:00 2001 From: dwayne Date: Wed, 30 Aug 2017 11:53:24 -0700 Subject: [PATCH 38/85] Removed f as calories is now represented as a double --- Fitbit.Portable.Tests/DayActivityTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fitbit.Portable.Tests/DayActivityTests.cs b/Fitbit.Portable.Tests/DayActivityTests.cs index 114b76cb..e6ace687 100644 --- a/Fitbit.Portable.Tests/DayActivityTests.cs +++ b/Fitbit.Portable.Tests/DayActivityTests.cs @@ -203,7 +203,7 @@ private void ValidateActivitySummary(ActivitySummary summary) Assert.AreEqual(1198, summary.HeartRateZones[0].Minutes); Assert.AreEqual(30, summary.HeartRateZones[0].Min); Assert.AreEqual(94, summary.HeartRateZones[0].Max); - Assert.AreEqual(1594.36823f, summary.HeartRateZones[0].CaloriesOut); + Assert.AreEqual(1594.36823, summary.HeartRateZones[0].CaloriesOut); // distances var d = summary.Distances.First(x => x.Activity == "total"); From 112ab43af6013da5efc11d9db4b85c6757addc0d Mon Sep 17 00:00:00 2001 From: dwayne Date: Wed, 30 Aug 2017 12:54:18 -0700 Subject: [PATCH 39/85] Removed obsolete attributes --- Fitbit.Portable.Tests/FatTests.cs | 2 +- Fitbit.Portable.Tests/WeightTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fitbit.Portable.Tests/FatTests.cs b/Fitbit.Portable.Tests/FatTests.cs index 67468dc5..b37dccff 100644 --- a/Fitbit.Portable.Tests/FatTests.cs +++ b/Fitbit.Portable.Tests/FatTests.cs @@ -16,7 +16,7 @@ public class FatTests { public Fixture fixture { get; set; } - [TestFixtureSetUp] + [OneTimeSetUp] public void Init() { fixture = new Fixture(); diff --git a/Fitbit.Portable.Tests/WeightTests.cs b/Fitbit.Portable.Tests/WeightTests.cs index 4692e212..f61985b2 100644 --- a/Fitbit.Portable.Tests/WeightTests.cs +++ b/Fitbit.Portable.Tests/WeightTests.cs @@ -16,7 +16,7 @@ public class WeightTests { public Fixture fixture { get; set; } - [TestFixtureSetUp] + [OneTimeSetUp] public void Init() { fixture = new Fixture(); From b6126e680f8fe20bf6bed0434e8401238469fa38 Mon Sep 17 00:00:00 2001 From: dwayne Date: Wed, 30 Aug 2017 13:11:29 -0700 Subject: [PATCH 40/85] Update NUnit --- Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj | 4 ++-- Fitbit.Portable.Tests/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj index ad49fe48..ac6982a4 100644 --- a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj +++ b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj @@ -55,8 +55,8 @@ ..\Fitbit\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll True - - ..\Fitbit\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll + + ..\Fitbit\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll ..\Fitbit\packages\AutoFixture.3.50.3\lib\net40\Ploeh.AutoFixture.dll diff --git a/Fitbit.Portable.Tests/packages.config b/Fitbit.Portable.Tests/packages.config index 6378805d..dd6cea1f 100644 --- a/Fitbit.Portable.Tests/packages.config +++ b/Fitbit.Portable.Tests/packages.config @@ -9,6 +9,6 @@ - + \ No newline at end of file From 4aa604dddcd198f63b09d55401e48b51d6a1a365 Mon Sep 17 00:00:00 2001 From: dwayne Date: Mon, 4 Sep 2017 19:09:23 -0700 Subject: [PATCH 41/85] Updated props to more closely resemble what Fitabase needs --- Fitbit.Portable.Tests/ActivityLogTests.cs | 7 ++++--- Fitbit.Portable/Fitbit.Portable.csproj | 2 +- Fitbit.Portable/FitbitClient.cs | 4 ++-- Fitbit.Portable/IFitbitClient.cs | 2 +- .../Models/{ActivityList.cs => ActivityLogsList.cs} | 7 ++++--- 5 files changed, 12 insertions(+), 10 deletions(-) rename Fitbit.Portable/Models/{ActivityList.cs => ActivityLogsList.cs} (96%) diff --git a/Fitbit.Portable.Tests/ActivityLogTests.cs b/Fitbit.Portable.Tests/ActivityLogTests.cs index 67392c4e..b01a82e4 100644 --- a/Fitbit.Portable.Tests/ActivityLogTests.cs +++ b/Fitbit.Portable.Tests/ActivityLogTests.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Fitbit.Api.Portable; +using Fitbit.Api.Portable.Models; using Fitbit.Models; using FluentAssertions; using NUnit.Framework; @@ -47,7 +48,7 @@ public void GetActivityLogsListAsync_Errors() var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); - Func>> result = () => fitbitClient.GetActivityLogsList(null, new DateTime(2017, 1, 1)); + Func>> result = () => fitbitClient.GetActivityLogsList(null, new DateTime(2017, 1, 1)); result.ShouldThrow().Which.ApiErrors.Count.Should().Be(1); } @@ -59,12 +60,12 @@ public void Can_Deserialize_ActivityLogsList() string content = SampleDataHelper.GetContent("GetActivityLogsList.json"); var deserializer = new JsonDotNetSerializer {RootProperty = "activities"}; - List stats = deserializer.Deserialize>(content); + List stats = deserializer.Deserialize>(content); ValidateActivity(stats); } - private void ValidateActivity(List stats) + private void ValidateActivity(List stats) { var stat = stats.First(); diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index f3f7fd38..0dce0502 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -46,7 +46,7 @@ - + diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index fff39c6c..fd87347c 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -948,7 +948,7 @@ public async Task LogActivityAsync(ActivityLog model) /// The max of the number of entries returned (maximum: 20) /// encoded user id, can be null for current logged in user /// ActivityLog - public async Task> GetActivityLogsList(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) + public async Task> GetActivityLogsList(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) { var apiCall = string.Empty; limit = limit > 20 ? 20 : limit; @@ -980,7 +980,7 @@ public async Task LogActivityAsync(ActivityLog model) HttpResponseMessage response = await HttpClient.GetAsync(apiCall); await HandleResponse(response); var responseBody = await response.Content.ReadAsStringAsync(); - return (new JsonDotNetSerializer() { RootProperty = "activities" }).Deserialize>(responseBody); + return (new JsonDotNetSerializer() { RootProperty = "activities" }).Deserialize>(responseBody); } diff --git a/Fitbit.Portable/IFitbitClient.cs b/Fitbit.Portable/IFitbitClient.cs index 8a5af5d6..dd6ca959 100644 --- a/Fitbit.Portable/IFitbitClient.cs +++ b/Fitbit.Portable/IFitbitClient.cs @@ -41,6 +41,6 @@ public interface IFitbitClient Task LogActivityAsync(ActivityLog model); Task GetHeartRateTimeSeries(DateTime date, DateRangePeriod dateRangePeriod, string userId = "-"); Task GetHeartRateIntraday(DateTime date, HeartRateResolution resolution, string userId = "-"); - Task> GetActivityLogsList(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)); + Task> GetActivityLogsList(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)); } } \ No newline at end of file diff --git a/Fitbit.Portable/Models/ActivityList.cs b/Fitbit.Portable/Models/ActivityLogsList.cs similarity index 96% rename from Fitbit.Portable/Models/ActivityList.cs rename to Fitbit.Portable/Models/ActivityLogsList.cs index 9a1715d0..ba3122a3 100644 --- a/Fitbit.Portable/Models/ActivityList.cs +++ b/Fitbit.Portable/Models/ActivityLogsList.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; +using Fitbit.Models; using Newtonsoft.Json; -namespace Fitbit.Models +namespace Fitbit.Api.Portable.Models { - public class ActivityList + public class ActivityLogsList { [JsonProperty(PropertyName = "activeDuration")] public int ActiveDuration { get; set; } @@ -79,7 +80,7 @@ public class ActivityList public class ActivityLevel { [JsonProperty(PropertyName = "minutes")] - public double Minutes { get; set; } + public int Minutes { get; set; } [JsonProperty(PropertyName = "name")] public string Name { get; set; } From 067c4282bfd9bab075f0ed6026745845dae971d2 Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 09:55:37 -0700 Subject: [PATCH 42/85] One class per file --- Fitbit.Portable/Fitbit.Portable.csproj | 3 ++ Fitbit.Portable/Models/ActivityLevel.cs | 17 +++++++ Fitbit.Portable/Models/ActivityLogSource.cs | 23 ++++++++++ Fitbit.Portable/Models/ActivityLogsList.cs | 44 ------------------- .../Models/ManualValuesSpecified.cs | 20 +++++++++ 5 files changed, 63 insertions(+), 44 deletions(-) create mode 100644 Fitbit.Portable/Models/ActivityLevel.cs create mode 100644 Fitbit.Portable/Models/ActivityLogSource.cs create mode 100644 Fitbit.Portable/Models/ManualValuesSpecified.cs diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index 0dce0502..11a78a98 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -46,8 +46,10 @@ + + @@ -93,6 +95,7 @@ + diff --git a/Fitbit.Portable/Models/ActivityLevel.cs b/Fitbit.Portable/Models/ActivityLevel.cs new file mode 100644 index 00000000..2113a1d9 --- /dev/null +++ b/Fitbit.Portable/Models/ActivityLevel.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Fitbit.Api.Portable.Models +{ + public class ActivityLevel + { + [JsonProperty(PropertyName = "minutes")] + public int Minutes { get; set; } + + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + } +} diff --git a/Fitbit.Portable/Models/ActivityLogSource.cs b/Fitbit.Portable/Models/ActivityLogSource.cs new file mode 100644 index 00000000..922416e3 --- /dev/null +++ b/Fitbit.Portable/Models/ActivityLogSource.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json; + +namespace Fitbit.Api.Portable.Models +{ + public class ActivityLogSource + { + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } + + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + + [JsonProperty(PropertyName = "type")] + public string Type { get; set; } + + [JsonProperty(PropertyName = "url")] + public string Url { get; set; } + } +} diff --git a/Fitbit.Portable/Models/ActivityLogsList.cs b/Fitbit.Portable/Models/ActivityLogsList.cs index ba3122a3..23efa14e 100644 --- a/Fitbit.Portable/Models/ActivityLogsList.cs +++ b/Fitbit.Portable/Models/ActivityLogsList.cs @@ -76,48 +76,4 @@ public class ActivityLogsList [JsonProperty(PropertyName = "tcxLink")] public string TcxLink { get; set; } } - - public class ActivityLevel - { - [JsonProperty(PropertyName = "minutes")] - public int Minutes { get; set; } - - [JsonProperty(PropertyName = "name")] - public string Name { get; set; } - } - - //public class HeartRateZone - //{ - // public int max { get; set; } - // public int min { get; set; } - // public int minutes { get; set; } - // public string name { get; set; } - //} - - public class ManualValuesSpecified - { - [JsonProperty(PropertyName = "calories")] - public bool Calories { get; set; } - - [JsonProperty(PropertyName = "distance")] - public bool Distance { get; set; } - - [JsonProperty(PropertyName = "steps")] - public bool Steps { get; set; } - } - - public class ActivityLogSource - { - [JsonProperty(PropertyName = "id")] - public string Id { get; set; } - - [JsonProperty(PropertyName = "name")] - public string Name { get; set; } - - [JsonProperty(PropertyName = "type")] - public string Type { get; set; } - - [JsonProperty(PropertyName = "url")] - public string Url { get; set; } - } } diff --git a/Fitbit.Portable/Models/ManualValuesSpecified.cs b/Fitbit.Portable/Models/ManualValuesSpecified.cs new file mode 100644 index 00000000..13bfffe9 --- /dev/null +++ b/Fitbit.Portable/Models/ManualValuesSpecified.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json; + +namespace Fitbit.Api.Portable.Models +{ + public class ManualValuesSpecified + { + [JsonProperty(PropertyName = "calories")] + public bool Calories { get; set; } + + [JsonProperty(PropertyName = "distance")] + public bool Distance { get; set; } + + [JsonProperty(PropertyName = "steps")] + public bool Steps { get; set; } + } +} From 52113adb065a8cfb4b366b0481451466a3e118e7 Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 09:57:02 -0700 Subject: [PATCH 43/85] Naming conventions -- include `Async` --- Fitbit.Portable.Tests/ActivityLogTests.cs | 4 ++-- Fitbit.Portable/FitbitClient.cs | 2 +- Fitbit.Portable/IFitbitClient.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Fitbit.Portable.Tests/ActivityLogTests.cs b/Fitbit.Portable.Tests/ActivityLogTests.cs index b01a82e4..386025af 100644 --- a/Fitbit.Portable.Tests/ActivityLogTests.cs +++ b/Fitbit.Portable.Tests/ActivityLogTests.cs @@ -32,7 +32,7 @@ public async Task GetActivityLogsListAsync_Success() var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); - var response = await fitbitClient.GetActivityLogsList(null, new DateTime(2017, 1, 1)); + var response = await fitbitClient.GetActivityLogsListAsync(null, new DateTime(2017, 1, 1)); ValidateActivity(response); } @@ -48,7 +48,7 @@ public void GetActivityLogsListAsync_Errors() var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); - Func>> result = () => fitbitClient.GetActivityLogsList(null, new DateTime(2017, 1, 1)); + Func>> result = () => fitbitClient.GetActivityLogsListAsync(null, new DateTime(2017, 1, 1)); result.ShouldThrow().Which.ApiErrors.Count.Should().Be(1); } diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index fd87347c..49e48a24 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -948,7 +948,7 @@ public async Task LogActivityAsync(ActivityLog model) /// The max of the number of entries returned (maximum: 20) /// encoded user id, can be null for current logged in user /// ActivityLog - public async Task> GetActivityLogsList(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) + public async Task> GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) { var apiCall = string.Empty; limit = limit > 20 ? 20 : limit; diff --git a/Fitbit.Portable/IFitbitClient.cs b/Fitbit.Portable/IFitbitClient.cs index dd6ca959..37835a62 100644 --- a/Fitbit.Portable/IFitbitClient.cs +++ b/Fitbit.Portable/IFitbitClient.cs @@ -41,6 +41,6 @@ public interface IFitbitClient Task LogActivityAsync(ActivityLog model); Task GetHeartRateTimeSeries(DateTime date, DateRangePeriod dateRangePeriod, string userId = "-"); Task GetHeartRateIntraday(DateTime date, HeartRateResolution resolution, string userId = "-"); - Task> GetActivityLogsList(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)); + Task> GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)); } } \ No newline at end of file From 505eb8bdb21171adaeff6828dafa59236b4cb511 Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 09:58:41 -0700 Subject: [PATCH 44/85] More formatting --- Fitbit.Portable/FitbitClient.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 49e48a24..2d5b7071 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -881,7 +881,6 @@ public async Task> GetSubscriptionsAsync() return serializer.Deserialize(responseBody); } - public async Task DeleteSubscriptionAsync(APICollectionType collection, string uniqueSubscriptionId, string subscriberId = null) { var collectionString = string.Empty; @@ -983,8 +982,6 @@ public async Task LogActivityAsync(ActivityLog model) return (new JsonDotNetSerializer() { RootProperty = "activities" }).Deserialize>(responseBody); } - - #region HeartRateTimeSeries private async Task ProcessHeartRateTimeSeries(string url) @@ -1008,11 +1005,9 @@ private async Task ProcessHeartRateTimeSeries(string /// public async Task GetHeartRateTimeSeries(DateTime date, DateRangePeriod dateRangePeriod, string userId = "-") { - string path = $"1.1/user/{userId}/activities/heart/date/{date:yyyy-MM-dd}/{dateRangePeriod.GetStringValue()}.json"; string apiCall = FitbitClientHelperExtensions.ToFullUrl(path); return await ProcessHeartRateTimeSeries(apiCall); - } #endregion @@ -1046,7 +1041,6 @@ private string GetHeartRateResolution(HeartRateResolution res) } } - /// /// Requests the Intraday Heart Rate Time Series for a specific date. /// From 71c02c59738b913df961c7e68b282d2b8af5f901 Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 10:01:08 -0700 Subject: [PATCH 45/85] Negative number check and formatting --- Fitbit.Portable/FitbitClient.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 2d5b7071..ee856c0c 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -949,8 +949,7 @@ public async Task LogActivityAsync(ActivityLog model) /// ActivityLog public async Task> GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) { - var apiCall = string.Empty; - limit = limit > 20 ? 20 : limit; + limit = limit > 20 || limit < 1 ? 20 : limit; const int offset = 0; var sort = string.Empty; var dateString = string.Empty; @@ -974,7 +973,7 @@ public async Task LogActivityAsync(ActivityLog model) sort = "asc"; } - apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/list.json?{1}={2}&sort={3}&limit={4}&offset={5}", encodedUserId, dateString, date, sort, limit, offset); + string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities/list.json?{1}={2}&sort={3}&limit={4}&offset={5}", encodedUserId, dateString, date, sort, limit, offset); HttpResponseMessage response = await HttpClient.GetAsync(apiCall); await HandleResponse(response); From 7901fff8127fd95b67f84b4ece15591e4bf62216 Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 10:02:11 -0700 Subject: [PATCH 46/85] comments and formatting --- Fitbit.Portable/FitbitClient.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index ee856c0c..21515482 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -949,7 +949,9 @@ public async Task LogActivityAsync(ActivityLog model) /// ActivityLog public async Task> GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) { - limit = limit > 20 || limit < 1 ? 20 : limit; + //Check to make sure limit is gt 1 and less than 20 + limit = limit < 1 || limit > 20 ? 20 : limit; + const int offset = 0; var sort = string.Empty; var dateString = string.Empty; From e1177b7cfb6f34d1aeebdeae7a71bf738feffefd Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 10:17:03 -0700 Subject: [PATCH 47/85] Unused class --- Fitbit.Portable/Fitbit.Portable.csproj | 1 - .../HeartActivitiesIntradayTimeSeries.cs | 48 ------------------- 2 files changed, 49 deletions(-) delete mode 100644 Fitbit.Portable/Models/HeartActivitiesIntradayTimeSeries.cs diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index 11a78a98..e19651e2 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -82,7 +82,6 @@ - diff --git a/Fitbit.Portable/Models/HeartActivitiesIntradayTimeSeries.cs b/Fitbit.Portable/Models/HeartActivitiesIntradayTimeSeries.cs deleted file mode 100644 index 19945b31..00000000 --- a/Fitbit.Portable/Models/HeartActivitiesIntradayTimeSeries.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Fitbit.Models; -using Newtonsoft.Json; - -namespace Fitbit.Api.Portable.Models -{ - public class HeartActivitiesIntradayTimeSeries - { - [JsonProperty(PropertyName = "activities-heart")] - public List ActivitiesHeart { get; set; } - [JsonProperty(PropertyName = "activities-heart-intraday")] - public ActivitesHeartIntraday ActivitiesHeartIntraday { get; set; } - } - public class ActivitesHeart - { - [JsonProperty(PropertyName = "customHeartRateZones")] - public List CustomHeartRateZones { get; set; } - [JsonProperty(PropertyName = "dateTime")] - public DateTime DateTime { get; set; } - [JsonProperty(PropertyName = "heartRateZones")] - public List HeartRateZones { get; set; } - [JsonProperty(PropertyName = "value")] - public double Value { get; set; } - } - - public class ActivitesHeartIntraday - { - [JsonProperty(PropertyName = "dataset")] - public List Dataset { get; set; } - - [JsonProperty(PropertyName = "datasetInterval")] - public int DatasetInterval { get; set; } - - [JsonProperty(PropertyName = "datasetType")] - public string DatasetType { get; set; } - } - public class HeartRateDatasetInterval - { - [JsonProperty(PropertyName = "time")] - public DateTime Time { get; set; } - - [JsonProperty(PropertyName = "value")] - public int Value { get; set; } - } -} From 2d58204a9187d3e8a0c76d22814d407f4387afd6 Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 10:21:48 -0700 Subject: [PATCH 48/85] Remove old commented code --- .../Models/HeartActivitiesIntraday.cs | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/Fitbit.Portable/Models/HeartActivitiesIntraday.cs b/Fitbit.Portable/Models/HeartActivitiesIntraday.cs index a438abcc..ff722636 100644 --- a/Fitbit.Portable/Models/HeartActivitiesIntraday.cs +++ b/Fitbit.Portable/Models/HeartActivitiesIntraday.cs @@ -6,7 +6,6 @@ namespace Fitbit.Models { - //[JsonConverter(typeof(HeartActivitiesIntradayConverter))] public class HeartActivitiesIntraday { public IntradayActivitiesHeart ActivitiesHeart { get; set; } @@ -15,7 +14,6 @@ public class HeartActivitiesIntraday public string DatasetType { get; set; } } - //[JsonConverter(typeof(DatasetIntervalConverter))] public class DatasetInterval { public DateTime Time { get; set; } @@ -105,44 +103,4 @@ public override bool CanConvert(Type objectType) return typeof(HeartActivitiesIntraday).IsAssignableFrom(objectType); } } - - /* - public class DatasetIntervalConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var datasetInverval = value as DatasetInterval; - - //{ - writer.WriteStartObject(); - - // "Time" : "2008-09-22T14:01:54.9571247Z" - writer.WritePropertyName("Time"); - writer.WriteValue(datasetInverval.Time.ToString("o")); - - // "Value": 1 - writer.WritePropertyName("Value"); - writer.WriteValue(datasetInverval.Value); - - //} - writer.WriteEndObject(); - - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - JObject jsonObject = JObject.Load(reader); - var properties = jsonObject.Properties().ToList(); - return new DatasetInterval - { - Time = DateTime.Parse(jsonObject["Time"].ToString()), - Value = Convert.ToInt32(jsonObject["Value"]) - }; - } - - public override bool CanConvert(Type objectType) - { - return typeof(DatasetInterval).IsAssignableFrom(objectType); - } - } */ } \ No newline at end of file From 42c34db3d952f0c925964ba5c84f2b222bdafd24 Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 10:35:49 -0700 Subject: [PATCH 49/85] One class per file --- Fitbit.Portable/Fitbit.Portable.csproj | 3 + Fitbit.Portable/Models/DatasetInterval.cs | 13 +++ .../Models/HeartActivitiesIntraday.cs | 91 +------------------ .../HeartActivitiesIntradayConverter.cs | 78 ++++++++++++++++ .../Models/IntradayActivitiesHeart.cs | 24 +++++ 5 files changed, 119 insertions(+), 90 deletions(-) create mode 100644 Fitbit.Portable/Models/DatasetInterval.cs create mode 100644 Fitbit.Portable/Models/HeartActivitiesIntradayConverter.cs create mode 100644 Fitbit.Portable/Models/IntradayActivitiesHeart.cs diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index e19651e2..31aa0cc1 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -66,6 +66,7 @@ + @@ -82,9 +83,11 @@ + + diff --git a/Fitbit.Portable/Models/DatasetInterval.cs b/Fitbit.Portable/Models/DatasetInterval.cs new file mode 100644 index 00000000..b0a38aac --- /dev/null +++ b/Fitbit.Portable/Models/DatasetInterval.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Fitbit.Api.Portable.Models +{ + public class DatasetInterval + { + public DateTime Time { get; set; } + public int Value { get; set; } + } +} diff --git a/Fitbit.Portable/Models/HeartActivitiesIntraday.cs b/Fitbit.Portable/Models/HeartActivitiesIntraday.cs index ff722636..8b1c062f 100644 --- a/Fitbit.Portable/Models/HeartActivitiesIntraday.cs +++ b/Fitbit.Portable/Models/HeartActivitiesIntraday.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Fitbit.Api.Portable.Models; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -13,94 +14,4 @@ public class HeartActivitiesIntraday public int DatasetInterval { get; set; } public string DatasetType { get; set; } } - - public class DatasetInterval - { - public DateTime Time { get; set; } - public int Value { get; set; } - } - - public class IntradayActivitiesHeart - { - [JsonProperty(PropertyName = "customHeartRateZones")] - public List CustomHeartRateZones { get; set; } - - [JsonProperty(PropertyName = "heartRateZones")] - public List HeartRateZones { get; set; } - - [JsonProperty(PropertyName = "dateTime")] - public DateTime DateTime { get; set; } - - [JsonProperty(PropertyName = "value")] - public double Value { get; set; } - } - - - public class HeartActivitiesIntradayConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var heartActivitiesIntraday = value as HeartActivitiesIntraday; - - //{ - writer.WriteStartObject(); - - writer.WritePropertyName("ActivitiesHeart"); - writer.WriteValue(heartActivitiesIntraday.ActivitiesHeart); - - // "DatasetInterval" : "1" - writer.WritePropertyName("DatasetInterval"); - writer.WriteValue(heartActivitiesIntraday.DatasetInterval); - - // "DatasetType" : "SecondsHeartrate" - writer.WritePropertyName("DatasetType"); - writer.WriteValue(heartActivitiesIntraday.DatasetType); - - writer.WritePropertyName("Dataset"); - writer.WriteStartArray(); - foreach (var datasetInverval in heartActivitiesIntraday.Dataset) - { - // "Time" : "2008-09-22T14:01:54.9571247Z" - writer.WritePropertyName("Time"); - writer.WriteValue(datasetInverval.Time.ToString("o")); - - // "Value": 1 - writer.WritePropertyName("Value"); - writer.WriteValue(datasetInverval.Value); - - } - writer.WriteEndArray(); - - //} - writer.WriteEndObject(); - - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - JObject jsonObject = JObject.Load(reader); - var properties = jsonObject.Properties().ToList(); - - HeartActivitiesIntraday result = new HeartActivitiesIntraday(); - result.DatasetInterval = Convert.ToInt32(jsonObject["DatasetInterval"]); - result.DatasetType = jsonObject["DatasetType"].ToString(); - result.Dataset = new List(); - - foreach (JToken item in jsonObject["Dataset"].Children()) - { - result.Dataset.Add(new DatasetInterval() - { - Time = DateTime.Parse(item["Time"].ToString()), - Value = Convert.ToInt32(item["Value"]) - }); - }; - - return result; - } - - public override bool CanConvert(Type objectType) - { - return typeof(HeartActivitiesIntraday).IsAssignableFrom(objectType); - } - } } \ No newline at end of file diff --git a/Fitbit.Portable/Models/HeartActivitiesIntradayConverter.cs b/Fitbit.Portable/Models/HeartActivitiesIntradayConverter.cs new file mode 100644 index 00000000..6f679530 --- /dev/null +++ b/Fitbit.Portable/Models/HeartActivitiesIntradayConverter.cs @@ -0,0 +1,78 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Fitbit.Models; +using Newtonsoft.Json.Linq; + +namespace Fitbit.Api.Portable.Models +{ + public class HeartActivitiesIntradayConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var heartActivitiesIntraday = value as HeartActivitiesIntraday; + + //{ + writer.WriteStartObject(); + + writer.WritePropertyName("ActivitiesHeart"); + writer.WriteValue(heartActivitiesIntraday.ActivitiesHeart); + + // "DatasetInterval" : "1" + writer.WritePropertyName("DatasetInterval"); + writer.WriteValue(heartActivitiesIntraday.DatasetInterval); + + // "DatasetType" : "SecondsHeartrate" + writer.WritePropertyName("DatasetType"); + writer.WriteValue(heartActivitiesIntraday.DatasetType); + + writer.WritePropertyName("Dataset"); + writer.WriteStartArray(); + foreach (var datasetInverval in heartActivitiesIntraday.Dataset) + { + // "Time" : "2008-09-22T14:01:54.9571247Z" + writer.WritePropertyName("Time"); + writer.WriteValue(datasetInverval.Time.ToString("o")); + + // "Value": 1 + writer.WritePropertyName("Value"); + writer.WriteValue(datasetInverval.Value); + + } + writer.WriteEndArray(); + + //} + writer.WriteEndObject(); + + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + JObject jsonObject = JObject.Load(reader); + var properties = jsonObject.Properties().ToList(); + + HeartActivitiesIntraday result = new HeartActivitiesIntraday(); + result.DatasetInterval = Convert.ToInt32(jsonObject["DatasetInterval"]); + result.DatasetType = jsonObject["DatasetType"].ToString(); + result.Dataset = new List(); + + foreach (JToken item in jsonObject["Dataset"].Children()) + { + result.Dataset.Add(new DatasetInterval() + { + Time = DateTime.Parse(item["Time"].ToString()), + Value = Convert.ToInt32(item["Value"]) + }); + }; + + return result; + } + + public override bool CanConvert(Type objectType) + { + return typeof(HeartActivitiesIntraday).IsAssignableFrom(objectType); + } + } +} diff --git a/Fitbit.Portable/Models/IntradayActivitiesHeart.cs b/Fitbit.Portable/Models/IntradayActivitiesHeart.cs new file mode 100644 index 00000000..6f2f7880 --- /dev/null +++ b/Fitbit.Portable/Models/IntradayActivitiesHeart.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Fitbit.Models; +using Newtonsoft.Json; + +namespace Fitbit.Api.Portable.Models +{ + public class IntradayActivitiesHeart + { + [JsonProperty(PropertyName = "customHeartRateZones")] + public List CustomHeartRateZones { get; set; } + + [JsonProperty(PropertyName = "heartRateZones")] + public List HeartRateZones { get; set; } + + [JsonProperty(PropertyName = "dateTime")] + public DateTime DateTime { get; set; } + + [JsonProperty(PropertyName = "value")] + public double Value { get; set; } + } +} From 37b9eaf794cb5d9a196ee7e687e08fa5a452f338 Mon Sep 17 00:00:00 2001 From: dwayne Date: Thu, 14 Sep 2017 10:41:44 -0700 Subject: [PATCH 50/85] Imports --- Fitbit.Portable/JsonDotNetSerializerExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Fitbit.Portable/JsonDotNetSerializerExtensions.cs b/Fitbit.Portable/JsonDotNetSerializerExtensions.cs index d2995584..d2f40a51 100644 --- a/Fitbit.Portable/JsonDotNetSerializerExtensions.cs +++ b/Fitbit.Portable/JsonDotNetSerializerExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Fitbit.Api.Portable.Models; using Fitbit.Models; using Newtonsoft.Json.Linq; From 7cc8d7645a14d2873e907a3120689d3c707f739f Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Thu, 21 Sep 2017 19:24:38 -0700 Subject: [PATCH 51/85] Added DateOfActivity and changed Datetimes to DateTimeOffsets --- Fitbit.Portable/Models/ActivityLogsList.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Fitbit.Portable/Models/ActivityLogsList.cs b/Fitbit.Portable/Models/ActivityLogsList.cs index 23efa14e..91d9a2ca 100644 --- a/Fitbit.Portable/Models/ActivityLogsList.cs +++ b/Fitbit.Portable/Models/ActivityLogsList.cs @@ -24,6 +24,8 @@ public class ActivityLogsList [JsonProperty(PropertyName = "calories")] public int Calories { get; set; } + + public DateTimeOffset DateOfActivity => StartTime.Date; [JsonProperty(PropertyName = "distance")] public double Distance { get; set; } @@ -56,7 +58,7 @@ public class ActivityLogsList public int OriginalDuration { get; set; } [JsonProperty(PropertyName = "originalStartTime")] - public DateTime OriginalStartTime { get; set; } + public DateTimeOffset OriginalStartTime { get; set; } [JsonProperty(PropertyName = "pace")] public double Pace { get; set; } @@ -68,7 +70,7 @@ public class ActivityLogsList public double Speed { get; set; } [JsonProperty(PropertyName = "startTime")] - public DateTime StartTime { get; set; } + public DateTimeOffset StartTime { get; set; } [JsonProperty(PropertyName = "steps")] public int Steps { get; set; } From 097aa7ce92b9ce0440b0c09f5989a7d990b863ae Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Thu, 21 Sep 2017 19:25:11 -0700 Subject: [PATCH 52/85] Added function to pull activity logs for one day --- Fitbit.Portable/FitbitClient.cs | 15 ++++++++++++++- Fitbit.Portable/IFitbitClient.cs | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 21515482..04a6647b 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -946,7 +946,7 @@ public async Task LogActivityAsync(ActivityLog model) /// The date in the format yyyy-MM-ddTHH:mm:ss. Only yyyy-MM-dd is required. Either beforeDate or afterDate must be specified. Set sort to asc when using afterDate. /// The max of the number of entries returned (maximum: 20) /// encoded user id, can be null for current logged in user - /// ActivityLog + /// ActivityLogsList public async Task> GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) { //Check to make sure limit is gt 1 and less than 20 @@ -983,6 +983,19 @@ public async Task LogActivityAsync(ActivityLog model) return (new JsonDotNetSerializer() { RootProperty = "activities" }).Deserialize>(responseBody); } + /// + /// Retrieves a list of a user's activity log entries on a given day + /// + /// The date of Activities. + /// encoded user id, can be null for current logged in user + /// ActivityLogsList + public async Task> GetActivityLogsListAsync(DateTime date, string encodedUserId = default(string)) + { + List logsAfterDate = await GetActivityLogsListAsync(null, date, 20, encodedUserId); + List logsOnDate = logsAfterDate?.Where(x => x.DateOfActivity == date).ToList(); + return logsOnDate; + } + #region HeartRateTimeSeries private async Task ProcessHeartRateTimeSeries(string url) diff --git a/Fitbit.Portable/IFitbitClient.cs b/Fitbit.Portable/IFitbitClient.cs index 37835a62..0a7cdc98 100644 --- a/Fitbit.Portable/IFitbitClient.cs +++ b/Fitbit.Portable/IFitbitClient.cs @@ -42,5 +42,7 @@ public interface IFitbitClient Task GetHeartRateTimeSeries(DateTime date, DateRangePeriod dateRangePeriod, string userId = "-"); Task GetHeartRateIntraday(DateTime date, HeartRateResolution resolution, string userId = "-"); Task> GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)); + Task> GetActivityLogsListAsync(DateTime date, string encodedUserId = default(string)); + } } \ No newline at end of file From 82dadd089b80913fc3877d9850a88ccde8e115d7 Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Mon, 25 Sep 2017 12:46:17 -0700 Subject: [PATCH 53/85] return DateOfActivity as a string --- Fitbit.Portable/Models/ActivityLogsList.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fitbit.Portable/Models/ActivityLogsList.cs b/Fitbit.Portable/Models/ActivityLogsList.cs index 91d9a2ca..c7bcc444 100644 --- a/Fitbit.Portable/Models/ActivityLogsList.cs +++ b/Fitbit.Portable/Models/ActivityLogsList.cs @@ -25,8 +25,8 @@ public class ActivityLogsList [JsonProperty(PropertyName = "calories")] public int Calories { get; set; } - public DateTimeOffset DateOfActivity => StartTime.Date; - + public string DateOfActivity => StartTime.Date.ToString("yyyy-MM-dd"); + [JsonProperty(PropertyName = "distance")] public double Distance { get; set; } From 606eb316a05a1f72a87fcc35c2276e998dd869cd Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Mon, 25 Sep 2017 13:12:16 -0700 Subject: [PATCH 54/85] Fixed DateTime comparison --- Fitbit.Portable/FitbitClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 04a6647b..f8cc432e 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -992,7 +992,7 @@ public async Task LogActivityAsync(ActivityLog model) public async Task> GetActivityLogsListAsync(DateTime date, string encodedUserId = default(string)) { List logsAfterDate = await GetActivityLogsListAsync(null, date, 20, encodedUserId); - List logsOnDate = logsAfterDate?.Where(x => x.DateOfActivity == date).ToList(); + List logsOnDate = logsAfterDate?.Where(x => x.StartTime.Date == date.Date).ToList(); return logsOnDate; } From 844005b461b162fbf679d122c659b58e56a6c31f Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Mon, 25 Sep 2017 17:21:50 -0700 Subject: [PATCH 55/85] Removed time from Activity Logs Request --- Fitbit.Portable/FitbitClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index f8cc432e..21588425 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -965,13 +965,13 @@ public async Task LogActivityAsync(ActivityLog model) if (beforeDate != null) { dateString = "beforeDate"; - date = beforeDate.Value.ToString("yyyy-MM-ddTHH:mm:ss"); + date = beforeDate.Value.ToString("yyyy-MM-dd"); sort = "desc"; } if (afterDate != null) { dateString = "afterDate"; - date = afterDate.Value.ToString("yyyy-MM-ddTHH:mm:ss"); + date = afterDate.Value.ToString("yyyy-MM-dd"); sort = "asc"; } From ffb639b5b2efe5015f619e44392ff66cfceca7ad Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Mon, 25 Sep 2017 17:49:04 -0700 Subject: [PATCH 56/85] Update tests to match activity changes --- Fitbit.Portable.Tests/ActivityLogTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fitbit.Portable.Tests/ActivityLogTests.cs b/Fitbit.Portable.Tests/ActivityLogTests.cs index 386025af..f71b9ff8 100644 --- a/Fitbit.Portable.Tests/ActivityLogTests.cs +++ b/Fitbit.Portable.Tests/ActivityLogTests.cs @@ -27,7 +27,7 @@ public async Task GetActivityLogsListAsync_Success() var verification = new Action((message, token) => { Assert.AreEqual(HttpMethod.Get, message.Method); - Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/list.json?afterDate=2017-01-01T00:00:00&sort=asc&limit=20&offset=0", message.RequestUri.AbsoluteUri); + Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/list.json?afterDate=2017-01-01&sort=asc&limit=20&offset=0", message.RequestUri.AbsoluteUri); }); var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); From a1efbce741afce30c5659cfda54e4e7e9e0c626f Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Thu, 28 Sep 2017 17:50:20 +0000 Subject: [PATCH 57/85] New test functions and file to test using the new activity logs format --- Fitbit.Portable.Tests/ActivityLogTests.cs | 48 +- .../Fitbit.Portable.Tests.csproj | 3 + .../SampleData/GetActivityLogsList2.json | 1582 +++++++++++++++++ 3 files changed, 1627 insertions(+), 6 deletions(-) create mode 100644 Fitbit.Portable.Tests/SampleData/GetActivityLogsList2.json diff --git a/Fitbit.Portable.Tests/ActivityLogTests.cs b/Fitbit.Portable.Tests/ActivityLogTests.cs index f71b9ff8..8b330d7a 100644 --- a/Fitbit.Portable.Tests/ActivityLogTests.cs +++ b/Fitbit.Portable.Tests/ActivityLogTests.cs @@ -9,6 +9,7 @@ using Fitbit.Api.Portable.Models; using Fitbit.Models; using FluentAssertions; +using Newtonsoft.Json; using NUnit.Framework; namespace Fitbit.Portable.Tests @@ -33,7 +34,7 @@ public async Task GetActivityLogsListAsync_Success() var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); var response = await fitbitClient.GetActivityLogsListAsync(null, new DateTime(2017, 1, 1)); - ValidateActivity(response); + ValidateActivity(response.Activities); } [Test] @@ -48,7 +49,7 @@ public void GetActivityLogsListAsync_Errors() var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); - Func>> result = () => fitbitClient.GetActivityLogsListAsync(null, new DateTime(2017, 1, 1)); + Func> result = () => fitbitClient.GetActivityLogsListAsync(null, new DateTime(2017, 1, 1)); result.ShouldThrow().Which.ApiErrors.Count.Should().Be(1); } @@ -58,14 +59,49 @@ public void GetActivityLogsListAsync_Errors() public void Can_Deserialize_ActivityLogsList() { string content = SampleDataHelper.GetContent("GetActivityLogsList.json"); - var deserializer = new JsonDotNetSerializer {RootProperty = "activities"}; + var settings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.DateTimeOffset }; + ActivityLogsList logList = JsonConvert.DeserializeObject(content, settings); - List stats = deserializer.Deserialize>(content); + ValidateActivity(logList.Activities); + } + + [Test] + [Category("Portable")] + public async Task Get_Multiple_ActivityLogsList() + { + var response = await GetActivityLogsList2(new DateTime(2017, 9, 4)); + response.Activities.Count.Should().Be(2); + } + + [Test] + [Category("Portable")] + public async Task Check_TimeZone_ActivityLogsList() + { + var response = await GetActivityLogsList2(new DateTime(2017, 9, 4)); + const string origOffset = "-07:00:00"; + + response.Activities[0].StartTime.Offset.ToString().Should().Be(origOffset); + response.Activities[1].StartTime.Offset.ToString().Should().Be(origOffset); + } + + private async Task GetActivityLogsList2(DateTime date) + { + string content = SampleDataHelper.GetContent("GetActivityLogsList2.json"); + var responseMessage = new Func(() => new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(content) }); + + var verification = new Action((message, token) => + { + Assert.AreEqual(HttpMethod.Get, message.Method); + Assert.AreEqual("https://api.fitbit.com/1/user/-/activities/list.json?afterDate=2017-09-04&sort=asc&limit=20&offset=0", message.RequestUri.AbsoluteUri); + }); + + var fitbitClient = Helper.CreateFitbitClient(responseMessage, verification); - ValidateActivity(stats); + var response = await fitbitClient.GetActivityLogsListAsync(date); + return response; } - private void ValidateActivity(List stats) + private void ValidateActivity(List stats) { var stat = stats.First(); diff --git a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj index ac6982a4..160581b5 100644 --- a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj +++ b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj @@ -219,6 +219,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Fitbit.Portable.Tests/SampleData/GetActivityLogsList2.json b/Fitbit.Portable.Tests/SampleData/GetActivityLogsList2.json new file mode 100644 index 00000000..274946d2 --- /dev/null +++ b/Fitbit.Portable.Tests/SampleData/GetActivityLogsList2.json @@ -0,0 +1,1582 @@ +{ + "activities": [ + + { + "activeDuration": 1126000, + "activityLevel": [ + + { + "minutes": 1, + "name": "sedentary" + }, + + { + "minutes": 0, + "name": "lightly" + }, + + { + "minutes": 2, + "name": "fairly" + }, + + { + "minutes": 15, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 94, + "calories": 150, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-01/2017-09-01/1min/time/8:16/8:35.json", + "duration": 1126000, + "elevationGain": 6.096, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-01/2017-09-01/1sec/time/08:16:14/08:35:00.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 3, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 6, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 2, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 1, + "name": "Peak" + } + ], + "lastModified": "2017-09-01T17:44:07.000Z", + "logId": 9672992546, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1126000, + "originalStartTime": "2017-09-01T08:16:14.000-07:00", + "startTime": "2017-09-01T08:16:14.000-07:00", + "steps": 1758, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9672992546.tcx" + }, + + { + "activeDuration": 1834000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 0, + "name": "lightly" + }, + + { + "minutes": 0, + "name": "fairly" + }, + + { + "minutes": 32, + "name": "very" + } + ], + "activityName": "Run", + "activityTypeId": 90009, + "averageHeartRate": 129, + "calories": 355, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-01/2017-09-01/1min/time/18:54/19:29.json", + "distance": 5.502559, + "distanceUnit": "Kilometer", + "duration": 2103000, + "elevationGain": 54.864, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-01/2017-09-01/1sec/time/18:54:51/19:29:54.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 1, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 8, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 22, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-02T02:31:34.000Z", + "logId": 9675733775, + "logType": "tracker", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 2103000, + "originalStartTime": "2017-09-01T18:54:51.000-07:00", + "pace": 333.299470301, + "source": { + "id": "93686741", + "name": "Surge", + "type": "tracker", + "url": "https://www.fitbit.com/" + }, + "speed": 10.801097273718646, + "startTime": "2017-09-01T18:54:51.000-07:00", + "steps": 5018, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9675733775.tcx" + }, + + { + "activeDuration": 2054000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 0, + "name": "lightly" + }, + + { + "minutes": 0, + "name": "fairly" + }, + + { + "minutes": 34, + "name": "very" + } + ], + "activityName": "Run", + "activityTypeId": 90009, + "averageHeartRate": 142, + "calories": 417, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-02/2017-09-02/1min/time/19:25/20:00.json", + "distance": 6.54444, + "distanceUnit": "Kilometer", + "duration": 2084000, + "elevationGain": 41.91, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-02/2017-09-02/1sec/time/19:25:24/20:00:08.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 1, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 1, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 27, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 6, + "name": "Peak" + } + ], + "lastModified": "2017-09-03T03:03:04.000Z", + "logId": 9692690916, + "logType": "tracker", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 2084000, + "originalStartTime": "2017-09-02T19:25:24.000-07:00", + "pace": 313.8542029570139, + "source": { + "id": "93686741", + "name": "Surge", + "type": "tracker", + "url": "https://www.fitbit.com/" + }, + "speed": 11.470294060370009, + "startTime": "2017-09-02T19:25:24.000-07:00", + "steps": 5651, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9692690916.tcx" + }, + + { + "activeDuration": 921000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 3, + "name": "lightly" + }, + + { + "minutes": 9, + "name": "fairly" + }, + + { + "minutes": 4, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 84, + "calories": 95, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-03/2017-09-03/1min/time/19:34/19:50.json", + "duration": 921000, + "elevationGain": 0, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-03/2017-09-03/1sec/time/19:34:51/19:50:12.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 11, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 5, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-04T04:54:51.000Z", + "logId": 9712603607, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 921000, + "originalStartTime": "2017-09-03T19:34:51.000-07:00", + "startTime": "2017-09-03T19:34:51.000-07:00", + "steps": 1150, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9712603607.tcx" + }, + + { + "activeDuration": 1203000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 0, + "name": "lightly" + }, + + { + "minutes": 0, + "name": "fairly" + }, + + { + "minutes": 20, + "name": "very" + } + ], + "activityName": "Run", + "activityTypeId": 90009, + "averageHeartRate": 162, + "calories": 289, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-03/2017-09-03/1min/time/20:00/20:21.json", + "distance": 5.12796, + "distanceUnit": "Kilometer", + "duration": 1271000, + "elevationGain": 15.24, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-03/2017-09-03/1sec/time/20:00:03/20:21:14.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 0, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 1, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 1, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 19, + "name": "Peak" + } + ], + "lastModified": "2017-09-04T04:54:46.000Z", + "logId": 9711437124, + "logType": "tracker", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1271000, + "originalStartTime": "2017-09-03T20:00:03.000-07:00", + "pace": 234.5962136990148, + "source": { + "id": "93686741", + "name": "Surge", + "type": "tracker", + "url": "https://www.fitbit.com/" + }, + "speed": 15.345516209476308, + "startTime": "2017-09-03T20:00:03.000-07:00", + "steps": 3496, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9711437124.tcx" + }, + + { + "activeDuration": 1280000, + "activityLevel": [ + + { + "minutes": 1, + "name": "sedentary" + }, + + { + "minutes": 2, + "name": "lightly" + }, + + { + "minutes": 6, + "name": "fairly" + }, + + { + "minutes": 12, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 85, + "calories": 143, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-04/2017-09-04/1min/time/10:34/10:56.json", + "duration": 1280000, + "elevationGain": 15.24, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-04/2017-09-04/1sec/time/10:34:56/10:56:16.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 16, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 3, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-04T18:10:32.000Z", + "logId": 9720996316, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1280000, + "originalStartTime": "2017-09-04T10:34:56.000-07:00", + "startTime": "2017-09-04T10:34:56.000-07:00", + "steps": 1904, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9720996316.tcx" + }, + + { + "activeDuration": 2048000, + "activityLevel": [ + + { + "minutes": 1, + "name": "sedentary" + }, + + { + "minutes": 1, + "name": "lightly" + }, + + { + "minutes": 11, + "name": "fairly" + }, + + { + "minutes": 21, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 88, + "calories": 236, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-04/2017-09-04/1min/time/19:24/19:59.json", + "duration": 2048000, + "elevationGain": 30.48, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-04/2017-09-04/1sec/time/19:24:52/19:59:00.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 18, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 16, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-05T21:41:11.000Z", + "logId": 9743358154, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 2048000, + "originalStartTime": "2017-09-04T19:24:52.000-07:00", + "startTime": "2017-09-04T19:24:52.000-07:00", + "steps": 3301, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9743358154.tcx" + }, + + { + "activeDuration": 1229000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 1, + "name": "lightly" + }, + + { + "minutes": 2, + "name": "fairly" + }, + + { + "minutes": 17, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 87, + "calories": 145, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-05/2017-09-05/1min/time/9:10/9:31.json", + "duration": 1229000, + "elevationGain": 9.144, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-05/2017-09-05/1sec/time/09:10:53/09:31:22.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 17, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 4, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-05T21:41:11.000Z", + "logId": 9743358155, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1229000, + "originalStartTime": "2017-09-05T09:10:53.000-07:00", + "startTime": "2017-09-05T09:10:53.000-07:00", + "steps": 2132, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9743358155.tcx" + }, + + { + "activeDuration": 1023000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 0, + "name": "lightly" + }, + + { + "minutes": 1, + "name": "fairly" + }, + + { + "minutes": 16, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 139, + "calories": 174, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-05/2017-09-05/1min/time/21:35/21:52.json", + "duration": 1023000, + "elevationGain": 3.048, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-05/2017-09-05/1sec/time/21:35:52/21:52:55.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 0, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 2, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 2, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 7, + "name": "Peak" + } + ], + "lastModified": "2017-09-06T04:57:31.000Z", + "logId": 9748240773, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1023000, + "originalStartTime": "2017-09-05T21:35:52.000-07:00", + "startTime": "2017-09-05T21:35:52.000-07:00", + "steps": 1738, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9748240773.tcx" + }, + + { + "activeDuration": 1382000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 3, + "name": "lightly" + }, + + { + "minutes": 2, + "name": "fairly" + }, + + { + "minutes": 19, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 117, + "calories": 215, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-06/2017-09-06/1min/time/20:39/21:03.json", + "duration": 1382000, + "elevationGain": 21.336, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-06/2017-09-06/1sec/time/20:39:59/21:03:01.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 3, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 4, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 4, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 4, + "name": "Peak" + } + ], + "lastModified": "2017-09-07T04:06:21.000Z", + "logId": 9766322317, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1382000, + "originalStartTime": "2017-09-06T20:39:59.000-07:00", + "startTime": "2017-09-06T20:39:59.000-07:00", + "steps": 2432, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9766322317.tcx" + }, + + { + "activeDuration": 920000, + "activityLevel": [ + + { + "minutes": 1, + "name": "sedentary" + }, + + { + "minutes": 14, + "name": "lightly" + }, + + { + "minutes": 0, + "name": "fairly" + }, + + { + "minutes": 0, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 89, + "calories": 91, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-07/2017-09-07/1min/time/16:07/16:22.json", + "duration": 920000, + "elevationGain": 21.336, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-07/2017-09-07/1sec/time/16:07:21/16:22:41.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 9, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 6, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-07T23:32:46.000Z", + "logId": 9782094419, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 920000, + "originalStartTime": "2017-09-07T16:07:21.000-07:00", + "startTime": "2017-09-07T16:07:21.000-07:00", + "steps": 1069, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9782094419.tcx" + }, + + { + "activeDuration": 1126000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 1, + "name": "lightly" + }, + + { + "minutes": 1, + "name": "fairly" + }, + + { + "minutes": 17, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 105, + "calories": 159, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-08/2017-09-08/1min/time/12:40/12:59.json", + "duration": 1126000, + "elevationGain": 6.096, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-08/2017-09-08/1sec/time/12:40:26/12:59:12.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 4, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 9, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 2, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-08T20:07:18.000Z", + "logId": 9795510989, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1126000, + "originalStartTime": "2017-09-08T12:40:26.000-07:00", + "startTime": "2017-09-08T12:40:26.000-07:00", + "steps": 2005, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9795510989.tcx" + }, + + { + "activeDuration": 1383000, + "activityLevel": [ + + { + "minutes": 4, + "name": "sedentary" + }, + + { + "minutes": 6, + "name": "lightly" + }, + + { + "minutes": 1, + "name": "fairly" + }, + + { + "minutes": 12, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 89, + "calories": 156, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-09/2017-09-09/1min/time/19:19/19:42.json", + "duration": 1383000, + "elevationGain": 30.48, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-09/2017-09-09/1sec/time/19:19:20/19:42:23.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 8, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 12, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-10T05:23:53.000Z", + "logId": 9816956883, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1383000, + "originalStartTime": "2017-09-09T19:19:20.000-07:00", + "startTime": "2017-09-09T19:19:20.000-07:00", + "steps": 1621, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9816956883.tcx" + }, + + { + "activeDuration": 1435000, + "activityLevel": [ + + { + "minutes": 1, + "name": "sedentary" + }, + + { + "minutes": 6, + "name": "lightly" + }, + + { + "minutes": 9, + "name": "fairly" + }, + + { + "minutes": 7, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 80, + "calories": 137, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-09/2017-09-09/1min/time/22:49/23:13.json", + "duration": 1435000, + "elevationGain": 3.048, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-09/2017-09-09/1sec/time/22:49:17/23:13:12.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 13, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 6, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-10T07:35:02.000Z", + "logId": 9817624169, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1435000, + "originalStartTime": "2017-09-09T22:49:17.000-07:00", + "startTime": "2017-09-09T22:49:17.000-07:00", + "steps": 1784, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9817624169.tcx" + }, + + { + "activeDuration": 1535000, + "activityLevel": [ + + { + "minutes": 4, + "name": "sedentary" + }, + + { + "minutes": 11, + "name": "lightly" + }, + + { + "minutes": 1, + "name": "fairly" + }, + + { + "minutes": 9, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 83, + "calories": 153, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-10/2017-09-10/1min/time/10:26/10:52.json", + "duration": 1535000, + "elevationGain": 12.192, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-10/2017-09-10/1sec/time/10:26:29/10:52:04.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 15, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 9, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-10T17:58:08.000Z", + "logId": 9824250863, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1535000, + "originalStartTime": "2017-09-10T10:26:29.000-07:00", + "startTime": "2017-09-10T10:26:29.000-07:00", + "steps": 1987, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9824250863.tcx" + }, + + { + "activeDuration": 1126000, + "activityLevel": [ + + { + "minutes": 1, + "name": "sedentary" + }, + + { + "minutes": 2, + "name": "lightly" + }, + + { + "minutes": 4, + "name": "fairly" + }, + + { + "minutes": 11, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 81, + "calories": 120, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-11/2017-09-11/1min/time/7:29/7:48.json", + "duration": 1126000, + "elevationGain": 15.24, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-11/2017-09-11/1sec/time/07:29:25/07:48:11.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 17, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 2, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-11T14:51:57.000Z", + "logId": 9837494906, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1126000, + "originalStartTime": "2017-09-11T07:29:25.000-07:00", + "startTime": "2017-09-11T07:29:25.000-07:00", + "steps": 1715, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9837494906.tcx" + }, + + { + "activeDuration": 1178000, + "activityLevel": [ + + { + "minutes": 0, + "name": "sedentary" + }, + + { + "minutes": 1, + "name": "lightly" + }, + + { + "minutes": 4, + "name": "fairly" + }, + + { + "minutes": 14, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 91, + "calories": 143, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-13/2017-09-13/1min/time/8:48/9:08.json", + "duration": 1178000, + "elevationGain": 18.288, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-13/2017-09-13/1sec/time/08:48:47/09:08:25.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 9, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 8, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-14T14:38:53.000Z", + "logId": 9894765643, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1178000, + "originalStartTime": "2017-09-13T08:48:47.000-07:00", + "startTime": "2017-09-13T08:48:47.000-07:00", + "steps": 1856, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9894765643.tcx" + }, + + { + "activeDuration": 1127000, + "activityLevel": [ + + { + "minutes": 2, + "name": "sedentary" + }, + + { + "minutes": 2, + "name": "lightly" + }, + + { + "minutes": 2, + "name": "fairly" + }, + + { + "minutes": 12, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 87, + "calories": 122, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-14/2017-09-14/1min/time/7:52/8:10.json", + "duration": 1127000, + "elevationGain": 18.288, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-14/2017-09-14/1sec/time/07:52:03/08:10:50.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 13, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 5, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-14T15:21:41.000Z", + "logId": 9895302005, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1127000, + "originalStartTime": "2017-09-14T07:52:03.000-07:00", + "startTime": "2017-09-14T07:52:03.000-07:00", + "steps": 1597, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9895302005.tcx" + }, + + { + "activeDuration": 973000, + "activityLevel": [ + + { + "minutes": 1, + "name": "sedentary" + }, + + { + "minutes": 0, + "name": "lightly" + }, + + { + "minutes": 4, + "name": "fairly" + }, + + { + "minutes": 11, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 85, + "calories": 128, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-14/2017-09-14/1min/time/14:51/15:07.json", + "duration": 973000, + "elevationGain": 13.004, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-14/2017-09-14/1sec/time/14:51:03/15:07:16.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 9, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 2, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 1, + "name": "Peak" + } + ], + "lastModified": "2017-09-14T22:19:56.000Z", + "logId": 9903511341, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 973000, + "originalStartTime": "2017-09-14T14:51:03.000-07:00", + "startTime": "2017-09-14T14:51:03.000-07:00", + "steps": 1440, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9903511341.tcx" + }, + + { + "activeDuration": 1740000, + "activityLevel": [ + + { + "minutes": 1, + "name": "sedentary" + }, + + { + "minutes": 2, + "name": "lightly" + }, + + { + "minutes": 9, + "name": "fairly" + }, + + { + "minutes": 17, + "name": "very" + } + ], + "activityName": "Walk", + "activityTypeId": 90013, + "averageHeartRate": 84, + "calories": 203, + "caloriesLink": "https://api.fitbit.com/1/user/-/activities/calories/date/2017-09-15/2017-09-15/1min/time/8:05/8:34.json", + "duration": 1740000, + "elevationGain": 21.336, + "heartRateLink": "https://api.fitbit.com/1/user/-/activities/heart/date/2017-09-15/2017-09-15/1sec/time/08:05:18/08:34:18.json", + "heartRateZones": [ + + { + "max": 92, + "min": 30, + "minutes": 21, + "name": "Out of Range" + }, + + { + "max": 128, + "min": 92, + "minutes": 8, + "name": "Fat Burn" + }, + + { + "max": 156, + "min": 128, + "minutes": 0, + "name": "Cardio" + }, + + { + "max": 220, + "min": 156, + "minutes": 0, + "name": "Peak" + } + ], + "lastModified": "2017-09-15T15:47:02.000Z", + "logId": 9914385428, + "logType": "auto_detected", + "manualValuesSpecified": { + "calories": false, + "distance": false, + "steps": false + }, + "originalDuration": 1740000, + "originalStartTime": "2017-09-15T08:05:18.000-07:00", + "startTime": "2017-09-15T08:05:18.000-07:00", + "steps": 2788, + "tcxLink": "https://api.fitbit.com/1/user/-/activities/9914385428.tcx" + } + ], + "pagination": { + "afterDate": "2017-09-01", + "limit": 20, + "next": "https://api.fitbit.com/1/user/-/activities/list.json?offset=20&limit=20&sort=asc&afterDate=2017-09-01", + "offset": 0, + "previous": "", + "sort": "asc" + } +} \ No newline at end of file From 114c052fd36fdf4179aa8449de09dd94542aff4d Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Thu, 28 Sep 2017 17:53:47 +0000 Subject: [PATCH 58/85] New ActivityLog Model structure to more closely match Fitbit's response and allow for correctly deserialilzed time zone offsets --- Fitbit.Portable/Fitbit.Portable.csproj | 1 + Fitbit.Portable/Models/Activities.cs | 81 ++++++++++++++++++++++ Fitbit.Portable/Models/ActivityLogsList.cs | 72 +------------------ 3 files changed, 85 insertions(+), 69 deletions(-) create mode 100644 Fitbit.Portable/Models/Activities.cs diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index 31aa0cc1..29c02486 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -42,6 +42,7 @@ + diff --git a/Fitbit.Portable/Models/Activities.cs b/Fitbit.Portable/Models/Activities.cs new file mode 100644 index 00000000..62fe270e --- /dev/null +++ b/Fitbit.Portable/Models/Activities.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using Fitbit.Models; +using Newtonsoft.Json; + +namespace Fitbit.Api.Portable.Models +{ + public class Activities + { + [JsonProperty(PropertyName = "activeDuration")] + public int ActiveDuration { get; set; } + + [JsonProperty(PropertyName = "activityLevel")] + public List ActivityLevel { get; set; } + + [JsonProperty(PropertyName = "activityName")] + public string ActivityName { get; set; } + + [JsonProperty(PropertyName = "activityTypeId")] + public int ActivityTypeId { get; set; } + + [JsonProperty(PropertyName = "averageHeartRate")] + public int AverageHeartRate { get; set; } + + [JsonProperty(PropertyName = "calories")] + public int Calories { get; set; } + + public string DateOfActivity => StartTime.Date.ToString("yyyy-MM-dd"); + + [JsonProperty(PropertyName = "distance")] + public double Distance { get; set; } + + [JsonProperty(PropertyName = "distanceUnit")] + public string DistanceUnit { get; set; } + + [JsonProperty(PropertyName = "duration")] + public int Duration { get; set; } + + [JsonProperty(PropertyName = "elevationGain")] + public double ElevationGain { get; set; } + + [JsonProperty(PropertyName = "heartRateZones")] + public List HeartRateZones { get; set; } + + [JsonProperty(PropertyName = "lastModified")] + public DateTime LastModified { get; set; } + + [JsonProperty(PropertyName = "logId")] + public long LogId { get; set; } + + [JsonProperty(PropertyName = "logType")] + public string LogType { get; set; } + + [JsonProperty(PropertyName = "manualValuesSpecified")] + public ManualValuesSpecified ManualValuesSpecified { get; set; } + + [JsonProperty(PropertyName = "originalDuration")] + public int OriginalDuration { get; set; } + + [JsonProperty(PropertyName = "originalStartTime")] + public DateTimeOffset OriginalStartTime { get; set; } + + [JsonProperty(PropertyName = "pace")] + public double Pace { get; set; } + + [JsonProperty(PropertyName = "source")] + public ActivityLogSource Source { get; set; } + + [JsonProperty(PropertyName = "speed")] + public double Speed { get; set; } + + [JsonProperty(PropertyName = "startTime")] + public DateTimeOffset StartTime { get; set; } + + [JsonProperty(PropertyName = "steps")] + public int Steps { get; set; } + + [JsonProperty(PropertyName = "tcxLink")] + public string TcxLink { get; set; } + } +} diff --git a/Fitbit.Portable/Models/ActivityLogsList.cs b/Fitbit.Portable/Models/ActivityLogsList.cs index c7bcc444..10990445 100644 --- a/Fitbit.Portable/Models/ActivityLogsList.cs +++ b/Fitbit.Portable/Models/ActivityLogsList.cs @@ -7,75 +7,9 @@ namespace Fitbit.Api.Portable.Models { public class ActivityLogsList { - [JsonProperty(PropertyName = "activeDuration")] - public int ActiveDuration { get; set; } + [JsonProperty(PropertyName = "activities")] + public List Activities{ get; set; } - [JsonProperty(PropertyName = "activityLevel")] - public List ActivityLevel { get; set; } - - [JsonProperty(PropertyName = "activityName")] - public string ActivityName { get; set; } - - [JsonProperty(PropertyName = "activityTypeId")] - public int ActivityTypeId { get; set; } - - [JsonProperty(PropertyName = "averageHeartRate")] - public int AverageHeartRate { get; set; } - - [JsonProperty(PropertyName = "calories")] - public int Calories { get; set; } - - public string DateOfActivity => StartTime.Date.ToString("yyyy-MM-dd"); - - [JsonProperty(PropertyName = "distance")] - public double Distance { get; set; } - - [JsonProperty(PropertyName = "distanceUnit")] - public string DistanceUnit { get; set; } - - [JsonProperty(PropertyName = "duration")] - public int Duration { get; set; } - - [JsonProperty(PropertyName = "elevationGain")] - public double ElevationGain { get; set; } - - [JsonProperty(PropertyName = "heartRateZones")] - public List HeartRateZones { get; set; } - - [JsonProperty(PropertyName = "lastModified")] - public DateTime LastModified { get; set; } - - [JsonProperty(PropertyName = "logId")] - public long LogId { get; set; } - - [JsonProperty(PropertyName = "logType")] - public string LogType { get; set; } - - [JsonProperty(PropertyName = "manualValuesSpecified")] - public ManualValuesSpecified ManualValuesSpecified { get; set; } - - [JsonProperty(PropertyName = "originalDuration")] - public int OriginalDuration { get; set; } - - [JsonProperty(PropertyName = "originalStartTime")] - public DateTimeOffset OriginalStartTime { get; set; } - - [JsonProperty(PropertyName = "pace")] - public double Pace { get; set; } - - [JsonProperty(PropertyName = "source")] - public ActivityLogSource Source { get; set; } - - [JsonProperty(PropertyName = "speed")] - public double Speed { get; set; } - - [JsonProperty(PropertyName = "startTime")] - public DateTimeOffset StartTime { get; set; } - - [JsonProperty(PropertyName = "steps")] - public int Steps { get; set; } - - [JsonProperty(PropertyName = "tcxLink")] - public string TcxLink { get; set; } + } } From 917a09cbf295d70b488ef0fd6b5517eee9769fe0 Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Thu, 28 Sep 2017 17:54:37 +0000 Subject: [PATCH 59/85] Added new serializer function, new method for getting one day's worth of activity, and changes to make use of the new Activity Logs Format --- Fitbit.Portable/FitbitClient.cs | 20 ++++++++++++++------ Fitbit.Portable/IFitbitClient.cs | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 21588425..23031216 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -8,6 +8,7 @@ using System.Net.Http.Headers; using Fitbit.Api.Portable.Models; using Fitbit.Models; +using Newtonsoft.Json; namespace Fitbit.Api.Portable { @@ -947,7 +948,7 @@ public async Task LogActivityAsync(ActivityLog model) /// The max of the number of entries returned (maximum: 20) /// encoded user id, can be null for current logged in user /// ActivityLogsList - public async Task> GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) + public async Task GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)) { //Check to make sure limit is gt 1 and less than 20 limit = limit < 1 || limit > 20 ? 20 : limit; @@ -980,7 +981,9 @@ public async Task LogActivityAsync(ActivityLog model) HttpResponseMessage response = await HttpClient.GetAsync(apiCall); await HandleResponse(response); var responseBody = await response.Content.ReadAsStringAsync(); - return (new JsonDotNetSerializer() { RootProperty = "activities" }).Deserialize>(responseBody); + var settings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.DateTimeOffset }; + ActivityLogsList result = JsonConvert.DeserializeObject(responseBody, settings); + return result; } /// @@ -989,11 +992,16 @@ public async Task LogActivityAsync(ActivityLog model) /// The date of Activities. /// encoded user id, can be null for current logged in user /// ActivityLogsList - public async Task> GetActivityLogsListAsync(DateTime date, string encodedUserId = default(string)) + public async Task GetActivityLogsListAsync(DateTime date, string encodedUserId = default(string)) { - List logsAfterDate = await GetActivityLogsListAsync(null, date, 20, encodedUserId); - List logsOnDate = logsAfterDate?.Where(x => x.StartTime.Date == date.Date).ToList(); - return logsOnDate; + ActivityLogsList logsAfterDate = await GetActivityLogsListAsync(null, date, 20, encodedUserId); + + ActivityLogsList result = new ActivityLogsList() + { + Activities = logsAfterDate?.Activities?.Where(x => x.StartTime.Date == date.Date).ToList() + }; + + return result; } #region HeartRateTimeSeries diff --git a/Fitbit.Portable/IFitbitClient.cs b/Fitbit.Portable/IFitbitClient.cs index 0a7cdc98..f0b916b7 100644 --- a/Fitbit.Portable/IFitbitClient.cs +++ b/Fitbit.Portable/IFitbitClient.cs @@ -41,8 +41,8 @@ public interface IFitbitClient Task LogActivityAsync(ActivityLog model); Task GetHeartRateTimeSeries(DateTime date, DateRangePeriod dateRangePeriod, string userId = "-"); Task GetHeartRateIntraday(DateTime date, HeartRateResolution resolution, string userId = "-"); - Task> GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)); - Task> GetActivityLogsListAsync(DateTime date, string encodedUserId = default(string)); + Task GetActivityLogsListAsync(DateTime? beforeDate, DateTime? afterDate, int limit = 20, string encodedUserId = default(string)); + Task GetActivityLogsListAsync(DateTime date, string encodedUserId = default(string)); } } \ No newline at end of file From d0f7a7d18833d8f01ab41443a23845388a0a3f6a Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Fri, 29 Sep 2017 18:39:36 +0000 Subject: [PATCH 60/85] Adding the ability to init with JsonSerializerSettings that can be used to convert jsjon with time zones --- Fitbit.Portable/JsonDotNetSerializer.cs | 31 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Fitbit.Portable/JsonDotNetSerializer.cs b/Fitbit.Portable/JsonDotNetSerializer.cs index 14abd7d9..086786db 100644 --- a/Fitbit.Portable/JsonDotNetSerializer.cs +++ b/Fitbit.Portable/JsonDotNetSerializer.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using System; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Fitbit.Api.Portable @@ -6,12 +7,12 @@ namespace Fitbit.Api.Portable internal class JsonDotNetSerializer { private readonly JsonSerializer _jsonSerializer; - - public JsonDotNetSerializer() + private readonly JsonSerializerSettings _settings; + public JsonDotNetSerializer(JsonSerializerSettings settings = null) { - JsonSerializerSettings settings = new JsonSerializerSettings(); - settings.Converters.Add(new EmptyDateToMinDateConverter()); - _jsonSerializer = JsonSerializer.CreateDefault(settings); + _settings = settings ?? new JsonSerializerSettings(); + _settings.Converters.Add(new EmptyDateToMinDateConverter()); + _jsonSerializer = JsonSerializer.CreateDefault(_settings); } /// @@ -27,6 +28,22 @@ internal T Deserialize(string data) return default(T); } + if (_settings.DateParseHandling == DateParseHandling.DateTimeOffset ) + { + /* Json.NET conversions do not correctly handle datetimeoffsets by default. + Instead they convert the offset into the local time of the server running the code. + This is problematic for using Fitbit data sets that include the user's timezone info. + In order to get around this, DateParseHandling.DateTimeOffset is set on the JsonConvert serializer. + Unfortunately, Jtoken.Parse does not have this ability and can not be used for this purpose. + On the flip side, JsonConvert does not seem to allow a RootProperty, so right now + only one or the other can be used.*/ + if (!string.IsNullOrWhiteSpace(RootProperty)) + { + throw new Exception("Root property not compatible with DateParseHandling.DateTimeOffset"); + } + return JsonConvert.DeserializeObject(data); + } + JToken o = JToken.Parse(data); return Deserialize(o); } @@ -39,6 +56,8 @@ internal T Deserialize(JToken token) } T result = string.IsNullOrWhiteSpace(RootProperty) ? token.ToObject(_jsonSerializer) : token[RootProperty].ToObject(_jsonSerializer); + + // T result = string.IsNullOrWhiteSpace(RootProperty) ? token.ToObject(_jsonSerializer) : token[RootProperty].ToObject(_jsonSerializer); return result; } } From 445917c2c44c410f1302396e0f2ccaaa1d2c7396 Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Fri, 29 Sep 2017 19:10:29 +0000 Subject: [PATCH 61/85] LastModified to DateTimeOffset --- Fitbit.Portable/Models/Activities.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fitbit.Portable/Models/Activities.cs b/Fitbit.Portable/Models/Activities.cs index 62fe270e..48eca6c0 100644 --- a/Fitbit.Portable/Models/Activities.cs +++ b/Fitbit.Portable/Models/Activities.cs @@ -43,7 +43,7 @@ public class Activities public List HeartRateZones { get; set; } [JsonProperty(PropertyName = "lastModified")] - public DateTime LastModified { get; set; } + public DateTimeOffset LastModified { get; set; } [JsonProperty(PropertyName = "logId")] public long LogId { get; set; } From df0b07e960100ebed36efb28c433f25d0d6c146e Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Fri, 29 Sep 2017 19:15:05 +0000 Subject: [PATCH 62/85] DateOfActivity formatting --- Fitbit.Portable/Models/Activities.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fitbit.Portable/Models/Activities.cs b/Fitbit.Portable/Models/Activities.cs index 48eca6c0..15cd5ba5 100644 --- a/Fitbit.Portable/Models/Activities.cs +++ b/Fitbit.Portable/Models/Activities.cs @@ -25,7 +25,7 @@ public class Activities [JsonProperty(PropertyName = "calories")] public int Calories { get; set; } - public string DateOfActivity => StartTime.Date.ToString("yyyy-MM-dd"); + public string DateOfActivity => StartTime.Date.ToString("MM-dd-yyyy"); [JsonProperty(PropertyName = "distance")] public double Distance { get; set; } From f2cf6038bbf068d3e3f95e2755670e1a1d88a657 Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Fri, 29 Sep 2017 20:46:18 +0000 Subject: [PATCH 63/85] test deserialization error for time zones --- Fitbit.Portable.Tests/ActivityLogTests.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Fitbit.Portable.Tests/ActivityLogTests.cs b/Fitbit.Portable.Tests/ActivityLogTests.cs index 8b330d7a..7c975ea4 100644 --- a/Fitbit.Portable.Tests/ActivityLogTests.cs +++ b/Fitbit.Portable.Tests/ActivityLogTests.cs @@ -54,6 +54,28 @@ public void GetActivityLogsListAsync_Errors() result.ShouldThrow().Which.ApiErrors.Count.Should().Be(1); } + [Test] + [Category("Portable")] + public void ActivityLogsList_JsonParse_Errors() + { + string content = SampleDataHelper.GetContent("GetActivityLogsList2.json"); + var settings = new JsonSerializerSettings() { DateParseHandling = DateParseHandling.DateTimeOffset }; + var serializer = new JsonDotNetSerializer(settings) { RootProperty = "activities" }; + + try + { + serializer.Deserialize(content); + } + catch (FitbitParseException e){ + // Success + } + catch (Exception e) + { + Assert.Fail(); + } + + } + [Test] [Category("Portable")] public void Can_Deserialize_ActivityLogsList() From 8b99612665f999b7aec746a9422a05ae6a2188ae Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Fri, 29 Sep 2017 20:46:36 +0000 Subject: [PATCH 64/85] New parse exception for time zones --- Fitbit.Portable/Fitbit.Portable.csproj | 1 + Fitbit.Portable/FitbitParseException.cs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Fitbit.Portable/FitbitParseException.cs diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj index 29c02486..e41edb1f 100644 --- a/Fitbit.Portable/Fitbit.Portable.csproj +++ b/Fitbit.Portable/Fitbit.Portable.csproj @@ -39,6 +39,7 @@ + diff --git a/Fitbit.Portable/FitbitParseException.cs b/Fitbit.Portable/FitbitParseException.cs new file mode 100644 index 00000000..7c24a8b0 --- /dev/null +++ b/Fitbit.Portable/FitbitParseException.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Fitbit.Api.Portable +{ + public class FitbitParseException: Exception + { + private const string DefaultMessage = "Error occured while trying to parse JSON."; + public FitbitParseException(Exception ex, string message = DefaultMessage) : base(message, ex) + { + + } + + public FitbitParseException(string message = DefaultMessage) : base(message) + { + + } + } +} From 8258bd7985c02016925a3b3cb86a77840da63147 Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Fri, 29 Sep 2017 20:47:57 +0000 Subject: [PATCH 65/85] Throw FitbitParseException --- Fitbit.Portable/JsonDotNetSerializer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Fitbit.Portable/JsonDotNetSerializer.cs b/Fitbit.Portable/JsonDotNetSerializer.cs index 086786db..7da23b01 100644 --- a/Fitbit.Portable/JsonDotNetSerializer.cs +++ b/Fitbit.Portable/JsonDotNetSerializer.cs @@ -39,7 +39,8 @@ Instead they convert the offset into the local time of the server running the co only one or the other can be used.*/ if (!string.IsNullOrWhiteSpace(RootProperty)) { - throw new Exception("Root property not compatible with DateParseHandling.DateTimeOffset"); + var message = "Error occured by parsing JSON. Root property not compatible with DateParseHandling.DateTimeOffset"; + throw new FitbitParseException(message); } return JsonConvert.DeserializeObject(data); } From c40a44861547e12caeded1644afaa9633764a473 Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Fri, 29 Sep 2017 20:48:19 +0000 Subject: [PATCH 66/85] Use JsonDotNetSerializer class --- Fitbit.Portable/FitbitClient.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 23031216..6607ce02 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -980,9 +980,12 @@ public async Task LogActivityAsync(ActivityLog model) HttpResponseMessage response = await HttpClient.GetAsync(apiCall); await HandleResponse(response); - var responseBody = await response.Content.ReadAsStringAsync(); - var settings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.DateTimeOffset }; - ActivityLogsList result = JsonConvert.DeserializeObject(responseBody, settings); + + string responseBody = await response.Content.ReadAsStringAsync(); + JsonSerializerSettings settings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.DateTimeOffset }; + JsonDotNetSerializer serializer = new JsonDotNetSerializer(settings); + ActivityLogsList result = serializer.Deserialize(responseBody); + return result; } From a2fa439374e1e82d99d88b748fb2e5e8b0e6ddb7 Mon Sep 17 00:00:00 2001 From: Dwayne Love Date: Mon, 2 Oct 2017 11:05:53 -0700 Subject: [PATCH 67/85] XML comment update --- Fitbit.Portable/FitbitClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 6607ce02..2ccecc0d 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -990,7 +990,7 @@ public async Task LogActivityAsync(ActivityLog model) } /// - /// Retrieves a list of a user's activity log entries on a given day + /// Retrieves a list of a user's activity log entries on a given day (Max: 20 records) /// /// The date of Activities. /// encoded user id, can be null for current logged in user From d0847e88abbf650fdfcb9336e3e5ca03ea5adee4 Mon Sep 17 00:00:00 2001 From: Josh Hoffman Date: Tue, 17 Oct 2017 16:39:40 -0700 Subject: [PATCH 68/85] add IsNullOrWhiteSpace guard for userId param of GetHeartRateTimeSeries() This prevents errors in HttpClient if the URL is malformed by omission of userId resulting in user//activities. In this case, the current version of HttpClient exhibits the behvior of switching from https to http (causing a fitbit error) --- Fitbit.Portable/FitbitClient.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 2ccecc0d..44bbf27a 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -1030,6 +1030,11 @@ private async Task ProcessHeartRateTimeSeries(string /// public async Task GetHeartRateTimeSeries(DateTime date, DateRangePeriod dateRangePeriod, string userId = "-") { + if (string.IsNullOrWhiteSpace(userId)) + { + userId = "-"; + } + string path = $"1.1/user/{userId}/activities/heart/date/{date:yyyy-MM-dd}/{dateRangePeriod.GetStringValue()}.json"; string apiCall = FitbitClientHelperExtensions.ToFullUrl(path); return await ProcessHeartRateTimeSeries(apiCall); From 181f717926db6aec1f8d9f0528edef9e7e894d3e Mon Sep 17 00:00:00 2001 From: Josh Hoffman Date: Wed, 18 Oct 2017 13:01:19 -0700 Subject: [PATCH 69/85] rework GetHeartRateTimeSeries to correctly utilize FitbitClientHelperExtensions.ToFullUrl(). Add better documentation on ToFullUrl() --- Fitbit.Portable/FitbitClient.cs | 9 ++------- Fitbit.Portable/FitbitClientHelperExtensions.cs | 6 ++++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index 44bbf27a..e6cd102f 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -1030,13 +1030,8 @@ private async Task ProcessHeartRateTimeSeries(string /// public async Task GetHeartRateTimeSeries(DateTime date, DateRangePeriod dateRangePeriod, string userId = "-") { - if (string.IsNullOrWhiteSpace(userId)) - { - userId = "-"; - } - - string path = $"1.1/user/{userId}/activities/heart/date/{date:yyyy-MM-dd}/{dateRangePeriod.GetStringValue()}.json"; - string apiCall = FitbitClientHelperExtensions.ToFullUrl(path); + string url = "1.1/user/{0}/" + "activities/heart/date/" + date.ToString("yyyy-MM-dd") + "/"+dateRangePeriod.GetStringValue() + ".json"; + string apiCall = FitbitClientHelperExtensions.ToFullUrl(url, userId); return await ProcessHeartRateTimeSeries(apiCall); } diff --git a/Fitbit.Portable/FitbitClientHelperExtensions.cs b/Fitbit.Portable/FitbitClientHelperExtensions.cs index 8498bc76..865788d5 100644 --- a/Fitbit.Portable/FitbitClientHelperExtensions.cs +++ b/Fitbit.Portable/FitbitClientHelperExtensions.cs @@ -10,10 +10,12 @@ internal static class FitbitClientHelperExtensions /// /// Converts the REST api resource into the fully qualified url /// - /// + /// + ///"Format String" with one "Format Item" as a placeholder for "UserId" + /// /// /// - /// + /// Fully qualified url internal static string ToFullUrl(string apiCall, string encodedUserId = default(string), params object[] args) { string userSignifier = "-"; //used for current user From 26b2fb61a8f197b81480a800abe9d366798aeb25 Mon Sep 17 00:00:00 2001 From: crysfitabase Date: Mon, 23 Jul 2018 11:20:05 -0700 Subject: [PATCH 70/85] Cast HttpStatusCodes to int --- Fitbit.Portable/FitbitClient.cs | 2 +- Fitbit.Portable/FitbitRequestException.cs | 2 +- Fitbit.Portable/FitbitTokenException.cs | 2 +- Fitbit.Portable/OAuth2/OAuth2AutoRefreshInterceptor.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs index e6cd102f..84059670 100644 --- a/Fitbit.Portable/FitbitClient.cs +++ b/Fitbit.Portable/FitbitClient.cs @@ -1142,7 +1142,7 @@ private async Task HandleResponse(HttpResponseMessage response) } // if we've got here then something unexpected has occured - throw new FitbitException($"An error has occured. Please see error list for details - {response.StatusCode}", errors); + throw new FitbitException($"An error has occured. Please see error list for details - {(int)response.StatusCode}", errors); } } diff --git a/Fitbit.Portable/FitbitRequestException.cs b/Fitbit.Portable/FitbitRequestException.cs index 5e865199..f89bedd0 100644 --- a/Fitbit.Portable/FitbitRequestException.cs +++ b/Fitbit.Portable/FitbitRequestException.cs @@ -11,7 +11,7 @@ public class FitbitRequestException : FitbitException public HttpResponseMessage Response { get; set; } public FitbitRequestException(HttpResponseMessage response, IEnumerable errors, string message = default(string), Exception innerEx = null) - : base(message ?? $"Fitbit Request exception - Http Status Code: {response.StatusCode} - see errors for more details.", errors, innerEx) + : base(message ?? $"Fitbit Request exception - Http Status Code: {(int)response.StatusCode} - see errors for more details.", errors, innerEx) { this.Response = response; } diff --git a/Fitbit.Portable/FitbitTokenException.cs b/Fitbit.Portable/FitbitTokenException.cs index 1cd45318..d2c70d9a 100644 --- a/Fitbit.Portable/FitbitTokenException.cs +++ b/Fitbit.Portable/FitbitTokenException.cs @@ -7,7 +7,7 @@ namespace Fitbit.Api.Portable public class FitbitTokenException : FitbitRequestException { public FitbitTokenException(HttpResponseMessage response, IEnumerable errors = null, string message = default(string)) - : base(response, errors, message ?? $"Fitbit Token exception - HTTP Status Code-- {response.StatusCode} -- see errors for more details.") + : base(response, errors, message ?? $"Fitbit Token exception - HTTP Status Code-- {(int)response.StatusCode} -- see errors for more details.") { } } diff --git a/Fitbit.Portable/OAuth2/OAuth2AutoRefreshInterceptor.cs b/Fitbit.Portable/OAuth2/OAuth2AutoRefreshInterceptor.cs index 0f20f2ae..67528bba 100644 --- a/Fitbit.Portable/OAuth2/OAuth2AutoRefreshInterceptor.cs +++ b/Fitbit.Portable/OAuth2/OAuth2AutoRefreshInterceptor.cs @@ -44,7 +44,7 @@ public async Task InterceptResponse(Task Date: Mon, 23 Jul 2018 11:28:15 -0700 Subject: [PATCH 71/85] Include System.Treading.Tasks nuget package --- Fitbit.Portable.Tests/packages.config | 1 + 1 file changed, 1 insertion(+) diff --git a/Fitbit.Portable.Tests/packages.config b/Fitbit.Portable.Tests/packages.config index dd6cea1f..9b030bdf 100644 --- a/Fitbit.Portable.Tests/packages.config +++ b/Fitbit.Portable.Tests/packages.config @@ -11,4 +11,5 @@ + \ No newline at end of file From 7eee694c02692d6fd1e45824b427051005637788 Mon Sep 17 00:00:00 2001 From: crysfitabase Date: Mon, 23 Jul 2018 12:49:36 -0700 Subject: [PATCH 72/85] Revert "Include System.Treading.Tasks nuget package" This reverts commit 0c837b6a38dfa15b1ad67bc659ede3ff46460b2e. --- Fitbit.Portable.Tests/packages.config | 1 - 1 file changed, 1 deletion(-) diff --git a/Fitbit.Portable.Tests/packages.config b/Fitbit.Portable.Tests/packages.config index 9b030bdf..dd6cea1f 100644 --- a/Fitbit.Portable.Tests/packages.config +++ b/Fitbit.Portable.Tests/packages.config @@ -11,5 +11,4 @@ - \ No newline at end of file From e8f70fe2586fbb1480c0cb9a771dc8bac51fbe7d Mon Sep 17 00:00:00 2001 From: crysfitabase Date: Mon, 23 Jul 2018 14:01:29 -0700 Subject: [PATCH 73/85] Fix System.Threading.Tasks reference --- Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj | 6 +++--- Fitbit.Portable.Tests/app.config | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj index 160581b5..702bdef2 100644 --- a/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj +++ b/Fitbit.Portable.Tests/Fitbit.Portable.Tests.csproj @@ -70,10 +70,10 @@ ..\Fitbit\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll - - ..\Fitbit\packages\Microsoft.Bcl.1.1.10\lib\portable-net40+sl5+win8+wp8+wpa81\System.Threading.Tasks.dll - + + True + diff --git a/Fitbit.Portable.Tests/app.config b/Fitbit.Portable.Tests/app.config index 1c087674..b2dcf31e 100644 --- a/Fitbit.Portable.Tests/app.config +++ b/Fitbit.Portable.Tests/app.config @@ -12,7 +12,7 @@ - + From 9f5ca6e584189b4f3f14e3f203053b7d8a966267 Mon Sep 17 00:00:00 2001 From: Adam Storr Date: Mon, 31 Dec 2018 21:09:59 +0000 Subject: [PATCH 74/85] remove oauth 1 projects; no longer required --- Fitbit/Fitbit.OAuth1Migration.sln | 28 ---- .../AuthenticatorTests.cs | 35 ---- .../Fitbit.OAuth1Migration.Tests.csproj | 153 ------------------ .../Properties/AssemblyInfo.cs | 36 ----- .../packages.config | 12 -- .../Fitbit.OAuth1Migration/Authenticator.cs | 91 ----------- .../Fitbit.OAuth1Migration/Constants.cs | 28 ---- .../Fitbit.OAuth1Migration.csproj | 100 ------------ .../FitbitClientOA1Factory.cs | 61 ------- .../Properties/AssemblyInfo.cs | 36 ----- .../Fitbit.OAuth1Migration/app.config | 11 -- .../Fitbit.OAuth1Migration/packages.config | 10 -- 12 files changed, 601 deletions(-) delete mode 100644 Fitbit/Fitbit.OAuth1Migration.sln delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration.Tests/AuthenticatorTests.cs delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration.Tests/Fitbit.OAuth1Migration.Tests.csproj delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration.Tests/Properties/AssemblyInfo.cs delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration.Tests/packages.config delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration/Authenticator.cs delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration/Constants.cs delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration/Fitbit.OAuth1Migration.csproj delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration/FitbitClientOA1Factory.cs delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration/Properties/AssemblyInfo.cs delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration/app.config delete mode 100644 OAuth1Migration/Fitbit.OAuth1Migration/packages.config diff --git a/Fitbit/Fitbit.OAuth1Migration.sln b/Fitbit/Fitbit.OAuth1Migration.sln deleted file mode 100644 index 16ec5f72..00000000 --- a/Fitbit/Fitbit.OAuth1Migration.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fitbit.OAuth1Migration", "..\OAuth1Migration\Fitbit.OAuth1Migration\Fitbit.OAuth1Migration.csproj", "{8FCFBC6C-36B0-4117-814A-2C2EA43F44AC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fitbit.OAuth1Migration.Tests", "..\OAuth1Migration\Fitbit.OAuth1Migration.Tests\Fitbit.OAuth1Migration.Tests.csproj", "{346C808A-9ACA-467F-B313-1368EA5306FF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8FCFBC6C-36B0-4117-814A-2C2EA43F44AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8FCFBC6C-36B0-4117-814A-2C2EA43F44AC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8FCFBC6C-36B0-4117-814A-2C2EA43F44AC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8FCFBC6C-36B0-4117-814A-2C2EA43F44AC}.Release|Any CPU.Build.0 = Release|Any CPU - {346C808A-9ACA-467F-B313-1368EA5306FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {346C808A-9ACA-467F-B313-1368EA5306FF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {346C808A-9ACA-467F-B313-1368EA5306FF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {346C808A-9ACA-467F-B313-1368EA5306FF}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/OAuth1Migration/Fitbit.OAuth1Migration.Tests/AuthenticatorTests.cs b/OAuth1Migration/Fitbit.OAuth1Migration.Tests/AuthenticatorTests.cs deleted file mode 100644 index 35f451f1..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration.Tests/AuthenticatorTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Fitbit.Api.Portable; -using Fitbit.Models; -using NUnit.Framework; - -namespace Fitbit.OAuth1Migration.Tests -{ - [TestFixture] - public class AuthenticatorTests - { - [Test] [Category("Portable")] - public void Constructor() - { - var authenticator = new Authenticator("key", "secret"); - Assert.IsNotNull(authenticator); - Assert.AreEqual("key", authenticator.ConsumerKey); - Assert.AreEqual("secret", authenticator.ConsumerSecret); - } - - [Test] [Category("Portable")] - public void Generate_Auth_Url_ForceLogout_True() - { - var authenticator = new Authenticator("key", "secret"); - var url = authenticator.GenerateAuthUrlFromRequestToken(new RequestToken {Token = "something"}, true); - Assert.AreEqual("https://api.fitbit.com/oauth/logout_and_authorize?oauth_token=something", url); - } - - [Test] [Category("Portable")] - public void Generate_Auth_Url_ForceLogout_False() - { - var authenticator = new Authenticator("key", "secret"); - var url = authenticator.GenerateAuthUrlFromRequestToken(new RequestToken { Token = "something" }, false); - Assert.AreEqual("https://api.fitbit.com/oauth/authorize?oauth_token=something", url); - } - } -} diff --git a/OAuth1Migration/Fitbit.OAuth1Migration.Tests/Fitbit.OAuth1Migration.Tests.csproj b/OAuth1Migration/Fitbit.OAuth1Migration.Tests/Fitbit.OAuth1Migration.Tests.csproj deleted file mode 100644 index a6d91ed3..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration.Tests/Fitbit.OAuth1Migration.Tests.csproj +++ /dev/null @@ -1,153 +0,0 @@ - - - - Debug - AnyCPU - {346C808A-9ACA-467F-B313-1368EA5306FF} - Library - Properties - Fitbit.OAuth1Migration.Tests - Fitbit.OAuth1Migration.Tests - v4.5.2 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\Fitbit\packages\AsyncOAuth.0.8.4\lib\AsyncOAuth.dll - True - - - ..\..\Fitbit\packages\Fitbit.NET.2.0.1-RC3\lib\net451\Fitbit.Portable.dll - True - - - ..\..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll - True - - - ..\..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll - True - - - ..\..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - True - - - ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll - True - - - ..\..\Fitbit\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll - False - - - ..\..\Fitbit\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll - False - - - ..\..\Fitbit\packages\NUnit.3.0.1\lib\net45\nunit.framework.dll - True - - - ..\..\Fitbit\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll - False - - - ..\..\Fitbit\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll - False - - - - - - ..\..\Fitbit\packages\Microsoft.Net.Http.2.2.22\lib\net45\System.Net.Http.Extensions.dll - True - - - ..\..\Fitbit\packages\Microsoft.Net.Http.2.2.22\lib\net45\System.Net.Http.Primitives.dll - True - - - - - - - - - - - - - - - - - - - - - - - {8fcfbc6c-36b0-4117-814a-2c2ea43f44ac} - Fitbit.OAuth1Migration - - - - - - - - - - False - - - False - - - False - - - False - - - - - - - - - - - - - \ No newline at end of file diff --git a/OAuth1Migration/Fitbit.OAuth1Migration.Tests/Properties/AssemblyInfo.cs b/OAuth1Migration/Fitbit.OAuth1Migration.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index f3afebd7..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("Fitbit.OAuth1Migration.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Fitbit.OAuth1Migration.Tests")] -[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("346c808a-9aca-467f-b313-1368ea5306ff")] - -// 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/OAuth1Migration/Fitbit.OAuth1Migration.Tests/packages.config b/OAuth1Migration/Fitbit.OAuth1Migration.Tests/packages.config deleted file mode 100644 index 54da0808..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration.Tests/packages.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/OAuth1Migration/Fitbit.OAuth1Migration/Authenticator.cs b/OAuth1Migration/Fitbit.OAuth1Migration/Authenticator.cs deleted file mode 100644 index 4918ea7a..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration/Authenticator.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using AsyncOAuth; -using Fitbit.Models; -using RequestToken = Fitbit.Models.RequestToken; - -namespace Fitbit.OAuth1Migration -{ - public class Authenticator - { - public string ConsumerKey { get; private set; } - public string ConsumerSecret { get; private set; } - - public Authenticator(string consumerKey, string consumerSecret) - { - ConsumerKey = consumerKey; - ConsumerSecret = consumerSecret; - } - - public string GenerateAuthUrlFromRequestToken(RequestToken token, bool forceLogoutBeforeAuth) - { - var url = Constants.BaseApiUrl + (forceLogoutBeforeAuth ? Constants.LogoutAndAuthorizeUri : Constants.AuthorizeUri); - return string.Format("{0}?oauth_token={1}", url, token.Token); - } - - /// - /// First step in the OAuth process is to ask Fitbit for a temporary request token. - /// From this you should store the RequestToken returned for later processing the auth token. - /// - /// - public async Task GetRequestTokenAsync() - { - // create authorizer - var authorizer = new OAuthAuthorizer(ConsumerKey, ConsumerSecret); - - // get request token - var tokenResponse = await authorizer.GetRequestToken(Constants.BaseApiUrl + Constants.TemporaryCredentialsRequestTokenUri); - var requestToken = tokenResponse.Token; - - // return the request token - return new RequestToken - { - Token = requestToken.Key, - Secret = requestToken.Secret - }; - } - - /// - /// For Desktop authentication. Your code should direct the user to the FitBit website to get - /// Their pin, they can then enter it here. - /// - /// - /// - /// - public async Task GetAuthCredentialFromPinAsync(string pin, RequestToken token) - { - var oauthRequestToken = new AsyncOAuth.RequestToken(token.Token, token.Secret); - var authorizer = new OAuthAuthorizer(ConsumerKey, ConsumerSecret); - var accessTokenResponse = await authorizer.GetAccessToken(Constants.BaseApiUrl + Constants.TemporaryCredentialsAccessTokenUri, oauthRequestToken, pin); - // save access token. - var accessToken = accessTokenResponse.Token; - return new AuthCredential - { - AuthToken = accessToken.Key, - AuthTokenSecret = accessToken.Secret - }; - } - - public async Task ProcessApprovedAuthCallbackAsync(RequestToken token) - { - if (token == null) - throw new ArgumentNullException("token", "RequestToken cannot be null"); - - if (string.IsNullOrWhiteSpace(token.Token)) - throw new ArgumentNullException("token", "RequestToken.Token must not be null"); - - var oauthRequestToken = new AsyncOAuth.RequestToken(token.Token, token.Secret); - var authorizer = new OAuthAuthorizer(ConsumerKey, ConsumerSecret); - var accessToken = await authorizer.GetAccessToken(Constants.BaseApiUrl + Constants.TemporaryCredentialsAccessTokenUri, oauthRequestToken, token.Verifier); - - var result = new AuthCredential - { - AuthToken = accessToken.Token.Key, - AuthTokenSecret = accessToken.Token.Secret, - UserId = accessToken.ExtraData["encoded_user_id"].FirstOrDefault() - }; - return result; - } - } -} \ No newline at end of file diff --git a/OAuth1Migration/Fitbit.OAuth1Migration/Constants.cs b/OAuth1Migration/Fitbit.OAuth1Migration/Constants.cs deleted file mode 100644 index bf94ba47..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration/Constants.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Fitbit.OAuth1Migration -{ - internal class Constants - { - public const string BaseApiUrl = "https://api.fitbit.com/"; - public const string TemporaryCredentialsRequestTokenUri = "oauth/request_token"; - public const string TemporaryCredentialsAccessTokenUri = "oauth/access_token"; - public const string AuthorizeUri = "oauth/authorize"; - public const string LogoutAndAuthorizeUri = "oauth/logout_and_authorize"; - - public class Headers - { - public const string XFitbitSubscriberId = "X-Fitbit-Subscriber-Id"; - } - - public class Formatting - { - public const string TrailingSlash = "{0}/"; - public const string LeadingDash = "-{0}"; - } - } -} diff --git a/OAuth1Migration/Fitbit.OAuth1Migration/Fitbit.OAuth1Migration.csproj b/OAuth1Migration/Fitbit.OAuth1Migration/Fitbit.OAuth1Migration.csproj deleted file mode 100644 index 76aaaec2..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration/Fitbit.OAuth1Migration.csproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Debug - AnyCPU - {8FCFBC6C-36B0-4117-814A-2C2EA43F44AC} - Library - Properties - Fitbit.OAuth1Migration - Fitbit.OAuth1Migration - v4.5.2 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\Fitbit\packages\AsyncOAuth.0.8.4\lib\AsyncOAuth.dll - True - - - ..\..\Fitbit\packages\Fitbit.NET.2.0.020160302.3-RC2-Dev\lib\net451\Fitbit.Portable.dll - True - - - ..\..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll - True - - - ..\..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll - True - - - ..\..\Fitbit\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - True - - - ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll - True - - - - - - ..\..\Fitbit\packages\Microsoft.Net.Http.2.2.22\lib\net45\System.Net.Http.Extensions.dll - True - - - ..\..\Fitbit\packages\Microsoft.Net.Http.2.2.22\lib\net45\System.Net.Http.Primitives.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OAuth1Migration/Fitbit.OAuth1Migration/FitbitClientOA1Factory.cs b/OAuth1Migration/Fitbit.OAuth1Migration/FitbitClientOA1Factory.cs deleted file mode 100644 index 49cfa70b..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration/FitbitClientOA1Factory.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Net.Http; -using Fitbit.Api.Portable; - -namespace Fitbit.OAuth1Migration -{ - public static class FitbitClientOA1Factory - { - /// - /// Private base constructor which takes it all and constructs or throws exceptions as appropriately - /// - /// - /// - /// - /// - /// - public static FitbitClient Create(string consumerKey, string consumerSecret, string accessToken, string accessSecret, IFitbitInterceptor interceptor = null) - { - - #region Parameter checking - if (string.IsNullOrWhiteSpace(consumerKey)) - { - throw new ArgumentNullException(nameof(consumerKey), "ConsumerKey must not be empty or null"); - } - - if (string.IsNullOrWhiteSpace(consumerSecret)) - { - throw new ArgumentNullException(nameof(consumerSecret), "ConsumerSecret must not be empty or null"); - } - - if (string.IsNullOrWhiteSpace(accessToken)) - { - throw new ArgumentNullException(nameof(accessToken), "AccessToken must not be empty or null"); - } - - if (string.IsNullOrWhiteSpace(accessSecret)) - { - throw new ArgumentNullException(nameof(accessSecret), "AccessSecret must not be empty or null"); - } - #endregion - - if (interceptor != null) - { - return new FitbitClient(mh => - { - //Injecting the Message Handler provided by FitbitClient library (mh) allows us to invoke any IFitbitInterceptor that has been registered - return AsyncOAuth.OAuthUtility.CreateOAuthClient(mh, consumerKey, consumerSecret, - new AsyncOAuth.AccessToken(accessToken, accessSecret)); - }, interceptor); - } - else - { - return new FitbitClient(mh => - { - return AsyncOAuth.OAuthUtility.CreateOAuthClient(consumerKey, consumerSecret, - new AsyncOAuth.AccessToken(accessToken, accessSecret)); - }); - } - } - } -} diff --git a/OAuth1Migration/Fitbit.OAuth1Migration/Properties/AssemblyInfo.cs b/OAuth1Migration/Fitbit.OAuth1Migration/Properties/AssemblyInfo.cs deleted file mode 100644 index fd802a66..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("Fitbit.OAuth1Migration")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Fitbit.OAuth1Migration")] -[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("8fcfbc6c-36b0-4117-814a-2c2ea43f44ac")] - -// 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/OAuth1Migration/Fitbit.OAuth1Migration/app.config b/OAuth1Migration/Fitbit.OAuth1Migration/app.config deleted file mode 100644 index 68f34666..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/OAuth1Migration/Fitbit.OAuth1Migration/packages.config b/OAuth1Migration/Fitbit.OAuth1Migration/packages.config deleted file mode 100644 index 369fe109..00000000 --- a/OAuth1Migration/Fitbit.OAuth1Migration/packages.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file From 6797d8ceee4d4767a9419a411af2960d91d97bea Mon Sep 17 00:00:00 2001 From: Adam Storr Date: Mon, 31 Dec 2018 21:13:15 +0000 Subject: [PATCH 75/85] remove fitbit live debug; no longer required, over complicating --- .../App_Start/BundleConfig.cs | 31 - .../App_Start/FilterConfig.cs | 13 - .../App_Start/IdentityConfig.cs | 109 - .../App_Start/RouteConfig.cs | 23 - .../App_Start/Startup.Auth.cs | 68 - Fitbit.Portable.DebugSite/Content/Site.css | 24 - .../Content/bootstrap-theme.css | 384 - .../Content/bootstrap-theme.min.css | 1 - .../Content/bootstrap.css | 6805 ------------ .../Content/bootstrap.min.css | 9 - .../Controllers/AccountController.cs | 485 - .../Controllers/FitbitController.cs | 241 - .../Controllers/HomeController.cs | 30 - .../Controllers/ManageController.cs | 387 - .../Fitbit.Portable.DebugSite.csproj | 292 - Fitbit.Portable.DebugSite/Global.asax | 1 - Fitbit.Portable.DebugSite/Global.asax.cs | 21 - .../Models/AccountViewModels.cs | 112 - .../Models/IdentityModels.cs | 33 - .../Models/ManageViewModels.cs | 86 - Fitbit.Portable.DebugSite/Project_Readme.html | 151 - .../Properties/AssemblyInfo.cs | 35 - .../Scripts/_references.js | Bin 396 -> 0 bytes .../Scripts/bootstrap.js | 1999 ---- .../Scripts/bootstrap.min.js | 6 - .../Scripts/jquery-1.10.2.intellisense.js | 2657 ----- .../Scripts/jquery-1.10.2.js | 9789 ----------------- .../Scripts/jquery-1.10.2.min.js | 6 - .../Scripts/jquery-1.10.2.min.map | 1 - .../Scripts/jquery.validate-vsdoc.js | 1288 --- .../Scripts/jquery.validate.js | 1231 --- .../Scripts/jquery.validate.min.js | 2 - .../Scripts/jquery.validate.unobtrusive.js | 410 - .../jquery.validate.unobtrusive.min.js | 19 - .../Scripts/modernizr-2.6.2.js | 1393 --- Fitbit.Portable.DebugSite/Scripts/respond.js | 340 - .../Scripts/respond.min.js | 20 - Fitbit.Portable.DebugSite/Startup.cs | 14 - .../Views/Account/ConfirmEmail.cshtml | 10 - .../Account/ExternalLoginConfirmation.cshtml | 36 - .../Views/Account/ExternalLoginFailure.cshtml | 8 - .../Views/Account/ForgotPassword.cshtml | 29 - .../Account/ForgotPasswordConfirmation.cshtml | 13 - .../Views/Account/Login.cshtml | 63 - .../Views/Account/Register.cshtml | 41 - .../Views/Account/ResetPassword.cshtml | 42 - .../Account/ResetPasswordConfirmation.cshtml | 12 - .../Views/Account/SendCode.cshtml | 24 - .../Views/Account/VerifyCode.cshtml | 38 - .../Account/_ExternalLoginsListPartial.cshtml | 28 - .../Views/Fitbit/Callback.cshtml | 25 - .../Views/Fitbit/LastWeekSteps.cshtml | 18 - .../Views/Fitbit/TestToken.cshtml | 21 - .../Views/Home/About.cshtml | 7 - .../Views/Home/Contact.cshtml | 17 - .../Views/Home/Index.cshtml | 21 - .../Views/Manage/AddPhoneNumber.cshtml | 29 - .../Views/Manage/ChangePassword.cshtml | 40 - .../Views/Manage/Index.cshtml | 84 - .../Views/Manage/ManageLogins.cshtml | 70 - .../Views/Manage/SetPassword.cshtml | 39 - .../Views/Manage/VerifyPhoneNumber.cshtml | 31 - .../Views/Shared/Error.cshtml | 9 - .../Views/Shared/Lockout.cshtml | 10 - .../Views/Shared/_Layout.cshtml | 44 - .../Views/Shared/_LoginPartial.cshtml | 22 - Fitbit.Portable.DebugSite/Views/Web.config | 35 - .../Views/_ViewStart.cshtml | 3 - Fitbit.Portable.DebugSite/Web.Debug.config | 30 - Fitbit.Portable.DebugSite/Web.Release.config | 31 - Fitbit.Portable.DebugSite/Web.config | 99 - Fitbit.Portable.DebugSite/favicon.ico | Bin 32038 -> 0 bytes .../fonts/glyphicons-halflings-regular.eot | Bin 14079 -> 0 bytes .../fonts/glyphicons-halflings-regular.svg | 228 - .../fonts/glyphicons-halflings-regular.ttf | Bin 29512 -> 0 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 16448 -> 0 bytes Fitbit.Portable.DebugSite/packages.config | 31 - Fitbit/Fitbit-Live-Debug.sln | 41 - 78 files changed, 29845 deletions(-) delete mode 100644 Fitbit.Portable.DebugSite/App_Start/BundleConfig.cs delete mode 100644 Fitbit.Portable.DebugSite/App_Start/FilterConfig.cs delete mode 100644 Fitbit.Portable.DebugSite/App_Start/IdentityConfig.cs delete mode 100644 Fitbit.Portable.DebugSite/App_Start/RouteConfig.cs delete mode 100644 Fitbit.Portable.DebugSite/App_Start/Startup.Auth.cs delete mode 100644 Fitbit.Portable.DebugSite/Content/Site.css delete mode 100644 Fitbit.Portable.DebugSite/Content/bootstrap-theme.css delete mode 100644 Fitbit.Portable.DebugSite/Content/bootstrap-theme.min.css delete mode 100644 Fitbit.Portable.DebugSite/Content/bootstrap.css delete mode 100644 Fitbit.Portable.DebugSite/Content/bootstrap.min.css delete mode 100644 Fitbit.Portable.DebugSite/Controllers/AccountController.cs delete mode 100644 Fitbit.Portable.DebugSite/Controllers/FitbitController.cs delete mode 100644 Fitbit.Portable.DebugSite/Controllers/HomeController.cs delete mode 100644 Fitbit.Portable.DebugSite/Controllers/ManageController.cs delete mode 100644 Fitbit.Portable.DebugSite/Fitbit.Portable.DebugSite.csproj delete mode 100644 Fitbit.Portable.DebugSite/Global.asax delete mode 100644 Fitbit.Portable.DebugSite/Global.asax.cs delete mode 100644 Fitbit.Portable.DebugSite/Models/AccountViewModels.cs delete mode 100644 Fitbit.Portable.DebugSite/Models/IdentityModels.cs delete mode 100644 Fitbit.Portable.DebugSite/Models/ManageViewModels.cs delete mode 100644 Fitbit.Portable.DebugSite/Project_Readme.html delete mode 100644 Fitbit.Portable.DebugSite/Properties/AssemblyInfo.cs delete mode 100644 Fitbit.Portable.DebugSite/Scripts/_references.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/bootstrap.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/bootstrap.min.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery-1.10.2.intellisense.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery-1.10.2.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery-1.10.2.min.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery-1.10.2.min.map delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery.validate-vsdoc.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery.validate.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery.validate.min.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery.validate.unobtrusive.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/jquery.validate.unobtrusive.min.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/modernizr-2.6.2.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/respond.js delete mode 100644 Fitbit.Portable.DebugSite/Scripts/respond.min.js delete mode 100644 Fitbit.Portable.DebugSite/Startup.cs delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/ConfirmEmail.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/ExternalLoginConfirmation.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/ExternalLoginFailure.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/ForgotPassword.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/ForgotPasswordConfirmation.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/Login.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/Register.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/ResetPassword.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/ResetPasswordConfirmation.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/SendCode.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/VerifyCode.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Account/_ExternalLoginsListPartial.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Fitbit/Callback.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Fitbit/LastWeekSteps.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Fitbit/TestToken.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Home/About.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Home/Contact.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Home/Index.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Manage/AddPhoneNumber.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Manage/ChangePassword.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Manage/Index.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Manage/ManageLogins.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Manage/SetPassword.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Manage/VerifyPhoneNumber.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Shared/Error.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Shared/Lockout.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Shared/_Layout.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Shared/_LoginPartial.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Views/Web.config delete mode 100644 Fitbit.Portable.DebugSite/Views/_ViewStart.cshtml delete mode 100644 Fitbit.Portable.DebugSite/Web.Debug.config delete mode 100644 Fitbit.Portable.DebugSite/Web.Release.config delete mode 100644 Fitbit.Portable.DebugSite/Web.config delete mode 100644 Fitbit.Portable.DebugSite/favicon.ico delete mode 100644 Fitbit.Portable.DebugSite/fonts/glyphicons-halflings-regular.eot delete mode 100644 Fitbit.Portable.DebugSite/fonts/glyphicons-halflings-regular.svg delete mode 100644 Fitbit.Portable.DebugSite/fonts/glyphicons-halflings-regular.ttf delete mode 100644 Fitbit.Portable.DebugSite/fonts/glyphicons-halflings-regular.woff delete mode 100644 Fitbit.Portable.DebugSite/packages.config delete mode 100644 Fitbit/Fitbit-Live-Debug.sln diff --git a/Fitbit.Portable.DebugSite/App_Start/BundleConfig.cs b/Fitbit.Portable.DebugSite/App_Start/BundleConfig.cs deleted file mode 100644 index 48e3639e..00000000 --- a/Fitbit.Portable.DebugSite/App_Start/BundleConfig.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Web; -using System.Web.Optimization; - -namespace SampleWebMVCOAuth2 -{ - public class BundleConfig - { - // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 - public static void RegisterBundles(BundleCollection bundles) - { - bundles.Add(new ScriptBundle("~/bundles/jquery").Include( - "~/Scripts/jquery-{version}.js")); - - bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( - "~/Scripts/jquery.validate*")); - - // Use the development version of Modernizr to develop with and learn from. Then, when you're - // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. - bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( - "~/Scripts/modernizr-*")); - - bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( - "~/Scripts/bootstrap.js", - "~/Scripts/respond.js")); - - bundles.Add(new StyleBundle("~/Content/css").Include( - "~/Content/bootstrap.css", - "~/Content/site.css")); - } - } -} diff --git a/Fitbit.Portable.DebugSite/App_Start/FilterConfig.cs b/Fitbit.Portable.DebugSite/App_Start/FilterConfig.cs deleted file mode 100644 index bfa4332b..00000000 --- a/Fitbit.Portable.DebugSite/App_Start/FilterConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Web; -using System.Web.Mvc; - -namespace SampleWebMVCOAuth2 -{ - public class FilterConfig - { - public static void RegisterGlobalFilters(GlobalFilterCollection filters) - { - filters.Add(new HandleErrorAttribute()); - } - } -} diff --git a/Fitbit.Portable.DebugSite/App_Start/IdentityConfig.cs b/Fitbit.Portable.DebugSite/App_Start/IdentityConfig.cs deleted file mode 100644 index ae8dbacc..00000000 --- a/Fitbit.Portable.DebugSite/App_Start/IdentityConfig.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data.Entity; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using System.Web; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using SampleWebMVCOAuth2.Models; - -namespace SampleWebMVCOAuth2 -{ - public class EmailService : IIdentityMessageService - { - public Task SendAsync(IdentityMessage message) - { - // Plug in your email service here to send an email. - return Task.FromResult(0); - } - } - - public class SmsService : IIdentityMessageService - { - public Task SendAsync(IdentityMessage message) - { - // Plug in your SMS service here to send a text message. - return Task.FromResult(0); - } - } - - // Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. - public class ApplicationUserManager : UserManager - { - public ApplicationUserManager(IUserStore store) - : base(store) - { - } - - public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context) - { - var manager = new ApplicationUserManager(new UserStore(context.Get())); - // Configure validation logic for usernames - manager.UserValidator = new UserValidator(manager) - { - AllowOnlyAlphanumericUserNames = false, - RequireUniqueEmail = true - }; - - // Configure validation logic for passwords - manager.PasswordValidator = new PasswordValidator - { - RequiredLength = 6, - RequireNonLetterOrDigit = true, - RequireDigit = true, - RequireLowercase = true, - RequireUppercase = true, - }; - - // Configure user lockout defaults - manager.UserLockoutEnabledByDefault = true; - manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); - manager.MaxFailedAccessAttemptsBeforeLockout = 5; - - // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user - // You can write your own provider and plug it in here. - manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider - { - MessageFormat = "Your security code is {0}" - }); - manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider - { - Subject = "Security Code", - BodyFormat = "Your security code is {0}" - }); - manager.EmailService = new EmailService(); - manager.SmsService = new SmsService(); - var dataProtectionProvider = options.DataProtectionProvider; - if (dataProtectionProvider != null) - { - manager.UserTokenProvider = - new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); - } - return manager; - } - } - - // Configure the application sign-in manager which is used in this application. - public class ApplicationSignInManager : SignInManager - { - public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) - : base(userManager, authenticationManager) - { - } - - public override Task CreateUserIdentityAsync(ApplicationUser user) - { - return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); - } - - public static ApplicationSignInManager Create(IdentityFactoryOptions options, IOwinContext context) - { - return new ApplicationSignInManager(context.GetUserManager(), context.Authentication); - } - } -} diff --git a/Fitbit.Portable.DebugSite/App_Start/RouteConfig.cs b/Fitbit.Portable.DebugSite/App_Start/RouteConfig.cs deleted file mode 100644 index 2dca0c69..00000000 --- a/Fitbit.Portable.DebugSite/App_Start/RouteConfig.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Mvc; -using System.Web.Routing; - -namespace SampleWebMVCOAuth2 -{ - public class RouteConfig - { - public static void RegisterRoutes(RouteCollection routes) - { - routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); - - routes.MapRoute( - name: "Default", - url: "{controller}/{action}/{id}", - defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } - ); - } - } -} diff --git a/Fitbit.Portable.DebugSite/App_Start/Startup.Auth.cs b/Fitbit.Portable.DebugSite/App_Start/Startup.Auth.cs deleted file mode 100644 index c07e3648..00000000 --- a/Fitbit.Portable.DebugSite/App_Start/Startup.Auth.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security.Cookies; -using Microsoft.Owin.Security.Google; -using Owin; -using SampleWebMVCOAuth2.Models; - -namespace SampleWebMVCOAuth2 -{ - public partial class Startup - { - // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 - public void ConfigureAuth(IAppBuilder app) - { - // Configure the db context, user manager and signin manager to use a single instance per request - app.CreatePerOwinContext(ApplicationDbContext.Create); - app.CreatePerOwinContext(ApplicationUserManager.Create); - app.CreatePerOwinContext(ApplicationSignInManager.Create); - - // Enable the application to use a cookie to store information for the signed in user - // and to use a cookie to temporarily store information about a user logging in with a third party login provider - // Configure the sign in cookie - app.UseCookieAuthentication(new CookieAuthenticationOptions - { - AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, - LoginPath = new PathString("/Account/Login"), - Provider = new CookieAuthenticationProvider - { - // Enables the application to validate the security stamp when the user logs in. - // This is a security feature which is used when you change a password or add an external login to your account. - OnValidateIdentity = SecurityStampValidator.OnValidateIdentity( - validateInterval: TimeSpan.FromMinutes(30), - regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) - } - }); - app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); - - // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process. - app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); - - // Enables the application to remember the second login verification factor such as phone or email. - // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from. - // This is similar to the RememberMe option when you log in. - app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); - - // Uncomment the following lines to enable logging in with third party login providers - //app.UseMicrosoftAccountAuthentication( - // clientId: "", - // clientSecret: ""); - - //app.UseTwitterAuthentication( - // consumerKey: "", - // consumerSecret: ""); - - //app.UseFacebookAuthentication( - // appId: "", - // appSecret: ""); - - //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() - //{ - // ClientId = "", - // ClientSecret = "" - //}); - } - } -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Content/Site.css b/Fitbit.Portable.DebugSite/Content/Site.css deleted file mode 100644 index 6ea5d8f6..00000000 --- a/Fitbit.Portable.DebugSite/Content/Site.css +++ /dev/null @@ -1,24 +0,0 @@ -body { - padding-top: 50px; - padding-bottom: 20px; -} - -/* Set padding to keep content from hitting the edges */ -.body-content { - padding-left: 15px; - padding-right: 15px; -} - -/* Override the default bootstrap behavior where horizontal description lists - will truncate terms that are too long to fit in the left column -*/ -.dl-horizontal dt { - white-space: normal; -} - -/* Set width on the form input elements since they're 100% wide by default */ -input, -select, -textarea { - max-width: 280px; -} diff --git a/Fitbit.Portable.DebugSite/Content/bootstrap-theme.css b/Fitbit.Portable.DebugSite/Content/bootstrap-theme.css deleted file mode 100644 index ad117356..00000000 --- a/Fitbit.Portable.DebugSite/Content/bootstrap-theme.css +++ /dev/null @@ -1,384 +0,0 @@ -.btn-default, -.btn-primary, -.btn-success, -.btn-info, -.btn-warning, -.btn-danger { - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.btn-default:active, -.btn-primary:active, -.btn-success:active, -.btn-info:active, -.btn-warning:active, -.btn-danger:active, -.btn-default.active, -.btn-primary.active, -.btn-success.active, -.btn-info.active, -.btn-warning.active, -.btn-danger.active { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} - -.btn:active, -.btn.active { - background-image: none; -} - -.btn-default { - text-shadow: 0 1px 0 #fff; - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, 0%, #e6e6e6, 100%); - background-image: -moz-linear-gradient(top, #ffffff 0%, #e6e6e6 100%); - background-image: linear-gradient(to bottom, #ffffff 0%, #e6e6e6 100%); - background-repeat: repeat-x; - border-color: #e0e0e0; - border-color: #ccc; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); -} - -.btn-default:active, -.btn-default.active { - background-color: #e6e6e6; - border-color: #e0e0e0; -} - -.btn-primary { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); - background-repeat: repeat-x; - border-color: #2d6ca2; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); -} - -.btn-primary:active, -.btn-primary.active { - background-color: #3071a9; - border-color: #2d6ca2; -} - -.btn-success { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5cb85c), to(#449d44)); - background-image: -webkit-linear-gradient(top, #5cb85c, 0%, #449d44, 100%); - background-image: -moz-linear-gradient(top, #5cb85c 0%, #449d44 100%); - background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); - background-repeat: repeat-x; - border-color: #419641; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); -} - -.btn-success:active, -.btn-success.active { - background-color: #449d44; - border-color: #419641; -} - -.btn-warning { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f0ad4e), to(#ec971f)); - background-image: -webkit-linear-gradient(top, #f0ad4e, 0%, #ec971f, 100%); - background-image: -moz-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); - background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); - background-repeat: repeat-x; - border-color: #eb9316; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); -} - -.btn-warning:active, -.btn-warning.active { - background-color: #ec971f; - border-color: #eb9316; -} - -.btn-danger { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9534f), to(#c9302c)); - background-image: -webkit-linear-gradient(top, #d9534f, 0%, #c9302c, 100%); - background-image: -moz-linear-gradient(top, #d9534f 0%, #c9302c 100%); - background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); - background-repeat: repeat-x; - border-color: #c12e2a; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); -} - -.btn-danger:active, -.btn-danger.active { - background-color: #c9302c; - border-color: #c12e2a; -} - -.btn-info { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5bc0de), to(#31b0d5)); - background-image: -webkit-linear-gradient(top, #5bc0de, 0%, #31b0d5, 100%); - background-image: -moz-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); - background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); - background-repeat: repeat-x; - border-color: #2aabd2; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); -} - -.btn-info:active, -.btn-info.active { - background-color: #31b0d5; - border-color: #2aabd2; -} - -.thumbnail, -.img-thumbnail { - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - background-color: #357ebd; - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#357ebd)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #357ebd, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #357ebd 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); -} - -.navbar { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#f8f8f8)); - background-image: -webkit-linear-gradient(top, #ffffff, 0%, #f8f8f8, 100%); - background-image: -moz-linear-gradient(top, #ffffff 0%, #f8f8f8 100%); - background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%); - background-repeat: repeat-x; - border-radius: 4px; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); -} - -.navbar .navbar-nav > .active > a { - background-color: #f8f8f8; -} - -.navbar-brand, -.navbar-nav > li > a { - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); -} - -.navbar-inverse { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#3c3c3c), to(#222222)); - background-image: -webkit-linear-gradient(top, #3c3c3c, 0%, #222222, 100%); - background-image: -moz-linear-gradient(top, #3c3c3c 0%, #222222 100%); - background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); -} - -.navbar-inverse .navbar-nav > .active > a { - background-color: #222222; -} - -.navbar-inverse .navbar-brand, -.navbar-inverse .navbar-nav > li > a { - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} - -.navbar-static-top, -.navbar-fixed-top, -.navbar-fixed-bottom { - border-radius: 0; -} - -.alert { - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.alert-success { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#dff0d8), to(#c8e5bc)); - background-image: -webkit-linear-gradient(top, #dff0d8, 0%, #c8e5bc, 100%); - background-image: -moz-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); - background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); - background-repeat: repeat-x; - border-color: #b2dba1; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); -} - -.alert-info { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9edf7), to(#b9def0)); - background-image: -webkit-linear-gradient(top, #d9edf7, 0%, #b9def0, 100%); - background-image: -moz-linear-gradient(top, #d9edf7 0%, #b9def0 100%); - background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); - background-repeat: repeat-x; - border-color: #9acfea; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); -} - -.alert-warning { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#fcf8e3), to(#f8efc0)); - background-image: -webkit-linear-gradient(top, #fcf8e3, 0%, #f8efc0, 100%); - background-image: -moz-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); - background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); - background-repeat: repeat-x; - border-color: #f5e79e; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); -} - -.alert-danger { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f2dede), to(#e7c3c3)); - background-image: -webkit-linear-gradient(top, #f2dede, 0%, #e7c3c3, 100%); - background-image: -moz-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); - background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); - background-repeat: repeat-x; - border-color: #dca7a7; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); -} - -.progress { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ebebeb), to(#f5f5f5)); - background-image: -webkit-linear-gradient(top, #ebebeb, 0%, #f5f5f5, 100%); - background-image: -moz-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); - background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); -} - -.progress-bar { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); -} - -.progress-bar-success { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5cb85c), to(#449d44)); - background-image: -webkit-linear-gradient(top, #5cb85c, 0%, #449d44, 100%); - background-image: -moz-linear-gradient(top, #5cb85c 0%, #449d44 100%); - background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); -} - -.progress-bar-info { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5bc0de), to(#31b0d5)); - background-image: -webkit-linear-gradient(top, #5bc0de, 0%, #31b0d5, 100%); - background-image: -moz-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); - background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); -} - -.progress-bar-warning { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f0ad4e), to(#ec971f)); - background-image: -webkit-linear-gradient(top, #f0ad4e, 0%, #ec971f, 100%); - background-image: -moz-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); - background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); -} - -.progress-bar-danger { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9534f), to(#c9302c)); - background-image: -webkit-linear-gradient(top, #d9534f, 0%, #c9302c, 100%); - background-image: -moz-linear-gradient(top, #d9534f 0%, #c9302c 100%); - background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); -} - -.list-group { - border-radius: 4px; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); -} - -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - text-shadow: 0 -1px 0 #3071a9; - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3278b3)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #3278b3, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #3278b3 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%); - background-repeat: repeat-x; - border-color: #3278b3; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0); -} - -.panel { - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.panel-default > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f5f5f5), to(#e8e8e8)); - background-image: -webkit-linear-gradient(top, #f5f5f5, 0%, #e8e8e8, 100%); - background-image: -moz-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); - background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); -} - -.panel-primary > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#357ebd)); - background-image: -webkit-linear-gradient(top, #428bca, 0%, #357ebd, 100%); - background-image: -moz-linear-gradient(top, #428bca 0%, #357ebd 100%); - background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); -} - -.panel-success > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#dff0d8), to(#d0e9c6)); - background-image: -webkit-linear-gradient(top, #dff0d8, 0%, #d0e9c6, 100%); - background-image: -moz-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); - background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); -} - -.panel-info > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9edf7), to(#c4e3f3)); - background-image: -webkit-linear-gradient(top, #d9edf7, 0%, #c4e3f3, 100%); - background-image: -moz-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); - background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); -} - -.panel-warning > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#fcf8e3), to(#faf2cc)); - background-image: -webkit-linear-gradient(top, #fcf8e3, 0%, #faf2cc, 100%); - background-image: -moz-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); - background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); -} - -.panel-danger > .panel-heading { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f2dede), to(#ebcccc)); - background-image: -webkit-linear-gradient(top, #f2dede, 0%, #ebcccc, 100%); - background-image: -moz-linear-gradient(top, #f2dede 0%, #ebcccc 100%); - background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); -} - -.well { - background-image: -webkit-gradient(linear, left 0%, left 100%, from(#e8e8e8), to(#f5f5f5)); - background-image: -webkit-linear-gradient(top, #e8e8e8, 0%, #f5f5f5, 100%); - background-image: -moz-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); - background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); - background-repeat: repeat-x; - border-color: #dcdcdc; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); - -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Content/bootstrap-theme.min.css b/Fitbit.Portable.DebugSite/Content/bootstrap-theme.min.css deleted file mode 100644 index cad36b4e..00000000 --- a/Fitbit.Portable.DebugSite/Content/bootstrap-theme.min.css +++ /dev/null @@ -1 +0,0 @@ -.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,0%,#e6e6e6,100%);background-image:-moz-linear-gradient(top,#fff 0,#e6e6e6 100%);background-image:linear-gradient(to bottom,#fff 0,#e6e6e6 100%);background-repeat:repeat-x;border-color:#e0e0e0;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0)}.btn-default:active,.btn-default.active{background-color:#e6e6e6;border-color:#e0e0e0}.btn-primary{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3071a9));background-image:-webkit-linear-gradient(top,#428bca,0%,#3071a9,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;border-color:#2d6ca2;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.btn-primary:active,.btn-primary.active{background-color:#3071a9;border-color:#2d6ca2}.btn-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5cb85c),to(#449d44));background-image:-webkit-linear-gradient(top,#5cb85c,0%,#449d44,100%);background-image:-moz-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;border-color:#419641;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.btn-success:active,.btn-success.active{background-color:#449d44;border-color:#419641}.btn-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f0ad4e),to(#ec971f));background-image:-webkit-linear-gradient(top,#f0ad4e,0%,#ec971f,100%);background-image:-moz-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;border-color:#eb9316;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.btn-warning:active,.btn-warning.active{background-color:#ec971f;border-color:#eb9316}.btn-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9534f),to(#c9302c));background-image:-webkit-linear-gradient(top,#d9534f,0%,#c9302c,100%);background-image:-moz-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;border-color:#c12e2a;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.btn-danger:active,.btn-danger.active{background-color:#c9302c;border-color:#c12e2a}.btn-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5bc0de),to(#31b0d5));background-image:-webkit-linear-gradient(top,#5bc0de,0%,#31b0d5,100%);background-image:-moz-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;border-color:#2aabd2;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.btn-info:active,.btn-info.active{background-color:#31b0d5;border-color:#2aabd2}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#357ebd));background-image:-webkit-linear-gradient(top,#428bca,0%,#357ebd,100%);background-image:-moz-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.navbar{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#f8f8f8));background-image:-webkit-linear-gradient(top,#fff,0%,#f8f8f8,100%);background-image:-moz-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff8f8f8',GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar .navbar-nav>.active>a{background-color:#f8f8f8}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-gradient(linear,left 0,left 100%,from(#3c3c3c),to(#222));background-image:-webkit-linear-gradient(top,#3c3c3c,0%,#222,100%);background-image:-moz-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c',endColorstr='#ff222222',GradientType=0)}.navbar-inverse .navbar-nav>.active>a{background-color:#222}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#dff0d8),to(#c8e5bc));background-image:-webkit-linear-gradient(top,#dff0d8,0%,#c8e5bc,100%);background-image:-moz-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;border-color:#b2dba1;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffc8e5bc',GradientType=0)}.alert-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9edf7),to(#b9def0));background-image:-webkit-linear-gradient(top,#d9edf7,0%,#b9def0,100%);background-image:-moz-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffb9def0',GradientType=0)}.alert-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fcf8e3),to(#f8efc0));background-image:-webkit-linear-gradient(top,#fcf8e3,0%,#f8efc0,100%);background-image:-moz-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;border-color:#f5e79e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fff8efc0',GradientType=0)}.alert-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f2dede),to(#e7c3c3));background-image:-webkit-linear-gradient(top,#f2dede,0%,#e7c3c3,100%);background-image:-moz-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;border-color:#dca7a7;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffe7c3c3',GradientType=0)}.progress{background-image:-webkit-gradient(linear,left 0,left 100%,from(#ebebeb),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#ebebeb,0%,#f5f5f5,100%);background-image:-moz-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb',endColorstr='#fff5f5f5',GradientType=0)}.progress-bar{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3071a9));background-image:-webkit-linear-gradient(top,#428bca,0%,#3071a9,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.progress-bar-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5cb85c),to(#449d44));background-image:-webkit-linear-gradient(top,#5cb85c,0%,#449d44,100%);background-image:-moz-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.progress-bar-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5bc0de),to(#31b0d5));background-image:-webkit-linear-gradient(top,#5bc0de,0%,#31b0d5,100%);background-image:-moz-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.progress-bar-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f0ad4e),to(#ec971f));background-image:-webkit-linear-gradient(top,#f0ad4e,0%,#ec971f,100%);background-image:-moz-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.progress-bar-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9534f),to(#c9302c));background-image:-webkit-linear-gradient(top,#d9534f,0%,#c9302c,100%);background-image:-moz-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3278b3));background-image:-webkit-linear-gradient(top,#428bca,0%,#3278b3,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3278b3',GradientType=0)}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f5f5f5),to(#e8e8e8));background-image:-webkit-linear-gradient(top,#f5f5f5,0%,#e8e8e8,100%);background-image:-moz-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#ffe8e8e8',GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#357ebd));background-image:-webkit-linear-gradient(top,#428bca,0%,#357ebd,100%);background-image:-moz-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#dff0d8),to(#d0e9c6));background-image:-webkit-linear-gradient(top,#dff0d8,0%,#d0e9c6,100%);background-image:-moz-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffd0e9c6',GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9edf7),to(#c4e3f3));background-image:-webkit-linear-gradient(top,#d9edf7,0%,#c4e3f3,100%);background-image:-moz-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffc4e3f3',GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fcf8e3),to(#faf2cc));background-image:-webkit-linear-gradient(top,#fcf8e3,0%,#faf2cc,100%);background-image:-moz-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fffaf2cc',GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f2dede),to(#ebcccc));background-image:-webkit-linear-gradient(top,#f2dede,0%,#ebcccc,100%);background-image:-moz-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffebcccc',GradientType=0)}.well{background-image:-webkit-gradient(linear,left 0,left 100%,from(#e8e8e8),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#e8e8e8,0%,#f5f5f5,100%);background-image:-moz-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Content/bootstrap.css b/Fitbit.Portable.DebugSite/Content/bootstrap.css deleted file mode 100644 index bbda4eed..00000000 --- a/Fitbit.Portable.DebugSite/Content/bootstrap.css +++ /dev/null @@ -1,6805 +0,0 @@ -/*! - * Bootstrap v3.0.0 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world by @mdo and @fat. - */ - -/*! normalize.css v2.1.0 | MIT License | git.io/normalize */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; -} - -audio, -canvas, -video { - display: inline-block; -} - -audio:not([controls]) { - display: none; - height: 0; -} - -[hidden] { - display: none; -} - -html { - font-family: sans-serif; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -body { - margin: 0; -} - -a:focus { - outline: thin dotted; -} - -a:active, -a:hover { - outline: 0; -} - -h1 { - margin: 0.67em 0; - font-size: 2em; -} - -abbr[title] { - border-bottom: 1px dotted; -} - -b, -strong { - font-weight: bold; -} - -dfn { - font-style: italic; -} - -hr { - height: 0; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -mark { - color: #000; - background: #ff0; -} - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - font-size: 1em; -} - -pre { - white-space: pre-wrap; -} - -q { - quotes: "\201C" "\201D" "\2018" "\2019"; -} - -small { - font-size: 80%; -} - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -img { - border: 0; -} - -svg:not(:root) { - overflow: hidden; -} - -figure { - margin: 0; -} - -fieldset { - padding: 0.35em 0.625em 0.75em; - margin: 0 2px; - border: 1px solid #c0c0c0; -} - -legend { - padding: 0; - border: 0; -} - -button, -input, -select, -textarea { - margin: 0; - font-family: inherit; - font-size: 100%; -} - -button, -input { - line-height: normal; -} - -button, -select { - text-transform: none; -} - -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - cursor: pointer; - -webkit-appearance: button; -} - -button[disabled], -html input[disabled] { - cursor: default; -} - -input[type="checkbox"], -input[type="radio"] { - padding: 0; - box-sizing: border-box; -} - -input[type="search"] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; -} - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} - -textarea { - overflow: auto; - vertical-align: top; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -@media print { - * { - color: #000 !important; - text-shadow: none !important; - background: transparent !important; - box-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - @page { - margin: 2cm .5cm; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } - .navbar { - display: none; - } - .table td, - .table th { - background-color: #fff !important; - } - .btn > .caret, - .dropup > .btn > .caret { - border-top-color: #000 !important; - } - .label { - border: 1px solid #000; - } - .table { - border-collapse: collapse !important; - } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } -} - -*, -*:before, -*:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html { - font-size: 62.5%; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 1.428571429; - color: #333333; - background-color: #ffffff; -} - -input, -button, -select, -textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -button, -input, -select[multiple], -textarea { - background-image: none; -} - -a { - color: #428bca; - text-decoration: none; -} - -a:hover, -a:focus { - color: #2a6496; - text-decoration: underline; -} - -a:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -img { - vertical-align: middle; -} - -.img-responsive { - display: block; - height: auto; - max-width: 100%; -} - -.img-rounded { - border-radius: 6px; -} - -.img-thumbnail { - display: inline-block; - height: auto; - max-width: 100%; - padding: 4px; - line-height: 1.428571429; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} - -.img-circle { - border-radius: 50%; -} - -hr { - margin-top: 20px; - margin-bottom: 20px; - border: 0; - border-top: 1px solid #eeeeee; -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0 0 0 0); - border: 0; -} - -p { - margin: 0 0 10px; -} - -.lead { - margin-bottom: 20px; - font-size: 16.099999999999998px; - font-weight: 200; - line-height: 1.4; -} - -@media (min-width: 768px) { - .lead { - font-size: 21px; - } -} - -small { - font-size: 85%; -} - -cite { - font-style: normal; -} - -.text-muted { - color: #999999; -} - -.text-primary { - color: #428bca; -} - -.text-warning { - color: #c09853; -} - -.text-danger { - color: #b94a48; -} - -.text-success { - color: #468847; -} - -.text-info { - color: #3a87ad; -} - -.text-left { - text-align: left; -} - -.text-right { - text-align: right; -} - -.text-center { - text-align: center; -} - -h1, -h2, -h3, -h4, -h5, -h6, -.h1, -.h2, -.h3, -.h4, -.h5, -.h6 { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-weight: 500; - line-height: 1.1; -} - -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small, -.h1 small, -.h2 small, -.h3 small, -.h4 small, -.h5 small, -.h6 small { - font-weight: normal; - line-height: 1; - color: #999999; -} - -h1, -h2, -h3 { - margin-top: 20px; - margin-bottom: 10px; -} - -h4, -h5, -h6 { - margin-top: 10px; - margin-bottom: 10px; -} - -h1, -.h1 { - font-size: 36px; -} - -h2, -.h2 { - font-size: 30px; -} - -h3, -.h3 { - font-size: 24px; -} - -h4, -.h4 { - font-size: 18px; -} - -h5, -.h5 { - font-size: 14px; -} - -h6, -.h6 { - font-size: 12px; -} - -h1 small, -.h1 small { - font-size: 24px; -} - -h2 small, -.h2 small { - font-size: 18px; -} - -h3 small, -.h3 small, -h4 small, -.h4 small { - font-size: 14px; -} - -.page-header { - padding-bottom: 9px; - margin: 40px 0 20px; - border-bottom: 1px solid #eeeeee; -} - -ul, -ol { - margin-top: 0; - margin-bottom: 10px; -} - -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} - -.list-unstyled { - padding-left: 0; - list-style: none; -} - -.list-inline { - padding-left: 0; - list-style: none; -} - -.list-inline > li { - display: inline-block; - padding-right: 5px; - padding-left: 5px; -} - -dl { - margin-bottom: 20px; -} - -dt, -dd { - line-height: 1.428571429; -} - -dt { - font-weight: bold; -} - -dd { - margin-left: 0; -} - -@media (min-width: 768px) { - .dl-horizontal dt { - float: left; - width: 160px; - overflow: hidden; - clear: left; - text-align: right; - text-overflow: ellipsis; - white-space: nowrap; - } - .dl-horizontal dd { - margin-left: 180px; - } - .dl-horizontal dd:before, - .dl-horizontal dd:after { - display: table; - content: " "; - } - .dl-horizontal dd:after { - clear: both; - } - .dl-horizontal dd:before, - .dl-horizontal dd:after { - display: table; - content: " "; - } - .dl-horizontal dd:after { - clear: both; - } -} - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; -} - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} - -blockquote { - padding: 10px 20px; - margin: 0 0 20px; - border-left: 5px solid #eeeeee; -} - -blockquote p { - font-size: 17.5px; - font-weight: 300; - line-height: 1.25; -} - -blockquote p:last-child { - margin-bottom: 0; -} - -blockquote small { - display: block; - line-height: 1.428571429; - color: #999999; -} - -blockquote small:before { - content: '\2014 \00A0'; -} - -blockquote.pull-right { - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; -} - -blockquote.pull-right p, -blockquote.pull-right small { - text-align: right; -} - -blockquote.pull-right small:before { - content: ''; -} - -blockquote.pull-right small:after { - content: '\00A0 \2014'; -} - -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 1.428571429; -} - -code, -pre { - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; -} - -code { - padding: 2px 4px; - font-size: 90%; - color: #c7254e; - white-space: nowrap; - background-color: #f9f2f4; - border-radius: 4px; -} - -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - line-height: 1.428571429; - color: #333333; - word-break: break-all; - word-wrap: break-word; - background-color: #f5f5f5; - border: 1px solid #cccccc; - border-radius: 4px; -} - -pre.prettyprint { - margin-bottom: 20px; -} - -pre code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border: 0; -} - -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} - -.container { - padding-right: 15px; - padding-left: 15px; - margin-right: auto; - margin-left: auto; -} - -.container:before, -.container:after { - display: table; - content: " "; -} - -.container:after { - clear: both; -} - -.container:before, -.container:after { - display: table; - content: " "; -} - -.container:after { - clear: both; -} - -.row { - margin-right: -15px; - margin-left: -15px; -} - -.row:before, -.row:after { - display: table; - content: " "; -} - -.row:after { - clear: both; -} - -.row:before, -.row:after { - display: table; - content: " "; -} - -.row:after { - clear: both; -} - -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11, -.col-xs-12, -.col-sm-1, -.col-sm-2, -.col-sm-3, -.col-sm-4, -.col-sm-5, -.col-sm-6, -.col-sm-7, -.col-sm-8, -.col-sm-9, -.col-sm-10, -.col-sm-11, -.col-sm-12, -.col-md-1, -.col-md-2, -.col-md-3, -.col-md-4, -.col-md-5, -.col-md-6, -.col-md-7, -.col-md-8, -.col-md-9, -.col-md-10, -.col-md-11, -.col-md-12, -.col-lg-1, -.col-lg-2, -.col-lg-3, -.col-lg-4, -.col-lg-5, -.col-lg-6, -.col-lg-7, -.col-lg-8, -.col-lg-9, -.col-lg-10, -.col-lg-11, -.col-lg-12 { - position: relative; - min-height: 1px; - padding-right: 15px; - padding-left: 15px; -} - -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11 { - float: left; -} - -.col-xs-1 { - width: 8.333333333333332%; -} - -.col-xs-2 { - width: 16.666666666666664%; -} - -.col-xs-3 { - width: 25%; -} - -.col-xs-4 { - width: 33.33333333333333%; -} - -.col-xs-5 { - width: 41.66666666666667%; -} - -.col-xs-6 { - width: 50%; -} - -.col-xs-7 { - width: 58.333333333333336%; -} - -.col-xs-8 { - width: 66.66666666666666%; -} - -.col-xs-9 { - width: 75%; -} - -.col-xs-10 { - width: 83.33333333333334%; -} - -.col-xs-11 { - width: 91.66666666666666%; -} - -.col-xs-12 { - width: 100%; -} - -@media (min-width: 768px) { - .container { - max-width: 750px; - } - .col-sm-1, - .col-sm-2, - .col-sm-3, - .col-sm-4, - .col-sm-5, - .col-sm-6, - .col-sm-7, - .col-sm-8, - .col-sm-9, - .col-sm-10, - .col-sm-11 { - float: left; - } - .col-sm-1 { - width: 8.333333333333332%; - } - .col-sm-2 { - width: 16.666666666666664%; - } - .col-sm-3 { - width: 25%; - } - .col-sm-4 { - width: 33.33333333333333%; - } - .col-sm-5 { - width: 41.66666666666667%; - } - .col-sm-6 { - width: 50%; - } - .col-sm-7 { - width: 58.333333333333336%; - } - .col-sm-8 { - width: 66.66666666666666%; - } - .col-sm-9 { - width: 75%; - } - .col-sm-10 { - width: 83.33333333333334%; - } - .col-sm-11 { - width: 91.66666666666666%; - } - .col-sm-12 { - width: 100%; - } - .col-sm-push-1 { - left: 8.333333333333332%; - } - .col-sm-push-2 { - left: 16.666666666666664%; - } - .col-sm-push-3 { - left: 25%; - } - .col-sm-push-4 { - left: 33.33333333333333%; - } - .col-sm-push-5 { - left: 41.66666666666667%; - } - .col-sm-push-6 { - left: 50%; - } - .col-sm-push-7 { - left: 58.333333333333336%; - } - .col-sm-push-8 { - left: 66.66666666666666%; - } - .col-sm-push-9 { - left: 75%; - } - .col-sm-push-10 { - left: 83.33333333333334%; - } - .col-sm-push-11 { - left: 91.66666666666666%; - } - .col-sm-pull-1 { - right: 8.333333333333332%; - } - .col-sm-pull-2 { - right: 16.666666666666664%; - } - .col-sm-pull-3 { - right: 25%; - } - .col-sm-pull-4 { - right: 33.33333333333333%; - } - .col-sm-pull-5 { - right: 41.66666666666667%; - } - .col-sm-pull-6 { - right: 50%; - } - .col-sm-pull-7 { - right: 58.333333333333336%; - } - .col-sm-pull-8 { - right: 66.66666666666666%; - } - .col-sm-pull-9 { - right: 75%; - } - .col-sm-pull-10 { - right: 83.33333333333334%; - } - .col-sm-pull-11 { - right: 91.66666666666666%; - } - .col-sm-offset-1 { - margin-left: 8.333333333333332%; - } - .col-sm-offset-2 { - margin-left: 16.666666666666664%; - } - .col-sm-offset-3 { - margin-left: 25%; - } - .col-sm-offset-4 { - margin-left: 33.33333333333333%; - } - .col-sm-offset-5 { - margin-left: 41.66666666666667%; - } - .col-sm-offset-6 { - margin-left: 50%; - } - .col-sm-offset-7 { - margin-left: 58.333333333333336%; - } - .col-sm-offset-8 { - margin-left: 66.66666666666666%; - } - .col-sm-offset-9 { - margin-left: 75%; - } - .col-sm-offset-10 { - margin-left: 83.33333333333334%; - } - .col-sm-offset-11 { - margin-left: 91.66666666666666%; - } -} - -@media (min-width: 992px) { - .container { - max-width: 970px; - } - .col-md-1, - .col-md-2, - .col-md-3, - .col-md-4, - .col-md-5, - .col-md-6, - .col-md-7, - .col-md-8, - .col-md-9, - .col-md-10, - .col-md-11 { - float: left; - } - .col-md-1 { - width: 8.333333333333332%; - } - .col-md-2 { - width: 16.666666666666664%; - } - .col-md-3 { - width: 25%; - } - .col-md-4 { - width: 33.33333333333333%; - } - .col-md-5 { - width: 41.66666666666667%; - } - .col-md-6 { - width: 50%; - } - .col-md-7 { - width: 58.333333333333336%; - } - .col-md-8 { - width: 66.66666666666666%; - } - .col-md-9 { - width: 75%; - } - .col-md-10 { - width: 83.33333333333334%; - } - .col-md-11 { - width: 91.66666666666666%; - } - .col-md-12 { - width: 100%; - } - .col-md-push-0 { - left: auto; - } - .col-md-push-1 { - left: 8.333333333333332%; - } - .col-md-push-2 { - left: 16.666666666666664%; - } - .col-md-push-3 { - left: 25%; - } - .col-md-push-4 { - left: 33.33333333333333%; - } - .col-md-push-5 { - left: 41.66666666666667%; - } - .col-md-push-6 { - left: 50%; - } - .col-md-push-7 { - left: 58.333333333333336%; - } - .col-md-push-8 { - left: 66.66666666666666%; - } - .col-md-push-9 { - left: 75%; - } - .col-md-push-10 { - left: 83.33333333333334%; - } - .col-md-push-11 { - left: 91.66666666666666%; - } - .col-md-pull-0 { - right: auto; - } - .col-md-pull-1 { - right: 8.333333333333332%; - } - .col-md-pull-2 { - right: 16.666666666666664%; - } - .col-md-pull-3 { - right: 25%; - } - .col-md-pull-4 { - right: 33.33333333333333%; - } - .col-md-pull-5 { - right: 41.66666666666667%; - } - .col-md-pull-6 { - right: 50%; - } - .col-md-pull-7 { - right: 58.333333333333336%; - } - .col-md-pull-8 { - right: 66.66666666666666%; - } - .col-md-pull-9 { - right: 75%; - } - .col-md-pull-10 { - right: 83.33333333333334%; - } - .col-md-pull-11 { - right: 91.66666666666666%; - } - .col-md-offset-0 { - margin-left: 0; - } - .col-md-offset-1 { - margin-left: 8.333333333333332%; - } - .col-md-offset-2 { - margin-left: 16.666666666666664%; - } - .col-md-offset-3 { - margin-left: 25%; - } - .col-md-offset-4 { - margin-left: 33.33333333333333%; - } - .col-md-offset-5 { - margin-left: 41.66666666666667%; - } - .col-md-offset-6 { - margin-left: 50%; - } - .col-md-offset-7 { - margin-left: 58.333333333333336%; - } - .col-md-offset-8 { - margin-left: 66.66666666666666%; - } - .col-md-offset-9 { - margin-left: 75%; - } - .col-md-offset-10 { - margin-left: 83.33333333333334%; - } - .col-md-offset-11 { - margin-left: 91.66666666666666%; - } -} - -@media (min-width: 1200px) { - .container { - max-width: 1170px; - } - .col-lg-1, - .col-lg-2, - .col-lg-3, - .col-lg-4, - .col-lg-5, - .col-lg-6, - .col-lg-7, - .col-lg-8, - .col-lg-9, - .col-lg-10, - .col-lg-11 { - float: left; - } - .col-lg-1 { - width: 8.333333333333332%; - } - .col-lg-2 { - width: 16.666666666666664%; - } - .col-lg-3 { - width: 25%; - } - .col-lg-4 { - width: 33.33333333333333%; - } - .col-lg-5 { - width: 41.66666666666667%; - } - .col-lg-6 { - width: 50%; - } - .col-lg-7 { - width: 58.333333333333336%; - } - .col-lg-8 { - width: 66.66666666666666%; - } - .col-lg-9 { - width: 75%; - } - .col-lg-10 { - width: 83.33333333333334%; - } - .col-lg-11 { - width: 91.66666666666666%; - } - .col-lg-12 { - width: 100%; - } - .col-lg-push-0 { - left: auto; - } - .col-lg-push-1 { - left: 8.333333333333332%; - } - .col-lg-push-2 { - left: 16.666666666666664%; - } - .col-lg-push-3 { - left: 25%; - } - .col-lg-push-4 { - left: 33.33333333333333%; - } - .col-lg-push-5 { - left: 41.66666666666667%; - } - .col-lg-push-6 { - left: 50%; - } - .col-lg-push-7 { - left: 58.333333333333336%; - } - .col-lg-push-8 { - left: 66.66666666666666%; - } - .col-lg-push-9 { - left: 75%; - } - .col-lg-push-10 { - left: 83.33333333333334%; - } - .col-lg-push-11 { - left: 91.66666666666666%; - } - .col-lg-pull-0 { - right: auto; - } - .col-lg-pull-1 { - right: 8.333333333333332%; - } - .col-lg-pull-2 { - right: 16.666666666666664%; - } - .col-lg-pull-3 { - right: 25%; - } - .col-lg-pull-4 { - right: 33.33333333333333%; - } - .col-lg-pull-5 { - right: 41.66666666666667%; - } - .col-lg-pull-6 { - right: 50%; - } - .col-lg-pull-7 { - right: 58.333333333333336%; - } - .col-lg-pull-8 { - right: 66.66666666666666%; - } - .col-lg-pull-9 { - right: 75%; - } - .col-lg-pull-10 { - right: 83.33333333333334%; - } - .col-lg-pull-11 { - right: 91.66666666666666%; - } - .col-lg-offset-0 { - margin-left: 0; - } - .col-lg-offset-1 { - margin-left: 8.333333333333332%; - } - .col-lg-offset-2 { - margin-left: 16.666666666666664%; - } - .col-lg-offset-3 { - margin-left: 25%; - } - .col-lg-offset-4 { - margin-left: 33.33333333333333%; - } - .col-lg-offset-5 { - margin-left: 41.66666666666667%; - } - .col-lg-offset-6 { - margin-left: 50%; - } - .col-lg-offset-7 { - margin-left: 58.333333333333336%; - } - .col-lg-offset-8 { - margin-left: 66.66666666666666%; - } - .col-lg-offset-9 { - margin-left: 75%; - } - .col-lg-offset-10 { - margin-left: 83.33333333333334%; - } - .col-lg-offset-11 { - margin-left: 91.66666666666666%; - } -} - -table { - max-width: 100%; - background-color: transparent; -} - -th { - text-align: left; -} - -.table { - width: 100%; - margin-bottom: 20px; -} - -.table thead > tr > th, -.table tbody > tr > th, -.table tfoot > tr > th, -.table thead > tr > td, -.table tbody > tr > td, -.table tfoot > tr > td { - padding: 8px; - line-height: 1.428571429; - vertical-align: top; - border-top: 1px solid #dddddd; -} - -.table thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid #dddddd; -} - -.table caption + thead tr:first-child th, -.table colgroup + thead tr:first-child th, -.table thead:first-child tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child td { - border-top: 0; -} - -.table tbody + tbody { - border-top: 2px solid #dddddd; -} - -.table .table { - background-color: #ffffff; -} - -.table-condensed thead > tr > th, -.table-condensed tbody > tr > th, -.table-condensed tfoot > tr > th, -.table-condensed thead > tr > td, -.table-condensed tbody > tr > td, -.table-condensed tfoot > tr > td { - padding: 5px; -} - -.table-bordered { - border: 1px solid #dddddd; -} - -.table-bordered > thead > tr > th, -.table-bordered > tbody > tr > th, -.table-bordered > tfoot > tr > th, -.table-bordered > thead > tr > td, -.table-bordered > tbody > tr > td, -.table-bordered > tfoot > tr > td { - border: 1px solid #dddddd; -} - -.table-bordered > thead > tr > th, -.table-bordered > thead > tr > td { - border-bottom-width: 2px; -} - -.table-striped > tbody > tr:nth-child(odd) > td, -.table-striped > tbody > tr:nth-child(odd) > th { - background-color: #f9f9f9; -} - -.table-hover > tbody > tr:hover > td, -.table-hover > tbody > tr:hover > th { - background-color: #f5f5f5; -} - -table col[class*="col-"] { - display: table-column; - float: none; -} - -table td[class*="col-"], -table th[class*="col-"] { - display: table-cell; - float: none; -} - -.table > thead > tr > td.active, -.table > tbody > tr > td.active, -.table > tfoot > tr > td.active, -.table > thead > tr > th.active, -.table > tbody > tr > th.active, -.table > tfoot > tr > th.active, -.table > thead > tr.active > td, -.table > tbody > tr.active > td, -.table > tfoot > tr.active > td, -.table > thead > tr.active > th, -.table > tbody > tr.active > th, -.table > tfoot > tr.active > th { - background-color: #f5f5f5; -} - -.table > thead > tr > td.success, -.table > tbody > tr > td.success, -.table > tfoot > tr > td.success, -.table > thead > tr > th.success, -.table > tbody > tr > th.success, -.table > tfoot > tr > th.success, -.table > thead > tr.success > td, -.table > tbody > tr.success > td, -.table > tfoot > tr.success > td, -.table > thead > tr.success > th, -.table > tbody > tr.success > th, -.table > tfoot > tr.success > th { - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.table-hover > tbody > tr > td.success:hover, -.table-hover > tbody > tr > th.success:hover, -.table-hover > tbody > tr.success:hover > td { - background-color: #d0e9c6; - border-color: #c9e2b3; -} - -.table > thead > tr > td.danger, -.table > tbody > tr > td.danger, -.table > tfoot > tr > td.danger, -.table > thead > tr > th.danger, -.table > tbody > tr > th.danger, -.table > tfoot > tr > th.danger, -.table > thead > tr.danger > td, -.table > tbody > tr.danger > td, -.table > tfoot > tr.danger > td, -.table > thead > tr.danger > th, -.table > tbody > tr.danger > th, -.table > tfoot > tr.danger > th { - background-color: #f2dede; - border-color: #eed3d7; -} - -.table-hover > tbody > tr > td.danger:hover, -.table-hover > tbody > tr > th.danger:hover, -.table-hover > tbody > tr.danger:hover > td { - background-color: #ebcccc; - border-color: #e6c1c7; -} - -.table > thead > tr > td.warning, -.table > tbody > tr > td.warning, -.table > tfoot > tr > td.warning, -.table > thead > tr > th.warning, -.table > tbody > tr > th.warning, -.table > tfoot > tr > th.warning, -.table > thead > tr.warning > td, -.table > tbody > tr.warning > td, -.table > tfoot > tr.warning > td, -.table > thead > tr.warning > th, -.table > tbody > tr.warning > th, -.table > tfoot > tr.warning > th { - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.table-hover > tbody > tr > td.warning:hover, -.table-hover > tbody > tr > th.warning:hover, -.table-hover > tbody > tr.warning:hover > td { - background-color: #faf2cc; - border-color: #f8e5be; -} - -@media (max-width: 768px) { - .table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-x: scroll; - overflow-y: hidden; - border: 1px solid #dddddd; - } - .table-responsive > .table { - margin-bottom: 0; - background-color: #fff; - } - .table-responsive > .table > thead > tr > th, - .table-responsive > .table > tbody > tr > th, - .table-responsive > .table > tfoot > tr > th, - .table-responsive > .table > thead > tr > td, - .table-responsive > .table > tbody > tr > td, - .table-responsive > .table > tfoot > tr > td { - white-space: nowrap; - } - .table-responsive > .table-bordered { - border: 0; - } - .table-responsive > .table-bordered > thead > tr > th:first-child, - .table-responsive > .table-bordered > tbody > tr > th:first-child, - .table-responsive > .table-bordered > tfoot > tr > th:first-child, - .table-responsive > .table-bordered > thead > tr > td:first-child, - .table-responsive > .table-bordered > tbody > tr > td:first-child, - .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; - } - .table-responsive > .table-bordered > thead > tr > th:last-child, - .table-responsive > .table-bordered > tbody > tr > th:last-child, - .table-responsive > .table-bordered > tfoot > tr > th:last-child, - .table-responsive > .table-bordered > thead > tr > td:last-child, - .table-responsive > .table-bordered > tbody > tr > td:last-child, - .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; - } - .table-responsive > .table-bordered > thead > tr:last-child > th, - .table-responsive > .table-bordered > tbody > tr:last-child > th, - .table-responsive > .table-bordered > tfoot > tr:last-child > th, - .table-responsive > .table-bordered > thead > tr:last-child > td, - .table-responsive > .table-bordered > tbody > tr:last-child > td, - .table-responsive > .table-bordered > tfoot > tr:last-child > td { - border-bottom: 0; - } -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: 21px; - line-height: inherit; - color: #333333; - border: 0; - border-bottom: 1px solid #e5e5e5; -} - -label { - display: inline-block; - margin-bottom: 5px; - font-weight: bold; -} - -input[type="search"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; - /* IE8-9 */ - - line-height: normal; -} - -input[type="file"] { - display: block; -} - -select[multiple], -select[size] { - height: auto; -} - -select optgroup { - font-family: inherit; - font-size: inherit; - font-style: inherit; -} - -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -input[type="number"]::-webkit-outer-spin-button, -input[type="number"]::-webkit-inner-spin-button { - height: auto; -} - -.form-control:-moz-placeholder { - color: #999999; -} - -.form-control::-moz-placeholder { - color: #999999; -} - -.form-control:-ms-input-placeholder { - color: #999999; -} - -.form-control::-webkit-input-placeholder { - color: #999999; -} - -.form-control { - display: block; - width: 100%; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.428571429; - color: #555555; - vertical-align: middle; - background-color: #ffffff; - border: 1px solid #cccccc; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; - transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; -} - -.form-control:focus { - border-color: #66afe9; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); -} - -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - cursor: not-allowed; - background-color: #eeeeee; -} - -textarea.form-control { - height: auto; -} - -.form-group { - margin-bottom: 15px; -} - -.radio, -.checkbox { - display: block; - min-height: 20px; - padding-left: 20px; - margin-top: 10px; - margin-bottom: 10px; - vertical-align: middle; -} - -.radio label, -.checkbox label { - display: inline; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; -} - -.radio input[type="radio"], -.radio-inline input[type="radio"], -.checkbox input[type="checkbox"], -.checkbox-inline input[type="checkbox"] { - float: left; - margin-left: -20px; -} - -.radio + .radio, -.checkbox + .checkbox { - margin-top: -5px; -} - -.radio-inline, -.checkbox-inline { - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - font-weight: normal; - vertical-align: middle; - cursor: pointer; -} - -.radio-inline + .radio-inline, -.checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; -} - -input[type="radio"][disabled], -input[type="checkbox"][disabled], -.radio[disabled], -.radio-inline[disabled], -.checkbox[disabled], -.checkbox-inline[disabled], -fieldset[disabled] input[type="radio"], -fieldset[disabled] input[type="checkbox"], -fieldset[disabled] .radio, -fieldset[disabled] .radio-inline, -fieldset[disabled] .checkbox, -fieldset[disabled] .checkbox-inline { - cursor: not-allowed; -} - -.input-sm { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -select.input-sm { - height: 30px; - line-height: 30px; -} - -textarea.input-sm { - height: auto; -} - -.input-lg { - height: 45px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -select.input-lg { - height: 45px; - line-height: 45px; -} - -textarea.input-lg { - height: auto; -} - -.has-warning .help-block, -.has-warning .control-label { - color: #c09853; -} - -.has-warning .form-control { - border-color: #c09853; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-warning .form-control:focus { - border-color: #a47e3c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; -} - -.has-warning .input-group-addon { - color: #c09853; - background-color: #fcf8e3; - border-color: #c09853; -} - -.has-error .help-block, -.has-error .control-label { - color: #b94a48; -} - -.has-error .form-control { - border-color: #b94a48; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-error .form-control:focus { - border-color: #953b39; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; -} - -.has-error .input-group-addon { - color: #b94a48; - background-color: #f2dede; - border-color: #b94a48; -} - -.has-success .help-block, -.has-success .control-label { - color: #468847; -} - -.has-success .form-control { - border-color: #468847; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-success .form-control:focus { - border-color: #356635; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; -} - -.has-success .input-group-addon { - color: #468847; - background-color: #dff0d8; - border-color: #468847; -} - -.form-control-static { - padding-top: 7px; - margin-bottom: 0; -} - -.help-block { - display: block; - margin-top: 5px; - margin-bottom: 10px; - color: #737373; -} - -@media (min-width: 768px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .form-control { - display: inline-block; - } - .form-inline .radio, - .form-inline .checkbox { - display: inline-block; - padding-left: 0; - margin-top: 0; - margin-bottom: 0; - } - .form-inline .radio input[type="radio"], - .form-inline .checkbox input[type="checkbox"] { - float: none; - margin-left: 0; - } -} - -.form-horizontal .control-label, -.form-horizontal .radio, -.form-horizontal .checkbox, -.form-horizontal .radio-inline, -.form-horizontal .checkbox-inline { - padding-top: 7px; - margin-top: 0; - margin-bottom: 0; -} - -.form-horizontal .form-group { - margin-right: -15px; - margin-left: -15px; -} - -.form-horizontal .form-group:before, -.form-horizontal .form-group:after { - display: table; - content: " "; -} - -.form-horizontal .form-group:after { - clear: both; -} - -.form-horizontal .form-group:before, -.form-horizontal .form-group:after { - display: table; - content: " "; -} - -.form-horizontal .form-group:after { - clear: both; -} - -@media (min-width: 768px) { - .form-horizontal .control-label { - text-align: right; - } -} - -.btn { - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-size: 14px; - font-weight: normal; - line-height: 1.428571429; - text-align: center; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - border: 1px solid transparent; - border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} - -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.btn:hover, -.btn:focus { - color: #333333; - text-decoration: none; -} - -.btn:active, -.btn.active { - background-image: none; - outline: 0; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} - -.btn.disabled, -.btn[disabled], -fieldset[disabled] .btn { - pointer-events: none; - cursor: not-allowed; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; -} - -.btn-default { - color: #333333; - background-color: #ffffff; - border-color: #cccccc; -} - -.btn-default:hover, -.btn-default:focus, -.btn-default:active, -.btn-default.active, -.open .dropdown-toggle.btn-default { - color: #333333; - background-color: #ebebeb; - border-color: #adadad; -} - -.btn-default:active, -.btn-default.active, -.open .dropdown-toggle.btn-default { - background-image: none; -} - -.btn-default.disabled, -.btn-default[disabled], -fieldset[disabled] .btn-default, -.btn-default.disabled:hover, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default:hover, -.btn-default.disabled:focus, -.btn-default[disabled]:focus, -fieldset[disabled] .btn-default:focus, -.btn-default.disabled:active, -.btn-default[disabled]:active, -fieldset[disabled] .btn-default:active, -.btn-default.disabled.active, -.btn-default[disabled].active, -fieldset[disabled] .btn-default.active { - background-color: #ffffff; - border-color: #cccccc; -} - -.btn-primary { - color: #ffffff; - background-color: #428bca; - border-color: #357ebd; -} - -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #3276b1; - border-color: #285e8e; -} - -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - background-image: none; -} - -.btn-primary.disabled, -.btn-primary[disabled], -fieldset[disabled] .btn-primary, -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled:active, -.btn-primary[disabled]:active, -fieldset[disabled] .btn-primary:active, -.btn-primary.disabled.active, -.btn-primary[disabled].active, -fieldset[disabled] .btn-primary.active { - background-color: #428bca; - border-color: #357ebd; -} - -.btn-warning { - color: #ffffff; - background-color: #f0ad4e; - border-color: #eea236; -} - -.btn-warning:hover, -.btn-warning:focus, -.btn-warning:active, -.btn-warning.active, -.open .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #ed9c28; - border-color: #d58512; -} - -.btn-warning:active, -.btn-warning.active, -.open .dropdown-toggle.btn-warning { - background-image: none; -} - -.btn-warning.disabled, -.btn-warning[disabled], -fieldset[disabled] .btn-warning, -.btn-warning.disabled:hover, -.btn-warning[disabled]:hover, -fieldset[disabled] .btn-warning:hover, -.btn-warning.disabled:focus, -.btn-warning[disabled]:focus, -fieldset[disabled] .btn-warning:focus, -.btn-warning.disabled:active, -.btn-warning[disabled]:active, -fieldset[disabled] .btn-warning:active, -.btn-warning.disabled.active, -.btn-warning[disabled].active, -fieldset[disabled] .btn-warning.active { - background-color: #f0ad4e; - border-color: #eea236; -} - -.btn-danger { - color: #ffffff; - background-color: #d9534f; - border-color: #d43f3a; -} - -.btn-danger:hover, -.btn-danger:focus, -.btn-danger:active, -.btn-danger.active, -.open .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #d2322d; - border-color: #ac2925; -} - -.btn-danger:active, -.btn-danger.active, -.open .dropdown-toggle.btn-danger { - background-image: none; -} - -.btn-danger.disabled, -.btn-danger[disabled], -fieldset[disabled] .btn-danger, -.btn-danger.disabled:hover, -.btn-danger[disabled]:hover, -fieldset[disabled] .btn-danger:hover, -.btn-danger.disabled:focus, -.btn-danger[disabled]:focus, -fieldset[disabled] .btn-danger:focus, -.btn-danger.disabled:active, -.btn-danger[disabled]:active, -fieldset[disabled] .btn-danger:active, -.btn-danger.disabled.active, -.btn-danger[disabled].active, -fieldset[disabled] .btn-danger.active { - background-color: #d9534f; - border-color: #d43f3a; -} - -.btn-success { - color: #ffffff; - background-color: #5cb85c; - border-color: #4cae4c; -} - -.btn-success:hover, -.btn-success:focus, -.btn-success:active, -.btn-success.active, -.open .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #47a447; - border-color: #398439; -} - -.btn-success:active, -.btn-success.active, -.open .dropdown-toggle.btn-success { - background-image: none; -} - -.btn-success.disabled, -.btn-success[disabled], -fieldset[disabled] .btn-success, -.btn-success.disabled:hover, -.btn-success[disabled]:hover, -fieldset[disabled] .btn-success:hover, -.btn-success.disabled:focus, -.btn-success[disabled]:focus, -fieldset[disabled] .btn-success:focus, -.btn-success.disabled:active, -.btn-success[disabled]:active, -fieldset[disabled] .btn-success:active, -.btn-success.disabled.active, -.btn-success[disabled].active, -fieldset[disabled] .btn-success.active { - background-color: #5cb85c; - border-color: #4cae4c; -} - -.btn-info { - color: #ffffff; - background-color: #5bc0de; - border-color: #46b8da; -} - -.btn-info:hover, -.btn-info:focus, -.btn-info:active, -.btn-info.active, -.open .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #39b3d7; - border-color: #269abc; -} - -.btn-info:active, -.btn-info.active, -.open .dropdown-toggle.btn-info { - background-image: none; -} - -.btn-info.disabled, -.btn-info[disabled], -fieldset[disabled] .btn-info, -.btn-info.disabled:hover, -.btn-info[disabled]:hover, -fieldset[disabled] .btn-info:hover, -.btn-info.disabled:focus, -.btn-info[disabled]:focus, -fieldset[disabled] .btn-info:focus, -.btn-info.disabled:active, -.btn-info[disabled]:active, -fieldset[disabled] .btn-info:active, -.btn-info.disabled.active, -.btn-info[disabled].active, -fieldset[disabled] .btn-info.active { - background-color: #5bc0de; - border-color: #46b8da; -} - -.btn-link { - font-weight: normal; - color: #428bca; - cursor: pointer; - border-radius: 0; -} - -.btn-link, -.btn-link:active, -.btn-link[disabled], -fieldset[disabled] .btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; -} - -.btn-link, -.btn-link:hover, -.btn-link:focus, -.btn-link:active { - border-color: transparent; -} - -.btn-link:hover, -.btn-link:focus { - color: #2a6496; - text-decoration: underline; - background-color: transparent; -} - -.btn-link[disabled]:hover, -fieldset[disabled] .btn-link:hover, -.btn-link[disabled]:focus, -fieldset[disabled] .btn-link:focus { - color: #999999; - text-decoration: none; -} - -.btn-lg { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -.btn-sm, -.btn-xs { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-xs { - padding: 1px 5px; -} - -.btn-block { - display: block; - width: 100%; - padding-right: 0; - padding-left: 0; -} - -.btn-block + .btn-block { - margin-top: 5px; -} - -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} - -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} - -.fade.in { - opacity: 1; -} - -.collapse { - display: none; -} - -.collapse.in { - display: block; -} - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition: height 0.35s ease; - transition: height 0.35s ease; -} - -@font-face { - font-family: 'Glyphicons Halflings'; - src: url('../fonts/glyphicons-halflings-regular.eot'); - src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); -} - -.glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - line-height: 1; -} - -.glyphicon-asterisk:before { - content: "\2a"; -} - -.glyphicon-plus:before { - content: "\2b"; -} - -.glyphicon-euro:before { - content: "\20ac"; -} - -.glyphicon-minus:before { - content: "\2212"; -} - -.glyphicon-cloud:before { - content: "\2601"; -} - -.glyphicon-envelope:before { - content: "\2709"; -} - -.glyphicon-pencil:before { - content: "\270f"; -} - -.glyphicon-glass:before { - content: "\e001"; -} - -.glyphicon-music:before { - content: "\e002"; -} - -.glyphicon-search:before { - content: "\e003"; -} - -.glyphicon-heart:before { - content: "\e005"; -} - -.glyphicon-star:before { - content: "\e006"; -} - -.glyphicon-star-empty:before { - content: "\e007"; -} - -.glyphicon-user:before { - content: "\e008"; -} - -.glyphicon-film:before { - content: "\e009"; -} - -.glyphicon-th-large:before { - content: "\e010"; -} - -.glyphicon-th:before { - content: "\e011"; -} - -.glyphicon-th-list:before { - content: "\e012"; -} - -.glyphicon-ok:before { - content: "\e013"; -} - -.glyphicon-remove:before { - content: "\e014"; -} - -.glyphicon-zoom-in:before { - content: "\e015"; -} - -.glyphicon-zoom-out:before { - content: "\e016"; -} - -.glyphicon-off:before { - content: "\e017"; -} - -.glyphicon-signal:before { - content: "\e018"; -} - -.glyphicon-cog:before { - content: "\e019"; -} - -.glyphicon-trash:before { - content: "\e020"; -} - -.glyphicon-home:before { - content: "\e021"; -} - -.glyphicon-file:before { - content: "\e022"; -} - -.glyphicon-time:before { - content: "\e023"; -} - -.glyphicon-road:before { - content: "\e024"; -} - -.glyphicon-download-alt:before { - content: "\e025"; -} - -.glyphicon-download:before { - content: "\e026"; -} - -.glyphicon-upload:before { - content: "\e027"; -} - -.glyphicon-inbox:before { - content: "\e028"; -} - -.glyphicon-play-circle:before { - content: "\e029"; -} - -.glyphicon-repeat:before { - content: "\e030"; -} - -.glyphicon-refresh:before { - content: "\e031"; -} - -.glyphicon-list-alt:before { - content: "\e032"; -} - -.glyphicon-flag:before { - content: "\e034"; -} - -.glyphicon-headphones:before { - content: "\e035"; -} - -.glyphicon-volume-off:before { - content: "\e036"; -} - -.glyphicon-volume-down:before { - content: "\e037"; -} - -.glyphicon-volume-up:before { - content: "\e038"; -} - -.glyphicon-qrcode:before { - content: "\e039"; -} - -.glyphicon-barcode:before { - content: "\e040"; -} - -.glyphicon-tag:before { - content: "\e041"; -} - -.glyphicon-tags:before { - content: "\e042"; -} - -.glyphicon-book:before { - content: "\e043"; -} - -.glyphicon-print:before { - content: "\e045"; -} - -.glyphicon-font:before { - content: "\e047"; -} - -.glyphicon-bold:before { - content: "\e048"; -} - -.glyphicon-italic:before { - content: "\e049"; -} - -.glyphicon-text-height:before { - content: "\e050"; -} - -.glyphicon-text-width:before { - content: "\e051"; -} - -.glyphicon-align-left:before { - content: "\e052"; -} - -.glyphicon-align-center:before { - content: "\e053"; -} - -.glyphicon-align-right:before { - content: "\e054"; -} - -.glyphicon-align-justify:before { - content: "\e055"; -} - -.glyphicon-list:before { - content: "\e056"; -} - -.glyphicon-indent-left:before { - content: "\e057"; -} - -.glyphicon-indent-right:before { - content: "\e058"; -} - -.glyphicon-facetime-video:before { - content: "\e059"; -} - -.glyphicon-picture:before { - content: "\e060"; -} - -.glyphicon-map-marker:before { - content: "\e062"; -} - -.glyphicon-adjust:before { - content: "\e063"; -} - -.glyphicon-tint:before { - content: "\e064"; -} - -.glyphicon-edit:before { - content: "\e065"; -} - -.glyphicon-share:before { - content: "\e066"; -} - -.glyphicon-check:before { - content: "\e067"; -} - -.glyphicon-move:before { - content: "\e068"; -} - -.glyphicon-step-backward:before { - content: "\e069"; -} - -.glyphicon-fast-backward:before { - content: "\e070"; -} - -.glyphicon-backward:before { - content: "\e071"; -} - -.glyphicon-play:before { - content: "\e072"; -} - -.glyphicon-pause:before { - content: "\e073"; -} - -.glyphicon-stop:before { - content: "\e074"; -} - -.glyphicon-forward:before { - content: "\e075"; -} - -.glyphicon-fast-forward:before { - content: "\e076"; -} - -.glyphicon-step-forward:before { - content: "\e077"; -} - -.glyphicon-eject:before { - content: "\e078"; -} - -.glyphicon-chevron-left:before { - content: "\e079"; -} - -.glyphicon-chevron-right:before { - content: "\e080"; -} - -.glyphicon-plus-sign:before { - content: "\e081"; -} - -.glyphicon-minus-sign:before { - content: "\e082"; -} - -.glyphicon-remove-sign:before { - content: "\e083"; -} - -.glyphicon-ok-sign:before { - content: "\e084"; -} - -.glyphicon-question-sign:before { - content: "\e085"; -} - -.glyphicon-info-sign:before { - content: "\e086"; -} - -.glyphicon-screenshot:before { - content: "\e087"; -} - -.glyphicon-remove-circle:before { - content: "\e088"; -} - -.glyphicon-ok-circle:before { - content: "\e089"; -} - -.glyphicon-ban-circle:before { - content: "\e090"; -} - -.glyphicon-arrow-left:before { - content: "\e091"; -} - -.glyphicon-arrow-right:before { - content: "\e092"; -} - -.glyphicon-arrow-up:before { - content: "\e093"; -} - -.glyphicon-arrow-down:before { - content: "\e094"; -} - -.glyphicon-share-alt:before { - content: "\e095"; -} - -.glyphicon-resize-full:before { - content: "\e096"; -} - -.glyphicon-resize-small:before { - content: "\e097"; -} - -.glyphicon-exclamation-sign:before { - content: "\e101"; -} - -.glyphicon-gift:before { - content: "\e102"; -} - -.glyphicon-leaf:before { - content: "\e103"; -} - -.glyphicon-eye-open:before { - content: "\e105"; -} - -.glyphicon-eye-close:before { - content: "\e106"; -} - -.glyphicon-warning-sign:before { - content: "\e107"; -} - -.glyphicon-plane:before { - content: "\e108"; -} - -.glyphicon-random:before { - content: "\e110"; -} - -.glyphicon-comment:before { - content: "\e111"; -} - -.glyphicon-magnet:before { - content: "\e112"; -} - -.glyphicon-chevron-up:before { - content: "\e113"; -} - -.glyphicon-chevron-down:before { - content: "\e114"; -} - -.glyphicon-retweet:before { - content: "\e115"; -} - -.glyphicon-shopping-cart:before { - content: "\e116"; -} - -.glyphicon-folder-close:before { - content: "\e117"; -} - -.glyphicon-folder-open:before { - content: "\e118"; -} - -.glyphicon-resize-vertical:before { - content: "\e119"; -} - -.glyphicon-resize-horizontal:before { - content: "\e120"; -} - -.glyphicon-hdd:before { - content: "\e121"; -} - -.glyphicon-bullhorn:before { - content: "\e122"; -} - -.glyphicon-certificate:before { - content: "\e124"; -} - -.glyphicon-thumbs-up:before { - content: "\e125"; -} - -.glyphicon-thumbs-down:before { - content: "\e126"; -} - -.glyphicon-hand-right:before { - content: "\e127"; -} - -.glyphicon-hand-left:before { - content: "\e128"; -} - -.glyphicon-hand-up:before { - content: "\e129"; -} - -.glyphicon-hand-down:before { - content: "\e130"; -} - -.glyphicon-circle-arrow-right:before { - content: "\e131"; -} - -.glyphicon-circle-arrow-left:before { - content: "\e132"; -} - -.glyphicon-circle-arrow-up:before { - content: "\e133"; -} - -.glyphicon-circle-arrow-down:before { - content: "\e134"; -} - -.glyphicon-globe:before { - content: "\e135"; -} - -.glyphicon-tasks:before { - content: "\e137"; -} - -.glyphicon-filter:before { - content: "\e138"; -} - -.glyphicon-fullscreen:before { - content: "\e140"; -} - -.glyphicon-dashboard:before { - content: "\e141"; -} - -.glyphicon-heart-empty:before { - content: "\e143"; -} - -.glyphicon-link:before { - content: "\e144"; -} - -.glyphicon-phone:before { - content: "\e145"; -} - -.glyphicon-usd:before { - content: "\e148"; -} - -.glyphicon-gbp:before { - content: "\e149"; -} - -.glyphicon-sort:before { - content: "\e150"; -} - -.glyphicon-sort-by-alphabet:before { - content: "\e151"; -} - -.glyphicon-sort-by-alphabet-alt:before { - content: "\e152"; -} - -.glyphicon-sort-by-order:before { - content: "\e153"; -} - -.glyphicon-sort-by-order-alt:before { - content: "\e154"; -} - -.glyphicon-sort-by-attributes:before { - content: "\e155"; -} - -.glyphicon-sort-by-attributes-alt:before { - content: "\e156"; -} - -.glyphicon-unchecked:before { - content: "\e157"; -} - -.glyphicon-expand:before { - content: "\e158"; -} - -.glyphicon-collapse-down:before { - content: "\e159"; -} - -.glyphicon-collapse-up:before { - content: "\e160"; -} - -.glyphicon-log-in:before { - content: "\e161"; -} - -.glyphicon-flash:before { - content: "\e162"; -} - -.glyphicon-log-out:before { - content: "\e163"; -} - -.glyphicon-new-window:before { - content: "\e164"; -} - -.glyphicon-record:before { - content: "\e165"; -} - -.glyphicon-save:before { - content: "\e166"; -} - -.glyphicon-open:before { - content: "\e167"; -} - -.glyphicon-saved:before { - content: "\e168"; -} - -.glyphicon-import:before { - content: "\e169"; -} - -.glyphicon-export:before { - content: "\e170"; -} - -.glyphicon-send:before { - content: "\e171"; -} - -.glyphicon-floppy-disk:before { - content: "\e172"; -} - -.glyphicon-floppy-saved:before { - content: "\e173"; -} - -.glyphicon-floppy-remove:before { - content: "\e174"; -} - -.glyphicon-floppy-save:before { - content: "\e175"; -} - -.glyphicon-floppy-open:before { - content: "\e176"; -} - -.glyphicon-credit-card:before { - content: "\e177"; -} - -.glyphicon-transfer:before { - content: "\e178"; -} - -.glyphicon-cutlery:before { - content: "\e179"; -} - -.glyphicon-header:before { - content: "\e180"; -} - -.glyphicon-compressed:before { - content: "\e181"; -} - -.glyphicon-earphone:before { - content: "\e182"; -} - -.glyphicon-phone-alt:before { - content: "\e183"; -} - -.glyphicon-tower:before { - content: "\e184"; -} - -.glyphicon-stats:before { - content: "\e185"; -} - -.glyphicon-sd-video:before { - content: "\e186"; -} - -.glyphicon-hd-video:before { - content: "\e187"; -} - -.glyphicon-subtitles:before { - content: "\e188"; -} - -.glyphicon-sound-stereo:before { - content: "\e189"; -} - -.glyphicon-sound-dolby:before { - content: "\e190"; -} - -.glyphicon-sound-5-1:before { - content: "\e191"; -} - -.glyphicon-sound-6-1:before { - content: "\e192"; -} - -.glyphicon-sound-7-1:before { - content: "\e193"; -} - -.glyphicon-copyright-mark:before { - content: "\e194"; -} - -.glyphicon-registration-mark:before { - content: "\e195"; -} - -.glyphicon-cloud-download:before { - content: "\e197"; -} - -.glyphicon-cloud-upload:before { - content: "\e198"; -} - -.glyphicon-tree-conifer:before { - content: "\e199"; -} - -.glyphicon-tree-deciduous:before { - content: "\e200"; -} - -.glyphicon-briefcase:before { - content: "\1f4bc"; -} - -.glyphicon-calendar:before { - content: "\1f4c5"; -} - -.glyphicon-pushpin:before { - content: "\1f4cc"; -} - -.glyphicon-paperclip:before { - content: "\1f4ce"; -} - -.glyphicon-camera:before { - content: "\1f4f7"; -} - -.glyphicon-lock:before { - content: "\1f512"; -} - -.glyphicon-bell:before { - content: "\1f514"; -} - -.glyphicon-bookmark:before { - content: "\1f516"; -} - -.glyphicon-fire:before { - content: "\1f525"; -} - -.glyphicon-wrench:before { - content: "\1f527"; -} - -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px solid #000000; - border-right: 4px solid transparent; - border-bottom: 0 dotted; - border-left: 4px solid transparent; - content: ""; -} - -.dropdown { - position: relative; -} - -.dropdown-toggle:focus { - outline: 0; -} - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - font-size: 14px; - list-style: none; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; -} - -.dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.dropdown-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} - -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.428571429; - color: #333333; - white-space: nowrap; -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - color: #ffffff; - text-decoration: none; - background-color: #428bca; -} - -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #ffffff; - text-decoration: none; - background-color: #428bca; - outline: 0; -} - -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #999999; -} - -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - cursor: not-allowed; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.open > .dropdown-menu { - display: block; -} - -.open > a { - outline: 0; -} - -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.428571429; - color: #999999; -} - -.dropdown-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 990; -} - -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0 dotted; - border-bottom: 4px solid #000000; - content: ""; -} - -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} - -@media (min-width: 768px) { - .navbar-right .dropdown-menu { - right: 0; - left: auto; - } -} - -.btn-default .caret { - border-top-color: #333333; -} - -.btn-primary .caret, -.btn-success .caret, -.btn-warning .caret, -.btn-danger .caret, -.btn-info .caret { - border-top-color: #fff; -} - -.dropup .btn-default .caret { - border-bottom-color: #333333; -} - -.dropup .btn-primary .caret, -.dropup .btn-success .caret, -.dropup .btn-warning .caret, -.dropup .btn-danger .caret, -.dropup .btn-info .caret { - border-bottom-color: #fff; -} - -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; -} - -.btn-group > .btn, -.btn-group-vertical > .btn { - position: relative; - float: left; -} - -.btn-group > .btn:hover, -.btn-group-vertical > .btn:hover, -.btn-group > .btn:focus, -.btn-group-vertical > .btn:focus, -.btn-group > .btn:active, -.btn-group-vertical > .btn:active, -.btn-group > .btn.active, -.btn-group-vertical > .btn.active { - z-index: 2; -} - -.btn-group > .btn:focus, -.btn-group-vertical > .btn:focus { - outline: none; -} - -.btn-group .btn + .btn, -.btn-group .btn + .btn-group, -.btn-group .btn-group + .btn, -.btn-group .btn-group + .btn-group { - margin-left: -1px; -} - -.btn-toolbar:before, -.btn-toolbar:after { - display: table; - content: " "; -} - -.btn-toolbar:after { - clear: both; -} - -.btn-toolbar:before, -.btn-toolbar:after { - display: table; - content: " "; -} - -.btn-toolbar:after { - clear: both; -} - -.btn-toolbar .btn-group { - float: left; -} - -.btn-toolbar > .btn + .btn, -.btn-toolbar > .btn-group + .btn, -.btn-toolbar > .btn + .btn-group, -.btn-toolbar > .btn-group + .btn-group { - margin-left: 5px; -} - -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; -} - -.btn-group > .btn:first-child { - margin-left: 0; -} - -.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.btn-group > .btn:last-child:not(:first-child), -.btn-group > .dropdown-toggle:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.btn-group > .btn-group { - float: left; -} - -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} - -.btn-group > .btn-group:first-child > .btn:last-child, -.btn-group > .btn-group:first-child > .dropdown-toggle { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.btn-group > .btn-group:last-child > .btn:first-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - -.btn-group-xs > .btn { - padding: 5px 10px; - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-group-sm > .btn { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-group-lg > .btn { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -.btn-group > .btn + .dropdown-toggle { - padding-right: 8px; - padding-left: 8px; -} - -.btn-group > .btn-lg + .dropdown-toggle { - padding-right: 12px; - padding-left: 12px; -} - -.btn-group.open .dropdown-toggle { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} - -.btn .caret { - margin-left: 0; -} - -.btn-lg .caret { - border-width: 5px 5px 0; - border-bottom-width: 0; -} - -.dropup .btn-lg .caret { - border-width: 0 5px 5px; -} - -.btn-group-vertical > .btn, -.btn-group-vertical > .btn-group { - display: block; - float: none; - width: 100%; - max-width: 100%; -} - -.btn-group-vertical > .btn-group:before, -.btn-group-vertical > .btn-group:after { - display: table; - content: " "; -} - -.btn-group-vertical > .btn-group:after { - clear: both; -} - -.btn-group-vertical > .btn-group:before, -.btn-group-vertical > .btn-group:after { - display: table; - content: " "; -} - -.btn-group-vertical > .btn-group:after { - clear: both; -} - -.btn-group-vertical > .btn-group > .btn { - float: none; -} - -.btn-group-vertical > .btn + .btn, -.btn-group-vertical > .btn + .btn-group, -.btn-group-vertical > .btn-group + .btn, -.btn-group-vertical > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; -} - -.btn-group-vertical > .btn:not(:first-child):not(:last-child) { - border-radius: 0; -} - -.btn-group-vertical > .btn:first-child:not(:last-child) { - border-top-right-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.btn-group-vertical > .btn:last-child:not(:first-child) { - border-top-right-radius: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 0; -} - -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} - -.btn-group-vertical > .btn-group:first-child > .btn:last-child, -.btn-group-vertical > .btn-group:first-child > .dropdown-toggle { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.btn-group-vertical > .btn-group:last-child > .btn:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.btn-group-justified { - display: table; - width: 100%; - border-collapse: separate; - table-layout: fixed; -} - -.btn-group-justified .btn { - display: table-cell; - float: none; - width: 1%; -} - -[data-toggle="buttons"] > .btn > input[type="radio"], -[data-toggle="buttons"] > .btn > input[type="checkbox"] { - display: none; -} - -.input-group { - position: relative; - display: table; - border-collapse: separate; -} - -.input-group.col { - float: none; - padding-right: 0; - padding-left: 0; -} - -.input-group .form-control { - width: 100%; - margin-bottom: 0; -} - -.input-group-lg > .form-control, -.input-group-lg > .input-group-addon, -.input-group-lg > .input-group-btn > .btn { - height: 45px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -select.input-group-lg > .form-control, -select.input-group-lg > .input-group-addon, -select.input-group-lg > .input-group-btn > .btn { - height: 45px; - line-height: 45px; -} - -textarea.input-group-lg > .form-control, -textarea.input-group-lg > .input-group-addon, -textarea.input-group-lg > .input-group-btn > .btn { - height: auto; -} - -.input-group-sm > .form-control, -.input-group-sm > .input-group-addon, -.input-group-sm > .input-group-btn > .btn { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -select.input-group-sm > .form-control, -select.input-group-sm > .input-group-addon, -select.input-group-sm > .input-group-btn > .btn { - height: 30px; - line-height: 30px; -} - -textarea.input-group-sm > .form-control, -textarea.input-group-sm > .input-group-addon, -textarea.input-group-sm > .input-group-btn > .btn { - height: auto; -} - -.input-group-addon, -.input-group-btn, -.input-group .form-control { - display: table-cell; -} - -.input-group-addon:not(:first-child):not(:last-child), -.input-group-btn:not(:first-child):not(:last-child), -.input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; -} - -.input-group-addon, -.input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle; -} - -.input-group-addon { - padding: 6px 12px; - font-size: 14px; - font-weight: normal; - line-height: 1; - text-align: center; - background-color: #eeeeee; - border: 1px solid #cccccc; - border-radius: 4px; -} - -.input-group-addon.input-sm { - padding: 5px 10px; - font-size: 12px; - border-radius: 3px; -} - -.input-group-addon.input-lg { - padding: 10px 16px; - font-size: 18px; - border-radius: 6px; -} - -.input-group-addon input[type="radio"], -.input-group-addon input[type="checkbox"] { - margin-top: 0; -} - -.input-group .form-control:first-child, -.input-group-addon:first-child, -.input-group-btn:first-child > .btn, -.input-group-btn:first-child > .dropdown-toggle, -.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.input-group-addon:first-child { - border-right: 0; -} - -.input-group .form-control:last-child, -.input-group-addon:last-child, -.input-group-btn:last-child > .btn, -.input-group-btn:last-child > .dropdown-toggle, -.input-group-btn:first-child > .btn:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.input-group-addon:last-child { - border-left: 0; -} - -.input-group-btn { - position: relative; - white-space: nowrap; -} - -.input-group-btn > .btn { - position: relative; -} - -.input-group-btn > .btn + .btn { - margin-left: -4px; -} - -.input-group-btn > .btn:hover, -.input-group-btn > .btn:active { - z-index: 2; -} - -.nav { - padding-left: 0; - margin-bottom: 0; - list-style: none; -} - -.nav:before, -.nav:after { - display: table; - content: " "; -} - -.nav:after { - clear: both; -} - -.nav:before, -.nav:after { - display: table; - content: " "; -} - -.nav:after { - clear: both; -} - -.nav > li { - position: relative; - display: block; -} - -.nav > li > a { - position: relative; - display: block; - padding: 10px 15px; -} - -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} - -.nav > li.disabled > a { - color: #999999; -} - -.nav > li.disabled > a:hover, -.nav > li.disabled > a:focus { - color: #999999; - text-decoration: none; - cursor: not-allowed; - background-color: transparent; -} - -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - background-color: #eeeeee; - border-color: #428bca; -} - -.nav .nav-divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} - -.nav > li > a > img { - max-width: none; -} - -.nav-tabs { - border-bottom: 1px solid #dddddd; -} - -.nav-tabs > li { - float: left; - margin-bottom: -1px; -} - -.nav-tabs > li > a { - margin-right: 2px; - line-height: 1.428571429; - border: 1px solid transparent; - border-radius: 4px 4px 0 0; -} - -.nav-tabs > li > a:hover { - border-color: #eeeeee #eeeeee #dddddd; -} - -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - color: #555555; - cursor: default; - background-color: #ffffff; - border: 1px solid #dddddd; - border-bottom-color: transparent; -} - -.nav-tabs.nav-justified { - width: 100%; - border-bottom: 0; -} - -.nav-tabs.nav-justified > li { - float: none; -} - -.nav-tabs.nav-justified > li > a { - text-align: center; -} - -@media (min-width: 768px) { - .nav-tabs.nav-justified > li { - display: table-cell; - width: 1%; - } -} - -.nav-tabs.nav-justified > li > a { - margin-right: 0; - border-bottom: 1px solid #dddddd; -} - -.nav-tabs.nav-justified > .active > a { - border-bottom-color: #ffffff; -} - -.nav-pills > li { - float: left; -} - -.nav-pills > li > a { - border-radius: 5px; -} - -.nav-pills > li + li { - margin-left: 2px; -} - -.nav-pills > li.active > a, -.nav-pills > li.active > a:hover, -.nav-pills > li.active > a:focus { - color: #ffffff; - background-color: #428bca; -} - -.nav-stacked > li { - float: none; -} - -.nav-stacked > li + li { - margin-top: 2px; - margin-left: 0; -} - -.nav-justified { - width: 100%; -} - -.nav-justified > li { - float: none; -} - -.nav-justified > li > a { - text-align: center; -} - -@media (min-width: 768px) { - .nav-justified > li { - display: table-cell; - width: 1%; - } -} - -.nav-tabs-justified { - border-bottom: 0; -} - -.nav-tabs-justified > li > a { - margin-right: 0; - border-bottom: 1px solid #dddddd; -} - -.nav-tabs-justified > .active > a { - border-bottom-color: #ffffff; -} - -.tabbable:before, -.tabbable:after { - display: table; - content: " "; -} - -.tabbable:after { - clear: both; -} - -.tabbable:before, -.tabbable:after { - display: table; - content: " "; -} - -.tabbable:after { - clear: both; -} - -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} - -.tab-content > .active, -.pill-content > .active { - display: block; -} - -.nav .caret { - border-top-color: #428bca; - border-bottom-color: #428bca; -} - -.nav a:hover .caret { - border-top-color: #2a6496; - border-bottom-color: #2a6496; -} - -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.navbar { - position: relative; - z-index: 1000; - min-height: 50px; - margin-bottom: 20px; - border: 1px solid transparent; -} - -.navbar:before, -.navbar:after { - display: table; - content: " "; -} - -.navbar:after { - clear: both; -} - -.navbar:before, -.navbar:after { - display: table; - content: " "; -} - -.navbar:after { - clear: both; -} - -@media (min-width: 768px) { - .navbar { - border-radius: 4px; - } -} - -.navbar-header:before, -.navbar-header:after { - display: table; - content: " "; -} - -.navbar-header:after { - clear: both; -} - -.navbar-header:before, -.navbar-header:after { - display: table; - content: " "; -} - -.navbar-header:after { - clear: both; -} - -@media (min-width: 768px) { - .navbar-header { - float: left; - } -} - -.navbar-collapse { - max-height: 340px; - padding-right: 15px; - padding-left: 15px; - overflow-x: visible; - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - -webkit-overflow-scrolling: touch; -} - -.navbar-collapse:before, -.navbar-collapse:after { - display: table; - content: " "; -} - -.navbar-collapse:after { - clear: both; -} - -.navbar-collapse:before, -.navbar-collapse:after { - display: table; - content: " "; -} - -.navbar-collapse:after { - clear: both; -} - -.navbar-collapse.in { - overflow-y: auto; -} - -@media (min-width: 768px) { - .navbar-collapse { - width: auto; - border-top: 0; - box-shadow: none; - } - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - .navbar-collapse.in { - overflow-y: visible; - } - .navbar-collapse .navbar-nav.navbar-left:first-child { - margin-left: -15px; - } - .navbar-collapse .navbar-nav.navbar-right:last-child { - margin-right: -15px; - } - .navbar-collapse .navbar-text:last-child { - margin-right: 0; - } -} - -.container > .navbar-header, -.container > .navbar-collapse { - margin-right: -15px; - margin-left: -15px; -} - -@media (min-width: 768px) { - .container > .navbar-header, - .container > .navbar-collapse { - margin-right: 0; - margin-left: 0; - } -} - -.navbar-static-top { - border-width: 0 0 1px; -} - -@media (min-width: 768px) { - .navbar-static-top { - border-radius: 0; - } -} - -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - border-width: 0 0 1px; -} - -@media (min-width: 768px) { - .navbar-fixed-top, - .navbar-fixed-bottom { - border-radius: 0; - } -} - -.navbar-fixed-top { - top: 0; - z-index: 1030; -} - -.navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; -} - -.navbar-brand { - float: left; - padding: 15px 15px; - font-size: 18px; - line-height: 20px; -} - -.navbar-brand:hover, -.navbar-brand:focus { - text-decoration: none; -} - -@media (min-width: 768px) { - .navbar > .container .navbar-brand { - margin-left: -15px; - } -} - -.navbar-toggle { - position: relative; - float: right; - padding: 9px 10px; - margin-top: 8px; - margin-right: 15px; - margin-bottom: 8px; - background-color: transparent; - border: 1px solid transparent; - border-radius: 4px; -} - -.navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; -} - -.navbar-toggle .icon-bar + .icon-bar { - margin-top: 4px; -} - -@media (min-width: 768px) { - .navbar-toggle { - display: none; - } -} - -.navbar-nav { - margin: 7.5px -15px; -} - -.navbar-nav > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 20px; -} - -@media (max-width: 767px) { - .navbar-nav .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - box-shadow: none; - } - .navbar-nav .open .dropdown-menu > li > a, - .navbar-nav .open .dropdown-menu .dropdown-header { - padding: 5px 15px 5px 25px; - } - .navbar-nav .open .dropdown-menu > li > a { - line-height: 20px; - } - .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-nav .open .dropdown-menu > li > a:focus { - background-image: none; - } -} - -@media (min-width: 768px) { - .navbar-nav { - float: left; - margin: 0; - } - .navbar-nav > li { - float: left; - } - .navbar-nav > li > a { - padding-top: 15px; - padding-bottom: 15px; - } -} - -@media (min-width: 768px) { - .navbar-left { - float: left !important; - } - .navbar-right { - float: right !important; - } -} - -.navbar-form { - padding: 10px 15px; - margin-top: 8px; - margin-right: -15px; - margin-bottom: 8px; - margin-left: -15px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); -} - -@media (min-width: 768px) { - .navbar-form .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .form-control { - display: inline-block; - } - .navbar-form .radio, - .navbar-form .checkbox { - display: inline-block; - padding-left: 0; - margin-top: 0; - margin-bottom: 0; - } - .navbar-form .radio input[type="radio"], - .navbar-form .checkbox input[type="checkbox"] { - float: none; - margin-left: 0; - } -} - -@media (max-width: 767px) { - .navbar-form .form-group { - margin-bottom: 5px; - } -} - -@media (min-width: 768px) { - .navbar-form { - width: auto; - padding-top: 0; - padding-bottom: 0; - margin-right: 0; - margin-left: 0; - border: 0; - -webkit-box-shadow: none; - box-shadow: none; - } -} - -.navbar-nav > li > .dropdown-menu { - margin-top: 0; - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.navbar-nav.pull-right > li > .dropdown-menu, -.navbar-nav > li > .dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.navbar-btn { - margin-top: 8px; - margin-bottom: 8px; -} - -.navbar-text { - float: left; - margin-top: 15px; - margin-bottom: 15px; -} - -@media (min-width: 768px) { - .navbar-text { - margin-right: 15px; - margin-left: 15px; - } -} - -.navbar-default { - background-color: #f8f8f8; - border-color: #e7e7e7; -} - -.navbar-default .navbar-brand { - color: #777777; -} - -.navbar-default .navbar-brand:hover, -.navbar-default .navbar-brand:focus { - color: #5e5e5e; - background-color: transparent; -} - -.navbar-default .navbar-text { - color: #777777; -} - -.navbar-default .navbar-nav > li > a { - color: #777777; -} - -.navbar-default .navbar-nav > li > a:hover, -.navbar-default .navbar-nav > li > a:focus { - color: #333333; - background-color: transparent; -} - -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #555555; - background-color: #e7e7e7; -} - -.navbar-default .navbar-nav > .disabled > a, -.navbar-default .navbar-nav > .disabled > a:hover, -.navbar-default .navbar-nav > .disabled > a:focus { - color: #cccccc; - background-color: transparent; -} - -.navbar-default .navbar-toggle { - border-color: #dddddd; -} - -.navbar-default .navbar-toggle:hover, -.navbar-default .navbar-toggle:focus { - background-color: #dddddd; -} - -.navbar-default .navbar-toggle .icon-bar { - background-color: #cccccc; -} - -.navbar-default .navbar-collapse, -.navbar-default .navbar-form { - border-color: #e6e6e6; -} - -.navbar-default .navbar-nav > .dropdown > a:hover .caret, -.navbar-default .navbar-nav > .dropdown > a:focus .caret { - border-top-color: #333333; - border-bottom-color: #333333; -} - -.navbar-default .navbar-nav > .open > a, -.navbar-default .navbar-nav > .open > a:hover, -.navbar-default .navbar-nav > .open > a:focus { - color: #555555; - background-color: #e7e7e7; -} - -.navbar-default .navbar-nav > .open > a .caret, -.navbar-default .navbar-nav > .open > a:hover .caret, -.navbar-default .navbar-nav > .open > a:focus .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} - -.navbar-default .navbar-nav > .dropdown > a .caret { - border-top-color: #777777; - border-bottom-color: #777777; -} - -@media (max-width: 767px) { - .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #777777; - } - .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: #333333; - background-color: transparent; - } - .navbar-default .navbar-nav .open .dropdown-menu > .active > a, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #555555; - background-color: #e7e7e7; - } - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #cccccc; - background-color: transparent; - } -} - -.navbar-default .navbar-link { - color: #777777; -} - -.navbar-default .navbar-link:hover { - color: #333333; -} - -.navbar-inverse { - background-color: #222222; - border-color: #080808; -} - -.navbar-inverse .navbar-brand { - color: #999999; -} - -.navbar-inverse .navbar-brand:hover, -.navbar-inverse .navbar-brand:focus { - color: #ffffff; - background-color: transparent; -} - -.navbar-inverse .navbar-text { - color: #999999; -} - -.navbar-inverse .navbar-nav > li > a { - color: #999999; -} - -.navbar-inverse .navbar-nav > li > a:hover, -.navbar-inverse .navbar-nav > li > a:focus { - color: #ffffff; - background-color: transparent; -} - -.navbar-inverse .navbar-nav > .active > a, -.navbar-inverse .navbar-nav > .active > a:hover, -.navbar-inverse .navbar-nav > .active > a:focus { - color: #ffffff; - background-color: #080808; -} - -.navbar-inverse .navbar-nav > .disabled > a, -.navbar-inverse .navbar-nav > .disabled > a:hover, -.navbar-inverse .navbar-nav > .disabled > a:focus { - color: #444444; - background-color: transparent; -} - -.navbar-inverse .navbar-toggle { - border-color: #333333; -} - -.navbar-inverse .navbar-toggle:hover, -.navbar-inverse .navbar-toggle:focus { - background-color: #333333; -} - -.navbar-inverse .navbar-toggle .icon-bar { - background-color: #ffffff; -} - -.navbar-inverse .navbar-collapse, -.navbar-inverse .navbar-form { - border-color: #101010; -} - -.navbar-inverse .navbar-nav > .open > a, -.navbar-inverse .navbar-nav > .open > a:hover, -.navbar-inverse .navbar-nav > .open > a:focus { - color: #ffffff; - background-color: #080808; -} - -.navbar-inverse .navbar-nav > .dropdown > a:hover .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.navbar-inverse .navbar-nav > .dropdown > a .caret { - border-top-color: #999999; - border-bottom-color: #999999; -} - -.navbar-inverse .navbar-nav > .open > a .caret, -.navbar-inverse .navbar-nav > .open > a:hover .caret, -.navbar-inverse .navbar-nav > .open > a:focus .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -@media (max-width: 767px) { - .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { - border-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { - color: #999999; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { - color: #ffffff; - background-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #ffffff; - background-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #444444; - background-color: transparent; - } -} - -.navbar-inverse .navbar-link { - color: #999999; -} - -.navbar-inverse .navbar-link:hover { - color: #ffffff; -} - -.breadcrumb { - padding: 8px 15px; - margin-bottom: 20px; - list-style: none; - background-color: #f5f5f5; - border-radius: 4px; -} - -.breadcrumb > li { - display: inline-block; -} - -.breadcrumb > li + li:before { - padding: 0 5px; - color: #cccccc; - content: "/\00a0"; -} - -.breadcrumb > .active { - color: #999999; -} - -.pagination { - display: inline-block; - padding-left: 0; - margin: 20px 0; - border-radius: 4px; -} - -.pagination > li { - display: inline; -} - -.pagination > li > a, -.pagination > li > span { - position: relative; - float: left; - padding: 6px 12px; - margin-left: -1px; - line-height: 1.428571429; - text-decoration: none; - background-color: #ffffff; - border: 1px solid #dddddd; -} - -.pagination > li:first-child > a, -.pagination > li:first-child > span { - margin-left: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; -} - -.pagination > li:last-child > a, -.pagination > li:last-child > span { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; -} - -.pagination > li > a:hover, -.pagination > li > span:hover, -.pagination > li > a:focus, -.pagination > li > span:focus { - background-color: #eeeeee; -} - -.pagination > .active > a, -.pagination > .active > span, -.pagination > .active > a:hover, -.pagination > .active > span:hover, -.pagination > .active > a:focus, -.pagination > .active > span:focus { - z-index: 2; - color: #ffffff; - cursor: default; - background-color: #428bca; - border-color: #428bca; -} - -.pagination > .disabled > span, -.pagination > .disabled > a, -.pagination > .disabled > a:hover, -.pagination > .disabled > a:focus { - color: #999999; - cursor: not-allowed; - background-color: #ffffff; - border-color: #dddddd; -} - -.pagination-lg > li > a, -.pagination-lg > li > span { - padding: 10px 16px; - font-size: 18px; -} - -.pagination-lg > li:first-child > a, -.pagination-lg > li:first-child > span { - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; -} - -.pagination-lg > li:last-child > a, -.pagination-lg > li:last-child > span { - border-top-right-radius: 6px; - border-bottom-right-radius: 6px; -} - -.pagination-sm > li > a, -.pagination-sm > li > span { - padding: 5px 10px; - font-size: 12px; -} - -.pagination-sm > li:first-child > a, -.pagination-sm > li:first-child > span { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; -} - -.pagination-sm > li:last-child > a, -.pagination-sm > li:last-child > span { - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -.pager { - padding-left: 0; - margin: 20px 0; - text-align: center; - list-style: none; -} - -.pager:before, -.pager:after { - display: table; - content: " "; -} - -.pager:after { - clear: both; -} - -.pager:before, -.pager:after { - display: table; - content: " "; -} - -.pager:after { - clear: both; -} - -.pager li { - display: inline; -} - -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 15px; -} - -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} - -.pager .next > a, -.pager .next > span { - float: right; -} - -.pager .previous > a, -.pager .previous > span { - float: left; -} - -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #999999; - cursor: not-allowed; - background-color: #ffffff; -} - -.label { - display: inline; - padding: .2em .6em .3em; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: .25em; -} - -.label[href]:hover, -.label[href]:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} - -.label:empty { - display: none; -} - -.label-default { - background-color: #999999; -} - -.label-default[href]:hover, -.label-default[href]:focus { - background-color: #808080; -} - -.label-primary { - background-color: #428bca; -} - -.label-primary[href]:hover, -.label-primary[href]:focus { - background-color: #3071a9; -} - -.label-success { - background-color: #5cb85c; -} - -.label-success[href]:hover, -.label-success[href]:focus { - background-color: #449d44; -} - -.label-info { - background-color: #5bc0de; -} - -.label-info[href]:hover, -.label-info[href]:focus { - background-color: #31b0d5; -} - -.label-warning { - background-color: #f0ad4e; -} - -.label-warning[href]:hover, -.label-warning[href]:focus { - background-color: #ec971f; -} - -.label-danger { - background-color: #d9534f; -} - -.label-danger[href]:hover, -.label-danger[href]:focus { - background-color: #c9302c; -} - -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: 12px; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - background-color: #999999; - border-radius: 10px; -} - -.badge:empty { - display: none; -} - -a.badge:hover, -a.badge:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} - -.btn .badge { - position: relative; - top: -1px; -} - -a.list-group-item.active > .badge, -.nav-pills > .active > a > .badge { - color: #428bca; - background-color: #ffffff; -} - -.nav-pills > li > a > .badge { - margin-left: 3px; -} - -.jumbotron { - padding: 30px; - margin-bottom: 30px; - font-size: 21px; - font-weight: 200; - line-height: 2.1428571435; - color: inherit; - background-color: #eeeeee; -} - -.jumbotron h1 { - line-height: 1; - color: inherit; -} - -.jumbotron p { - line-height: 1.4; -} - -.container .jumbotron { - border-radius: 6px; -} - -@media screen and (min-width: 768px) { - .jumbotron { - padding-top: 48px; - padding-bottom: 48px; - } - .container .jumbotron { - padding-right: 60px; - padding-left: 60px; - } - .jumbotron h1 { - font-size: 63px; - } -} - -.thumbnail { - display: inline-block; - display: block; - height: auto; - max-width: 100%; - padding: 4px; - line-height: 1.428571429; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} - -.thumbnail > img { - display: block; - height: auto; - max-width: 100%; -} - -a.thumbnail:hover, -a.thumbnail:focus { - border-color: #428bca; -} - -.thumbnail > img { - margin-right: auto; - margin-left: auto; -} - -.thumbnail .caption { - padding: 9px; - color: #333333; -} - -.alert { - padding: 15px; - margin-bottom: 20px; - border: 1px solid transparent; - border-radius: 4px; -} - -.alert h4 { - margin-top: 0; - color: inherit; -} - -.alert .alert-link { - font-weight: bold; -} - -.alert > p, -.alert > ul { - margin-bottom: 0; -} - -.alert > p + p { - margin-top: 5px; -} - -.alert-dismissable { - padding-right: 35px; -} - -.alert-dismissable .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; -} - -.alert-success { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.alert-success hr { - border-top-color: #c9e2b3; -} - -.alert-success .alert-link { - color: #356635; -} - -.alert-info { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.alert-info hr { - border-top-color: #a6e1ec; -} - -.alert-info .alert-link { - color: #2d6987; -} - -.alert-warning { - color: #c09853; - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.alert-warning hr { - border-top-color: #f8e5be; -} - -.alert-warning .alert-link { - color: #a47e3c; -} - -.alert-danger { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.alert-danger hr { - border-top-color: #e6c1c7; -} - -.alert-danger .alert-link { - color: #953b39; -} - -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-moz-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-o-keyframes progress-bar-stripes { - from { - background-position: 0 0; - } - to { - background-position: 40px 0; - } -} - -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -.progress { - height: 20px; - margin-bottom: 20px; - overflow: hidden; - background-color: #f5f5f5; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} - -.progress-bar { - float: left; - width: 0; - height: 100%; - font-size: 12px; - color: #ffffff; - text-align: center; - background-color: #428bca; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-transition: width 0.6s ease; - transition: width 0.6s ease; -} - -.progress-striped .progress-bar { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 40px 40px; -} - -.progress.active .progress-bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} - -.progress-bar-success { - background-color: #5cb85c; -} - -.progress-striped .progress-bar-success { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-info { - background-color: #5bc0de; -} - -.progress-striped .progress-bar-info { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-warning { - background-color: #f0ad4e; -} - -.progress-striped .progress-bar-warning { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-danger { - background-color: #d9534f; -} - -.progress-striped .progress-bar-danger { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.media, -.media-body { - overflow: hidden; - zoom: 1; -} - -.media, -.media .media { - margin-top: 15px; -} - -.media:first-child { - margin-top: 0; -} - -.media-object { - display: block; -} - -.media-heading { - margin: 0 0 5px; -} - -.media > .pull-left { - margin-right: 10px; -} - -.media > .pull-right { - margin-left: 10px; -} - -.media-list { - padding-left: 0; - list-style: none; -} - -.list-group { - padding-left: 0; - margin-bottom: 20px; -} - -.list-group-item { - position: relative; - display: block; - padding: 10px 15px; - margin-bottom: -1px; - background-color: #ffffff; - border: 1px solid #dddddd; -} - -.list-group-item:first-child { - border-top-right-radius: 4px; - border-top-left-radius: 4px; -} - -.list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; -} - -.list-group-item > .badge { - float: right; -} - -.list-group-item > .badge + .badge { - margin-right: 5px; -} - -a.list-group-item { - color: #555555; -} - -a.list-group-item .list-group-item-heading { - color: #333333; -} - -a.list-group-item:hover, -a.list-group-item:focus { - text-decoration: none; - background-color: #f5f5f5; -} - -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - z-index: 2; - color: #ffffff; - background-color: #428bca; - border-color: #428bca; -} - -.list-group-item.active .list-group-item-heading, -.list-group-item.active:hover .list-group-item-heading, -.list-group-item.active:focus .list-group-item-heading { - color: inherit; -} - -.list-group-item.active .list-group-item-text, -.list-group-item.active:hover .list-group-item-text, -.list-group-item.active:focus .list-group-item-text { - color: #e1edf7; -} - -.list-group-item-heading { - margin-top: 0; - margin-bottom: 5px; -} - -.list-group-item-text { - margin-bottom: 0; - line-height: 1.3; -} - -.panel { - margin-bottom: 20px; - background-color: #ffffff; - border: 1px solid transparent; - border-radius: 4px; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.panel-body { - padding: 15px; -} - -.panel-body:before, -.panel-body:after { - display: table; - content: " "; -} - -.panel-body:after { - clear: both; -} - -.panel-body:before, -.panel-body:after { - display: table; - content: " "; -} - -.panel-body:after { - clear: both; -} - -.panel > .list-group { - margin-bottom: 0; -} - -.panel > .list-group .list-group-item { - border-width: 1px 0; -} - -.panel > .list-group .list-group-item:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.panel > .list-group .list-group-item:last-child { - border-bottom: 0; -} - -.panel-heading + .list-group .list-group-item:first-child { - border-top-width: 0; -} - -.panel > .table { - margin-bottom: 0; -} - -.panel > .panel-body + .table { - border-top: 1px solid #dddddd; -} - -.panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} - -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: 16px; -} - -.panel-title > a { - color: inherit; -} - -.panel-footer { - padding: 10px 15px; - background-color: #f5f5f5; - border-top: 1px solid #dddddd; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} - -.panel-group .panel { - margin-bottom: 0; - overflow: hidden; - border-radius: 4px; -} - -.panel-group .panel + .panel { - margin-top: 5px; -} - -.panel-group .panel-heading { - border-bottom: 0; -} - -.panel-group .panel-heading + .panel-collapse .panel-body { - border-top: 1px solid #dddddd; -} - -.panel-group .panel-footer { - border-top: 0; -} - -.panel-group .panel-footer + .panel-collapse .panel-body { - border-bottom: 1px solid #dddddd; -} - -.panel-default { - border-color: #dddddd; -} - -.panel-default > .panel-heading { - color: #333333; - background-color: #f5f5f5; - border-color: #dddddd; -} - -.panel-default > .panel-heading + .panel-collapse .panel-body { - border-top-color: #dddddd; -} - -.panel-default > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #dddddd; -} - -.panel-primary { - border-color: #428bca; -} - -.panel-primary > .panel-heading { - color: #ffffff; - background-color: #428bca; - border-color: #428bca; -} - -.panel-primary > .panel-heading + .panel-collapse .panel-body { - border-top-color: #428bca; -} - -.panel-primary > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #428bca; -} - -.panel-success { - border-color: #d6e9c6; -} - -.panel-success > .panel-heading { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.panel-success > .panel-heading + .panel-collapse .panel-body { - border-top-color: #d6e9c6; -} - -.panel-success > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #d6e9c6; -} - -.panel-warning { - border-color: #fbeed5; -} - -.panel-warning > .panel-heading { - color: #c09853; - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.panel-warning > .panel-heading + .panel-collapse .panel-body { - border-top-color: #fbeed5; -} - -.panel-warning > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #fbeed5; -} - -.panel-danger { - border-color: #eed3d7; -} - -.panel-danger > .panel-heading { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.panel-danger > .panel-heading + .panel-collapse .panel-body { - border-top-color: #eed3d7; -} - -.panel-danger > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #eed3d7; -} - -.panel-info { - border-color: #bce8f1; -} - -.panel-info > .panel-heading { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.panel-info > .panel-heading + .panel-collapse .panel-body { - border-top-color: #bce8f1; -} - -.panel-info > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #bce8f1; -} - -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #e3e3e3; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} - -.well-lg { - padding: 24px; - border-radius: 6px; -} - -.well-sm { - padding: 9px; - border-radius: 3px; -} - -.close { - float: right; - font-size: 21px; - font-weight: bold; - line-height: 1; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} - -.close:hover, -.close:focus { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.5; - filter: alpha(opacity=50); -} - -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} - -.modal-open { - overflow: hidden; -} - -body.modal-open, -.modal-open .navbar-fixed-top, -.modal-open .navbar-fixed-bottom { - margin-right: 15px; -} - -.modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - display: none; - overflow: auto; - overflow-y: scroll; -} - -.modal.fade .modal-dialog { - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -moz-transition: -moz-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; -} - -.modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - transform: translate(0, 0); -} - -.modal-dialog { - z-index: 1050; - width: auto; - padding: 10px; - margin-right: auto; - margin-left: auto; -} - -.modal-content { - position: relative; - background-color: #ffffff; - border: 1px solid #999999; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - outline: none; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - background-clip: padding-box; -} - -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1030; - background-color: #000000; -} - -.modal-backdrop.fade { - opacity: 0; - filter: alpha(opacity=0); -} - -.modal-backdrop.in { - opacity: 0.5; - filter: alpha(opacity=50); -} - -.modal-header { - min-height: 16.428571429px; - padding: 15px; - border-bottom: 1px solid #e5e5e5; -} - -.modal-header .close { - margin-top: -2px; -} - -.modal-title { - margin: 0; - line-height: 1.428571429; -} - -.modal-body { - position: relative; - padding: 20px; -} - -.modal-footer { - padding: 19px 20px 20px; - margin-top: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - content: " "; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - content: " "; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer .btn + .btn { - margin-bottom: 0; - margin-left: 5px; -} - -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} - -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} - -@media screen and (min-width: 768px) { - .modal-dialog { - right: auto; - left: 50%; - width: 600px; - padding-top: 30px; - padding-bottom: 30px; - } - .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - } -} - -.tooltip { - position: absolute; - z-index: 1030; - display: block; - font-size: 12px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); - visibility: visible; -} - -.tooltip.in { - opacity: 0.9; - filter: alpha(opacity=90); -} - -.tooltip.top { - padding: 5px 0; - margin-top: -3px; -} - -.tooltip.right { - padding: 0 5px; - margin-left: 3px; -} - -.tooltip.bottom { - padding: 5px 0; - margin-top: 3px; -} - -.tooltip.left { - padding: 0 5px; - margin-left: -3px; -} - -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - border-radius: 4px; -} - -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.top-left .tooltip-arrow { - bottom: 0; - left: 5px; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.top-right .tooltip-arrow { - right: 5px; - bottom: 0; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-right-color: #000000; - border-width: 5px 5px 5px 0; -} - -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-left-color: #000000; - border-width: 5px 0 5px 5px; -} - -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.tooltip.bottom-left .tooltip-arrow { - top: 0; - left: 5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.tooltip.bottom-right .tooltip-arrow { - top: 0; - right: 5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1010; - display: none; - max-width: 276px; - padding: 1px; - text-align: left; - white-space: normal; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - background-clip: padding-box; -} - -.popover.top { - margin-top: -10px; -} - -.popover.right { - margin-left: 10px; -} - -.popover.bottom { - margin-top: 10px; -} - -.popover.left { - margin-left: -10px; -} - -.popover-title { - padding: 8px 14px; - margin: 0; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-radius: 5px 5px 0 0; -} - -.popover-content { - padding: 9px 14px; -} - -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.popover .arrow { - border-width: 11px; -} - -.popover .arrow:after { - border-width: 10px; - content: ""; -} - -.popover.top .arrow { - bottom: -11px; - left: 50%; - margin-left: -11px; - border-top-color: #999999; - border-top-color: rgba(0, 0, 0, 0.25); - border-bottom-width: 0; -} - -.popover.top .arrow:after { - bottom: 1px; - margin-left: -10px; - border-top-color: #ffffff; - border-bottom-width: 0; - content: " "; -} - -.popover.right .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-right-color: #999999; - border-right-color: rgba(0, 0, 0, 0.25); - border-left-width: 0; -} - -.popover.right .arrow:after { - bottom: -10px; - left: 1px; - border-right-color: #ffffff; - border-left-width: 0; - content: " "; -} - -.popover.bottom .arrow { - top: -11px; - left: 50%; - margin-left: -11px; - border-bottom-color: #999999; - border-bottom-color: rgba(0, 0, 0, 0.25); - border-top-width: 0; -} - -.popover.bottom .arrow:after { - top: 1px; - margin-left: -10px; - border-bottom-color: #ffffff; - border-top-width: 0; - content: " "; -} - -.popover.left .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-left-color: #999999; - border-left-color: rgba(0, 0, 0, 0.25); - border-right-width: 0; -} - -.popover.left .arrow:after { - right: 1px; - bottom: -10px; - border-left-color: #ffffff; - border-right-width: 0; - content: " "; -} - -.carousel { - position: relative; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; -} - -.carousel-inner > .item { - position: relative; - display: none; - -webkit-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} - -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - height: auto; - max-width: 100%; - line-height: 1; -} - -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} - -.carousel-inner > .active { - left: 0; -} - -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} - -.carousel-inner > .next { - left: 100%; -} - -.carousel-inner > .prev { - left: -100%; -} - -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} - -.carousel-inner > .active.left { - left: -100%; -} - -.carousel-inner > .active.right { - left: 100%; -} - -.carousel-control { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 15%; - font-size: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); - opacity: 0.5; - filter: alpha(opacity=50); -} - -.carousel-control.left { - background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); - background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%)); - background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); -} - -.carousel-control.right { - right: 0; - left: auto; - background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); - background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%)); - background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); -} - -.carousel-control:hover, -.carousel-control:focus { - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} - -.carousel-control .icon-prev, -.carousel-control .icon-next, -.carousel-control .glyphicon-chevron-left, -.carousel-control .glyphicon-chevron-right { - position: absolute; - top: 50%; - left: 50%; - z-index: 5; - display: inline-block; -} - -.carousel-control .icon-prev, -.carousel-control .icon-next { - width: 20px; - height: 20px; - margin-top: -10px; - margin-left: -10px; - font-family: serif; -} - -.carousel-control .icon-prev:before { - content: '\2039'; -} - -.carousel-control .icon-next:before { - content: '\203a'; -} - -.carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - padding-left: 0; - margin-left: -30%; - text-align: center; - list-style: none; -} - -.carousel-indicators li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - cursor: pointer; - border: 1px solid #ffffff; - border-radius: 10px; -} - -.carousel-indicators .active { - width: 12px; - height: 12px; - margin: 0; - background-color: #ffffff; -} - -.carousel-caption { - position: absolute; - right: 15%; - bottom: 20px; - left: 15%; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); -} - -.carousel-caption .btn { - text-shadow: none; -} - -@media screen and (min-width: 768px) { - .carousel-control .icon-prev, - .carousel-control .icon-next { - width: 30px; - height: 30px; - margin-top: -15px; - margin-left: -15px; - font-size: 30px; - } - .carousel-caption { - right: 20%; - left: 20%; - padding-bottom: 30px; - } - .carousel-indicators { - bottom: 20px; - } -} - -.clearfix:before, -.clearfix:after { - display: table; - content: " "; -} - -.clearfix:after { - clear: both; -} - -.pull-right { - float: right !important; -} - -.pull-left { - float: left !important; -} - -.hide { - display: none !important; -} - -.show { - display: block !important; -} - -.invisible { - visibility: hidden; -} - -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.affix { - position: fixed; -} - -@-ms-viewport { - width: device-width; -} - -@media screen and (max-width: 400px) { - @-ms-viewport { - width: 320px; - } -} - -.hidden { - display: none !important; - visibility: hidden !important; -} - -.visible-xs { - display: none !important; -} - -tr.visible-xs { - display: none !important; -} - -th.visible-xs, -td.visible-xs { - display: none !important; -} - -@media (max-width: 767px) { - .visible-xs { - display: block !important; - } - tr.visible-xs { - display: table-row !important; - } - th.visible-xs, - td.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-xs.visible-sm { - display: block !important; - } - tr.visible-xs.visible-sm { - display: table-row !important; - } - th.visible-xs.visible-sm, - td.visible-xs.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-xs.visible-md { - display: block !important; - } - tr.visible-xs.visible-md { - display: table-row !important; - } - th.visible-xs.visible-md, - td.visible-xs.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-xs.visible-lg { - display: block !important; - } - tr.visible-xs.visible-lg { - display: table-row !important; - } - th.visible-xs.visible-lg, - td.visible-xs.visible-lg { - display: table-cell !important; - } -} - -.visible-sm { - display: none !important; -} - -tr.visible-sm { - display: none !important; -} - -th.visible-sm, -td.visible-sm { - display: none !important; -} - -@media (max-width: 767px) { - .visible-sm.visible-xs { - display: block !important; - } - tr.visible-sm.visible-xs { - display: table-row !important; - } - th.visible-sm.visible-xs, - td.visible-sm.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm { - display: block !important; - } - tr.visible-sm { - display: table-row !important; - } - th.visible-sm, - td.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-sm.visible-md { - display: block !important; - } - tr.visible-sm.visible-md { - display: table-row !important; - } - th.visible-sm.visible-md, - td.visible-sm.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-sm.visible-lg { - display: block !important; - } - tr.visible-sm.visible-lg { - display: table-row !important; - } - th.visible-sm.visible-lg, - td.visible-sm.visible-lg { - display: table-cell !important; - } -} - -.visible-md { - display: none !important; -} - -tr.visible-md { - display: none !important; -} - -th.visible-md, -td.visible-md { - display: none !important; -} - -@media (max-width: 767px) { - .visible-md.visible-xs { - display: block !important; - } - tr.visible-md.visible-xs { - display: table-row !important; - } - th.visible-md.visible-xs, - td.visible-md.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-md.visible-sm { - display: block !important; - } - tr.visible-md.visible-sm { - display: table-row !important; - } - th.visible-md.visible-sm, - td.visible-md.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md { - display: block !important; - } - tr.visible-md { - display: table-row !important; - } - th.visible-md, - td.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-md.visible-lg { - display: block !important; - } - tr.visible-md.visible-lg { - display: table-row !important; - } - th.visible-md.visible-lg, - td.visible-md.visible-lg { - display: table-cell !important; - } -} - -.visible-lg { - display: none !important; -} - -tr.visible-lg { - display: none !important; -} - -th.visible-lg, -td.visible-lg { - display: none !important; -} - -@media (max-width: 767px) { - .visible-lg.visible-xs { - display: block !important; - } - tr.visible-lg.visible-xs { - display: table-row !important; - } - th.visible-lg.visible-xs, - td.visible-lg.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-lg.visible-sm { - display: block !important; - } - tr.visible-lg.visible-sm { - display: table-row !important; - } - th.visible-lg.visible-sm, - td.visible-lg.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-lg.visible-md { - display: block !important; - } - tr.visible-lg.visible-md { - display: table-row !important; - } - th.visible-lg.visible-md, - td.visible-lg.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-lg { - display: block !important; - } - tr.visible-lg { - display: table-row !important; - } - th.visible-lg, - td.visible-lg { - display: table-cell !important; - } -} - -.hidden-xs { - display: block !important; -} - -tr.hidden-xs { - display: table-row !important; -} - -th.hidden-xs, -td.hidden-xs { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-xs { - display: none !important; - } - tr.hidden-xs { - display: none !important; - } - th.hidden-xs, - td.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-xs.hidden-sm { - display: none !important; - } - tr.hidden-xs.hidden-sm { - display: none !important; - } - th.hidden-xs.hidden-sm, - td.hidden-xs.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-xs.hidden-md { - display: none !important; - } - tr.hidden-xs.hidden-md { - display: none !important; - } - th.hidden-xs.hidden-md, - td.hidden-xs.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-xs.hidden-lg { - display: none !important; - } - tr.hidden-xs.hidden-lg { - display: none !important; - } - th.hidden-xs.hidden-lg, - td.hidden-xs.hidden-lg { - display: none !important; - } -} - -.hidden-sm { - display: block !important; -} - -tr.hidden-sm { - display: table-row !important; -} - -th.hidden-sm, -td.hidden-sm { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-sm.hidden-xs { - display: none !important; - } - tr.hidden-sm.hidden-xs { - display: none !important; - } - th.hidden-sm.hidden-xs, - td.hidden-sm.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-sm { - display: none !important; - } - tr.hidden-sm { - display: none !important; - } - th.hidden-sm, - td.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-sm.hidden-md { - display: none !important; - } - tr.hidden-sm.hidden-md { - display: none !important; - } - th.hidden-sm.hidden-md, - td.hidden-sm.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-sm.hidden-lg { - display: none !important; - } - tr.hidden-sm.hidden-lg { - display: none !important; - } - th.hidden-sm.hidden-lg, - td.hidden-sm.hidden-lg { - display: none !important; - } -} - -.hidden-md { - display: block !important; -} - -tr.hidden-md { - display: table-row !important; -} - -th.hidden-md, -td.hidden-md { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-md.hidden-xs { - display: none !important; - } - tr.hidden-md.hidden-xs { - display: none !important; - } - th.hidden-md.hidden-xs, - td.hidden-md.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-md.hidden-sm { - display: none !important; - } - tr.hidden-md.hidden-sm { - display: none !important; - } - th.hidden-md.hidden-sm, - td.hidden-md.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-md { - display: none !important; - } - tr.hidden-md { - display: none !important; - } - th.hidden-md, - td.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-md.hidden-lg { - display: none !important; - } - tr.hidden-md.hidden-lg { - display: none !important; - } - th.hidden-md.hidden-lg, - td.hidden-md.hidden-lg { - display: none !important; - } -} - -.hidden-lg { - display: block !important; -} - -tr.hidden-lg { - display: table-row !important; -} - -th.hidden-lg, -td.hidden-lg { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-lg.hidden-xs { - display: none !important; - } - tr.hidden-lg.hidden-xs { - display: none !important; - } - th.hidden-lg.hidden-xs, - td.hidden-lg.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-lg.hidden-sm { - display: none !important; - } - tr.hidden-lg.hidden-sm { - display: none !important; - } - th.hidden-lg.hidden-sm, - td.hidden-lg.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-lg.hidden-md { - display: none !important; - } - tr.hidden-lg.hidden-md { - display: none !important; - } - th.hidden-lg.hidden-md, - td.hidden-lg.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-lg { - display: none !important; - } - tr.hidden-lg { - display: none !important; - } - th.hidden-lg, - td.hidden-lg { - display: none !important; - } -} - -.visible-print { - display: none !important; -} - -tr.visible-print { - display: none !important; -} - -th.visible-print, -td.visible-print { - display: none !important; -} - -@media print { - .visible-print { - display: block !important; - } - tr.visible-print { - display: table-row !important; - } - th.visible-print, - td.visible-print { - display: table-cell !important; - } - .hidden-print { - display: none !important; - } - tr.hidden-print { - display: none !important; - } - th.hidden-print, - td.hidden-print { - display: none !important; - } -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Content/bootstrap.min.css b/Fitbit.Portable.DebugSite/Content/bootstrap.min.css deleted file mode 100644 index a553c4f5..00000000 --- a/Fitbit.Portable.DebugSite/Content/bootstrap.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Bootstrap v3.0.0 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world by @mdo and @fat. - *//*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:2cm .5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}button,input,select[multiple],textarea{background-image:none}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16.099999999999998px;font-weight:200;line-height:1.4}@media(min-width:768px){.lead{font-size:21px}}small{font-size:85%}cite{font-style:normal}.text-muted{color:#999}.text-primary{color:#428bca}.text-warning{color:#c09853}.text-danger{color:#b94a48}.text-success{color:#468847}.text-info{color:#3a87ad}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{margin-top:20px;margin-bottom:10px}h4,h5,h6{margin-top:10px;margin-bottom:10px}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}h1 small,.h1 small{font-size:24px}h2 small,.h2 small{font-size:18px}h3 small,.h3 small,h4 small,.h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small{display:block;line-height:1.428571429;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:1.428571429}code,pre{font-family:Monaco,Menlo,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11{float:left}.col-xs-1{width:8.333333333333332%}.col-xs-2{width:16.666666666666664%}.col-xs-3{width:25%}.col-xs-4{width:33.33333333333333%}.col-xs-5{width:41.66666666666667%}.col-xs-6{width:50%}.col-xs-7{width:58.333333333333336%}.col-xs-8{width:66.66666666666666%}.col-xs-9{width:75%}.col-xs-10{width:83.33333333333334%}.col-xs-11{width:91.66666666666666%}.col-xs-12{width:100%}@media(min-width:768px){.container{max-width:750px}.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11{float:left}.col-sm-1{width:8.333333333333332%}.col-sm-2{width:16.666666666666664%}.col-sm-3{width:25%}.col-sm-4{width:33.33333333333333%}.col-sm-5{width:41.66666666666667%}.col-sm-6{width:50%}.col-sm-7{width:58.333333333333336%}.col-sm-8{width:66.66666666666666%}.col-sm-9{width:75%}.col-sm-10{width:83.33333333333334%}.col-sm-11{width:91.66666666666666%}.col-sm-12{width:100%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-3{left:25%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-6{left:50%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-9{left:75%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-11{left:91.66666666666666%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-3{right:25%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-6{right:50%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-9{right:75%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-11{margin-left:91.66666666666666%}}@media(min-width:992px){.container{max-width:970px}.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11{float:left}.col-md-1{width:8.333333333333332%}.col-md-2{width:16.666666666666664%}.col-md-3{width:25%}.col-md-4{width:33.33333333333333%}.col-md-5{width:41.66666666666667%}.col-md-6{width:50%}.col-md-7{width:58.333333333333336%}.col-md-8{width:66.66666666666666%}.col-md-9{width:75%}.col-md-10{width:83.33333333333334%}.col-md-11{width:91.66666666666666%}.col-md-12{width:100%}.col-md-push-0{left:auto}.col-md-push-1{left:8.333333333333332%}.col-md-push-2{left:16.666666666666664%}.col-md-push-3{left:25%}.col-md-push-4{left:33.33333333333333%}.col-md-push-5{left:41.66666666666667%}.col-md-push-6{left:50%}.col-md-push-7{left:58.333333333333336%}.col-md-push-8{left:66.66666666666666%}.col-md-push-9{left:75%}.col-md-push-10{left:83.33333333333334%}.col-md-push-11{left:91.66666666666666%}.col-md-pull-0{right:auto}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-3{right:25%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-6{right:50%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-9{right:75%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-11{right:91.66666666666666%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-11{margin-left:91.66666666666666%}}@media(min-width:1200px){.container{max-width:1170px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11{float:left}.col-lg-1{width:8.333333333333332%}.col-lg-2{width:16.666666666666664%}.col-lg-3{width:25%}.col-lg-4{width:33.33333333333333%}.col-lg-5{width:41.66666666666667%}.col-lg-6{width:50%}.col-lg-7{width:58.333333333333336%}.col-lg-8{width:66.66666666666666%}.col-lg-9{width:75%}.col-lg-10{width:83.33333333333334%}.col-lg-11{width:91.66666666666666%}.col-lg-12{width:100%}.col-lg-push-0{left:auto}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-3{left:25%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-6{left:50%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-9{left:75%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-11{left:91.66666666666666%}.col-lg-pull-0{right:auto}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-3{right:25%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-6{right:50%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-9{right:75%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-11{margin-left:91.66666666666666%}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table thead>tr>th,.table tbody>tr>th,.table tfoot>tr>th,.table thead>tr>td,.table tbody>tr>td,.table tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table caption+thead tr:first-child th,.table colgroup+thead tr:first-child th,.table thead:first-child tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed thead>tr>th,.table-condensed tbody>tr>th,.table-condensed tfoot>tr>th,.table-condensed thead>tr>td,.table-condensed tbody>tr>td,.table-condensed tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8;border-color:#d6e9c6}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td{background-color:#d0e9c6;border-color:#c9e2b3}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede;border-color:#eed3d7}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td{background-color:#ebcccc;border-color:#e6c1c7}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3;border-color:#fbeed5}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td{background-color:#faf2cc;border-color:#f8e5be}@media(max-width:768px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0;background-color:#fff}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>thead>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>thead>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm{height:auto}.input-lg{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:45px;line-height:45px}textarea.input-lg{height:auto}.has-warning .help-block,.has-warning .control-label{color:#c09853}.has-warning .form-control{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.has-warning .input-group-addon{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.has-error .help-block,.has-error .control-label{color:#b94a48}.has-error .form-control{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.has-error .input-group-addon{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.has-success .help-block,.has-success .control-label{color:#468847}.has-success .form-control{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.has-success .input-group-addon{color:#468847;background-color:#dff0d8;border-color:#468847}.form-control-static{padding-top:7px;margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-link{font-weight:normal;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-print:before{content:"\e045"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-briefcase:before{content:"\1f4bc"}.glyphicon-calendar:before{content:"\1f4c5"}.glyphicon-pushpin:before{content:"\1f4cc"}.glyphicon-paperclip:before{content:"\1f4ce"}.glyphicon-camera:before{content:"\1f4f7"}.glyphicon-lock:before{content:"\1f512"}.glyphicon-bell:before{content:"\1f514"}.glyphicon-bookmark:before{content:"\1f516"}.glyphicon-fire:before{content:"\1f525"}.glyphicon-wrench:before{content:"\1f527"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0 dotted;border-left:4px solid transparent;content:""}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#fff;text-decoration:none;background-color:#428bca}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0 dotted;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.btn-default .caret{border-top-color:#333}.btn-primary .caret,.btn-success .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret{border-top-color:#fff}.dropup .btn-default .caret{border-bottom-color:#333}.dropup .btn-primary .caret,.dropup .btn-success .caret,.dropup .btn-warning .caret,.dropup .btn-danger .caret,.dropup .btn-info .caret{border-bottom-color:#fff}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:5px 10px;padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified .btn{display:table-cell;float:none;width:1%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group.col{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:45px;line-height:45px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}}.nav-tabs.nav-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs.nav-justified>.active>a{border-bottom-color:#fff}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:5px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs-justified>.active>a{border-bottom-color:#fff}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.nav .caret{border-top-color:#428bca;border-bottom-color:#428bca}.nav a:hover .caret{border-top-color:#2a6496;border-bottom-color:#2a6496}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;z-index:1000;min-height:50px;margin-bottom:20px;border:1px solid transparent}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:4px}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-collapse .navbar-nav.navbar-left:first-child{margin-left:-15px}.navbar-collapse .navbar-nav.navbar-right:last-child{margin-right:-15px}.navbar-collapse .navbar-text:last-child{margin-right:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;border-width:0 0 1px}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;z-index:1030}.navbar-fixed-bottom{bottom:0;margin-bottom:0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;border:1px solid transparent;border-radius:4px}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}@media(min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-text{float:left;margin-top:15px;margin-bottom:15px}@media(min-width:768px){.navbar-text{margin-right:15px;margin-left:15px}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e6e6e6}.navbar-default .navbar-nav>.dropdown>a:hover .caret,.navbar-default .navbar-nav>.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.open>a .caret,.navbar-default .navbar-nav>.open>a:hover .caret,.navbar-default .navbar-nav>.open>a:focus .caret{border-top-color:#555;border-bottom-color:#555}.navbar-default .navbar-nav>.dropdown>a .caret{border-top-color:#777;border-bottom-color:#777}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-nav>.dropdown>a .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .navbar-nav>.open>a .caret,.navbar-inverse .navbar-nav>.open>a:hover .caret,.navbar-inverse .navbar-nav>.open>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.badge:empty{display:none}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.btn .badge{position:relative;top:-1px}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.jumbotron h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.thumbnail{display:inline-block;display:block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img{display:block;height:auto;max-width:100%}a.thumbnail:hover,a.thumbnail:focus{border-color:#428bca}.thumbnail>img{margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#356635}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#2d6987}.alert-warning{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.alert-warning hr{border-top-color:#f8e5be}.alert-warning .alert-link{color:#a47e3c}.alert-danger{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger hr{border-top-color:#e6c1c7}.alert-danger .alert-link{color:#953b39}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table{margin-bottom:0}.panel>.panel-body+.table{border-top:1px solid #ddd}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-title{margin-top:0;margin-bottom:0;font-size:16px}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-warning{border-color:#fbeed5}.panel-warning>.panel-heading{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#fbeed5}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#fbeed5}.panel-danger{border-color:#eed3d7}.panel-danger>.panel-heading{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#eed3d7}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#eed3d7}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}body.modal-open,.modal-open .navbar-fixed-top,.modal-open .navbar-fixed-bottom{margin-right:15px}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{z-index:1050;width:auto;padding:10px;margin-right:auto;margin-left:auto}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.modal-dialog{right:auto;left:50%;width:600px;padding-top:30px;padding-bottom:30px}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.carousel-control.left{background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.5)),to(rgba(0,0,0,0.0001)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.5) 0),color-stop(rgba(0,0,0,0.0001) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.0001)),to(rgba(0,0,0,0.5)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.0001) 0),color-stop(rgba(0,0,0,0.5) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1)}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;left:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.affix{position:fixed}@-ms-viewport{width:device-width}@media screen and (max-width:400px){@-ms-viewport{width:320px}}.hidden{display:none!important;visibility:hidden!important}.visible-xs{display:none!important}tr.visible-xs{display:none!important}th.visible-xs,td.visible-xs{display:none!important}@media(max-width:767px){.visible-xs{display:block!important}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}tr.visible-xs.visible-sm{display:table-row!important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}tr.visible-xs.visible-md{display:table-row!important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block!important}tr.visible-xs.visible-lg{display:table-row!important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell!important}}.visible-sm{display:none!important}tr.visible-sm{display:none!important}th.visible-sm,td.visible-sm{display:none!important}@media(max-width:767px){.visible-sm.visible-xs{display:block!important}tr.visible-sm.visible-xs{display:table-row!important}th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block!important}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}tr.visible-sm.visible-md{display:table-row!important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block!important}tr.visible-sm.visible-lg{display:table-row!important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell!important}}.visible-md{display:none!important}tr.visible-md{display:none!important}th.visible-md,td.visible-md{display:none!important}@media(max-width:767px){.visible-md.visible-xs{display:block!important}tr.visible-md.visible-xs{display:table-row!important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}tr.visible-md.visible-sm{display:table-row!important}th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block!important}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-md.visible-lg{display:block!important}tr.visible-md.visible-lg{display:table-row!important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell!important}}.visible-lg{display:none!important}tr.visible-lg{display:none!important}th.visible-lg,td.visible-lg{display:none!important}@media(max-width:767px){.visible-lg.visible-xs{display:block!important}tr.visible-lg.visible-xs{display:table-row!important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}tr.visible-lg.visible-sm{display:table-row!important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}tr.visible-lg.visible-md{display:table-row!important}th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-lg{display:block!important}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}.hidden-xs{display:block!important}tr.hidden-xs{display:table-row!important}th.hidden-xs,td.hidden-xs{display:table-cell!important}@media(max-width:767px){.hidden-xs{display:none!important}tr.hidden-xs{display:none!important}th.hidden-xs,td.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm{display:none!important}tr.hidden-xs.hidden-sm{display:none!important}th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md{display:none!important}tr.hidden-xs.hidden-md{display:none!important}th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-xs.hidden-lg{display:none!important}tr.hidden-xs.hidden-lg{display:none!important}th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none!important}}.hidden-sm{display:block!important}tr.hidden-sm{display:table-row!important}th.hidden-sm,td.hidden-sm{display:table-cell!important}@media(max-width:767px){.hidden-sm.hidden-xs{display:none!important}tr.hidden-sm.hidden-xs{display:none!important}th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}tr.hidden-sm{display:none!important}th.hidden-sm,td.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md{display:none!important}tr.hidden-sm.hidden-md{display:none!important}th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-sm.hidden-lg{display:none!important}tr.hidden-sm.hidden-lg{display:none!important}th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none!important}}.hidden-md{display:block!important}tr.hidden-md{display:table-row!important}th.hidden-md,td.hidden-md{display:table-cell!important}@media(max-width:767px){.hidden-md.hidden-xs{display:none!important}tr.hidden-md.hidden-xs{display:none!important}th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm{display:none!important}tr.hidden-md.hidden-sm{display:none!important}th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}tr.hidden-md{display:none!important}th.hidden-md,td.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-md.hidden-lg{display:none!important}tr.hidden-md.hidden-lg{display:none!important}th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none!important}}.hidden-lg{display:block!important}tr.hidden-lg{display:table-row!important}th.hidden-lg,td.hidden-lg{display:table-cell!important}@media(max-width:767px){.hidden-lg.hidden-xs{display:none!important}tr.hidden-lg.hidden-xs{display:none!important}th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm{display:none!important}tr.hidden-lg.hidden-sm{display:none!important}th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md{display:none!important}tr.hidden-lg.hidden-md{display:none!important}th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-lg{display:none!important}tr.hidden-lg{display:none!important}th.hidden-lg,td.hidden-lg{display:none!important}}.visible-print{display:none!important}tr.visible-print{display:none!important}th.visible-print,td.visible-print{display:none!important}@media print{.visible-print{display:block!important}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}.hidden-print{display:none!important}tr.hidden-print{display:none!important}th.hidden-print,td.hidden-print{display:none!important}} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Controllers/AccountController.cs b/Fitbit.Portable.DebugSite/Controllers/AccountController.cs deleted file mode 100644 index 01096b01..00000000 --- a/Fitbit.Portable.DebugSite/Controllers/AccountController.cs +++ /dev/null @@ -1,485 +0,0 @@ -using System; -using System.Globalization; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using System.Web; -using System.Web.Mvc; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin.Security; -using SampleWebMVCOAuth2.Models; - -namespace SampleWebMVCOAuth2.Controllers -{ - [Authorize] - public class AccountController : Controller - { - private ApplicationSignInManager _signInManager; - private ApplicationUserManager _userManager; - - public AccountController() - { - } - - public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager ) - { - UserManager = userManager; - SignInManager = signInManager; - } - - public ApplicationSignInManager SignInManager - { - get - { - return _signInManager ?? HttpContext.GetOwinContext().Get(); - } - private set - { - _signInManager = value; - } - } - - public ApplicationUserManager UserManager - { - get - { - return _userManager ?? HttpContext.GetOwinContext().GetUserManager(); - } - private set - { - _userManager = value; - } - } - - // - // GET: /Account/Login - [AllowAnonymous] - public ActionResult Login(string returnUrl) - { - ViewBag.ReturnUrl = returnUrl; - return View(); - } - - // - // POST: /Account/Login - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task Login(LoginViewModel model, string returnUrl) - { - if (!ModelState.IsValid) - { - return View(model); - } - - // This doesn't count login failures towards account lockout - // To enable password failures to trigger account lockout, change to shouldLockout: true - var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); - switch (result) - { - case SignInStatus.Success: - return RedirectToLocal(returnUrl); - case SignInStatus.LockedOut: - return View("Lockout"); - case SignInStatus.RequiresVerification: - return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); - case SignInStatus.Failure: - default: - ModelState.AddModelError("", "Invalid login attempt."); - return View(model); - } - } - - // - // GET: /Account/VerifyCode - [AllowAnonymous] - public async Task VerifyCode(string provider, string returnUrl, bool rememberMe) - { - // Require that the user has already logged in via username/password or external login - if (!await SignInManager.HasBeenVerifiedAsync()) - { - return View("Error"); - } - return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe }); - } - - // - // POST: /Account/VerifyCode - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task VerifyCode(VerifyCodeViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - - // The following code protects for brute force attacks against the two factor codes. - // If a user enters incorrect codes for a specified amount of time then the user account - // will be locked out for a specified amount of time. - // You can configure the account lockout settings in IdentityConfig - var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser); - switch (result) - { - case SignInStatus.Success: - return RedirectToLocal(model.ReturnUrl); - case SignInStatus.LockedOut: - return View("Lockout"); - case SignInStatus.Failure: - default: - ModelState.AddModelError("", "Invalid code."); - return View(model); - } - } - - // - // GET: /Account/Register - [AllowAnonymous] - public ActionResult Register() - { - return View(); - } - - // - // POST: /Account/Register - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task Register(RegisterViewModel model) - { - if (ModelState.IsValid) - { - var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; - var result = await UserManager.CreateAsync(user, model.Password); - if (result.Succeeded) - { - await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false); - - // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 - // Send an email with this link - // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); - // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); - // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking here"); - - return RedirectToAction("Index", "Home"); - } - AddErrors(result); - } - - // If we got this far, something failed, redisplay form - return View(model); - } - - // - // GET: /Account/ConfirmEmail - [AllowAnonymous] - public async Task ConfirmEmail(string userId, string code) - { - if (userId == null || code == null) - { - return View("Error"); - } - var result = await UserManager.ConfirmEmailAsync(userId, code); - return View(result.Succeeded ? "ConfirmEmail" : "Error"); - } - - // - // GET: /Account/ForgotPassword - [AllowAnonymous] - public ActionResult ForgotPassword() - { - return View(); - } - - // - // POST: /Account/ForgotPassword - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task ForgotPassword(ForgotPasswordViewModel model) - { - if (ModelState.IsValid) - { - var user = await UserManager.FindByNameAsync(model.Email); - if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id))) - { - // Don't reveal that the user does not exist or is not confirmed - return View("ForgotPasswordConfirmation"); - } - - // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 - // Send an email with this link - // string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); - // var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); - // await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking here"); - // return RedirectToAction("ForgotPasswordConfirmation", "Account"); - } - - // If we got this far, something failed, redisplay form - return View(model); - } - - // - // GET: /Account/ForgotPasswordConfirmation - [AllowAnonymous] - public ActionResult ForgotPasswordConfirmation() - { - return View(); - } - - // - // GET: /Account/ResetPassword - [AllowAnonymous] - public ActionResult ResetPassword(string code) - { - return code == null ? View("Error") : View(); - } - - // - // POST: /Account/ResetPassword - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task ResetPassword(ResetPasswordViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - var user = await UserManager.FindByNameAsync(model.Email); - if (user == null) - { - // Don't reveal that the user does not exist - return RedirectToAction("ResetPasswordConfirmation", "Account"); - } - var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password); - if (result.Succeeded) - { - return RedirectToAction("ResetPasswordConfirmation", "Account"); - } - AddErrors(result); - return View(); - } - - // - // GET: /Account/ResetPasswordConfirmation - [AllowAnonymous] - public ActionResult ResetPasswordConfirmation() - { - return View(); - } - - // - // POST: /Account/ExternalLogin - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public ActionResult ExternalLogin(string provider, string returnUrl) - { - // Request a redirect to the external login provider - return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl })); - } - - // - // GET: /Account/SendCode - [AllowAnonymous] - public async Task SendCode(string returnUrl, bool rememberMe) - { - var userId = await SignInManager.GetVerifiedUserIdAsync(); - if (userId == null) - { - return View("Error"); - } - var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(userId); - var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList(); - return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe }); - } - - // - // POST: /Account/SendCode - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task SendCode(SendCodeViewModel model) - { - if (!ModelState.IsValid) - { - return View(); - } - - // Generate the token and send it - if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider)) - { - return View("Error"); - } - return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe }); - } - - // - // GET: /Account/ExternalLoginCallback - [AllowAnonymous] - public async Task ExternalLoginCallback(string returnUrl) - { - var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); - if (loginInfo == null) - { - return RedirectToAction("Login"); - } - - // Sign in the user with this external login provider if the user already has a login - var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false); - switch (result) - { - case SignInStatus.Success: - return RedirectToLocal(returnUrl); - case SignInStatus.LockedOut: - return View("Lockout"); - case SignInStatus.RequiresVerification: - return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false }); - case SignInStatus.Failure: - default: - // If the user does not have an account, then prompt the user to create an account - ViewBag.ReturnUrl = returnUrl; - ViewBag.LoginProvider = loginInfo.Login.LoginProvider; - return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email }); - } - } - - // - // POST: /Account/ExternalLoginConfirmation - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) - { - if (User.Identity.IsAuthenticated) - { - return RedirectToAction("Index", "Manage"); - } - - if (ModelState.IsValid) - { - // Get the information about the user from the external login provider - var info = await AuthenticationManager.GetExternalLoginInfoAsync(); - if (info == null) - { - return View("ExternalLoginFailure"); - } - var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; - var result = await UserManager.CreateAsync(user); - if (result.Succeeded) - { - result = await UserManager.AddLoginAsync(user.Id, info.Login); - if (result.Succeeded) - { - await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); - return RedirectToLocal(returnUrl); - } - } - AddErrors(result); - } - - ViewBag.ReturnUrl = returnUrl; - return View(model); - } - - // - // POST: /Account/LogOff - [HttpPost] - [ValidateAntiForgeryToken] - public ActionResult LogOff() - { - AuthenticationManager.SignOut(); - return RedirectToAction("Index", "Home"); - } - - // - // GET: /Account/ExternalLoginFailure - [AllowAnonymous] - public ActionResult ExternalLoginFailure() - { - return View(); - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (_userManager != null) - { - _userManager.Dispose(); - _userManager = null; - } - - if (_signInManager != null) - { - _signInManager.Dispose(); - _signInManager = null; - } - } - - base.Dispose(disposing); - } - - #region Helpers - // Used for XSRF protection when adding external logins - private const string XsrfKey = "XsrfId"; - - private IAuthenticationManager AuthenticationManager - { - get - { - return HttpContext.GetOwinContext().Authentication; - } - } - - private void AddErrors(IdentityResult result) - { - foreach (var error in result.Errors) - { - ModelState.AddModelError("", error); - } - } - - private ActionResult RedirectToLocal(string returnUrl) - { - if (Url.IsLocalUrl(returnUrl)) - { - return Redirect(returnUrl); - } - return RedirectToAction("Index", "Home"); - } - - internal class ChallengeResult : HttpUnauthorizedResult - { - public ChallengeResult(string provider, string redirectUri) - : this(provider, redirectUri, null) - { - } - - public ChallengeResult(string provider, string redirectUri, string userId) - { - LoginProvider = provider; - RedirectUri = redirectUri; - UserId = userId; - } - - public string LoginProvider { get; set; } - public string RedirectUri { get; set; } - public string UserId { get; set; } - - public override void ExecuteResult(ControllerContext context) - { - var properties = new AuthenticationProperties { RedirectUri = RedirectUri }; - if (UserId != null) - { - properties.Dictionary[XsrfKey] = UserId; - } - context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); - } - } - #endregion - } -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Controllers/FitbitController.cs b/Fitbit.Portable.DebugSite/Controllers/FitbitController.cs deleted file mode 100644 index e79a159a..00000000 --- a/Fitbit.Portable.DebugSite/Controllers/FitbitController.cs +++ /dev/null @@ -1,241 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.Mvc; -using Fitbit.Api; -using System.Configuration; -using Fitbit.Models; -using Fitbit.Api.Portable; -using System.Threading.Tasks; -using Fitbit.Api.Portable.OAuth2; - -namespace SampleWebMVC.Controllers -{ - public class FitbitController : Controller - { - // - // GET: /Fitbit/ - - public ActionResult Index() - { - return RedirectToAction("Index", "Home"); - } - - // - // GET: /FitbitAuth/ - // Setup - prepare the user redirect to Fitbit.com to prompt them to authorize this app. - public ActionResult Authorize() - { - var appCredentials = new FitbitAppCredentials() { - ClientId = ConfigurationManager.AppSettings["FitbitClientId"], - ClientSecret = ConfigurationManager.AppSettings["FitbitClientSecret"] - }; - //make sure you've set these up in Web.Config under : - - Session["AppCredentials"] = appCredentials; - - //Provide the App Credentials. You get those by registering your app at dev.fitbit.com - //Configure Fitbit authenticaiton request to perform a callback to this constructor's Callback method - var authenticator = new OAuth2Helper(appCredentials, Request.Url.GetLeftPart(UriPartial.Authority) + "/Fitbit/Callback"); - string[] scopes = new string[] {"profile"}; - - string authUrl = authenticator.GenerateAuthUrl(scopes, null); - - return Redirect(authUrl); - } - - //Final step. Take this authorization information and use it in the app - public async Task Callback() - { - FitbitAppCredentials appCredentials = (FitbitAppCredentials)Session["AppCredentials"]; - - var authenticator = new OAuth2Helper(appCredentials, Request.Url.GetLeftPart(UriPartial.Authority) + "/Fitbit/Callback"); - - string code = Request.Params["code"]; - - OAuth2AccessToken accessToken = await authenticator.ExchangeAuthCodeForAccessTokenAsync(code); - - //Store credentials in FitbitClient. The client in its default implementation manages the Refresh process - var fitbitClient = GetFitbitClient(accessToken); - fitbitClient.AccessToken = accessToken; - - ViewBag.AccessToken = accessToken; - - return View(); - - } - - /// - /// In this example we show how to explicitly request a token refresh. However, FitbitClient V2 on its default implementation provide an OOB automatic token refresh. - /// - /// A refreshed token - public async Task RefreshToken() - { - var fitbitClient = GetFitbitClient(); - - ViewBag.AccessToken = await fitbitClient.RefreshOAuth2Token(); - - return View("Callback"); - } - - public async Task TestToken() - { - var fitbitClient = GetFitbitClient(); - - ViewBag.AccessToken = fitbitClient.AccessToken; - - ViewBag.UserProfile = await fitbitClient.GetUserProfileAsync(); - - return View("TestToken"); - } - - /* - public string TestTimeSeries() - { - FitbitClient client = GetFitbitClient(); - - var results = client.GetTimeSeries(TimeSeriesResourceType.DistanceTracker, DateTime.UtcNow.AddDays(-7), DateTime.UtcNow); - - string sOutput = ""; - foreach (var result in results.DataList) - { - sOutput += result.DateTime.ToString() + " - " + result.Value.ToString(); - } - - return sOutput; - - } - - public ActionResult LastWeekDistance() - { - FitbitClient client = GetFitbitClient(); - - TimeSeriesDataList results = client.GetTimeSeries(TimeSeriesResourceType.Distance, DateTime.UtcNow.AddDays(-7), DateTime.UtcNow); - - return View(results); - } - */ - - public async Task LastWeekSteps() - { - - FitbitClient client = GetFitbitClient(); - - var response = await client.GetTimeSeriesIntAsync(TimeSeriesResourceType.Steps, DateTime.UtcNow.AddDays(-7), DateTime.UtcNow); - - return View(response); - - } - /* - //example using the direct API call getting all the individual logs - public ActionResult MonthFat(string id) - { - DateTime dateStart = Convert.ToDateTime(id); - - FitbitClient client = GetFitbitClient(); - - Fat fat = client.GetFat(dateStart, DateRangePeriod.OneMonth); - - if (fat == null || fat.FatLogs == null) //succeeded but no records - { - fat = new Fat(); - fat.FatLogs = new List(); - } - return View(fat); - - } - - //example using the time series, one per day - public ActionResult LastYearFat() - { - FitbitClient client = GetFitbitClient(); - - TimeSeriesDataList fatSeries = client.GetTimeSeries(TimeSeriesResourceType.Fat, DateTime.UtcNow, DateRangePeriod.OneYear); - - return View(fatSeries); - - } - - //example using the direct API call getting all the individual logs - public ActionResult MonthWeight(string id) - { - DateTime dateStart = Convert.ToDateTime(id); - - FitbitClient client = GetFitbitClient(); - - Weight weight = client.GetWeight(dateStart, DateRangePeriod.OneMonth); - - if (weight == null || weight.Weights == null) //succeeded but no records - { - weight = new Weight(); - weight.Weights = new List(); - } - return View(weight); - - } - - //example using the time series, one per day - public ActionResult LastYearWeight() - { - FitbitClient client = GetFitbitClient(); - - TimeSeriesDataList weightSeries = client.GetTimeSeries(TimeSeriesResourceType.Weight, DateTime.UtcNow, DateRangePeriod.OneYear); - - return View(weightSeries); - - } - - /// - /// This requires the Fitbit staff approval of your app before it can be called - /// - /// - public string TestIntraDay() - { - FitbitClient client = new FitbitClient(ConfigurationManager.AppSettings["FitbitConsumerKey"], - ConfigurationManager.AppSettings["FitbitConsumerSecret"], - Session["FitbitAuthToken"].ToString(), - Session["FitbitAuthTokenSecret"].ToString()); - - IntradayData data = client.GetIntraDayTimeSeries(IntradayResourceType.Steps, new DateTime(2012, 5, 28, 11, 0, 0), new TimeSpan(1, 0, 0)); - - string result = ""; - - foreach (IntradayDataValues intraData in data.DataSet) - { - result += intraData.Time.ToShortTimeString() + " - " + intraData.Value + Environment.NewLine; - } - - return result; - - } - - */ - - /// - /// HttpClient and hence FitbitClient are designed to be long-lived for the duration of the session. This method ensures only one client is created for the duration of the session. - /// More info at: http://stackoverflow.com/questions/22560971/what-is-the-overhead-of-creating-a-new-httpclient-per-call-in-a-webapi-client - /// - /// - private FitbitClient GetFitbitClient(OAuth2AccessToken accessToken = null) - { - if (Session["FitbitClient"] == null) - { - if (accessToken != null) - { - var appCredentials = (FitbitAppCredentials)Session["AppCredentials"]; - FitbitClient client = new FitbitClient(appCredentials, accessToken); - Session["FitbitClient"] = client; - return client; - } - else - { - throw new Exception("First time requesting a FitbitClient from the session you must pass the AccessToken."); - } - - } - else - { - return (FitbitClient)Session["FitbitClient"]; - } - } - } -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Controllers/HomeController.cs b/Fitbit.Portable.DebugSite/Controllers/HomeController.cs deleted file mode 100644 index 4e97c38d..00000000 --- a/Fitbit.Portable.DebugSite/Controllers/HomeController.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Mvc; - -namespace SampleWebMVCOAuth2.Controllers -{ - public class HomeController : Controller - { - public ActionResult Index() - { - return View(); - } - - public ActionResult About() - { - ViewBag.Message = "Your application description page."; - - return View(); - } - - public ActionResult Contact() - { - ViewBag.Message = "Your contact page."; - - return View(); - } - } -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Controllers/ManageController.cs b/Fitbit.Portable.DebugSite/Controllers/ManageController.cs deleted file mode 100644 index f8178daa..00000000 --- a/Fitbit.Portable.DebugSite/Controllers/ManageController.cs +++ /dev/null @@ -1,387 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using System.Web; -using System.Web.Mvc; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin.Security; -using SampleWebMVCOAuth2.Models; - -namespace SampleWebMVCOAuth2.Controllers -{ - [Authorize] - public class ManageController : Controller - { - private ApplicationSignInManager _signInManager; - private ApplicationUserManager _userManager; - - public ManageController() - { - } - - public ManageController(ApplicationUserManager userManager, ApplicationSignInManager signInManager) - { - UserManager = userManager; - SignInManager = signInManager; - } - - public ApplicationSignInManager SignInManager - { - get - { - return _signInManager ?? HttpContext.GetOwinContext().Get(); - } - private set - { - _signInManager = value; - } - } - - public ApplicationUserManager UserManager - { - get - { - return _userManager ?? HttpContext.GetOwinContext().GetUserManager(); - } - private set - { - _userManager = value; - } - } - - // - // GET: /Manage/Index - public async Task Index(ManageMessageId? message) - { - ViewBag.StatusMessage = - message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." - : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set." - : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set." - : message == ManageMessageId.Error ? "An error has occurred." - : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added." - : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed." - : ""; - - var userId = User.Identity.GetUserId(); - var model = new IndexViewModel - { - HasPassword = HasPassword(), - PhoneNumber = await UserManager.GetPhoneNumberAsync(userId), - TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId), - Logins = await UserManager.GetLoginsAsync(userId), - BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userId) - }; - return View(model); - } - - // - // POST: /Manage/RemoveLogin - [HttpPost] - [ValidateAntiForgeryToken] - public async Task RemoveLogin(string loginProvider, string providerKey) - { - ManageMessageId? message; - var result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey)); - if (result.Succeeded) - { - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - if (user != null) - { - await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); - } - message = ManageMessageId.RemoveLoginSuccess; - } - else - { - message = ManageMessageId.Error; - } - return RedirectToAction("ManageLogins", new { Message = message }); - } - - // - // GET: /Manage/AddPhoneNumber - public ActionResult AddPhoneNumber() - { - return View(); - } - - // - // POST: /Manage/AddPhoneNumber - [HttpPost] - [ValidateAntiForgeryToken] - public async Task AddPhoneNumber(AddPhoneNumberViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - // Generate the token and send it - var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), model.Number); - if (UserManager.SmsService != null) - { - var message = new IdentityMessage - { - Destination = model.Number, - Body = "Your security code is: " + code - }; - await UserManager.SmsService.SendAsync(message); - } - return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number }); - } - - // - // POST: /Manage/EnableTwoFactorAuthentication - [HttpPost] - [ValidateAntiForgeryToken] - public async Task EnableTwoFactorAuthentication() - { - await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true); - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - if (user != null) - { - await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); - } - return RedirectToAction("Index", "Manage"); - } - - // - // POST: /Manage/DisableTwoFactorAuthentication - [HttpPost] - [ValidateAntiForgeryToken] - public async Task DisableTwoFactorAuthentication() - { - await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false); - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - if (user != null) - { - await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); - } - return RedirectToAction("Index", "Manage"); - } - - // - // GET: /Manage/VerifyPhoneNumber - public async Task VerifyPhoneNumber(string phoneNumber) - { - var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), phoneNumber); - // Send an SMS through the SMS provider to verify the phone number - return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber }); - } - - // - // POST: /Manage/VerifyPhoneNumber - [HttpPost] - [ValidateAntiForgeryToken] - public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - var result = await UserManager.ChangePhoneNumberAsync(User.Identity.GetUserId(), model.PhoneNumber, model.Code); - if (result.Succeeded) - { - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - if (user != null) - { - await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); - } - return RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess }); - } - // If we got this far, something failed, redisplay form - ModelState.AddModelError("", "Failed to verify phone"); - return View(model); - } - - // - // GET: /Manage/RemovePhoneNumber - public async Task RemovePhoneNumber() - { - var result = await UserManager.SetPhoneNumberAsync(User.Identity.GetUserId(), null); - if (!result.Succeeded) - { - return RedirectToAction("Index", new { Message = ManageMessageId.Error }); - } - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - if (user != null) - { - await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); - } - return RedirectToAction("Index", new { Message = ManageMessageId.RemovePhoneSuccess }); - } - - // - // GET: /Manage/ChangePassword - public ActionResult ChangePassword() - { - return View(); - } - - // - // POST: /Manage/ChangePassword - [HttpPost] - [ValidateAntiForgeryToken] - public async Task ChangePassword(ChangePasswordViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword); - if (result.Succeeded) - { - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - if (user != null) - { - await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); - } - return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess }); - } - AddErrors(result); - return View(model); - } - - // - // GET: /Manage/SetPassword - public ActionResult SetPassword() - { - return View(); - } - - // - // POST: /Manage/SetPassword - [HttpPost] - [ValidateAntiForgeryToken] - public async Task SetPassword(SetPasswordViewModel model) - { - if (ModelState.IsValid) - { - var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword); - if (result.Succeeded) - { - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - if (user != null) - { - await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); - } - return RedirectToAction("Index", new { Message = ManageMessageId.SetPasswordSuccess }); - } - AddErrors(result); - } - - // If we got this far, something failed, redisplay form - return View(model); - } - - // - // GET: /Manage/ManageLogins - public async Task ManageLogins(ManageMessageId? message) - { - ViewBag.StatusMessage = - message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed." - : message == ManageMessageId.Error ? "An error has occurred." - : ""; - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - if (user == null) - { - return View("Error"); - } - var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId()); - var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList(); - ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1; - return View(new ManageLoginsViewModel - { - CurrentLogins = userLogins, - OtherLogins = otherLogins - }); - } - - // - // POST: /Manage/LinkLogin - [HttpPost] - [ValidateAntiForgeryToken] - public ActionResult LinkLogin(string provider) - { - // Request a redirect to the external login provider to link a login for the current user - return new AccountController.ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage"), User.Identity.GetUserId()); - } - - // - // GET: /Manage/LinkLoginCallback - public async Task LinkLoginCallback() - { - var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId()); - if (loginInfo == null) - { - return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error }); - } - var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login); - return result.Succeeded ? RedirectToAction("ManageLogins") : RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error }); - } - - protected override void Dispose(bool disposing) - { - if (disposing && _userManager != null) - { - _userManager.Dispose(); - _userManager = null; - } - - base.Dispose(disposing); - } - -#region Helpers - // Used for XSRF protection when adding external logins - private const string XsrfKey = "XsrfId"; - - private IAuthenticationManager AuthenticationManager - { - get - { - return HttpContext.GetOwinContext().Authentication; - } - } - - private void AddErrors(IdentityResult result) - { - foreach (var error in result.Errors) - { - ModelState.AddModelError("", error); - } - } - - private bool HasPassword() - { - var user = UserManager.FindById(User.Identity.GetUserId()); - if (user != null) - { - return user.PasswordHash != null; - } - return false; - } - - private bool HasPhoneNumber() - { - var user = UserManager.FindById(User.Identity.GetUserId()); - if (user != null) - { - return user.PhoneNumber != null; - } - return false; - } - - public enum ManageMessageId - { - AddPhoneSuccess, - ChangePasswordSuccess, - SetTwoFactorSuccess, - SetPasswordSuccess, - RemoveLoginSuccess, - RemovePhoneSuccess, - Error - } - -#endregion - } -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Fitbit.Portable.DebugSite.csproj b/Fitbit.Portable.DebugSite/Fitbit.Portable.DebugSite.csproj deleted file mode 100644 index d644feb8..00000000 --- a/Fitbit.Portable.DebugSite/Fitbit.Portable.DebugSite.csproj +++ /dev/null @@ -1,292 +0,0 @@ - - - - - Debug - AnyCPU - - - 2.0 - {61C8AD29-A128-442E-BF0B-539A990B15C7} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - SampleWebMVCOAuth2 - SampleWebMVCOAuth2 - v4.5.1 - false - true - 44300 - - - - ..\Fitbit\ - true - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - - ..\Fitbit\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll - True - - - - - - - - - - - - - - ..\packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll - True - - - - - - - - True - ..\Fitbit\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - - - - - True - ..\Fitbit\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.Helpers.dll - - - ..\Fitbit\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll - - - True - ..\Fitbit\packages\Microsoft.AspNet.Razor.3.2.2\lib\net45\System.Web.Razor.dll - - - True - ..\Fitbit\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.dll - - - True - ..\Fitbit\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Deployment.dll - - - True - ..\Fitbit\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Razor.dll - - - - True - ..\Fitbit\packages\WebGrease.1.5.2\lib\WebGrease.dll - - - True - ..\Fitbit\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll - - - - - ..\Fitbit\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.dll - - - ..\Fitbit\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.SqlServer.dll - - - ..\Fitbit\packages\Microsoft.AspNet.Identity.Core.2.1.0\lib\net45\Microsoft.AspNet.Identity.Core.dll - - - ..\Fitbit\packages\Microsoft.AspNet.Identity.Owin.2.1.0\lib\net45\Microsoft.AspNet.Identity.Owin.dll - - - ..\Fitbit\packages\Microsoft.AspNet.Identity.EntityFramework.2.1.0\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll - - - ..\Fitbit\packages\Owin.1.0\lib\net40\Owin.dll - - - ..\Fitbit\packages\Microsoft.Owin.3.0.0\lib\net45\Microsoft.Owin.dll - - - ..\Fitbit\packages\Microsoft.Owin.Host.SystemWeb.3.0.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll - - - ..\Fitbit\packages\Microsoft.Owin.Security.3.0.0\lib\net45\Microsoft.Owin.Security.dll - - - ..\Fitbit\packages\Microsoft.Owin.Security.Facebook.3.0.0\lib\net45\Microsoft.Owin.Security.Facebook.dll - - - ..\Fitbit\packages\Microsoft.Owin.Security.Cookies.3.0.0\lib\net45\Microsoft.Owin.Security.Cookies.dll - - - ..\Fitbit\packages\Microsoft.Owin.Security.OAuth.3.0.0\lib\net45\Microsoft.Owin.Security.OAuth.dll - - - ..\Fitbit\packages\Microsoft.Owin.Security.Google.3.0.0\lib\net45\Microsoft.Owin.Security.Google.dll - - - ..\Fitbit\packages\Microsoft.Owin.Security.Twitter.3.0.0\lib\net45\Microsoft.Owin.Security.Twitter.dll - - - ..\Fitbit\packages\Microsoft.Owin.Security.MicrosoftAccount.3.0.0\lib\net45\Microsoft.Owin.Security.MicrosoftAccount.dll - - - - - - - - - - - - - - Global.asax - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer - - - Web.config - - - Web.config - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {1358d3b4-0698-4003-97eb-b6d489e04138} - Fitbit.Portable - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - - - - True - True - 1531 - / - http://localhost:1531/ - False - False - - - False - - - - - - \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Global.asax b/Fitbit.Portable.DebugSite/Global.asax deleted file mode 100644 index dc1981e8..00000000 --- a/Fitbit.Portable.DebugSite/Global.asax +++ /dev/null @@ -1 +0,0 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="SampleWebMVCOAuth2.MvcApplication" Language="C#" %> diff --git a/Fitbit.Portable.DebugSite/Global.asax.cs b/Fitbit.Portable.DebugSite/Global.asax.cs deleted file mode 100644 index 4757e792..00000000 --- a/Fitbit.Portable.DebugSite/Global.asax.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Mvc; -using System.Web.Optimization; -using System.Web.Routing; - -namespace SampleWebMVCOAuth2 -{ - public class MvcApplication : System.Web.HttpApplication - { - protected void Application_Start() - { - AreaRegistration.RegisterAllAreas(); - FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); - RouteConfig.RegisterRoutes(RouteTable.Routes); - BundleConfig.RegisterBundles(BundleTable.Bundles); - } - } -} diff --git a/Fitbit.Portable.DebugSite/Models/AccountViewModels.cs b/Fitbit.Portable.DebugSite/Models/AccountViewModels.cs deleted file mode 100644 index a6983ceb..00000000 --- a/Fitbit.Portable.DebugSite/Models/AccountViewModels.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; - -namespace SampleWebMVCOAuth2.Models -{ - public class ExternalLoginConfirmationViewModel - { - [Required] - [Display(Name = "Email")] - public string Email { get; set; } - } - - public class ExternalLoginListViewModel - { - public string ReturnUrl { get; set; } - } - - public class SendCodeViewModel - { - public string SelectedProvider { get; set; } - public ICollection Providers { get; set; } - public string ReturnUrl { get; set; } - public bool RememberMe { get; set; } - } - - public class VerifyCodeViewModel - { - [Required] - public string Provider { get; set; } - - [Required] - [Display(Name = "Code")] - public string Code { get; set; } - public string ReturnUrl { get; set; } - - [Display(Name = "Remember this browser?")] - public bool RememberBrowser { get; set; } - - public bool RememberMe { get; set; } - } - - public class ForgotViewModel - { - [Required] - [Display(Name = "Email")] - public string Email { get; set; } - } - - public class LoginViewModel - { - [Required] - [Display(Name = "Email")] - [EmailAddress] - public string Email { get; set; } - - [Required] - [DataType(DataType.Password)] - [Display(Name = "Password")] - public string Password { get; set; } - - [Display(Name = "Remember me?")] - public bool RememberMe { get; set; } - } - - public class RegisterViewModel - { - [Required] - [EmailAddress] - [Display(Name = "Email")] - public string Email { get; set; } - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "Password")] - public string Password { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm password")] - [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - } - - public class ResetPasswordViewModel - { - [Required] - [EmailAddress] - [Display(Name = "Email")] - public string Email { get; set; } - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "Password")] - public string Password { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm password")] - [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - - public string Code { get; set; } - } - - public class ForgotPasswordViewModel - { - [Required] - [EmailAddress] - [Display(Name = "Email")] - public string Email { get; set; } - } -} diff --git a/Fitbit.Portable.DebugSite/Models/IdentityModels.cs b/Fitbit.Portable.DebugSite/Models/IdentityModels.cs deleted file mode 100644 index 199a1147..00000000 --- a/Fitbit.Portable.DebugSite/Models/IdentityModels.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Data.Entity; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.EntityFramework; - -namespace SampleWebMVCOAuth2.Models -{ - // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. - public class ApplicationUser : IdentityUser - { - public async Task GenerateUserIdentityAsync(UserManager manager) - { - // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType - var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); - // Add custom user claims here - return userIdentity; - } - } - - public class ApplicationDbContext : IdentityDbContext - { - public ApplicationDbContext() - : base("DefaultConnection", throwIfV1Schema: false) - { - } - - public static ApplicationDbContext Create() - { - return new ApplicationDbContext(); - } - } -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Models/ManageViewModels.cs b/Fitbit.Portable.DebugSite/Models/ManageViewModels.cs deleted file mode 100644 index 1a67ee26..00000000 --- a/Fitbit.Portable.DebugSite/Models/ManageViewModels.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using Microsoft.AspNet.Identity; -using Microsoft.Owin.Security; - -namespace SampleWebMVCOAuth2.Models -{ - public class IndexViewModel - { - public bool HasPassword { get; set; } - public IList Logins { get; set; } - public string PhoneNumber { get; set; } - public bool TwoFactor { get; set; } - public bool BrowserRemembered { get; set; } - } - - public class ManageLoginsViewModel - { - public IList CurrentLogins { get; set; } - public IList OtherLogins { get; set; } - } - - public class FactorViewModel - { - public string Purpose { get; set; } - } - - public class SetPasswordViewModel - { - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "New password")] - public string NewPassword { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm new password")] - [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - } - - public class ChangePasswordViewModel - { - [Required] - [DataType(DataType.Password)] - [Display(Name = "Current password")] - public string OldPassword { get; set; } - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "New password")] - public string NewPassword { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm new password")] - [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - } - - public class AddPhoneNumberViewModel - { - [Required] - [Phone] - [Display(Name = "Phone Number")] - public string Number { get; set; } - } - - public class VerifyPhoneNumberViewModel - { - [Required] - [Display(Name = "Code")] - public string Code { get; set; } - - [Required] - [Phone] - [Display(Name = "Phone Number")] - public string PhoneNumber { get; set; } - } - - public class ConfigureTwoFactorViewModel - { - public string SelectedProvider { get; set; } - public ICollection Providers { get; set; } - } -} \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Project_Readme.html b/Fitbit.Portable.DebugSite/Project_Readme.html deleted file mode 100644 index 4bb67605..00000000 --- a/Fitbit.Portable.DebugSite/Project_Readme.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - Your ASP.NET application - - - - - - -
-
-

This application consists of:

-
    -
  • Sample pages showing basic nav between Home, About, and Contact
  • -
  • Theming using Bootstrap
  • -
  • Authentication, if selected, shows how to register and sign in
  • -
  • ASP.NET features managed using NuGet
  • -
-
- - - - - -
-

Get help

- -
-
- - - \ No newline at end of file diff --git a/Fitbit.Portable.DebugSite/Properties/AssemblyInfo.cs b/Fitbit.Portable.DebugSite/Properties/AssemblyInfo.cs deleted file mode 100644 index a211b2cc..00000000 --- a/Fitbit.Portable.DebugSite/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -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("SampleWebMVCOAuth2")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SampleWebMVCOAuth2")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("427a7ef3-0ac3-461e-afd4-262a519c6a90")] - -// 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 Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Fitbit.Portable.DebugSite/Scripts/_references.js b/Fitbit.Portable.DebugSite/Scripts/_references.js deleted file mode 100644 index 518a95992a99e9a3b60c01f77668ad6fb1fcbf08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 396 zcmbu5F%H5o3`O6J#2qU30%c$V?vj!qsGxzQ3~+eh$E-|Lk!35kpTGTnEhw*IgX7LX zB=ewWufHJgXgMqLY?&#aR239e>e?}7V*Ou2Qsy8lz7T?{t|AN^t@|Rnw|viur|N1} u%vsBd?=<^Aa>vbdC26l|#A;ZMrnb@>r9RufJSgw-Ah`NpcLHYpnGd@HB diff --git a/Fitbit.Portable.DebugSite/Scripts/bootstrap.js b/Fitbit.Portable.DebugSite/Scripts/bootstrap.js deleted file mode 100644 index 2c642571..00000000 --- a/Fitbit.Portable.DebugSite/Scripts/bootstrap.js +++ /dev/null @@ -1,1999 +0,0 @@ -/** -* bootstrap.js v3.0.0 by @fat and @mdo -* Copyright 2013 Twitter Inc. -* http://www.apache.org/licenses/LICENSE-2.0 -*/ -if (!jQuery) { throw new Error("Bootstrap requires jQuery") } - -/* ======================================================================== - * Bootstrap: transition.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#transitions - * ======================================================================== - * Copyright 2013 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) - // ============================================================ - - function transitionEnd() { - var el = document.createElement('bootstrap') - - var transEndEventNames = { - 'WebkitTransition' : 'webkitTransitionEnd' - , 'MozTransition' : 'transitionend' - , 'OTransition' : 'oTransitionEnd otransitionend' - , 'transition' : 'transitionend' - } - - for (var name in transEndEventNames) { - if (el.style[name] !== undefined) { - return { end: transEndEventNames[name] } - } - } - } - - // http://blog.alexmaccaw.com/css-transitions - $.fn.emulateTransitionEnd = function (duration) { - var called = false, $el = this - $(this).one($.support.transition.end, function () { called = true }) - var callback = function () { if (!called) $($el).trigger($.support.transition.end) } - setTimeout(callback, duration) - return this - } - - $(function () { - $.support.transition = transitionEnd() - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: alert.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#alerts - * ======================================================================== - * Copyright 2013 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // ALERT CLASS DEFINITION - // ====================== - - var dismiss = '[data-dismiss="alert"]' - var Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.prototype.close = function (e) { - var $this = $(this) - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = $(selector) - - if (e) e.preventDefault() - - if (!$parent.length) { - $parent = $this.hasClass('alert') ? $this : $this.parent() - } - - $parent.trigger(e = $.Event('close.bs.alert')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - $parent.trigger('closed.bs.alert').remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent - .one($.support.transition.end, removeElement) - .emulateTransitionEnd(150) : - removeElement() - } - - - // ALERT PLUGIN DEFINITION - // ======================= - - var old = $.fn.alert - - $.fn.alert = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.alert') - - if (!data) $this.data('bs.alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.alert.Constructor = Alert - - - // ALERT NO CONFLICT - // ================= - - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this - } - - - // ALERT DATA-API - // ============== - - $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: button.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#buttons - * ======================================================================== - * Copyright 2013 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // BUTTON PUBLIC CLASS DEFINITION - // ============================== - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Button.DEFAULTS, options) - } - - Button.DEFAULTS = { - loadingText: 'loading...' - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - var $el = this.$element - var val = $el.is('input') ? 'val' : 'html' - var data = $el.data() - - state = state + 'Text' - - if (!data.resetText) $el.data('resetText', $el[val]()) - - $el[val](data[state] || this.options[state]) - - // push to event loop to allow forms to submit - setTimeout(function () { - state == 'loadingText' ? - $el.addClass(d).attr(d, d) : - $el.removeClass(d).removeAttr(d); - }, 0) - } - - Button.prototype.toggle = function () { - var $parent = this.$element.closest('[data-toggle="buttons"]') - - if ($parent.length) { - var $input = this.$element.find('input') - .prop('checked', !this.$element.hasClass('active')) - .trigger('change') - if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active') - } - - this.$element.toggleClass('active') - } - - - // BUTTON PLUGIN DEFINITION - // ======================== - - var old = $.fn.button - - $.fn.button = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.button') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.button', (data = new Button(this, options))) - - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - $.fn.button.Constructor = Button - - - // BUTTON NO CONFLICT - // ================== - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - // BUTTON DATA-API - // =============== - - $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - $btn.button('toggle') - e.preventDefault() - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: carousel.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#carousel - * ======================================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // CAROUSEL CLASS DEFINITION - // ========================= - - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.paused = - this.sliding = - this.interval = - this.$active = - this.$items = null - - this.options.pause == 'hover' && this.$element - .on('mouseenter', $.proxy(this.pause, this)) - .on('mouseleave', $.proxy(this.cycle, this)) - } - - Carousel.DEFAULTS = { - interval: 5000 - , pause: 'hover' - , wrap: true - } - - Carousel.prototype.cycle = function (e) { - e || (this.paused = false) - - this.interval && clearInterval(this.interval) - - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - - return this - } - - Carousel.prototype.getActiveIndex = function () { - this.$active = this.$element.find('.item.active') - this.$items = this.$active.parent().children() - - return this.$items.index(this.$active) - } - - Carousel.prototype.to = function (pos) { - var that = this - var activeIndex = this.getActiveIndex() - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) return this.$element.one('slid', function () { that.to(pos) }) - if (activeIndex == pos) return this.pause().cycle() - - return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) - } - - Carousel.prototype.pause = function (e) { - e || (this.paused = true) - - if (this.$element.find('.next, .prev').length && $.support.transition.end) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - - this.interval = clearInterval(this.interval) - - return this - } - - Carousel.prototype.next = function () { - if (this.sliding) return - return this.slide('next') - } - - Carousel.prototype.prev = function () { - if (this.sliding) return - return this.slide('prev') - } - - Carousel.prototype.slide = function (type, next) { - var $active = this.$element.find('.item.active') - var $next = next || $active[type]() - var isCycling = this.interval - var direction = type == 'next' ? 'left' : 'right' - var fallback = type == 'next' ? 'first' : 'last' - var that = this - - if (!$next.length) { - if (!this.options.wrap) return - $next = this.$element.find('.item')[fallback]() - } - - this.sliding = true - - isCycling && this.pause() - - var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction }) - - if ($next.hasClass('active')) return - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - this.$element.one('slid', function () { - var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) - $nextIndicator && $nextIndicator.addClass('active') - }) - } - - if ($.support.transition && this.$element.hasClass('slide')) { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - $active - .one($.support.transition.end, function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { that.$element.trigger('slid') }, 0) - }) - .emulateTransitionEnd(600) - } else { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger('slid') - } - - isCycling && this.cycle() - - return this - } - - - // CAROUSEL PLUGIN DEFINITION - // ========================== - - var old = $.fn.carousel - - $.fn.carousel = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.carousel') - var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) - var action = typeof option == 'string' ? option : options.slide - - if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) - } - - $.fn.carousel.Constructor = Carousel - - - // CAROUSEL NO CONFLICT - // ==================== - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - - // CAROUSEL DATA-API - // ================= - - $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { - var $this = $(this), href - var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 - var options = $.extend({}, $target.data(), $this.data()) - var slideIndex = $this.attr('data-slide-to') - if (slideIndex) options.interval = false - - $target.carousel(options) - - if (slideIndex = $this.attr('data-slide-to')) { - $target.data('bs.carousel').to(slideIndex) - } - - e.preventDefault() - }) - - $(window).on('load', function () { - $('[data-ride="carousel"]').each(function () { - var $carousel = $(this) - $carousel.carousel($carousel.data()) - }) - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: collapse.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#collapse - * ======================================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // COLLAPSE PUBLIC CLASS DEFINITION - // ================================ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Collapse.DEFAULTS, options) - this.transitioning = null - - if (this.options.parent) this.$parent = $(this.options.parent) - if (this.options.toggle) this.toggle() - } - - Collapse.DEFAULTS = { - toggle: true - } - - Collapse.prototype.dimension = function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - Collapse.prototype.show = function () { - if (this.transitioning || this.$element.hasClass('in')) return - - var startEvent = $.Event('show.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var actives = this.$parent && this.$parent.find('> .panel > .in') - - if (actives && actives.length) { - var hasData = actives.data('bs.collapse') - if (hasData && hasData.transitioning) return - actives.collapse('hide') - hasData || actives.data('bs.collapse', null) - } - - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - .addClass('collapsing') - [dimension](0) - - this.transitioning = 1 - - var complete = function () { - this.$element - .removeClass('collapsing') - .addClass('in') - [dimension]('auto') - this.transitioning = 0 - this.$element.trigger('shown.bs.collapse') - } - - if (!$.support.transition) return complete.call(this) - - var scrollSize = $.camelCase(['scroll', dimension].join('-')) - - this.$element - .one($.support.transition.end, $.proxy(complete, this)) - .emulateTransitionEnd(350) - [dimension](this.$element[0][scrollSize]) - } - - Collapse.prototype.hide = function () { - if (this.transitioning || !this.$element.hasClass('in')) return - - var startEvent = $.Event('hide.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var dimension = this.dimension() - - this.$element - [dimension](this.$element[dimension]()) - [0].offsetHeight - - this.$element - .addClass('collapsing') - .removeClass('collapse') - .removeClass('in') - - this.transitioning = 1 - - var complete = function () { - this.transitioning = 0 - this.$element - .trigger('hidden.bs.collapse') - .removeClass('collapsing') - .addClass('collapse') - } - - if (!$.support.transition) return complete.call(this) - - this.$element - [dimension](0) - .one($.support.transition.end, $.proxy(complete, this)) - .emulateTransitionEnd(350) - } - - Collapse.prototype.toggle = function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - - // COLLAPSE PLUGIN DEFINITION - // ========================== - - var old = $.fn.collapse - - $.fn.collapse = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.collapse') - var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.collapse.Constructor = Collapse - - - // COLLAPSE NO CONFLICT - // ==================== - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - // COLLAPSE DATA-API - // ================= - - $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) { - var $this = $(this), href - var target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - var $target = $(target) - var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $this.data() - var parent = $this.attr('data-parent') - var $parent = parent && $(parent) - - if (!data || !data.transitioning) { - if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed') - $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') - } - - $target.collapse(option) - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: dropdown.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#dropdowns - * ======================================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // DROPDOWN CLASS DEFINITION - // ========================= - - var backdrop = '.dropdown-backdrop' - var toggle = '[data-toggle=dropdown]' - var Dropdown = function (element) { - var $el = $(element).on('click.bs.dropdown', this.toggle) - } - - Dropdown.prototype.toggle = function (e) { - var $this = $(this) - - if ($this.is('.disabled, :disabled')) return - - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { - // if mobile we we use a backdrop because click events don't delegate - $('