text:
using static NodaTime.NodaConstants;

using System;
using System.Globalization;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using JetBrains.Annotations;
using NodaTime.Annotations;
using NodaTime.Calendars;
using NodaTime.Text;
using NodaTime.Utility;

namespace NodaTime
{
    /// <summary>
    /// Represents a fixed (and calendar-independent) length of time.
    /// </summary>
    /// <remarks>
    /// <para>
    /// A duration is a length of time defined by an integral number of nanoseconds.
    /// Although durations are usually used with a positive number of nanoseconds, negative durations are valid, and may occur
    /// naturally when e.g. subtracting an earlier <see cref="Instant"/> from a later one.
    /// </para>
    /// <para>
    /// A duration represents a fixed length of elapsed time along the time line that occupies the same amount of
    /// time regardless of when it is applied. In contrast, <see cref="Period"/> represents a period of time in
    /// calendrical terms (years, months, days, and so on) that may vary in elapsed time when applied.
    /// </para>
    /// <para>
    /// In general, use <see cref="Duration"/> to represent durations applied to global types like <see cref="Instant"/>
    /// and <see cref="ZonedDateTime"/>; use <c>Period</c> to represent a period applied to local types like
    /// <see cref="LocalDateTime"/>.
    /// </para>
    /// <para>
    /// The range of valid values of a <c>Duration</c> is greater than the span of time supported by Noda Time - so for
    /// example, subtracting one <see cref="Instant"/> from another will always give a valid <c>Duration</c>. See the user guide
    /// for more details of the exact range, but it is not expected that this will ever be exceeded in normal code.
    /// </para>
    /// </remarks>
    /// <threadsafety>This type is an immutable value type. See the thread safety section of the user guide for more information.</threadsafety>
#if !PCL
    [Serializable]
#endif
    public struct Duration : IEquatable<Duration>, IComparable<Duration>, IComparable, IXmlSerializable, IFormattable
#if !PCL
        , ISerializable
#endif
    {
        // This is one more bit than we really need, but it allows Instant.BeforeMinValue and Instant.AfterMaxValue
        // to be easily
        internal const int MaxDays = (1 << 24) - 1;
        internal const int MinDays = ~MaxDays;
        private static readonly decimal MinNanoseconds = (decimal)MinDays * NanosecondsPerDay;
        private static readonly decimal MaxNanoseconds = (MaxDays + 1M) * NanosecondsPerDay - 1M;

        // The -1 here is to allow for the addition of nearly a whole day in the nanoOfDay field.
        private const long MaxDaysForLongNanos = (int) (long.MaxValue / NanosecondsPerDay) - 1;
        private const long MinDaysForLongNanos = (int) (long.MinValue / NanosecondsPerDay);

        #region Readonly static properties
        /// <summary>
        /// Gets a zero <see cref="Duration"/> of 0 nanoseconds.
        /// </summary>
        /// <value>The zero <see cref="Duration"/> value.</value>
        public static Duration Zero => new Duration(0, 0L);

        /// <summary>
        /// Gets a <see cref="Duration"/> value equal to 1 nanosecond; the smallest amount by which an instant can vary.
        /// </summary>
        /// <value>A duration representing 1 nanosecond.</value>
        public static Duration Epsilon => new Duration(0, 1L);

        /// <summary>
        /// Gets the maximum value supported by <see cref="Duration"/>.
        /// </summary>
        public static Duration MaxValue => new Duration(MaxDays, NanosecondsPerDay - 1);

        /// <summary>
        /// Gets the minimum (largest negative) value supported by <see cref="Duration"/>.
        /// </summary>
        public static Duration MinValue => new Duration(MinDays, 0);

        /// <summary>
        /// Represents the <see cref="Duration"/> value equal to the number of nanoseconds in 1 standard week (7 days).
        /// </summary>
        /// <remarks>
        /// The value of this property is 604,800,000,000,000 nanoseconds.
        /// </remarks>
        internal static Duration OneWeek => new Duration(7, 0L);

        /// <summary>
        /// Represents the <see cref="Duration"/> value equal to the number of nanoseconds in 1 day.
        /// </summary>
        /// <remarks>
        /// The value of this property is 86.4 trillion nanoseconds; that is, 86,400,000,000,000 nanoseconds.
        /// </remarks>
        internal static Duration OneDay => new Duration(1, 0L);

        /// <summary>
        /// Represents the <see cref="Duration"/> value equal to the number of nanoseconds in 1 hour.
        /// </summary>
        /// <remarks>
        /// The value of this property is 3.6 trillion nanoseconds; that is, 3,600,000,000,000 nanoseconds.
        /// </remarks>
        private static Duration OneHour => new Duration(0, NanosecondsPerHour);

        /// <summary>
        /// Represents the <see cref="Duration"/> value equal to the number of nanoseconds in 1 minute.
        /// </summary>
        /// <remarks>
        /// The value of this property is 60 billion nanoseconds; that is, 60,000,000,000 nanoseconds.
        /// </remarks>
        private static Duration OneMinute => new Duration(0, NanosecondsPerMinute);

        /// <summary>
        /// Represents the <see cref="Duration"/> value equal to the number of nanoseconds in 1 second.
        /// </summary>
        /// <remarks>
        /// The value of this property is 1 billion nanoseconds; that is, 1,000,000,000 nanoseconds.
        /// </remarks>
        private static Duration OneSecond => new Duration(0, NanosecondsPerSecond);

        /// <summary>
        /// Represents the <see cref="Duration"/> value equals to number of ticks in 1 millisecond.
        /// </summary>
        /// <remarks>
        /// The value of this property is 1,000,000 nanoseconds.
        /// </remarks>
        private static Duration OneMillisecond => new Duration(0, NanosecondsPerMillisecond);
        #endregion

        // This is effectively a 25 bit value. (It can't be 24 bits, or we can't represent every TimeSpan value.)
        private readonly int days;
        // Always non-negative; a negative duration will have a negative number of days, but may have a
        // positive nanoOfDay. (A duration of -1ns will have a days value of -1 and a nanoOfDay of
        // NanosecondsPerDay - 1, for example.)
        private readonly long nanoOfDay;

        internal Duration(int days, [Trusted] long nanoOfDay)
        {
            // Heavily used: avoid the method call unless it's going to throw.
            // TODO: Validate that this actually has a measurable impact...
            if (days < MinDays || days > MaxDays)
            {
                Preconditions.CheckArgumentRange(nameof(days), days, MinDays, MaxDays);
            }
            Preconditions.DebugCheckArgumentRange(nameof(nanoOfDay), nanoOfDay, 0, NanosecondsPerDay - 1);
            this.days = days;
            this.nanoOfDay = nanoOfDay;
        }

        /// <summary>
        /// Days portion of this duration. The <see cref="NanosecondOfFloorDay" /> is added to this
        /// value, so this effectively Math.Floor(TotalDays).
        /// </summary>
        internal int FloorDays => days;

        /// <summary>
        /// Nanosecond within the "floor day". This is *always* non-negative, even for
        /// negative durations.
        /// </summary>
        internal long NanosecondOfFloorDay => nanoOfDay;

        /// <summary>
        /// Gets the whole number of standard (24 hour) days within this duration. This is truncated towards zero;
        /// for example, "-1.75 days" and "1.75 days" would have results of -1 and 1 respectively.
        /// </summary>
        /// <value>The whole number of days in the duration</value>
        public int Days => days >= 0 || nanoOfDay == 0 ? days : days + 1;

        /// <summary>
        /// Gets the number of nanoseconds within the day of this duration. For negative durations, this
        /// will be negative (or zero).
        /// </summary>
        /// <value>The number of nanoseconds within the day of this duration.</value>
        public long NanosecondOfDay => days >= 0 ? nanoOfDay
                    : nanoOfDay == 0 ? 0L
                    : nanoOfDay - NanosecondsPerDay;

        /// <summary>
        /// The hour component of this duration, in the range [-23, 23], truncated towards zero.
        /// </summary>
        /// <value>The hour component of the duration, within the day.</value>
        public int Hours => unchecked((int) (NanosecondOfDay / NanosecondsPerHour));

        /// <summary>
        /// The minute component of this duration, in the range [-59, 59], truncated towards zero.
        /// </summary>
        /// <value>The minute component of the duration, within the hour.</value>
        public int Minutes => unchecked((int) ((NanosecondOfDay / NanosecondsPerMinute) % MinutesPerHour));

        /// <summary>
        /// Gets the second component of this duration, in the range [-59, 59], truncated towards zero.
        /// </summary>
        /// <value>The second component of the duration, within the minute.</value>
        public int Seconds => unchecked((int) ((NanosecondOfDay / NanosecondsPerSecond) % SecondsPerMinute));

        /// <summary>
        /// Gets the subsecond component of this duration, expressed in milliseconds, in the range [-999, 999] and truncated towards zero.
        /// </summary>
        /// <value>The subsecond component of the duration, in milliseconds.</value>
        public int Milliseconds => unchecked((int) ((NanosecondOfDay / NanosecondsPerMillisecond) % MillisecondsPerSecond));

        /// <summary>
        /// Gets the subsecond component of this duration, expressed in ticks, in the range [-9999999, 9999999] and truncated towards zero.
        /// </summary>
        /// <value>The subsecond component of the duration, in ticks.</value>
        public int SubsecondTicks => unchecked((int) ((NanosecondOfDay / NanosecondsPerTick) % TicksPerSecond));

        /// <summary>
        /// Gets the subsecond component of this duration, expressed in nanoseconds, in the range [-999999999, 999999999].
        /// </summary>
        /// <value>The subsecond component of the duration, in nanoseconds.</value>
        public int SubsecondNanoseconds => unchecked((int) (NanosecondOfDay % NanosecondsPerSecond));

        /// <summary>
        /// Gets the total number of ticks in the duration.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If the number of nanoseconds in a duration is not a whole number of ticks, it is truncated towards zero.
        /// For example, durations in the range [-99ns, 99ns] would all count as 0 ticks.
        /// </para>
        /// <para>Although this method can overflow, it will only do so in very exceptional cases, with durations
        /// with a magnitude of more than 29000 Gregorian years or so.</para>
        /// </remarks>
        /// <exception cref="OverflowException">The number of ticks cannot be represented a signed 64-bit integer.</exception>
        /// <value>The total number of ticks in the duration.</value>
        public long Ticks
        {
            get
            {
                long ticks = TickArithmetic.DaysAndTickOfDayToTicks(days, nanoOfDay / NanosecondsPerTick);
                if (days < 0 && nanoOfDay % NanosecondsPerTick != 0)
                {
                    ticks++;
                }
                return ticks;
            }
        }

        /// <summary>
        /// Gets the total number of days in this duration, as a <see cref="double"/>.
        /// </summary>
        /// <remarks>This method is the <c>Duration</c> equivalent of <see cref="TimeSpan.TotalDays"/>.
        /// It represents the complete duration in days, rather than only the whole number of
        /// days. For example, for a duration of 36 hours, this property would return 1.5.
        /// </remarks>
        /// <value>The total number of days in this duration.</value>
        public double TotalDays => days + nanoOfDay / (double) NanosecondsPerDay;

        /// <summary>
        /// Gets the total number of hours in this duration, as a <see cref="double"/>.
        /// </summary>
        /// <remarks>
        /// This method is the <c>Duration</c> equivalent of <see cref="TimeSpan.TotalHours"/>.
        /// Unlike <see cref="Hours"/>, it represents the complete duration in hours rather than the
        /// whole number of hours as part of the day. So for a duration
        /// of 1 day, 2 hours and 30 minutes, the <c>Hours</c> property will return 2, but <c>TotalHours</c>
        /// will return 26.5.
        /// </remarks>
        /// <value>The total number of hours in this duration.</value>
        public double TotalHours => days * 24.0 + nanoOfDay / (double) NanosecondsPerHour;

        /// <summary>
        /// Gets the total number of minutes in this duration, as a <see cref="double"/>.
        /// </summary>
        /// <remarks>This method is the <c>Duration</c> equivalent of <see cref="TimeSpan.TotalMinutes"/>.</remarks>
        /// Unlike <see cref="Minutes"/>, it represents the complete duration in minutes rather than
        /// the whole number of minutes within the hour. So for a duration
        /// of 2 hours, 30 minutes and 45 seconds, the <c>Minutes</c> property will return 30, but <c>TotalMinutes</c>
        /// will return 150.75.
        /// <value>The total number of minutes in this duration.</value>
        public double TotalMinutes => days * (double) MinutesPerDay + nanoOfDay / (double) NanosecondsPerMinute;

        /// <summary>
        /// Gets the total number of seconds in this duration, as a <see cref="double"/>.
        /// </summary>
        /// <remarks>This method is the <c>Duration</c> equivalent of <see cref="TimeSpan.TotalSeconds"/>.</remarks>
        /// Unlike <see cref="Seconds"/>, it represents the complete duration in seconds rather than
        /// the whole number of seconds within the minute. So for a duration
        /// of 10 minutes, 20 seconds and 250 milliseconds, the <c>Seconds</c> property will return 20, but <c>TotalSeconds</c>
        /// will return 620.25.
        /// <value>The total number of minutes in this duration.</value>
        public double TotalSeconds => days * (double) SecondsPerDay + nanoOfDay / (double) NanosecondsPerSecond;

        /// <summary>
        /// Adds a "small" number of nanoseconds to this duration: it is trusted to be less or equal to than 24 hours
        /// in magnitude.
        /// </summary>
        [Pure]
        internal Duration PlusSmallNanoseconds([Trusted] long smallNanos)
        {
            unchecked
            {
                Preconditions.DebugCheckArgumentRange(nameof(smallNanos), smallNanos, -NanosecondsPerDay, NanosecondsPerDay);
                int newDays = days;
                long newNanos = nanoOfDay + smallNanos;
                if (newNanos >= NanosecondsPerDay)
                {
                    newDays++;
                    newNanos -= NanosecondsPerDay;
                }
                else if (newNanos < 0)
                {
                    newDays--;
                    newNanos += NanosecondsPerDay;
                }
                return new Duration(newDays, newNanos);
            }
        }

        /// <summary>
        /// Subtracts a "small" number of nanoseconds from this duration: it is trusted to be less than 24 hours
        /// in magnitude.
        /// </summary>
        [Pure]
        internal Duration MinusSmallNanoseconds(long smallNanos)
        {
            unchecked
            {
                Preconditions.DebugCheckArgumentRange(nameof(smallNanos), smallNanos, -NanosecondsPerDay, NanosecondsPerDay);
                int newDays = days;
                long newNanos = nanoOfDay - smallNanos;
                if (newNanos >= NanosecondsPerDay)
                {
                    newDays++;
                    newNanos -= NanosecondsPerDay;
                }
                else if (newNanos < 0)
                {
                    newDays--;
                    newNanos += NanosecondsPerDay;
                }
                return new Duration(newDays, newNanos);
            }
        }

        #region Object overrides
        /// <summary>
        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
        /// <returns>
        /// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance;
        /// otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj) => obj is Duration && Equals((Duration)obj);

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data
        /// structures like a hash table.
        /// </returns>
        public override int GetHashCode() => days ^ nanoOfDay.GetHashCode();
        #endregion

        #region Formatting
        /// <summary>
        /// Returns a <see cref="System.String" /> that represents this instance.
        /// </summary>
        /// <returns>
        /// The value of the current instance in the default format pattern ("o"), using the current thread's
        /// culture to obtain a format provider.
        /// </returns>
        public override string ToString() => DurationPattern.BclSupport.Format(this, null, CultureInfo.CurrentCulture);

        /// <summary>
        /// Formats the value of the current instance using the specified pattern.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String" /> containing the value of the current instance in the specified format.
        /// </returns>
        /// <param name="patternText">The <see cref="T:System.String" /> specifying the pattern to use,
        /// or null to use the default format pattern ("o").
        /// </param>
        /// <param name="formatProvider">The <see cref="T:System.IFormatProvider" /> to use when formatting the value,
        /// or null to use the current thread's culture to obtain a format provider.
        /// </param>
        /// <filterpriority>2</filterpriority>
        public string ToString(string patternText, IFormatProvider formatProvider) =>
            DurationPattern.BclSupport.Format(this, patternText, formatProvider);
        #endregion Formatting

        #region Operators
        /// <summary>
        /// Implements the operator + (addition).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the sum of the given values.</returns>
        public static Duration operator +(Duration left, Duration right)
        {
            unchecked
            {
                int newDays = left.days + right.days;
                long newNanos = left.nanoOfDay + right.nanoOfDay;
                if (newNanos >= NanosecondsPerDay)
                {
                    newDays++;
                    newNanos -= NanosecondsPerDay;
                }
                else if (newNanos < 0)
                {
                    newDays--;
                    newNanos += NanosecondsPerDay;
                }
                return new Duration(newDays, newNanos);
            }
        }

        /// <summary>
        /// Adds one duration to another. Friendly alternative to <c>operator+()</c>.
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the sum of the given values.</returns>
        public static Duration Add(Duration left, Duration right) => left + right;

        /// <summary>
        /// Returns the result of adding another duration to this one, for a fluent alternative to <c>operator+()</c>.
        /// </summary>
        /// <param name="other">The duration to add</param>
        /// <returns>A new <see cref="Duration" /> representing the result of the addition.</returns>
        [Pure]
        public Duration Plus(Duration other) => this + other;

        /// <summary>
        /// Implements the operator - (subtraction).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the difference of the given values.</returns>
        public static Duration operator -(Duration left, Duration right)
        {
            unchecked
            {
                int newDays = left.days - right.days;
                long newNanos = left.nanoOfDay - right.nanoOfDay;
                if (newNanos >= NanosecondsPerDay)
                {
                    newDays++;
                    newNanos -= NanosecondsPerDay;
                }
                else if (newNanos < 0)
                {
                    newDays--;
                    newNanos += NanosecondsPerDay;
                }
                return new Duration(newDays, newNanos);
            }
        }

        /// <summary>
        /// Subtracts one duration from another. Friendly alternative to <c>operator-()</c>.
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the difference of the given values.</returns>
        public static Duration Subtract(Duration left, Duration right) => left - right;

        /// <summary>
        /// Returns the result of subtracting another duration from this one, for a fluent alternative to <c>operator-()</c>.
        /// </summary>
        /// <param name="other">The duration to subtract</param>
        /// <returns>A new <see cref="Duration" /> representing the result of the subtraction.</returns>
        [Pure]
        public Duration Minus(Duration other) => this - other;

        /// <summary>
        /// Implements the operator / (division).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the result of dividing <paramref name="left"/> by
        /// <paramref name="right"/>.</returns>
        public static Duration operator /(Duration left, long right)
        {
            int days = left.days;
            // Simplest scenario to handle
            if (days == 0 && right > 0)
            {
                return new Duration(0, left.nanoOfDay / right);
            }
            // Now for the ~[-250, +250] year range, where we can do it all as a long.
            if (days >= MinDaysForLongNanos && days <= MaxDaysForLongNanos)
            {
                long nanos = left.ToInt64Nanoseconds() / right;
                return Duration.FromNanoseconds(nanos);
            }
            // Fall back to decimal arithmetic.
            decimal x = left.ToDecimalNanoseconds();
            return FromNanoseconds(x / right);
        }

        /// <summary>
        /// Divides a duration by a number. Friendly alternative to <c>operator/()</c>.
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the result of dividing <paramref name="left"/> by
        /// <paramref name="right"/>.</returns>
        public static Duration Divide(Duration left, long right) => left / right;

        /// <summary>
        /// Implements the operator * (multiplication).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the result of multiplying <paramref name="left"/> by
        /// <paramref name="right"/>.</returns>
        public static Duration operator *(Duration left, long right)
        {
            if (right == 0 || left == Zero)
            {
                return Zero;
            }
            int days = left.days;
            // Speculatively try integer arithmetic... currently just for positive nanos because
            // it's more common and easier to think about.
            if (days >= 0 && days <= MaxDaysForLongNanos)
            {
                long originalNanos = left.ToInt64Nanoseconds();
                if (right > 0)
                {
                    if (right < long.MaxValue / originalNanos)
                    {
                        return FromNanoseconds(originalNanos * right);
                    }
                }
                else
                {
                    if (right > long.MinValue / originalNanos)
                    {
                        return FromNanoseconds(originalNanos * right);
                    }
                }
            }
            // Fall back to decimal arithmetic
            decimal x = left.ToDecimalNanoseconds();
            return FromNanoseconds(x * right);
        }

        /// <summary>
        /// Implements the operator * (multiplication).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the result of multiplying <paramref name="left"/> by
        /// <paramref name="right"/>.</returns>
        public static Duration operator *(long left, Duration right) => right * left;

        /// <summary>
        /// Multiplies a duration by a number. Friendly alternative to <c>operator*()</c>.
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the product of the given values.</returns>
        public static Duration Multiply(Duration left, long right) => left * right;

        /// <summary>
        /// Multiplies a duration by a number. Friendly alternative to <c>operator*()</c>.
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns>A new <see cref="Duration"/> representing the product of the given values.</returns>
        public static Duration Multiply(long left, Duration right) => left * right;

        /// <summary>
        /// Implements the operator == (equality).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns><c>true</c> if values are equal to each other, otherwise <c>false</c>.</returns>
        public static bool operator ==(Duration left, Duration right) =>
            left.days == right.days && left.nanoOfDay == right.nanoOfDay;

        /// <summary>
        /// Implements the operator != (inequality).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns><c>true</c> if values are not equal to each other, otherwise <c>false</c>.</returns>
        public static bool operator !=(Duration left, Duration right) => !(left == right);

        /// <summary>
        /// Implements the operator < (less than).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns><c>true</c> if the left value is less than the right value, otherwise <c>false</c>.</returns>
        public static bool operator <(Duration left, Duration right) =>
            left.days < right.days || (left.days == right.days && left.nanoOfDay < right.nanoOfDay);

        /// <summary>
        /// Implements the operator <= (less than or equal).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns><c>true</c> if the left value is less than or equal to the right value, otherwise <c>false</c>.</returns>
        public static bool operator <=(Duration left, Duration right) =>
            left.days < right.days || (left.days == right.days && left.nanoOfDay <= right.nanoOfDay);

        /// <summary>
        /// Implements the operator > (greater than).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns><c>true</c> if the left value is greater than the right value, otherwise <c>false</c>.</returns>
        public static bool operator >(Duration left, Duration right) =>
            left.days > right.days || (left.days == right.days && left.nanoOfDay > right.nanoOfDay);

        /// <summary>
        /// Implements the operator >= (greater than or equal).
        /// </summary>
        /// <param name="left">The left hand side of the operator.</param>
        /// <param name="right">The right hand side of the operator.</param>
        /// <returns><c>true</c> if the left value is greater than or equal to the right value, otherwise <c>false</c>.</returns>
        public static bool operator >=(Duration left, Duration right) =>
            left.days > right.days || (left.days == right.days && left.nanoOfDay >= right.nanoOfDay);

        /// <summary>
        /// Implements the unary negation operator.
        /// </summary>
        /// <param name="duration">Duration to negate</param>
        /// <returns>The negative value of this duration</returns>
        public static Duration operator -(Duration duration)
        {
            int oldDays = duration.days;
            long oldNanoOfDay = duration.nanoOfDay;
            if (oldNanoOfDay == 0)
            {
                return new Duration(-oldDays, 0);
            }
            long newNanoOfDay = NanosecondsPerDay - oldNanoOfDay;
            return new Duration(-oldDays - 1, newNanoOfDay);
        }

        /// <summary>
        /// Implements a friendly alternative to the unary negation operator.
        /// </summary>
        /// <param name="duration">Duration to negate</param>
        /// <returns>The negative value of this duration</returns>
        public static Duration Negate(Duration duration) => -duration;
        #endregion // Operators

        #region IComparable<Duration> Members
        /// <summary>
        /// Compares the current object with another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// A 32-bit signed integer that indicates the relative order of the objects being compared.
        /// The return value has the following meanings:
        /// <list type="table">
        /// <listheader>
        /// <term>Value</term>
        /// <description>Meaning</description>
        /// </listheader>
        /// <item>
        /// <term>< 0</term>
        /// <description>This object is less than the <paramref name="other"/> parameter.</description>
        /// </item>
        /// <item>
        /// <term>0</term>
        /// <description>This object is equal to <paramref name="other"/>.</description>
        /// </item>
        /// <item>
        /// <term>> 0</term>
        /// <description>This object is greater than <paramref name="other"/>.</description>
        /// </item>
        /// </list>
        /// </returns>
        public int CompareTo(Duration other)
        {
            int dayComparison = days.CompareTo(other.days);
            return dayComparison != 0 ? dayComparison : nanoOfDay.CompareTo(other.nanoOfDay);
        }

        /// <summary>
        /// Implementation of <see cref="IComparable.CompareTo"/> to compare two offsets.
        /// </summary>
        /// <remarks>
        /// This uses explicit interface implementation to avoid it being called accidentally. The generic implementation should usually be preferred.
        /// </remarks>
        /// <exception cref="ArgumentException"><paramref name="obj"/> is non-null but does not refer to an instance of <see cref="Duration"/>.</exception>
        /// <param name="obj">The object to compare this value with.</param>
        /// <returns>The result of comparing this instant with another one; see <see cref="CompareTo(NodaTime.Duration)"/> for general details.
        /// If <paramref name="obj"/> is null, this method returns a value greater than 0.
        /// </returns>
        int IComparable.CompareTo(object obj)
        {
            if (obj == null)
            {
                return 1;
            }
            Preconditions.CheckArgument(obj is Duration, nameof(obj), "Object must be of type NodaTime.Duration.");
            return CompareTo((Duration)obj);
        }
        #endregion

        #region IEquatable<Duration> Members
        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// true if the current object is equal to the <paramref name="other"/> parameter;
        /// otherwise, false.
        /// </returns>
        public bool Equals(Duration other) => this == other;
        #endregion

        /// <summary>
        /// Returns a <see cref="Duration"/> that represents the given number of days, assuming a 'standard' 24-hour
        /// day.
        /// </summary>
        /// <param name="days">The number of days.</param>
        /// <returns>A <see cref="Duration"/> representing the given number of days.</returns>
        public static Duration FromDays(int days) => new Duration(days, 0L);

        /// <summary>
        /// Returns a <see cref="Duration"/> that represents the given number of hours.
        /// </summary>
        /// <param name="hours">The number of hours.</param>
        /// <returns>A <see cref="Duration"/> representing the given number of hours.</returns>
        public static Duration FromHours(int hours)
        {
            Preconditions.CheckArgumentRange(
                nameof(hours),
                hours,
                (long)MinDays * HoursPerDay,
                (MaxDays + 1L) * HoursPerDay - 1);
            return OneHour * hours;
        }

        /// <summary>
        /// Returns a <see cref="Duration"/> that represents the given number of minutes.
        /// </summary>
        /// <param name="minutes">The number of minutes.</param>
        /// <returns>A <see cref="Duration"/> representing the given number of minutes.</returns>
        public static Duration FromMinutes(long minutes)
        {
            Preconditions.CheckArgumentRange(
                nameof(minutes),
                minutes,
                (long)MinDays * MinutesPerDay,
                (MaxDays + 1L) * MinutesPerDay - 1);
            return OneMinute * minutes;
        }

        /// <summary>
        /// Returns a <see cref="Duration"/> that represents the given number of seconds.
        /// </summary>
        /// <param name="seconds">The number of seconds.</param>
        /// <returns>A <see cref="Duration"/> representing the given number of seconds.</returns>
        public static Duration FromSeconds(long seconds)
        {
            Preconditions.CheckArgumentRange(
                nameof(seconds),
                seconds,
                (long)MinDays * SecondsPerDay,
                (MaxDays + 1L) * SecondsPerDay - 1);
            return OneSecond * seconds;
        }

        /// <summary>
        /// Returns a <see cref="Duration"/> that represents the given number of milliseconds.
        /// </summary>
        /// <param name="milliseconds">The number of milliseconds.</param>
        /// <returns>A <see cref="Duration"/> representing the given number of milliseconds.</returns>
        public static Duration FromMilliseconds(long milliseconds)
        {
            Preconditions.CheckArgumentRange(
                nameof(milliseconds),
                milliseconds,
                (long)MinDays * MillisecondsPerDay,
                (MaxDays + 1L) * (long)MillisecondsPerDay - 1);
            return OneMillisecond * milliseconds;
        }

        /// <summary>
        /// Returns a <see cref="Duration"/> that represents the given number of ticks.
        /// </summary>
        /// <param name="ticks">The number of ticks.</param>
        /// <returns>A <see cref="Duration"/> representing the given number of ticks.</returns>
        public static Duration FromTicks(long ticks)
        {
            long tickOfDay;
            int days = TickArithmetic.TicksToDaysAndTickOfDay(ticks, out tickOfDay);
            return new Duration(days, tickOfDay * NanosecondsPerTick);
        }

        /// <summary>
        /// Returns a <see cref="Duration"/> that represents the given number of nanoseconds.
        /// </summary>
        /// <param name="nanoseconds">The number of nanoseconds.</param>
        /// <returns>A <see cref="Duration"/> representing the given number of nanoseconds.</returns>
        public static Duration FromNanoseconds(long nanoseconds)
        {
            // TODO: Try DivRem
            int days = nanoseconds >= 0
                ? (int) (nanoseconds / NanosecondsPerDay)
                : (int) ((nanoseconds + 1) / NanosecondsPerDay) - 1;

            long nanoOfDay = nanoseconds >= long.MinValue + NanosecondsPerDay
                ? nanoseconds - days * NanosecondsPerDay
                : nanoseconds - (days + 1) * NanosecondsPerDay + NanosecondsPerDay; // Avoid multiplication overflow
            return new Duration(days, nanoOfDay);
        }

        /// <summary>
        /// Converts a number of nanoseconds expressed as a <see cref="Decimal"/> into a duration.
        /// </summary>
        /// <remarks>Any fractional part of <paramref name="nanoseconds"/> is truncated.</remarks>
        /// <param name="nanoseconds">The number of nanoseconds to represent.</param>
        /// <returns>A duration with the given number of nanoseconds.</returns>
        public static Duration FromNanoseconds(decimal nanoseconds)
        {
            if (nanoseconds < MinNanoseconds || nanoseconds > MaxNanoseconds)
            {
                throw new ArgumentOutOfRangeException(nameof(nanoseconds), $"Value should be in range [{MinNanoseconds}-{MaxNanoseconds}]");
            }
            // Avoid worrying about what happens in later arithmetic.
            nanoseconds = decimal.Truncate(nanoseconds);

            int days = nanoseconds >= 0
                ? (int) (nanoseconds / NanosecondsPerDay)
                : (int) ((nanoseconds + 1) / NanosecondsPerDay) - 1;

            long nanoOfDay = (long) (nanoseconds - ((decimal) days) * NanosecondsPerDay);
            return new Duration(days, nanoOfDay);
        }

        /// <summary>
        /// Returns a <see cref="Duration"/> that represents the same number of ticks as the
        /// given <see cref="TimeSpan"/>.
        /// </summary>
        /// <param name="timeSpan">The TimeSpan value to convert</param>
        /// <returns>A new Duration with the same number of ticks as the given TimeSpan.</returns>
        public static Duration FromTimeSpan(TimeSpan timeSpan)
        {
            return FromTicks(timeSpan.Ticks);
        }

        /// <summary>
        /// Returns a <see cref="TimeSpan"/> that represents the same number of ticks as this
        /// <see cref="Duration"/>.
        /// </summary>
        /// <remarks>
        /// If the number of nanoseconds in a duration is not a whole number of ticks, it is truncated towards zero.
        /// For example, durations in the range [-99ns, 99ns] would all count as 0 ticks.
        /// </remarks>
        /// <exception cref="OverflowException">The number of ticks cannot be represented a signed 64-bit integer.</exception>
        /// <returns>A new TimeSpan with the same number of ticks as this Duration.</returns>
        [Pure]
        public TimeSpan ToTimeSpan() => new TimeSpan(Ticks);

        #region XML serialization
        /// <inheritdoc />
        XmlSchema IXmlSerializable.GetSchema() => null;

        /// <inheritdoc />
        void IXmlSerializable.ReadXml([NotNull] XmlReader reader)
        {
            Preconditions.CheckNotNull(reader, nameof(reader));
            var pattern = DurationPattern.RoundtripPattern;
            string text = reader.ReadElementContentAsString();
            this = pattern.Parse(text).Value;
        }

        /// <inheritdoc />
        void IXmlSerializable.WriteXml([NotNull] XmlWriter writer)
        {
            Preconditions.CheckNotNull(writer, nameof(writer));
            writer.WriteString(DurationPattern.RoundtripPattern.Format(this));
        }
        #endregion

        /// <summary>
        /// Conversion to an <see cref="Int64"/> number of nanoseconds. This will fail if the number of nanoseconds is
        /// out of the range of <c>Int64</c>, which is approximately 292 years (positive or negative).
        /// </summary>
        /// <exception cref="System.OverflowException">The number of nanoseconds is outside the representable range.</exception>
        /// <returns>This duration as a number of nanoseconds, represented as an <c>Int64</c>.</returns>
        [Pure]
        public long ToInt64Nanoseconds()
        {
            if (days < 0)
            {
                if (days >= MinDaysForLongNanos)
                {
                    return unchecked(days * NanosecondsPerDay + nanoOfDay);
                }
                // Need to be careful to avoid overflow in a case where it's actually representable
                return (days + 1) * NanosecondsPerDay + nanoOfDay - NanosecondsPerDay;
            }
            if (days <= MaxDaysForLongNanos)
            {
                return unchecked(days * NanosecondsPerDay + nanoOfDay);
            }
            // Either the multiplication or the addition could overflow, so we do it in a checked context.
            return days * NanosecondsPerDay + nanoOfDay;
        }

        /// <summary>
        /// Conversion to a <see cref="Decimal"/> number of nanoseconds, as a convenient built-in numeric
        /// type which can always represent values in the range we need.
        /// </summary>
        /// <remarks>The value returned is always an integer.</remarks>
        /// <returns>This duration as a number of nanoseconds, represented as a <c>Decimal</c>.</returns>
        [Pure]
        public decimal ToDecimalNanoseconds() => ((decimal)days) * NanosecondsPerDay + nanoOfDay;

#if !PCL
        #region Binary serialization
        private const string DefaultDaysSerializationName = "days";
        private const string DefaultNanosecondOfDaySerializationName = "nanoOfDay";

        /// <summary>
        /// Private constructor only present for serialization.
        /// </summary>
        /// <param name="info">The <see cref="SerializationInfo"/> to fetch data from.</param>
        /// <param name="context">The source for this deserialization.</param>
        private Duration([NotNull] SerializationInfo info, StreamingContext context)
            : this(info, DefaultDaysSerializationName, DefaultNanosecondOfDaySerializationName)
        {
        }

        /// <summary>
        /// Internal constructor used for deserialization, for cases where this is part of
        /// a larger value, but the duration part has been serialized with the default keys.
        /// </summary>
        internal Duration([NotNull] SerializationInfo info)
            : this(info, DefaultDaysSerializationName, DefaultNanosecondOfDaySerializationName)
        {
        }

        /// <summary>
        /// Internal constructor used for deserialization, for cases where the
        /// names in the serialization info aren't the default ones.
        /// </summary>
        internal Duration([NotNull] SerializationInfo info,
            [Trusted] [NotNull] string daysSerializationName, [Trusted] [NotNull] string nanosecondOfDaySerializationName)
        {
            Preconditions.CheckNotNull(info, nameof(info));
            Preconditions.DebugCheckNotNull(daysSerializationName, nameof(daysSerializationName));
            Preconditions.DebugCheckNotNull(nanosecondOfDaySerializationName, nameof(nanosecondOfDaySerializationName));
            days = info.GetInt32(daysSerializationName);
            nanoOfDay = info.GetInt64(nanosecondOfDaySerializationName);
            if (days < MinDays || days > MaxDays)
            {
                throw new ArgumentException("Serialized value contains a 'days' value which is out of range");
            }
            if (nanoOfDay < 0 || nanoOfDay >= NanosecondsPerDay)
            {
                throw new ArgumentException("Serialized value contains a 'nanosecond-of-day' value which is out of range");
            }
        }

        /// <summary>
        /// Implementation of <see cref="ISerializable.GetObjectData"/>.
        /// </summary>
        /// <param name="info">The <see cref="SerializationInfo"/> to populate with data.</param>
        /// <param name="context">The destination for this serialization.</param>
        [System.Security.SecurityCritical]
        void ISerializable.GetObjectData([NotNull] SerializationInfo info, StreamingContext context)
        {
            // FIXME(2.0): Determine serialization policy
            Serialize(info);
        }
        #endregion

        internal void Serialize([NotNull] SerializationInfo info)
        {
            Serialize(info, DefaultDaysSerializationName, DefaultNanosecondOfDaySerializationName);
        }

        internal void Serialize([NotNull] SerializationInfo info,
            [Trusted] [NotNull] string daysSerializationName, [Trusted] [NotNull] string nanosecondOfDaySerializationName)
        {
            Preconditions.CheckNotNull(info, nameof(info));
            Preconditions.DebugCheckNotNull(daysSerializationName, nameof(daysSerializationName));
            Preconditions.DebugCheckNotNull(nanosecondOfDaySerializationName, nameof(nanosecondOfDaySerializationName));
            info.AddValue(daysSerializationName, days);
            info.AddValue(nanosecondOfDaySerializationName, nanoOfDay);
        }
#endif
    }
}

redpajama_set_name: RedPajamaGithub


Need relief NOW from a migraine or headache.
Want help overcoming food sensitivities or intolerances.
We can help improve most health conditions – click to contact us to see if we can help you!
and wellness solutions since 2007.
Natural Pain Solutions is an Australian leader in fast, natural pain relief. The best kind of pain relief is the kind that lasts, and the best way to achieve this is not by suppressing symptoms, but by creating true wellness. This is our specialty.
We combine Naturopathy with Traditional Chinese Medicine and fuse advanced technology with time-tested techniques. We consistently achieve outstanding results for our clients. Keep scrolling down to find out how!
Book online today, or call our friendly staff on 03 9876 8786.
Read independent 5 star reviews from our clients.
We have loads of independent reviews and testimonials on Google and WOMO (Word of Mouth Online)… check them out and decide for yourself!
As of February 2019 we have 51 reviews on WOMO with an average rating of 4.7 stars, and 29 reviews on Google with average of 4.9 stars.
We've also received Customer Service awards from Word of Mouth Online every year since 2012.
Our policy is to use only what works and discard the rest.
But behind all these techniques is one crucial element which is unique to our clinic: the use of scientific clinical testing and expert Chinese Pulse Diagnosis to accurately identify exactly what is going on in your body and why it is sending you signals of pain or ill health.
We believe the best way to permanently relieve pain is to create wellness.
Our Ringwood Naturopath & Acupuncturist, Scott Hankinson, talks about how he gets outstanding results.
These are just the most common health conditions Scott treats. Please contact us if you would like specific information on whether we can treat your health condition or concerns.
Read more about Scott Hankinson here.
Our Naturopathy and Acupuncture clinic is conveniently located in Ringwood, Melbourne's Eastern Suburbs.
Our close proximity to the Eastlink in Ringwood means that Natural Pain Solutions' Acupuncture and Naturopathy services are within reach of most of Melbourne's eastern, north-eastern and south-eastern suburbs. Many of the place names below can be clicked on to see driving directions to our clinic. There's nearly always ample parking right next to our clinic, and we are only a short walk from Ringwood Train Station.


You need to no doubt that the actual best things in life-time are free. If are a skeptic, then simply just just ask the a lot of money of people who work with in free online gaming every day. In the modern day day and age, your entire family can't be too traditionalistic when it comes on to watching your money. Whenever you are like a great number of of us, family promesse are paramount because in the responsibilities each related us has with honor to the care and as well oversight of others.
Maybe it is some sort of wife and children; perhaps, you are caring the elderly parent or people less fortunate than your own self. Whatever the case may be, you are certainly more careful today into spending your money shrewdly than ten years within the past. This is directly attributable to the worldwide country. Since a recession has gripped our global local weather since and it depicts little effort to jump back, thoughtful people which in turn enjoy playing online gambling enterprise games can no for a long time take the chance perform for money frivolously. You don't too risky to participate in playforpay games, such manner in which poker, on a consistent basis.
You need to help at least part of one's discretionary income for a good rainy day. Free modern casino games allow you delight in your favorite pastime, with regard to online poker, and not endanger your savings subscription. The casino gaming sites have made enormous design advancements over the previous decade. There have happen to be marked improvements in visuals and in audio sheduled delivery. Free online poker and several other casino console games have equaled or exceeded their playforpay counterparts here in popularity. Dewapoker88 have another positive half as a draw to gain players the best gambling den sites have a mini seminar page as an illuminating tool for their online players.
The tutorial page is an introduction for beginners into the world including casino games, and fans can review the conventions of each casino online application as well as the dog's best practices. In almost every other words, players looking comprehend how to play cards can review the on-line poker tutorial and understand the rules of the game title and the best processes to use, depending on their unique card hand. Veteran game enthusiasts can use the poker on-line tutorial as a refresher course. Facebook participants which discuss online casino competitions with friends are producing that they play poker on-line and other fine rid casino games in select to perfect new ads and test out select theories of play.


