/*!

 * Time picker for pickadate.js v3.5.6

 * http://amsul.github.io/pickadate.js/time.htm

 */



(function ( factory ) {



    // AMD.

    if ( typeof define == 'function' && define.amd )

        define( ['picker', 'jquery'], factory )



    // Node.js/browserify.

    else if ( typeof exports == 'object' )

        module.exports = factory( require('./picker.js'), require('jquery') )



    // Browser globals.

    else factory( Picker, jQuery )



}(function( Picker, $ ) {





/**

 * Globals and constants

 */

var HOURS_IN_DAY = 24,

    MINUTES_IN_HOUR = 60,

    HOURS_TO_NOON = 12,

    MINUTES_IN_DAY = HOURS_IN_DAY * MINUTES_IN_HOUR,

    _ = Picker._







/**

 * The time picker constructor

 */

function TimePicker( picker, settings ) {



    var clock = this,

        elementValue = picker.$node[ 0 ].value,

        elementDataValue = picker.$node.data( 'value' ),

        valueString = elementDataValue || elementValue,

        formatString = elementDataValue ? settings.formatSubmit : settings.format



    clock.settings = settings

    clock.$node = picker.$node



    // The queue of methods that will be used to build item objects.

    clock.queue = {

        interval: 'i',

        min: 'measure create',

        max: 'measure create',

        now: 'now create',

        select: 'parse create validate',

        highlight: 'parse create validate',

        view: 'parse create validate',

        disable: 'deactivate',

        enable: 'activate'

    }



    // The component's item object.

    clock.item = {}



    clock.item.clear = null

    clock.item.interval = settings.interval || 30

    clock.item.disable = ( settings.disable || [] ).slice( 0 )

    clock.item.enable = -(function( collectionDisabled ) {

        return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1

    })( clock.item.disable )



    clock.

        set( 'min', settings.min ).

        set( 'max', settings.max ).

        set( 'now' )



    // When there’s a value, set the `select`, which in turn

    // also sets the `highlight` and `view`.

    if ( valueString ) {

        clock.set( 'select', valueString, {

            format: formatString

        })

    }



    // If there’s no value, default to highlighting “today”.

    else {

        clock.

            set( 'select', null ).

            set( 'highlight', clock.item.now )

    }



    // The keycode to movement mapping.

    clock.key = {

        40: 1, // Down

        38: -1, // Up

        39: 1, // Right

        37: -1, // Left

        go: function( timeChange ) {

            clock.set(

                'highlight',

                clock.item.highlight.pick + timeChange * clock.item.interval,

                { interval: timeChange * clock.item.interval }

            )

            this.render()

        }

    }





    // Bind some picker events.

    picker.

        on( 'render', function() {

            var $pickerHolder = picker.$root.children(),

                $viewset = $pickerHolder.find( '.' + settings.klass.viewset ),

                vendors = function( prop ) {

                    return ['webkit', 'moz', 'ms', 'o', ''].map(function( vendor ) {

                        return ( vendor ? '-' + vendor + '-' : '' ) + prop

                    })

                },

                animations = function( $el, state ) {

                    vendors( 'transform' ).map(function( prop ) {

                        $el.css( prop, state )

                    })

                    vendors( 'transition' ).map(function( prop ) {

                        $el.css( prop, state )

                    })

                }

            if ( $viewset.length ) {

                animations( $pickerHolder, 'none' )

                $pickerHolder[ 0 ].scrollTop = ~~$viewset.position().top - ( $viewset[ 0 ].clientHeight * 2 )

                animations( $pickerHolder, '' )

            }

        }, 1 ).

        on( 'open', function() {

            picker.$root.find( 'button' ).attr( 'disabled', false )

        }, 1 ).

        on( 'close', function() {

            picker.$root.find( 'button' ).attr( 'disabled', true )

        }, 1 )



} //TimePicker





/**

 * Set a timepicker item object.

 */

TimePicker.prototype.set = function( type, value, options ) {



    var clock = this,

        clockItem = clock.item



    // If the value is `null` just set it immediately.

    if ( value === null ) {

        if ( type == 'clear' ) type = 'select'

        clockItem[ type ] = value

        return clock

    }



    // Otherwise go through the queue of methods, and invoke the functions.

    // Update this as the time unit, and set the final value as this item.

    // * In the case of `enable`, keep the queue but set `disable` instead.

    //   And in the case of `flip`, keep the queue but set `enable` instead.

    clockItem[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = clock.queue[ type ].split( ' ' ).map( function( method ) {

        value = clock[ method ]( type, value, options )

        return value

    }).pop()



    // Check if we need to cascade through more updates.

    if ( type == 'select' ) {

        clock.set( 'highlight', clockItem.select, options )

    }

    else if ( type == 'highlight' ) {

        clock.set( 'view', clockItem.highlight, options )

    }

    else if ( type == 'interval' ) {

        clock.

            set( 'min', clockItem.min, options ).

            set( 'max', clockItem.max, options )

    }

    else if ( type.match( /^(flip|min|max|disable|enable)$/ ) ) {

        if ( clockItem.select && clock.disabled( clockItem.select ) ) {

            clock.set( 'select', value, options )

        }

        if ( clockItem.highlight && clock.disabled( clockItem.highlight ) ) {

            clock.set( 'highlight', value, options )

        }

        if ( type == 'min' ) {

            clock.set( 'max', clockItem.max, options )

        }

    }



    return clock

} //TimePicker.prototype.set





/**

 * Get a timepicker item object.

 */

TimePicker.prototype.get = function( type ) {

    return this.item[ type ]

} //TimePicker.prototype.get





/**

 * Create a picker time object.

 */

TimePicker.prototype.create = function( type, value, options ) {



    var clock = this



    // If there’s no value, use the type as the value.

    value = value === undefined ? type : value



    // If it’s a date object, convert it into an array.

    if ( _.isDate( value ) ) {

        value = [ value.getHours(), value.getMinutes() ]

    }



    // If it’s an object, use the “pick” value.

    if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {

        value = value.pick

    }



    // If it’s an array, convert it into minutes.

    else if ( $.isArray( value ) ) {

        value = +value[ 0 ] * MINUTES_IN_HOUR + (+value[ 1 ])

    }



    // If no valid value is passed, set it to “now”.

    else if ( !_.isInteger( value ) ) {

        value = clock.now( type, value, options )

    }



    // If we’re setting the max, make sure it’s greater than the min.

    if ( type == 'max' && value < clock.item.min.pick ) {

        value += MINUTES_IN_DAY

    }



    // If the value doesn’t fall directly on the interval,

    // add one interval to indicate it as “passed”.

    if ( type != 'min' && type != 'max' && (value - clock.item.min.pick) % clock.item.interval !== 0 ) {

        value += clock.item.interval

    }



    // Normalize it into a “reachable” interval.

    value = clock.normalize( type, value, options )



    // Return the compiled object.

    return {



        // Divide to get hours from minutes.

        hour: ~~( HOURS_IN_DAY + value / MINUTES_IN_HOUR ) % HOURS_IN_DAY,



        // The remainder is the minutes.

        mins: ( MINUTES_IN_HOUR + value % MINUTES_IN_HOUR ) % MINUTES_IN_HOUR,



        // The time in total minutes.

        time: ( MINUTES_IN_DAY + value ) % MINUTES_IN_DAY,



        // Reference to the “relative” value to pick.

        pick: value % MINUTES_IN_DAY

    }

} //TimePicker.prototype.create





/**

 * Create a range limit object using an array, date object,

 * literal “true”, or integer relative to another time.

 */

TimePicker.prototype.createRange = function( from, to ) {



    var clock = this,

        createTime = function( time ) {

            if ( time === true || $.isArray( time ) || _.isDate( time ) ) {

                return clock.create( time )

            }

            return time

        }



    // Create objects if possible.

    if ( !_.isInteger( from ) ) {

        from = createTime( from )

    }

    if ( !_.isInteger( to ) ) {

        to = createTime( to )

    }



    // Create relative times.

    if ( _.isInteger( from ) && $.isPlainObject( to ) ) {

        from = [ to.hour, to.mins + ( from * clock.settings.interval ) ];

    }

    else if ( _.isInteger( to ) && $.isPlainObject( from ) ) {

        to = [ from.hour, from.mins + ( to * clock.settings.interval ) ];

    }



    return {

        from: createTime( from ),

        to: createTime( to )

    }

} //TimePicker.prototype.createRange





/**

 * Check if a time unit falls within a time range object.

 */

TimePicker.prototype.withinRange = function( range, timeUnit ) {

    range = this.createRange(range.from, range.to)

    return timeUnit.pick >= range.from.pick && timeUnit.pick <= range.to.pick

}





/**

 * Check if two time range objects overlap.

 */

TimePicker.prototype.overlapRanges = function( one, two ) {



    var clock = this



    // Convert the ranges into comparable times.

    one = clock.createRange( one.from, one.to )

    two = clock.createRange( two.from, two.to )



    return clock.withinRange( one, two.from ) || clock.withinRange( one, two.to ) ||

        clock.withinRange( two, one.from ) || clock.withinRange( two, one.to )

}





/**

 * Get the time relative to now.

 */

TimePicker.prototype.now = function( type, value/*, options*/ ) {



    var interval = this.item.interval,

        date = new Date(),

        nowMinutes = date.getHours() * MINUTES_IN_HOUR + date.getMinutes(),

        isValueInteger = _.isInteger( value ),

        isBelowInterval



    // Make sure “now” falls within the interval range.

    nowMinutes -= nowMinutes % interval



    // Check if the difference is less than the interval itself.

    isBelowInterval = value < 0 && interval * value + nowMinutes <= -interval



    // Add an interval because the time has “passed”.

    nowMinutes += type == 'min' && isBelowInterval ? 0 : interval



    // If the value is a number, adjust by that many intervals.

    if ( isValueInteger ) {

        nowMinutes += interval * (

            isBelowInterval && type != 'max' ?

                value + 1 :

                value

            )

    }



    // Return the final calculation.

    return nowMinutes

} //TimePicker.prototype.now





/**

 * Normalize minutes to be “reachable” based on the min and interval.

 */

TimePicker.prototype.normalize = function( type, value/*, options*/ ) {



    var interval = this.item.interval,

        minTime = this.item.min && this.item.min.pick || 0



    // If setting min time, don’t shift anything.

    // Otherwise get the value and min difference and then

    // normalize the difference with the interval.

    value -= type == 'min' ? 0 : ( value - minTime ) % interval



    // Return the adjusted value.

    return value

} //TimePicker.prototype.normalize





/**

 * Measure the range of minutes.

 */

TimePicker.prototype.measure = function( type, value, options ) {



    var clock = this



    // If it’s anything false-y, set it to the default.

    if ( !value ) {

        value = type == 'min' ? [ 0, 0 ] : [ HOURS_IN_DAY - 1, MINUTES_IN_HOUR - 1 ]

    }



    // If it’s a string, parse it.

    if ( typeof value == 'string' ) {

        value = clock.parse( type, value )

    }



    // If it’s a literal true, or an integer, make it relative to now.

    else if ( value === true || _.isInteger( value ) ) {

        value = clock.now( type, value, options )

    }



    // If it’s an object already, just normalize it.

    else if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {

        value = clock.normalize( type, value.pick, options )

    }



    return value

} ///TimePicker.prototype.measure





/**

 * Validate an object as enabled.

 */

TimePicker.prototype.validate = function( type, timeObject, options ) {



    var clock = this,

        interval = options && options.interval ? options.interval : clock.item.interval



    // Check if the object is disabled.

    if ( clock.disabled( timeObject ) ) {



        // Shift with the interval until we reach an enabled time.

        timeObject = clock.shift( timeObject, interval )

    }



    // Scope the object into range.

    timeObject = clock.scope( timeObject )



    // Do a second check to see if we landed on a disabled min/max.

    // In that case, shift using the opposite interval as before.

    if ( clock.disabled( timeObject ) ) {

        timeObject = clock.shift( timeObject, interval * -1 )

    }



    // Return the final object.

    return timeObject

} //TimePicker.prototype.validate





/**

 * Check if an object is disabled.

 */

TimePicker.prototype.disabled = function( timeToVerify ) {



    var clock = this,



        // Filter through the disabled times to check if this is one.

        isDisabledMatch = clock.item.disable.filter( function( timeToDisable ) {



            // If the time is a number, match the hours.

            if ( _.isInteger( timeToDisable ) ) {

                return timeToVerify.hour == timeToDisable

            }



            // If it’s an array, create the object and match the times.

            if ( $.isArray( timeToDisable ) || _.isDate( timeToDisable ) ) {

                return timeToVerify.pick == clock.create( timeToDisable ).pick

            }



            // If it’s an object, match a time within the “from” and “to” range.

            if ( $.isPlainObject( timeToDisable ) ) {

                return clock.withinRange( timeToDisable, timeToVerify )

            }

        })



    // If this time matches a disabled time, confirm it’s not inverted.

    isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function( timeToDisable ) {

        return $.isArray( timeToDisable ) && timeToDisable[2] == 'inverted' ||

            $.isPlainObject( timeToDisable ) && timeToDisable.inverted

    }).length



    // If the clock is "enabled" flag is flipped, flip the condition.

    return clock.item.enable === -1 ? !isDisabledMatch : isDisabledMatch ||

        timeToVerify.pick < clock.item.min.pick ||

        timeToVerify.pick > clock.item.max.pick

} //TimePicker.prototype.disabled





/**

 * Shift an object by an interval until we reach an enabled object.

 */

TimePicker.prototype.shift = function( timeObject, interval ) {



    var clock = this,

        minLimit = clock.item.min.pick,

        maxLimit = clock.item.max.pick/*,

        safety = 1000*/



    interval = interval || clock.item.interval



    // Keep looping as long as the time is disabled.

    while ( /*safety &&*/ clock.disabled( timeObject ) ) {



        /*safety -= 1

        if ( !safety ) {

            throw 'Fell into an infinite loop while shifting to ' + timeObject.hour + ':' + timeObject.mins + '.'

        }*/



        // Increase/decrease the time by the interval and keep looping.

        timeObject = clock.create( timeObject.pick += interval )



        // If we've looped beyond the limits, break out of the loop.

        if ( timeObject.pick <= minLimit || timeObject.pick >= maxLimit ) {

            break

        }

    }



    // Return the final object.

    return timeObject

} //TimePicker.prototype.shift





/**

 * Scope an object to be within range of min and max.

 */

TimePicker.prototype.scope = function( timeObject ) {

    var minLimit = this.item.min.pick,

        maxLimit = this.item.max.pick

    return this.create( timeObject.pick > maxLimit ? maxLimit : timeObject.pick < minLimit ? minLimit : timeObject )

} //TimePicker.prototype.scope





/**

 * Parse a string into a usable type.

 */

TimePicker.prototype.parse = function( type, value, options ) {



    var hour, minutes, isPM, item, parseValue,

        clock = this,

        parsingObject = {}



    // If it’s already parsed, we’re good.

    if ( !value || typeof value != 'string' ) {

        return value

    }



    // We need a `.format` to parse the value with.

    if ( !( options && options.format ) ) {

        options = options || {}

        options.format = clock.settings.format

    }



    // Convert the format into an array and then map through it.

    clock.formats.toArray( options.format ).map( function( label ) {



        var

            substring,



            // Grab the formatting label.

            formattingLabel = clock.formats[ label ],



            // The format length is from the formatting label function or the

            // label length without the escaping exclamation (!) mark.

            formatLength = formattingLabel ?

                _.trigger( formattingLabel, clock, [ value, parsingObject ] ) :

                label.replace( /^!/, '' ).length



        // If there's a format label, split the value up to the format length.

        // Then add it to the parsing object with appropriate label.

        if ( formattingLabel ) {

            substring = value.substr( 0, formatLength )

            parsingObject[ label ] = substring.match(/^\d+$/) ? +substring : substring

        }



        // Update the time value as the substring from format length to end.

        value = value.substr( formatLength )

    })



    // Grab the hour and minutes from the parsing object.

    for ( item in parsingObject ) {

        parseValue = parsingObject[item]

        if ( _.isInteger(parseValue) ) {

            if ( item.match(/^(h|hh)$/i) ) {

                hour = parseValue

                if ( item == 'h' || item == 'hh' ) {

                    hour %= 12

                }

            }

            else if ( item == 'i' ) {

                minutes = parseValue

            }

        }

        else if ( item.match(/^a$/i) && parseValue.match(/^p/i) && ('h' in parsingObject || 'hh' in parsingObject) ) {

            isPM = true

        }

    }



    // Calculate it in minutes and return.

    return (isPM ? hour + 12 : hour) * MINUTES_IN_HOUR + minutes

} //TimePicker.prototype.parse





/**

 * Various formats to display the object in.

 */

TimePicker.prototype.formats = {



    h: function( string, timeObject ) {



        // If there's string, then get the digits length.

        // Otherwise return the selected hour in "standard" format.

        return string ? _.digits( string ) : timeObject.hour % HOURS_TO_NOON || HOURS_TO_NOON

    },

    hh: function( string, timeObject ) {



        // If there's a string, then the length is always 2.

        // Otherwise return the selected hour in "standard" format with a leading zero.

        return string ? 2 : _.lead( timeObject.hour % HOURS_TO_NOON || HOURS_TO_NOON )

    },

    H: function( string, timeObject ) {



        // If there's string, then get the digits length.

        // Otherwise return the selected hour in "military" format as a string.

        return string ? _.digits( string ) : '' + ( timeObject.hour % 24 )

    },

    HH: function( string, timeObject ) {



        // If there's string, then get the digits length.

        // Otherwise return the selected hour in "military" format with a leading zero.

        return string ? _.digits( string ) : _.lead( timeObject.hour % 24 )

    },

    i: function( string, timeObject ) {



        // If there's a string, then the length is always 2.

        // Otherwise return the selected minutes.

        return string ? 2 : _.lead( timeObject.mins )

    },

    a: function( string, timeObject ) {



        // If there's a string, then the length is always 4.

        // Otherwise check if it's more than "noon" and return either am/pm.

        return string ? 4 : MINUTES_IN_DAY / 2 > timeObject.time % MINUTES_IN_DAY ? 'a.m.' : 'p.m.'

    },

    A: function( string, timeObject ) {



        // If there's a string, then the length is always 2.

        // Otherwise check if it's more than "noon" and return either am/pm.

        return string ? 2 : MINUTES_IN_DAY / 2 > timeObject.time % MINUTES_IN_DAY ? 'AM' : 'PM'

    },



    // Create an array by splitting the formatting string passed.

    toArray: function( formatString ) { return formatString.split( /(h{1,2}|H{1,2}|i|a|A|!.)/g ) },



    // Format an object into a string using the formatting options.

    toString: function ( formatString, itemObject ) {

        var clock = this

        return clock.formats.toArray( formatString ).map( function( label ) {

            return _.trigger( clock.formats[ label ], clock, [ 0, itemObject ] ) || label.replace( /^!/, '' )

        }).join( '' )

    }

} //TimePicker.prototype.formats









/**

 * Check if two time units are the exact.

 */

TimePicker.prototype.isTimeExact = function( one, two ) {



    var clock = this



    // When we’re working with minutes, do a direct comparison.

    if (

        ( _.isInteger( one ) && _.isInteger( two ) ) ||

        ( typeof one == 'boolean' && typeof two == 'boolean' )

     ) {

        return one === two

    }



    // When we’re working with time representations, compare the “pick” value.

    if (

        ( _.isDate( one ) || $.isArray( one ) ) &&

        ( _.isDate( two ) || $.isArray( two ) )

    ) {

        return clock.create( one ).pick === clock.create( two ).pick

    }



    // When we’re working with range objects, compare the “from” and “to”.

    if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {

        return clock.isTimeExact( one.from, two.from ) && clock.isTimeExact( one.to, two.to )

    }



    return false

}





/**

 * Check if two time units overlap.

 */

TimePicker.prototype.isTimeOverlap = function( one, two ) {



    var clock = this



    // When we’re working with an integer, compare the hours.

    if ( _.isInteger( one ) && ( _.isDate( two ) || $.isArray( two ) ) ) {

        return one === clock.create( two ).hour

    }

    if ( _.isInteger( two ) && ( _.isDate( one ) || $.isArray( one ) ) ) {

        return two === clock.create( one ).hour

    }



    // When we’re working with range objects, check if the ranges overlap.

    if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {

        return clock.overlapRanges( one, two )

    }



    return false

}





/**

 * Flip the “enabled” state.

 */

TimePicker.prototype.flipEnable = function(val) {

    var itemObject = this.item

    itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1)

}





/**

 * Mark a collection of times as “disabled”.

 */

TimePicker.prototype.deactivate = function( type, timesToDisable ) {



    var clock = this,

        disabledItems = clock.item.disable.slice(0)





    // If we’re flipping, that’s all we need to do.

    if ( timesToDisable == 'flip' ) {

        clock.flipEnable()

    }



    else if ( timesToDisable === false ) {

        clock.flipEnable(1)

        disabledItems = []

    }



    else if ( timesToDisable === true ) {

        clock.flipEnable(-1)

        disabledItems = []

    }



    // Otherwise go through the times to disable.

    else {



        timesToDisable.map(function( unitToDisable ) {



            var matchFound



            // When we have disabled items, check for matches.

            // If something is matched, immediately break out.

            for ( var index = 0; index < disabledItems.length; index += 1 ) {

                if ( clock.isTimeExact( unitToDisable, disabledItems[index] ) ) {

                    matchFound = true

                    break

                }

            }



            // If nothing was found, add the validated unit to the collection.

            if ( !matchFound ) {

                if (

                    _.isInteger( unitToDisable ) ||

                    _.isDate( unitToDisable ) ||

                    $.isArray( unitToDisable ) ||

                    ( $.isPlainObject( unitToDisable ) && unitToDisable.from && unitToDisable.to )

                ) {

                    disabledItems.push( unitToDisable )

                }

            }

        })

    }



    // Return the updated collection.

    return disabledItems

} //TimePicker.prototype.deactivate





/**

 * Mark a collection of times as “enabled”.

 */

TimePicker.prototype.activate = function( type, timesToEnable ) {



    var clock = this,

        disabledItems = clock.item.disable,

        disabledItemsCount = disabledItems.length



    // If we’re flipping, that’s all we need to do.

    if ( timesToEnable == 'flip' ) {

        clock.flipEnable()

    }



    else if ( timesToEnable === true ) {

        clock.flipEnable(1)

        disabledItems = []

    }



    else if ( timesToEnable === false ) {

        clock.flipEnable(-1)

        disabledItems = []

    }



    // Otherwise go through the disabled times.

    else {



        timesToEnable.map(function( unitToEnable ) {



            var matchFound,

                disabledUnit,

                index,

                isRangeMatched



            // Go through the disabled items and try to find a match.

            for ( index = 0; index < disabledItemsCount; index += 1 ) {



                disabledUnit = disabledItems[index]



                // When an exact match is found, remove it from the collection.

                if ( clock.isTimeExact( disabledUnit, unitToEnable ) ) {

                    matchFound = disabledItems[index] = null

                    isRangeMatched = true

                    break

                }



                // When an overlapped match is found, add the “inverted” state to it.

                else if ( clock.isTimeOverlap( disabledUnit, unitToEnable ) ) {

                    if ( $.isPlainObject( unitToEnable ) ) {

                        unitToEnable.inverted = true

                        matchFound = unitToEnable

                    }

                    else if ( $.isArray( unitToEnable ) ) {

                        matchFound = unitToEnable

                        if ( !matchFound[2] ) matchFound.push( 'inverted' )

                    }

                    else if ( _.isDate( unitToEnable ) ) {

                        matchFound = [ unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted' ]

                    }

                    break

                }

            }



            // If a match was found, remove a previous duplicate entry.

            if ( matchFound ) for ( index = 0; index < disabledItemsCount; index += 1 ) {

                if ( clock.isTimeExact( disabledItems[index], unitToEnable ) ) {

                    disabledItems[index] = null

                    break

                }

            }



            // In the event that we’re dealing with an overlap of range times,

            // make sure there are no “inverted” times because of it.

            if ( isRangeMatched ) for ( index = 0; index < disabledItemsCount; index += 1 ) {

                if ( clock.isTimeOverlap( disabledItems[index], unitToEnable ) ) {

                    disabledItems[index] = null

                    break

                }

            }



            // If something is still matched, add it into the collection.

            if ( matchFound ) {

                disabledItems.push( matchFound )

            }

        })

    }



    // Return the updated collection.

    return disabledItems.filter(function( val ) { return val != null })

} //TimePicker.prototype.activate





/**

 * The division to use for the range intervals.

 */

TimePicker.prototype.i = function( type, value/*, options*/ ) {

    return _.isInteger( value ) && value > 0 ? value : this.item.interval

}





/**

 * Create a string for the nodes in the picker.

 */

TimePicker.prototype.nodes = function( isOpen ) {



    var

        clock = this,

        settings = clock.settings,

        selectedObject = clock.item.select,

        highlightedObject = clock.item.highlight,

        viewsetObject = clock.item.view,

        disabledCollection = clock.item.disable



    return _.node(

        'ul',

        _.group({

            min: clock.item.min.pick,

            max: clock.item.max.pick,

            i: clock.item.interval,

            node: 'li',

            item: function( loopedTime ) {

                loopedTime = clock.create( loopedTime )

                var timeMinutes = loopedTime.pick,

                    isSelected = selectedObject && selectedObject.pick == timeMinutes,

                    isHighlighted = highlightedObject && highlightedObject.pick == timeMinutes,

                    isDisabled = disabledCollection && clock.disabled( loopedTime ),

                    formattedTime = _.trigger( clock.formats.toString, clock, [ settings.format, loopedTime ] )

                return [

                    _.trigger( clock.formats.toString, clock, [ _.trigger( settings.formatLabel, clock, [ loopedTime ] ) || settings.format, loopedTime ] ),

                    (function( klasses ) {



                        if ( isSelected ) {

                            klasses.push( settings.klass.selected )

                        }



                        if ( isHighlighted ) {

                            klasses.push( settings.klass.highlighted )

                        }



                        if ( viewsetObject && viewsetObject.pick == timeMinutes ) {

                            klasses.push( settings.klass.viewset )

                        }



                        if ( isDisabled ) {

                            klasses.push( settings.klass.disabled )

                        }



                        return klasses.join( ' ' )

                    })( [ settings.klass.listItem ] ),

                    'data-pick=' + loopedTime.pick + ' ' + _.ariaAttr({

                        role: 'option',

                        label: formattedTime,

                        selected: isSelected && clock.$node.val() === formattedTime ? true : null,

                        activedescendant: isHighlighted ? true : null,

                        disabled: isDisabled ? true : null

                    })

                ]

            }

        }) +



        // * For Firefox forms to submit, make sure to set the button’s `type` attribute as “button”.

        _.node(

            'li',

            _.node(

                'button',

                settings.clear,

                settings.klass.buttonClear,

                'type=button data-clear=1' + ( isOpen ? '' : ' disabled' ) + ' ' +

                _.ariaAttr({ controls: clock.$node[0].id })

            ),

            '', _.ariaAttr({ role: 'presentation' })

        ),

        settings.klass.list,

        _.ariaAttr({ role: 'listbox', controls: clock.$node[0].id })

    )

} //TimePicker.prototype.nodes















/**

 * Extend the picker to add the component with the defaults.

 */

TimePicker.defaults = (function( prefix ) {



    return {



        // Clear

        clear: 'Clear',



        // The format to show on the `input` element

        format: 'h:i A',



        // The interval between each time

        interval: 30,



        // Picker close behavior

        closeOnSelect: true,

        closeOnClear: true,



        // Classes

        klass: {



            picker: prefix + ' ' + prefix + '--time',

            holder: prefix + '__holder',



            list: prefix + '__list',

            listItem: prefix + '__list-item',



            disabled: prefix + '__list-item--disabled',

            selected: prefix + '__list-item--selected',

            highlighted: prefix + '__list-item--highlighted',

            viewset: prefix + '__list-item--viewset',

            now: prefix + '__list-item--now',



            buttonClear: prefix + '__button--clear'

        }

    }

})( Picker.klasses().picker )











/**

 * Extend the picker to add the time picker.

 */

Picker.extend( 'pickatime', TimePicker )





}));







