package Ġio . fluid sonic . locale ĊĊ Ċ /** Ċ Ġ* ĠA ĠB CP Ġ 4 7 Ġlanguage Ġtag , Ġfor Ġexample Ġ` en `, Ġ` en - US ` Ġor Ġ` sl - IT - ned is `. Ċ Ġ* Ċ Ġ* ĠReferences : Ċ Ġ* Ġ- Ġ[ https :// tools . ietf . org / html / b cp 4 7 ] Ċ Ġ*/ Ċ public Ġclass ĠLanguage Tag Ġprivate Ġconstructor ( Ċ ĉ public Ġval Ġextensions : ĠList < String >, Ċ ĉ public Ġval Ġext langs : ĠList < String >, Ċ ĉ public Ġval Ġlanguage : ĠString ?, Ċ ĉ public Ġval Ġprivate use : ĠString ?, Ċ ĉ public Ġval Ġregion : ĠString ?, Ċ ĉ public Ġval Ġscript : ĠString ?, Ċ ĉ public Ġval Ġvariants : ĠList < String >, Ċ ) Ġ{ ĊĊ ĉ init Ġ{ Ċĉ ĉ freeze () Ċ ĉ } ĊĊĊ ĉ public Ġfun Ġcopy ( Ċĉ ĉ extensions : ĠList < String > Ġ= Ġthis . extensions , Ċĉ ĉ ext langs : ĠList < String > Ġ= Ġthis . ext langs , Ċĉ ĉ language : ĠString ? Ġ= Ġthis . language , Ċĉ ĉ private use : ĠString ? Ġ= Ġthis . private use , Ċĉ ĉ region : ĠString ? Ġ= Ġthis . region , Ċĉ ĉ script : ĠString ? Ġ= Ġthis . script , Ċĉ ĉ variants : ĠList < String > Ġ= Ġthis . variants , Ċ ĉ ): ĠLanguage Tag Ġ= Ċĉ ĉ when Ġ{ Ċĉĉ ĉ language Ġ!= Ġnull Ġ-> Ċĉĉĉ ĉ for Language ( Ċĉĉĉĉ ĉ extensions Ġ= Ġextensions , Ċĉĉĉĉ ĉ ext langs Ġ= Ġext langs , Ċĉĉĉĉ ĉ language Ġ= Ġlanguage , Ċĉĉĉĉ ĉ private use Ġ= Ġprivate use , Ċĉĉĉĉ ĉ region Ġ= Ġregion , Ċĉĉĉĉ ĉ script Ġ= Ġscript , Ċĉĉĉĉ ĉ variants Ġ= Ġvariants Ċĉĉĉ ĉ ) ĊĊĉĉ ĉ private use Ġ!= Ġnull Ġ-> Ċĉĉĉ ĉ for Private Use ( private use Ġ= Ġprivate use ) ĊĊĉĉ ĉ else Ġ-> Ċĉĉĉ ĉ error (" Either Ġ' language ' Ġor Ġ' private use ' Ġmust Ġbe Ġnon - null .") Ċĉ ĉ } ĊĊĊ ĉ override Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ= Ċĉ ĉ this Ġ=== Ġother Ġ|| Ċĉĉ ĉ ( other Ġis ĠLanguage Tag Ġ&& Ċĉĉĉ ĉ extensions Ġ== Ġother . extensions Ġ&& Ċĉĉĉ ĉ ext langs Ġ== Ġother . ext langs Ġ&& Ċĉĉĉ ĉ language Ġ== Ġother . language Ġ&& Ċĉĉĉ ĉ private use Ġ== Ġother . private use Ġ&& Ċĉĉĉ ĉ region Ġ== Ġother . region Ġ&& Ċĉĉĉ ĉ script Ġ== Ġother . script Ġ&& Ċĉĉĉ ĉ variants . equals ( other . variants , Ġignore Case Ġ= Ġtrue )) ĊĊĊ ĉ override Ġfun ĠhashCode (): ĠInt Ġ{ Ċĉ ĉ var Ġresult Ġ= Ġextensions . hashCode () Ċĉ ĉ result Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġext langs . hashCode () Ċĉ ĉ result Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġlanguage . hashCode () Ċĉ ĉ result Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġprivate use . hashCode () Ċĉ ĉ result Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġregion . hashCode () Ċĉ ĉ result Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġscript . hashCode () Ċĉ ĉ result Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġvariants . if Empty Ġ{ Ġnull Ġ} ?. map ( String :: toLowerCase ). hashCode () ĊĊĉ ĉ return Ġresult Ċ ĉ } ĊĊĊ ĉ override Ġfun ĠtoString (): ĠString Ġ= Ġbuild String Ġ{ Ċĉ ĉ if Ġ( language Ġ!= Ġnull ) Ġ{ Ċĉĉ ĉ append ( language ) ĊĊĉĉ ĉ for Ġ( ext lang Ġin Ġext langs ) Ġ{ Ċĉĉĉ ĉ append ( separator ) Ċĉĉĉ ĉ append ( ext lang ) Ċĉĉ ĉ } ĊĊĉĉ ĉ if Ġ( script Ġ!= Ġnull ) Ġ{ Ċĉĉĉ ĉ append ( separator ) Ċĉĉĉ ĉ append ( script ) Ċĉĉ ĉ } ĊĊĉĉ ĉ if Ġ( region Ġ!= Ġnull ) Ġ{ Ċĉĉĉ ĉ append ( separator ) Ċĉĉĉ ĉ append ( region ) Ċĉĉ ĉ } ĊĊĉĉ ĉ for Ġ( variant Ġin Ġvariants ) Ġ{ Ċĉĉĉ ĉ append ( separator ) Ċĉĉĉ ĉ append ( variant ) Ċĉĉ ĉ } ĊĊĉĉ ĉ for Ġ( extension Ġin Ġextensions ) Ġ{ Ċĉĉĉ ĉ append ( separator ) Ċĉĉĉ ĉ append ( extension ) Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ if Ġ( private use Ġ!= Ġnull ) Ġ{ Ċĉĉ ĉ if Ġ( isNotEmpty ()) Ċĉĉĉ ĉ append ( separator ) ĊĊĉĉ ĉ append ( private use ) Ċĉ ĉ } Ċ ĉ } ĊĊĊ ĉ public Ġcompanion Ġobject Ġ{ ĊĊĉ ĉ public Ġconst Ġval Ġprivate use Prefix : ĠChar Ġ= Ġ' x ' Ċĉ ĉ public Ġconst Ġval Ġseparator : ĠChar Ġ= Ġ'-' Ċĉ ĉ public Ġconst Ġval Ġun determin ed Prefix : ĠString Ġ= Ġ" und " ĊĊĉ ĉ // Ġhttps :// www . iana . org / assignments / language - sub tag - registry / language - sub tag - registry Ċĉ ĉ // Ġgrand father ed Ġ= Ġir regular ĠĠĠĠĠĠĠĠĠĠ Ġ; Ġnon - red undant Ġtags Ġregistered Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġregular ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġduring Ġthe ĠRFC Ġ 3 0 6 6 Ġera Ċĉ ĉ // Ċĉ ĉ // Ġir regular ĠĠĠĠ Ġ= Ġ" en - GB - o ed " ĠĠĠĠĠĠĠĠ Ġ; Ġir regular Ġtags Ġdo Ġnot Ġmatch Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - ami " ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġthe Ġ' lang tag ' Ġproduction Ġand Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - b nn " ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġwould Ġnot Ġotherwise Ġbe Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - default " ĠĠĠĠĠĠĠĠ Ġ; Ġconsidered Ġ' well - formed ' Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - eno ch ian " ĠĠĠĠĠĠĠ Ġ; ĠThese Ġtags Ġare Ġall Ġvalid , Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - hak " ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġbut Ġmost Ġare Ġdeprecated Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - k ling on " ĠĠĠĠĠĠĠĠ Ġ; Ġin Ġfavor Ġof Ġmore Ġmodern Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - lux " ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġsub tags Ġor Ġsub tag Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - ming o " ĠĠĠĠĠĠĠĠĠĠ Ġ; Ġcombination Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - n ava jo " Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - p wn " Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - ta o " Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - t ay " Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" i - ts u " Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" sg n - BE - FR " Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" sg n - BE - NL " Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" sg n - CH - DE " Ċĉ ĉ // Ċĉ ĉ // Ġregular ĠĠĠĠĠĠ Ġ= Ġ" art - lo j ban " ĠĠĠĠĠĠĠ Ġ; Ġthese Ġtags Ġmatch Ġthe Ġ' lang tag ' Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" cel - ga ul ish " ĠĠĠĠĠĠ Ġ; Ġproduction , Ġbut Ġtheir Ġsub tags Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" no - bok " ĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġare Ġnot Ġextended Ġlanguage Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" no - n yn " ĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġor Ġvariant Ġsub tags : Ġtheir Ġmeaning Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" zh - gu oy u " ĠĠĠĠĠĠĠĠĠ Ġ; Ġis Ġdefined Ġby Ġtheir Ġregistration Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" zh - h akka " ĠĠĠĠĠĠĠĠĠ Ġ; Ġand Ġall Ġof Ġthese Ġare Ġdeprecated Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" zh - min " ĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġin Ġfavor Ġof Ġa Ġmore Ġmodern Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" zh - min - nan " ĠĠĠĠĠĠĠ Ġ; Ġsub tag Ġor Ġsequence Ġof Ġsub tags Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ" zh - xi ang " Ċĉ ĉ private Ġval Ġgrand father ed : ĠMap < String , ĠString > Ġ= Ġhash Map Of ( Ċĉĉ ĉ " art - lo j ban " Ġto Ġ" j bo ", Ċĉĉ ĉ " cel - ga ul ish " Ġto Ġ" xt g - x - cel - ga ul ish ", Ċĉĉ ĉ " en - gb - o ed " Ġto Ġ" en - GB - ox end ict ", Ċĉĉ ĉ " i - ami " Ġto Ġ" ami ", Ċĉĉ ĉ " i - b nn " Ġto Ġ" b nn ", Ċĉĉ ĉ " i - default " Ġto Ġ" en - x - i - default ", Ċĉĉ ĉ " i - eno ch ian " Ġto Ġ" und - x - i - eno ch ian ", Ċĉĉ ĉ " i - hak " Ġto Ġ" hak ", Ċĉĉ ĉ " i - k ling on " Ġto Ġ" tl h ", Ċĉĉ ĉ " i - lux " Ġto Ġ" lb ", Ċĉĉ ĉ " i - ming o " Ġto Ġ" see - x - i - ming o ", Ċĉĉ ĉ " i - n ava jo " Ġto Ġ" nv ", Ċĉĉ ĉ " i - p wn " Ġto Ġ" p wn ", Ċĉĉ ĉ " i - ta o " Ġto Ġ" ta o ", Ċĉĉ ĉ " i - t ay " Ġto Ġ" t ay ", Ċĉĉ ĉ " i - ts u " Ġto Ġ" ts u ", Ċĉĉ ĉ " no - bok " Ġto Ġ" nb ", Ċĉĉ ĉ " no - n yn " Ġto Ġ" nn ", Ċĉĉ ĉ " sg n - be - fr " Ġto Ġ" s fb ", Ċĉĉ ĉ " sg n - be - nl " Ġto Ġ" v gt ", Ċĉĉ ĉ " sg n - ch - de " Ġto Ġ" sg g ", Ċĉĉ ĉ " zh - gu oy u " Ġto Ġ" cm n ", Ċĉĉ ĉ " zh - h akka " Ġto Ġ" hak ", Ċĉĉ ĉ " zh - min " Ġto Ġ" nan - x - zh - min ", Ċĉĉ ĉ " zh - min - nan " Ġto Ġ" nan ", Ċĉĉ ĉ " zh - xi ang " Ġto Ġ" hs n ", Ċĉ ĉ ) ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Extension ( extension : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ extension ?. if Empty Ġ{ Ġnull Ġ} ?. toLowerCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Extension Singleton ( singleton : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ singleton ?. if Empty Ġ{ Ġnull Ġ} ?. toLowerCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Extension Sub tag ( sub tag : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ sub tag ?. if Empty Ġ{ Ġnull Ġ} ?. toLowerCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Extensions ( extensions : ĠList < String >): ĠList < String > Ġ= Ċĉĉ ĉ extensions . if Empty Ġ{ Ġnull Ġ} ?. map NotNull (:: canonical ize Extension )?. sorted (). or Empty () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Ext lang ( ext lang : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ ext lang ?. if Empty Ġ{ Ġnull Ġ} ?. toLowerCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Ext langs ( ext langs : ĠList < String >): ĠList < String > Ġ= Ċĉĉ ĉ ext langs . if Empty Ġ{ Ġnull Ġ} ?. map NotNull (:: canonical ize Ext lang ). or Empty () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Language ( language : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ language ?. if Empty Ġ{ Ġnull Ġ} ?. toLowerCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Private use ( private use : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ private use ?. if Empty Ġ{ Ġnull Ġ} ?. toLowerCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Private use Prefix ( prefix : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ prefix ?. if Empty Ġ{ Ġnull Ġ} ?. toLowerCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Private use Sub tag ( sub tag : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ sub tag ?. if Empty Ġ{ Ġnull Ġ} ?. toLowerCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Region ( region : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ region ?. if Empty Ġ{ Ġnull Ġ} ?. toUpperCase () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Script ( script : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ script ?. if Empty Ġ{ Ġnull Ġ} ?. to Upper case First Lower case Rest () ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Variant ( variant : ĠString ?): ĠString ? Ġ= Ċĉĉ ĉ variant ?. if Empty Ġ{ Ġnull Ġ} ĊĊĊĉ ĉ public Ġfun Ġcanonical ize Variants ( variants : ĠList < String >): ĠList < String > Ġ= Ċĉĉ ĉ variants . if Empty Ġ{ Ġnull Ġ} ?. map NotNull (:: canonical ize Variant ). or Empty () ĊĊĊĉ ĉ public Ġfun Ġfor Language ( Ċĉĉ ĉ language : ĠString , Ċĉĉ ĉ script : ĠString ? Ġ= Ġnull , Ċĉĉ ĉ region : ĠString ? Ġ= Ġnull , Ċĉĉ ĉ variants : ĠList < String > Ġ= Ġempty List (), Ċĉĉ ĉ ext langs : ĠList < String > Ġ= Ġempty List (), Ċĉĉ ĉ extensions : ĠList < String > Ġ= Ġempty List (), Ċĉĉ ĉ private use : ĠString ? Ġ= Ġnull , Ċĉ ĉ ): ĠLanguage Tag Ġ{ Ċĉĉ ĉ val Ġcanonical Language Ġ= Ġcanonical ize Language ( language ) Ċĉĉ ĉ val Ġcanonical Script Ġ= Ġcanonical ize Script ( script ) Ċĉĉ ĉ val Ġcanonical Region Ġ= Ġcanonical ize Region ( region ) Ċĉĉ ĉ val Ġcanonical Variants Ġ= Ġcanonical ize Variants ( variants ) Ċĉĉ ĉ val Ġcanonical Ext langs Ġ= Ġcanonical ize Ext langs ( ext langs ) Ċĉĉ ĉ val Ġcanonical Extensions Ġ= Ġcanonical ize Extensions ( extensions ) Ċĉĉ ĉ val Ġcanonical Private use Ġ= Ġcanonical ize Private use ( private use ) ĊĊĉĉ ĉ require ( canonical Language Ġ!= Ġnull Ġ&& Ġis Language ( canonical Language )) Ġ{ Ġ" Invalid Ġlanguage : Ġ$ language " Ġ} Ċĉĉ ĉ require ( canonical Script Ġ== Ġnull Ġ|| Ġis Script ( canonical Script )) Ġ{ Ġ" Invalid Ġscript : Ġ$ script " Ġ} Ċĉĉ ĉ require ( canonical Region Ġ== Ġnull Ġ|| Ġis Region ( canonical Region )) Ġ{ Ġ" Invalid Ġregion : Ġ$ region " Ġ} ĊĊĉĉ ĉ for Ġ( variant Ġin Ġcanonical Variants ) Ċĉĉĉ ĉ require ( is Variant ( variant )) Ġ{ Ġ" Invalid Ġvariant : Ġ$ variant " Ġ} Ċĉĉ ĉ for Ġ( ext lang Ġin Ġcanonical Ext langs ) Ċĉĉĉ ĉ require ( is Ext lang ( ext lang )) Ġ{ Ġ" Invalid Ġext lang : Ġ$ ext lang " Ġ} Ċĉĉ ĉ for Ġ( extension Ġin Ġcanonical Extensions ) Ċĉĉĉ ĉ require ( is Extension ( extension )) Ġ{ Ġ" Invalid Ġextension : Ġ$ extension " Ġ} ĊĊĉĉ ĉ require ( canonical Private use Ġ== Ġnull Ġ|| Ġis Private use ( canonical Private use )) Ġ{ Ġ" Invalid Ġprivate use : Ġ$ private use " Ġ} ĊĊĉĉ ĉ return ĠLanguage Tag ( Ċĉĉĉ ĉ extensions Ġ= Ġcanonical Extensions , Ċĉĉĉ ĉ ext langs Ġ= Ġcanonical Ext langs , Ċĉĉĉ ĉ language Ġ= Ġcanonical Language , Ċĉĉĉ ĉ private use Ġ= Ġcanonical Private use , Ċĉĉĉ ĉ region Ġ= Ġcanonical Region , Ċĉĉĉ ĉ script Ġ= Ġcanonical Script , Ċĉĉĉ ĉ variants Ġ= Ġcanonical Variants Ċĉĉ ĉ ) Ċĉ ĉ } ĊĊĊĉ ĉ public Ġfun Ġfor Language OrNull ( Ċĉĉ ĉ language : ĠString , Ċĉĉ ĉ script : ĠString ? Ġ= Ġnull , Ċĉĉ ĉ region : ĠString ? Ġ= Ġnull , Ċĉĉ ĉ variants : ĠList < String > Ġ= Ġempty List (), Ċĉĉ ĉ ext langs : ĠList < String > Ġ= Ġempty List (), Ċĉĉ ĉ extensions : ĠList < String > Ġ= Ġempty List (), Ċĉĉ ĉ private use : ĠString ? Ġ= Ġnull , Ċĉ ĉ ): ĠLanguage Tag ? Ġ{ Ċĉĉ ĉ val Ġcanonical Language Ġ= Ġcanonical ize Language ( language ) Ċĉĉ ĉ val Ġcanonical Script Ġ= Ġcanonical ize Script ( script ) Ċĉĉ ĉ val Ġcanonical Region Ġ= Ġcanonical ize Region ( region ) Ċĉĉ ĉ val Ġcanonical Variants Ġ= Ġcanonical ize Variants ( variants ) Ċĉĉ ĉ val Ġcanonical Ext langs Ġ= Ġcanonical ize Ext langs ( ext langs ) Ċĉĉ ĉ val Ġcanonical Extensions Ġ= Ġcanonical ize Extensions ( extensions ) Ċĉĉ ĉ val Ġcanonical Private use Ġ= Ġcanonical ize Private use ( private use ) ĊĊĉĉ ĉ require ( canonical Language Ġ!= Ġnull Ġ&& Ġis Language ( canonical Language )) Ġ{ Ġreturn Ġnull Ġ} Ċĉĉ ĉ require ( canonical Script Ġ== Ġnull Ġ|| Ġis Script ( canonical Script )) Ġ{ Ġreturn Ġnull Ġ} Ċĉĉ ĉ require ( canonical Region Ġ== Ġnull Ġ|| Ġis Region ( canonical Region )) Ġ{ Ġreturn Ġnull Ġ} ĊĊĉĉ ĉ for Ġ( variant Ġin Ġcanonical Variants ) Ċĉĉĉ ĉ require ( is Variant ( variant )) Ġ{ Ġreturn Ġnull Ġ} Ċĉĉ ĉ for Ġ( ext lang Ġin Ġcanonical Ext langs ) Ċĉĉĉ ĉ require ( is Ext lang ( ext lang )) Ġ{ Ġreturn Ġnull Ġ} Ċĉĉ ĉ for Ġ( extension Ġin Ġcanonical Extensions ) Ċĉĉĉ ĉ require ( is Extension ( extension )) Ġ{ Ġreturn Ġnull Ġ} ĊĊĉĉ ĉ require ( canonical Private use Ġ== Ġnull Ġ|| Ġis Private use ( canonical Private use )) Ġ{ Ġreturn Ġnull Ġ} ĊĊĉĉ ĉ return ĠLanguage Tag ( Ċĉĉĉ ĉ extensions Ġ= Ġcanonical Extensions , Ċĉĉĉ ĉ ext langs Ġ= Ġcanonical Ext langs , Ċĉĉĉ ĉ language Ġ= Ġcanonical Language , Ċĉĉĉ ĉ private use Ġ= Ġcanonical Private use , Ċĉĉĉ ĉ region Ġ= Ġcanonical Region , Ċĉĉĉ ĉ script Ġ= Ġcanonical Script , Ċĉĉĉ ĉ variants Ġ= Ġcanonical Variants Ċĉĉ ĉ ) Ċĉ ĉ } ĊĊĊĉ ĉ public Ġfun Ġfor Private Use ( Ċĉĉ ĉ private use : ĠString , Ċĉ ĉ ): ĠLanguage Tag Ġ{ Ċĉĉ ĉ val Ġcanonical Private use Ġ= Ġcanonical ize Private use ( private use ) Ċĉĉ ĉ require ( canonical Private use Ġ!= Ġnull Ġ&& Ġis Private use ( private use )) Ġ{ Ġ" Invalid Ġprivate use : Ġ$ private use " Ġ} ĊĊĉĉ ĉ return ĠLanguage Tag ( Ċĉĉĉ ĉ extensions Ġ= Ġempty List (), Ċĉĉĉ ĉ ext langs Ġ= Ġempty List (), Ċĉĉĉ ĉ language Ġ= Ġnull , Ċĉĉĉ ĉ private use Ġ= Ġcanonical Private use , Ċĉĉĉ ĉ region Ġ= Ġnull , Ċĉĉĉ ĉ script Ġ= Ġnull , Ċĉĉĉ ĉ variants Ġ= Ġempty List () Ċĉĉ ĉ ) Ċĉ ĉ } ĊĊĊĉ ĉ public Ġfun Ġfor Private Use OrNull ( Ċĉĉ ĉ private use : ĠString , Ċĉ ĉ ): ĠLanguage Tag ? Ġ{ Ċĉĉ ĉ val Ġcanonical Private use Ġ= Ġcanonical ize Private use ( private use ) Ċĉĉ ĉ require ( canonical Private use Ġ!= Ġnull Ġ&& Ġis Private use ( private use )) Ġ{ Ġreturn Ġnull Ġ} ĊĊĉĉ ĉ return ĠLanguage Tag ( Ċĉĉĉ ĉ extensions Ġ= Ġempty List (), Ċĉĉĉ ĉ ext langs Ġ= Ġempty List (), Ċĉĉĉ ĉ language Ġ= Ġnull , Ċĉĉĉ ĉ private use Ġ= Ġcanonical Private use , Ċĉĉĉ ĉ region Ġ= Ġnull , Ċĉĉĉ ĉ script Ġ= Ġnull , Ċĉĉĉ ĉ variants Ġ= Ġempty List () Ċĉĉ ĉ ) Ċĉ ĉ } ĊĊĊĉ ĉ // Ġextension ĠĠĠĠ Ġ= Ġsingleton Ġ 1 * ("- " Ġ( 2 * 8 al phanum )) Ċĉ ĉ public Ġfun Ġis Extension ( extension : ĠString ): ĠBoolean Ġ{ Ċĉĉ ĉ val Ġtokens Ġ= Ġextension . split To Sequence ( separator ). iterator () ĊĊĉĉ ĉ if Ġ(! is Extension Singleton ( tokens . next ())) Ċĉĉĉ ĉ return Ġfalse ĊĊĉĉ ĉ if Ġ(! tokens . hasNext ()) Ċĉĉĉ ĉ return Ġfalse ĊĊĉĉ ĉ for Ġ( token Ġin Ġtokens ) Ċĉĉĉ ĉ if Ġ(! is Extension Sub tag ( token )) Ċĉĉĉĉ ĉ return Ġfalse ĊĊĉĉ ĉ return Ġtrue Ċĉ ĉ } ĊĊĊĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; ĠSingle Ġal phanum erics Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġ" x " Ġreserved Ġfor Ġprivate Ġuse Ċĉ ĉ // Ġsingleton ĠĠĠĠ Ġ= ĠDIG IT ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġ 0 Ġ- Ġ 9 Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ% x 4 1 - 5 7 ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; ĠA Ġ- ĠW Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ% x 5 9 - 5 A ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; ĠY Ġ- ĠZ Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ% x 6 1 - 7 7 ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġa Ġ- Ġw Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ% x 7 9 - 7 A ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġy Ġ- Ġz Ċĉ ĉ public Ġfun Ġis Extension Singleton ( singleton : ĠChar ): ĠBoolean Ġ= Ċĉĉ ĉ singleton . is Alpha Numeric () Ġ&& Ġ! is Private use Prefix ( singleton ) ĊĊĊĉ ĉ public Ġfun Ġis Extension Singleton ( singleton : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ singleton . length Ġ== Ġ 1 Ġ&& Ġis Extension Singleton ( singleton [ 0 ]) ĊĊĊĉ ĉ // Ġextension ĠĠĠĠ Ġ= Ġsingleton Ġ 1 * ("- " Ġ( 2 * 8 al phanum )) Ċĉ ĉ public Ġfun Ġis Extension Sub tag ( extension : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ extension . length Ġin Ġ 2 Ġ.. Ġ 8 Ġ&& Ġextension . is Alpha Numeric () ĊĊĊĉ ĉ // Ġext lang ĠĠĠĠĠĠ Ġ= Ġ 3 ALPHA ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġselected ĠISO Ġ 6 3 9 Ġcodes Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* 2 ("- " Ġ 3 ALPHA ) ĠĠĠĠĠ Ġ; Ġper manently Ġreserved Ċĉ ĉ public Ġfun Ġis Ext lang ( ext lang : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ ext lang . length Ġ== Ġ 3 Ġ&& Ġext lang . is Alpha () ĊĊĊĉ ĉ // Ġlanguage ĠĠĠĠĠ Ġ= Ġ 2 * 3 ALPHA ĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġshortest ĠISO Ġ 6 3 9 Ġcode Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ[" -" Ġext lang ] ĠĠĠĠĠĠ Ġ; Ġsometimes Ġfollowed Ġby Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġextended Ġlanguage Ġsub tags Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ 4 ALPHA ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġor Ġreserved Ġfor Ġfuture Ġuse Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ 5 * 8 ALPHA ĠĠĠĠĠĠĠĠĠĠĠ Ġ; Ġor Ġregistered Ġlanguage Ġsub tag Ċĉ ĉ public Ġfun Ġis Language ( language : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ language . length Ġin Ġ 2 Ġ.. Ġ 8 Ġ&& Ġlanguage . is Alpha () ĊĊĊĉ ĉ // Ġprivate use ĠĠĠ Ġ= Ġ" x " Ġ 1 * ("- " Ġ( 1 * 8 al phanum )) Ċĉ ĉ public Ġfun Ġis Private use ( private use : ĠString ): ĠBoolean Ġ{ Ċĉĉ ĉ val Ġtokens Ġ= Ġprivate use . split To Sequence ( separator ). iterator () ĊĊĉĉ ĉ if Ġ(! is Private use Prefix ( tokens . next ())) Ċĉĉĉ ĉ return Ġfalse ĊĊĉĉ ĉ if Ġ(! tokens . hasNext ()) Ċĉĉĉ ĉ return Ġfalse ĊĊĉĉ ĉ for Ġ( token Ġin Ġtokens ) Ċĉĉĉ ĉ if Ġ(! is Private use Sub tag ( token )) Ċĉĉĉĉ ĉ return Ġfalse ĊĊĉĉ ĉ return Ġtrue Ċĉ ĉ } ĊĊĊĉ ĉ // Ġprivate use ĠĠĠ Ġ= Ġ" x " Ġ 1 * ("- " Ġ( 1 * 8 al phanum )) Ċĉ ĉ public Ġfun Ġis Private use Prefix ( prefix : ĠChar ): ĠBoolean Ġ= Ċĉĉ ĉ prefix . equals ( private use Prefix , Ġignore Case Ġ= Ġtrue ) ĊĊĊĉ ĉ public Ġfun Ġis Private use Prefix ( prefix : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ prefix . length Ġ== Ġ 1 Ġ&& Ġis Private use Prefix ( prefix [ 0 ]) ĊĊĊĉ ĉ // Ġprivate use ĠĠĠ Ġ= Ġ" x " Ġ 1 * ("- " Ġ( 1 * 8 al phanum )) Ċĉ ĉ public Ġfun Ġis Private use Sub tag ( private use : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ private use . length Ġin Ġ 1 Ġ.. Ġ 8 Ġ&& Ġprivate use . is Alpha Numeric () ĊĊĊĉ ĉ // Ġregion ĠĠĠĠĠĠĠ Ġ= Ġ 2 ALPHA ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; ĠISO Ġ 3 1 6 6 - 1 Ġcode Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ 3 DIGIT ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; ĠUN ĠM . 4 9 Ġcode Ċĉ ĉ public Ġfun Ġis Region ( region : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ when Ġ( region . length ) Ġ{ Ċĉĉĉĉ 2 Ġ-> Ġregion . is Alpha () Ċĉĉĉĉ 3 Ġ-> Ġregion . is Numeric () Ċĉĉĉ ĉ else Ġ-> Ġfalse Ċĉĉ ĉ } ĊĊĊĉ ĉ // Ġscript ĠĠĠĠĠĠĠ Ġ= Ġ 4 ALPHA ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ; ĠISO Ġ 1 5 9 2 4 Ġcode Ċĉ ĉ public Ġfun Ġis Script ( script : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ script . length Ġ== Ġ 4 Ġ&& Ġscript . is Alpha () ĊĊĊĉ ĉ // Ġvariant ĠĠĠĠĠĠ Ġ= Ġ 5 * 8 al phanum ĠĠĠĠĠĠĠĠ Ġ; Ġregistered Ġvariants Ċĉ ĉ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/ Ġ( DIGIT Ġ 3 al phanum ) Ċĉ ĉ public Ġfun Ġis Variant ( variant : ĠString ): ĠBoolean Ġ= Ċĉĉ ĉ when Ġ( variant . length ) Ġ{ Ċĉĉĉĉ 4 Ġ-> Ġvariant [ 0 ]. is Numeric () Ġ&& Ġvariant [ 1 ]. is Alpha Numeric () Ġ&& Ġvariant [ 2 ]. is Alpha Numeric () Ġ&& Ġvariant [ 3 ]. is Alpha Numeric () Ċĉĉĉ ĉ in Ġ 5 Ġ.. Ġ 8 Ġ-> Ġvariant . is Alpha Numeric () Ċĉĉĉ ĉ else Ġ-> Ġfalse Ċĉĉ ĉ } ĊĊĊĉ ĉ public Ġfun Ġparse ( string : ĠString ): ĠLanguage Tag Ġ= Ċĉĉ ĉ parse OrNull ( string ) Ġ?: Ġerror (" Ill - formed ĠB CP Ġ 4 7 Ġlanguage Ġtag : Ġ$ string ") ĊĊĊĉ ĉ @ Suppress (" NAME _ SH ADO WING ") Ċĉ ĉ public Ġfun Ġparse OrNull ( string : ĠString ): ĠLanguage Tag ? Ġ{ Ċĉĉ ĉ val Ġstring Ġ= Ġgrand father ed [ string . toLowerCase ()] Ġ?: Ġstring ĊĊĉĉ ĉ val Ġtokens Ġ= Ġstring . split To Sequence ( separator ). iterator () ĊĊĉĉ ĉ var Ġext langs : ĠMutable List < String >? Ġ= Ġnull Ċĉĉ ĉ var Ġextensions : ĠMutable List < String >? Ġ= Ġnull Ċĉĉ ĉ var Ġlanguage : ĠString ? Ġ= Ġnull Ċĉĉ ĉ var Ġprivate use : ĠString ? Ġ= Ġnull Ċĉĉ ĉ var Ġregion : ĠString ? Ġ= Ġnull Ċĉĉ ĉ var Ġscript : ĠString ? Ġ= Ġnull Ċĉĉ ĉ var Ġvariants : ĠMutable List < String >? Ġ= Ġnull ĊĊĉĉ ĉ var Ġtoken : ĠString ? Ċĉĉ ĉ token Ġ= Ġtokens . next () Ċĉĉ ĉ if Ġ( is Language ( token )) Ġ{ Ċĉĉĉ ĉ language Ġ= Ġcanonical ize Language ( token ) Ċĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () ĊĊĉĉĉ ĉ if Ġ( token Ġ!= Ġnull Ġ&& Ġis Ext lang ( token )) Ġ{ Ċĉĉĉĉ ĉ ext langs Ġ= Ġmutable ListOf () ĊĊĉĉĉĉ ĉ do Ġ{ Ċĉĉĉĉĉ ĉ ext langs . add ( canonical ize Ext lang ( token ) !! ) ĊĊĉĉĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ while Ġ( token Ġ!= Ġnull Ġ&& Ġext langs . size Ġ< Ġ 3 Ġ&& Ġis Ext lang ( token )) Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ if Ġ( token Ġ!= Ġnull Ġ&& Ġis Script ( token )) Ġ{ Ċĉĉĉĉ ĉ script Ġ= Ġcanonical ize Script ( token ) Ċĉĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ if Ġ( token Ġ!= Ġnull Ġ&& Ġis Region ( token )) Ġ{ Ċĉĉĉĉ ĉ region Ġ= Ġcanonical ize Region ( token ) Ċĉĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ if Ġ( token Ġ!= Ġnull Ġ&& Ġis Variant ( token )) Ġ{ Ċĉĉĉĉ ĉ variants Ġ= Ġmutable ListOf () ĊĊĉĉĉĉ ĉ do Ġ{ Ċĉĉĉĉĉ ĉ variants . add ( canonical ize Variant ( token ) !! ) ĊĊĉĉĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ while Ġ( token Ġ!= Ġnull Ġ&& Ġis Variant ( token )) Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ if Ġ( token Ġ!= Ġnull Ġ&& Ġis Extension Singleton ( token )) Ġ{ Ċĉĉĉĉ ĉ extensions Ġ= Ġmutable ListOf () ĊĊĉĉĉĉ ĉ do Ġ{ Ċĉĉĉĉĉ ĉ val Ġextension Builder Ġ= ĠStringBuilder ( canonical ize Extension Singleton ( token ) !! ) ĊĊĉĉĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () ĊĊĉĉĉĉĉ ĉ if Ġ( token Ġ!= Ġnull Ġ&& Ġis Extension Sub tag ( token )) Ġ{ Ċĉĉĉĉĉĉ ĉ do Ġ{ Ċĉĉĉĉĉĉĉ ĉ extension Builder . append ( separator ) Ċĉĉĉĉĉĉĉ ĉ extension Builder . append ( canonical ize Extension Sub tag ( token )) ĊĊĉĉĉĉĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ while Ġ( token Ġ!= Ġnull Ġ&& Ġis Extension Sub tag ( token )) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ else Ċĉĉĉĉĉĉ ĉ return Ġnull Ġ// Ġincomplete Ġextension ĊĊĉĉĉĉĉ ĉ extensions . add ( extension Builder . toString ()) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ while Ġ( token Ġ!= Ġnull Ġ&& Ġis Extension Singleton ( token )) Ċĉĉĉ ĉ } Ċĉĉ ĉ } ĊĊĉĉ ĉ if Ġ( token Ġ!= Ġnull Ġ&& Ġis Private use Prefix ( token )) Ġ{ Ċĉĉĉ ĉ val Ġprivate use Builder Ġ= ĠStringBuilder ( canonical ize Private use Prefix ( token ) !! ) ĊĊĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () ĊĊĉĉĉ ĉ if Ġ( token Ġ!= Ġnull Ġ&& Ġis Private use Sub tag ( token )) Ġ{ Ċĉĉĉĉ ĉ do Ġ{ Ċĉĉĉĉĉ ĉ private use Builder . append ( separator ) Ċĉĉĉĉĉ ĉ private use Builder . append ( canonical ize Private use Sub tag ( token )) ĊĊĉĉĉĉĉ ĉ token Ġ= Ġtokens . next OrNull () Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ while Ġ( token Ġ!= Ġnull Ġ&& Ġis Private use Sub tag ( token )) Ċĉĉĉ ĉ } Ċĉĉĉ ĉ else Ċĉĉĉĉ ĉ return Ġnull Ġ// Ġincomplete Ġprivate use ĊĊĉĉĉ ĉ private use Ġ= Ġprivate use Builder . toString () Ċĉĉ ĉ } ĊĊĉĉ ĉ if Ġ( token Ġ!= Ġnull ) Ċĉĉĉ ĉ return Ġnull ĊĊĉĉ ĉ return ĠLanguage Tag ( Ċĉĉĉ ĉ extensions Ġ= Ġextensions . or Empty (), Ċĉĉĉ ĉ ext langs Ġ= Ġext langs . or Empty (), Ċĉĉĉ ĉ language Ġ= Ġlanguage , Ċĉĉĉ ĉ private use Ġ= Ġprivate use , Ċĉĉĉ ĉ region Ġ= Ġregion , Ċĉĉĉ ĉ script Ġ= Ġscript , Ċĉĉĉ ĉ variants Ġ= Ġvariants . or Empty (), Ċĉĉ ĉ ) Ċĉ ĉ } Ċ ĉ } Ċ } Ċ