Does skin thinning from Prednisone recover after quitting?
Posted 8 months ago , 8 users are following.
I was only on for a short period of time but the skin all over my body thinned and feels dried up. Will this thicken with time if I quit Prednisone?
I 've been on steroids for several months. My skin is thin too. If i bump my arms i get bleeding under the skin like bruising. Extremely ugly. Didn't think about the steroids causing it.
My skin is llke Irene describes. I have been on Prednisone for several years (lost count) and I get dreadful skin tears if I bump into something which I do often :-( I use Cerave in the thick variety and it helps keep the skin moist.


The Hershey Bears announced today in conjunction with the Washington Capitals that defenseman Tyler Sloan has been assigned by the NHL club.
The announcement was made today by Bears President/GM Doug Yingst.
Sloan, 27, returns to Hershey where he has skated in seven games this season and recorded four assists. He has played in 24 games for Washington this season, and scored his first NHL goal October 25 at Dallas. Sloan is expected to be available when the Bears play the Providence Bruins Friday in New England.
The Bears are in Providence to face the Bruins Friday night at Dunkin Donuts Center. Face-off is at 7:05 p.m. Hershey continues the New England swing Saturday with a game in Hartford against the Wolf Pack and a date with Worcester Sunday afternoon at 4:05 p.m. Hershey's next home game is Friday, January 9 when the Houston Aeros visit GIANT Center for the first time. Tickets are available for the game by calling (717) 534-3911 or visiting the GIANT Center box office.


text:
Home BREAKING NEWS Car rams Times Square pedestrians, kills one, injures others
Car rams Times Square pedestrians, kills one, injures others
First responders are at the scene as people help injured pedestrians after a vehicle struck pedestrians on a sidewalk in Times Square in New York, U.S., May 18, 2017. REUTERS/Jeremy Schultz
NEW YORK – A speeding car crashed into pedestrians on a sidewalk in New York City's busy Times Square on Thursday, killing one person and injuring at least 12, and police said the incident did not appear to be an act of terrorism, witnesses, police and news media said.
A Reuters witness said one person was covered with a bloodstained blanket after the collision, which occurred around noon ET (1600 GMT) at the Midtown Manhattan tourist venue.
Hundreds of thousands of people, many of them visitors from around the world, pass daily through the bustling commercial area, the heart of the Broadway theater district.
The vehicle was a red Honda sedan and CBS New York Television said the driver had been removed. Television footage showed police officers restraining a man in a dark T-shirt and placing him in a police car.
Witnesses said the motorist had driven against traffic and onto the sidewalk, striking pedestrians.
"Everybody was just running, everyone was concerned for their lives," a witness told local CBS television.
The car crashed into a pole and came to rest at 45th Street and Broadway.
Seven people were being placed on stretchers, a Reuters witness said. Shoes were scattered at the scene and one person was covered by a bloodstained blanket, the Reuters witness said.
Previous article$150 billion revenue Indian IT outsourcing business in US has to act fast, or face oblivion
Next articleHouston man sentenced to 10 years for 2013 robbery of Indian-American jewelry store
'Sikhs of New York' create new Guinness world record
Bright lights of Times Square beckon, even on a frigid New Year's Eve
New York charges Times Square bomb suspect; Bangladesh questions wife
Aicon to present 'secular' art exhibition in New York
Penn Masala: Iconic South Asian a-cappella group releasing 11th album
Taliban ready to reduce violence in exchange for peace deal, Pakistan...
Maryland man sentenced for defrauding employer of more than $1 million

redpajama_set_name: RedPajamaCommonCrawl


text:
Ricardo Alberto Córdoba Mosque, more commonly known as Ricardo Cordoba, (born 11 October 1983 in Santa Marta, Panama) is a Panamanian professional boxer who fights in the super bantamweight division.

Professional career
Cordoba turned professional in September 2000. In his debut at the Gimnasio de los Leones, David, Panama, Cordoba defeated fellow debutant Hussein Sanchez with a knockout in the first round.

On September 18, 2008, Cordoba defeated Luis Pérez via twelve-round unanimous decision in Panama City for the vacant WBA Interim Super Bantamweight Title.

Cordoba was promoted to the full-fledge WBA Super Bantamweight champion on November 21, 2008 after fellow-Panamanian Celestino Caballero won an IBF title to become unified champion.

Cordoba lost his WBA title to Irishman Bernard Dunne on March 21, 2009, being knocked out in the 11th (of 12) round.

Cordoba is now an attorney in Panama.

Professional Record

References

External links

|-

1983 births
Living people
People from Bugaba District
World Boxing Association champions
World super-bantamweight boxing champions
Panamanian male boxers

redpajama_set_name: RedPajamaWikipedia


There are few things in life more delicious, satisfying and universally loved than a plate of glistening, slow-cooked rack of ribs.
RIBS is the ultimate collection of the very best recipes, tips and techniques from barbecue aficionado Adam Roberts.
both indoor and outdoor kitchens.


What do you think about/want from the SWJC platform? Let us know!
Thank you all for being a part of the SWJC community. Our product development team has created a short questionnaire to collect user opinions on the game, which you can access by clicking here, or on the link below.
Additionally, there is a second questionnaire regarding the future of the Mirage AR platform, but we require participants to sign an NDA in advance. If you would like to contribute to this second questionnaire, please PM me.
More updates with more foes would be nice.
An update with the training ball that Luke faces on the Falcon in ANH? It would be a great training activity (plonk the holochess set and Chewie and 3PO in the background with a bit of Han and Obi-Wan offering advice?) the atmosphere would be stunning!
And, given the technology is in our hands, surely the good people at Disney can develop other apps that allows us to use our current hardware? Perhaps more story based games? Or re-enact famous fight scenes from the movies? Or a game playing characters from the Dark Side perspective?
Also, it's a pity the saber doesn't come with a stand for the saber to display it on (although I have 3D printed my own).
I'd like to participate in the second questionaire. How do I send you a PM?
While I haven't gotten the multiplayer version to work yet, I would love to see a STORY mode, that combines all the elements created so far.
I'd also love being in an X-Wing, but that might require additional equipment and defeats the easy to use gear.
But STORY mode, yeah, and online VS play.
New Jedi to fight! While the additional engagements are challenging I would like to see some characters from KOTOR or even the expanded universe. Asajj Ventriss would be a good one. Also with the dark side expansion there are many more jedi that are available to face. Mace Windu, Ahsoka Tano, Qui-Gon Jinn and Obi Wan. Perhaps fights against bounty hunters would be interesting. Another thing that would be fun and challenging would be an onslaught mode for the Stormtroopers where you don't just have to pass a few rounds but keep up the fight until you are defeated. Also with dark sie expansion why not fight against clone troopers, resistance troopers, Wookies on Kashyyyk or even Forest rebels and Ewoks on Endor. This would expand the universe and allow for further replayability.
Hi, I would love to participate in the extra survey. I'm a developer and I want to learn more about lenovos plans to open this up to app creatorts. Love the Jedi game and the headset, best consumer AR experience I have seen so far.


text:
Category: Top News
Attribute Text:
Libby Clark was recently named the recipient of the 2019-20 Presser Undergraduate Scholar Award.
Elizabeth (Libby) Clark, a junior music education major, was recently named the recipient of Lee University's 2019-20 Presser Undergraduate Scholar Award.
The Presser Foundation, established by music publisher Theodore Presser, is dedicated solely to the support of music and music education. With its Undergraduate Scholar Award, the Pennsylvania-based foundation recognizes students who demonstrate outstanding accomplishments in music performance at accredited colleges and universities across the country.
Dr. Bill Green presents Libby Clark with the Presser Award.
"It was a great pleasure to present the Presser Award to Libby Clark at our recent Masterworks concert," said Dr. William Green, dean of Lee's School of Music. "Libby is an exceptional student that brings together outstanding scholarly skills with extraordinary talent. She is a musician that is versatile and excels across various styles and genres."
A native of Cleveland, Tennessee, Clark grew up singing and playing the piano. She joined band in middle school, played the French horn, and was part of her high school choir. While at Lee, Clark has been a member of Voices of Lee, Lee Opera Theater, and Choral Union. Recently, Clark won 2nd place at National Association of Teachers of Singing (NATS), a regional vocal competition.
As the 2019-20 Presser Scholar, Clark will receive a cash stipend for her upcoming senior year.
Presser Undergraduate Scholar Awards are distributed to a number of accredited institutions throughout America. Past recipients of Lee University include Danae Bromley (2018), Brittany Martin (2017), Kristiana McCombs (2016), Matthew Kelly (2015), Joey Archer (2014), Erica Tipton (2013), Matthew Wilkinson (2012), Lamprini Lindeman (2011), Christopher Oglesby (2010), Sabbath Ward (2009), Rachael Skidmore (2008), Michael Land (2007), and Brooke Upton (2006).
For more information on Lee's School of Music, call (423) 614-8240.
Clark Named 2019 Presser Scholar
The School of Music will present its annual "Masterworks" concert on Tuesday, April 16.
Masterworks 2018
The Lee University School of Music will present its annual "Masterworks" concert on Tuesday, April 16, at 7:30 p.m. in the Conn Center. This year's program, "Opera's Greatest Hits," will include a variety of arias, ensembles, and choruses. The performance will be conducted by Robert Bernhardt, artist-in-residence at Lee and director of Lee's Symphony Orchestra, along with several of Lee's graduate conducting students.
The concert will feature student and faculty soloists from Opera Theater and will also feature Choral Union, Chorale, and the Symphony Orchestra. The ensembles will perform excerpts from many well-known and popular operas, such as Mozart's "The Magic Flute," Gilbert and Sullivan's "The Mikado," Verdi's "La Traviata," and even the "Bridal Chorus" from Wagner's "Lohengrin."
"I am so delighted to be working with students and faculty in this concert," said Bernhardt. "As a devoted lover of opera and great singing, for me this is a joyful evening of beautiful music among friends. It's intended as much for opera lovers as it is for those who've never been to an opera, and even for those who think they don't like opera. I guarantee that every member of the audience will know the majority of these great melodies, even if they don't know where they came from, and we want it to be fun, informal, and entertaining."
The evening will also include the announcement of Lee University's recipient of the Presser Scholarship, an annual award given to students who demonstrate outstanding accomplishments in music performance at accredited colleges and universities across the country.
Lee University Choral Union is a blend of both music and non-music majors, and it specializes in choral music and major masterworks.
Lee University Chorale is an ensemble of vocalists who are selected by audition. An emphasis is placed on the diversity and breadth of traditional choral literature.
Lee University Opera Theater is an ensemble of vocalists who are selected by audition. They perform one major opera a year, and a selection of opera scenes each semester.
The Symphony Orchestra, an ensemble of select instrumentalists, performs one major concert each semester. Its musicians frequently perform in opera, choral, and other concerts on campus.
Bernhardt joined Lee's School of Music in the fall of 2011. He also serves as music director emeritus and principal pops conductor of the Chattanooga Symphony and Opera (CSO) and principal pops conductor of the Louisville Orchestra and Grand Rapids Symphony. He is a frequent guest conductor for the Boston Pops and the Edmonton Symphony Orchestra.
The concert is free, non-ticketed, and open to the public.
For more information, contact the School of Music at (423) 614-8240 or music@leeuniversity.edu.http://music@leeuniversity.edu
School of Music to Present "Masterworks"
The Collaborative Piano Ensemble will present a piano showcase, Instrumentalabend, on Thursday, April.
Lee University's Collaborative Piano Ensemble will present a piano showcase, Instrumentalabend (Instrumental Evening), on Thursday, April 11, at 4 p.m. in the Squires Recital Hall.
The program will feature diverse compositions by Kreisler, Pilss, Schumann, and Sulek.
The showcase performers include piano students Aidan Hedrick, Soyoung Lim, and Emma Motok, featuring Jesse Crabtree (trombone), Danae Powers (oboe), and Blake Vayda (trumpet). Dr. Josh Holritz, Chattanooga Symphony Orchestra associate concertmaster, will also perform on violin.
The Collaborative Piano Ensemble is a newly founded School of Music ensemble, which aims to encourage young pianists to explore the recently expanded field of collaborative piano arts.
The Squires Recital Hall is located in the Humanities Center on Parker Street.
The event is free and open to the public.
For more information, contact the School of Music at (423) 614-8240.
Collaborative Piano Showcase to Take Place Thursday
Ladies of Lee and the new's Men's Chorale will perform a joint concert on Tuesday, March 26.
On Tuesday, March 26, at 7:30 p.m., Ladies of Lee and the newly established Men's Chorale will perform a joint concert in the Lee University Chapel.
The groups will perform works from a variety of periods, from Renaissance to modern-day. The program will include selections by composers such as Stephen Hatfield, David Hill, Giovanni Pierluigi da Palestrina, Alice Parker, Dolly Parton, Randall Thompson, and Tomás Luis de Victoria.
"I am excited about this joint concert from these two contrasting groups," said Dr. Randy Sheeks, co-director of the Ladies of Lee. "The audience will enjoy two unique sounds – the beautiful treble sound from the Ladies of Lee and the robust male sound of the Men's Chorale. I think these two groups will create a wonderful night of music. For this to be the inaugural performance of the Men's Chorale is an added bonus."
Men's Chorale is Lee's newest choral ensemble and comprises vocal and instrumental music majors and minors. Under the direction of Dr. Joshua Cheney, assistant professor of choral music, Men's Chorale will perform alongside Ladies of Lee.
The Ladies of Lee is directed by Randy and Debbie Sheeks. Randy Sheeks is an associate professor of music and coordinates the music and worship degree program for Lee. Debbie is an adjunct vocal instructor. This husband and wife team began directing the group in the fall of 2018.
The all-female group has enjoyed a thriving history of choral music for over 50 years, performing in churches, schools, and other venues throughout the United States and abroad. Tours include Alaska, Costa Rica, Europe, India, Israel, and Mexico. In 2017, the choir was selected to perform for the Tennessee Music Education Association annual conference. Ladies of Lee performs a wide variety of music including songs of worship, both contemporary and traditional, along with collegiate choral repertoire and patriotic selections.
In addition to conducting Men's Chorale, Cheney directs Choral Union, manages the graduate choral conducting program, and teaches conducting. He is currently a member of the Atlanta-based professional choral ensemble, Coro Vocati.
In addition to directing Ladies of Lee, Randy Sheeks teaches a variety of music and worship courses. While Lee University has had a church music degree for many years, Randy Sheeks led an effort to redesign and rename the degree, which currently has the highest number of students ever enrolled in church music/music and worship at Lee. Prior to his arrival at Lee, Randy and Debbie spent 23 years in local church ministry in churches in Alabama, Georgia, and Ohio.
This event is free, non-ticketed, and open to the public.
For more information, contact the School of Music at (423) 614-8240 or music@leeuniversity.edu.
Men's Chorale and Ladies of Lee to Perform Tuesday
The Small Jazz Ensemble will perform March 25 in the Conn Center.
Small Jazz Ensemble
Lee University's Small Jazz Ensemble will perform on Monday, March 25, at 7:30 p.m. in the Conn Center.
The concert will be divided into two halves, each featuring a different set of students. The first half will led by Dr. Nathan Warner, and the second half will be led by Dr. José Valentino Ruiz.
"Every member of the ensemble has put in 150 percent of the work with the highest level of passion, enthusiasm, dedication, creativity, and collaboration," said Ruiz. " This concert will be the culmination of what I hope will carry on for years to come at Lee University- the glorious unfolding of students' callings as creative expressers of thought through the power of music and worship in the context of jazz and commercial music."
Warner's ensemble will perform works by John Coltrane, Curtis Fuller, Mike Stern, and Sting, as well as a variety of jazz standards. The concert will feature several pieces that Warner arranged specifically for this ensemble.
Ruiz's ensemble will perform works by Johnny Burke, Herbie Hancock, Juan Jose Hernandez, and Bart Howard, among others.
Ruiz is an assistant professor of music business at Lee, where he has been a faculty member since 2016. As a flutist, saxophonist, bassist, and Latin percussionist, Ruiz has performed in over 400 music festivals and with artists such as Chick Corea, Paquito D'Rivera, Alex Acuña, and Jim Walker. He is an Emmy Award winner, a two-time Latin Grammy Award nominee, 49-time DownBeat Music Award recipient, and TEDx Presenter.
Warner, assistant professor of music, joined Lee's faculty in 2014. He regularly performs as a classical, orchestral, commercial, big band, and jazz artist, and has performed with artists such as Doc Severinsen, The Glenn Miller Orchestra, Slide Hampton, and The Temptations. As an advocate for inner-city education, Warner has worked with the Midori and Friends Foundation and the New York Pops Orchestra Outreach Program.
The event is free, non-ticketed, and open to the public.
For more information, contact Lee's School of Music at (423) 614-8240.
Small Jazz Ensemble to Perform Monday in Conn Center
... Next »


Published 04/26/2019 02:10:19 am at 04/26/2019 02:10:19 am in Concrete Couches.
concrete couches hugo sectional rove concepts sandro.
kensington upholstered sofa , furniture store couches bedroom sets dining tables more contemporary concrete end table magnum, stylish modern living room designs in pictures you have to see modern concrete living room with large white sofa in open concept design, diy outdoor sofa that will last a lifetime you can create sofas , sofas ligne roset official site contemporary highend furniture nomadeexpress ligne roset, tilted concrete sofa and coffee table by taylor donsker freshomecom collect this idea tilted concrete sofa and coffee table by taylor donsker, concrete couch center for nonprofit excellence concrete couch, concrete coffee tables you can buy or build yourself , concrete couch community built association kelley with steve,outdoor concrete sofa deckpatio alexander designs outdoor concrete sofa, sofas abc warehouse sofas.


text:
<?php

declare(strict_types=1);

/**
 * This file is part of Narrowspark Framework.
 *
 * (c) Daniel Bannert <d.bannert@anolilab.de>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Viserio\Component\Http\Tests;

use Narrowspark\TestingHelper\Phpunit\MockeryTestCase;
use Nyholm\NSA;
use Throwable;
use Viserio\Component\Http\Stream;
use Viserio\Component\Http\Stream\NoSeekStream;
use Viserio\Contract\Http\Exception\RuntimeException;
use Viserio\Contract\Http\Exception\UnexpectedValueException;

/**
 * @internal
 *
 * @small
 */
final class StreamTest extends MockeryTestCase
{
    /** @var bool */
    public static $isFreadError = false;

    /** @var string */
    private $tmpnam;

    /** @var resource|string pipe stream file handle */
    private $pipeFh;

    /** @var string */
    private $tmpPath;

    /**
     * {@inheritdoc}
     */
    protected function setUp(): void
    {
        parent::setUp();

        /** @var resource $resource */
        $resource = \popen('php StreamTest.php &', 'r');

        $this->pipeFh = $resource;
        $this->tmpPath = __DIR__ . \DIRECTORY_SEPARATOR . 'tmp';

        @\mkdir($this->tmpPath);
    }

    /**
     * {@inheritdoc}
     */
    protected function tearDown(): void
    {
        if (\is_resource($this->pipeFh)) {
            \stream_get_contents($this->pipeFh); // prevent broken pipe error message
            \pclose($this->pipeFh);
        }

        \array_map(static function (string $value): void {
            @\unlink($value);
        }, (array) \glob($this->tmpPath . \DIRECTORY_SEPARATOR . '*', \GLOB_NOSORT));

        @\rmdir($this->tmpPath);
    }

    public function testConstructorThrowsExceptionOnInvalidArgument(): void
    {
        $this->expectException(UnexpectedValueException::class);

        new Stream(true);
    }

    public function testConstructorInitializesProperties(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'r+b');

        \fwrite($handle, 'data');

        $stream = new Stream($handle);

        self::assertTrue($stream->isReadable());
        self::assertTrue($stream->isWritable());
        self::assertTrue($stream->isSeekable());
        self::assertEquals('php://temp', $stream->getMetadata('uri'));
        self::assertIsArray($stream->getMetadata());
        self::assertEquals(4, $stream->getSize());
        self::assertFalse($stream->eof());

        $stream->close();
    }

    public function testStreamClosesHandleOnDestruct(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'rb');

        $stream = new Stream($handle);

        unset($stream);

        self::assertSame('Unknown', \get_resource_type($handle));
    }

    public function testConvertsToString(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'w+b');

        \fwrite($handle, 'data');

        $stream = new Stream($handle);

        self::assertEquals('data', (string) $stream);
        self::assertEquals('data', (string) $stream);

        $stream->close();
    }

    public function testGetsContents(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'w+b');

        \fwrite($handle, 'data');

        $stream = new Stream($handle);

        self::assertEquals('', $stream->getContents());

        $stream->seek(0);

        self::assertEquals('data', $stream->getContents());
        self::assertEquals('', $stream->getContents());

        $stream->close();
    }

    public function testChecksEof(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'w+b');

        \fwrite($handle, 'data');

        $stream = new Stream($handle);

        self::assertSame(4, $stream->tell(), 'Stream cursor already at the end');
        self::assertFalse($stream->eof(), 'Stream still not eof');
        self::assertSame('', $stream->read(1), 'Need to read one more byte to reach eof');
        self::assertTrue($stream->eof());

        $stream->close();
    }

    public function testGetSize(): void
    {
        $size = \filesize(__FILE__);

        /** @var resource $handle */
        $handle = \fopen(__FILE__, 'rb');

        $stream = new Stream($handle);

        self::assertEquals($size, $stream->getSize());
        // Load from cache
        self::assertEquals($size, $stream->getSize());

        $stream->close();
    }

    public function testEnsuresSizeIsConsistent(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'w+b');

        self::assertEquals(3, \fwrite($handle, 'foo'));

        $stream = new Stream($handle);

        self::assertEquals(3, $stream->getSize());
        self::assertEquals(4, $stream->write('test'));
        self::assertEquals(7, $stream->getSize());
        self::assertEquals(7, $stream->getSize());

        $stream->close();
    }

    public function testProvidesStreamPosition(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'w+b');

        $stream = new Stream($handle);

        self::assertEquals(0, $stream->tell());

        $stream->write('foo');

        self::assertEquals(3, $stream->tell());

        $stream->seek(1);

        self::assertEquals(1, $stream->tell());
        self::assertSame(\ftell($handle), $stream->tell());

        $stream->close();
    }

    public function testDetachStreamAndClearProperties(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'rb');

        $stream = new Stream($handle);

        self::assertSame($handle, $stream->detach());
        self::assertIsResource($handle, 'Stream is not closed');
        self::assertNull($stream->detach());
        self::assertStreamStateAfterClosedOrDetached($stream);

        $stream->close();
    }

    public function testCloseResourceAndClearProperties(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'rb');

        $stream = new Stream($handle);
        $stream->close();

        self::assertSame('Unknown', \get_resource_type($handle));
        self::assertStreamStateAfterClosedOrDetached($stream);
    }

    public function testDoesNotThrowInToString(): void
    {
        $body = 'foo';
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'r+b');

        \fwrite($handle, $body);
        \fseek($handle, 0);

        $stream = new NoSeekStream(new Stream($handle));

        self::assertEquals('foo', (string) $stream);
    }

    public function testStreamReadingWithZeroLength(): void
    {
        /** @var resource $handle */
        $handle = \fopen('php://temp', 'rb');

        $stream = new Stream($handle);

        self::assertSame('', $stream->read(0));

        $stream->close();
    }

    public function testStreamReadingWithNegativeLength(): void
    {
        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('Length parameter cannot be negative');

        /** @var resource $handle */
        $handle = \fopen('php://temp', 'rb');
        $stream = new Stream($handle);

        try {
            $stream->read(-1);
        } catch (Throwable $e) {
            $stream->close();

            throw $e;
        }

        $stream->close();
    }

    public function testStreamReadingFreadError(): void
    {
        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('Unable to read from stream');

        self::$isFreadError = true;

        /** @var resource $handle */
        $handle = \fopen('php://temp', 'rb');
        $stream = new Stream($handle);

        try {
            $stream->read(1);
        } catch (Throwable $e) {
            self::$isFreadError = false;

            $stream->close();

            throw $e;
        }

        self::$isFreadError = false;

        $stream->close();
    }

    public function testCanReadContentFromNotSeekableResource(): void
    {
        /** @var string $tmpnam */
        $tmpnam = \tempnam($this->tmpPath, 'diac');

        $this->tmpnam = $tmpnam;

        \file_put_contents($this->tmpnam, 'FOO BAR');

        /** @var resource $resource */
        $resource = \fopen($this->tmpnam, 'rb');

        /** @var \Mockery\MockInterface|Stream $stream */
        $stream = \Mockery::mock(new Stream($resource));
        $stream->shouldReceive('isSeekable')
            ->andReturn(false);

        self::assertEquals('FOO BAR', $stream->__toString());
    }

    /**
     * @dataProvider provideForReadableStreamsCases
     *
     * @param string $mode
     * @param string $func
     * @param bool   $createFile
     *
     * @throws \Exception
     *
     * @return void
     */
    public function testForReadableStreams(string $mode, string $func, bool $createFile = false): void
    {
        $tmpnam = $this->tmpPath . \DIRECTORY_SEPARATOR . ((string) \random_int(100, 999)) . $mode . $func;

        if ($createFile) {
            \touch($tmpnam);
        }

        $stream = new Stream($func($tmpnam, $mode));

        self::assertTrue($stream->isReadable());

        @\unlink($tmpnam);
    }

    /**
     * @return array<int, array<int, bool|string>>
     */
    public static function provideForReadableStreamsCases(): iterable
    {
        return [
            ['r', 'fopen', true],
            ['w+', 'fopen'],
            ['w+b', 'fopen'],
            ['w+b', 'fopen'],
            ['w+t', 'fopen'],
            ['r+', 'fopen', true],
            ['c+', 'fopen'],
            ['cb+', 'fopen'],
            ['c+b', 'fopen'],
            ['c+t', 'fopen'],
            ['rb', 'fopen', true],
            ['r+b', 'fopen', true],
            ['x+', 'fopen'],
            ['x+b', 'fopen'],
            ['xb+', 'fopen'],
            ['x+t', 'fopen'],
            ['rt', 'fopen', true],
            ['r+t', 'fopen', true],
            ['a+', 'fopen'],
            ['a+b', 'fopen'],
            ['ab+', 'fopen'],
            ['a+t', 'fopen'],
            ['r+b', 'fopen', true],
            ['r1', 'gzopen', true],
            ['r2', 'gzopen', true],
            ['r3', 'gzopen', true],
            ['r4', 'gzopen', true],
            ['r5', 'gzopen', true],
            ['r6', 'gzopen', true],
            ['r7', 'gzopen', true],
            ['r8', 'gzopen', true],
            ['r9', 'gzopen', true],
            ['rb1', 'gzopen', true],
            ['rb2', 'gzopen', true],
            ['rb3', 'gzopen', true],
            ['rb4', 'gzopen', true],
            ['rb5', 'gzopen', true],
            ['rb6', 'gzopen', true],
            ['rb7', 'gzopen', true],
            ['rb8', 'gzopen', true],
            ['rb9', 'gzopen', true],
            ['rb1f', 'gzopen', true],
            ['rb2f', 'gzopen', true],
            ['rb3f', 'gzopen', true],
            ['rb4f', 'gzopen', true],
            ['rb5f', 'gzopen', true],
            ['rb6f', 'gzopen', true],
            ['rb7f', 'gzopen', true],
            ['rb8f', 'gzopen', true],
            ['rb9f', 'gzopen', true],
            ['rb1h', 'gzopen', true],
            ['rb2h', 'gzopen', true],
            ['rb3h', 'gzopen', true],
            ['rb4h', 'gzopen', true],
            ['rb5h', 'gzopen', true],
            ['rb6h', 'gzopen', true],
            ['rb7h', 'gzopen', true],
            ['rb8h', 'gzopen', true],
            ['rb9h', 'gzopen', true],
            ['rb1R', 'gzopen', true],
            ['rb2R', 'gzopen', true],
            ['rb3R', 'gzopen', true],
            ['rb4R', 'gzopen', true],
            ['rb5R', 'gzopen', true],
            ['rb6R', 'gzopen', true],
            ['rb7R', 'gzopen', true],
            ['rb8R', 'gzopen', true],
            ['rb9R', 'gzopen', true],
            ['rb1F', 'gzopen', true],
            ['rb2F', 'gzopen', true],
            ['rb3F', 'gzopen', true],
            ['rb4F', 'gzopen', true],
            ['rb5F', 'gzopen', true],
            ['rb6F', 'gzopen', true],
            ['rb7F', 'gzopen', true],
            ['rb8F', 'gzopen', true],
            ['rb9F', 'gzopen', true],
        ];
    }

    /**
     * @dataProvider provideForWritableStreamsCases
     *
     * @param string $mode
     * @param string $func
     * @param bool   $createFile
     *
     * @throws \Exception
     *
     * @return void
     */
    public function testForWritableStreams(string $mode, string $func, bool $createFile = false): void
    {
        $tmpnam = $this->tmpPath . \DIRECTORY_SEPARATOR . ((string) \random_int(100, 999)) . $mode . $func;

        if ($createFile) {
            \touch($tmpnam);
        }

        $stream = new Stream($func($tmpnam, $mode));

        self::assertTrue($stream->isWritable());

        if ($createFile && \file_exists($tmpnam)) {
            @\unlink($tmpnam);
        }
    }

    /**
     * @return array<int, array<int, bool|string>>
     */
    public static function provideForWritableStreamsCases(): iterable
    {
        return [
            ['w', 'fopen'],
            ['w+', 'fopen'],
            ['rw', 'fopen', true],
            ['r+', 'fopen', true],
            ['x', 'fopen'],
            ['x+', 'fopen'],
            ['c', 'fopen'],
            ['c+', 'fopen'],
            ['wb', 'fopen'],
            ['w+b', 'fopen'],
            ['r+b', 'fopen', true],
            ['x+b', 'fopen'],
            ['c+b', 'fopen'],
            ['w+t', 'fopen'],
            ['r+t', 'fopen', true],
            ['x+t', 'fopen'],
            ['c+', 'fopen'],
            ['a', 'fopen'],
            ['a+', 'fopen'],
            ['a+b', 'fopen'],
            ['ab', 'fopen'],
            ['ab+', 'fopen'],
            ['w1', 'gzopen'],
            ['w2', 'gzopen'],
            ['w3', 'gzopen'],
            ['w4', 'gzopen'],
            ['w5', 'gzopen'],
            ['w6', 'gzopen'],
            ['w7', 'gzopen'],
            ['w8', 'gzopen'],
            ['w9', 'gzopen'],
            ['wb1', 'gzopen'],
            ['wb2', 'gzopen'],
            ['wb3', 'gzopen'],
            ['wb4', 'gzopen'],
            ['wb5', 'gzopen'],
            ['wb6', 'gzopen'],
            ['wb7', 'gzopen'],
            ['wb8', 'gzopen'],
            ['wb9', 'gzopen'],
            ['wb1f', 'gzopen'],
            ['wb2f', 'gzopen'],
            ['wb3f', 'gzopen'],
            ['wb4f', 'gzopen'],
            ['wb5f', 'gzopen'],
            ['wb6f', 'gzopen'],
            ['wb7f', 'gzopen'],
            ['wb8f', 'gzopen'],
            ['wb9f', 'gzopen'],
            ['wb1h', 'gzopen'],
            ['wb2h', 'gzopen'],
            ['wb3h', 'gzopen'],
            ['wb4h', 'gzopen'],
            ['wb5h', 'gzopen'],
            ['wb6h', 'gzopen'],
            ['wb7h', 'gzopen'],
            ['wb8h', 'gzopen'],
            ['wb9h', 'gzopen'],
            ['wb1R', 'gzopen'],
            ['wb2R', 'gzopen'],
            ['wb3R', 'gzopen'],
            ['wb4R', 'gzopen'],
            ['wb5R', 'gzopen'],
            ['wb6R', 'gzopen'],
            ['wb7R', 'gzopen'],
            ['wb8R', 'gzopen'],
            ['wb9R', 'gzopen'],
            ['wb1F', 'gzopen'],
            ['wb2F', 'gzopen'],
            ['wb3F', 'gzopen'],
            ['wb4F', 'gzopen'],
            ['wb5F', 'gzopen'],
            ['wb6F', 'gzopen'],
            ['wb7F', 'gzopen'],
            ['wb8F', 'gzopen'],
            ['wb9F', 'gzopen'],
        ];
    }

    public function testIsPipe(): void
    {
        $stream = new Stream($this->pipeFh);

        self::assertTrue(NSA::invokeMethod($stream, 'isPipe'));

        $stream->detach();

        self::assertFalse(NSA::invokeMethod($stream, 'isPipe'));

        /** @var resource $handler */
        $handler = \fopen(__FILE__, 'r');

        $fileStream = new Stream($handler);

        self::assertFalse(NSA::invokeMethod($fileStream, 'isPipe'));
    }

    public function testIsPipeReadable(): void
    {
        $stream = new Stream($this->pipeFh);

        self::assertTrue($stream->isReadable());
    }

    public function testPipeIsNotSeekable(): void
    {
        $stream = new Stream($this->pipeFh);

        self::assertFalse($stream->isSeekable());
    }

    public function testCannotSeekPipe(): void
    {
        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('Stream is not seekable.');

        $stream = new Stream($this->pipeFh);

        $stream->seek(0);
    }

    public function testCannotTellPipe(): void
    {
        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('Unable to determine stream position.');

        $stream = new Stream($this->pipeFh);

        $stream->tell();
    }

    public function testCannotRewindPipe(): void
    {
        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('Stream is not seekable.');

        $stream = new Stream($this->pipeFh);

        $stream->rewind();
    }

    public function testPipeGetSizeYieldsNull(): void
    {
        $stream = new Stream($this->pipeFh);

        self::assertNull($stream->getSize());
    }

    public function testClosePipe(): void
    {
        /** @var resource $handler */
        $handler = $this->pipeFh;

        $stream = new Stream($handler);

        \stream_get_contents($handler); // prevent broken pipe error message

        $stream->close();

        $handler = null;

        self::assertFalse(NSA::invokeMethod($stream, 'isPipe'));
    }

    public function testPipeToString(): void
    {
        $stream = new Stream($this->pipeFh);

        self::assertSame("Could not open input file: StreamTest.php\n", $stream->__toString());
    }

    public function testPipeGetContents(): void
    {
        $stream = new Stream($this->pipeFh);

        $contents = \trim($stream->getContents());

        self::assertSame('Could not open input file: StreamTest.php', $contents);
    }

    public function testConvertsToStringNonSeekableStream(): void
    {
        $handle = \popen('echo foo', 'r');
        $stream = new Stream($handle);

        self::assertFalse($stream->isSeekable());
        self::assertSame('foo', \trim((string) $stream));
    }

    public function testConvertsToStringNonSeekablePartiallyReadStream(): void
    {
        $handle = \popen('echo bar', 'r');
        $stream = new Stream($handle);
        $firstLetter = $stream->read(1);

        self::assertFalse($stream->isSeekable());
        self::assertSame('b', $firstLetter);
        self::assertSame('ar', \trim((string) $stream));
    }

    /**
     * @param Stream $stream
     */
    private static function assertStreamStateAfterClosedOrDetached(Stream $stream): void
    {
        self::assertFalse($stream->isReadable());
        self::assertFalse($stream->isWritable());
        self::assertFalse($stream->isSeekable());
        self::assertNull($stream->getSize());
        self::assertSame([], $stream->getMetadata());
        self::assertNull($stream->getMetadata('foo'));

        $throws = static function (callable $fn): void {
            try {
                $fn();
            } catch (Throwable $e) {
                self::assertStringContainsString('Stream is detached', $e->getMessage());

                return;
            }

            self::fail('Exception should be thrown after the stream is detached.');
        };
        $throws(static function () use ($stream): void {
            $stream->read(10);
        });
        $throws(static function () use ($stream): void {
            $stream->write('bar');
        });
        $throws(static function () use ($stream): void {
            $stream->seek(10);
        });
        $throws(static function () use ($stream): void {
            $stream->tell();
        });
        $throws(static function () use ($stream): void {
            $stream->eof();
        });
        $throws(static function () use ($stream): void {
            $stream->getContents();
        });

        \set_error_handler(static function (int $errno, string $errstr): bool {
            if ($errno === \E_USER_ERROR) {
                self::assertStringContainsString('::__toString exception: ', $errstr);

                return true;
            }

            return false;
        });

        self::assertSame('', (string) $stream);

        \restore_error_handler();
    }
}

