/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 Ġthe Ġoriginal Ġauthor Ġor Ġauthors . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġcom . b ilib ili . b router . common . util . graph Ċ Ċ import Ġjava . util .* Ċ import Ġkotlin . math . min ĊĊ Ċ interface ĠDirect ed Graph < N , ĠV > Ġ{ ĊĠĠĠ Ġfun ĠgetNode Values ( ĊĠĠĠĠĠĠĠ Ġnode : ĠN , ĊĠĠĠĠĠĠĠ Ġvalues : ĠMutable Collection < in ĠV >, ĊĠĠĠĠĠĠĠ Ġconnected Nodes : ĠMutable Collection < in ĠN > ĊĠĠĠ Ġ) Ċ } Ċ Ċ /** Ċ Ġ* ĠA Ġdirected Ġgraph Ġwith Ġnodes Ġof Ġtype ĠN . ĠEach Ġedge Ġhas Ġa Ġcollection Ġof Ġvalues Ġof Ġtype ĠV Ċ Ġ*/ Ċ interface ĠDirect ed Graph With Edge Values < N , ĠV > Ġ: ĊĠĠĠ ĠDirect ed Graph < N , ĠV > Ġ{ ĊĠĠĠ Ġfun Ġget Edge Values ( from : ĠN , Ġto : ĠN , Ġvalues : ĠMutable Collection < in ĠV >) Ċ } ĊĊ Ċ /** Ċ Ġ* ĠA Ġgraph Ġwalk er Ġwhich Ġcollect s Ġthe Ġvalues Ġreachable Ġfrom Ġa Ġgiven Ġset Ġof Ġstart Ġnodes . ĠHandles Ġcycles Ġin Ġthe Ġgraph . ĠCan Ċ Ġ* Ġbe Ġreused Ġto Ġperform Ġmultiple Ġsearches , Ġand Ġre uses Ġthe Ġresults Ġof Ġprevious Ġsearches . Ċ Ġ* Ċ Ġ* ĠUses Ġa Ġvariation Ġof ĠTar jan 's Ġalgorithm : Ġhttp :// en . wikipedia . org / wiki / Tar jan % 2 7 s _ strong ly _ connected _ components _ algorithm Ċ Ġ*/ Ċ class ĠC aching Direct ed Graph Walker < N , ĠT > Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġclean Cache : ĠBoolean Ġ= Ġfalse , ĊĠĠĠ Ġprivate Ġval Ġgraph : ĠDirect ed Graph With Edge Values < N , ĠT > Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġstart Nodes Ġ= Ġarray ListOf < N >() ĊĠĠĠ Ġprivate Ġval Ġstrong Components Ġ= Ġlinked Set Of < Node Details < N , ĠT >>() ĊĠĠĠ Ġprivate Ġval Ġcached Node Values Ġ= Ġhash Map Of < N , ĠMutable Set < T >>() ĊĊĠĠĠ Ġconstructor ( clean Cache : ĠBoolean , Ġgraph : ĠDirect ed Graph < N , ĠT >) Ġ: Ġthis ( ĊĠĠĠĠĠĠĠ Ġclean Cache , ĊĠĠĠĠĠĠĠ ĠGraph With Empty Edges ( graph ) ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġsome Ġstart Ġnodes . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd ( var arg Ġvalues : ĠN ): ĠC aching Direct ed Graph Walker < N , ĠT > Ġ{ ĊĠĠĠĠĠĠĠ Ġstart Nodes Ġ+= Ġvalues ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġsome Ġstart Ġnodes . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd ( values : ĠIterable < N >): ĠC aching Direct ed Graph Walker < *, Ġ*> Ġ{ ĊĠĠĠĠĠĠĠ Ġstart Nodes Ġ+= Ġvalues ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalculates Ġthe Ġset Ġof Ġvalues Ġof Ġnodes Ġreachable Ġfrom Ġthe Ġstart Ġnodes . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġfind Values (): ĠSet < T > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= Ġdo Search () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( strong Components . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcycles Ġ= Ġstrong Components . fold ( array ListOf < N >()) Ġ{ Ġlist , Ġnode Details Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist Ġ+= Ġnode Details . component Members . map To ( linked Set Of < N >()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . node ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Found Ġcycles : Ġ$ cycles ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalues ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Nodes . clear () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġset Ġof Ġcycles Ġseen Ġin Ġthe Ġgraph . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġfind Cycles (): ĠList < Set < N >> Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Search () ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Nodes . clear () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġstrong Components . fold ( array ListOf ()) Ġ{ Ġlist , Ġnode Details Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlist Ġ+= Ġnode Details . component Members . map To ( linked Set Of < N >()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlist ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdo Search (): ĠSet < T > Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcomponent Count Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġseen Nodes : ĠMutable Map < N , ĠNode Details < N , ĠT >> Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHashMap () ĊĠĠĠĠĠĠĠ Ġval Ġcomponents : ĠMutable Map < Int , ĠNode Details < N , ĠT >> Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHashMap () ĊĠĠĠĠĠĠĠ Ġval Ġqueue : ĠDe que < N > Ġ= ĠArray Deque ( start Nodes ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! queue . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnode Ġ= Ġqueue . first ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġdetails Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseen Nodes [ node ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( details Ġ== Ġnull ) Ġ{ Ġ// ĠHave Ġnot Ġvisited Ġthis Ġnode Ġyet . ĠPush Ġits Ġsuccess ors Ġonto Ġthe Ġqueue Ġin Ġfront Ġof Ġthis Ġnode Ġand Ġvisit Ċ // Ġthem ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNode Details ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Count ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseen Nodes [ node ] Ġ= Ġdetails ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponents [ details . component ] Ġ= Ġdetails ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcache Values Ġ= Ġcached Node Values [ node ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cache Values Ġ!= Ġnull ) Ġ{ Ġ// ĠAlready Ġvisited Ġthis Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails . values Ġ= Ġcache Values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails . finished Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . remove First () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgraph . getNode Values ( node , Ġdetails . values , Ġdetails . success ors ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( connected Node Ġin Ġdetails . success ors ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconnected Node Details Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseen Nodes [ connected Node ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( connected Node Details Ġ== Ġnull ) Ġ{ Ġ// ĠHave Ġnot Ġvisited Ġthe Ġsuccess or Ġnode , Ġso Ġadd Ġto Ġthe Ġqueue Ġfor Ġvisit ing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . add First ( connected Node ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ(! connected Node Details . finished ) Ġ{ Ġ// ĠCurrently Ġvisit ing Ġthe Ġsuccess or Ġnode Ġ- Ġwe 're Ġin Ġa Ġcycle ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails . strong ly Connected Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠElse , Ġalready Ġvisited ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ Ġ// ĠHave Ġvisited Ġall Ġof Ġthis Ġnode 's Ġsuccess ors ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . remove First () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cached Node Values . containsKey ( node )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( connected Node Ġin Ġdetails . success ors ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconnected Node Details Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseen Nodes [ connected Node ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! connected Node Details !!. finished ) Ġ{ Ġ// Ġpart Ġof Ġa Ġcycle Ġ: Ġuse Ġthe Ġ' minimum ' Ġcomponent Ġas Ġthe Ġroot Ġof Ġthe Ġcycle ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmin Seen Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmin ( details . min Seen , Ġconnected Node Details . min Seen ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails . min Seen Ġ= Ġmin Seen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnected Node Details . min Seen Ġ= Ġmin Seen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails . strong ly Connected Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails . values . addAll ( connected Node Details . values ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgraph . get Edge Values ( node , Ġconnected Node , Ġdetails . values ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( details . min Seen Ġ!= Ġdetails . component ) Ġ{ Ġ// ĠPart Ġof Ġa Ġstrongly Ġconnected Ġcomponent Ġ( ie Ġcycle ) Ġ- Ġmove Ġvalues Ġto Ġroot Ġof Ġthe Ġcomponent Ċ // ĠThe Ġroot Ġis Ġthe Ġfirst Ġnode Ġof Ġthe Ġcomponent Ġwe Ġencountered ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġroot Details Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponents [ details . min Seen ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroot Details !!. values . addAll ( details . values ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails . values . clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroot Details . component Members . addAll ( details . component Members ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ Ġ// ĠNot Ġpart Ġof Ġa Ġstrongly Ġconnected Ġcomponent Ġor Ġthe Ġroot Ġof Ġa Ġstrongly Ġconnected Ġcomponent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( component Member Ġin Ġdetails . component Members ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcached Node Values [ component Member . node ] Ġ= Ġdetails . values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Member . finished Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponents . remove ( component Member . component ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( details . strong ly Connected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstrong Components . add ( details ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġstart Nodes . fold ( linked Set Of < T >()) Ġ{ Ġset , Ġstart Node Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Ġ+= Ġcached Node Values [ start Node ] Ġ?: Ġempty Set () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset ĊĠĠĠĠĠĠĠ Ġ}. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( clean Cache ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcached Node Values . clear () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠNode Details < N , ĠT >( val Ġnode : ĠN , Ġval Ġcomponent : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġvalues : ĠMutable Set < T > Ġ= ĠLinked HashSet () ĊĠĠĠĠĠĠĠ Ġval Ġsuccess ors : ĠMutable List < N > Ġ= ĠArrayList () ĊĠĠĠĠĠĠĠ Ġval Ġcomponent Members : ĠMutable Set < Node Details < N , ĠT >> Ġ= Ġlinked Set Of ( this ) ĊĠĠĠĠĠĠĠ Ġvar Ġmin Seen : ĠInt Ġ= Ġcomponent ĊĠĠĠĠĠĠĠ Ġvar Ġstrongly Connected Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġfinished Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠGraph With Empty Edges < N , ĠT >( private Ġval Ġgraph : ĠDirect ed Graph < N , ĠT >) Ġ: ĊĠĠĠĠĠĠĠ ĠDirect ed Graph With Edge Values < N , ĠT > Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget Edge Values ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfrom : ĠN , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto : ĠN , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalues : ĠMutable Collection < in ĠT > ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠgetNode Values ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode : ĠN , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalues : ĠMutable Collection < in ĠT >, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnected Nodes : ĠMutable Collection < in ĠN > ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgraph . getNode Values ( node , Ġvalues , Ġconnected Nodes ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }