package Ġcom . be lo tron . we ath err ad ar hr Ċ Ċ import Ġandroid . animation . Object Animator Ċ import Ġandroid . content . Context Ċ import Ġandroid . graphics . Bitmap Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . V ibration Effect Ċ import Ġandroid . os . V ibr ator Ċ import Ġandroid . view . animation . Linear Interpolator Ċ import Ġandroid . widget . Seek Bar Ċ import Ġcom . be lo tron . we ath err ad ar hr . gif decode . Bitmap Fre el ists Ċ import Ġcom . be lo tron . we ath err ad ar hr . gif decode . Gif Decoder Ċ import Ġcom . be lo tron . we ath err ad ar hr . gif decode . Parsed Gif Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . Dispatch ers . IO Ċ import Ġjava . text . DateFormat Ċ import Ġjava . util . concurrent . Array BlockingQueue Ċ import Ġjava . util . concurrent . Thread Factory Ċ import Ġjava . util . concurrent . ThreadPoolExecutor Ċ import Ġjava . util . concurrent . ThreadPoolExecutor . Discard Ol dest Policy Ċ import Ġjava . util . concurrent . TimeUnit . NAN O SECONDS Ċ import Ġjava . util . concurrent . TimeUnit . SECONDS Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . round ToInt Ċ import Ġkotlin . math . round To Long Ċ Ċ private Ġval Ġsingle Thread Ġ= ĠThreadPool Executor ( 0 , Ġ 1 , Ġ 2 , ĠSE CON DS , ĠArray BlockingQueue ( 1 ), ĊĠĠĠĠĠĠĠ ĠThread Factory Ġ{ Ġtask Ġ-> ĠThread ( task , Ġ" weather - radar - animation ") Ġ}, ĠDis card Ol dest Policy ()) ĊĠĠĠĠĠĠĠ Ġ. as Coroutine Dispatcher () Ċ Ċ private Ġval Ġlinear Ġ= ĠLinear Interpolator () Ċ Ċ private Ġlateinit Ġvar ĠdateFormat : ĠDate Format Ċ private Ġlateinit Ġvar Ġtime Format : ĠDate Format Ċ Ċ class ĠAnimation Looper ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġds : ĠDisplay State Ċ ) Ġ: ĠSeek Bar . On Seek Bar ChangeListener Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġanim ators Ġ= ĠarrayOf Null s < Gif Animator >( ds . img Bund les . size ) ĊĠĠĠ Ġprivate Ġval Ġanim ator Jobs Ġ= ĠarrayOf Null s < Job >( ds . img Bund les . size ) ĊĠĠĠ Ġprivate Ġvar Ġlooping Job : ĠJob ? Ġ= Ġnull ĊĊĠĠĠ Ġfun Ġreceive New Gif ( desc : ĠImg Descriptor , Ġparsed Gif : ĠParsed Gif , Ġis Offline : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġanim ators [ desc . index ] Ġ= ĠG if Animator ( ds . img Bund les , Ġdesc , Ġparsed Gif , Ġis Offline ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġresume ( context : ĠContext ? Ġ= Ġnull , Ġnew Rate M ins Per Sec : ĠInt ? Ġ= Ġnull , Ġnew Freeze Time Millis : ĠInt ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġinfo Ġ{ Ġ" Animation Looper . resume " Ġ} ĊĠĠĠĠĠĠĠ Ġcontext ?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠdateFormat Ġ= Ġit . date Format ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtime Format Ġ= Ġit . time Format ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( anim ators . all Ġ{ Ġit Ġ== Ġnull Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġanim ators . filter NotNull (). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Rate M ins Per Sec ?. also Ġ{ Ġ_ Ġ-> Ġit . rate M ins Per Sec Ġ= Ġnew Rate M ins Per Sec Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Freeze Time Millis ?. also Ġ{ Ġ_ Ġ-> Ġit . freeze Time Millis Ġ= Ġnew Freeze Time Millis Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( ds . is Tracking Touch ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠ Ġvar Ġold Loop ing Job Ġ= Ġlooping Job ĊĠĠĠĠĠĠĠ Ġlooping Job Ġ= Ġapp Cor o Scope . start Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġold Loop ing Job ?. join () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġold Loop ing Job Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanim ator Jobs . forEach Ġ{ Ġit ?. join () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanim ators . with Index () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġ( i , Ġ_) Ġ-> Ġds . indexOf Img In FullScreen ?. let Ġ{ Ġit Ġ== Ġi Ġ} Ġ?: Ġtrue Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġ( i , Ġit ) Ġ-> Ġanim ator Jobs [ i ] Ġ= Ġit ?. animate ( ds . isIn FullScreen ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġanim ator Jobs . forEach Ġ{ Ġit ?. cancel () Ġ} ĊĠĠĠĠĠĠĠ Ġanim ators . forEach Ġ{ Ġit ?. stop Seek Bar Animation () Ġ} ĊĠĠĠĠĠĠĠ Ġlooping Job ?. cancel () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonStart Tracking Touch ( seek Bar : ĠSeek Bar ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( anim ators . any Ġ{ Ġit . has Seek Bar ( seek Bar ) Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġds . is Tracking Touch Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Progress Changed ( seek Bar : ĠSeek Bar , Ġprogress : ĠInt , Ġfrom User : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( from User ) Ġds . start Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanim ators . find Ġ{ Ġit . has Seek Bar ( seek Bar ) Ġ} ?. seek To ( progress , Ġseek Bar . context ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Stop Tracking Touch ( seek Bar : ĠSeek Bar ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( seek Bar Ġ! is ĠThumb Seek Bar ) Ġreturn ĊĠĠĠĠĠĠĠ Ġ( anim ators . find Ġ{ Ġit . has Seek Bar ( seek Bar ) Ġ} Ġ?: Ġreturn ). also Ġ{ Ġfull Screen Animator Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseek Bar . thumb Text Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfull Screen Progress Ġ= Ġfull Screen Animator . img Bundle . animation Progress ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanim ators . filter NotNull (). filter Ġ{ Ġit . has Seek Bar ( null ) Ġ}. forEach Ġ{ Ġplain Animator Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain Animator . img Bundle . animation Progress Ġ= Ġfull Screen Progress ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġds . is Tracking Touch Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresume () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠG if Animator ?. has Seek Bar ( seek Bar : ĠSeek Bar ?) Ġ= Ġthis ?. img Bundle ?. seek Bar Ġ== Ġseek Bar Ċ } Ċ Ċ class ĠG if Animator ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġimg Bund les : ĠList < Image Bundle >, ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġimg Desc : ĠImg Descriptor , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġparsed Gif : ĠParsed Gif , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġis Offline : ĠBoolean Ċ ) Ġ{ ĊĠĠĠ Ġvar Ġrate M ins Per Sec : ĠInt Ġ= Ġ 2 0 ĊĠĠĠ Ġvar Ġfreeze Time Millis : ĠInt Ġ= Ġ 0 ĊĠĠĠ Ġval Ġimg Bundle : ĠImage Bundle Ġget () Ġ= Ġimg Bund les [ img Desc . index ] ĊĊĠĠĠ Ġprivate Ġval Ġframe Delay Millis Ġget () Ġ= ĠĠ 1 0 0 0 Ġ* Ġimg Desc . minutes Per Frame Ġ/ Ġrate M ins Per Sec ĊĠĠĠ Ġprivate Ġval Ġallocator Ġ= ĠBitmap Fre el ists () ĊĠĠĠ Ġprivate Ġval Ġgif Decoder Ġ= ĠG if Decoder ( allocator , Ġparsed Gif ) ĊĠĠĠ Ġprivate Ġvar Ġcurr Frame : ĠBitmap ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcurr Frame Index Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġseek Bar Animator : ĠObject Animator ? Ġ= Ġnull ĊĊĠĠĠ Ġfun Ġanimate ( is Full Range : ĠBoolean ): ĠJob Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġframe Count Ġ= Ġgif Decoder . frame Count ĊĠĠĠĠĠĠĠ Ġval Ġstart Frame Index Ġ= Ġif Ġ( is Full Range ) Ġ 0 Ġelse Ġmax ( 0 , Ġframe Count Ġ- Ġimg Desc . frames To Keep ) ĊĠĠĠĠĠĠĠ Ġcurr Frame Index Ġ= Ġto Frame Index ( img Bundle . animation Progress , Ġstart Frame Index ) ĊĠĠĠĠĠĠĠ Ġreturn Ġapp Cor o Scope . start Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Age Text () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġframe Ġ= Ġsuspend Decode Frame ( curr Frame Index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( curr Frame Index Ġuntil Ġframe Count ). forEach Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġanimation Progress Ġ= Ġto Progress ( frame Index Ġ= Ġi ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( i Ġ== Ġcurr Frame Index ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Frame ( frame , Ġanimation Progress ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanimate Seek Bar IfNeeded () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġframe Shown At Ġ= ĠSystem . nano Time () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Frame Shown Ġ= Ġi Ġ== Ġframe Count Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! last Frame Shown ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurr Frame Index Ġ= Ġi Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġframe Ġ= Ġsuspend Decode Frame ( i Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġelapsed Since Frame Shown Ġ= ĠN AN O SECONDS . to Millis ( System . nano Time () Ġ- Ġframe Shown At ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Delay Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( last Frame Shown ) Ġmax ( freeze Time Millis , Ġframe Delay Millis ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġframe Delay Millis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremaining Delay Ġ= Ġtarget Delay Ġ- Ġelapsed Since Frame Shown ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Ġ{ Ġ"$ elapsed Since Frame Shown Ġms Ġsince Ġlast Ġframe , Ġ$ remaining Delay Ġms Ġtill Ġnext Ġframe " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremaining Delay . take If Ġ{ Ġit Ġ> Ġ 0 Ġ} ?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimg Bundle . animation Progress Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop Seek Bar Animation () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstop Seek Bar Animation () Ġ{ ĊĠĠĠĠĠĠĠ Ġseek Bar Animator ?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . pause () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseek Bar Animator Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġseek To ( animation Progress : ĠInt , Ġctx : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtarget Index Ġ= Ġto Frame Index ( animation Progress , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġif Ġ( target Index Ġ== Ġcurr Frame Index ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurr Frame Index Ġ= Ġtarget Index ĊĠĠĠĠĠĠĠ Ġupdate Seek Bar Thumb ( target Index , Ġtimestamp ( target Index )) ĊĠĠĠĠĠĠĠ Ġif Ġ( target Index Ġ== Ġ 0 Ġ|| Ġtarget Index Ġ== Ġgif Decoder . frame Count Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvi br ator Ġ= Ġctx . getSystem Service ( Context . V IB R ATOR _ SERVICE ) Ġas ĠV ibr ator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . Q ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvi br ator . vi br ate ( V ibration Effect . create Pre defined ( V ibration Effect . EFFECT _ HE AV Y _ CLICK )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvi br ator . vi br ate ( 2 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġnew Frame Ġ= Ġsuspend Decode Frame ( target Index , Ġsingle Thread ) ĊĠĠĠĠĠĠĠ Ġshow Frame ( new Frame , Ġanimation Progress ) ĊĠĠĠĠĠĠĠ Ġupdate Age Text () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Frame ( new Frame : ĠBitmap , Ġanimation Progress : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Ġ( img Bundle ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimg View ?. setImage Bitmap ( new Frame ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . animation Progress Ġ= Ġanimation Progress ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurr Frame ?. dispose () ĊĠĠĠĠĠĠĠ Ġcurr Frame Ġ= Ġnew Frame ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Seek Bar Thumb ( frame Index : ĠInt , Ġtimestamp : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġimg Bundle . seek Bar ?. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthumb Progress Ġ= Ġto Progress ( frame Index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthumb Text Ġ= Ġtime Format . format ( timestamp ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġanimate Seek Bar IfNeeded () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( seek Bar Animator Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġseek Bar Ġ= Ġimg Bundle . seek Bar Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġseek Bar . also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprogress F Ġ= Ġimg Bundle . animation Progress Ġ/ Ġ 1 0 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseek Bar Animator Ġ= ĠObject Animator . of Int ( it , Ġ" progress ", Ġimg Bundle . animation Progress , Ġ 1 0 0 ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġduration Ġ= Ġ( gif Decoder . frame Count Ġ* Ġframe Delay Millis Ġ* Ġ( 1 Ġ- Ġprogress F )). round To Long () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinterpol ator Ġ= Ġlinear ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Age Text () Ġ{ ĊĠĠĠĠĠĠĠ Ġimg Bundle . take If Ġ{ Ġit . status Ġin ĠImage Bundle . loading Or Showing Ġ} ?. textView ?. set Age Text ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtimestamp ( parsed Gif . frame Count Ġ- Ġ 1 ), Ġis Offline , ĠdateFormat Ġ= ĠdateFormat , Ġtime Format Ġ= Ġtime Format ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġtimestamp ( frame Index : ĠInt ) Ġ= Ġparsed Gif . frames [ frame Index ]. timestamp ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsuspend Decode Frame ( frame Index : ĠInt , Ġcor o Ctx : ĠCor outine Dispatcher Ġ= ĠIO ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( cor o Ctx ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized Ġ( gif Decoder ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgif Decoder . decode Frame ( frame Index ). to Bitmap () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠBitmap . dispose () Ġ= Ġallocator . release ( this ) ĊĊĠĠĠ Ġprivate Ġfun Ġto Frame Index ( animation Progress : ĠInt , Ġstart Frame Index : ĠInt ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( animation Progress Ġ/ Ġ 1 0 0 f Ġ* Ġ( gif Decoder . frame Count Ġ- Ġstart Frame Index Ġ- Ġ 1 ) Ġ+ Ġstart Frame Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. round ToInt () ĊĊĠĠĠ Ġprivate Ġfun Ġto Progress ( frame Index : ĠInt ) Ġ= Ġgif Decoder . frame Count . let Ġ{ Ġframe Count Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( frame Count Ġ== Ġ 1 ) Ġ 1 0 0 ĊĠĠĠĠĠĠĠ Ġelse Ġ 1 0 0 Ġ* Ġframe Index Ġ/ Ġ( frame Count Ġ- Ġ 1 ) ĊĠĠĠ Ġ} Ċ } Ċ