2012-06-20 13:25:41 -07:00
// Underscore.js 1.3.1
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
( function ( ) { function q ( a , c , d ) { if ( a === c ) return a !== 0 || 1 / a == 1 / c ; if ( a == null || c == null ) return a === c ; if ( a . _chain ) a = a . _wrapped ; if ( c . _chain ) c = c . _wrapped ; if ( a . isEqual && b . isFunction ( a . isEqual ) ) return a . isEqual ( c ) ; if ( c . isEqual && b . isFunction ( c . isEqual ) ) return c . isEqual ( a ) ; var e = l . call ( a ) ; if ( e != l . call ( c ) ) return false ; switch ( e ) { case "[object String]" : return a == String ( c ) ; case "[object Number]" : return a != + a ? c != + c : a == 0 ? 1 / a == 1 / c : a == + c ; case "[object Date]" : case "[object Boolean]" : return + a == + c ; case "[object RegExp]" : return a . source ==
c . source && a . global == c . global && a . multiline == c . multiline && a . ignoreCase == c . ignoreCase } if ( typeof a != "object" || typeof c != "object" ) return false ; for ( var f = d . length ; f -- ; ) if ( d [ f ] == a ) return true ; d . push ( a ) ; var f = 0 , g = true ; if ( e == "[object Array]" ) { if ( f = a . length , g = f == c . length ) for ( ; f -- ; ) if ( ! ( g = f in a == f in c && q ( a [ f ] , c [ f ] , d ) ) ) break } else { if ( "constructor" in a != "constructor" in c || a . constructor != c . constructor ) return false ; for ( var h in a ) if ( b . has ( a , h ) && ( f ++ , ! ( g = b . has ( c , h ) && q ( a [ h ] , c [ h ] , d ) ) ) ) break ; if ( g ) { for ( h in c ) if ( b . has ( c ,
h ) && ! f -- ) break ; g = ! f } } d . pop ( ) ; return g } var r = this , G = r . _ , n = { } , k = Array . prototype , o = Object . prototype , i = k . slice , H = k . unshift , l = o . toString , I = o . hasOwnProperty , w = k . forEach , x = k . map , y = k . reduce , z = k . reduceRight , A = k . filter , B = k . every , C = k . some , p = k . indexOf , D = k . lastIndexOf , o = Array . isArray , J = Object . keys , s = Function . prototype . bind , b = function ( a ) { return new m ( a ) } ; if ( typeof exports !== "undefined" ) { if ( typeof module !== "undefined" && module . exports ) exports = module . exports = b ; exports . _ = b } else r . _ = b ; b . VERSION = "1.3.1" ; var j = b . each =
b . forEach = function ( a , c , d ) { if ( a != null ) if ( w && a . forEach === w ) a . forEach ( c , d ) ; else if ( a . length === + a . length ) for ( var e = 0 , f = a . length ; e < f ; e ++ ) { if ( e in a && c . call ( d , a [ e ] , e , a ) === n ) break } else for ( e in a ) if ( b . has ( a , e ) && c . call ( d , a [ e ] , e , a ) === n ) break } ; b . map = b . collect = function ( a , c , b ) { var e = [ ] ; if ( a == null ) return e ; if ( x && a . map === x ) return a . map ( c , b ) ; j ( a , function ( a , g , h ) { e [ e . length ] = c . call ( b , a , g , h ) } ) ; if ( a . length === + a . length ) e . length = a . length ; return e } ; b . reduce = b . foldl = b . inject = function ( a , c , d , e ) { var f = arguments . length > 2 ; a ==
null && ( a = [ ] ) ; if ( y && a . reduce === y ) return e && ( c = b . bind ( c , e ) ) , f ? a . reduce ( c , d ) : a . reduce ( c ) ; j ( a , function ( a , b , i ) { f ? d = c . call ( e , d , a , b , i ) : ( d = a , f = true ) } ) ; if ( ! f ) throw new TypeError ( "Reduce of empty array with no initial value" ) ; return d } ; b . reduceRight = b . foldr = function ( a , c , d , e ) { var f = arguments . length > 2 ; a == null && ( a = [ ] ) ; if ( z && a . reduceRight === z ) return e && ( c = b . bind ( c , e ) ) , f ? a . reduceRight ( c , d ) : a . reduceRight ( c ) ; var g = b . toArray ( a ) . reverse ( ) ; e && ! f && ( c = b . bind ( c , e ) ) ; return f ? b . reduce ( g , c , d , e ) : b . reduce ( g , c ) } ; b . find = b . detect =
function ( a , c , b ) { var e ; E ( a , function ( a , g , h ) { if ( c . call ( b , a , g , h ) ) return e = a , true } ) ; return e } ; b . filter = b . select = function ( a , c , b ) { var e = [ ] ; if ( a == null ) return e ; if ( A && a . filter === A ) return a . filter ( c , b ) ; j ( a , function ( a , g , h ) { c . call ( b , a , g , h ) && ( e [ e . length ] = a ) } ) ; return e } ; b . reject = function ( a , c , b ) { var e = [ ] ; if ( a == null ) return e ; j ( a , function ( a , g , h ) { c . call ( b , a , g , h ) || ( e [ e . length ] = a ) } ) ; return e } ; b . every = b . all = function ( a , c , b ) { var e = true ; if ( a == null ) return e ; if ( B && a . every === B ) return a . every ( c , b ) ; j ( a , function ( a , g , h ) { if ( ! ( e =
e && c . call ( b , a , g , h ) ) ) return n } ) ; return e } ; var E = b . some = b . any = function ( a , c , d ) { c || ( c = b . identity ) ; var e = false ; if ( a == null ) return e ; if ( C && a . some === C ) return a . some ( c , d ) ; j ( a , function ( a , b , h ) { if ( e || ( e = c . call ( d , a , b , h ) ) ) return n } ) ; return ! ! e } ; b . include = b . contains = function ( a , c ) { var b = false ; if ( a == null ) return b ; return p && a . indexOf === p ? a . indexOf ( c ) != - 1 : b = E ( a , function ( a ) { return a === c } ) } ; b . invoke = function ( a , c ) { var d = i . call ( arguments , 2 ) ; return b . map ( a , function ( a ) { return ( b . isFunction ( c ) ? c || a : a [ c ] ) . apply ( a , d ) } ) } ; b . pluck =
function ( a , c ) { return b . map ( a , function ( a ) { return a [ c ] } ) } ; b . max = function ( a , c , d ) { if ( ! c && b . isArray ( a ) ) return Math . max . apply ( Math , a ) ; if ( ! c && b . isEmpty ( a ) ) return - Infinity ; var e = { computed : - Infinity } ; j ( a , function ( a , b , h ) { b = c ? c . call ( d , a , b , h ) : a ; b >= e . computed && ( e = { value : a , computed : b } ) } ) ; return e . value } ; b . min = function ( a , c , d ) { if ( ! c && b . isArray ( a ) ) return Math . min . apply ( Math , a ) ; if ( ! c && b . isEmpty ( a ) ) return Infinity ; var e = { computed : Infinity } ; j ( a , function ( a , b , h ) { b = c ? c . call ( d , a , b , h ) : a ; b < e . computed && ( e = { value : a , computed : b } ) } ) ;
return e . value } ; b . shuffle = function ( a ) { var b = [ ] , d ; j ( a , function ( a , f ) { f == 0 ? b [ 0 ] = a : ( d = Math . floor ( Math . random ( ) * ( f + 1 ) ) , b [ f ] = b [ d ] , b [ d ] = a ) } ) ; return b } ; b . sortBy = function ( a , c , d ) { return b . pluck ( b . map ( a , function ( a , b , g ) { return { value : a , criteria : c . call ( d , a , b , g ) } } ) . sort ( function ( a , b ) { var c = a . criteria , d = b . criteria ; return c < d ? - 1 : c > d ? 1 : 0 } ) , "value" ) } ; b . groupBy = function ( a , c ) { var d = { } , e = b . isFunction ( c ) ? c : function ( a ) { return a [ c ] } ; j ( a , function ( a , b ) { var c = e ( a , b ) ; ( d [ c ] || ( d [ c ] = [ ] ) ) . push ( a ) } ) ; return d } ; b . sortedIndex = function ( a ,
c , d ) { d || ( d = b . identity ) ; for ( var e = 0 , f = a . length ; e < f ; ) { var g = e + f >> 1 ; d ( a [ g ] ) < d ( c ) ? e = g + 1 : f = g } return e } ; b . toArray = function ( a ) { return ! a ? [ ] : a . toArray ? a . toArray ( ) : b . isArray ( a ) ? i . call ( a ) : b . isArguments ( a ) ? i . call ( a ) : b . values ( a ) } ; b . size = function ( a ) { return b . toArray ( a ) . length } ; b . first = b . head = function ( a , b , d ) { return b != null && ! d ? i . call ( a , 0 , b ) : a [ 0 ] } ; b . initial = function ( a , b , d ) { return i . call ( a , 0 , a . length - ( b == null || d ? 1 : b ) ) } ; b . last = function ( a , b , d ) { return b != null && ! d ? i . call ( a , Math . max ( a . length - b , 0 ) ) : a [ a . length - 1 ] } ; b . rest =
b . tail = function ( a , b , d ) { return i . call ( a , b == null || d ? 1 : b ) } ; b . compact = function ( a ) { return b . filter ( a , function ( a ) { return ! ! a } ) } ; b . flatten = function ( a , c ) { return b . reduce ( a , function ( a , e ) { if ( b . isArray ( e ) ) return a . concat ( c ? e : b . flatten ( e ) ) ; a [ a . length ] = e ; return a } , [ ] ) } ; b . without = function ( a ) { return b . difference ( a , i . call ( arguments , 1 ) ) } ; b . uniq = b . unique = function ( a , c , d ) { var d = d ? b . map ( a , d ) : a , e = [ ] ; b . reduce ( d , function ( d , g , h ) { if ( 0 == h || ( c === true ? b . last ( d ) != g : ! b . include ( d , g ) ) ) d [ d . length ] = g , e [ e . length ] = a [ h ] ; return d } , [ ] ) ;
return e } ; b . union = function ( ) { return b . uniq ( b . flatten ( arguments , true ) ) } ; b . intersection = b . intersect = function ( a ) { var c = i . call ( arguments , 1 ) ; return b . filter ( b . uniq ( a ) , function ( a ) { return b . every ( c , function ( c ) { return b . indexOf ( c , a ) >= 0 } ) } ) } ; b . difference = function ( a ) { var c = b . flatten ( i . call ( arguments , 1 ) ) ; return b . filter ( a , function ( a ) { return ! b . include ( c , a ) } ) } ; b . zip = function ( ) { for ( var a = i . call ( arguments ) , c = b . max ( b . pluck ( a , "length" ) ) , d = Array ( c ) , e = 0 ; e < c ; e ++ ) d [ e ] = b . pluck ( a , "" + e ) ; return d } ; b . indexOf = function ( a , c ,
d ) { if ( a == null ) return - 1 ; var e ; if ( d ) return d = b . sortedIndex ( a , c ) , a [ d ] === c ? d : - 1 ; if ( p && a . indexOf === p ) return a . indexOf ( c ) ; for ( d = 0 , e = a . length ; d < e ; d ++ ) if ( d in a && a [ d ] === c ) return d ; return - 1 } ; b . lastIndexOf = function ( a , b ) { if ( a == null ) return - 1 ; if ( D && a . lastIndexOf === D ) return a . lastIndexOf ( b ) ; for ( var d = a . length ; d -- ; ) if ( d in a && a [ d ] === b ) return d ; return - 1 } ; b . range = function ( a , b , d ) { arguments . length <= 1 && ( b = a || 0 , a = 0 ) ; for ( var d = arguments [ 2 ] || 1 , e = Math . max ( Math . ceil ( ( b - a ) / d ) , 0 ) , f = 0 , g = Array ( e ) ; f < e ; ) g [ f ++ ] = a , a += d ; return g } ;
var F = function ( ) { } ; b . bind = function ( a , c ) { var d , e ; if ( a . bind === s && s ) return s . apply ( a , i . call ( arguments , 1 ) ) ; if ( ! b . isFunction ( a ) ) throw new TypeError ; e = i . call ( arguments , 2 ) ; return d = function ( ) { if ( ! ( this instanceof d ) ) return a . apply ( c , e . concat ( i . call ( arguments ) ) ) ; F . prototype = a . prototype ; var b = new F , g = a . apply ( b , e . concat ( i . call ( arguments ) ) ) ; return Object ( g ) === g ? g : b } } ; b . bindAll = function ( a ) { var c = i . call ( arguments , 1 ) ; c . length == 0 && ( c = b . functions ( a ) ) ; j ( c , function ( c ) { a [ c ] = b . bind ( a [ c ] , a ) } ) ; return a } ; b . memoize = function ( a ,
c ) { var d = { } ; c || ( c = b . identity ) ; return function ( ) { var e = c . apply ( this , arguments ) ; return b . has ( d , e ) ? d [ e ] : d [ e ] = a . apply ( this , arguments ) } } ; b . delay = function ( a , b ) { var d = i . call ( arguments , 2 ) ; return setTimeout ( function ( ) { return a . apply ( a , d ) } , b ) } ; b . defer = function ( a ) { return b . delay . apply ( b , [ a , 1 ] . concat ( i . call ( arguments , 1 ) ) ) } ; b . throttle = function ( a , c ) { var d , e , f , g , h , i = b . debounce ( function ( ) { h = g = false } , c ) ; return function ( ) { d = this ; e = arguments ; var b ; f || ( f = setTimeout ( function ( ) { f = null ; h && a . apply ( d , e ) ; i ( ) } , c ) ) ; g ? h = true :
a . apply ( d , e ) ; i ( ) ; g = true } } ; b . debounce = function ( a , b ) { var d ; return function ( ) { var e = this , f = arguments ; clearTimeout ( d ) ; d = setTimeout ( function ( ) { d = null ; a . apply ( e , f ) } , b ) } } ; b . once = function ( a ) { var b = false , d ; return function ( ) { if ( b ) return d ; b = true ; return d = a . apply ( this , arguments ) } } ; b . wrap = function ( a , b ) { return function ( ) { var d = [ a ] . concat ( i . call ( arguments , 0 ) ) ; return b . apply ( this , d ) } } ; b . compose = function ( ) { var a = arguments ; return function ( ) { for ( var b = arguments , d = a . length - 1 ; d >= 0 ; d -- ) b = [ a [ d ] . apply ( this , b ) ] ; return b [ 0 ] } } ;
b . after = function ( a , b ) { return a <= 0 ? b ( ) : function ( ) { if ( -- a < 1 ) return b . apply ( this , arguments ) } } ; b . keys = J || function ( a ) { if ( a !== Object ( a ) ) throw new TypeError ( "Invalid object" ) ; var c = [ ] , d ; for ( d in a ) b . has ( a , d ) && ( c [ c . length ] = d ) ; return c } ; b . values = function ( a ) { return b . map ( a , b . identity ) } ; b . functions = b . methods = function ( a ) { var c = [ ] , d ; for ( d in a ) b . isFunction ( a [ d ] ) && c . push ( d ) ; return c . sort ( ) } ; b . extend = function ( a ) { j ( i . call ( arguments , 1 ) , function ( b ) { for ( var d in b ) a [ d ] = b [ d ] } ) ; return a } ; b . defaults = function ( a ) { j ( i . call ( arguments ,
1 ) , function ( b ) { for ( var d in b ) a [ d ] == null && ( a [ d ] = b [ d ] ) } ) ; return a } ; b . clone = function ( a ) { return ! b . isObject ( a ) ? a : b . isArray ( a ) ? a . slice ( ) : b . extend ( { } , a ) } ; b . tap = function ( a , b ) { b ( a ) ; return a } ; b . isEqual = function ( a , b ) { return q ( a , b , [ ] ) } ; b . isEmpty = function ( a ) { if ( b . isArray ( a ) || b . isString ( a ) ) return a . length === 0 ; for ( var c in a ) if ( b . has ( a , c ) ) return false ; return true } ; b . isElement = function ( a ) { return ! ! ( a && a . nodeType == 1 ) } ; b . isArray = o || function ( a ) { return l . call ( a ) == "[object Array]" } ; b . isObject = function ( a ) { return a === Object ( a ) } ;
b . isArguments = function ( a ) { return l . call ( a ) == "[object Arguments]" } ; if ( ! b . isArguments ( arguments ) ) b . isArguments = function ( a ) { return ! ( ! a || ! b . has ( a , "callee" ) ) } ; b . isFunction = function ( a ) { return l . call ( a ) == "[object Function]" } ; b . isString = function ( a ) { return l . call ( a ) == "[object String]" } ; b . isNumber = function ( a ) { return l . call ( a ) == "[object Number]" } ; b . isNaN = function ( a ) { return a !== a } ; b . isBoolean = function ( a ) { return a === true || a === false || l . call ( a ) == "[object Boolean]" } ; b . isDate = function ( a ) { return l . call ( a ) == "[object Date]" } ;
b . isRegExp = function ( a ) { return l . call ( a ) == "[object RegExp]" } ; b . isNull = function ( a ) { return a === null } ; b . isUndefined = function ( a ) { return a === void 0 } ; b . has = function ( a , b ) { return I . call ( a , b ) } ; b . noConflict = function ( ) { r . _ = G ; return this } ; b . identity = function ( a ) { return a } ; b . times = function ( a , b , d ) { for ( var e = 0 ; e < a ; e ++ ) b . call ( d , e ) } ; b . escape = function ( a ) { return ( "" + a ) . replace ( /&/g , "&" ) . replace ( /</g , "<" ) . replace ( />/g , ">" ) . replace ( /"/g , """ ) . replace ( /'/g , "'" ) . replace ( /\//g , "/" ) } ; b . mixin = function ( a ) { j ( b . functions ( a ) ,
function ( c ) { K ( c , b [ c ] = a [ c ] ) } ) } ; var L = 0 ; b . uniqueId = function ( a ) { var b = L ++ ; return a ? a + b : b } ; b . templateSettings = { evaluate : /<%([\s\S]+?)%>/g , interpolate : /<%=([\s\S]+?)%>/g , escape : /<%-([\s\S]+?)%>/g } ; var t = /.^/ , u = function ( a ) { return a . replace ( /\\\\/g , "\\" ) . replace ( /\\'/g , "'" ) } ; b . template = function ( a , c ) { var d = b . templateSettings , d = "var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('" + a . replace ( /\\/g , "\\\\" ) . replace ( /'/g , "\\'" ) . replace ( d . escape || t , function ( a , b ) { return "',_.escape(" +
u ( b ) + "),'" } ) . replace ( d . interpolate || t , function ( a , b ) { return "'," + u ( b ) + ",'" } ) . replace ( d . evaluate || t , function ( a , b ) { return "');" + u ( b ) . replace ( /[\r\n\t]/g , " " ) + ";__p.push('" } ) . replace ( /\r/g , "\\r" ) . replace ( /\n/g , "\\n" ) . replace ( /\t/g , "\\t" ) + "');}return __p.join('');" , e = new Function ( "obj" , "_" , d ) ; return c ? e ( c , b ) : function ( a ) { return e . call ( this , a , b ) } } ; b . chain = function ( a ) { return b ( a ) . chain ( ) } ; var m = function ( a ) { this . _wrapped = a } ; b . prototype = m . prototype ; var v = function ( a , c ) { return c ? b ( a ) . chain ( ) : a } , K = function ( a , c ) { m . prototype [ a ] =
function ( ) { var a = i . call ( arguments ) ; H . call ( a , this . _wrapped ) ; return v ( c . apply ( b , a ) , this . _chain ) } } ; b . mixin ( b ) ; j ( "pop,push,reverse,shift,sort,splice,unshift" . split ( "," ) , function ( a ) { var b = k [ a ] ; m . prototype [ a ] = function ( ) { var d = this . _wrapped ; b . apply ( d , arguments ) ; var e = d . length ; ( a == "shift" || a == "splice" ) && e === 0 && delete d [ 0 ] ; return v ( d , this . _chain ) } } ) ; j ( [ "concat" , "join" , "slice" ] , function ( a ) { var b = k [ a ] ; m . prototype [ a ] = function ( ) { return v ( b . apply ( this . _wrapped , arguments ) , this . _chain ) } } ) ; m . prototype . chain = function ( ) { this . _chain =
true ; return this } ; m . prototype . value = function ( ) { return this . _wrapped } } ) . call ( this ) ;
var JSON ; if ( ! JSON ) { JSON = { } ; }
( function ( ) { "use strict" ; function f ( n ) { return n < 10 ? '0' + n : n ; }
if ( typeof Date . prototype . toJSON !== 'function' ) { Date . prototype . toJSON = function ( key ) { return isFinite ( this . valueOf ( ) ) ? this . getUTCFullYear ( ) + '-' +
f ( this . getUTCMonth ( ) + 1 ) + '-' +
f ( this . getUTCDate ( ) ) + 'T' +
f ( this . getUTCHours ( ) ) + ':' +
f ( this . getUTCMinutes ( ) ) + ':' +
f ( this . getUTCSeconds ( ) ) + 'Z' : null ; } ; String . prototype . toJSON = Number . prototype . toJSON = Boolean . prototype . toJSON = function ( key ) { return this . valueOf ( ) ; } ; }
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g , escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g , gap , indent , meta = { '\b' : '\\b' , '\t' : '\\t' , '\n' : '\\n' , '\f' : '\\f' , '\r' : '\\r' , '"' : '\\"' , '\\' : '\\\\' } , rep ; function quote ( string ) { escapable . lastIndex = 0 ; return escapable . test ( string ) ? '"' + string . replace ( escapable , function ( a ) { var c = meta [ a ] ; return typeof c === 'string' ? c : '\\u' + ( '0000' + a . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 4 ) ; } ) + '"' : '"' + string + '"' ; }
function str ( key , holder ) { var i , k , v , length , mind = gap , partial , value = holder [ key ] ; if ( value && typeof value === 'object' && typeof value . toJSON === 'function' ) { value = value . toJSON ( key ) ; }
if ( typeof rep === 'function' ) { value = rep . call ( holder , key , value ) ; }
switch ( typeof value ) { case 'string' : return quote ( value ) ; case 'number' : return isFinite ( value ) ? String ( value ) : 'null' ; case 'boolean' : case 'null' : return String ( value ) ; case 'object' : if ( ! value ) { return 'null' ; }
gap += indent ; partial = [ ] ; if ( Object . prototype . toString . apply ( value ) === '[object Array]' ) { length = value . length ; for ( i = 0 ; i < length ; i += 1 ) { partial [ i ] = str ( i , value ) || 'null' ; }
v = partial . length === 0 ? '[]' : gap ? '[\n' + gap + partial . join ( ',\n' + gap ) + '\n' + mind + ']' : '[' + partial . join ( ',' ) + ']' ; gap = mind ; return v ; }
if ( rep && typeof rep === 'object' ) { length = rep . length ; for ( i = 0 ; i < length ; i += 1 ) { if ( typeof rep [ i ] === 'string' ) { k = rep [ i ] ; v = str ( k , value ) ; if ( v ) { partial . push ( quote ( k ) + ( gap ? ': ' : ':' ) + v ) ; } } } } else { for ( k in value ) { if ( Object . prototype . hasOwnProperty . call ( value , k ) ) { v = str ( k , value ) ; if ( v ) { partial . push ( quote ( k ) + ( gap ? ': ' : ':' ) + v ) ; } } } }
v = partial . length === 0 ? '{}' : gap ? '{\n' + gap + partial . join ( ',\n' + gap ) + '\n' + mind + '}' : '{' + partial . join ( ',' ) + '}' ; gap = mind ; return v ; } }
if ( typeof JSON . stringify !== 'function' ) { JSON . stringify = function ( value , replacer , space ) { var i ; gap = '' ; indent = '' ; if ( typeof space === 'number' ) { for ( i = 0 ; i < space ; i += 1 ) { indent += ' ' ; } } else if ( typeof space === 'string' ) { indent = space ; }
rep = replacer ; if ( replacer && typeof replacer !== 'function' && ( typeof replacer !== 'object' || typeof replacer . length !== 'number' ) ) { throw new Error ( 'JSON.stringify' ) ; }
return str ( '' , { '' : value } ) ; } ; }
if ( typeof JSON . parse !== 'function' ) { JSON . parse = function ( text , reviver ) { var j ; function walk ( holder , key ) { var k , v , value = holder [ key ] ; if ( value && typeof value === 'object' ) { for ( k in value ) { if ( Object . prototype . hasOwnProperty . call ( value , k ) ) { v = walk ( value , k ) ; if ( v !== undefined ) { value [ k ] = v ; } else { delete value [ k ] ; } } } }
return reviver . call ( holder , key , value ) ; }
text = String ( text ) ; cx . lastIndex = 0 ; if ( cx . test ( text ) ) { text = text . replace ( cx , function ( a ) { return '\\u' +
( '0000' + a . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 4 ) ; } ) ; }
if ( /^[\],:{}\s]*$/ . test ( text . replace ( /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g , '@' ) . replace ( /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g , ']' ) . replace ( /(?:^|:|,)(?:\s*\[)+/g , '' ) ) ) { j = eval ( '(' + text + ')' ) ; return typeof reviver === 'function' ? walk ( { '' : j } , '' ) : j ; }
throw new SyntaxError ( 'JSON.parse' ) ; } ; } } ( ) ) ;
// Backbone.js 0.9.1
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// http://backbonejs.org
( function ( ) { var i = this , r = i . Backbone , s = Array . prototype . slice , t = Array . prototype . splice , g ; g = "undefined" !== typeof exports ? exports : i . Backbone = { } ; g . VERSION = "0.9.1" ; var f = i . _ ; ! f && "undefined" !== typeof require && ( f = require ( "underscore" ) ) ; var h = i . jQuery || i . Zepto || i . ender ; g . setDomLibrary = function ( a ) { h = a } ; g . noConflict = function ( ) { i . Backbone = r ; return this } ; g . emulateHTTP = ! 1 ; g . emulateJSON = ! 1 ; g . Events = { on : function ( a , b , c ) { for ( var d , a = a . split ( /\s+/ ) , e = this . _callbacks || ( this . _callbacks = { } ) ; d = a . shift ( ) ; ) { d = e [ d ] || ( e [ d ] =
{ } ) ; var f = d . tail || ( d . tail = d . next = { } ) ; f . callback = b ; f . context = c ; d . tail = f . next = { } } return this } , off : function ( a , b , c ) { var d , e , f ; if ( a ) { if ( e = this . _callbacks ) for ( a = a . split ( /\s+/ ) ; d = a . shift ( ) ; ) if ( f = e [ d ] , delete e [ d ] , b && f ) for ( ; ( f = f . next ) && f . next ; ) if ( ! ( f . callback === b && ( ! c || f . context === c ) ) ) this . on ( d , f . callback , f . context ) } else delete this . _callbacks ; return this } , trigger : function ( a ) { var b , c , d , e ; if ( ! ( d = this . _callbacks ) ) return this ; e = d . all ; for ( ( a = a . split ( /\s+/ ) ) . push ( null ) ; b = a . shift ( ) ; ) e && a . push ( { next : e . next , tail : e . tail ,
event : b } ) , ( c = d [ b ] ) && a . push ( { next : c . next , tail : c . tail } ) ; for ( e = s . call ( arguments , 1 ) ; c = a . pop ( ) ; ) { b = c . tail ; for ( d = c . event ? [ c . event ] . concat ( e ) : e ; ( c = c . next ) !== b ; ) c . callback . apply ( c . context || this , d ) } return this } } ; g . Events . bind = g . Events . on ; g . Events . unbind = g . Events . off ; g . Model = function ( a , b ) { var c ; a || ( a = { } ) ; b && b . parse && ( a = this . parse ( a ) ) ; if ( c = j ( this , "defaults" ) ) a = f . extend ( { } , c , a ) ; b && b . collection && ( this . collection = b . collection ) ; this . attributes = { } ; this . _escapedAttributes = { } ; this . cid = f . uniqueId ( "c" ) ; if ( ! this . set ( a ,
{ silent : ! 0 } ) ) throw Error ( "Can't create an invalid model" ) ; delete this . _changed ; this . _previousAttributes = f . clone ( this . attributes ) ; this . initialize . apply ( this , arguments ) } ; f . extend ( g . Model . prototype , g . Events , { idAttribute : "id" , initialize : function ( ) { } , toJSON : function ( ) { return f . clone ( this . attributes ) } , get : function ( a ) { return this . attributes [ a ] } , escape : function ( a ) { var b ; if ( b = this . _escapedAttributes [ a ] ) return b ; b = this . attributes [ a ] ; return this . _escapedAttributes [ a ] = f . escape ( null == b ? "" : "" + b ) } , has : function ( a ) { return null !=
this . attributes [ a ] } , set : function ( a , b , c ) { var d , e ; f . isObject ( a ) || null == a ? ( d = a , c = b ) : ( d = { } , d [ a ] = b ) ; c || ( c = { } ) ; if ( ! d ) return this ; d instanceof g . Model && ( d = d . attributes ) ; if ( c . unset ) for ( e in d ) d [ e ] = void 0 ; if ( ! this . _validate ( d , c ) ) return ! 1 ; this . idAttribute in d && ( this . id = d [ this . idAttribute ] ) ; var b = this . attributes , k = this . _escapedAttributes , n = this . _previousAttributes || { } , h = this . _setting ; this . _changed || ( this . _changed = { } ) ; this . _setting = ! 0 ; for ( e in d ) if ( a = d [ e ] , f . isEqual ( b [ e ] , a ) || delete k [ e ] , c . unset ? delete b [ e ] : b [ e ] =
a , this . _changing && ! f . isEqual ( this . _changed [ e ] , a ) && ( this . trigger ( "change:" + e , this , a , c ) , this . _moreChanges = ! 0 ) , delete this . _changed [ e ] , ! f . isEqual ( n [ e ] , a ) || f . has ( b , e ) != f . has ( n , e ) ) this . _changed [ e ] = a ; h || ( ! c . silent && this . hasChanged ( ) && this . change ( c ) , this . _setting = ! 1 ) ; return this } , unset : function ( a , b ) { ( b || ( b = { } ) ) . unset = ! 0 ; return this . set ( a , null , b ) } , clear : function ( a ) { ( a || ( a = { } ) ) . unset = ! 0 ; return this . set ( f . clone ( this . attributes ) , a ) } , fetch : function ( a ) { var a = a ? f . clone ( a ) : { } , b = this , c = a . success ; a . success = function ( d ,
e , f ) { if ( ! b . set ( b . parse ( d , f ) , a ) ) return ! 1 ; c && c ( b , d ) } ; a . error = g . wrapError ( a . error , b , a ) ; return ( this . sync || g . sync ) . call ( this , "read" , this , a ) } , save : function ( a , b , c ) { var d , e ; f . isObject ( a ) || null == a ? ( d = a , c = b ) : ( d = { } , d [ a ] = b ) ; c = c ? f . clone ( c ) : { } ; c . wait && ( e = f . clone ( this . attributes ) ) ; a = f . extend ( { } , c , { silent : ! 0 } ) ; if ( d && ! this . set ( d , c . wait ? a : c ) ) return ! 1 ; var k = this , h = c . success ; c . success = function ( a , b , e ) { b = k . parse ( a , e ) ; c . wait && ( b = f . extend ( d || { } , b ) ) ; if ( ! k . set ( b , c ) ) return ! 1 ; h ? h ( k , a ) : k . trigger ( "sync" , k , a , c ) } ; c . error = g . wrapError ( c . error ,
k , c ) ; b = this . isNew ( ) ? "create" : "update" ; b = ( this . sync || g . sync ) . call ( this , b , this , c ) ; c . wait && this . set ( e , a ) ; return b } , destroy : function ( a ) { var a = a ? f . clone ( a ) : { } , b = this , c = a . success , d = function ( ) { b . trigger ( "destroy" , b , b . collection , a ) } ; if ( this . isNew ( ) ) return d ( ) ; a . success = function ( e ) { a . wait && d ( ) ; c ? c ( b , e ) : b . trigger ( "sync" , b , e , a ) } ; a . error = g . wrapError ( a . error , b , a ) ; var e = ( this . sync || g . sync ) . call ( this , "delete" , this , a ) ; a . wait || d ( ) ; return e } , url : function ( ) { var a = j ( this . collection , "url" ) || j ( this , "urlRoot" ) || o ( ) ; return this . isNew ( ) ?
a : a + ( "/" == a . charAt ( a . length - 1 ) ? "" : "/" ) + encodeURIComponent ( this . id ) } , parse : function ( a ) { return a } , clone : function ( ) { return new this . constructor ( this . attributes ) } , isNew : function ( ) { return null == this . id } , change : function ( a ) { if ( this . _changing || ! this . hasChanged ( ) ) return this ; this . _moreChanges = this . _changing = ! 0 ; for ( var b in this . _changed ) this . trigger ( "change:" + b , this , this . _changed [ b ] , a ) ; for ( ; this . _moreChanges ; ) this . _moreChanges = ! 1 , this . trigger ( "change" , this , a ) ; this . _previousAttributes = f . clone ( this . attributes ) ;
delete this . _changed ; this . _changing = ! 1 ; return this } , hasChanged : function ( a ) { return ! arguments . length ? ! f . isEmpty ( this . _changed ) : this . _changed && f . has ( this . _changed , a ) } , changedAttributes : function ( a ) { if ( ! a ) return this . hasChanged ( ) ? f . clone ( this . _changed ) : ! 1 ; var b , c = ! 1 , d = this . _previousAttributes , e ; for ( e in a ) if ( ! f . isEqual ( d [ e ] , b = a [ e ] ) ) ( c || ( c = { } ) ) [ e ] = b ; return c } , previous : function ( a ) { return ! arguments . length || ! this . _previousAttributes ? null : this . _previousAttributes [ a ] } , previousAttributes : function ( ) { return f . clone ( this . _previousAttributes ) } ,
isValid : function ( ) { return ! this . validate ( this . attributes ) } , _validate : function ( a , b ) { if ( b . silent || ! this . validate ) return ! 0 ; var a = f . extend ( { } , this . attributes , a ) , c = this . validate ( a , b ) ; if ( ! c ) return ! 0 ; b && b . error ? b . error ( this , c , b ) : this . trigger ( "error" , this , c , b ) ; return ! 1 } } ) ; g . Collection = function ( a , b ) { b || ( b = { } ) ; b . comparator && ( this . comparator = b . comparator ) ; this . _reset ( ) ; this . initialize . apply ( this , arguments ) ; a && this . reset ( a , { silent : ! 0 , parse : b . parse } ) } ; f . extend ( g . Collection . prototype , g . Events , { model : g . Model , initialize : function ( ) { } ,
toJSON : function ( ) { return this . map ( function ( a ) { return a . toJSON ( ) } ) } , add : function ( a , b ) { var c , d , e , g , h , i = { } , j = { } ; b || ( b = { } ) ; a = f . isArray ( a ) ? a . slice ( ) : [ a ] ; for ( c = 0 , d = a . length ; c < d ; c ++ ) { if ( ! ( e = a [ c ] = this . _prepareModel ( a [ c ] , b ) ) ) throw Error ( "Can't add an invalid model to a collection" ) ; if ( i [ g = e . cid ] || this . _byCid [ g ] || null != ( h = e . id ) && ( j [ h ] || this . _byId [ h ] ) ) throw Error ( "Can't add the same model to a collection twice" ) ; i [ g ] = j [ h ] = e } for ( c = 0 ; c < d ; c ++ ) ( e = a [ c ] ) . on ( "all" , this . _onModelEvent , this ) , this . _byCid [ e . cid ] = e , null !=
e . id && ( this . _byId [ e . id ] = e ) ; this . length += d ; t . apply ( this . models , [ null != b . at ? b . at : this . models . length , 0 ] . concat ( a ) ) ; this . comparator && this . sort ( { silent : ! 0 } ) ; if ( b . silent ) return this ; for ( c = 0 , d = this . models . length ; c < d ; c ++ ) if ( i [ ( e = this . models [ c ] ) . cid ] ) b . index = c , e . trigger ( "add" , e , this , b ) ; return this } , remove : function ( a , b ) { var c , d , e , g ; b || ( b = { } ) ; a = f . isArray ( a ) ? a . slice ( ) : [ a ] ; for ( c = 0 , d = a . length ; c < d ; c ++ ) if ( g = this . getByCid ( a [ c ] ) || this . get ( a [ c ] ) ) delete this . _byId [ g . id ] , delete this . _byCid [ g . cid ] , e = this . indexOf ( g ) , this . models . splice ( e ,
1 ) , this . length -- , b . silent || ( b . index = e , g . trigger ( "remove" , g , this , b ) ) , this . _removeReference ( g ) ; return this } , get : function ( a ) { return null == a ? null : this . _byId [ null != a . id ? a . id : a ] } , getByCid : function ( a ) { return a && this . _byCid [ a . cid || a ] } , at : function ( a ) { return this . models [ a ] } , sort : function ( a ) { a || ( a = { } ) ; if ( ! this . comparator ) throw Error ( "Cannot sort a set without a comparator" ) ; var b = f . bind ( this . comparator , this ) ; 1 == this . comparator . length ? this . models = this . sortBy ( b ) : this . models . sort ( b ) ; a . silent || this . trigger ( "reset" ,
this , a ) ; return this } , pluck : function ( a ) { return f . map ( this . models , function ( b ) { return b . get ( a ) } ) } , reset : function ( a , b ) { a || ( a = [ ] ) ; b || ( b = { } ) ; for ( var c = 0 , d = this . models . length ; c < d ; c ++ ) this . _removeReference ( this . models [ c ] ) ; this . _reset ( ) ; this . add ( a , { silent : ! 0 , parse : b . parse } ) ; b . silent || this . trigger ( "reset" , this , b ) ; return this } , fetch : function ( a ) { a = a ? f . clone ( a ) : { } ; void 0 === a . parse && ( a . parse = ! 0 ) ; var b = this , c = a . success ; a . success = function ( d , e , f ) { b [ a . add ? "add" : "reset" ] ( b . parse ( d , f ) , a ) ; c && c ( b , d ) } ; a . error = g . wrapError ( a . error ,
b , a ) ; return ( this . sync || g . sync ) . call ( this , "read" , this , a ) } , create : function ( a , b ) { var c = this , b = b ? f . clone ( b ) : { } , a = this . _prepareModel ( a , b ) ; if ( ! a ) return ! 1 ; b . wait || c . add ( a , b ) ; var d = b . success ; b . success = function ( e , f ) { b . wait && c . add ( e , b ) ; d ? d ( e , f ) : e . trigger ( "sync" , a , f , b ) } ; a . save ( null , b ) ; return a } , parse : function ( a ) { return a } , chain : function ( ) { return f ( this . models ) . chain ( ) } , _reset : function ( ) { this . length = 0 ; this . models = [ ] ; this . _byId = { } ; this . _byCid = { } } , _prepareModel : function ( a , b ) { a instanceof g . Model ? a . collection ||
( a . collection = this ) : ( b . collection = this , a = new this . model ( a , b ) , a . _validate ( a . attributes , b ) || ( a = ! 1 ) ) ; return a } , _removeReference : function ( a ) { this == a . collection && delete a . collection ; a . off ( "all" , this . _onModelEvent , this ) } , _onModelEvent : function ( a , b , c , d ) { ( "add" == a || "remove" == a ) && c != this || ( "destroy" == a && this . remove ( b , d ) , b && a === "change:" + b . idAttribute && ( delete this . _byId [ b . previous ( b . idAttribute ) ] , this . _byId [ b . id ] = b ) , this . trigger . apply ( this , arguments ) ) } } ) ; f . each ( "forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy" . split ( "," ) ,
function ( a ) { g . Collection . prototype [ a ] = function ( ) { return f [ a ] . apply ( f , [ this . models ] . concat ( f . toArray ( arguments ) ) ) } } ) ; g . Router = function ( a ) { a || ( a = { } ) ; a . routes && ( this . routes = a . routes ) ; this . _bindRoutes ( ) ; this . initialize . apply ( this , arguments ) } ; var u = /:\w+/g , v = /\*\w+/g , w = /[-[\]{}()+?.,\\^$|#\s]/g ; f . extend ( g . Router . prototype , g . Events , { initialize : function ( ) { } , route : function ( a , b , c ) { g . history || ( g . history = new g . History ) ; f . isRegExp ( a ) || ( a = this . _routeToRegExp ( a ) ) ; c || ( c = this [ b ] ) ; g . history . route ( a , f . bind ( function ( d ) { d =
this . _extractParameters ( a , d ) ; c && c . apply ( this , d ) ; this . trigger . apply ( this , [ "route:" + b ] . concat ( d ) ) ; g . history . trigger ( "route" , this , b , d ) } , this ) ) ; return this } , navigate : function ( a , b ) { g . history . navigate ( a , b ) } , _bindRoutes : function ( ) { if ( this . routes ) { var a = [ ] , b ; for ( b in this . routes ) a . unshift ( [ b , this . routes [ b ] ] ) ; b = 0 ; for ( var c = a . length ; b < c ; b ++ ) this . route ( a [ b ] [ 0 ] , a [ b ] [ 1 ] , this [ a [ b ] [ 1 ] ] ) } } , _routeToRegExp : function ( a ) { a = a . replace ( w , "\\$&" ) . replace ( u , "([^/]+)" ) . replace ( v , "(.*?)" ) ; return RegExp ( "^" + a + "$" ) } , _extractParameters : function ( a ,
b ) { return a . exec ( b ) . slice ( 1 ) } } ) ; g . History = function ( ) { this . handlers = [ ] ; f . bindAll ( this , "checkUrl" ) } ; var m = /^[#\/]/ , x = /msie [\w.]+/ , l = ! 1 ; f . extend ( g . History . prototype , g . Events , { interval : 50 , getFragment : function ( a , b ) { if ( null == a ) if ( this . _hasPushState || b ) { var a = window . location . pathname , c = window . location . search ; c && ( a += c ) } else a = window . location . hash ; a = decodeURIComponent ( a ) ; a . indexOf ( this . options . root ) || ( a = a . substr ( this . options . root . length ) ) ; return a . replace ( m , "" ) } , start : function ( a ) { if ( l ) throw Error ( "Backbone.history has already been started" ) ;
this . options = f . extend ( { } , { root : "/" } , this . options , a ) ; this . _wantsHashChange = ! 1 !== this . options . hashChange ; this . _wantsPushState = ! ! this . options . pushState ; this . _hasPushState = ! ( ! this . options . pushState || ! window . history || ! window . history . pushState ) ; var a = this . getFragment ( ) , b = document . documentMode ; if ( b = x . exec ( navigator . userAgent . toLowerCase ( ) ) && ( ! b || 7 >= b ) ) this . iframe = h ( '<iframe src="javascript:0" tabindex="-1" />' ) . hide ( ) . appendTo ( "body" ) [ 0 ] . contentWindow , this . navigate ( a ) ; this . _hasPushState ? h ( window ) . bind ( "popstate" ,
this . checkUrl ) : this . _wantsHashChange && "onhashchange" in window && ! b ? h ( window ) . bind ( "hashchange" , this . checkUrl ) : this . _wantsHashChange && ( this . _checkUrlInterval = setInterval ( this . checkUrl , this . interval ) ) ; this . fragment = a ; l = ! 0 ; a = window . location ; b = a . pathname == this . options . root ; if ( this . _wantsHashChange && this . _wantsPushState && ! this . _hasPushState && ! b ) return this . fragment = this . getFragment ( null , ! 0 ) , window . location . replace ( this . options . root + "#" + this . fragment ) , ! 0 ; this . _wantsPushState && this . _hasPushState && b && a . hash &&
( this . fragment = a . hash . replace ( m , "" ) , window . history . replaceState ( { } , document . title , a . protocol + "//" + a . host + this . options . root + this . fragment ) ) ; if ( ! this . options . silent ) return this . loadUrl ( ) } , stop : function ( ) { h ( window ) . unbind ( "popstate" , this . checkUrl ) . unbind ( "hashchange" , this . checkUrl ) ; clearInterval ( this . _checkUrlInterval ) ; l = ! 1 } , route : function ( a , b ) { this . handlers . unshift ( { route : a , callback : b } ) } , checkUrl : function ( ) { var a = this . getFragment ( ) ; a == this . fragment && this . iframe && ( a = this . getFragment ( this . iframe . location . hash ) ) ;
if ( a == this . fragment || a == decodeURIComponent ( this . fragment ) ) return ! 1 ; this . iframe && this . navigate ( a ) ; this . loadUrl ( ) || this . loadUrl ( window . location . hash ) } , loadUrl : function ( a ) { var b = this . fragment = this . getFragment ( a ) ; return f . any ( this . handlers , function ( a ) { if ( a . route . test ( b ) ) return a . callback ( b ) , ! 0 } ) } , navigate : function ( a , b ) { if ( ! l ) return ! 1 ; if ( ! b || ! 0 === b ) b = { trigger : b } ; var c = ( a || "" ) . replace ( m , "" ) ; this . fragment == c || this . fragment == decodeURIComponent ( c ) || ( this . _hasPushState ? ( 0 != c . indexOf ( this . options . root ) && ( c =
this . options . root + c ) , this . fragment = c , window . history [ b . replace ? "replaceState" : "pushState" ] ( { } , document . title , c ) ) : this . _wantsHashChange ? ( this . fragment = c , this . _updateHash ( window . location , c , b . replace ) , this . iframe && c != this . getFragment ( this . iframe . location . hash ) && ( b . replace || this . iframe . document . open ( ) . close ( ) , this . _updateHash ( this . iframe . location , c , b . replace ) ) ) : window . location . assign ( this . options . root + a ) , b . trigger && this . loadUrl ( a ) ) } , _updateHash : function ( a , b , c ) { c ? a . replace ( a . toString ( ) . replace ( /(javascript:|#).*$/ ,
"" ) + "#" + b ) : a . hash = b } } ) ; g . View = function ( a ) { this . cid = f . uniqueId ( "view" ) ; this . _configure ( a || { } ) ; this . _ensureElement ( ) ; this . initialize . apply ( this , arguments ) ; this . delegateEvents ( ) } ; var y = /^(\S+)\s*(.*)$/ , p = "model,collection,el,id,attributes,className,tagName" . split ( "," ) ; f . extend ( g . View . prototype , g . Events , { tagName : "div" , $ : function ( a ) { return this . $el . find ( a ) } , initialize : function ( ) { } , render : function ( ) { return this } , remove : function ( ) { this . $el . remove ( ) ; return this } , make : function ( a , b , c ) { a = document . createElement ( a ) ;
b && h ( a ) . attr ( b ) ; c && h ( a ) . html ( c ) ; return a } , setElement : function ( a , b ) { this . $el = h ( a ) ; this . el = this . $el [ 0 ] ; ! 1 !== b && this . delegateEvents ( ) ; return this } , delegateEvents : function ( a ) { if ( a || ( a = j ( this , "events" ) ) ) { this . undelegateEvents ( ) ; for ( var b in a ) { var c = a [ b ] ; f . isFunction ( c ) || ( c = this [ a [ b ] ] ) ; if ( ! c ) throw Error ( 'Event "' + a [ b ] + '" does not exist' ) ; var d = b . match ( y ) , e = d [ 1 ] , d = d [ 2 ] , c = f . bind ( c , this ) , e = e + ( ".delegateEvents" + this . cid ) ; "" === d ? this . $el . bind ( e , c ) : this . $el . delegate ( d , e , c ) } } } , undelegateEvents : function ( ) { this . $el . unbind ( ".delegateEvents" +
this . cid ) } , _configure : function ( a ) { this . options && ( a = f . extend ( { } , this . options , a ) ) ; for ( var b = 0 , c = p . length ; b < c ; b ++ ) { var d = p [ b ] ; a [ d ] && ( this [ d ] = a [ d ] ) } this . options = a } , _ensureElement : function ( ) { if ( this . el ) this . setElement ( this . el , ! 1 ) ; else { var a = j ( this , "attributes" ) || { } ; this . id && ( a . id = this . id ) ; this . className && ( a [ "class" ] = this . className ) ; this . setElement ( this . make ( this . tagName , a ) , ! 1 ) } } } ) ; g . Model . extend = g . Collection . extend = g . Router . extend = g . View . extend = function ( a , b ) { var c = z ( this , a , b ) ; c . extend = this . extend ; return c } ;
var A = { create : "POST" , update : "PUT" , "delete" : "DELETE" , read : "GET" } ; g . sync = function ( a , b , c ) { var d = A [ a ] , e = { type : d , dataType : "json" } ; c . url || ( e . url = j ( b , "url" ) || o ( ) ) ; if ( ! c . data && b && ( "create" == a || "update" == a ) ) e . contentType = "application/json" , e . data = JSON . stringify ( b . toJSON ( ) ) ; g . emulateJSON && ( e . contentType = "application/x-www-form-urlencoded" , e . data = e . data ? { model : e . data } : { } ) ; if ( g . emulateHTTP && ( "PUT" === d || "DELETE" === d ) ) g . emulateJSON && ( e . data . _method = d ) , e . type = "POST" , e . beforeSend = function ( a ) { a . setRequestHeader ( "X-HTTP-Method-Override" ,
d ) } ; "GET" !== e . type && ! g . emulateJSON && ( e . processData = ! 1 ) ; return h . ajax ( f . extend ( e , c ) ) } ; g . wrapError = function ( a , b , c ) { return function ( d , e ) { e = d === b ? e : d ; a ? a ( b , e , c ) : b . trigger ( "error" , b , e , c ) } } ; var q = function ( ) { } , z = function ( a , b , c ) { var d ; d = b && b . hasOwnProperty ( "constructor" ) ? b . constructor : function ( ) { a . apply ( this , arguments ) } ; f . extend ( d , a ) ; q . prototype = a . prototype ; d . prototype = new q ; b && f . extend ( d . prototype , b ) ; c && f . extend ( d , c ) ; d . prototype . constructor = d ; d . _ _super _ _ = a . prototype ; return d } , j = function ( a , b ) { return ! a || ! a [ b ] ?
null : f . isFunction ( a [ b ] ) ? a [ b ] ( ) : a [ b ] } , o = function ( ) { throw Error ( 'A "url" property or function must be specified' ) ; } } ) . call ( this ) ;
/ * !
* Bootstrap . js by @ fat & @ mdo
* Copyright 2012 Twitter , Inc .
* http : //www.apache.org/licenses/LICENSE-2.0.txt
* /
! function ( a ) { a ( function ( ) { "use strict" , a . support . transition = function ( ) { var a = function ( ) { var a = document . createElement ( "bootstrap" ) , b = { WebkitTransition : "webkitTransitionEnd" , MozTransition : "transitionend" , OTransition : "oTransitionEnd" , msTransition : "MSTransitionEnd" , transition : "transitionend" } , c ; for ( c in b ) if ( a . style [ c ] !== undefined ) return b [ c ] } ( ) ; return a && { end : a } } ( ) } ) } ( window . jQuery ) , ! function ( a ) { "use strict" ; var b = '[data-dismiss="alert"]' , c = function ( c ) { a ( c ) . on ( "click" , b , this . close ) } ; c . prototype . close = function ( b ) { function f ( ) { e . trigger ( "closed" ) . remove ( ) } var c = a ( this ) , d = c . attr ( "data-target" ) , e ; d || ( d = c . attr ( "href" ) , d = d && d . replace ( /.*(?=#[^\s]*$)/ , "" ) ) , e = a ( d ) , b && b . preventDefault ( ) , e . length || ( e = c . hasClass ( "alert" ) ? c : c . parent ( ) ) , e . trigger ( b = a . Event ( "close" ) ) ; if ( b . isDefaultPrevented ( ) ) return ; e . removeClass ( "in" ) , a . support . transition && e . hasClass ( "fade" ) ? e . on ( a . support . transition . end , f ) : f ( ) } , a . fn . alert = function ( b ) { return this . each ( function ( ) { var d = a ( this ) , e = d . data ( "alert" ) ; e || d . data ( "alert" , e = new c ( this ) ) , typeof b == "string" && e [ b ] . call ( d ) } ) } , a . fn . alert . Constructor = c , a ( function ( ) { a ( "body" ) . on ( "click.alert.data-api" , b , c . prototype . close ) } ) } ( window . jQuery ) , ! function ( a ) { "use strict" ; var b = function ( b , c ) { this . $element = a ( b ) , this . options = a . extend ( { } , a . fn . button . defaults , c ) } ; b . prototype . setState = function ( a ) { var b = "disabled" , c = this . $element , d = c . data ( ) , e = c . is ( "input" ) ? "val" : "html" ; a += "Text" , d . resetText || c . data ( "resetText" , c [ e ] ( ) ) , c [ e ] ( d [ a ] || this . options [ a ] ) , setTimeout ( function ( ) { a == "loadingText" ? c . addClass ( b ) . attr ( b , b ) : c . removeClass ( b ) . removeAttr ( b ) } , 0 ) } , b . prototype . toggle = function ( ) { var a = this . $element . parent ( '[data-toggle="buttons-radio"]' ) ; a && a . find ( ".active" ) . removeClass ( "active" ) , this . $element . toggleClass ( "active" ) } , a . fn . button = function ( c ) { return this . each ( function ( ) { var d = a ( this ) , e = d . data ( "button" ) , f = typeof c == "object" && c ; e || d . data ( "button" , e = new b ( this , f ) ) , c == "toggle" ? e . toggle ( ) : c && e . setState ( c ) } ) } , a . fn . button . defaults = { loadingText : "loading..." } , a . fn . button . Constructor = b , a ( function ( ) { a ( "body" ) . on ( "click.button.data-api" , "[data-toggle^=button]" , function ( b ) { var c = a ( b . target ) ; c . hasClass ( "btn" ) || ( c = c . closest ( ".btn" ) ) , c . button ( "toggle" ) } ) } ) } ( window . jQuery ) , ! function ( a ) { "use strict" ; var b = function ( b , c ) { this . $element = a ( b ) , this . options = c , this . options . slide && this . slide ( this . options . slide ) , this . options . pause == "hover" && this . $element . on ( "mouseenter" , a . proxy ( this . pause , this ) ) . on ( "mouseleave" , a . proxy ( this . cycle , this ) ) } ; b . prototype = { cycle : function ( b ) { return b || ( this . paused = ! 1 ) , this . options . interval && ! this . paused && ( this . interval = setInterval ( a . proxy ( this . next , this ) , this . options . interval ) ) , this } , to : function ( b ) { var c = this . $element . find ( ".active" ) , d = c . parent ( ) . children ( ) , e = d . index ( c ) , f = this ; if ( b > d . length - 1 || b < 0 ) return ; return this . sliding ? this . $element . one ( "slid" , function ( ) { f . to ( b ) } ) : e == b ? this . pause ( ) . cycle ( ) : this . slide ( b > e ? "next" : "prev" , a ( d [ b ] ) ) } , pause : function ( a ) { return a || ( this . paused = ! 0 ) , clearInterval ( this . interval ) , this . interval = null , this } , next : function ( ) { if ( this . sliding ) return ; return this . slide ( "next" ) } , prev : function ( ) { if ( this . sliding ) return ; return this . slide ( "prev" ) } , slide : function ( b , c ) { var d = this . $element . find ( ".active" ) , e = c || d [ b ] ( ) , f = this . interval , g = b == "next" ? "left" : "right" , h = b == "next" ? "first" : "last" , i = this , j = a . Event ( "slide" ) ; this . sliding = ! 0 , f && this . pause ( ) , e = e . length ? e : this . $element . find ( ".item" ) [ h ] ( ) ; if ( e . hasClass ( "active" ) ) return ; if ( a . support . transition && this . $element . hasClass ( "slide" ) ) { this . $element . trigger ( j ) ; if ( j . isDefaultPrevented ( ) ) return ; e . addClass ( b ) , e [ 0 ] . offsetWidth , d . addClass ( g ) , e . addClass ( g ) , this . $element . one ( a . support . transition . end , function ( ) { e . removeClass ( [ b , g ] . join ( " " ) ) . addClass ( "active" ) , d . removeClass ( [ "active" , g ] . join ( " " ) ) , i . sliding = ! 1 , setTimeout ( function ( ) { i . $element . trigger ( "slid" ) } , 0 ) } ) } else { this . $element . trigger ( j ) ; if ( j . isDefaultPrevented ( ) ) return ; d . removeClass ( "active" ) , e . addClass ( "active" ) , this . sliding = ! 1 , this . $element . trigger ( "slid" ) } return f && this . cycle ( ) , this } } , a . fn . carousel = function ( c ) { return this . each ( function ( ) { var d = a ( this ) , e = d . data ( "carousel" ) , f = a . extend ( { } , a . fn . carousel . defaults , typeof c == "object" && c ) ; e || d . data ( " c
( function ( jQuery ) { jQuery . hotkeys = { version : "0.8" , specialKeys : { 8 : "backspace" , 9 : "tab" , 13 : "return" , 16 : "shift" , 17 : "ctrl" , 18 : "alt" , 19 : "pause" , 20 : "capslock" , 27 : "esc" , 32 : "space" , 33 : "pageup" , 34 : "pagedown" , 35 : "end" , 36 : "home" , 37 : "left" , 38 : "up" , 39 : "right" , 40 : "down" , 45 : "insert" , 46 : "del" , 96 : "0" , 97 : "1" , 98 : "2" , 99 : "3" , 100 : "4" , 101 : "5" , 102 : "6" , 103 : "7" , 104 : "8" , 105 : "9" , 106 : "*" , 107 : "+" , 109 : "-" , 110 : "." , 111 : "/" , 112 : "f1" , 113 : "f2" , 114 : "f3" , 115 : "f4" , 116 : "f5" , 117 : "f6" , 118 : "f7" , 119 : "f8" , 120 : "f9" , 121 : "f10" , 122 : "f11" , 123 : "f12" , 144 : "numlock" , 145 : "scroll" , 191 : "/" , 224 : "meta" } , shiftNums : { "`" : "~" , "1" : "!" , "2" : "@" , "3" : "#" , "4" : "$" , "5" : "%" , "6" : "^" , "7" : "&" , "8" : "*" , "9" : "(" , "0" : ")" , "-" : "_" , "=" : "+" , ";" : ": " , "'" : "\"" , "," : "<" , "." : ">" , "/" : "?" , "\\" : "|" } } ; function keyHandler ( handleObj ) { if ( typeof handleObj . data !== "string" ) { return ; }
var origHandler = handleObj . handler , keys = handleObj . data . toLowerCase ( ) . split ( " " ) ; handleObj . handler = function ( event ) { if ( this !== event . target && ( /textarea|select/i . test ( event . target . nodeName ) || event . target . type === "text" || event . target . type === "password" ) ) { return ; }
var special = event . type !== "keypress" && jQuery . hotkeys . specialKeys [ event . which ] , character = String . fromCharCode ( event . which ) . toLowerCase ( ) , key , modif = "" , possible = { } ; if ( event . altKey && special !== "alt" ) { modif += "alt+" ; }
if ( event . ctrlKey && special !== "ctrl" ) { modif += "ctrl+" ; }
if ( event . metaKey && ! event . ctrlKey && special !== "meta" ) { modif += "meta+" ; }
if ( event . shiftKey && special !== "shift" ) { modif += "shift+" ; }
if ( special ) { possible [ modif + special ] = true ; } else { possible [ modif + character ] = true ; possible [ modif + jQuery . hotkeys . shiftNums [ character ] ] = true ; if ( modif === "shift+" ) { possible [ jQuery . hotkeys . shiftNums [ character ] ] = true ; } }
for ( var i = 0 , l = keys . length ; i < l ; i ++ ) { if ( possible [ keys [ i ] ] ) { return origHandler . apply ( this , arguments ) ; } } } ; }
jQuery . each ( [ "keydown" , "keyup" , "keypress" ] , function ( ) { jQuery . event . special [ this ] = { add : keyHandler } ; } ) ; } ) ( jQuery ) ;
( function ( $ ) { $ . InFieldLabels = function ( label , field , options ) { var base = this ; base . $label = $ ( label ) ; base . label = label ; base . $field = $ ( field ) ; base . field = field ; base . $label . data ( "InFieldLabels" , base ) ; base . showing = true ; base . init = function ( ) { base . options = $ . extend ( { } , $ . InFieldLabels . defaultOptions , options ) ; if ( base . $field . val ( ) !== "" ) { base . $label . hide ( ) ; base . showing = false ; }
base . $field . focus ( function ( ) { base . fadeOnFocus ( ) ; } ) . blur ( function ( ) { base . checkForEmpty ( true ) ; } ) . bind ( 'keydown.infieldlabel' , function ( e ) { base . hideOnChange ( e ) ; } ) . bind ( 'paste' , function ( e ) { base . setOpacity ( 0.0 ) ; } ) . change ( function ( e ) { base . checkForEmpty ( ) ; } ) . bind ( 'onPropertyChange' , function ( ) { base . checkForEmpty ( ) ; } ) ; } ; base . fadeOnFocus = function ( ) { if ( base . showing ) { base . setOpacity ( base . options . fadeOpacity ) ; } } ; base . setOpacity = function ( opacity ) { base . $label . stop ( ) . animate ( { opacity : opacity } , base . options . fadeDuration ) ; base . showing = ( opacity > 0.0 ) ; } ; base . checkForEmpty = function ( blur ) { if ( base . $field . val ( ) === "" ) { base . prepForShow ( ) ; base . setOpacity ( blur ? 1.0 : base . options . fadeOpacity ) ; } else { base . setOpacity ( 0.0 ) ; } } ; base . prepForShow = function ( e ) { if ( ! base . showing ) { base . $label . css ( { opacity : 0.0 } ) . show ( ) ; base . $field . bind ( 'keydown.infieldlabel' , function ( e ) { base . hideOnChange ( e ) ; } ) ; } } ; base . hideOnChange = function ( e ) { if ( ( e . keyCode === 16 ) || ( e . keyCode === 9 ) || ( e . keyCode === 27 ) ) { return ; }
if ( base . showing ) { base . $label . hide ( ) ; base . showing = false ; }
base . $field . unbind ( 'keydown.infieldlabel' ) ; } ; base . init ( ) ; } ; $ . InFieldLabels . defaultOptions = { fadeOpacity : 0.5 , fadeDuration : 300 } ; $ . fn . inFieldLabels = function ( options ) { return this . each ( function ( ) { var for _attr = $ ( this ) . attr ( 'for' ) , $field ; if ( ! for _attr ) { return ; }
$field = $ ( "input#" + for _attr + "[type='text']," + "input#" + for _attr + "[type='search']," + "input#" + for _attr + "[type='tel']," + "input#" + for _attr + "[type='url']," + "input#" + for _attr + "[type='email']," + "input#" + for _attr + "[type='password']," + "textarea#" + for _attr ) ; if ( $field . length === 0 ) { return ; }
( new $ . InFieldLabels ( this , $field [ 0 ] , options ) ) ; } ) ; } ; } ( jQuery ) ) ;
// Chosen, a Select Box Enhancer for jQuery and Protoype
// by Patrick Filler for Harvest, http://getharvest.com
//
// Version 0.9.8
// Full source at https://github.com/harvesthq/chosen
// Copyright (c) 2011 Harvest http://getharvest.com
// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
// This file is generated by `cake build`, do not edit it by hand.
( ( function ( ) { var a ; a = function ( ) { function a ( ) { this . options _index = 0 , this . parsed = [ ] } return a . prototype . add _node = function ( a ) { return a . nodeName === "OPTGROUP" ? this . add _group ( a ) : this . add _option ( a ) } , a . prototype . add _group = function ( a ) { var b , c , d , e , f , g ; b = this . parsed . length , this . parsed . push ( { array _index : b , group : ! 0 , label : a . label , children : 0 , disabled : a . disabled } ) , f = a . childNodes , g = [ ] ; for ( d = 0 , e = f . length ; d < e ; d ++ ) c = f [ d ] , g . push ( this . add _option ( c , b , a . disabled ) ) ; return g } , a . prototype . add _option = function ( a , b , c ) { if ( a . nodeName === "OPTION" ) return a . text !== "" ? ( b != null && ( this . parsed [ b ] . children += 1 ) , this . parsed . push ( { array _index : this . parsed . length , options _index : this . options _index , value : a . value , text : a . text , html : a . innerHTML , selected : a . selected , disabled : c === ! 0 ? c : a . disabled , group _array _index : b , classes : a . className , style : a . style . cssText } ) ) : this . parsed . push ( { array _index : this . parsed . length , options _index : this . options _index , empty : ! 0 } ) , this . options _index += 1 } , a } ( ) , a . select _to _array = function ( b ) { var c , d , e , f , g ; d = new a , g = b . childNodes ; for ( e = 0 , f = g . length ; e < f ; e ++ ) c = g [ e ] , d . add _node ( c ) ; return d . parsed } , this . SelectParser = a } ) ) . call ( this ) , function ( ) { var a , b ; b = this , a = function ( ) { function a ( a , b ) { this . form _field = a , this . options = b != null ? b : { } , this . set _default _values ( ) , this . is _multiple = this . form _field . multiple , this . default _text _default = this . is _multiple ? "Select Some Options" : "Select an Option" , this . setup ( ) , this . set _up _html ( ) , this . register _observers ( ) , this . finish _setup ( ) } return a . prototype . set _default _values = function ( ) { var a = this ; return this . click _test _action = function ( b ) { return a . test _active _click ( b ) } , this . activate _action = function ( b ) { return a . activate _field ( b ) } , this . active _field = ! 1 , this . mouse _on _container = ! 1 , this . results _showing = ! 1 , this . result _highlighted = null , this . result _single _selected = null , this . allow _single _deselect = this . options . allow _single _deselect != null && this . form _field . options [ 0 ] != null && this . form _field . options [ 0 ] . text === "" ? this . options . allow _single _deselect : ! 1 , this . disable _search _threshold = this . options . disable _search _threshold || 0 , this . search _contains = this . options . search _contains || ! 1 , this . choices = 0 , this . results _none _found = this . options . no _results _text || "No results match" } , a . prototype . mouse _enter = function ( ) { return this . mouse _on _container = ! 0 } , a . prototype . mouse _leave = function ( ) { return this . mouse _on _container = ! 1 } , a . prototype . input _focus = function ( a ) { var b = this ; if ( ! this . active _field ) return setTimeout ( function ( ) { return b . container _mousedown ( ) } , 50 ) } , a . prototype . input _blur = function ( a ) { var b = this ; if ( ! this . mouse _on _container ) return this . active _field = ! 1 , setTimeout ( function ( ) { return b . blur _test ( ) } , 100 ) } , a . prototype . result _add _option = function ( a ) { var b , c ; return a . disabled ? "" : ( a . dom _id = this . container _id + "_o_" + a . array _index , b = a . selected && this . is _multiple ? [ ] : [ "active-result" ] , a . selected && b . push ( "result-selected" ) , a . group _array _index != null && b . push ( "group-option" ) , a . classes !== "" && b . push ( a . classes ) , c = a . style . cssText !== "" ? ' style="' + a . style + '"' : "" , '<li id="' + a . dom _id + '" class="' + b . join ( " " ) + '"' + c + ">" + a . html + "</li>" ) } , a . prototype . results _update _field = function ( ) { return this . result _clear _highlight ( ) , this . result _single _selected = null , this . results _build ( ) } , a . prototype . results _toggle = function ( ) { return this . results _showing ? this . results _hide ( ) : this . results _show ( ) } , a . prototype . results _search = function ( a ) { return this . results _showing ? this . winnow _results ( ) : this . results _show ( ) } , a . prototype . keyup _checker = function ( a ) { var b , c ; b = ( c = a . which ) != null ? c : a . keyCode , this . search _field _scale ( ) ; switch ( b ) { case 8 : if ( this . is _multiple && this . backstroke _length < 1 && this . choices > 0 ) return this . keydown _backstroke ( ) ; if ( ! this . pending _backstroke ) return this . result _clear _highlight ( ) , this . results _search ( ) ; break ; case 13 : a . preventDefault ( ) ; if ( this . results _showing ) return this . result _select ( a ) ; break ; case 27 : return this . results _showing && this . results _hide ( ) , ! 0 ; case 9 : case 38 : case 40 : case 16 : case 91 : case 17 : break ; default : return this . results _search ( ) } } , a . prototype . generate _field _id = function ( ) { var a ; return a = this . generate _random _id ( ) , this . form _field . id = a , a } , a . prototype . generate _random _char = function ( ) { var a , b , c ; return a = " 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXT
var snipt = { module : function ( ) { var modules = { } ; return function ( name ) { if ( modules [ name ] ) { return modules [ name ] ; }
return modules [ name ] = { } ; } ; } ( ) } ; jQuery ( function ( $ ) { var SiteView = snipt . module ( 'site' ) . SiteView ; window . site = new SiteView ( ) ; if ( window . detail && ! window . blog _post ) { window . site . $snipts . eq ( 0 ) . trigger ( 'selectSnipt' ) ; } } ) ;
2012-07-08 09:25:15 -07:00
( function ( Site ) { var Snipt = snipt . module ( 'snipt' ) ; Backbone . oldSync = Backbone . sync ; Backbone . Model . prototype . idAttribute = 'resource_uri' ; var addSlash = function ( str ) { return str + ( ( str . length > 0 && str . charAt ( str . length - 1 ) === '/' ) ? '' : '/' ) ; } ; Backbone . sync = function ( method , model , options ) { options . headers = _ . extend ( { 'Authorization' : 'ApiKey ' + window . user + ':' + window . api _key } , options . headers ) ; return Backbone . oldSync ( method , model , options ) ; } ; Backbone . Model . prototype . url = function ( ) { var url = this . id ; if ( ! url ) { url = this . urlRoot ; url = url || this . collection && ( _ . isFunction ( this . collection . url ) ? this . collection . url ( ) : this . collection . url ) ; if ( url && this . has ( 'id' ) ) { url = addSlash ( url ) + this . get ( 'id' ) ; } }
2012-06-20 13:25:41 -07:00
url = url && addSlash ( url ) ; if ( typeof url === 'undefined' ) { url = '/api/private/snipt/' ; this . unset ( 'id' , { 'silent' : true } ) ; this . unset ( 'user' , { 'silent' : true } ) ; }
2012-07-08 09:25:15 -07:00
return url || null ; } ; Site . SiteView = Backbone . View . extend ( { el : 'body' , initialize : function ( opts ) { this . $body = $ ( this . el ) ; this . $html = $ ( 'html' ) ; this . $html _body = this . $body . add ( this . $html ) ; this . $aside _nav = $ ( 'aside.nav' , this . $body ) ; this . $aside _nav _ul = $ ( 'ul' , this . $aside _nav ) ; this . $search _form = $ ( 'form.search' , this . $body ) ; this . $search _query = $ ( 'input#search-query' , this . $body ) ; this . $search _page _query = $ ( 'input.search-query' , this . $body ) ; this . $search _queries = this . $search _query . add ( this . $search _page _query ) ; this . $snipts = $ ( 'section#snipts article.snipt' , this . $body ) ; this . $modals = $ ( 'div.modal' , this . $snipts ) ; this . $main _edit = $ ( 'section#main-edit' ) ; this . $main = $ ( 'section#main' ) ; this . $keyboard _shortcuts = $ ( '#keyboard-shortcuts' , this . $body ) ; this . $amazon _ads = $ ( 'section.amazon' , this . $main ) ; this . keyboardShortcuts ( ) ; this . inFieldLabels ( ) ; if ( this . $amazon _ads . length ) { this . initAmazonAds ( ) ; }
var SniptListView = Snipt . SniptListView ; this . snipt _list = new SniptListView ( { 'snipts' : this . $snipts } ) ; var that = this ; this . $body . click ( function ( ) { if ( ! window . ui _halted && ! window . from _modal && window . $selected ) { window . $selected . trigger ( 'deselect' ) ; }
2012-06-20 13:25:41 -07:00
if ( window . from _modal ) { window . from _modal = false ; }
2012-07-08 09:25:15 -07:00
that . $aside _nav . removeClass ( 'open' ) ; } ) ; this . $aside _nav _ul . click ( function ( e ) { e . stopPropagation ( ) ; } ) ; $search _queries = this . $search _queries ; $search _queries . focus ( function ( ) { if ( window . $selected ) { $selected . trigger ( 'deselect' ) ; } } ) ; this . $body . on ( 'click' , 'a.close' , function ( ) { $ ( this ) . parent ( ) . parent ( ) . modal ( 'hide' ) ; window . ui _halted = false ; return false ; } ) ; this . $keyboard _shortcuts . on ( 'hidden' , function ( ) { window . ui _halted = false ; } ) ; window . ui _halted = false ; } , events : { 'showKeyboardShortcuts' : 'showKeyboardShortcuts' , 'click a.mini-profile' : 'toggleMiniProfile' } , keyboardShortcuts : function ( ) { var $body = this . $body ; var that = this ; $search _queries = this . $search _queries ; $search _page _query = this . $search _page _query ; $search _query = this . $search _query ; $document = $ ( document ) ; $document . bind ( 'keydown' , '/' , function ( e ) { if ( ! window . ui _halted ) { e . preventDefault ( ) ; if ( $body . hasClass ( 'search' ) ) { $search _page _query . focus ( ) ; } else { $search _query . focus ( ) ; } } } ) ; $document . bind ( 'keydown' , 'h' , function ( e ) { if ( ! window . ui _halted ) { window . ui _halted = true ; $body . trigger ( 'showKeyboardShortcuts' ) ; } else { if ( that . $keyboard _shortcuts . is ( ':visible' ) ) { that . $keyboard _shortcuts . modal ( 'hide' ) ; } } } ) ; $document . bind ( 'keydown' , 't' , function ( e ) { if ( ! window . ui _halted ) { window . open ( '' , '_blank' ) ; } } ) ; $document . bind ( 'keydown' , 'r' , function ( e ) { if ( ! window . ui _halted ) { location . reload ( true ) ; } } ) ; $document . bind ( 'keydown' , 'Ctrl+h' , function ( e ) { if ( ! window . ui _halted ) { history . go ( - 1 ) ; } } ) ; $document . bind ( 'keydown' , 'Ctrl+l' , function ( e ) { if ( ! window . ui _halted ) { history . go ( 1 ) ; } } ) ; this . $search _queries . bind ( 'keydown' , 'esc' , function ( e ) { if ( ! window . ui _halted ) { e . preventDefault ( ) ; this . blur ( ) ; } } ) ; } , showKeyboardShortcuts : function ( ) { this . $keyboard _shortcuts . modal ( 'toggle' ) ; } , toggleMiniProfile : function ( e ) { this . $aside _nav . toggleClass ( 'open' ) ; return false ; } , inFieldLabels : function ( ) { $ ( 'div.infield label' , this . $body ) . inFieldLabels ( { fadeDuration : 200 } ) ; } , initAmazonAds : function ( ) { var $more = $ ( 'div.more' , this . $amazon _ads ) ; var that = this ; var adTemplate = $ ( 'script#amazon-ad' ) . html ( ) ; $ ( 'a' , $more ) . on ( 'click' , function ( ) { var $current = $ ( 'li:visible' , that . $amazon _ads ) ; $ ( 'li' , that . $amazon _ads ) . hide ( ) ; if ( $ ( this ) . hasClass ( 'see-previous' ) ) { var $prev = $current . prev ( ) ; if ( $prev . length ) { $prev = $prev ; } else { $prev = $ ( 'li' , that . $amazon _ads ) . eq ( - 1 ) ; }
2012-07-08 19:56:33 -07:00
$prev . fadeIn ( 'fast' ) ; } else { var $next = $current . next ( ) ; if ( $next . length ) { $next = $next ; } else { $next = $ ( 'li' , that . $amazon _ads ) . eq ( 0 ) ; }
$next . fadeIn ( 'fast' ) ; }
2012-07-08 11:32:31 -07:00
return false ; } ) ; $ . getJSON ( '/api/public/a/' , { 'q' : window . tag } , function ( resp ) { if ( resp . result . length === 0 ) { that . $amazon _ads . slideUp ( 'fast' ) ; } else { var html = '' ; for ( var i = 0 ; i < resp . result . length ; i ++ ) { if ( resp . result [ i ] . image ) { html += _ . template ( adTemplate , { url : resp . result [ i ] . url , title : resp . result [ i ] . title , review : resp . result [ i ] . review , image : resp . result [ i ] . image } ) ; } }
2012-07-08 12:09:41 -07:00
$ul = $ ( 'ul' , that . $amazon _ads ) ; $ul . hide ( ) . html ( html ) ; $lis = $ ( 'li' , $ul ) ; $lis . hide ( ) ; $lis . eq ( 0 ) . fadeIn ( 'fast' ) ; if ( $lis . length === 1 ) { $ ( 'a' , $more ) . fadeOut ( 'fast' ) ; }
2012-07-08 11:32:31 -07:00
if ( $lis . length === 0 ) { that . $amazon _ads . slideUp ( 'fast' ) ; }
2012-07-08 12:09:41 -07:00
$ul . show ( ) ; $ ( 'div.more span' , that . $amazon _ads ) . hide ( ) . text ( 'Books' ) . fadeIn ( 'fast' ) ; } } ) ; } } ) ; } ) ( snipt . module ( 'site' ) ) ;
2012-07-08 09:25:15 -07:00
( function ( Snipt ) { Snipt . SniptModel = Backbone . Model . extend ( { toSafe : function ( ) { var snipt = this . toJSON ( ) ; snipt . code = this . escape ( 'code' ) ; snipt . title = this . escape ( 'title' ) ; snipt . tags _list = this . escape ( 'tags_list' ) ; if ( typeof snipt . tags === 'object' ) { for ( var i ; i < snipt . tags . length ; i ++ ) { snipt . tags [ i ] . name = _ . escape ( snipt . tags [ i ] . name ) ; } }
2012-06-20 13:25:41 -07:00
return snipt ; } } ) ; Snipt . SniptView = Backbone . View . extend ( { tagName : 'article' , initialize : function ( ) { this . model . view = this ; this . model . bind ( 'change' , this . render , this ) ; this . template = _ . template ( $ ( '#snipt' ) . html ( ) ) ; this . editTemplate = _ . template ( $ ( '#edit' ) . html ( ) ) ; this . initLocalVars ( ) ; } , events : { 'click a.copy' : 'copyFromClick' , 'click a.edit' : 'edit' , 'click a.favorite' : 'favoriteToggle' , 'click a.embed' : 'embedFromClick' , 'click a.expand' : 'expand' , 'click .container' : 'selectFromClick' , 'copyClose' : 'copyClose' , 'copyRaw' : 'copy' , 'detail' : 'detail' , 'deselect' : 'deselect' , 'destroy' : 'destroy' , 'edit' : 'edit' , 'embed' : 'embed' , 'embedClose' : 'embedClose' , 'expand' : 'expand' , 'fadeAndRemove' : 'fadeAndRemove' , 'goToAuthor' : 'goToAuthor' , 'next' : 'next' , 'prev' : 'prev' , 'selectSnipt' : 'select' } , copy : function ( ) { $ ( 'textarea' , this . $copyModal ) . remove ( ) ; window . ui _halted = true ; this . $copyModalBody . append ( '<textarea class="raw"></textarea>' ) ; $textarea = $ ( 'textarea.raw' , this . $copyModalBody ) . val ( this . model . get ( 'code' ) ) ; this . $copyModal . modal ( 'show' ) ; $textarea . select ( ) ; } , copyClose : function ( ) { $ ( 'textarea' , this . $copyModal ) . remove ( ) ; } , copyFromClick : function ( ) { this . copy ( ) ; return false ; } , deselect : function ( ) { this . $el . removeClass ( 'selected' ) ; window . $selected = false ; } , detail : function ( ) { window . location = this . model . get ( 'absolute_url' ) ; } , destroy : function ( ) { this . model . destroy ( ) ; } , edit : function ( ) { window . editing = true ; window . ui _halted = true ; this . select ( ) ; that = this ; var editPane = this . editTemplate ( { snipt : this . model . toSafe ( ) } ) ; window . site . $main . hide ( ) ; window . site . $body . addClass ( 'detail editing' ) ; window . site . $main _edit . html ( editPane ) ; $ ( 'option[value="' + this . model . get ( 'lexer' ) + '"]' , window . site . $main _edit ) . attr ( 'selected' , 'selected' ) ; $ ( 'select#id_lexer' , window . site . $main _edit ) . chosen ( ) ; $ ( 'label.blog-post input' , window . site . $main _edit ) . on ( 'change' , function ( ) { var $checkbox = $ ( this ) ; var $label = $checkbox . parent ( ) ; var $publish _date = $label . siblings ( 'label.publish-date' ) ; if ( $checkbox . attr ( 'checked' ) ) { $label . removeClass ( 'is-not-blog-post' ) . addClass ( 'is-blog-post' ) ; $publish _date . show ( ) ; } else { $label . addClass ( 'is-not-blog-post' ) . removeClass ( 'is-blog-post' ) ; $publish _date . hide ( ) ; }
return false ; } ) . trigger ( 'change' ) ; $ ( 'label.public input' , window . site . $main _edit ) . on ( 'change' , function ( ) { var $checkbox = $ ( this ) ; var $label = $checkbox . parent ( ) ; if ( $checkbox . attr ( 'checked' ) ) { $label . removeClass ( 'is-private' ) . addClass ( 'is-public' ) ; } else { $label . addClass ( 'is-private' ) . removeClass ( 'is-public' ) ; }
return false ; } ) . trigger ( 'change' ) ; window . site . $main _edit . show ( ) ; $ ( 'div#editor' , window . site . $main _edit ) . css ( 'height' , ( $ ( window ) . height ( ) - 187 ) ) ; window . editor = ace . edit ( 'editor' ) ; window . editor . setTheme ( 'ace/theme/tomorrow' ) ; window . editor . renderer . setShowGutter ( false ) ; window . editor . focus ( ) ; $ ( 'textarea, input' , window . site . $main _edit ) . bind ( 'keydown' , 'esc' , function ( e ) { $ ( this ) . blur ( ) ; return false ; } ) ; $ ( 'button.delete' , window . site . $main _edit ) . on ( 'click' , function ( ) { if ( confirm ( 'Are you sure you want to delete this snipt?' ) ) { that . model . destroy ( ) ; window . site . snipt _list . escapeUI ( true ) ; }
2012-07-08 09:25:15 -07:00
return false ; } ) ; $ ( 'button.cancel' , window . site . $main _edit ) . on ( 'click' , function ( ) { window . site . snipt _list . escapeUI ( ) ; return false ; } ) ; $ ( 'button.save' , window . site . $main _edit ) . on ( 'click' , function ( ) { $ ( 'button.cancel' ) . text ( 'Close' ) ; that . save ( ) ; return false ; } ) ; $ ( 'button.save-and-close' , window . site . $main _edit ) . on ( 'click' , function ( ) { that . save ( ) ; window . site . snipt _list . escapeUI ( ) ; return false ; } ) ; window . scrollTo ( 0 , 0 ) ; return false ; } , embed : function ( ) { $ ( 'textarea' , this . $embedModal ) . remove ( ) ; window . ui _halted = true ; this . $embedModalBody . append ( '<textarea class="raw"></textarea>' ) ; $textarea = $ ( 'textarea.raw' , this . $embedModalBody ) . val ( '<script type="text/javascript" src="' + this . model . get ( 'embed_url' ) + '"></script>' ) ; this . $embedModal . modal ( 'show' ) ; $textarea . select ( ) ; } , embedFromClick : function ( ) { this . embed ( ) ; return false ; } , embedClose : function ( ) { $ ( 'textarea' , this . $embedModal ) . remove ( ) ; } , expand : function ( ) { this . $container . toggleClass ( 'expanded' , 100 ) ; this . $tags . toggleClass ( 'expanded' ) ; this . select ( ) ; return false ; } , fadeAndRemove : function ( ) { var $toRemove = $ ( this . el ) ; var $nextSnipt = $toRemove . next ( 'article.snipt' ) ; window . $selected = false ; $toRemove . fadeOut ( 'fast' , function ( ) { $ ( this ) . remove ( ) ; $nextSnipt . trigger ( 'selectSnipt' ) ; } ) ; return false ; } , goToAuthor : function ( ) { window . location = this . model . get ( 'user' ) . absolute _url ; } , favoriteToggle : function ( ) { var that = this ; if ( this . $el . hasClass ( 'favorited' ) ) { $ . ajax ( '/api/private/favorite/' + this . model . get ( 'favorite_id' ) + '/' , { type : 'delete' , success : function ( ) { that . $el . removeClass ( 'favorited' ) ; that . $favorite . text ( 'Favorite' ) ; } , headers : { 'Authorization' : 'ApiKey ' + window . user + ':' + window . api _key } } ) ; } else { $ . ajax ( '/api/private/favorite/' , { data : '{"snipt": ' + this . model . get ( 'id' ) + '}' , contentType : 'application/json' , type : 'post' , success : function ( resp ) { that . $el . addClass ( 'favorited' ) ; that . model . set ( { 'favorite_id' : resp . id } , { 'silent' : true } ) ; that . $favorite . text ( 'Favorited' ) ; } , headers : { 'Authorization' : 'ApiKey ' + window . user + ':' + window . api _key } } ) ; }
2012-06-20 13:25:41 -07:00
return false ; } , initLocalVars : function ( ) { this . $aside = $ ( 'aside' , this . $el ) ; this . $container = $ ( 'div.container' , this . $el ) ; this . $copyModal = $ ( 'div.copy-modal' , this . $el ) ; this . $copyModalBody = $ ( 'div.modal-body' , this . $copyModal ) ; this . $embedModal = $ ( 'div.embed-modal' , this . $el ) ; this . $embedModalBody = $ ( 'div.modal-body' , this . $embedModal ) ; this . $favorite = $ ( 'a.favorite' , this . $el ) ; this . $h1 = $ ( 'header h1 a' , this . $el ) ; this . $tags = $ ( 'section.tags ul' , this . $aside ) ; this . $copyModal . on ( 'hidden' , function ( e ) { $ ( this ) . parent ( ) . trigger ( 'copyClose' ) ; window . ui _halted = false ; window . from _modal = true ; } ) ; this . $embedModal . on ( 'hidden' , function ( e ) { $ ( this ) . parent ( ) . trigger ( 'embedClose' ) ; window . ui _halted = false ; window . from _modal = true ; } ) ; } , next : function ( ) { if ( ! window . ui _halted ) { nextSnipt = this . $el . next ( 'article.snipt' ) ; if ( nextSnipt . length ) { return nextSnipt . trigger ( 'selectSnipt' ) ; } } } , prev : function ( ) { if ( ! window . ui _halted ) { prevSnipt = this . $el . prev ( 'article.snipt' ) ; if ( prevSnipt . length ) { return prevSnipt . trigger ( 'selectSnipt' ) ; } } } , remove : function ( ) { return false ; } , render : function ( ) { this . $el . html ( this . template ( { snipt : this . model . toSafe ( ) } ) ) ; this . initLocalVars ( ) ; if ( this . model . get ( 'blog_post' ) === true ) { this . $el . addClass ( 'blog-post' ) ; } else { this . $el . removeClass ( 'blog-post' ) ; }
if ( this . model . get ( 'public' ) === true ) { this . $el . removeClass ( 'private-snipt' ) ; } else { this . $el . addClass ( 'private-snipt' ) ; }
if ( this . model . get ( 'user' ) . username === window . user ) { this . $el . addClass ( 'editable' ) ; } else { this . $el . removeClass ( 'editable' ) ; }
if ( this . model . get ( 'line_count' ) > 8 && ! window . detail ) { this . $el . addClass ( 'expandable' ) ; } else { this . $el . removeClass ( 'expandable' ) ; }
$ ( 'script#disqus' ) . remove ( ) ; window . site . $body . append ( '<script id="disqus" type="text/javascript">' + $ ( 'script#disqus-template' ) . text ( ) + '</script>' ) ; if ( this . $el . attr ( 'id' ) === 'new-snipt' ) { this . $el . fadeIn ( 'fast' ) ; this . $el . attr ( 'id' , 'snipt-' + this . model . get ( 'id' ) ) ; }
return this ; } , save : function ( ) { that . model . set ( { 'title' : $ ( 'input#snipt_title' ) . val ( ) , 'tags' : $ ( 'label.tags textarea' ) . val ( ) , 'tags_list' : $ ( 'label.tags textarea' ) . val ( ) , 'lexer' : $ ( 'select[name="lexer"]' ) . val ( ) , 'lexer_name' : $ ( 'select[name="lexer"] option:selected' ) . text ( ) , 'code' : window . editor . getSession ( ) . getValue ( ) , 'blog_post' : $ ( 'label.blog-post input' ) . is ( ':checked' ) , 'publish_date' : $ ( 'label.publish-date input' ) . val ( ) , 'public' : $ ( 'label.public input' ) . is ( ':checked' ) } , { 'silent' : true } ) ; that . model . save ( ) ; } , select : function ( fromClick ) { $ ( 'article.selected' , window . site . snipt _list . $el ) . removeClass ( 'selected' ) ; this . $el . addClass ( 'selected' ) ; if ( fromClick !== true ) { if ( window . site . $snipts . index ( this . $el ) === 0 ) { window . scrollTo ( 0 , 0 ) ; } else { window . site . $html _body . animate ( { scrollTop : this . $el . offset ( ) . top - 50 } , 0 ) ; } }
window . $selected = this . $el ; } , selectFromClick : function ( e ) { this . select ( true ) ; e . stopPropagation ( ) ; window . site . $aside _nav . removeClass ( 'open' ) ; } } ) ; Snipt . SniptListView = Backbone . View . extend ( { el : 'section#snipts' , initialize : function ( opts ) { var that = this ; opts . snipts . each ( this . addExistingSnipt ) ; this . keyboardShortcuts ( ) ; var cmd ; if ( navigator . platform == 'MacPPC' || navigator . platform == 'MacIntel' ) { cmd = 'Cmd' ; }
else { cmd = 'Ctrl' ; }
$ ( 'span.cmd-ctrl' ) . text ( cmd ) ; $ ( 'button#add-snipt' ) . click ( function ( ) { that . addNewSnipt ( ) ; } ) ; } , addExistingSnipt : function ( ) { var $el = $ ( this ) ; var $created = $ ( 'li.created' , $el ) ; var $h1 = $ ( 'header h1 a' , $el ) ; var $public = $ ( 'div.public' , $el ) ; var $blog _post = $ ( 'div.blog-post' , $el ) ; var $publish _date = $ ( 'div.publish-date' , $el ) ; var $user = $ ( 'li.author a' , $el ) ; var is _public = $public . text ( ) === 'True' ? true : false ; var is _blog _post = $blog _post . text ( ) === 'True' ? true : false ; var tag _lis = $ ( 'section.tags li' , $el ) ; var tags = [ ] ; for ( var i = 0 ; i < tag _lis . length ; i ++ ) { var $tag = $ ( 'a' , tag _lis . eq ( i ) ) ; tags [ i ] = { name : $tag . text ( ) , absolute _url : $tag . attr ( 'href' ) } ; }
2012-07-08 09:25:15 -07:00
var data = { code : $ ( 'textarea.raw' , $el ) . text ( ) , created : $created . attr ( 'title' ) , created _formatted : $created . text ( ) , embed _url : $ ( 'div.embed-url' , $el ) . text ( ) , absolute _url : $h1 . attr ( 'href' ) , favorite _id : $el . data ( 'favorite-id' ) , id : parseInt ( $el . attr ( 'id' ) . replace ( 'snipt-' , '' ) , 0 ) , key : $ ( 'div.key' , $el ) . text ( ) , lexer : $ ( 'div.lexer' , $el ) . text ( ) , lexer _name : $ ( 'div.lexer-name' , $el ) . text ( ) , line _count : parseInt ( $ ( 'div.line-count' , $el ) . text ( ) , 0 ) , modified : $ ( 'div.modified' , $el ) . text ( ) , resource _uri : $ ( 'div.resource-uri' , $el ) . text ( ) , slug : $ ( 'div.slug' , $el ) . text ( ) , stylized : $ ( 'div.stylized' , $el ) . text ( ) , tags : tags , publish _date : $publish _date . text ( ) , tags _list : $ ( 'div.tags-list' , $el ) . text ( ) , title : $h1 . text ( ) , user : { absolute _url : $user . attr ( 'href' ) , username : $user . text ( ) } } ; data [ 'public' ] = is _public ; data . blog _post = is _blog _post ; var view = new Snipt . SniptView ( { el : this , model : new Snipt . SniptModel ( data ) } ) ; } , addNewSnipt : function ( ) { var $articleNewSnipt = $ ( 'article#new-snipt' ) ; if ( $articleNewSnipt . length === 0 ) { window . site . snipt _list . $el . prepend ( '<article id="new-snipt" class="hidden snipt"></article>' ) ; var data = { id : '' , code : '' , tags : [ ] , tags _list : '' , title : '' , lexer : 'text' , lexer _name : 'Text only' , new _from _js : true , user : { username : '' } } ; data [ 'public' ] = false ; data . blog _post = false ; var newSniptView = new Snipt . SniptView ( { el : $ ( 'article#new-snipt' ) , model : new Snipt . SniptModel ( data ) } ) ; newSniptView . edit ( ) ; } else { $articleNewSnipt . trigger ( 'edit' ) ; }
2012-06-20 13:25:41 -07:00
return false ; } , escapeUI : function ( destroyed ) { if ( window . editing || destroyed ) { if ( ! window . site . $html . hasClass ( 'detail' ) ) { window . site . $body . removeClass ( 'detail' ) ; }
window . site . $main _edit . hide ( ) ; window . site . $body . removeClass ( 'editing' ) ; window . site . $main . show ( ) ; window . editing = true ; window . ui _halted = false ; if ( window . site . $snipts . index ( window . $selected ) === 0 ) { window . scrollTo ( 0 , 0 ) ; } else { window . site . $html _body . animate ( { scrollTop : window . $selected . offset ( ) . top - 50 } , 0 ) ; }
if ( destroyed ) { window . $selected . trigger ( 'fadeAndRemove' ) ; } } else { if ( ! window . ui _halted ) { if ( $selected ) { $selected . trigger ( 'deselect' ) ; }
window . site . $aside _nav . removeClass ( 'open' ) ; } } } , keyboardShortcuts : function ( ) { var that = this ; $selected = window . selected ; $document = $ ( document ) ; $document . bind ( 'keydown' , 'j' , function ( ) { if ( ! window . ui _halted ) { if ( ! $selected ) { window . site . $snipts . eq ( 0 ) . trigger ( 'selectSnipt' ) ; } else { $selected . trigger ( 'next' ) ; } } } ) ; $document . bind ( 'keydown' , 'k' , function ( ) { if ( ! window . ui _halted ) { if ( ! $selected ) { window . site . $snipts . eq ( 0 ) . trigger ( 'selectSnipt' ) ; } else { $selected . trigger ( 'prev' ) ; } } } ) ; $document . bind ( 'keydown' , 'c' , function ( e ) { if ( ! window . ui _halted && ! window . blog _post ) { if ( $selected ) { e . preventDefault ( ) ; $selected . trigger ( 'copyRaw' ) ; } } } ) ; $document . bind ( 'keydown' , 'Ctrl+e' , function ( ) { if ( ! window . ui _halted ) { if ( $selected ) { if ( $selected . hasClass ( 'editable' ) ) { $selected . trigger ( 'edit' ) ; } } } } ) ; $document . bind ( 'keydown' , 'Ctrl+backspace' , function ( ) { if ( ! window . ui _halted || window . editing ) { if ( $selected ) { if ( $selected . hasClass ( 'editable' ) ) { if ( confirm ( 'Are you sure you want to delete this snipt?' ) ) { $selected . trigger ( 'destroy' ) ; window . site . snipt _list . escapeUI ( true ) ; } } } } } ) ; $document . bind ( 'keydown' , 'Ctrl+del' , function ( ) { if ( ! window . ui _halted || window . editing ) { if ( $selected ) { if ( $selected . hasClass ( 'editable' ) ) { if ( confirm ( 'Are you sure you want to delete this snipt?' ) ) { $selected . trigger ( 'destroy' ) ; window . site . snipt _list . escapeUI ( true ) ; } } } } } ) ; $document . bind ( 'keydown' , 'Alt+n' , function ( ) { if ( ! window . ui _halted ) { that . addNewSnipt ( ) ; } } ) ; $document . bind ( 'keydown' , 'Ctrl+n' , function ( ) { if ( ! window . ui _halted ) { that . addNewSnipt ( ) ; } } ) ; $document . bind ( 'keydown' , 'Ctrl+s' , function ( ) { if ( window . editing ) { if ( $selected ) { if ( $selected . hasClass ( 'editable' ) ) { $ ( 'button.save' ) . click ( ) ; } } } } ) ; $document . bind ( 'keydown' , 'Ctrl+c' , function ( ) { if ( window . editing ) { if ( $selected ) { if ( $selected . hasClass ( 'editable' ) ) { $ ( 'button.save-and-close' ) . click ( ) ; } } } } ) ; $document . bind ( 'keydown' , 'esc' , function ( ) { that . escapeUI ( ) ; } ) ; $document . bind ( 'keydown' , 'g' , function ( ) { if ( ! window . ui _halted ) { if ( window . $selected ) { window . $selected . trigger ( 'deselect' ) ; }
window . scrollTo ( 0 , 0 ) ; } } ) ; $document . bind ( 'keydown' , 'Shift+g' , function ( ) { if ( ! window . ui _halted ) { if ( window . $selected ) { window . $selected . trigger ( 'deselect' ) ; }
2012-07-08 09:25:15 -07:00
window . scrollTo ( 0 , document . body . scrollHeight ) ; } } ) ; $document . bind ( 'keydown' , 'n' , function ( ) { if ( ! window . ui _halted ) { var $anc = $ ( 'li.next a' ) ; if ( $anc . length ) { if ( $anc . attr ( 'href' ) !== '#' ) { window . location = $anc . attr ( 'href' ) ; } } } } ) ; $document . bind ( 'keydown' , 'e' , function ( ) { if ( ! window . ui _halted ) { if ( $selected ) { if ( $selected . hasClass ( 'expandable' ) ) { $selected . trigger ( 'expand' ) ; } } } } ) ; $document . bind ( 'keydown' , 'u' , function ( ) { if ( ! window . ui _halted ) { if ( $selected ) { $selected . trigger ( 'goToAuthor' ) ; } } } ) ; $document . bind ( 'keydown' , 'p' , function ( ) { if ( ! window . ui _halted ) { var $anc = $ ( 'li.prev a' ) ; if ( $anc . length ) { if ( $anc . attr ( 'href' ) !== '#' ) { window . location = $anc . attr ( 'href' ) ; } } } } ) ; $document . bind ( 'keydown' , 'v' , function ( e ) { if ( ! window . ui _halted && ! window . blog _post ) { if ( $selected ) { e . preventDefault ( ) ; $selected . trigger ( 'embed' ) ; } } } ) ; $document . bind ( 'keydown' , 'o' , function ( ) { if ( ! window . ui _halted ) { if ( $selected ) { $selected . trigger ( 'detail' ) ; } } } ) ; $document . bind ( 'keydown' , 'return' , function ( ) { if ( ! window . ui _halted ) { if ( $selected ) { $selected . trigger ( 'detail' ) ; } } } ) ; } } ) ; } ) ( snipt . module ( 'snipt' ) ) ;