namespace Viserio\Component\Http;

use Viserio\Component\Http\Tests\StreamTest;

/**
 * @param resource $handle
 * @param int      $length
 *
 * @return false|string
 */
function fread($handle, int $length)
{
    return StreamTest::$isFreadError ? false : \fread($handle, $length);
}


text:
Tag Archives: mafia 3 guides
All Endings in Mafia 3
Mafia 3 has several endings. Which one you'll get depends on a choice you make in one of the final missions. Most of them are…
I Need A Favor Side Mission
I Need A Favor is one of the side missions in Mafia 3. It is given out by Vito Scaletta – your underboss and the…
Secrets & Easter Eggs
While playing Mafia 3, you'll come across a bunch of secrets. The town of New Bordeaux is fairly large, and it's peppered with easter eggs,…
Underboss Loyalty in Mafia 3 – How to get it
Underboss Loyalty status is the final stage of a relationship with a lieutenant in Mafia 3. It can be achieved later on in the game,…
Best Weapon Loadouts
Weapon loadouts are combinations of two guns in Mafia 3. The best weapon combos are made up of guns that complement each other. For example,…
.45 In My Hand Side Mission
.45 In My Hand is a side mission in Mafia 3. It's the one given out by Cassandra, in Delray Hollow. It involves doing tasks…
Silenced Pistol / Gun in Mafia 3 – How to get
Mafia 3 Silenced Pistol is any gun with a silencer you find in the game. Their main advantage is that they let you shoot people…
Are We Cool Side Mission
Are We Cool is a side mission in Mafia 3. You can start it by talking to Emmanuel Lazare, Cassandra's associate. He's going to ask…
How to Get Car Back
Getting a car back in Mafia 3 can be tricky. Not all cars can be retrieved, and those that can require you to make use…
How to Assign Districts
Assigning districts in Mafia 3 will let them start generating revenue. It will also push the story forward, getting you closer to taking down the…
How to collect money from rackets
Mafia 3 rackets are places that constantly generate revenue while you play. All you need to do is pick it up from time to time…
How to unlock preorder bonus in Mafia 3
Mafia 3 preorder bonus includes the Family Kick-Back pack. It's a modest offering – three exclusive weapons and three cars. Everyone who bought the game…
IRA Don't Ask – Burke Side Mission
IRA Don't Ask is a side mission in Mafia 3. It is given out by Burke, the Irish underboss. It involves finding and stealing vehicles…
How to unlock side missions
Mafia 3 side missions are optional tasks you can do in order to help your underbosses. Each one of your lieutenants will have their own…
Errors & Problems in Mafia 3
Mafia 3 is out, and the PC version has had a troublesome start. Players are already complaining about crashes, poor performance and other issues. Some…
Underboss Perks & Upgrades
Mafia 3 Underbosses are your loyal lieutenants who can run daily operations in captured districts instead of you. Once you conquer an area, you'll get…
Controls List
Mafia 3 is out, and it allows you to be the vengeful murderer you always wanted to be. It lets you to drive across a…
Mafia 3 30 FPS Lock – How to fix it
Mafia 3 isn't officialy out yet, but some streamers and members of the press have received early copies. While they're slowly trudging through the game…
Robbing Stores in Mafia 3
Robbing Stores is one of the activities you can do while taking a break from the main missions in Mafia 3. It's a profitable way…
Mafia 3 takes place in a huge city. Getting to places requires lots of driving. Since you'll be spending a big chunk of your time…
PREVIOUS POSTFight Club Activity
NEXT POSTFFXV Death Spell Trailer