diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fb2000e..879b967 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: #- windows-latest #- macOS-latest nim_version: - - '1.4.0' + - '1.6.12' - 'stable' needs: before steps: diff --git a/README.md b/README.md index 00217f1..d45d5b9 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ NICO is a simple game framework for the [Nim](http://nim-lang.org/) programming * For web builds you'll need [Emscripten](https://emscripten.org/docs/getting_started/downloads.html). * From your project directory run ```nimble webr``` to build for web in release mode. * From your project directory run ```nimble webd``` to build for web in debug mode. + * From your project directory run ```nimble runweb``` or ```emrun projectname.html ``` open browser run it. ## Learning * [API Documentation](API.md) diff --git a/exampleApp/exampleApp.nimble b/exampleApp/exampleApp.nimble index 918dd82..b90af7b 100644 --- a/exampleApp/exampleApp.nimble +++ b/exampleApp/exampleApp.nimble @@ -22,6 +22,9 @@ task runr, "Runs exampleApp for current platform": task rund, "Runs debug exampleApp for current platform": exec &"nim c -r {debugOpts} -o:exampleApp src/main.nim" +task runweb, "Runs web exampleApp for current platform": + exec &"emrun exampleApp.html" + task release, "Builds exampleApp for current platform": exec &"nim c {releaseOpts} -o:exampleApp src/main.nim" diff --git a/examples/assets/ChillBitmap7x.png b/examples/assets/ChillBitmap7x.png new file mode 100644 index 0000000..8c0d628 Binary files /dev/null and b/examples/assets/ChillBitmap7x.png differ diff --git a/examples/assets/ChillBitmap7x.png.dat b/examples/assets/ChillBitmap7x.png.dat new file mode 100644 index 0000000..98166fa --- /dev/null +++ b/examples/assets/ChillBitmap7x.png.dat @@ -0,0 +1 @@ + !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¡¢£¤¥¦§¨©ª«¬®¯°±´¶·¸º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩīĮįİıIJijĴĵĶķĹĺĻļĽľŁłŃńŅņŇňŊŋŌōŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžƁƆƇƈƉƊƎƏƐƑƒƓƔƖƗƘƙƝƤƥƩƪƬƭƮƱƲƳƴƷǍǎǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǢǣǦǧǾǿȘșȚțȨȩȪȫȲȳȷɂɃɄɅɋɌɑɓɔɖɗəɛɠɣɦɨɩɲɷɽɾʃʅʈʉʊʋʌʒʔʕʖʘʚʼʽʾʿ˂˃ˆˇˉˊˋˍ˘˙˚˛˜˝˪˫΄ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяёїԾಠಥกฅง฿ᇂᐛᴑᴗᴥᵍᵎᵏᵐᵒᵕḄḅḌḍḎḏḒḓḠḡḤḥḪḫḮḯḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉṊṋṌṍṐṑṒṓṜṝṞṟṢṣṬṭṮṯṰṱẀẁẂẃẄẅẎẏẒẓẔẕẖẗẞạẬậẸẹẼẽỆệỊịỌọỏỘộỤụỲỳỸỹ῀‐‑‒–—―‖‘’‚“”„†‡•‥…‧‰′″‴‵‷‸‹›※‼‾‿⁄⁰⁽⁾₀₃₍₎₪€₴₹₽⃝℃℅℉№℡™ÅⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩↁↂ←↑→↓↔↕↖↗↘↙⇎⇒⇔∂∃∇∈∋∏∑−∙√∝∞∟∠∣∥∧∨∩∫∬∮∴∵∷∼∽≈≒≖≝≠≡≤≥≦≧≪≫≼≽⊂⊃⊆⊇⊕⊖⊙⊜⊥⊹⊿⋚⋛⌒⎛⎝⎞⎠⎩⎭①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵Ⓘⓔⓛⓞⓥ⓪─│┌┐└┘├┤┬┴┼═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕■□▣▤▥▦▧▨▩▪▫▬▰▲△▶▷►▻▼▽◀◁◄◆◇◈◉◊○◌◍◎●◐◑◓◔◕◘◙◛◜◝◞◟◡◢◣◤◥◦◨◯☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☜☞☭☮☯☹☺☻☼☽☾♀♂♠♡♢♣♤♥♦♧♨♩♪♫♬♭♯⚆✂✈✉✓✕✖✗✚✡✦✧✨✪✽✿❀❂❄❖⧸⧹ⱤⱭⱲⱳ⺁⺄⺈⺋⺌⺗⺧⺪⺮⺳⺶⺷⺻⺾⻊⻌⻍⻎⻜⼾⾡⿈⿊、。〃〄々〆〇〈〉《》「」『』【】〒〓〔〕〖〗〜〝〞〟〠〡〢〣〤〥〦〧〨〩ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん゛゜ゝゞァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ・ーヽヾㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩㄪㄫㄬㄭㄮㄯㅂㆀㆆㆠㆡㆢㆣㆤㆥㆦㆧㆨㆩㆪㆫㆬㆭㆮㆯㆰㆱㆲㆳㆴㆵㆶㆷㆸㆹㆺㆻㆼㆽㆾㆿ㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩㈱㈲㈹㉨㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㊤㊥㊦㊧㊨㋿㌃㌍㌔㌘㌢㌣㌦㌧㌫㌶㌻㍉㍊㍍㍑㍗㍻㍼㍽㍾㎎㎏㎜㎝㎞㎡㏄㏍㏎㏒㏕㐁㑑㓤㓾㕷㖡㖭㖿㗎㗒㗳㗾㜷㤘㧒㧡㧸㧾㨘㩒㩧㩮㬹㷧㷫㸃㹴䀴䀹䁅䁥䁪䂻䃟䆀䌈䏝䓪䗁䘆䘼䟴䤭䥑䨒䪴䫌䯋䱽䲁䲅䲳䴈一丁丂七丄丅丆万丈三上下丌不与丏丐丑丒专且丕世丗丘丙业丛东丝丞丟丠両丢丣两严並丧丨丩个丫丬中丮丯丰丱串丳临丵丶丷丸丹为主丼丽举丿乀乁乂乃乄久乆乇么义乊之乌乍乎乏乐乑乒乓乔乕乖乗乘乙乚乛乜九乞也习乡乢乣乤乥书乧乨乩乪乫乬乭乮乯买乱乲乳乴乵乶乷乸乹乺乻乼乽乾乿亀亁亂亃亄亅了亇予争亊事二亍于亏亐云互亓五井亖亗亘亙亚些亜亝亞亟亠亡亢亣交亥亦产亨亩亪享京亭亮亯亰亱亲亳亴亵亶亷亸亹人亻亼亽亾亿什仁仂仃仄仅仆仇仈仉今介仌仍从仏仐仑仒仓仔仕他仗付仙仚仛仜仝仞仟仠仡仢代令以仦仧仨仩仪仫们仭仮仯仰仱仲仳仴仵件价仸仹仺任仼份仾仿伀企伂伃伄伅伆伇伈伉伊伋伌伍伎伏伐休伒伓伔伕伖众优伙会伛伜伝伞伟传伡伢伣伤伥伦伧伨伩伪伫伬伭伮伯估伱伲伳伴伵伶伷伸伹伺伻似伽伾伿佀佁佂佃佄佅但佇佈佉佊佋佌位低住佐佑佒体佔何佖佗佘余佚佛作佝佞佟你佡佢佣佤佥佦佧佨佩佪佫佬佭佮佯佰佱佲佳佴併佶佷佸佹佺佻佼佽佾使侀侁侂侃侄侅來侇侈侉侊例侌侍侎侏侐侑侒侓侔侕侖侗侘侙侚供侜依侞侟侠価侢侣侤侥侦侧侨侩侪侫侬侭侮侯侰侱侲侳侴侵侶侷侸侹侺侻侼侽侾便俀俁係促俄俅俆俇俈俉俊俋俌俍俎俏俐俑俒俓俔俕俖俗俘俙俚俛俜保俞俟俠信俢俣俤俥俦俧俨俩俪俫俬俭修俯俰俱俲俳俴俵俶俷俸俹俺俻俼俽俾俿倀倁倂倃倄倅倆倇倈倉倊個倌倍倎倏倐們倒倓倔倕倖倗倘候倚倛倜倝倞借倡倢倣値倥倦倨倩倪倫倬倭倮倶倹债值倾偃假偈偉偌偎偏偐偕偖做停健偬偭偯偲側偵偶偷偸偺偻偽偾偿傀傅傈傌傍傑傕傖傘備傚傜傢傣傥傧储傩催傭傯傲傳傴債傷傸傺傻傾僂僅僇僉僊働僎像僑僕僖僚僞僣僥僦僧僨僩僫僬僭僮僱僳僵價僻儀儁儂億儅儆儇儈儉儋儐儒儔儕儖儘儚償儡優儲儳儷儸儺儻儼儿兀允兂元兄充兆兇先光兊克兌免兎兏児兑兒兓兔兕兖兗兙党兛兜兝兞兡兢兣入兦內全兩兪八公六兮兯兰共兲关兴兵其具典兹养兼兽冀冁冂冃冄内円冇冈冉冊冋册再冎冏冐冑冒冓冔冕冖冗冘写冚军农冝冞冠冢冤冥冦冧冨冩冪冫冬冭冮冯冰冱冲决冴况冶冷冻冼冽冾净凃凄凅准凇凈凉凋凌凍凎减凑凖凛凜凝几凡凢凤凥処凧凩凪凫凭凮凯凰凱凳凴凵凶凷凸凹出击凼函凾凿刀刁刂刃刄刅分切刈刉刊刋刌刍刎刑划刔刕刖列刘则刚创初删刣判別刧刨利刪别刭刮到刳制刷券刹刺刻刽刿剀剁剂剃剄則剉削剋剌前剎剏剐剑剔剖剛剜剝剞剡剣剤剥剧剩剪副剰剱割剳剴創剷剽剾剿劁劂劃劄劇劈劉劊劍劏劐劑劒劓劔劖力劜劝办功加务劢劣劦动助努劫劬劭励劲劳労劵効劻劼劾势勀勁勃勅勇勉勋勍勐勒動勖勗勘務勛勝勞募勠勢勣勤勥勦勧勰勲勳勵勷勸勹勺勻勼勽勾勿匀匁匂匃包匆匈匊匋匍匏匐匕化北匘匙匚匛匜匝匞匟匠匡匣匦匪匭匮匯匱匳匸匹区医匾匿區十卂千卄卅卆升午卉半卋卌卍华协卐卑卒卓協单卖南単博卜卝卞卟占卡卢卣卤卥卦卧卨卩卪卫卬卭卮卯印危即却卵卷卸卹卺卻卽卿厂厃厄厅历厉压厌厍厎厕厖厘厙厚厝原厠厢厣厥厦厨厩厭厮厰厲厳厴厶去县叁参參又叉及友双反収发叔取受变叙叚叛叟叠叡叢口古句另叨叩只叫召叭叮可台叱史右叵叶号司叹叺叻叼叽叾吁吃各吆吇合吉吊吋同名后吏吐向吒吓吔吕吖吗君吝吞吟吠吡吣吥否吧吨吩吪含听吭吮启吱吲吳吴吵吶吸吹吻吼吽吾吿呀呂呃呆呈呉告呋呎呐呑呒呓呔呕呖呗员呙呛呜呟呢呣呤呦周呪呯呰呱呲味呵呶呷呸呻呼命咀咁咂咄咆咇咈咊咋和咎咏咐咑咒咓咔咕咖咗咙咚咛咝咡咢咣咤咥咦咧咨咩咪咫咬咭咯咱咲咳咴咸咹咻咼咽咾咿哀品哂哄哆哇哈哉哋哌响哎哏哐哑哒哓哔哕哖哗哘哙哚哜哝哞哟員哢哥哦哧哨哩哪哭哮哲哳哺哼哽哿唁唄唆唇唉唏唐唑唓唔唖唚唛唞唠唢唣唤唥唧唪唬唭售唯唰唱唳唵唷唸唹唼唾唿啀啁啃啄啅商啉啊啋啌啍問啐啓啕啖啗啜啝啞啟啡啣啤啥啦啧啩啪啫啬啭啮啰啱啲啵啶啷啸啹啻啼啾喀喁喂喃善喆喇喈喉喊喋喎喏喑喔喘喙喚喜喝喞喟喧喨喩喪喫喬單喰喱喲喳喵営喷喹喺喻喼喽喾嗄嗅嗆嗇嗉嗌嗍嗎嗐嗑嗒嗓嗔嗖嗗嗚嗜嗝嗟嗡嗣嗤嗥嗦嗧嗨嗩嗪嗫嗬嗯嗰嗱嗲嗳嗵嗶嗷嗹嗽嗾嘀嘁嘂嘅嘆嘈嘉嘌嘍嘎嘏嘐嘓嘔嘖嘗嘘嘚嘛嘜嘞嘟嘢嘣嘤嘥嘧嘩嘬嘭嘮嘯嘰嘱嘲嘴嘶嘸嘹嘻嘿噀噁噂噃噉噌噍噎噏噐噒噓噔噗噘噙噚噛噜噝噠噢噤噥器噩噪噫噬噯噱噴噶噸噹噺噻噼嚀嚄嚅嚆嚇嚉嚊嚎嚏嚐嚓嚔嚕嚙嚟嚠嚡嚢嚣嚤嚥嚦嚨嚭嚮嚯嚱嚴嚶嚷嚹嚼嚿囀囁囂囃囈囉囊囌囍囎囑囒囓囔囖囗囘囙囚四囜囝回囟因囡团団囤囥囦囧囨囩囪囫囬园囮囯困囱囲図围囵囶囷囸囹固囻囼国图囿圀圁圂圃圄圅圆圇圈圉圊國圌圍圎圏圐圑園圓圔圕圖圗團圙圚圛圜圝圞土圠圡圢圣圤圦圧在圩圪圬圭圮圯地圳圷圸圹场圻圾址坂均坊坌坍坎坏坐坑坔块坚坛坜坝坞坟坠坡坤坦坨坩坪坫坭坯坳坵坶坷坻坼坿垂垃垄垅垆垈垉型垌垒垓垚垛垠垡垢垣垤垦垧垩垪垫垭垮垰垱垲垳垴垵垸垺垻埀埂埃埆埋城埏埒埓埔埕埖埗埘埙埚埜埝埞域埠埡埣埤埧埪埭埯埲埴執埸培基埼埽堀堂堃堅堆堇堉堊堋堍堑堕堙堝堞堠堡堤堪堭堯堰報場堵堺堽塀塁塄塊塋塌塍塑塒塔塗塘塙塚塞塡塢塤塥塩填塬塭塯塰塱塲塳塵塹塽塾墀墁境墅墉墊墒墓増墘墙墚墜增墟墣墦墨墩墫墬墮墳墶墸墹墺墻墼墾壁壂壅壆壇壊壌壎壑壓壕壗壘壙壚壜壞壟壠壢壤壥壩士壬壮壯声壱売壳壶壷壹壺壻壼壽夂处夆备変夊夌复夏夐夓夔夕外夘夙多夛夜够夠夢夤夥大夨天太夫夬夭央夯夰失夲夳头夷夸夹夺夼夾奀奁奂奄奇奈奉奋奌奎奏奐契奔奕奖套奘奚奠奢奥奧奨奩奪奬奭奮女奴奶奸她奼好妁如妃妄妆妇妈妊妍妏妒妓妖妗妘妙妛妝妞妣妤妥妨妩妪妫妬妮妯妲妳妹妻妾姅姆姉姊始姍姐姑姒姓委姗姘姙姚姜姝姣姥姦姨姪姫姬姮姵姶姹姻姿威娃娄娅娆娇娈娉娌娑娓娘娚娛娜娟娠娣娥娩娯娱娲娳娴娵娶娼婀婁婆婉婊婕婚婢婦婧婪婬婭婴婵婶婷婺婿媄媒媗媚媛媜媞媠媧媪媬媱媲媳媵媸媺媼媽媾嫁嫂嫈嫉嫋嫌嫐嫒嫔嫖嫗嫘嫚嫜嫠嫡嫣嫦嫩嫫嫱嫲嫵嫺嫻嬃嬅嬈嬉嬋嬌嬖嬗嬛嬝嬡嬢嬤嬪嬬嬰嬲嬴嬶嬷嬸嬾嬿孀孃孅孋孌孍子孑孒孓孔孕孖字存孙孚孛孜孝孞孟孢季孤孥学孩孪孫孬孭孰孱孳孵學孺孻孽孿宀宁宂它宄宅宇守安宋完宍宏宐宓宕宗官宙定宛宜宝实実宠审客宣室宥宦宪宫宮宰害宴宵家宸容宽宾宿寂寃寄寅密寇寉富寍寐寒寓寔寛寝寞察寡寢寤寥實寧寨審寫寬寮寰寳寵寶寸对寺寻导対寿封専射尅将將專尉尊尋對導小尐少尒尓尔尕尖尗尘尙尚尜尝尠尢尣尤尥尧尨尪尬尭就尴尶尷尸尹尺尻尼尽尾尿局屁层屄居屆屇屈屉届屋屌屍屎屏屐屑屓展屘屙屛屜屝属屠屡屢屣層履屦屨屬屭屮屯屰山屳屴屵屶屹屺屾屿岁岂岈岌岍岐岑岔岖岗岘岙岚岛岜岠岡岢岣岨岩岫岬岭岱岳岵岶岷岸岻岼岽岾岿峀峁峄峅峇峋峒峙峠峡峣峤峥峦峨峩峪峭峯峰峴島峺峻峽崁崂崃崆崇崋崌崎崑崔崕崖崗崘崙崚崛崞崟崠崢崤崦崧崩崭崮崴崽崾嵇嵊嵋嵌嵎嵐嵒嵖嵘嵙嵛嵜嵝嵩嵫嵬嵯嵳嵴嵶嶂嶄嶇嶋嶌嶐嶔嶙嶝嶠嶢嶬嶮嶷嶸嶺嶼嶽巅巉巌巍巒巓巔巖巛川州巟巠巡巢巣巤工左巧巨巩巫差巯己已巳巴巵巷巸巻巽巾巿帀币市布帅帆师帋希帏帐帑帔帕帖帘帙帚帛帜帝帟帥带帧師席帮帯帰帱帳帶帷常帻帼帽幀幂幃幄幅幇幌幎幔幕幗幛幞幟幡幢幣幤幪幫干平年幵并幷幸幹幺幻幼幽幾广庀庁庂広庄庆庇床庋序庐庑库应底庖店庙庚府庞废庠庥度座庫庭庳庴庵庶康庸庹庾廁廂廃廄廈廉廊廍廏廐廑廒廓廔廖廚廛廝廟廠廡廢廣廨廩廪廬廰廱廳廴延廷廸建廻廼廾廿开弁异弃弄弇弈弉弊弋弌弍弎式弐弑弒弓弔引弖弗弘弛弜弟张弥弦弧弩弪弭弯弱張強弸弹强弼弾彀彁彆彈彊彌彎彐彑归当录彖彗彘彙彜彝彞彡形彣彤彥彦彧彩彪彫彬彭彰影彳彷役彻彼彿往征徂徃径待徇很徉徊律後徐徑徒従徕得徘徙徜從徠御徨復循徫徬徭微徳徴徵德徹徼徽心忄必忆忉忌忍忏忐忑忒忓忖志忘忙応忝忟忠忡忤忧忪快忭忮忰忱念忸忻忼忽忾忿怀态怂怃怄怅怆怊怍怎怏怐怒怔怕怖怙怛怜思怠怡急怦性怨怩怪怫怯怱怵怺总怼怿恁恂恃恆恊恋恍恐恒恓恕恙恚恝恟恠恢恣恤恥恧恨恩恪恫恬恭息恰恳恵恶恷恸恹恺恻恼恽恿悁悃悄悅悉悋悌悍悒悔悖悗悚悛悝悟悠患悦悧您悩悪悫悬悭悯悱悲悳悴悵悶悸悻悼悽情惆惇惊惋惑惓惕惘惚惜惝惟惠惡惣惦惧惨惩惫惬惭惮惯惰惱想惴惶惷惹惺惻愀愁愃愆愈愉愍愎意愒愓愔愕愚愛愜感愠愡愣愤愦愧愨愫愬愴愷愼愽愾愿慂慄慇慈慊態慌慍慎慑慓慕慘慙慚慝慟慢慣慤慥慧慨慪慫慮慯慰慱慳慴慵慶慷慼慾憂憇憊憋憎憐憑憔憖憙憚憝憤憧憨憩憫憬憮憲憶憷憺憾懂懃懆懇懈應懊懋懌懍懐懑懒懔懞懟懣懦懨懲懴懵懶懷懸懺懼懽懾懿戀戆戇戈戉戊戋戌戍戎戏成我戒戓戔戕或戗战戙戚戛戝戞戟戡戢戤戥戦戩截戬戮戯戰戲戳戴戶户戸戻戽戾房所扁扃扇扈扉手扌才扎扑扒打扔払托扙扚扛扞扠扣扥扦执扨扩扪扫扬扭扮扯扰扱扳扶批扺扼找承技抂抃抄抆抉把抌抑抒抓抔投抖抗折抚抛抜択抟抠抡抢护报抦抨披抬抱抵抹抺抻押抽抿拂拃拄担拆拇拈拉拊拋拌拍拎拏拐拑拒拓拔拖拗拘拙拚招拜拝拟拠拡拢拣拤拥拦拧拨择括拭拮拯拱拳拴拵拶拷拼拽拾拿持挂指挈按挌挎挑挖挙挚挛挝挞挟挠挡挢挣挤挥挦挧挨挪挫振挲挵挹挺挽挾挿捂捃捅捆捉捋捌捍捎捏捐捕捗捜捞损捡换捣捧捨捩捫捭据捯捱捲捶捷捺捻捽掀掂掃掄掇授掉掊掌掎掏掐排掖掘掙掛掟掠採探掣接控推掩措掫掬掭掮掰掲掳掴掵掷掸掹掺掻掼掾揀揃揄揆揈揉揍揎描提插揖揚換揞揠握揣揤揦揩揪揬揭揮揲援揶揸揹揺揻揼揽揾揿搀搁搂搅搆搇搋搌損搏搐搓搔搖搗搙搛搜搝搞搠搡搣搥搦搧搨搪搬搭搲搴搵搶携搽搾搿摀摁摂摃摄摅摆摇摈摊摎摑摒摔摘摙摜摞摟摧摩摭摯摰摱摳摵摶摷摸摹摺摻撂撃撄撅撇撈撍撐撑撒撓撕撖撘撙撚撞撟撢撣撤撥撩撫撬播撮撰撲撳撴撵撷撸撹撺撻撼撾撿擀擁擂擄擅擇擊擋操擎擐擒擔擗擘據擝擞擠擡擢擣擤擦擧擬擭擯擰擱擲擴擶擷擸擺擻擼擽擾攀攅攆攉攏攑攒攔攖攘攙攜攝攞攢攣攤攥攪攫攬攮支攰攴攵收攷攸改攺攻放政故效敉敌敍敎敏救敔敕敖敗敘教敛敝敞敢散敦敫敬数敲整敵敷數斂斃文斈斉斋斌斎斐斑斓斕斗料斛斜斟斡斤斥斧斩斫斬断斯新斲斷方於施旁旂旃旄旅旆旋旌旎族旒旖旗旙旛无旡既日旦旧旨早旬旭旮旯旰旱时旷旸旺旻旼昀昂昃昆昇昉昊昌明昏易昔昕昙昜昝星映昤春昧昨昫昭是昱昴昵昶昼显昿晁時晃晄晅晉晋晌晏晒晓晔晕晖晗晚晝晞晟晡晢晤晦晧晨晩普景晰晴晶晷智晾暁暂暃暄暇暈暉暌暍暎暐暑暖暗暘暝暢暦暧暨暪暫暮暱暴暸暹暼暾曁曄曆曇曉曖曙曚曛曜曝曠曣曦曩曬曯曰曱曲曳更曵曷書曹曺曼曽曾替最會月有朊朋服朏朐朑朔朕朖朗望朝朞期朥朦朧木朩未末本札朮术朰朱朴朵朶朷朸机朽朿杀杁杂权杆杈杉杋杌李杏材村杓杕杖杗杙杜杞束杠条杢杣杤来杧杨杩杪杭杯杰東杲杳杵杷杺杻杼松板极构枅枇枉枋枌枏析枒枓枕林枘枚果枝枞枠枡枢枣枥枦枧枨枩枪枫枭枯枰枱枳枴枵架枷枸枹柁柃柄柆柈柊柎柏某柑柒染柔柘柙柚柜柝柞柠柢柤查柧柩柬柮柯柰柱柳柴柵柺査柽柾柿栀栂栃栄栅标栈栉栊栋栌栎栏树栓栖栗栘栝栞栟校栢栩株栫栲栳栴样核根格栽栾桀桁桂桃桄桅框案桉桊桌桍桎桐桑桓桔桕桙桜桝桟桠桡桢档桤桥桦桧桨桩桫桴桶桷桹桾桿梁梂梃梅梆梇梍梏梓梔梗梘梛條梟梠梡梢梦梧梨梭梯械梱梲梳梵梶梹梺梼检棂棄棆棈棉棊棋棍棒棔棕棖棗棘棚棟棠棡棣棧棨棪森棯棰棱棲棵棹棺棻棼椀椁椄椅椈椋椌植椎椏椐椒椙椚椛検椟椠椡椢椣椤椥椦椨椪椭椰椴椶椹椽椿楂楊楓楔楕楗楙楚楛楜楝楞楠楡楢楣楦楨楪楫楬業楮楯楱楳楴極楷楸楹楼楽楾榀榁概榄榆榇榈榉榊榍榎榑榔榕榖榘榛榜榠榣榦榧榨榫榭榮榱榲榴榷榻榾榿槁槃槇槊構槌槍槎槐槓槔様槙槛槝槞槟槠槤槧槨槪槫槭槲槳槹槺槻槽槿樁樂樅樊樋樌樑樒樓樔樗樘標樛樞樟模樢樣樨権横樫樮樯樱樵樶樸樹樺樽樾橄橇橈橋橐橘橙橛機橡橢橥橦橫橱橲橸橹橼橾橿檀檄檍檎檐檑檔檗檜檠檢檣檨檩檪檫檬檮檯檳檸檻櫁櫂櫃櫆櫈櫑櫓櫚櫛櫝櫞櫟櫥櫧櫨櫪櫫櫬櫳櫸櫺櫻欄欅欉權欐欒欖欗欝欞欟欠次欢欣欤欧欲欷欸欹欺欽款歃歆歇歉歌歎歐歓歔歙歛歜歟歡止正此步武歧歩歪歯歲歳歴歷歸歹歺死歼歿殀殁殂殃殄殆殇殉殊残殍殒殓殕殖殘殚殛殞殡殤殪殫殭殮殯殱殲殳殴段殷殺殻殼殿毀毁毂毅毆毋毌母毎每毐毑毒毓比毕毖毗毘毙毚毛毟毡毪毫毬毯毳毵毹毽氅氆氇氈氊氍氏氐民氓气氕氖気氘氙氚氛氜氝氞氟氠氡氢氣氤氥氦氧氨氩氪氫氬氭氮氯氰氱氲氳水氵氶氷永氹氺氽氾汀汁求汆汇汉汊汍汎汐汔汕汗汙汚汛汜汝汞江池污汢汤汨汩汪汫汰汲汳汴汶汹決汽汾沁沂沃沄沅沆沈沉沌沍沏沐沒沓沔沖沘沙沚沛沟没沢沣沤沥沦沧沨沩沪沫沬沭沮沱沲河沸油沺治沼沽沾沿況泂泄泅泉泊泌泐泓泔法泖泗泙泛泜泝泞泠泡波泣泥注泪泫泮泯泰泱泳泵泶泷泸泺泻泼泽泾洁洄洇洋洌洎洐洒洗洙洚洛洞洟津洧洨洩洪洫洮洱洲洳洵洶洸洹洺活洼洽派流浃浄浅浆浇浈浊测浍济浏浑浒浓浔浕浙浚浜浞浠浣浤浥浦浩浪浬浮浯浴海浸浹浼涂涅涇消涉涊涌涎涑涓涔涕涘涙涛涜涝涞涟涠涡涣涤润涧涨涩涪涫涮涯液涵涷涸涼涿淀淄淅淆淇淋淌淍淑淒淕淖淘淙淚淝淞淠淡淤淥淦淨淩淪淫淬淮淯深淳淵混淸淹淺添淼清渇済渉渊渋渌渍渎渐渑渓渔渕渖渗渙渚減渝渟渠渡渣渤渥渦温渫測渭渮港渲渴游渺渼渾湃湄湊湍湎湓湔湖湘湛湟湡湣湧湩湫湮湯湲湳湶湾湿満溂溃溅溆溉溌溏源準溘溜溝溟溢溥溧溪溫溯溱溲溴溶溷溺溻溼溽滁滂滄滅滇滉滋滌滎滏滑滓滔滕滗滘滙滚滝滞滟滠满滢滤滥滦滨滩滬滯滲滴滷滸滹滾滿漁漂漆漉漏漑漓演漕漚漠漢漣漤漥漧漩漪漫漬漭漯漱漲漳漶漸漾漿潁潅潆潇潋潍潑潔潘潛潜潞潟潠潢潤潦潭潮潯潰潲潴潸潺潼潾澀澁澂澄澆澇澈澉澌澍澎澐澑澔澗澜澠澡澣澤澦澧澪澱澳澴澶澹激濁濂濃濆濉濑濒濔濕濘濛濞濟濠濡濤濨濩濫濬濮濯濰濱濳濶濺濾瀁瀂瀅瀆瀉瀋瀏瀑瀕瀘瀚瀛瀝瀞瀟瀡瀣瀦瀧瀨瀬瀰瀲瀵瀹瀾灃灌灏灑灔灕灘灝灞灠灣灤灥灧灩火灬灭灯灰灵灶灸灼災灾灿炀炅炆炉炊炎炒炔炕炖炘炙炜炝炤炫炬炭炮炯炱炳炷炸点為炻炼炽烀烁烂烃烇烈烊烋烏烔烘烙烚烛烜烝烟烤烦烧烨烩烫烬热烯烱烴烷烹烽焄焉焊焌焐焓焔焕焖焗焘焙焚焜焠無焢焦焯焰焱然焼焿煀煃煅煆煇煉煊煌煎煏煐煑煒煕煖煙煚煜煞煢煤煥煦照煨煩煬煮煲煳煸煺煽熄熈熊熏熒熔熕熗熘熙熟熠熨熬熱熳熵熹熾燁燃燄燈燉燊燎燐燒燔燕燗燙燜營燠燥燦燧燬燭燮燴燵燶燸燹燻燼燾燿爆爌爍爐爛爝爨爪爫爬爭爰爱爲爵父爷爸爹爺爻爼爽爾爿牀牆片版牋牌牍牒牖牘牙牛牝牟牠牡牢牤牦牧物牮牯牲牴牵特牺牽牾牿犀犁犂犄犇犊犋犍犏犒犖犛犟犠犡犢犧犬犭犮犯犰犲犴状犷犸犹狀狁狂狃狄狆狈狍狎狐狒狗狙狛狞狠狡狢狨狩独狭狮狯狰狱狲狳狴狷狸狹狺狻狼狽猁猃猊猎猓猕猖猗猙猛猜猝猞猟猡猢猥猩猪猫猬献猯猱猴猶猷猸猹猻猾猿獁獃獄獅獇獍獎獏獐獒獗獠獢獣獨獪獬獭獯獰獲獴獵獷獸獺獻獼獾玀玄玆率玉玊王玎玑玒玕玖玘玙玛玟玠玡玢玥玦玨玩玫玭玮环现玲玳玷玺玻玽珀珂珅珈珉珊珍珎珏珐珑珙珝珞珠珡珣珥珧珩珪班珮珰珱珲珸珺珽現球琄琅理琇琉琊琍琏琐琚琛琡琢琤琥琦琨琪琬琭琮琯琰琲琳琴琵琶琺琼琿瑀瑁瑄瑋瑕瑗瑙瑚瑛瑜瑞瑟瑠瑢瑣瑤瑩瑪瑭瑯瑰瑱瑲瑳瑶瑷瑾璀璁璃璇璉璊璋璎璐璘璜璞璟璠璢璣璦璧璨璩璪環璱璸璺璽璿瓈瓊瓏瓒瓔瓖瓘瓚瓜瓞瓠瓢瓣瓤瓦瓧瓩瓮瓯瓰瓱瓲瓴瓶瓷瓸瓿甃甄甅甌甍甎甏甑甓甕甘甙甚甜甞生甡產産甥甦用甩甫甬甭甯田由甲申甴电男甸町画甼甽甾畀畄畅畆畇畈畉畊畋界畍畎畏畑畔留畚畛畜畝畠畢畤略畦畧畩番畫畬畭異畲畳畴當畷畸畹畿疂疃疆疇疉疊疋疎疏疑疒疔疖疗疙疚疝疟疠疡疢疣疤疥疪疫疬疮疯疰疱疲疳疴疵疸疹疼疽疾痀痂痃痄病症痈痉痊痍痒痔痕痖痘痙痛痞痠痢痣痤痦痧痨痩痪痫痰痱痲痳痴痹痺痼痾痿瘀瘁瘃瘅瘉瘊瘋瘌瘍瘐瘓瘕瘖瘗瘘瘙瘛瘜瘞瘟瘠瘡瘢瘤瘥瘦瘧瘩瘪瘫瘭瘮瘰瘳瘴瘵瘸瘺瘻瘼瘾瘿癀療癃癆癇癈癌癍癎癒癔癖癘癜癞癟癡癢癣癤癥癦癧癨癩癪癫癬癮癯癰癱癲癶癸発登發白百皀皂皃的皆皇皈皋皎皐皑皓皖皙皚皛皞皤皮皰皱皲皴皷皸皹皺皿盂盃盅盆盈益盍盎盏盐监盒盔盖盗盘盛盜盞盟盡監盤盥盧盪盬目盯盱盲直盷相盹盻盼盾省眄眇眈眉看県眍眙眚眛眞真眠眢眤眥眦眨眩眭眯眵眶眷眸眺眼眾着睁睃睆睇睏睐睑睚睛睜睞睡睢督睥睦睨睩睪睫睬睹睽睾睿瞀瞄瞅瞇瞋瞌瞍瞎瞑瞒瞓瞞瞟瞠瞢瞥瞧瞩瞪瞬瞭瞰瞳瞵瞶瞹瞻瞼瞽瞿矇矋矍矓矗矚矛矜矢矣知矧矩矫矬短矮矯石矶矸矻矼矽矾矿砀码砂砈砉砌砍砑砒研砕砖砗砘砚砜砝砟砠砣砥砦砧砩砬砭砰砱砲破砵砷砸砹砺砻砼砾砿础硃硅硇硌硎硐硒硓硕硖硗硝硤硦硪硫硬硭确硯硲硴硷硼硿碁碆碇碉碌碍碎碑碓碕碖碗碘碚碛碜碟碡碣碥碧碩碪碯碰碱碲碳碴碵碹確碼碾磁磅磆磉磊磋磐磑磔磕磘磙磚磜磡磧磨磬磯磲磴磷磺磻磽礁礅礇礎礐礑礒礓礙礞礡礤礦礪礫礬礱礴示礻礼礽社祀祁祂祅祆祇祈祉祎祐祓祕祖祗祚祛祜祝神祟祠祢祥祧票祭祯祷祸祺祼祿禀禁禄禅禊禍禎福禔禕禚禛禝禡禤禦禧禪禮禰禱禳禹禺离禽禾禿秀私秃秆秈秉秋种科秒秕秘秝租秡秣秤秦秧秩秫秬秭积称秸移秽秾稀稂稃稅稆稈稉程稍税稔稗稘稙稚稜稞稟稠稣種稱稲稳稷稹稻稼稽稾稿穀穂穃穆穇穉穋穌積穎穏穐穑穗穠穡穢穣穨穩穫穰穴究穷穸穹空穽穿窀突窃窄窆窈窍窑窒窓窕窖窗窘窜窝窟窠窣窥窦窨窩窪窬窭窮窯窰窳窶窸窺窿竃竄竅竇竈竊立竍竏竑竒竓竕竖站竚竜竝竞竟章竡竢竣童竦竪竭端竰競竸竹竺竽竿笂笃笄笆笈笊笋笏笑笔笕笘笙笛笞笠笤笥符笨笪笫第笭笮笱笳笵笶笸笹笺笼笾筅筆筇筈等筊筋筌筍筏筐筑筒答策筘筚筛筝筠筢筥筦筧筬筮筯筰筱筲筴筵筷筹筺筻签简箄箅箆箇箋箍箎箏箐箒箔箕算箘箙箚箜箝箟箠管箢箦箧箨箩箪箫箬箭箱箴箸節篁範篆篇築篋篌篏篑篓篙篚篛篝篠篡篤篥篦篩篪篭篮篱篳篶篷篼篾簀簇簋簌簍簏簑簒簓簔簖簗簞簟簡簣簦簧簪簫簰簷簸簽簾簿籀籁籃籌籍籏籐籓籔籖籗籘籙籜籟籠籣籤籥籬籮籲米籴籵籸类籼籽籾粁粂粃粄粉粋粍粐粑粒粕粗粘粛粜粝粞粟粡粢粤粥粧粨粪粫粭粮粱粲粳粵粹粺粼粽精粿糀糁糂糅糇糈糉糊糌糍糎糒糕糖糗糘糙糜糝糞糟糠糢糧糨糬糭糯糰糲糴糶糸糺系糾紀紂約紅紆紇紈紉紊紋納紐紓純紕紗紘紙級紛紜素紡索紧紫紬紮累細紱紲紳紵紹紺紼紿絀終絃組絅絆絋経絎絏結絕絖絚絛絜絝絞絡絢絣給絨絮絰統絲絳絵絶絷絹絺絽綁綉綏綑經継続綛綜綞綟綠綢綣綦綫綬維綮綯綰綱網綴綵綸綺綻綽綾綿緁緄緇緊緋総緑緒緕緘緙線緜緝緞締緡緣緤編緩緬緯緲練緹緻縁縄縅縈縉縊縋縐縑縒縕縛縝縞縟縡縢縣縦縧縫縭縮縯縱縲縳縴縵縷縹縺縻總績縿繁繃繅繆繇繈繊繋繍繑繒織繕繖繙繚繝繞繡繦繧繩繪繫繭繮繰繳繹繻繼繽繾繿纂纃纈纉續纍纎纏纐纒纓纔纖纘纛纜纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵缶缸缺缽罂罄罅罈罌罍罎罏罐网罒罓罔罕罗罘罚罟罠罡罢罣罧罨罩罪罫置罰罱署罴罵罷罸罹罾羁羂羃羅羆羇羈羊羋羌美羔羗羚羝羞羟羡羣群羥羧羨義羮羯羰羲羶羸羹羼羽羿翁翅翆翊翌翎習翔翕翘翟翠翡翥翦翩翫翬翮翰翱翳翹翺翻翼耀老考耄者耆耋而耍耐耑耒耔耕耖耗耘耙耜耠耡耢耥耦耧耨耩耪耱耳耵耶耷耸耻耽耿聂聃聆聊聋职聍聒联聖聘聚聞聟聡聢聨聩聪聯聰聱聲聳聴聵聶職聹聽聾聿肀肃肄肅肆肇肉肋肌肏肓肖肘肙肚肛肜肝肟肠股肢肤肥肩肪肫肬肭肮肯肱育肴肷肺肼肽肾肿胀胁胂胃胄胆背胍胎胖胗胙胚胛胜胝胞胡胤胥胧胨胩胪胫胬胭胯胰胱胲胳胴胶胸胺胼能胿脂脅脆脇脈脉脊脍脎脏脐脑脒脓脔脖脗脘脚脛脝脞脢脣脤脩脫脬脯脰脱脲脳脶脷脸脹脾腆腈腊腋腌腎腐腑腓腔腕腙腚腟腠腥腦腧腩腫腭腮腰腱腳腴腸腹腺腻腼腽腾腿膀膂膃膈膊膎膏膑膓膕膘膚膛膜膝膠膣膤膥膦膨膩膪膰膳膵膶膸膺膻膽膾膿臀臁臂臃臆臈臉臊臌臍臏臑臓臘臙臚臟臠臢臣臥臧臨自臬臭至致臺臻臼臾舀舁舂舄舅舆與興舉舊舌舍舎舐舒舔舖舗舘舛舜舞舟舡舢舣舦舨舩航舫般舭舮舯舰舱舳舴舵舶舷舸船舺舻舾艀艄艇艉艋艏艘艙艚艝艟艢艤艦艨艪艫艮良艰艱色艳艴艶艷艸艹艺艽艾艿节芃芄芈芊芋芍芎芏芑芒芗芘芙芜芝芟芡芣芤芥芦芧芨芩芪芫芬芭芮芯芰花芳芴芵芷芸芹芻芽芾苁苄苅苇苈苊苋苌苍苎苏苑苒苓苔苕苖苗苘苙苛苜苞苟苠苡苣苤若苦苧苫苯英苳苴苷苹苺苻茁茂范茄茅茆茇茈茉茌茍茎茏茑茔茕茖茗茘茚茛茜茣茧茨茫茬茭茯茱茲茳茴茵茶茸茹茺茼荀荃荅荆荇草荊荎荏荐荑荒荔荖荘荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药荳荵荷荸荺荻荼荽莅莆莇莉莊莎莒莓莕莖莘莚莛莜莞莟莠莢莧莨莩莪莫莰莱莲莳莴莵莶获莸莹莺莼莽莿菀菁菅菇菈菉菊菌菎菏菑菓菔菖菘菜菝菟菠菡菥菩菪菫華菰菱菲菴菷菸菹菻菽萁萃萄萆萇萊萋萌萍萎萏萑萓萘萜萝萠萢萣萤营萦萧萨萩萪萬萱萵萸萼落葆葉葎葑著葙葚葛葜葡葢董葦葩葫葬葭葮葯葱葳葵葶葷葸葹葺蒂蒄蒇蒈蒉蒋蒌蒍蒎蒐蒔蒗蒙蒜蒝蒞蒟蒡蒨蒭蒯蒲蒴蒸蒹蒺蒻蒼蒽蒿蓀蓁蓄蓆蓉蓊蓋蓍蓐蓑蓓蓖蓙蓚蓝蓟蓠蓣蓥蓦蓪蓬蓮蓯蓰蓳蓴蓼蓽蓿蔀蔆蔌蔑蔓蔔蔕蔗蔘蔚蔞蔟蔡蔣蔥蔦蔫蔬蔭蔴蔵蔷蔸蔹蔺蔻蔼蔽蕀蕁蕃蕈蕉蕊蕋蕎蕕蕖蕗蕘蕙蕚蕞蕣蕤蕨蕩蕪蕭蕲蕴蕷蕹蕺蕻蕾薀薄薅薇薈薊薌薏薐薑薔薗薙薛薜薤薦薨薩薪薫薬薮薯薰薴薶薷薹薺薾藁藉藍藏藐藓藕藜藝藤藥藩藪藴藷藹藺藻藾藿蘂蘄蘅蘆蘇蘊蘋蘑蘓蘖蘗蘚蘞蘢蘦蘧蘩蘭蘯蘰蘸蘼蘿虍虎虏虐虑虔處虚虛虜虞號虢虧虫虬虮虯虰虱虳虹虺虻虼虽虾虿蚀蚁蚂蚊蚋蚌蚍蚓蚕蚜蚝蚣蚤蚧蚨蚩蚪蚫蚬蚯蚰蚱蚴蚵蚶蚺蛀蛄蛅蛆蛇蛉蛊蛋蛍蛎蛏蛐蛑蛔蛘蛙蛛蛞蛟蛤蛩蛬蛭蛮蛯蛰蛱蛲蛳蛴蛸蛹蛺蛻蛾蜀蜂蜃蜆蜇蜈蜉蜊蜍蜑蜒蜓蜕蜗蜘蜚蜜蜞蜡蜢蜣蜥蜩蜮蜱蜴蜷蜻蜾蜿蝇蝈蝉蝋蝌蝎蝓蝕蝗蝙蝟蝠蝣蝤蝥蝦蝨蝪蝮蝰蝴蝶蝸蝻蝼蝽蝾蝿螂螃螅螆螈螋融螓螗螞螟螢螣螨螫螬螭螯螳螵螺螻螽蟀蟄蟆蟇蟈蟊蟋蟎蟐蟑蟒蟓蟛蟠蟥蟧蟪蟬蟮蟯蟲蟳蟶蟷蟹蟻蟾蠃蠄蠅蠊蠋蠍蠎蠏蠑蠓蠔蠕蠖蠛蠟蠡蠢蠣蠧蠱蠲蠵蠶蠹蠻蠼血衂衄衅衆衊行衍衎衒術衔衕衖街衙衚衛衝衞衡衢衣衤补表衩衫衬衮衰衲衵衷衹衽衾衿袁袂袄袅袈袋袍袒袓袖袗袙袜袞袢袤袪被袭袮袰袱袴袵袷袼袿裁裂裃裄装裆裇裉裊裎裏裒裔裕裘裙補裝裟裡裢裣裤裥裨裯裰裱裲裳裴裸裹裼製裾褂褄複褊褌褐褒褓褔褕褘褙褚褛褝褞褟褡褥褪褫褰褲褴褵褶褸褻褽襁襃襄襌襍襖襞襟襠襤襦襪襬襭襯襲襴襷襻襾西要覃覅覆覇覈覊見規覓視覗覘覚覜覡覤覦覧覩親覬覯覲観覷覺覽覿觀见观规觅视觇览觉觊觋觌觎觏觐觑角觔觖觚觜觝觞解觥触觧觫觭觯觳觴觸觼言訂訃訇計訊訌討訏訐訑訓訕訖託記訛訝訟訢訣訥訪設許訳訴訶診註証訾詁詆詈詎詐詑詒詔評詖詘詛詞詠詡詢詣試詨詩詫詬詭詮詰話該詳詹詻詼誂誄誅誆誇誉誊誌認誑誒誓誕誘誚語誠誡誣誤誥誦誧誨說説読誰課誶誹誼調諂諄談諉請諌諍諏諒論諗諚諛諜諞諠諡諢諤諦諧諪諫諭諮諱諳諴諶諷諸諺諼諾謀謁謂謄謅謇謊謌謎謐謔謖謗謙謚講謝謠謡謢謦謨謫謬謮謳謹謾譁譆證譊譌譎譏譖識譙譚譛譜譟譠警譪譫譬譭譯議譱譲譴護譽譿讀讃變讌讎讐讒讓讖讙讚讜讞讠计订讣认讥讦讧讨让讪讫讬训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谉谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷谺谿豁豆豇豈豉豊豌豎豐豔豕豚象豢豪豫豬豭豳豸豹豺豼貂貅貉貊貌貍貎貓貔貘貝貞負財貢貧貨販貪貫責貭貮貯貰貲貳貴貶買貸費貼貽貿賀賁賂賃賄賅資賈賊賍賎賏賑賒賓賚賛賜賞賠賡賢賣賤賦質賬賭賴賸賺賻購賽贄贅贇贈贊贋贍贏贐贓贔贖贗贛贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赤赦赧赩赫赭走赱赳赴赵赶起趁趄超越趋趑趔趕趖趙趟趣趨趯趱足趴趵趸趺趼趾趿跂跃跄跆跋跌跎跏跑跖跗跚跛距跞跟跡跣跤跦跨跩跪跫跬路跳践跶跷跸跹跺跻跼跽跿踅踈踉踊踌踎踏踐踔踜踝踞踟踡踢踣踩踪踫踬踭踮踯踰踱踴踵踹踺踼踽蹀蹁蹂蹄蹇蹈蹉蹊蹋蹌蹐蹑蹒蹓蹔蹕蹙蹚蹟蹠蹣蹤蹦蹧蹩蹬蹭蹯蹰蹲蹴蹶蹺蹻蹼蹾蹿躀躁躂躄躅躇躉躊躋躍躏躐躑躓躔躕躙躜躝躞躡躥躪身躬躭躯躰躱躲躺躼躾軀軁軅軆軈車軋軌軍軎軏軒軔軚軛軟転軣軨軫軲軸軻軼軽軾較輄輅載輊輋輌輒輓輔輕輙輛輜輝輞輟輥輦輩輪輭輯輳輶輸輹輻輾輿轀轂轄轅轆轉轌轍轎轔轗轜轟轡轢轣轤车轧轨轩轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辁辂较辄辅辆辇辈辉辊辋辍辎辏辐辑输辔辕辖辗辘辙辚辛辜辞辟辣辦辧辨辩辫辭辮辯辰辱農辵辶辷边辺辻込辽达辿迀迁迂迄迅迆过迈迋迌迎运近迓返迕还这迚进远违连迟迢迤迥迦迨迩迪迫迭迮迯述迳迴迷迸迹迺追退送适逃逄逅逆选逊逋逍逎透逐逑递逓途逕逖逗這通逛逝逞速造逡逢連逦逧逭逮逯週進逵逶逸逹逻逼逾遁遂遄遅遇遉遊運遍過遏遐遑遒道達違遖遗遘遙遛遜遝遞遠遡遢遣遥遨適遭遮遯遲遴遵遶遷選遺遼遽避邀邁邂邃還邇邈邉邊邋邏邐邑邓邕邗邙邛邝邡邢那邦邨邪邬邮邯邰邱邳邴邵邶邸邹邺邻邾郁郃郄郅郇郊郎郏郐郑郓郗郛郜郝郞郡郢郤郦郧部郫郭郯郴郵郷郸都郾鄂鄄鄉鄒鄔鄕鄗鄘鄙鄞鄢鄣鄧鄭鄯鄰鄱鄲鄴鄹鄺酃酆酈酉酊酋酌配酎酏酐酒酔酖酗酘酚酜酝酞酡酢酣酤酥酩酪酬酮酯酰酱酲酳酴酵酶酷酸酹酽酾酿醂醃醅醇醉醋醌醍醐醑醒醖醗醚醛醜醞醢醣醤醪醫醬醭醮醯醱醴醵醸醺釀釁釅釆采釈釉释釋里重野量釐金釓釔釕釖釗釘釙釛釜針釟釡釣釤釦釧釩釭釵釶釷釹釼釿鈀鈁鈇鈈鈉鈊鈍鈎鈐鈑鈔鈕鈜鈞鈣鈥鈦鈧鈩鈪鈬鈮鈰鈴鈷鈸鈹鈺鈽鈾鈿鉀鉄鉅鉆鉈鉉鉋鉍鉐鉑鉕鉗鉚鉛鉝鉞鉢鉤鉦鉨鉬鉭鉱鉲鉳鉴鉸鉺鉻鉼鉾鉿銀銃銅銈銊銎銑銓銕銖銘銚銛銜銠銣銥銦銧銨銩銪銫銬銭銮銲銳銶銷銹銻銼鋁鋂鋃鋅鋆鋇鋈鋉鋌鋏鋐鋒鋕鋤鋦鋨鋩鋪鋭鋯鋰鋱鋲鋳鋸鋺鋼錀錂錄錆錏錐錒錕錘錙錚錛錞錠錡錢錣錤錦錨錩錫錬錮錯録錳錵錶錸錺錻錼錾鍄鍅鍆鍇鍈鍊鍋鍍鍔鍖鍘鍙鍚鍛鍜鍠鍥鍩鍪鍬鍮鍰鍵鍶鍺鍼鍾鎂鎅鎊鎌鎏鎔鎖鎗鎘鎚鎝鎡鎢鎤鎦鎧鎩鎬鎭鎮鎯鎰鎳鎵鎶鎷鎹鏃鏄鏈鏊鏌鏍鏐鏑鏖鏗鏘鏜鏝鏞鏟鏡鏢鏤鏥鏨鏵鏷鏹鏽鐃鐇鐏鐐鐒鐓鐔鐘鐙鐚鐠鐡鐤鐧鐨鐫鐮鐲鐳鐵鐶鐸鐺鐽鐾鐿鑀鑁鑄鑊鑌鑑鑒鑓鑚鑛鑞鑠鑢鑣鑤鑪鑫鑭鑰鑲鑵鑷鑼鑽鑾鑿钁钅钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钜钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铇铈铉铊铋铌铍铎铏铐铑铒铓铔铕铖铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锜锝锞锟锠锡锢锣锤锥锦锧锨锩锪锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镄镅镆镇镈镉镊镋镌镍镎镏镐镑镒镓镔镕镖镗镘镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镵镶長长門閁閂閃閆閇閉閊開閎閏閑閒間閔閖閘閙閠閡関閣閤閥閧閨閩閪閫閬閭閱閲閹閺閻閼閾闃闆闇闈闊闋闌闍闐闔闕闖闘關闡闢闥门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛阜阝队阡阢阨阪阬阮阯阱防阳阴阵阶阻阼阽阿陀陂附际陆陇陈陉陋陌降陏限陔陕陘陛陜陝陞陟陡院陣除陥陦陧陨险陪陬陰陲陳陴陵陶陷陸険陽隄隅隆隈隊隋隍階随隐隔隕隗隘隙際障隠隣隧隨險隰隱隲隳隴隶隷隸隹隻隼隽难雀雁雃雄雅集雇雉雊雋雌雍雎雏雑雒雕雖雙雛雜雞雠離難雨雩雪雫雯雰雲雳零雷雹電雾需霁霂霄霆震霈霉霊霍霎霏霑霓霖霙霜霞霤霦霧霨霪霭霰露霸霹霽霾靂靄靆靈靉靑青靓靖静靚靛靜非靠靡面靤靥靦靨革靫靭靱靳靴靶靹靺靼鞁鞄鞅鞆鞋鞍鞏鞐鞑鞒鞔鞘鞜鞠鞣鞦鞨鞫鞭鞯鞲鞳鞴韁韃韆韈韉韋韌韓韙韜韞韡韦韧韩韪韫韬韭韮韱韲音韵韶韹韻韾響頁頂頃項順頇須頊頌頎頏預頑頒頓頗領頚頜頡頤頫頬頭頰頴頷頸頹頻頼頽顆顋題額顎顏顓顔顕顗願顙顛類顢顥顧顫顯顰顱顳顴页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧風颪颯颱颳颶颺颼飃飄飆飈风飑飒飓飕飘飙飚飛飜飞食飢飧飨飩飪飫飭飮飯飲飴飼飽飾餃餅餉養餌餍餐餑餒餓餔餘餚餛餝餞餠餡餤館餬餮餵餸餽餾餿饂饅饈饉饋饌饐饑饒饔饕饗饜饞饣饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕首馗馘香馥馨馬馭馮馱馳馴馼駁駄駅駆駈駐駑駒駕駘駙駛駝駟駢駭駮駱駲駸駻駿騁騅騎騏騒験騖騙騨騫騮騯騰騵騷騾驀驁驂驃驄驅驊驌驍驕驗驚驛驟驢驣驤驥驩驪驫马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧骨骭骯骰骱骶骷骸骹骺骼骾髀髁髂髄髅髋髌髏髑髒髓體髕髖高髞髟髡髢髣髦髪髫髭髮髯髱髴髷髹髻鬃鬆鬈鬍鬏鬓鬘鬚鬟鬢鬣鬥鬧鬨鬩鬪鬮鬯鬱鬲鬻鬼魁魂魃魄魅魆魇魈魉魍魎魏魑魔魘魚魟魠魨魩魯魴魷魽鮀鮃鮋鮎鮐鮑鮒鮓鮖鮗鮟鮠鮨鮪鮫鮭鮮鮴鮸鮹鯀鯁鯆鯇鯈鯉鯊鯏鯑鯒鯓鯔鯖鯗鯙鯛鯝鯡鯢鯣鯤鯧鯨鯪鯭鯰鯱鯲鯵鯷鯽鰂鰄鰆鰈鰉鰊鰌鰍鰐鰒鰓鰔鰕鰛鰜鰡鰤鰥鰭鰮鰯鰰鰱鰲鰹鰺鰻鰾鱆鱇鱈鱉鱒鱔鱖鱗鱘鱙鱚鱟鱠鱧鱲鱶鱷鱸鱺鱼鱽鱾鱿鲀鲁鲂鲃鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳚鳛鳜鳝鳞鳟鳠鳡鳢鳣鳤鳥鳧鳩鳫鳬鳰鳳鳴鳶鴃鴆鴇鴈鴉鴎鴒鴕鴛鴝鴞鴟鴣鴦鴨鴪鴫鴬鴷鴻鴽鴾鴿鵁鵄鵆鵈鵐鵑鵙鵜鵝鵞鵟鵠鵡鵤鵪鵬鵯鵰鵲鵺鶆鶇鶉鶏鶖鶘鶚鶤鶩鶫鶯鶲鶴鶸鶺鶻鶼鶿鷁鷂鷄鷆鷏鷓鷗鷙鷥鷦鷭鷯鷲鷴鷸鷹鷺鷽鷿鸕鸚鸛鸝鸞鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹙鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹮鹯鹰鹱鹲鹳鹵鹸鹹鹼鹽鹾鹿麁麂麇麈麋麌麐麑麒麓麕麖麗麝麟麥麦麧麨麩麪麫麬麭麮麯麰麱麲麳麴麵麶麷麸麹麺麻麼麽麾麿黀黁黂黃黄黅黆黇黈黉黊黋黌黍黎黏黐黑黒黓黔黕黖黗默黙黚黛黜黝點黟黠黡黢黣黤黥黦黧黨黩黪黫黬黭黮黯黰黱黲黳黴黵黶黷黸黹黺黻黼黽黾黿鼀鼁鼂鼃鼄鼅鼆鼇鼈鼉鼊鼋鼌鼍鼎鼏鼐鼑鼒鼓鼔鼕鼖鼗鼘鼙鼚鼛鼜鼝鼞鼟鼠鼡鼢鼣鼤鼥鼦鼧鼨鼩鼪鼫鼬鼭鼮鼯鼰鼱鼲鼳鼴鼵鼶鼷鼸鼹鼺鼻鼼鼽鼾鼿齀齁齂齃齄齅齆齇齈齉齊齋齌齍齎齏齐齑齒齓齔齕齖齗齘齙齚齛齜齝齞齟齠齡齢齣齤齥齦齧齨齩齪齫齬齭齮齯齰齱齲齳齴齵齶齷齸齹齺齻齼齽齾齿龀龁龂龃龄龅龆龇龈龉龊龋龌龍龎龏龐龑龒龓龔龕龖龗龘龙龚龛龜龝龞龟龠龡龢龣龤龥鿏鿔鿫鿬鿭꒳ꞋꞌꞍꞪfi︐︑︒︙︰︱︳︴︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄﹉﹊﹋﹌﹍﹎﹏﹐﹑﹒﹔﹕﹖﹗﹙﹚﹛﹜﹝﹞﹟﹠﹡﹢﹣﹤﹥﹦﹨﹩﹪﹫!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚¢£¬ ̄¦¥→🚢𠮟冒 \ No newline at end of file diff --git a/examples/assets/quan.png b/examples/assets/quan.png new file mode 100644 index 0000000..af1dda6 Binary files /dev/null and b/examples/assets/quan.png differ diff --git a/examples/assets/quan.png.dat b/examples/assets/quan.png.dat new file mode 100644 index 0000000..b41d2bf --- /dev/null +++ b/examples/assets/quan.png.dat @@ -0,0 +1 @@ + !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±´µ¶·¸º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩīĮįİıIJijĴĵĶķĹĺĻļĽľŁłŃńŅņŇňŊŋŌōŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžƁƆƇƈƉƊƎƏƐƑƒƓƔƖƗƘƙƝƤƥƩƪƬƭƮƱƲƳƴƷǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǢǣǦǧǾǿȘșȚțȨȩȪȫȲȳȷɂɃɄɅɋɌɑɓɔɖɗəɛɠɣɦɨɩɲɴɷɽɾʀʃʅʈʉʊʋʌʏʒʔʕʖʘʚʟʼʽʾʿ˂˃ˆˇˉˊˋˍ˘˙˚˛˜˝˪˫΄ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώЁЄІЇАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяёєіїҐґԾಠಥกฅง฿ᇂᐛᴀᴄᴏᴑᴗᴛᴜᴢᴥᵍᵎᵏᵐᵒᵕḄḅḌḍḎḏḒḓḠḡḤḥḪḫḮḯḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉṊṋṌṍṐṑṒṓṜṝṞṟṢṣṬṭṮṯṰṱẀẁẂẃẄẅẎẏẒẓẔẕẖẗẞạẬậẸẹẼẽỆệỊịỌọỏỘộỤụỲỳỸỹ῀ ‐‑‒–—―‖‗‘’‚‛“”„‟†‡•‣․‥…‧‰‱′″‴‵‶‷‸‹›※‼‽‾‿⁃⁄⁅⁆⁇⁈⁉⁋⁗⁰⁽⁾₀₃₍₎₡₤₩₪€₴₹₽⃝℃℅℉№℡™ÅⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿↁↂ←↑→↓↔↕↖↗↘↙⇎⇒⇔∀∂∃∆∇∈∋∏∑−∙√∝∞∟∠∣∥∧∨∩∪∫∬∮∴∵∷∼∽≈≒≖≝≠≡≤≥≦≧≪≫≼≽⊂⊃⊆⊇⊕⊖⊙⊜⊥⊹⊿⋚⋛⌒⎛⎝⎞⎠⎩⎭①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵Ⓘⓔⓛⓞⓥ⓪⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴─│┌┐└┘├┤┬┴┼═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕■□▢▣▤▥▦▧▨▩▪▫▬▰▲△▶▷►▻▼▽◀◁◄◆◇◈◉◊○◌◍◎●◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☜☞☭☮☯☰☱☲☳☴☵☶☷☹☺☻☼☽☾♀♁♂♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚠⛄⛔✂✆✈✉✓✕✖✗✚✡✦✧✨✪✽✿❀❂❄❓❖❗❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓⧸⧹ⱤⱭⱲⱳ⺁⺄⺈⺋⺌⺗⺧⺪⺮⺳⺶⺷⺻⻊⻌⻍⻎⾡ 、。〃〄々〆〇〈〉《》「」『』【】〒〓〔〕〖〗〜〝〞〟〠〡〢〣〤〥〦〧〨〩ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖ゙゚゛゜ゝゞ゠ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩㄪㄫㄬㄭㄮㄯㄱㄲㄳㄴㄵㄶㄷㄸㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅃㅄㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣㆀㆆㆠㆡㆢㆣㆤㆥㆦㆧㆨㆩㆪㆫㆬㆭㆮㆯㆰㆱㆲㆳㆴㆵㆶㆷㆸㆹㆺㆻㆼㆽㆾㆿ㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩㈱㈲㈹㉨㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㊤㊥㊦㊧㊨㋿㌃㌍㌔㌘㌢㌣㌦㌧㌫㌶㌻㍉㍊㍍㍑㍗㍻㍼㍽㍾㎎㎏㎜㎝㎞㎡㏄㏍㏎㏒㏕㐁㑑㓤㓾㕷㖡㖭㖿㗎㗒㗳㗾㜷㤘㧒㧡㧸㧾㨘㩒㩧㩮㬹㷧㷫㸃㹴䀴䀹䁅䁥䁪䂻䃟䆀䌈䏝䓪䗁䘆䘼䟴䤭䥑䨒䪴䫌䯋䱽䲁䲅䲳䴈一丁丂七丄丅丆万丈三上下丌不与丏丐丑丒专且丕世丗丘丙业丛东丝丞丟丠両丢丣两严並丧丨丩个丫丬中丮丯丰丱串丳临丵丶丷丸丹为主丼丽举丿乀乁乂乃乄久乆乇么义乊之乌乍乎乏乐乑乒乓乔乕乖乗乘乙乚乛乜九乞也习乡乢乣乤乥书乧乨乩乪乫乬乭乮乯买乱乲乳乴乵乶乷乸乹乺乻乼乽乾乿亀亁亂亃亄亅了亇予争亊事二亍于亏亐云互亓五井亖亗亘亙亚些亜亝亞亟亠亡亢亣交亥亦产亨亩亪享京亭亮亯亰亱亲亳亴亵亶亷亸亹人亻亼亽亾亿什仁仂仃仄仅仆仇仈仉今介仌仍从仏仐仑仒仓仔仕他仗付仙仚仛仜仝仞仟仠仡仢代令以仦仧仨仩仪仫们仭仮仯仰仱仲仳仴仵件价仸仹仺任仼份仾仿伀企伂伃伄伅伆伇伈伉伊伋伌伍伎伏伐休伒伓伔伕伖众优伙会伛伜伝伞伟传伡伢伣伤伥伦伧伨伩伪伫伬伭伮伯估伱伲伳伴伵伶伷伸伹伺伻似伽伾伿佀佁佂佃佄佅但佇佈佉佊佋佌位低住佐佑佒体佔何佖佗佘余佚佛作佝佞佟你佡佢佣佤佥佦佧佨佩佪佫佬佭佮佯佰佱佲佳佴併佶佷佸佹佺佻佼佽佾使侀侁侂侃侄侅來侇侈侉侊例侌侍侎侏侐侑侒侓侔侕侖侗侘侙侚供侜依侞侟侠価侢侣侤侥侦侧侨侩侪侫侬侭侮侯侰侱侲侳侴侵侶侷侸侹侺侻侼侽侾便俀俁係促俄俅俆俇俈俉俊俋俌俍俎俏俐俑俒俓俔俕俖俗俘俙俚俛俜保俞俟俠信俢俣俤俥俦俧俨俩俪俫俬俭修俯俰俱俲俳俴俵俶俷俸俹俺俻俼俽俾俿倀倁倂倃倄倅倆倇倈倉倊個倌倍倎倏倐們倒倓倔倕倖倗倘候倚倛倜倝倞借倡倢倣値倥倦倨倩倪倫倬倭倮倶倹债值倾偃假偈偉偌偎偏偐偕偖做停偣健偬偭偯偲側偵偶偷偸偺偻偽偾偿傀傅傈傌傍傑傕傖傘備傚傜傢傣傥傧储傩催傭傯傲傳傴債傷傸傺傻傾僂僅僇僉僊働僎像僑僕僖僚僞僣僥僦僧僨僩僫僬僭僮僱僳僵價僻儀儁儂億儅儆儇儈儉儋儐儒儔儕儖儘儚償儡優儲儳儷儸儺儻儼儿兀允兂元兄充兆兇先光兊克兌免兎兏児兑兒兓兔兕兖兗兙党兛兜兝兞兡兢兣入兦內全兩兪八公六兮兯兰共兲关兴兵其具典兹养兼兽冀冁冂冃冄内円冇冈冉冊冋册再冎冏冐冑冒冓冔冕冖冗冘写冚军农冝冞冠冢冤冥冦冧冨冩冪冫冬冭冮冯冰冱冲决冴况冶冷冻冼冽冾净凃凄凅准凇凈凉凋凌凍凎减凑凖凛凜凝几凡凢凤凥処凧凩凪凫凭凮凯凰凱凳凴凵凶凷凸凹出击凼函凾凿刀刁刂刃刄刅分切刈刉刊刋刌刍刎刑划刔刕刖列刘则刚创初删刣判別刧刨利刪别刭刮到刳制刷券刹刺刻刽刿剀剁剂剃剄則剉削剋剌前剎剏剐剑剔剖剛剜剝剞剡剣剤剥剧剩剪副剰剱割剳剴創剷剽剾剿劁劂劃劄劇劈劉劊劍劏劐劑劒劓劔劖力劜劝办功加务劢劣劦动助努劫劬劭励劲劳労劵効劻劼劾势勀勁勃勅勇勉勋勍勐勒動勖勗勘務勛勝勞募勠勢勣勤勥勦勧勰勲勳勵勷勸勹勺勻勼勽勾勿匀匁匂匃包匆匈匊匋匍匏匐匕化北匘匙匚匛匜匝匞匟匠匡匣匦匪匭匮匯匱匳匸匹区医匾匿區十卂千卄卅卆升午卉半卋卌卍华协卐卑卒卓協单卖南単博卜卝卞卟占卡卢卣卤卥卦卧卨卩卪卫卬卭卮卯印危即却卵卷卸卹卺卻卽卿厂厃厄厅历厉压厌厍厎厕厖厘厙厚厝原厠厢厣厥厦厨厩厭厮厰厲厳厴厶厷去县叁参參又叉及友双反収发叔取受变叙叚叛叟叠叡叢口古句另叨叩只叫召叭叮可台叱史右叵叶号司叹叺叻叼叽叾吁吃各吆吇合吉吊吋同名后吏吐向吒吓吔吕吖吗君吝吞吟吠吡吣吥否吧吨吩吪含听吭吮启吱吲吳吴吵吶吸吹吻吼吽吾吿呀呂呃呆呈呉告呋呎呐呑呒呓呔呕呖呗员呙呛呜呟呢呣呤呦周呪呯呰呱呲味呵呶呷呸呻呼命咀咁咂咄咆咇咈咊咋和咎咏咐咑咒咓咔咕咖咗咙咚咛咝咡咢咣咤咥咦咧咨咩咪咫咬咭咯咱咲咳咴咸咹咻咼咽咾咿哀品哂哄哆哇哈哉哊哋哌响哎哏哐哑哒哓哔哕哖哗哘哙哚哜哝哞哟員哢哥哦哧哨哩哪哭哮哲哳哺哼哽哿唁唄唆唇唉唏唐唑唓唔唖唚唛唞唠唢唣唤唥唧唪唬唭售唯唰唱唳唵唷唸唹唼唾唿啀啁啃啄啅商啉啊啋啌啍問啐啓啕啖啗啜啝啞啟啡啣啤啥啦啧啩啪啫啬啭啮啰啱啲啵啶啷啸啹啻啼啾喀喁喂喃善喆喇喈喉喊喋喎喏喑喔喘喙喚喜喝喞喟喧喨喩喪喫喬單喰喱喲喳喵営喷喹喺喻喼喽喾嗄嗅嗆嗇嗉嗌嗍嗎嗐嗑嗒嗓嗔嗖嗗嗚嗜嗝嗟嗡嗣嗤嗥嗦嗧嗨嗩嗪嗫嗬嗯嗰嗱嗲嗳嗵嗶嗷嗹嗽嗾嘀嘁嘂嘅嘆嘈嘉嘌嘍嘎嘏嘐嘓嘔嘖嘗嘘嘚嘛嘜嘞嘟嘢嘣嘤嘥嘧嘩嘬嘭嘮嘯嘰嘱嘲嘴嘶嘸嘹嘻嘿噀噁噂噃噉噌噍噎噏噐噒噓噔噗噘噙噚噛噜噝噠噢噤噥器噩噪噫噬噯噱噴噶噸噹噺噻噼嚀嚄嚅嚆嚇嚉嚊嚎嚏嚐嚓嚔嚕嚙嚟嚠嚡嚢嚣嚤嚥嚦嚨嚭嚮嚯嚱嚴嚶嚷嚹嚼嚿囀囁囂囃囈囉囊囌囍囎囑囒囓囔囖囗囘囙囚四囜囝回囟因囡团団囤囥囦囧囨囩囪囫囬园囮囯困囱囲図围囵囶囷囸囹固囻囼国图囿圀圁圂圃圄圅圆圇圈圉圊國圌圍圎圏圐圑園圓圔圕圖圗團圙圚圛圜圝圞土圠圡圢圣圤圦圧在圩圪圬圭圮圯地圳圷圸圹场圻圾址坂均坊坌坍坎坏坐坑坔块坚坛坜坝坞坟坠坡坤坦坨坩坪坫坭坯坳坵坶坷坻坼坿垂垃垄垅垆垈垉型垌垒垓垚垛垠垡垢垣垤垦垧垩垪垫垭垮垰垱垲垳垴垵垸垺垻埀埂埃埆埋城埏埒埓埔埕埖埗埘埙埚埜埝埞域埠埡埣埤埧埪埭埯埲埴執埸培基埼埽堀堂堃堅堆堇堉堊堋堍堑堕堙堝堞堠堡堤堪堭堯堰報場堵堺堽塀塁塄塊塋塌塍塑塒塔塗塘塙塚塞塡塢塤塥塩填塬塭塯塰塱塲塳塵塹塽塾墀墁境墅墉墊墒墓増墘墙墚墜增墟墣墦墨墩墫墬墮墳墶墸墹墺墻墼墾壁壂壅壆壇壊壌壎壑壓壕壗壘壙壚壜壞壟壠壢壤壥壩士壬壮壯声壱売壳壶壷壹壺壻壼壽夂处夆备変夊夌复夏夐夓夔夕外夘夙多夛夜够夠夢夤夥大夨天太夫夬夭央夯夰失夲夳头夷夸夹夺夼夾奀奁奂奄奇奈奉奋奌奎奏奐契奔奕奖套奘奚奠奢奥奧奨奩奪奬奭奮女奴奶奸她奼好妁如妃妄妆妇妈妊妍妏妒妓妖妗妘妙妛妝妞妣妤妥妨妩妪妫妬妮妯妲妳妹妻妾姅姆姉姊始姍姐姑姒姓委姗姘姙姚姜姝姣姥姦姨姪姫姬姮姵姶姹姻姿威娃娄娅娆娇娈娉娌娑娓娘娚娛娜娟娠娣娥娩娯娱娲娳娴娵娶娼婀婁婆婉婊婕婚婢婦婧婪婬婭婴婵婶婷婺婿媄媒媗媚媛媜媞媠媧媪媬媱媲媳媵媸媺媼媽媾嫁嫂嫈嫉嫋嫌嫐嫒嫔嫖嫗嫘嫚嫜嫠嫡嫣嫦嫩嫫嫱嫲嫵嫺嫻嬃嬅嬈嬉嬋嬌嬖嬗嬛嬝嬡嬢嬤嬪嬬嬰嬲嬴嬶嬷嬸嬾嬿孀孃孅孋孌孍子孑孒孓孔孕孖字存孙孚孛孜孝孞孟孢季孤孥学孩孪孫孬孭孰孱孳孵學孺孻孽孿宀宁宂它宄宅宇守安宋完宍宏宐宓宕宗官宙定宛宜宝实実宠审客宣室宥宦宪宫宮宰害宴宵家宸容宽宾宿寂寃寄寅密寇寉富寍寐寒寓寔寛寝寞察寡寢寤寥實寧寨審寫寬寮寰寳寵寶寸对寺寻导対寿封専射尅将將專尉尊尋對導小尐少尒尓尔尕尖尗尘尙尚尜尝尠尢尣尤尥尧尨尪尬尭就尴尶尷尸尹尺尻尼尽尾尿局屁层屄居屆屇屈屉届屋屌屍屎屏屐屑屓展屘屙屛屜屝属屠屡屢屣層履屦屨屬屭屮屯屰山屳屴屵屶屹屺屾屿岁岂岈岌岍岐岑岔岖岗岘岙岚岛岜岠岡岢岣岨岩岫岬岭岱岳岵岶岷岸岻岼岽岾岿峀峁峄峅峇峋峒峙峠峡峣峤峥峦峨峩峪峭峯峰峴島峺峻峽崁崂崃崆崇崋崌崎崑崔崕崖崗崘崙崚崛崞崟崠崢崤崦崧崩崭崮崴崽崾嵇嵊嵋嵌嵎嵐嵒嵖嵘嵙嵛嵜嵝嵩嵫嵬嵯嵳嵴嵶嶂嶄嶇嶋嶌嶐嶔嶙嶝嶠嶢嶬嶮嶷嶸嶺嶼嶽巅巉巌巍巒巓巔巖巛川州巟巠巡巢巣巤工左巧巨巩巫差巯己已巳巴巵巷巸巻巽巾巿帀币市布帅帆师帋希帏帐帑帔帕帖帘帙帚帛帜帝帟帥带帧師席帮帯帰帱帳帶帷常帻帼帽幀幂幃幄幅幇幌幎幔幕幗幛幞幟幡幢幣幤幪幫干平年幵并幷幸幹幺幻幼幽幾广庀庁庂広庄庆庇床庋序庐庑库应底庖店庙庚府庞废庠庥度座庫庭庳庴庵庶康庸庹庾廁廂廃廄廈廉廊廍廏廐廑廒廓廔廖廚廛廝廟廠廡廢廣廨廩廪廬廰廱廳廴延廷廸建廻廼廾廿开弁异弃弄弇弈弉弊弋弌弍弎式弐弑弒弓弔引弖弗弘弛弜弟张弥弦弧弩弪弭弯弱張強弸弹强弼弾彀彁彆彈彊彌彎彐彑归当录彖彗彘彙彜彝彞彡形彣彤彥彦彧彩彪彫彬彭彰影彳彷役彻彼彿往征徂徃径待徇很徉徊律後徐徑徒従徕得徘徙徜從徠御徨復循徫徬徭微徳徴徵德徹徼徽心忄必忆忉忌忍忏忐忑忒忓忖志忘忙応忝忟忠忡忤忧忪快忭忮忰忱念忸忻忼忽忾忿怀态怂怃怄怅怆怊怍怎怏怐怒怔怕怖怙怛怜思怠怡急怦性怨怩怪怫怯怱怵怺总怼怿恁恂恃恆恊恋恍恐恒恓恕恙恚恝恟恠恢恣恤恥恧恨恩恪恫恬恭息恰恳恵恶恷恸恹恺恻恼恽恿悁悃悄悅悉悋悌悍悒悔悖悗悚悛悝悟悠患悦悧您悩悪悫悬悭悯悱悲悳悴悵悶悸悻悼悽情惆惇惊惋惑惓惕惘惚惜惝惟惠惡惣惦惧惨惩惫惬惭惮惯惰惱想惴惶惷惹惺惻愀愁愃愆愈愉愍愎意愒愓愔愕愚愛愜感愠愡愣愤愦愧愨愫愬愴愷愼愽愾愿慂慄慇慈慊態慌慍慎慑慓慕慘慙慚慝慟慢慣慤慥慧慨慪慫慮慯慰慱慳慴慵慶慷慼慾憂憇憊憋憎憐憑憔憖憙憚憝憤憧憨憩憫憬憮憲憶憷憺憾懂懃懆懇懈應懊懋懌懍懐懑懒懔懞懟懣懦懨懲懴懵懶懷懸懺懼懽懾懿戀戆戇戈戉戊戋戌戍戎戏成我戒戓戔戕或戗战戙戚戛戝戞戟戡戢戤戥戦戩截戬戮戯戰戲戳戴戶户戸戻戽戾房所扁扃扇扈扉手扌才扎扑扒打扔払托扙扚扛扞扠扣扥扦执扨扩扪扫扬扭扮扯扰扱扳扶批扺扼找承技抂抃抄抆抉把抌抑抒抓抔投抖抗折抚抛抜択抟抠抡抢护报抦抨披抬抱抵抹抺抻押抽抿拂拃拄担拆拇拈拉拊拋拌拍拎拏拐拑拒拓拔拖拗拘拙拚招拜拝拟拠拡拢拣拤拥拦拧拨择括拭拮拯拱拳拴拵拶拷拼拽拾拿持挂指挈按挌挎挑挖挙挚挛挝挞挟挠挡挢挣挤挥挦挧挨挪挫振挲挵挹挺挽挾挿捂捃捅捆捉捋捌捍捎捏捐捕捗捜捞损捡换捣捧捨捩捫捭据捯捱捲捶捷捺捻捽掀掂掃掄掇授掉掊掌掎掏掐排掖掘掙掛掟掠採探掣接控推掩措掫掬掭掮掰掲掳掴掵掷掸掹掺掻掼掾揀揃揄揆揈揉揍揎描提插揖揚換揞揠握揣揤揦揩揪揬揭揮揲援揶揸揹揺揻揼揽揾揿搀搁搂搅搆搇搋搌損搏搐搓搔搖搗搙搛搜搝搞搠搡搣搥搦搧搨搪搬搭搲搴搵搶携搽搾搿摀摁摂摃摄摅摆摇摈摊摎摑摒摔摘摙摜摞摟摧摩摭摯摰摱摳摵摶摷摸摹摺摻撂撃撄撅撇撈撍撐撑撒撓撕撖撘撙撚撞撟撢撣撤撥撩撫撬播撮撰撲撳撴撵撷撸撹撺撻撼撾撿擀擁擂擄擅擇擊擋操擎擐擒擔擗擘據擝擞擠擡擢擣擤擦擧擬擭擯擰擱擲擴擶擷擸擺擻擼擽擾攀攅攆攉攏攑攒攔攖攘攙攜攝攞攢攣攤攥攪攫攬攮支攰攴攵收攷攸改攺攻放政故效敉敌敍敎敏救敔敕敖敗敘教敛敝敞敢散敦敫敬数敲整敵敷數斂斃文斈斉斋斌斎斐斑斓斕斗料斛斜斟斡斤斥斧斩斫斬断斯新斲斷方於施旁旂旃旄旅旆旋旌旎族旒旖旗旙旛无旡既日旦旧旨早旬旭旮旯旰旱时旷旸旺旻旼昀昂昃昆昇昉昊昌明昏易昔昕昙昜昝星映昤春昧昨昫昭是昱昴昵昶昼显昿晁時晃晄晅晉晋晌晏晒晓晔晕晖晗晚晝晞晟晡晢晤晦晧晨晩普景晰晴晶晷智晾暁暂暃暄暇暈暉暌暍暎暐暑暖暗暘暝暢暦暧暨暪暫暮暱暴暸暹暼暾曁曄曆曇曉曖曙曚曛曜曝曠曣曦曩曬曯曰曱曲曳更曵曷書曹曺曼曽曾替最會月有朊朋服朏朐朑朔朕朖朗望朝朞期朥朦朧木朩未末本札朮术朰朱朳朴朵朶朷朸机朽朿杀杁杂权杆杈杉杋杌李杏材村杓杕杖杗杙杜杞束杠条杢杣杤来杧杨杩杪杭杯杰東杲杳杵杷杺杻杼松板极构枅枇枉枋枌枏析枒枓枕林枘枚果枝枞枠枡枢枣枥枦枧枨枩枪枫枭枯枰枱枳枴枵架枷枸枹柁柃柄柆柈柊柎柏某柑柒染柔柘柙柚柜柝柞柠柢柤查柧柩柬柮柯柰柱柳柴柵柺査柽柾柿栀栂栃栄栅标栈栉栊栋栌栎栏树栓栖栗栘栝栞栟校栢栩株栫栲栳栴样核根格栽栾桀桁桂桃桄桅框案桉桊桌桍桎桐桑桓桔桕桙桜桝桟桠桡桢档桤桥桦桧桨桩桫桴桶桷桹桾桿梁梂梃梅梆梇梍梏梓梔梗梘梛條梟梠梡梢梦梧梨梭梯械梱梲梳梵梶梹梺梼检棁棂棄棆棈棉棊棋棍棒棔棕棖棗棘棚棟棠棡棣棧棨棪森棯棰棱棲棵棹棺棻棼椀椁椄椅椈椋椌植椎椏椐椒椙椚椛検椟椠椡椢椣椤椥椦椨椪椭椰椴椶椹椽椿楂楊楓楔楕楗楙楚楛楜楝楞楠楡楢楣楦楨楪楫楬業楮楯楱楳楴極楷楸楹楼楽楾榀榁概榄榆榇榈榉榊榍榎榑榔榕榖榘榛榜榠榣榦榧榨榫榭榮榱榲榴榷榻榾榿槁槃槇槊構槌槍槎槐槓槔様槙槛槝槞槟槠槤槧槨槪槫槭槲槳槹槺槻槽槿樁樂樅樊樋樌樑樒樓樔樗樘標樛樞樟模樢樣樨権横樫樮樯樱樵樶樸樹樺樽樾橄橇橈橋橐橘橙橛機橡橢橥橦橫橱橲橸橹橼橾橿檀檄檍檎檐檑檔檗檜檠檢檣檨檩檪檫檬檮檯檳檸檻櫁櫂櫃櫆櫈櫑櫓櫚櫛櫝櫞櫟櫥櫧櫨櫪櫫櫬櫳櫸櫺櫻欄欅欉權欐欒欖欗欝欞欟欠次欢欣欤欧欲欷欸欹欺欽款歃歆歇歉歌歎歐歓歔歙歛歜歟歡止正此步武歧歩歪歯歲歳歴歷歸歹歺死歼歿殀殁殂殃殄殆殇殉殊残殍殒殓殕殖殘殚殛殞殡殤殪殫殭殮殯殱殲殳殴段殷殺殻殼殿毀毁毂毅毆毋毌母毎每毐毑毒毓比毕毖毗毘毙毚毛毟毡毪毫毬毯毳毵毹毽氅氆氇氈氊氍氏氐民氓气氕氖気氘氙氚氛氜氝氞氟氠氡氢氣氤氥氦氧氨氩氪氫氬氭氮氯氰氱氲氳水氵氶氷永氹氺氽氾氿汀汁求汆汇汉汊汍汎汐汔汕汗汙汚汛汜汝汞江池污汢汤汨汩汪汫汰汲汳汴汶汹決汽汾沁沂沃沄沅沆沈沉沌沍沏沐沒沓沔沖沘沙沚沛沟没沢沣沤沥沦沧沨沩沪沫沬沭沮沱沲河沸油沺治沼沽沾沿況泂泄泅泉泊泌泐泓泔法泖泗泙泛泜泝泞泠泡波泣泥注泪泫泮泯泰泱泳泵泶泷泸泺泻泼泽泾洁洄洇洋洌洎洐洒洗洙洚洛洞洟津洧洨洩洪洫洮洱洲洳洵洶洸洹洺活洼洽派流浃浄浅浆浇浈浊测浍济浏浑浒浓浔浕浙浚浜浞浠浣浤浥浦浩浪浬浮浯浴海浸浹浼涂涅涇消涉涊涌涎涑涓涔涕涘涙涛涜涝涞涟涠涡涣涤润涧涨涩涪涫涮涯液涵涷涸涼涿淀淄淅淆淇淋淌淍淑淒淕淖淘淙淚淝淞淠淡淤淥淦淨淩淪淫淬淮淯深淳淵混淸淹淺添淼清渇済渉渊渋渌渍渎渐渑渓渔渕渖渗渙渚減渝渟渠渡渣渤渥渦温渫測渭渮港渲渴游渺渼渾湃湄湊湍湎湓湔湖湘湛湟湡湣湧湩湫湮湯湲湳湶湾湿満溂溃溅溆溉溌溏源準溘溜溝溟溢溥溧溪溫溯溱溲溴溶溷溺溻溼溽滁滂滄滅滇滉滋滌滎滏滑滓滔滕滗滘滙滚滝滞滟滠满滢滤滥滦滨滩滬滯滲滴滷滸滹滾滿漁漂漆漉漏漑漓演漕漚漠漢漣漤漥漧漩漪漫漬漭漯漱漲漳漶漸漾漿潁潅潆潇潋潍潑潔潘潛潜潞潟潠潢潤潦潭潮潯潰潲潴潸潺潼潾澀澁澂澄澆澇澈澉澌澍澎澐澑澔澗澜澠澡澣澤澦澧澪澱澳澴澶澹激濁濂濃濆濉濑濒濔濕濘濛濞濟濠濡濤濨濩濫濬濮濯濰濱濳濶濺濾瀁瀂瀅瀆瀉瀋瀏瀑瀕瀘瀚瀛瀝瀞瀟瀡瀣瀦瀧瀨瀬瀰瀲瀵瀹瀾灃灌灏灑灔灕灘灝灞灠灣灤灥灧灩火灬灭灯灰灵灶灸灼災灾灿炀炅炆炉炊炎炒炔炕炖炘炙炜炝炤炫炬炭炮炯炱炳炷炸点為炻炼炽烀烁烂烃烇烈烊烋烏烔烘烙烚烛烜烝烟烤烦烧烨烩烫烬热烯烱烴烷烹烽焄焉焊焌焐焓焔焕焖焗焘焙焚焜焠無焢焦焯焰焱然焼焿煀煃煅煆煇煉煊煌煎煏煐煑煒煕煖煙煚煜煞煢煤煥煦照煨煩煬煮煲煳煸煺煽熄熈熊熏熒熔熕熗熘熙熟熠熨熬熱熳熵熹熾燁燃燄燈燉燊燎燐燒燔燕燗燙燜營燠燥燦燧燬燭燮燴燵燶燸燹燻燼燾燿爆爌爍爐爛爝爨爪爫爬爭爰爱爲爵父爷爸爹爺爻爼爽爾爿牀牁牂牆片版牋牌牍牒牖牘牙牛牝牟牠牡牢牤牦牧物牮牯牲牴牵特牺牽牾牿犀犁犂犄犇犊犋犍犏犒犖犛犟犠犡犢犧犬犭犮犯犰犲犴状犷犸犹狀狁狂狃狄狆狈狍狎狐狒狗狙狛狞狠狡狢狨狩独狭狮狯狰狱狲狳狴狷狸狹狺狻狼狽猁猃猊猎猓猕猖猗猙猛猜猝猞猟猡猢猥猩猪猫猬献猯猱猴猶猷猸猹猻猾猿獁獃獄獅獇獍獎獏獐獒獗獠獢獣獨獪獬獭獯獰獲獴獵獷獸獺獻獼獾玀玄玆率玉玊王玎玑玒玕玖玘玙玛玟玠玡玢玥玦玨玩玫玭玮环现玲玳玷玺玻玽珀珂珅珈珉珊珍珎珏珐珑珙珝珞珠珡珣珥珧珩珪班珮珰珱珲珸珺珽現球琄琅理琇琉琊琍琏琐琚琛琡琢琤琥琦琨琪琫琬琭琮琯琰琲琳琴琵琶琺琼琿瑀瑁瑄瑋瑕瑗瑙瑚瑛瑜瑞瑟瑠瑢瑣瑤瑩瑪瑭瑯瑰瑱瑲瑳瑶瑷瑾璀璁璃璇璉璊璋璎璐璘璜璞璟璠璢璣璦璧璨璩璪環璱璸璺璽璿瓈瓊瓏瓒瓔瓖瓘瓚瓜瓞瓠瓢瓣瓤瓦瓧瓩瓮瓯瓰瓱瓲瓴瓶瓷瓸瓿甃甄甅甌甍甎甏甑甓甕甘甙甚甜甞生甡產産甥甦用甩甫甬甭甯田由甲申甴电男甸町画甼甽甾畀畄畅畆畇畈畉畊畋界畍畎畏畑畔留畚畛畜畝畠畢畤略畦畧畩番畫畬畭異畲畳畴當畷畸畹畿疂疃疆疇疉疊疋疎疏疑疒疔疖疗疙疚疝疟疠疡疢疣疤疥疪疫疬疮疯疰疱疲疳疴疵疸疹疼疽疾痀痂痃痄病症痈痉痊痍痒痔痕痖痘痙痛痞痠痢痣痤痦痧痨痩痪痫痰痱痲痳痴痹痺痼痾痿瘀瘁瘃瘅瘉瘊瘋瘌瘍瘐瘓瘕瘖瘗瘘瘙瘛瘜瘞瘟瘠瘡瘢瘤瘥瘦瘧瘩瘪瘫瘭瘮瘰瘳瘴瘵瘸瘺瘻瘼瘾瘿癀療癃癆癇癈癌癍癎癒癔癖癘癜癞癟癡癢癣癤癥癦癧癨癩癪癫癬癮癯癰癱癲癶癸発登發白百皀皂皃的皆皇皈皋皎皐皑皓皖皙皚皛皞皤皮皰皱皲皴皷皸皹皺皿盂盃盅盆盈益盍盎盏盐监盒盔盖盗盘盛盜盞盟盡監盤盥盧盪盬目盯盱盲直盷相盹盻盼盾省眄眇眈眉眊看県眍眙眚眛眞真眠眢眤眥眦眨眩眬眭眯眵眶眷眸眺眼眾着睁睃睆睇睏睐睑睚睛睜睞睡睢督睥睦睨睩睪睫睬睹睽睾睿瞀瞄瞅瞇瞋瞌瞍瞎瞑瞒瞓瞞瞟瞠瞢瞥瞧瞩瞪瞬瞭瞰瞳瞵瞶瞹瞻瞼瞽瞿矇矋矍矓矗矚矛矜矢矣知矧矩矫矬短矮矯石矶矸矻矼矽矾矿砀码砂砈砉砌砍砑砒研砕砖砗砘砚砜砝砟砠砣砥砦砧砩砬砭砰砱砲破砵砷砸砹砺砻砼砾砿础硃硅硇硌硎硐硒硓硕硖硗硝硤硦硪硫硬硭确硯硲硴硷硼硿碁碆碇碉碌碍碎碑碓碕碖碗碘碚碛碜碟碡碣碥碧碩碪碯碰碱碲碳碴碵碹確碼碾磁磅磆磉磊磋磐磑磔磕磘磙磚磜磡磧磨磬磯磲磴磷磺磻磽礁礅礇礎礐礑礒礓礙礞礡礤礦礪礫礬礱礴示礻礼礽社祀祁祂祅祆祇祈祉祎祐祓祕祖祗祚祛祜祝神祟祠祢祥祧票祭祯祷祸祺祼祿禀禁禄禅禊禍禎福禔禕禚禛禝禡禤禦禧禪禮禰禱禳禹禺离禽禾禿秀私秃秆秈秉秋种科秒秕秘秝租秡秣秤秦秧秩秫秬秭积称秸移秽秾稀稂稃稅稆稈稉程稍税稔稗稘稙稚稜稞稟稠稣種稱稲稳稷稹稻稼稽稾稿穀穂穃穆穇穉穋穌積穎穏穐穑穗穠穡穢穣穨穩穫穰穴究穷穸穹空穽穿窀突窃窄窆窈窍窑窒窓窕窖窗窘窜窝窟窠窣窥窦窨窩窪窬窭窮窯窰窳窶窸窺窿竃竄竅竇竈竊立竍竏竑竒竓竕竖站竚竜竝竞竟章竡竢竣童竦竪竭端竰競竸竹竺竽竿笂笃笄笆笈笊笋笏笑笔笕笘笙笛笞笠笤笥符笨笪笫第笭笮笱笳笵笶笸笹笺笼笾筅筆筇筈等筊筋筌筍筏筐筑筒答策筘筚筛筝筠筢筥筦筧筬筮筯筰筱筲筴筵筷筹筺筻签简箄箅箆箇箋箍箎箏箐箒箔箕算箘箙箚箜箝箟箠管箢箦箧箨箩箪箫箬箭箱箴箸節篁範篆篇築篋篌篏篑篓篙篚篛篝篠篡篤篥篦篩篪篭篮篱篳篶篷篼篾簀簇簋簌簍簏簑簒簓簔簖簗簞簟簡簣簦簧簪簫簰簷簸簽簾簿籀籁籃籌籍籏籐籓籔籖籗籘籙籜籟籠籣籤籥籬籮籲米籴籵籸类籼籽籾粁粂粃粄粉粋粍粐粑粒粕粗粘粛粜粝粞粟粡粢粤粥粧粨粪粫粭粮粱粲粳粵粹粺粼粽精粿糀糁糂糅糇糈糉糊糌糍糎糒糕糖糗糘糙糜糝糞糟糠糢糧糨糬糭糯糰糲糴糶糸糺系糾紀紂約紅紆紇紈紉紊紋納紐紓純紕紗紘紙級紛紜素紡索紧紫紬紮累細紱紲紳紵紹紺紼紿絀終絃組絅絆絋経絎絏結絕絖絚絛絜絝絞絡絢絣給絨絮絰統絲絳絵絶絷絹絺絽綁綉綏綑經継続綛綜綞綟綠綢綣綦綫綬維綮綯綰綱網綴綵綸綺綻綽綾綿緁緄緇緊緋総緑緒緕緘緙線緜緝緞締緡緣緤編緩緬緯緲練緹緻縁縄縅縈縉縊縋縐縑縒縕縛縝縞縟縡縢縣縦縧縫縭縮縯縱縲縳縴縵縷縹縺縻總績縿繁繃繅繆繇繈繊繋繍繑繒織繕繖繙繚繝繞繡繦繧繩繪繫繭繮繰繳繹繻繼繽繾繿纂纃纈纉續纍纎纏纐纒纓纔纖纘纛纜纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵缶缸缺缽罂罄罅罈罌罍罎罏罐网罒罓罔罕罗罘罚罟罠罡罢罣罧罨罩罪罫置罰罱署罴罵罷罸罹罾羁羂羃羅羆羇羈羊羋羌美羔羗羚羝羞羟羡羣群羥羧羨義羮羯羰羲羶羸羹羼羽羿翁翅翆翊翌翎習翔翕翘翟翠翡翥翦翩翫翬翮翰翱翳翹翺翻翼耀老考耄者耆耋而耍耐耑耒耔耕耖耗耘耙耜耠耡耢耥耦耧耨耩耪耱耳耵耶耷耸耻耽耿聂聃聆聊聋职聍聒联聖聘聚聞聟聡聢聨聩聪聯聰聱聲聳聴聵聶職聹聽聾聿肀肃肄肅肆肇肉肋肌肏肓肖肘肙肚肛肜肝肟肠股肢肤肥肩肪肫肬肭肮肯肱育肴肷肺肼肽肾肿胀胁胂胃胄胆背胍胎胖胗胙胚胛胜胝胞胡胤胥胧胨胩胪胫胬胭胯胰胱胲胳胴胶胸胺胼能胿脂脅脆脇脈脉脊脍脎脏脐脑脒脓脔脖脗脘脚脛脝脞脢脣脤脩脫脬脯脰脱脲脳脶脷脸脹脾腆腈腊腋腌腎腐腑腓腔腕腙腚腟腠腥腦腧腩腫腭腮腰腱腳腴腸腹腺腻腼腽腾腿膀膂膃膈膊膎膏膑膓膕膘膚膛膜膝膠膣膤膥膦膨膩膪膰膳膵膶膸膺膻膽膾膿臀臁臂臃臆臈臉臊臌臍臏臑臓臘臙臚臟臠臢臣臥臧臨自臬臭至致臺臻臼臾舀舁舂舄舅舆與興舉舊舌舍舎舐舒舔舖舗舘舛舜舞舟舡舢舣舦舨舩航舫般舭舮舯舰舱舳舴舵舶舷舸船舺舻舾艀艄艇艉艋艏艘艙艚艝艟艢艤艦艨艪艫艮良艰艱色艳艴艶艷艸艹艺艽艾艿节芃芄芈芊芋芍芎芏芑芒芗芘芙芜芝芟芡芣芤芥芦芧芨芩芪芫芬芭芮芯芰花芳芴芵芷芸芹芻芽芾苁苄苅苇苈苊苋苌苍苎苏苑苒苓苔苕苖苗苘苙苛苜苞苟苠苡苣苤若苦苧苫苯英苳苴苷苹苺苻茁茂范茄茅茆茇茈茉茌茍茎茏茑茔茕茖茗茘茚茛茜茣茧茨茫茬茭茯茱茲茳茴茵茶茸茹茺茼荀荃荅荆荇草荊荎荏荐荑荒荔荖荘荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药荳荵荷荸荺荻荼荽莅莆莇莉莊莎莒莓莕莖莘莚莛莜莞莟莠莢莧莨莩莪莫莰莱莲莳莴莵莶获莸莹莺莼莽莿菀菁菅菇菈菉菊菌菎菏菑菓菔菖菘菜菝菟菠菡菥菩菪菫華菰菱菲菴菷菸菹菻菽萁萃萄萆萇萊萋萌萍萎萏萑萓萘萜萝萠萢萣萤营萦萧萨萩萪萬萱萵萸萼落葆葉葎葑著葙葚葛葜葡葢董葦葩葫葬葭葮葯葱葳葵葶葷葸葹葺蒂蒄蒇蒈蒉蒋蒌蒍蒎蒐蒔蒗蒙蒜蒝蒞蒟蒡蒨蒭蒯蒲蒴蒸蒹蒺蒻蒼蒽蒿蓀蓁蓄蓆蓉蓊蓋蓍蓐蓑蓓蓖蓙蓚蓝蓟蓠蓣蓥蓦蓪蓬蓮蓯蓰蓳蓴蓼蓽蓿蔀蔆蔌蔑蔓蔔蔕蔗蔘蔚蔞蔟蔡蔣蔥蔦蔫蔬蔭蔴蔵蔷蔸蔹蔺蔻蔼蔽蕀蕁蕃蕈蕉蕊蕋蕎蕕蕖蕗蕘蕙蕚蕞蕣蕤蕨蕩蕪蕭蕲蕴蕷蕹蕺蕻蕾薀薄薅薇薈薊薌薏薐薑薔薗薙薛薜薤薦薨薩薪薫薬薮薯薰薴薶薷薹薺薾藁藉藍藏藐藓藕藜藝藤藥藩藪藴藷藹藺藻藾藿蘂蘄蘅蘆蘇蘊蘋蘑蘓蘖蘗蘚蘞蘢蘦蘧蘩蘭蘯蘰蘸蘼蘿虍虎虏虐虑虔處虚虛虜虞號虢虧虫虬虮虯虰虱虳虹虺虻虼虽虾虿蚀蚁蚂蚊蚋蚌蚍蚓蚕蚜蚝蚣蚤蚧蚨蚩蚪蚫蚬蚯蚰蚱蚴蚵蚶蚺蛀蛄蛅蛆蛇蛉蛊蛋蛍蛎蛏蛐蛑蛔蛘蛙蛛蛞蛟蛤蛩蛬蛭蛮蛯蛰蛱蛲蛳蛴蛸蛹蛺蛻蛾蜀蜂蜃蜆蜇蜈蜉蜊蜍蜑蜒蜓蜕蜗蜘蜚蜜蜞蜡蜢蜣蜥蜩蜮蜱蜴蜷蜻蜾蜿蝇蝈蝉蝋蝌蝎蝓蝕蝗蝙蝟蝠蝣蝤蝥蝦蝨蝪蝮蝰蝴蝶蝸蝻蝼蝽蝾蝿螂螃螅螆螈螋融螓螗螞螟螢螣螨螫螬螭螯螳螵螺螻螽蟀蟄蟆蟇蟈蟊蟋蟎蟐蟑蟒蟓蟛蟠蟥蟧蟪蟬蟮蟯蟲蟳蟶蟷蟹蟻蟾蠃蠄蠅蠊蠋蠍蠎蠏蠑蠓蠔蠕蠖蠛蠟蠡蠢蠣蠧蠱蠲蠵蠶蠹蠻蠼血衂衄衅衆衊行衍衎衒術衔衕衖街衙衚衛衝衞衡衢衣衤补表衩衫衬衮衰衲衵衷衹衽衾衿袁袂袄袅袈袋袍袒袓袖袗袙袜袞袢袤袪被袭袮袰袱袴袵袷袼袿裁裂裃裄装裆裇裉裊裎裏裒裔裕裘裙補裝裟裡裢裣裤裥裨裯裰裱裲裳裴裸裹裼製裾褂褄複褊褌褐褒褓褔褕褘褙褚褛褝褞褟褡褥褪褫褰褲褴褵褶褸褻褽襁襃襄襌襍襖襞襟襠襤襦襪襬襭襯襲襴襷襻襾西要覃覅覆覇覈覊見規覓視覗覘覚覜覡覤覦覧覩親覬覯覲観覷覺覽覿觀见观规觅视觇览觉觊觋觌觎觏觐觑角觔觖觚觜觝觞解觥触觧觫觭觯觳觴觸觼言訂訃訇計訊訌討訏訐訑訓訕訖託記訛訝訟訢訣訥訪設許訳訴訶診註証訾詁詆詈詎詐詑詒詔評詖詘詛詞詠詡詢詣試詨詩詫詬詭詮詰話該詳詹詻詼誂誄誅誆誇誉誊誌認誑誒誓誕誘誚語誠誡誣誤誥誦誧誨說説読誰課誶誹誼調諂諄談諉請諌諍諏諒論諗諚諛諜諞諠諡諢諤諦諧諪諫諭諮諱諳諴諶諷諸諺諼諾謀謁謂謄謅謇謊謌謎謐謔謖謗謙謚講謝謠謡謢謦謨謫謬謮謳謹謾譁譆證譊譌譎譏譖識譙譚譛譜譟譠警譪譫譬譭譯議譱譲譴護譽譿讀讃變讌讎讐讒讓讖讙讚讜讞讠计订讣认讥讦讧讨让讪讫讬训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谉谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷谺谿豁豆豇豈豉豊豌豎豐豔豕豚象豢豪豫豬豭豳豸豹豺豼貂貅貉貊貌貍貎貓貔貘貝貞負財貢貧貨販貪貫責貭貮貯貰貲貳貴貶買貸費貼貽貿賀賁賂賃賄賅資賈賊賍賎賏賑賒賓賚賛賜賞賠賡賢賣賤賦質賬賭賴賸賺賻購賽贄贅贇贈贊贋贍贏贐贓贔贖贗贛贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赤赦赧赩赫赭走赱赳赴赵赶起趁趄超越趋趑趔趕趖趙趟趣趨趯趱足趴趵趸趺趼趾趿跂跃跄跆跋跌跎跏跑跖跗跚跛距跞跟跡跣跤跦跨跩跪跫跬路跳践跶跷跸跹跺跻跼跽跿踅踈踉踊踌踎踏踐踔踜踝踞踟踡踢踣踩踪踫踬踭踮踯踰踱踴踵踹踺踼踽蹀蹁蹂蹄蹇蹈蹉蹊蹋蹌蹐蹑蹒蹓蹔蹕蹙蹚蹟蹠蹣蹤蹦蹧蹩蹬蹭蹯蹰蹲蹴蹶蹺蹻蹼蹾蹿躀躁躂躄躅躇躉躊躋躍躏躐躑躓躔躕躙躜躝躞躡躥躪身躬躭躯躰躱躲躺躼躾軀軁軅軆軈車軋軌軍軎軏軒軔軚軛軟転軣軨軫軲軸軻軼軽軾較輄輅載輊輋輌輒輓輔輕輙輛輜輝輞輟輥輦輩輪輭輯輳輶輸輹輻輾輿轀轂轄轅轆轉轌轍轎轔轗轜轟轡轢轣轤车轧轨轩轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辁辂较辄辅辆辇辈辉辊辋辍辎辏辐辑输辔辕辖辗辘辙辚辛辜辞辟辣辦辧辨辩辫辭辮辯辰辱農辵辶辷边辺辻込辽达辿迀迁迂迄迅迆过迈迋迌迎运近迓返迕还这迚进远违连迟迢迤迥迦迨迩迪迫迭迮迯述迳迴迷迸迹迺追退送适逃逄逅逆选逊逋逍逎透逐逑递逓途逕逖逗這通逛逝逞速造逡逢連逦逧逭逮逯週進逵逶逸逹逻逼逾遁遂遄遅遇遉遊運遍過遏遐遑遒道達違遖遗遘遙遛遜遝遞遠遡遢遣遥遨適遭遮遯遲遴遵遶遷選遺遼遽避邀邁邂邃還邇邈邉邊邋邏邐邑邓邕邗邙邛邝邡邢那邦邨邪邬邮邯邰邱邳邴邵邶邸邹邺邻邾郁郃郄郅郇郊郎郏郐郑郓郗郛郜郝郞郡郢郤郦郧部郫郭郯郴郵郷郸都郾鄂鄄鄉鄒鄔鄕鄗鄘鄙鄞鄢鄣鄧鄭鄯鄰鄱鄲鄴鄹鄺酃酆酈酉酊酋酌配酎酏酐酒酔酖酗酘酚酜酝酞酡酢酣酤酥酩酪酬酮酯酰酱酲酳酴酵酶酷酸酹酽酾酿醂醃醅醇醉醋醌醍醐醑醒醖醗醚醛醜醞醢醣醤醪醫醬醭醮醯醱醴醵醸醺釀釁釅釆采釈釉释釋里重野量釐金釓釔釕釖釗釘釙釛釜針釟釡釣釤釦釧釩釭釵釶釷釹釼釿鈀鈁鈇鈈鈉鈊鈍鈎鈐鈑鈔鈕鈜鈞鈣鈥鈦鈧鈩鈪鈬鈮鈰鈴鈷鈸鈹鈺鈽鈾鈿鉀鉄鉅鉆鉈鉉鉋鉍鉐鉑鉕鉗鉚鉛鉝鉞鉢鉤鉦鉨鉬鉭鉱鉲鉳鉴鉸鉺鉻鉼鉾鉿銀銃銅銈銊銎銑銓銕銖銘銚銛銜銠銣銥銦銧銨銩銪銫銬銭銮銲銳銶銷銹銻銼鋁鋂鋃鋅鋆鋇鋈鋉鋌鋏鋐鋒鋕鋤鋦鋨鋩鋪鋭鋯鋰鋱鋲鋳鋸鋺鋼錀錂錄錆錏錐錒錕錘錙錚錛錞錠錡錢錣錤錦錨錩錫錬錮錯録錳錵錶錸錺錻錼錾鍄鍅鍆鍇鍈鍊鍋鍍鍔鍖鍘鍙鍚鍛鍜鍠鍥鍩鍪鍬鍮鍰鍵鍶鍺鍼鍾鎂鎅鎊鎌鎏鎔鎖鎗鎘鎚鎝鎡鎢鎤鎦鎧鎩鎬鎭鎮鎯鎰鎳鎵鎶鎷鎹鏃鏄鏈鏊鏌鏍鏐鏑鏖鏗鏘鏜鏝鏞鏟鏡鏢鏤鏥鏨鏵鏷鏹鏽鐃鐇鐏鐐鐒鐓鐔鐘鐙鐚鐠鐡鐤鐧鐨鐫鐮鐲鐳鐵鐶鐸鐺鐽鐾鐿鑀鑁鑄鑊鑌鑑鑒鑓鑚鑛鑞鑠鑢鑣鑤鑪鑫鑭鑰鑲鑵鑷鑼鑽鑾鑿钁钅钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钜钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铇铈铉铊铋铌铍铎铏铐铑铒铓铔铕铖铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锜锝锞锟锠锡锢锣锤锥锦锧锨锩锪锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镄镅镆镇镈镉镊镋镌镍镎镏镐镑镒镓镔镕镖镗镘镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镵镶長长門閁閂閃閆閇閉閊開閎閏閑閒間閔閖閘閙閠閡関閣閤閥閧閨閩閪閫閬閭閱閲閹閺閻閼閾闃闆闇闈闊闋闌闍闐闔闕闖闘關闡闢闥门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛阜阝队阡阢阨阪阬阮阯阱防阳阴阵阶阻阼阽阿陀陂附际陆陇陈陉陋陌降陏限陔陕陘陛陜陝陞陟陡院陣除陥陦陧陨险陪陬陰陲陳陴陵陶陷陸険陽隄隅隆隈隊隋隍階随隐隔隕隗隘隙際障隠隣隧隨險隰隱隲隳隴隶隷隸隹隻隼隽难雀雁雃雄雅集雇雉雊雋雌雍雎雏雑雒雕雖雙雛雜雞雠離難雨雩雪雫雯雰雲雳零雷雹電雾需霁霂霄霆震霈霉霊霍霎霏霑霓霖霙霜霞霤霦霧霨霪霭霰露霸霹霽霾靂靄靆靈靉靑青靓靖静靚靛靜非靠靡面靤靥靦靨革靫靭靱靳靴靶靹靺靼鞁鞄鞅鞆鞋鞍鞏鞐鞑鞒鞔鞘鞜鞠鞣鞦鞨鞫鞭鞯鞲鞳鞴韁韃韆韈韉韋韌韓韙韜韞韡韦韧韩韪韫韬韭韮韱韲音韵韶韹韻韾響頁頂頃項順頇須頊頌頎頏預頑頒頓頗領頚頜頡頤頫頬頭頰頴頷頸頹頻頼頽顆顋題額顎顏顓顔顕顗願顙顛類顢顥顧顫顯顰顱顳顴页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧風颪颯颱颳颶颺颼飃飄飆飈风飑飒飓飕飘飙飚飛飜飞食飢飧飨飩飪飫飭飮飯飲飴飼飽飾餃餅餉養餌餍餐餑餒餓餔餘餚餛餝餞餠餡餤館餬餮餵餸餽餾餿饂饅饈饉饋饌饐饑饒饔饕饗饜饞饣饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕首馗馘香馥馨馬馭馮馱馳馴馼駁駄駅駆駈駐駑駒駕駘駙駛駝駟駢駭駮駱駲駸駻駿騁騅騎騏騒験騖騙騨騫騮騯騰騵騷騾驀驁驂驃驄驅驊驌驍驕驗驚驛驟驢驣驤驥驩驪驫马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧骨骭骯骰骱骶骷骸骹骺骼骾髀髁髂髄髅髋髌髏髑髒髓體髕髖高髞髟髡髢髣髦髪髫髭髮髯髱髴髷髹髻鬃鬆鬈鬍鬏鬓鬘鬚鬟鬢鬣鬥鬧鬨鬩鬪鬮鬯鬱鬲鬻鬼魁魂魃魄魅魆魇魈魉魍魎魏魑魔魘魚魟魠魨魩魯魴魷魽鮀鮃鮋鮎鮐鮑鮒鮓鮖鮗鮟鮠鮨鮪鮫鮭鮮鮴鮸鮹鯀鯁鯆鯇鯈鯉鯊鯏鯑鯒鯓鯔鯖鯗鯙鯛鯝鯡鯢鯣鯤鯧鯨鯪鯭鯰鯱鯲鯵鯷鯽鰂鰄鰆鰈鰉鰊鰌鰍鰐鰒鰓鰔鰕鰛鰜鰡鰤鰥鰭鰮鰯鰰鰱鰲鰹鰺鰻鰾鱆鱇鱈鱉鱒鱔鱖鱗鱘鱙鱚鱟鱠鱧鱲鱶鱷鱸鱺鱼鱽鱾鱿鲀鲁鲂鲃鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳚鳛鳜鳝鳞鳟鳠鳡鳢鳣鳤鳥鳧鳩鳫鳬鳰鳳鳴鳶鴃鴆鴇鴈鴉鴎鴒鴕鴛鴝鴞鴟鴣鴦鴨鴪鴫鴬鴷鴻鴽鴾鴿鵁鵄鵆鵈鵐鵑鵙鵜鵝鵞鵟鵠鵡鵤鵪鵬鵯鵰鵲鵺鶆鶇鶉鶏鶖鶘鶚鶤鶩鶫鶯鶲鶴鶸鶺鶻鶼鶿鷁鷂鷄鷆鷏鷓鷗鷙鷥鷦鷭鷯鷲鷴鷸鷹鷺鷽鷿鸕鸚鸛鸝鸞鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹙鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹮鹯鹰鹱鹲鹳鹵鹸鹹鹼鹽鹾鹿麁麂麇麈麋麌麐麑麒麓麕麖麗麝麟麥麦麧麨麩麪麫麬麭麮麯麰麱麲麳麴麵麶麷麸麹麺麻麼麽麾麿黀黁黂黃黄黅黆黇黈黉黊黋黌黍黎黏黐黑黒黓黔黕黖黗默黙黚黛黜黝點黟黠黡黢黣黤黥黦黧黨黩黪黫黬黭黮黯黰黱黲黳黴黵黶黷黸黹黺黻黼黽黾黿鼀鼁鼂鼃鼄鼅鼆鼇鼈鼉鼊鼋鼌鼍鼎鼏鼐鼑鼒鼓鼔鼕鼖鼗鼘鼙鼚鼛鼜鼝鼞鼟鼠鼡鼢鼣鼤鼥鼦鼧鼨鼩鼪鼫鼬鼭鼮鼯鼰鼱鼲鼳鼴鼵鼶鼷鼸鼹鼺鼻鼼鼽鼾鼿齀齁齂齃齄齅齆齇齈齉齊齋齌齍齎齏齐齑齒齓齔齕齖齗齘齙齚齛齜齝齞齟齠齡齢齣齤齥齦齧齨齩齪齫齬齭齮齯齰齱齲齳齴齵齶齷齸齹齺齻齼齽齾齿龀龁龂龃龄龅龆龇龈龉龊龋龌龍龎龏龐龑龒龓龔龕龖龗龘龙龚龛龜龝龞龟龠龡龢龣龤龥鿏鿔鿫鿬鿭꒳ꞋꞌꞍꞪ가각갂갃간갇갈갉갊갋갌감갑값갓갔강갖갗같갚갛개객갠갢갣갤갬갭갯갰갱갲갵갶갸갹갼갿걀걁걇걈걉걋걌걍걔걘걜걤걥거걱걳건걵걷걸걹걺검겁겂것겄겅겆겇겉겊겋게겍겐겓겔겜겝겟겠겡겥겧겨격겪견겯결겱겴겷겸겹겻겼경겾겿곁곂계곅곈곋곌곔곕곗곘곙고곡곤곧골곩곪곫곬곮곯곰곱곳공곶곷곹곺곻과곽관괃괄괆괌괍괏괐광괒괘괙괜괟괠괢괨괩괫괬괭괴괵괸괻괼괾굄굅굇굈굉교굑굔굗굘굠굡굣굥구국군굳굴굵굶굸굻굼굽굿궁궂궃궆궈궉권궏궐궘궙궛궜궝궤궥궨궫궬궴궵궷궸궹귀귁귄귇귈귊귐귑귓귔귕규귝균귤귨귬귭귯귱그극근귾귿글긁긂긃긄긇금급긋긍긎긏긑긒긓긔긕긘긜긠긤긥긧긩기긱긴긷길긹긺긼김깁깃깄깅깆깇깉깊깋까깍깎깐깓깔깖깜깝깟깠깡깢깣깥깨깩깪깬깯깰깳깶깸깹깻깼깽꺁꺄꺅꺆꺈꺋꺌꺍꺗꺙꺠꺤꺵꺼꺽꺾껀껂껃껄껌껍껏껐껑껒껓껕께껙껚껜껟껠껨껩껫껬껭껱껴껵껸껻껼꼄꼅꼇꼈꼉꼍꼐꼗꼥꼬꼭꼰꼱꼲꼳꼴꼶꼸꼻꼼꼽꼿꽁꽂꽃꽅꽇꽈꽉꽌꽏꽐꽘꽙꽛꽜꽝꽤꽥꽨꽫꽬꽴꽵꽸꽹꾀꾁꾄꾇꾈꾐꾑꾓꾔꾕꾜꾠꾣꾤꾬꾭꾲꾸꾹꾼꾿꿀꿁꿇꿈꿉꿋꿍꿎꿏꿔꿕꿘꿛꿜꿤꿥꿧꿨꿩꿰꿱꿴꿷꿸뀀뀁뀃뀄뀅뀌뀍뀐뀓뀔뀜뀝뀟뀡뀨뀬뀰뀸뀹뀼끄끅끈끊끋끌끍끎끓끔끕끗끙끛끝끟끠끡끤끧끨끫끳끵끼끽낀낃낄낋낌낍낏낐낑낕나낙낚낛난낟날낡낢낤남납낪낫났낭낮낯낰낱낲낳내낵낸낻낼냄냅냇냈냉냎냐냑냔냗냘냠냡냣냥냦냩냬넁너넉넊넋넌넏널넑넒넓넗넘넙넛넜넝넞넠넡넢넣네넥넨넫넬넴넵넷넸넹넼넽넾넿녀녁녃년녇녈녋념녑녓녔녕녘녙녚녛녜녝녠녣녤녬녭녯녱노녹녺녻논녾녿놀놁놂놈놉놋농놎놐놑높놓놔놕놘놛놜놤놥놧놨놩놰놴놸뇄뇌뇍뇐뇓뇔뇜뇝뇟뇠뇡뇦뇨뇩뇬뇯뇰뇸뇹뇻뇽누눅눈눋눌눍눐눓눔눕눗눙눛눝눞눠눡눤눧눨눰눱눳눴눵눼눽뉀뉃뉄뉌뉍뉏뉐뉑뉘뉙뉜뉟뉠뉨뉩뉫뉭뉯뉴뉵뉸뉻뉼늄늅늇늉늊늋느늑는늗늘늙늚늜늠늡늣능늦늧늪늫늬늭늰늳늴늼늽늿닀닁니닉닌닏닐닑닒닓닔님닙닛닝닞닠닢닣다닥닦단닫달닭닮닯닰닲닳담답닶닷닸당닺닻닼닽닾닿대댁댄댇댈댐댑댓댔댕댖댙댜댝댠댤댧댬댭댯댱댸댼덍더덕덖던덙덛덜덞덟덤덥덦덧덨덩덪덫덭덮덯데덱덴덷델뎀뎁뎃뎄뎅뎆뎊뎌뎍뎏뎐뎓뎔뎘뎜뎝뎟뎠뎡뎨뎩뎬뎰뎸뎹뎻뎽도독돆돇돈돋돌돎돏돐돓돔돕돗동돚돛돜돝돞돟돠돡돤돨돰돱돳돴돵돼됀됃됄됌됍됏됐되됙된됟될됤됨됩됫됬됭됴됵됸됻됼둄둅둇둉둏두둑둔둗둘둙둚둛둠둡둣둥둪둬둭둰둳둴둼둽둿뒀뒁뒈뒉뒌뒏뒐뒘뒙뒛뒜뒝뒤뒥뒨뒫뒬뒴뒵뒷뒸뒹듀듁듄듈듐듑듓듕드득든듣들듥듦듧듨듬듭듯등듸듹듼듿딀딈딉딋딍딑디딕딘딛딜딤딥딧딨딩딪딫딭딮딯따딱딲딴딷딸딹딺딻딿땀땁땃땄땅땋때땍땎땐땓땔땜땝땟땠땡땧땨땩땬땰땽떄떈떔떙떠떡떤떧떨떪떫떯떰떱떳떴떵떻떼떽뗀뗃뗄뗌뗍뗏뗐뗑뗘뗙뗜뗟뗨뗩뗫뗬뗭뗴뗸똅똉또똑똒똔똗똘똙똚똟똠똡똣똥똬똭똰똴뙁뙇뙈뙉뙌뙏뙐뙘뙙뙛뙜뙤뙥뙨뙫뙬뙴뙵뙷뙸뙹뚀뚁뚜뚝뚠뚣뚤뚦뚧뚫뚬뚭뚯뚱뚵뚸뚼뚿뛋뛌뛔뛘뛛뛜뛤뛥뛨뛩뛰뛴뛷뛸뜀뜁뜃뜄뜅뜌뜍뜔뜜뜡뜨뜩뜬뜯뜰뜲뜳뜷뜸뜹뜻뜽뜾띃띄띅띈띌띔띕띙띠띡띤띧띨띰띱띳띵띻라락란랃랄랈람랍랏랐랑랒랓랔랕랖랗래랙랜랟랠램랩랫랬랭랰랱랲랴략랸랻랼럄럅럇량럐럔럣러럭런럲럳럴럼럽럾럿렀렁렂렄렆렇레렉렌렏렐렘렙렛렜렝렡렢렣려력련렫렬렰렴렵렷렸령렼렾례롁롄롇롈롐롑롓롕로록론롣롤롨롫롬롭롯롱롴롶롷롸롹롼뢀뢈뢉뢋뢌뢍뢔뢘뢛뢜뢧뢨뢰뢱뢴뢵뢷뢸룀룁룃룄룅료룍룐룓룔룜룝룟룡루룩룬룯룰룳룸룹룻룽뤀뤂뤄뤅뤈뤋뤌뤔뤕뤗뤘뤙뤠뤡뤤뤨뤰뤱뤳뤴뤵뤼뤽륀륃륄륌륍륏륐륑류륙륜륟률륨륩륫륭르륵른륻를륽릀름릅릇릉릊릋릍릎릏릐릑릔릘릞릠릡릣릥리릭린릳릴림립릾릿맀링맄맆마막맊만많맏말맑맒맔맘맙맛맜망맞맟맠맡맢맣매맥맧맨맫맬맭맴맵맷맸맹맺맻맽맾먀먁먄먈먐먑먓먕먘먜머먹먻먼먿멀멁멂멈멉멋멌멍멎멏멓메멕멘멛멜멠멤멥멧멨멩멪멫멭며멱면멷멸멺몀몁몃몄명몇몉몌몍몐몓몔몜몝몟몡몣몥몦모목몫몬몯몰몱몲몴몸몹못몽몿뫃뫄뫅뫈뫋뫌뫔뫕뫗뫘뫙뫠뫤뫨뫱뫴뫼뫽묀묃묄묌묍묏묑묘묙묜묟묠묨묩묫묭무묵묶문묺묻물묽묾뭀뭄뭅뭇뭉뭋뭍뭏뭐뭑뭔뭗뭘뭠뭡뭣뭤뭥뭬뭭뭰뭴뭼뭽뭿뮀뮁뮈뮉뮊뮌뮐뮘뮙뮛뮜뮝뮤뮥뮨뮫뮬뮴뮵뮷뮹므믁믃믄믇믈믉믌믏믐믑믓믕믙믜믝믠믤믬믭믯믱믲미믹민믿밀밁밂밄밈밉밋밌밍밎및밐밑바박밖밗반받발밝밞밟밠밣밤밥밧밨방밫밬밭밯배백밲밴밷밸뱀뱁뱃뱄뱅뱆뱉뱌뱍뱐뱔뱜뱝뱟뱡뱧뱨뱰뱷뱽버벅벆번벋벌벍벎벐범법벗벘벙벚벜벝벟베벡벢벤벧벨벰벱벳벴벵벸벹벼벽변볃별볈볌볍볏볐병볒볓볔볕볘볙볜볠볨볩볫볭보복볶볷본볻볼볽볾볿봄봅봇봉봊봋봍봏봐봑봔봗봘봠봡봣봤봥봬봰봳봴뵀뵈뵉뵊뵌뵏뵐뵘뵙뵛뵜뵝뵤뵥뵨뵬뵴뵵뵷뵹부북붂분붇불붉붊붋붎붐붑붓붔붕붖붗붘붙붚붛붜붝붠붣붤붬붭붯붰붱붴붸붹붼붿뷀뷁뷈뷉뷋뷌뷍뷔뷕뷘뷛뷜뷤뷥뷧뷩뷰뷱뷲뷴뷷뷸븀븁븃븅브븍븐븓블븕븗븘븛븜븝븟븡븣븥븧븨븩븬븰븸븹븻븽비빅빈빋빌빎빔빕빗빘빙빚빛빜빝빟빠빡빢빤빧빨빩빪빰빱빳빴빵빶빹빻빼빽빾뺀뺃뺄뺌뺍뺏뺐뺑뺘뺙뺜뺨뺴뺸뻐뻑뻔뻗뻘뻙뻠뻡뻣뻤뻥뻦뻬뻭뻰뻳뻴뻼뻽뻿뼁뼈뼉뼌뼏뼐뼘뼙뼛뼜뼝뼟뼡뼤뼷뼸뼹뽀뽁뽄뽇뽈뽐뽑뽓뽕뽙뽛뽜뽠뽣뽸뽿뾔뾤뾥뾬뾰뾱뿀뿁뿅뿌뿍뿐뿓뿔뿕뿜뿝뿟뿡뿥뿨뿯쀄쀠쀡쀼쁃쁄쁑쁘쁙쁜쁟쁠쁨쁩쁫쁭쁴삐삑삔삗삘삠삡삣삤삥삦삧삫사삭삮삯산삳살삵삶삷삸삺삻삼삽삿샀상샂샃샄샅샆샇새색샊샋샌샏샐샘샙샛샜생샣샤샥샨샫샬샴샵샷샸샹샻샾샿섀섁섄섈섐섕서석섞섟선섣설섥섦섧섨섪섬섭섯섰성섴섶세섹센섿셀셈셉셋셌셍셎셑셒셔셕셗션셛셜셟셠셤셥셧셨셩셰셱셳셴셸솀솁솃솄솅소속솎손솓솔솕솖솗솘솜솝솟송솣솥솦솨솩솬솰솸솹솻솼솽쇄쇅쇈쇋쇌쇔쇕쇗쇘쇙쇠쇡쇤쇧쇨쇰쇱쇳쇴쇵쇼쇽숀숃숄숌숍숏숑숖수숙순숟술숡숤숧숨숩숫숭숮숯숱숲숳숴숵숸숻숼쉄쉅쉇쉈쉉쉐쉑쉔쉗쉘쉠쉡쉣쉤쉥쉬쉭쉰쉳쉴쉼쉽쉿슁슆슈슉슌슏슐슘슙슛슝스슥슨슫슬슭슮슯슰슲슳슴습슷승슺슻슾싀싁싄싈싐싑싓싕시식싞신싢싣실싥싦싨싫심십싯싰싱싳싴싶싸싹싻싼싿쌀쌁쌂쌈쌉쌋쌌쌍쌎쌑쌓쌔쌕쌘쌛쌜쌤쌥쌧쌨쌩쌯쌰쌱쌴쌷쌸썀썁썃썅썌썐썔썜썡써썩썪썬썯썰썲썸썹썻썼썽쎂쎄쎅쎈쎋쎌쎔쎕쎗쎘쎙쎝쎠쎡쎤쎧쎨쎰쎱쎳쎴쎵쎼쎽쏀쏌쏍쏏쏐쏑쏘쏙쏚쏜쏟쏠쏢쏨쏩쏫쏭쏱쏴쏵쏸쏻쏼쐄쐅쐇쐈쐉쐋쐐쐑쐔쐗쐘쐣쐤쐬쐭쐰쐳쐴쐼쐽쐿쑀쑁쑈쑉쑌쑏쑐쑘쑙쑛쑝쑤쑥쑨쑫쑬쑴쑵쑷쑹쑾쒀쒁쒄쒇쒈쒐쒑쒓쒔쒕쒜쒝쒠쒣쒤쒬쒭쒯쒰쒱쒸쒹쒼쒿쓀쓈쓉쓋쓍쓓쓔쓕쓘쓛쓜쓤쓥쓧쓩쓰쓱쓴쓷쓸쓺쓿씀씁씃씅씌씍씐씔씜씝씟씡씨씩씫씬씯씰씱씸씹씻씼씽씿앀앃아악안앉않앋알앍앎앏앒앓암압앖앗았앙앚앛앜앝앞앟애액앤앧앨앰앱앳앴앵앹앺야약앾얀얃얄얇얌얍얏얐양얒얔얕얗얘얙얜얟얠얨얩얫얬얭어억얶언얹얺얻얼얽얾얿엄업없엇었엉엊엌엎엏에엑엔엗엘엠엡엣엤엥엩엪여역엮연엱엳열엶엷엸염엽엾엿였영옄옅옆옇예옉옌옏옐옘옙옛옜옝옠오옥옦온옪옫올옭옮옯옰옲옳옴옵옷옹옺옻옽옾와왁완왇왈왎왐왑왓왔왕왘왙왜왝왠왣왤왬왭왯왰왱외왹왼왿욀욂욈욉욋욌욍욒요욕욘욛욜욝욤욥욧용욬우욱운욷울욹욺욼움웁웂웃웅웆웇웉워웍원웒웓월웘웜웝웟웠웡웤웥웨웩웬웯웰웸웹웻웼웽윁위윅윈윋윌윎윓윔윕윗윘윙윜윝유육윤윧율윰윱윳융윶윷윸윹으윽윾은읃을읅읆읇읊음읍읎읏응읒읓읔읕읖읗의읙읜읟읠읦읨읩읫읬읭이익인읻일읽읾잀잂잃임입잆잇있잉잊잋잌잍잎잏자작잓잔잖잗잘잙잚잠잡잣잤장잦잧잩잪잫재잭잰잲잳잴잼잽잿쟀쟁쟂쟈쟉쟌쟎쟏쟐쟘쟙쟛쟝쟤쟨쟫쟬쟴쟵쟷쟹저적젂전젆젇절젉젊젋점접젓젔정젖젙젛제젝젠젣젤젬젭젯젰젱젲젶져젹젼젿졀졁졂졃졇졈졉졋졌졍졎졑졓졔졕졘졜졤졥졧졩조족존졷졸졺좀좁좃종좆좇좋좌좍좐좒좓좔좕좖좜좝좟좠좡좦좨좩좬좯좰좸좹좻좼좽죄죅죈죋죌죔죕죗죘죙죠죡죤죧죨죰죱죳죵죻주죽준줃줄줅줆줈줌줍줏중줗줘줙줜줟줠줨줩줫줬줭줴줵줸줻줼쥄쥅쥇쥈쥉쥐쥑쥔쥗쥘쥠쥡쥣쥥쥬쥭쥰쥴쥼쥽쥿즁즈즉즌즏즐즑즒즔즘즙즛증즞즤즥즨즬즴즵즷즹지직진짇질짊짏짐집짒짓짔징짖짗짙짚짛짜짝짞짠짢짣짤짧짨짬짭짯짰짱짲짷째짹짼짿쨀쨈쨉쨋쨌쨍쨔쨕쨘쨚쨜쨤쨥쨧쨩쨭쨰쨴쩌쩍쩐쩓쩔쩗쩘쩛쩜쩝쩟쩠쩡쩧쩨쩩쩬쩯쩰쩸쩹쩻쩼쩽쪁쪄쪅쪈쪋쪌쪔쪕쪗쪘쪙쪠쪡쪤쪨쪰쪱쪳쪵쪼쪽쪾쫀쫃쫄쫆쫌쫍쫏쫑쫒쫓쫗쫘쫙쫜쫟쫠쫨쫩쫫쫬쫭쫴쫵쫸쫻쫼쬈쬐쬑쬔쬗쬘쬠쬡쬣쬤쬥쬧쬬쬭쬰쬲쬴쬼쬽쬿쭁쭈쭉쭊쭌쭏쭐쭒쭘쭙쭛쭝쭤쭥쭨쭫쭬쭴쭵쭷쭸쭹쮀쮁쮄쮇쮈쮐쮑쮓쮔쮕쮜쮝쮠쮣쮤쮬쮭쮯쮱쮸쮹쮼쯀쯈쯉쯋쯍쯔쯕쯘쯛쯜쯤쯥쯧쯩쯪쯰쯱쯴쯸찀찁찃찅찆찌찍찐찓찔찜찝찟찡찢찦찧차착찬찮찯찰찱참찹찻찼창찾찿챂채책챈챋챌챔챕챗챘챙챛챞챠챡챤챦챨챰챱챳챵챺챼첑처척천첟철첧첨첩첫첬청첮첲체첵첸첻첼쳃쳄쳅쳇쳈쳉쳊쳐쳑쳔쳗쳘쳠쳡쳣쳤쳥쳬쳭쳰쳴쳼쳽쳿촁초촉촌촏촐촘촙촛총촣촤촥촨촫촬촴촵촷촹쵀쵄쵓쵔최쵝쵠쵣쵤쵬쵭쵯쵰쵱쵸쵹쵼춀춈춉춋춍추축춘춛출춤춥춧충춰춱춴춷춸췀췁췃췄췅췌췍췐췔췜췝췟췠췡취췩췬췯췰췸췹췻췽츄츅츈츌츔츕츗츙츠측츤츧츨츩츬츰츱츳층츼츽칀칄칌칍칏칑치칙친칟칠칡칢침칩칫칬칭칮칰칲카칵칸칻칼캄캅캇캈캉캍캎캐캑캔캗캘캠캡캣캤캥캨캩캪캬캭캰캴캼캽캿컁컄컈컌커컥컨컫컬컴컵컷컸컹컻컽컾케켁켄켇켈켐켑켓켔켕켘켙켚켜켝켠켣켤켬켭켯켰켱켸켹켼콀콈콉콋콌콍코콕콘콛콜콤콥콧콩콪콮콰콱콴콸쾀쾁쾃쾅쾌쾍쾐쾓쾔쾜쾝쾟쾡쾨쾩쾬쾰쾸쾹쾻쾽쿄쿅쿈쿌쿔쿕쿗쿙쿠쿡쿤쿧쿨쿰쿱쿳쿵쿺쿼쿽퀀퀃퀄퀌퀍퀐퀑퀘퀙퀜퀠퀨퀩퀫퀬퀭퀴퀵퀸퀻퀼큄큅큇큉큐큑큔큘큠큡큣큥큨크큭큰큲클큶큼큽큿킁킄킈킉킌킐킘킙킛킝키킥킨킫킬킴킵킷킸킹킾타탁탄탇탈탉탊탏탐탑탓탔탕탚태택탠탢탣탤탥탬탭탯탰탱탶탸탹탼턀턈턉턋턍턔턘턚터턱턴턷털턹턺턻텀텁텃텄텅테텍텐텓텔템텝텟텠텡텦텨텩텬텯텰텸텹텻텼텽톄톅톈톌톔톗톙토톡톤톧톨톰톱톳통톷톸톹톺톼톽퇀퇄퇌퇍퇏퇑퇘퇬퇭퇴퇵퇸퇻퇼툄툅툇툈툉툐툑툔툘툠툡툣툥투툭툰툳툴툶툼툽툿퉁퉈퉉퉌퉏퉐퉔퉘퉙퉛퉜퉝퉤퉥퉨퉫퉬퉴퉵퉷퉸퉹튀튁튄튇튈튐튑튓튕튜튝튠튤튬튭튯튱트특튻튼튿틀틁틂틄틈틉틋틍틑틔틕틘틜틠틤틥틧틩티틱틴틷틸팀팁팃팅팈팊파팍팎판팑팓팔팖팜팝팟팠팡팣팤팥팦패팩팬팯팰팸팹팻팼팽퍁퍄퍅퍈퍌퍔퍕퍗퍙퍝퍠퍼퍽펀펃펄펌펍펎펏펐펑펕펖페펙펜펟펠펨펩펫펬펭펲펴펵편펹펻펼폄폅폇폈평폐폑폔폗폘폠폡폣폥포폭폮폰폳폴폼폽폿퐁퐄퐅퐆퐈퐉퐌퐐퐘퐙퐛퐝퐤푀푁푄푈푐푑푓푕표푝푠푣푤푬푭푯푱푸푹푼푿풀풂품풉풋풍풔풕풘풛풜풤풥풧풨풩풰풱풴풸퓀퓁퓃퓅퓌퓍퓐퓔퓜퓝퓟퓡퓨퓩퓬퓯퓰퓸퓹퓻퓽프픅픈픋플픐픔픕픗픙픠픡픤픨픰픱픳픵피픽핀핃필핌핍핏핐핑핕핖하학한핟할핡핣핤핥핧함합핫핬항핮핰핱핳해핵핸핻핼햄햅햇했행햋햍햏햐햑햔햘햠햡햣향햫햬헀허헉헌헏헐헑헒헕헗험헙헛헜헝헠헡헢헣헤헥헨헫헬헴헵헷헸헹헾헿혀혁현혇혈혐협혓혔형혜혝혠혤혬혭혯혰혱호혹혻혼혽혿홀홁홄홅홇홈홉홋홍홑화확환홛활홠홤홥홦홧홨황홰홱홴홷홸횀횁횃횄횅회획횐횓횔횜횝횟횡효횩횬횯횰횸횹횻횽후훅훈훋훌훍훎훐훑훒훓훔훕훗훙훜훝훠훡훤훨훰훱훳훴훵훼훽휀휃휄휌휍휏휐휑휘휙휜휟휠휨휩휫휭휴휵휸휺휻휼흃흄흅흇흉흍흐흑흔흕흖흗흘흙흝흟흠흡흣흥흨흩흪흫희흭흰흳흴흼흽흿힁히힉힌힏힐힗힘힙힛힜힝힠힣fi️︐︑︒︓︔︕︖︙︰︱︲︳︴︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄﹇﹈﹉﹊﹋﹌﹍﹎﹏﹐﹑﹒﹔﹕﹖﹗﹙﹚﹛﹜﹝﹞﹟﹠﹡﹢﹣﹤﹥﹦﹨﹩﹪﹫!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⦅⦆。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚¢£¬ ̄¦¥₩→� \ No newline at end of file diff --git a/examples/nim.cfg b/examples/nim.cfg new file mode 100644 index 0000000..0f840a1 --- /dev/null +++ b/examples/nim.cfg @@ -0,0 +1 @@ +--path:".." diff --git a/examples/unicode.nim b/examples/unicode.nim new file mode 100755 index 0000000..bbc6be2 --- /dev/null +++ b/examples/unicode.nim @@ -0,0 +1,119 @@ +import nico + +var messages = @[ + ("English", "!\"#$%&'()*+,-./0123456789\n:;<=>?@abcdefghijklmnopqrstuvwxyz\n[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{}~"), + ("German", "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg"), + ("German", "Beiß nicht in die Hand, die dich füttert."), + ("German", "Außerordentliche Übel erfordern außerordentliche Mittel."), + ("Armenian", "Կրնամ ապակի ուտել և ինծի անհանգիստ չըներ"), + ("Armenian", "Երբ որ կացինը եկաւ անտառ, ծառերը ասացին... «Կոտը մերոնցից է:»"), + ("Armenian", "Գառը՝ գարնան, ձիւնը՝ ձմռան"), + ("Polish", "Jeżu klątw, spłódź Finom część gry hańb!"), + ("Polish", "Dobrymi chęciami jest piekło wybrukowane."), + ("Romanian", "Îți mulțumesc că ai ales nico.\nȘi sper să ai o zi bună!"), + ("Russian", "Эх, чужак, общий съём цен шляп (юфть) вдрызг!"), + ("Russian", "Я люблю nico!"), + ("Russian", "Молчи, скрывайся и таи\nИ чувства и мечты свои –\nПускай в душевной глубине\nИ всходят и зайдут оне\nКак звезды ясные в ночи-\nЛюбуйся ими – и молчи."), + ("French", "Voix ambiguë d’un cœur qui au zéphyr préfère les jattes de kiwi"), + ("Spanish", "Benjamín pidió una bebida de kiwi y fresa; Noé, sin vergüenza, la más exquisita champaña del menú."), + ("Greek", "Ταχίστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός"), + ("Greek", "Η καλύτερη άμυνα είναι η επίθεση."), + ("Greek", "Χρόνια και ζαμάνια!"), + ("Greek", "Πώς τα πας σήμερα;"), + ("Chinese", "我能吞下玻璃而不伤身体。"), + ("Chinese", "你吃了吗?"), + ("Chinese", "不作不死。"), + ("Chinese", "最近好吗?"), + ("Chinese", "塞翁失马,焉知非福。"), + ("Chinese", "千军易得, 一将难求"), + ("Chinese", "万事开头难。"), + ("Chinese", "风无常顺,兵无常胜。"), + ("Chinese", "活到老,学到老。"), + ("Chinese", "一言既出,驷马难追。"), + ("Chinese", "路遥知马力,日久见人心"), + ("Chinese", "有理走遍天下,无理寸步难行。"), + ("Japanese", "猿も木から落ちる"), + ("Japanese", "亀の甲より年の功"), + ("Japanese", "うらやまし 思ひ切る時 猫の恋"), + ("Japanese", "虎穴に入らずんば虎子を得ず。"), + ("Japanese", "二兎を追う者は一兎をも得ず。"), + ("Japanese", "馬鹿は死ななきゃ治らない。"), + ("Japanese", "枯野路に 影かさなりて わかれけり"), + ("Japanese", "繰り返し麦の畝縫ふ胡蝶哉"), + ("Korean", "아득한 바다 위에 갈매기 두엇 날아 돈다.\n너훌너훌 시를 쓴다. 모르는 나라 글자다.\n널따란 하늘 복판에 나도 같이 시를 쓴다."), + ("Korean", "제 눈에 안경이다"), + ("Korean", "꿩 먹고 알 먹는다"), + ("Korean", "로마는 하루아침에 이루어진 것이 아니다"), + ("Korean", "고생 끝에 낙이 온다"), + ("Korean", "개천에서 용 난다"), + ("Korean", "안녕하세요?"), + ("Korean", "만나서 반갑습니다"), + ("Korean", "한국말 하실 줄 아세요?"), + ] + +var langs = @[ +"quan.png", +"ChillBitmap7x.png", +"font.png" +] +var langIdx = 0 +proc gameInit() = + for i in 0.. 1000: + langIdx.inc + if langIdx >= langs.len: + isPrintr = not isPrintr + langIdx = langIdx mod langs.len + iFrame = 0 + setFont(langIdx) + setWindowTitle("[ " & langs[langIdx][0..^5] & " ] font") + iFrame.inc + discard + +import strformat +proc gameDraw() = + cls() + var + rcolor {.global.} = rnd(1, 15) + scale {.global.} = 1 + block unicode: + #break + var + color = rcolor + h,i = 0 + if iFrame < 2: rcolor = rnd(1, 15) + for (language, msg) in messages: + if h > screenHeight: + cls() + h = 0 + setColor(color) + if not isPrintr: + print(&"{language}: {msg}", 0, h, scale) + else: + printr(&"{language}: {msg}", screenWidth, h, scale) + h += msg.textHeight(scale) + color.inc + color = color mod 15 + 1 # rnd(1,16) + i.inc + if i > iFrame div 20: break + discard + + setColor(6) + printr(&"frame: {iFrame}", screenWidth, screenHeight - fontHeight()) + printr("font: " & langs[langIdx][0..^5], screenWidth, screenHeight - fontHeight() * 2 * scale - scale) + discard + +nico.init("nico", "unicode test") +nico.createWindow("nico", 384, 384, 2, false) +fixedSize(true) +integerScale(true) +nico.run(gameInit, gameUpdate, gameDraw) diff --git a/nico.nim b/nico.nim old mode 100644 new mode 100755 index 8446ad1..7626212 --- a/nico.nim +++ b/nico.nim @@ -1,7 +1,6 @@ -import nico/backends/common -import tables -import unicode +import std/[tables, unicode, os] +import nico/backends/common import nico/keycodes export nico.keycodes @@ -11,8 +10,6 @@ export spritedraw when not defined(js): import nico/backends/sdl2 as backend -import os - export StencilMode export StencilBlend @@ -154,6 +151,7 @@ proc printc*(text: string, x,y: Pint, scale: Pint = 1) # centered proc printr*(text: string, x,y: Pint, scale: Pint = 1) # right aligned proc textWidth*(text: string, scale: Pint = 1): Pint +proc textHeight*(text: string, scale: Pint = 1): Pint proc glyphWidth*(c: Rune, scale: Pint = 1): Pint proc glyphWidth*(c: char, scale: Pint = 1): Pint @@ -738,7 +736,7 @@ proc ditherADitherXor*(v: float32, a = 149,b = 1234, c = 511) = proc ditherPass(x,y: int): bool {.inline.} = if gDitherMode == DitherNone: return true - + let x = floorMod(x + gDitherOffsetX, screenWidth) let y = floorMod(y + gDitherOffsetY, screenHeight) @@ -2221,10 +2219,17 @@ proc glyph*(c: Rune, x,y: Pint, scale: Pint = 1): Pint = ## draw a glyph from the current font if currentFont == nil: raise newException(Exception, "No font selected") + + var src: Rect if not currentFont.rects.hasKey(c): - return - let src: Rect = currentFont.rects[c] - let dst: Rect = (x.int, y.int, src.w * scale, src.h * scale) + let unknown = '?'.Rune + if not currentFont.rects.hasKey(unknown): + return + src = currentFont.rects[unknown] + else: + src = currentFont.rects[c] + + let dst: Rect = (x.int, y.int, src.w * scale.int, src.h * scale.int) try: fontBlit(currentFont, src, dst, currentColor) except IndexDefect: @@ -2240,32 +2245,34 @@ proc fontHeight*(): Pint = ## returns the height of the current font in pixels if currentFont == nil: return 0 - return currentFont.rects[Rune(' ')].h + return currentFontHeight proc print*(text: string, x,y: Pint, scale: Pint = 1) = ## prints a string using the current font if currentFont == nil: raise newException(Exception, "No font selected") - var x = x - var y = y - let ix = x - let lineHeight = fontHeight() * scale + scale + var tx = x; var ty = y + let ix = x; let lineHeight = fontHeight() * scale + scale for line in text.splitLines: for c in line.runes: - x += glyph(c, x, y, scale) - x = ix - y += lineHeight + tx += glyph(c, tx, ty, scale) + tx = ix + ty += lineHeight proc print*(text: string, scale: Pint = 1) = ## prints a string using the current font at cursor position - if currentFont == nil: - raise newException(Exception, "No font selected") - var x = cursorX - let y = cursorY - let lineHeight = fontHeight() * scale + scale - for c in text.runes: - x += glyph(c, x, y, scale) - cursorY += lineHeight + print(text, cursorX, cursorY, scale) + +proc printr*(text: string, x,y: Pint, scale: Pint = 1) = + ## prints a string in the current font, right aligned + let width = textWidth(text, scale) + print(text, x-width, y, scale) + +proc printc*(text: string, x,y: Pint, scale: Pint = 1) = + ## prints a string in the current font, center aligned + let width = textWidth(text, scale) + print(text, x-(width div 2), y, scale) + proc glyphWidth*(c: Rune, scale: Pint = 1): Pint = ## returns the width of the glyph in the current font @@ -2283,20 +2290,23 @@ proc textWidth*(text: string, scale: Pint = 1): Pint = ## returns the width of a string in the current font if currentFont == nil: raise newException(Exception, "No font selected") - for c in text.runes: - if not currentFont.rects.hasKey(c): - raise newException(Exception, "character not in font: '" & $c & "'") - result += currentFont.rects[c].w*scale + scale - -proc printr*(text: string, x,y: Pint, scale: Pint = 1) = - ## prints a string in the current font, right aligned - let width = textWidth(text, scale) - print(text, x-width, y, scale) + for line in text.splitLines: + var lineWidth = 0 + for c in line.runes: + if not currentFont.rects.hasKey(c): + let unknown = '?'.Rune + if not currentFont.rects.hasKey(unknown): + raise newException(Exception, "character not in font: '" & $c & "' = " & $(c.int)) + lineWidth += currentFont.rects[unknown].w*scale + scale + else: + lineWidth += currentFont.rects[c].w*scale + scale + if result < lineWidth: + result = lineWidth -proc printc*(text: string, x,y: Pint, scale: Pint = 1) = - ## prints a string in the current font, center aligned - let width = textWidth(text, scale) - print(text, x-(width div 2), y, scale) +proc textHeight*(text: string, scale: Pint = 1): Pint = + ## returns the height of a string in the current font + let lineslen = text.countLines() + result = lineslen * fontHeight() * scale + lineslen * scale proc copy*(sx,sy,dx,dy,w,h: Pint) = ## copy a rectangle of w by h pixels from sx,sy to dx,dy @@ -2532,12 +2542,12 @@ proc spr*(drawer: SpriteDraw, x,y:Pint)= proc sprOverlap*(a,b : SpriteDraw): bool= ##Will return true if the sprites overlap setSpritesheet(a.spriteSheet) - let + let aSprRect = getSprRect(a.spriteIndex,a.w,a.h) aRect: Rect = (a.x, a.y, aSprRect.w, aSprRect.h) if(a.spritesheet != b.spritesheet): setSpritesheet(b.spriteSheet) - let + let bSprRect = getSprRect(b.spriteIndex,b.w,b.h) bRect: Rect = (b.x, b.y, bSprRect.w, bSprRect.h) @@ -2552,7 +2562,7 @@ proc sprOverlap*(a,b : SpriteDraw): bool= bXRelative = xOverlap - b.x bYRelative = yOverlap - b.y - var + var surfA = spritesheets[a.spriteSheet] surfB = spritesheets[b.spriteSheet] indA = 0 @@ -2561,7 +2571,7 @@ proc sprOverlap*(a,b : SpriteDraw): bool= #Foreach pixel in the overlap check the colour there for xSamp in 0.. 0 and surfB.data[indB] > 0): #Using 0 as of now for alpha check - return true + return true return false @@ -2955,10 +2965,14 @@ proc getControllers*(): seq[NicoController] = proc setFont*(fontId: FontId) = ## sets the active font to be used by future print calls - if fontId > fonts.len: + if fontId > fonts.len: return + let font = fonts[fontId] + if font == nil: + echo "Haven't font id: " & $fontId return + currentFont = font currentFontId = fontId - currentFont = fonts[currentFontId] + currentFontHeight = currentFont.rects[Rune(' ')].h proc getFont*(): FontId = ## gets the current font id diff --git a/nico.nimble b/nico.nimble index 0839d0d..eea364b 100644 --- a/nico.nimble +++ b/nico.nimble @@ -29,7 +29,7 @@ let tests = collect(newSeq): task test, "run tests": for file in tests: - exec &"nim c -p:. -r {file}" + exec &"nim c -p:./tests -r {file}" task docs, "Generate documentation": exec "nim doc -p:. --git.url:https://github.com/ftsf/nico --git.commit:main --project --outdir:docs nico.nim" @@ -38,34 +38,37 @@ task docs, "Generate documentation": task testemscripten, "compile tests with emscripten": # test they compile with emscripten backend, harder to test running for file in tests: - exec &"nim c -d:emscripten -p:. {file}" + exec &"nim c -d:emscripten -p:./tests {file}" + +task unicode, "compile unicode example": + exec "nim c -r -p:./examples -d:release -o:examples/unicode examples/unicode.nim" task paintout, "compile paintout example": - exec "nim c -p:. -d:debug examples/paintout.nim" + exec "nim c -p:./examples -d:debug -o:examples/paintout examples/paintout.nim" task platformer, "compile platformer example": - exec "nim c -p:. -d:release --multimethods:on -o:examples/platformer examples/platformer.nim" + exec "nim c -p:./examples -d:release --multimethods:on -o:examples/platformer examples/platformer.nim" task audio, "compile audio example": - exec "nim c -p:. -d:debug -o:examples/audio examples/audio.nim" + exec "nim c -p:./examples -d:debug -o:examples/audio examples/audio.nim" task vertex, "compile vertex example": - exec "nim c -p:. -d:debug -o:examples/vertex examples/vertex.nim" + exec "nim c -p:./examples -d:debug -o:examples/vertex examples/vertex.nim" task gui, "compile gui example": - exec "nim c -p:. -d:debug -o:examples/gui examples/gui.nim" + exec "nim c -p:./examples -d:debug -o:examples/gui examples/gui.nim" task guiweb, "compile gui example": - exec "nim c -d:emscripten -p:. -o:examples/gui.js examples/gui2.nim" + exec "nim c -d:emscripten -p:./examples -o:examples/gui.js examples/gui2.nim" task coro, "compile coro example": - exec "nim c -p:. -d:debug -o:examples/gui examples/coro.nim" + exec "nim c -p:./examples -d:debug -o:examples/gui examples/coro.nim" task benchmark, "compile benchmark example": - exec "nim c -p:. -d:release -d:danger -o:examples/benchmark examples/benchmark.nim" + exec "nim c -p:./examples -d:release -d:danger -o:examples/benchmark examples/benchmark.nim" task tweaker, "compile tweaker example": - exec "nim c -p:. -d:release -d:danger -o:examples/tweaker examples/tweaker.nim" + exec "nim c -p:./examples -d:release -d:danger -o:examples/tweaker examples/tweaker.nim" task examples, "compile all examples": exec "nimble paintout" @@ -76,6 +79,7 @@ task examples, "compile all examples": exec "nimble benchmark" exec "nimble coro" exec "nimble tweaks" + exec "nimble unicode" task nicosynth, "runs nicosynth": exec "nim c -r -p:. -d:release -o:tools/nicosynth tools/nicosynth.nim" diff --git a/nico/backends/common.nim b/nico/backends/common.nim old mode 100644 new mode 100755 index 11c231d..20fe08c --- a/nico/backends/common.nim +++ b/nico/backends/common.nim @@ -1,13 +1,6 @@ -import math -import tables -import unicode -import hashes -import times -import algorithm -import strutils +import std/[strutils, math, tables, unicode, hashes, times, algorithm] import nico/keycodes - export keycodes.Keycode export keycodes.Scancode @@ -437,6 +430,7 @@ var resizeFuncs*: seq[ResizeFunc] var fonts*: array[FontId, Font] var currentFont*: Font var currentFontId*: FontId +var currentFontHeight*: Pint var frame* = 0 diff --git a/nico/backends/sdl2.nim b/nico/backends/sdl2.nim index 62c4985..222cf3f 100644 --- a/nico/backends/sdl2.nim +++ b/nico/backends/sdl2.nim @@ -1,17 +1,7 @@ -import common +import std/[json ,tables ,hashes ,strutils ,sequtils + ,times ,math ,streams ,random ,os ,osproc ,parsecfg] -import std/json -import std/tables -import std/hashes -import std/strutils -import std/sequtils -import std/times -import std/math -import std/streams -import std/random -import std/os -import std/osproc -import std/parsecfg +import common when defined(android): import std/strformat @@ -496,7 +486,7 @@ proc createWindow*(title: string, w,h: int, scale: int = 2, fullscreen: bool = f window = createWindow(title.cstring, r.x, r.y, r.w, r.h, (WINDOW_RESIZABLE or WINDOW_OPENGL).uint32) else: - window = createWindow(title.cstring, WINDOWPOS_CENTERED, WINDOWPOS_CENTERED, (w * scale).cint, (h * scale).cint, + window = createWindow(title.cstring, WINDOWPOS_CENTERED, WINDOWPOS_CENTERED, (w * scale).cint, (h * scale).cint, (WINDOW_RESIZABLE or (if fullscreen: WINDOW_FULLSCREEN_DESKTOP else: 0) or WINDOW_OPENGL.cint).uint32) discard glSetAttribute(GLattr.GL_CONTEXT_PROFILE_MASK, GL_CONTEXT_PROFILE_ES) @@ -630,7 +620,7 @@ void main() { window = createWindow(title.cstring, r.x, r.y, r.w, r.h, (WINDOW_RESIZABLE).uint32) else: - window = createWindow(title.cstring, WINDOWPOS_CENTERED, WINDOWPOS_CENTERED, (w * scale).cint, (h * scale).cint, + window = createWindow(title.cstring, WINDOWPOS_CENTERED, WINDOWPOS_CENTERED, (w * scale).cint, (h * scale).cint, (WINDOW_RESIZABLE or (if fullscreen: WINDOW_FULLSCREEN_DESKTOP else: 0)).uint32) if window == nil: @@ -1392,7 +1382,7 @@ when defined(emscripten): {.emit:""" EM_ASM( //create your directory where we keep our persistent data - FS.mkdir('/IDBFS'); + FS.mkdir('/IDBFS'); //mount persistent directory as IDBFS FS.mount(IDBFS,{},'/IDBFS'); @@ -1401,9 +1391,9 @@ when defined(emscripten): //flag to check when data are synchronized Module.syncdone = 0; - //populate persistent_data directory with existing persistent source data + //populate persistent_data directory with existing persistent source data //stored with Indexed Db - //first parameter = "true" mean synchronize from Indexed Db to + //first parameter = "true" mean synchronize from Indexed Db to //Emscripten file system, // "false" mean synchronize from Emscripten file system to Indexed Db //second parameter = function called when data are synchronized diff --git a/nico/console.nim b/nico/console.nim index 042f1d8..0cfc1bc 100644 --- a/nico/console.nim +++ b/nico/console.nim @@ -1,6 +1,5 @@ +import std/[strutils, tables] import nico -import strutils -import tables var consoleBG: ColorId = 9 var consoleFG: ColorId = 1 diff --git a/nico/debug.nim b/nico/debug.nim index f1f531d..ed5d3ae 100644 --- a/nico/debug.nim +++ b/nico/debug.nim @@ -1,7 +1,6 @@ +import std/[sequtils, strutils] import nico import nico/vec -import sequtils -import strutils type DebugKind = enum Point diff --git a/nico/gui.nim b/nico/gui.nim index 405ade2..ca1001d 100644 --- a/nico/gui.nim +++ b/nico/gui.nim @@ -1,7 +1,6 @@ +import std/[strutils, wordwrap] import nico import nico/utils -import strutils -import std/wordwrap export TextAlign diff --git a/nico/gui2.nim b/nico/gui2.nim index f2b4d9f..5687a80 100644 --- a/nico/gui2.nim +++ b/nico/gui2.nim @@ -1,14 +1,8 @@ +import std/[tables, algorithm, strformat] import nico -import tables - -import algorithm - import nico/debug -import strformat - # gui inspired by Dear Imgui - const hPadding = 4 const vPadding = 2 const hSpacing = 2 diff --git a/nico/matrix.nim b/nico/matrix.nim index 475d0f0..31458d6 100644 --- a/nico/matrix.nim +++ b/nico/matrix.nim @@ -1,4 +1,4 @@ -import math +import std/math import nico/vec type diff --git a/nico/quat.nim b/nico/quat.nim index a821269..ab1c4d3 100644 --- a/nico/quat.nim +++ b/nico/quat.nim @@ -1,5 +1,5 @@ +import std/math import nico/vec -import math type Quat* = array[4,float32] diff --git a/nico/ringbuffer.nim b/nico/ringbuffer.nim index 11269a7..22df5c0 100644 --- a/nico/ringbuffer.nim +++ b/nico/ringbuffer.nim @@ -1,4 +1,4 @@ -import math +import std/math type RingBuffer*[T] = object diff --git a/nico/stb_vorbis.nim b/nico/stb_vorbis.nim index 1bd254f..15d431b 100644 --- a/nico/stb_vorbis.nim +++ b/nico/stb_vorbis.nim @@ -30,14 +30,14 @@ when defined(linux) and not defined(android): {.passL: "-lm".} {.emit: """ -// Ogg Vorbis audio decoder - v1.10 - public domain +// Ogg Vorbis audio decoder - v1.22 - public domain // http://nothings.org/stb_vorbis/ // // Original version written by Sean Barrett in 2007. // -// Originally sponsored by RAD Game Tools. Seeking sponsored -// by Phillip Bennefall, Marc Andersen, Aaron Baker, Elias Software, -// Aras Pranckevicius, and Sean Barrett. +// Originally sponsored by RAD Game Tools. Seeking implementation +// sponsored by Phillip Bennefall, Marc Andersen, Aaron Baker, +// Elias Software, Aras Pranckevicius, and Sean Barrett. // // LICENSE // @@ -58,25 +58,41 @@ when defined(linux) and not defined(android): // Terje Mathisen Niklas Frykholm Andy Hill // Casey Muratori John Bolton Gargaj // Laurent Gomila Marc LeBlanc Ronny Chevalier -// Bernhard Wodo Evan Balster alxprd@github +// Bernhard Wodo Evan Balster github:alxprd // Tom Beaumont Ingo Leitgeb Nicolas Guillemot // Phillip Bennefall Rohit Thiago Goulart -// manxorist@github saga musix +// github:manxorist Saga Musix github:infatum +// Timur Gagiev Maxwell Koo Peter Waller +// github:audinowho Dougall Johnson David Reid +// github:Clownacy Pedro J. Estebanez Remi Verschelde +// AnthoFoxo github:morlat Gabriel Ravier // // Partial history: -// 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory -// 1.09 - 2016/04/04 - back out 'truncation of last frame' fix from previous version -// 1.08 - 2016/04/02 - warnings; setup memory leaks; truncation of last frame -// 1.07 - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const -// 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson) +// 1.22 - 2021-07-11 - various small fixes +// 1.21 - 2021-07-02 - fix bug for files with no comments +// 1.20 - 2020-07-11 - several small fixes +// 1.19 - 2020-02-05 - warnings +// 1.18 - 2020-02-02 - fix seek bugs; parse header comments; misc warnings etc. +// 1.17 - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure) +// 1.16 - 2019-03-04 - fix warnings +// 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found +// 1.14 - 2018-02-11 - delete bogus dealloca usage +// 1.13 - 2018-01-29 - fix truncation of last frame (hopefully) +// 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files +// 1.11 - 2017-07-23 - fix MinGW compilation +// 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory +// 1.09 - 2016-04-04 - back out 'truncation of last frame' fix from previous version +// 1.08 - 2016-04-02 - warnings; setup memory leaks; truncation of last frame +// 1.07 - 2015-01-16 - fixes for crashes on invalid files; warning fixes; const +// 1.06 - 2015-08-31 - full, correct support for seeking API (Dougall Johnson) // some crash fixes when out of memory or with corrupt files // fix some inappropriately signed shifts -// 1.05 - 2015/04/19 - don't define __forceinline if it's redundant -// 1.04 - 2014/08/27 - fix missing const-correct case in API -// 1.03 - 2014/08/07 - warning fixes -// 1.02 - 2014/07/09 - declare qsort comparison as explicitly _cdecl in Windows -// 1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float (interleaved was correct) -// 1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in >2-channel; +// 1.05 - 2015-04-19 - don't define __forceinline if it's redundant +// 1.04 - 2014-08-27 - fix missing const-correct case in API +// 1.03 - 2014-08-07 - warning fixes +// 1.02 - 2014-07-09 - declare qsort comparison as explicitly _cdecl in Windows +// 1.01 - 2014-06-18 - fix stb_vorbis_get_samples_float (interleaved was correct) +// 1.0 - 2014-05-26 - fix memory leaks; fix warnings; fix bugs in >2-channel; // (API change) report sample rate for decode-full-file funcs // // See end of file for full version history. @@ -154,9 +170,20 @@ typedef struct int max_frame_size; } stb_vorbis_info; +typedef struct +{ + char *vendor; + + int comment_list_length; + char **comment_list; +} stb_vorbis_comment; + // get general information about the file extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f); +// get ogg comments +extern stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f); + // get the last error detected (clears it, too) extern int stb_vorbis_get_error(stb_vorbis *f); @@ -228,6 +255,12 @@ extern int stb_vorbis_decode_frame_pushdata( // channel. In other words, (*output)[0][0] contains the first sample from // the first channel, and (*output)[1][0] contains the first sample from // the second channel. +// +// *output points into stb_vorbis's internal output buffer storage; these +// buffers are owned by stb_vorbis and application code should not free +// them or modify their contents. They are transient and will be overwritten +// once you ask for more data to get decoded, so be sure to grab any data +// you need before then. extern void stb_vorbis_flush_pushdata(stb_vorbis *f); // inform stb_vorbis that your next datablock will not be contiguous with @@ -280,7 +313,7 @@ extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close, // create an ogg vorbis decoder from an open FILE *, looking for a stream at // the _current_ seek point (ftell). on failure, returns NULL and sets *error. // note that stb_vorbis must "own" this stream; if you seek it in between -// calls to stb_vorbis, it will become confused. Morever, if you attempt to +// calls to stb_vorbis, it will become confused. Moreover, if you attempt to // perform stb_vorbis_seek_*() operations on this file, it will assume it // owns the _entire_ rest of the file after the start point. Use the next // function, stb_vorbis_open_file_section(), to limit it. @@ -401,7 +434,8 @@ enum STBVorbisError VORBIS_invalid_first_page, VORBIS_bad_packet_type, VORBIS_cant_find_last_page, - VORBIS_seek_failed + VORBIS_seek_failed, + VORBIS_ogg_skeleton_not_supported }; @@ -583,10 +617,10 @@ enum STBVorbisError #include // find definition of alloca if it's not in stdlib.h: - #ifdef _MSC_VER + #if defined(_MSC_VER) || defined(__MINGW32__) #include #endif - #if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__) + #if defined(__linux__) || defined(__linux) || defined(__sun__) || defined(__EMSCRIPTEN__) || defined(__NEWLIB__) #include #endif #else // STB_VORBIS_NO_CRT @@ -608,6 +642,9 @@ enum STBVorbisError #undef __forceinline #endif #define __forceinline + #ifndef alloca + #define alloca __builtin_alloca + #endif #elif !defined(_MSC_VER) #if __GNUC__ #define __forceinline inline @@ -650,6 +687,12 @@ typedef signed int int32; typedef float codetype; +#ifdef _MSC_VER +#define STBV_NOTUSED(v) (void)(v) +#else +#define STBV_NOTUSED(v) (void)sizeof(v) +#endif + // @NOTE // // Some arrays below are tagged "//varies", which means it's actually @@ -781,6 +824,10 @@ struct stb_vorbis unsigned int temp_memory_required; unsigned int setup_temp_memory_required; + char *vendor; + int comment_list_length; + char **comment_list; + // input config #ifndef STB_VORBIS_NO_STDIO FILE *f; @@ -796,8 +843,11 @@ struct stb_vorbis uint8 push_mode; + // the page to seek to when seeking to start, may be zero uint32 first_audio_page_offset; + // p_first is the page on which the first audio packet ends + // (but not necessarily the page on which it starts) ProbedPage p_first, p_last; // memory management @@ -846,7 +896,7 @@ struct stb_vorbis int current_loc_valid; // per-blocksize precomputed data - + // twiddle factors float *A[2],*B[2],*C[2]; float *window[2]; @@ -910,11 +960,7 @@ static int error(vorb *f, enum STBVorbisError e) #define array_size_required(count,size) (count*(sizeof(void *)+(size))) #define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : alloca(size)) -#ifdef dealloca -#define temp_free(f,p) (f->alloc.alloc_buffer ? 0 : dealloca(size)) -#else -#define temp_free(f,p) 0 -#endif +#define temp_free(f,p) (void)0 #define temp_alloc_save(f) ((f)->temp_offset) #define temp_alloc_restore(f,p) ((f)->temp_offset = (p)) @@ -935,7 +981,7 @@ static void *make_block_array(void *mem, int count, int size) static void *setup_malloc(vorb *f, int sz) { - sz = (sz+3) & ~3; + sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs. f->setup_memory_required += sz; if (f->alloc.alloc_buffer) { void *p = (char *) f->alloc.alloc_buffer + f->setup_offset; @@ -954,7 +1000,7 @@ static void setup_free(vorb *f, void *p) static void *setup_temp_malloc(vorb *f, int sz) { - sz = (sz+3) & ~3; + sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs. if (f->alloc.alloc_buffer) { if (f->temp_offset - sz < f->setup_offset) return NULL; f->temp_offset -= sz; @@ -966,7 +1012,7 @@ static void *setup_temp_malloc(vorb *f, int sz) static void setup_temp_free(vorb *f, void *p, int sz) { if (f->alloc.alloc_buffer) { - f->temp_offset += (sz+3)&~3; + f->temp_offset += (sz+7)&~7; return; } free(p); @@ -1047,7 +1093,7 @@ static float float32_unpack(uint32 x) uint32 sign = x & 0x80000000; uint32 exp = (x & 0x7fe00000) >> 21; double res = sign ? -(double)mantissa : (double)mantissa; - return (float) ldexp((float)res, exp-788); + return (float) ldexp((float)res, (int)exp-788); } @@ -1078,6 +1124,7 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) // find the first entry for (k=0; k < n; ++k) if (len[k] < NO_CODE) break; if (k == n) { assert(c->sorted_entries == 0); return TRUE; } + assert(len[k] < 32); // no error return required, code reading lens checks this // add to the list add_entry(c, 0, k, m++, len[k], values); // add all available leaves @@ -1091,6 +1138,7 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) uint32 res; int z = len[i], y; if (z == NO_CODE) continue; + assert(z < 32); // no error return required, code reading lens checks this // find lowest available leaf (should always be earliest, // which is what the specification calls for) // note that this property, and the fact we can never have @@ -1100,12 +1148,10 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) while (z > 0 && !available[z]) --z; if (z == 0) { return FALSE; } res = available[z]; - assert(z >= 0 && z < 32); available[z] = 0; add_entry(c, bit_reverse(res), i, m++, len[i], values); - // propogate availability up the tree + // propagate availability up the tree if (z != len[i]) { - assert(len[i] >= 0 && len[i] < 32); for (y=len[i]; y > z; --y) { assert(available[y] == 0); available[y] = res + (1 << (32-y)); @@ -1172,7 +1218,7 @@ static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values) if (!c->sparse) { int k = 0; for (i=0; i < c->entries; ++i) - if (include_in_sort(c, lengths[i])) + if (include_in_sort(c, lengths[i])) c->sorted_codewords[k++] = bit_reverse(c->codewords[i]); assert(k == c->sorted_entries); } else { @@ -1229,8 +1275,10 @@ static int lookup1_values(int entries, int dim) int r = (int) floor(exp((float) log((float) entries) / dim)); if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning; ++r; // floor() to avoid _ftol() when non-CRT - assert(pow((float) r+1, dim) > entries); - assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above + if (pow((float) r+1, dim) <= entries) + return -1; + if ((int) floor(pow((float) r, dim)) > entries) + return -1; return r; } @@ -1353,7 +1401,7 @@ static int getn(vorb *z, uint8 *data, int n) return 1; } - #ifndef STB_VORBIS_NO_STDIO + #ifndef STB_VORBIS_NO_STDIO if (fread(data, n, 1, z->f) == 1) return 1; else { @@ -1428,12 +1476,15 @@ static int capture_pattern(vorb *f) static int start_page_no_capturepattern(vorb *f) { uint32 loc0,loc1,n; + if (f->first_decode && !IS_PUSH_MODE(f)) { + f->p_first.page_start = stb_vorbis_get_file_offset(f) - 4; + } // stream structure version if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version); // header flag f->page_flag = get8(f); // absolute granule position - loc0 = get32(f); + loc0 = get32(f); loc1 = get32(f); // @TODO: validate loc0,loc1 as valid positions? // stream serial number -- vorbis doesn't interleave, so discard @@ -1464,15 +1515,12 @@ static int start_page_no_capturepattern(vorb *f) } if (f->first_decode) { int i,len; - ProbedPage p; len = 0; for (i=0; i < f->segment_count; ++i) len += f->segments[i]; len += 27 + f->segment_count; - p.page_start = f->first_audio_page_offset; - p.page_end = p.page_start + len; - p.last_decoded_sample = loc0; - f->p_first = p; + f->p_first.page_end = f->p_first.page_start + len; + f->p_first.last_decoded_sample = loc0; } f->next_seg = 0; return TRUE; @@ -1563,6 +1611,16 @@ static int get8_packet(vorb *f) return x; } +static int get32_packet(vorb *f) +{ + uint32 x; + x = get8_packet(f); + x += get8_packet(f) << 8; + x += get8_packet(f) << 16; + x += (uint32) get8_packet(f) << 24; + return x; +} + static void flush_packet(vorb *f) { while (get8_packet_raw(f) != EOP); @@ -1593,7 +1651,8 @@ static uint32 get_bits(vorb *f, int n) f->valid_bits += 8; } } - if (f->valid_bits < 0) return 0; + + assert(f->valid_bits >= n); z = f->acc & ((1 << n)-1); f->acc >>= n; f->valid_bits -= n; @@ -1918,69 +1977,69 @@ static int predict_point(int x, int x0, int x1, int y0, int y1) // the following table is block-copied from the specification static float inverse_db_table[256] = { - 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, - 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, - 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, - 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, - 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, - 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, - 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, - 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, - 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, - 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, - 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, - 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, - 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, - 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, - 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, - 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, - 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, - 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, - 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, - 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, - 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, - 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, - 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, - 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, - 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, - 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, - 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, - 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, - 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, - 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, - 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, - 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, - 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, - 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, - 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, - 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, - 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, - 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, - 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, - 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, - 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, - 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, - 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, - 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, - 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, - 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, - 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, - 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, - 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, - 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, - 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, - 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, - 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, - 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, - 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, - 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, - 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, - 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, - 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, - 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, - 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, - 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, - 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, + 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, + 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, + 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, + 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, + 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, + 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, + 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, + 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, + 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, + 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, + 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, + 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, + 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, + 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, + 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, + 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, + 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, + 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, + 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, + 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, + 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, + 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, + 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, + 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, + 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, + 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, + 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, + 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, + 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, + 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, + 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, + 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, + 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, + 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, + 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, + 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, + 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, + 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, + 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, + 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, + 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, + 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, + 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, + 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, + 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, + 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, + 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, + 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, + 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, + 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, + 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, + 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, + 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, + 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, + 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, + 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, + 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, + 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, + 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, + 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, + 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, + 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, + 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, 0.82788260f, 0.88168307f, 0.9389798f, 1.0f }; @@ -2040,7 +2099,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y ady -= abs(base) * adx; if (x1 > n) x1 = n; if (x < x1) { - LINE_OP(output[x], inverse_db_table[y]); + LINE_OP(output[x], inverse_db_table[y&255]); for (++x; x < x1; ++x) { err += ady; if (err >= adx) { @@ -2048,7 +2107,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y y += sy; } else y += base; - LINE_OP(output[x], inverse_db_table[y]); + LINE_OP(output[x], inverse_db_table[y&255]); } } } @@ -2072,6 +2131,8 @@ static int residue_decode(vorb *f, Codebook *book, float *target, int offset, in return TRUE; } +// n is 1/2 of the blocksize -- +// specification: "Correct per-vector decode length is [n]/2" static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode) { int i,j,pass; @@ -2079,7 +2140,10 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int int rtype = f->residue_types[rn]; int c = r->classbook; int classwords = f->codebooks[c].dimensions; - int n_read = r->end - r->begin; + unsigned int actual_size = rtype == 2 ? n*2 : n; + unsigned int limit_r_begin = (r->begin < actual_size ? r->begin : actual_size); + unsigned int limit_r_end = (r->end < actual_size ? r->end : actual_size); + int n_read = limit_r_end - limit_r_begin; int part_read = n_read / r->part_size; int temp_alloc_point = temp_alloc_save(f); #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE @@ -2149,47 +2213,7 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int ++class_set; #endif } - } else if (ch == 1) { - while (pcount < part_read) { - int z = r->begin + pcount*r->part_size; - int c_inter = 0, p_inter = z; - if (pass == 0) { - Codebook *c = f->codebooks+r->classbook; - int q; - DECODE(q,f,c); - if (q == EOP) goto done; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - part_classdata[0][class_set] = r->classdata[q]; - #else - for (i=classwords-1; i >= 0; --i) { - classifications[0][i+pcount] = q % r->classifications; - q /= r->classifications; - } - #endif - } - for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { - int z = r->begin + pcount*r->part_size; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - int c = part_classdata[0][class_set][i]; - #else - int c = classifications[0][pcount]; - #endif - int b = r->residue_books[c][pass]; - if (b >= 0) { - Codebook *book = f->codebooks + b; - if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) - goto done; - } else { - z += r->part_size; - c_inter = 0; - p_inter = z; - } - } - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - ++class_set; - #endif - } - } else { + } else if (ch > 2) { while (pcount < part_read) { int z = r->begin + pcount*r->part_size; int c_inter = z % ch, p_inter = z/ch; @@ -2376,11 +2400,11 @@ void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) #if LIBVORBIS_MDCT // directly call the vorbis MDCT using an interface documented // by Jeff Roberts... useful for performance comparison -typedef struct +typedef struct { int n; int log2n; - + float *trig; int *bitrev; @@ -2399,7 +2423,7 @@ void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) if (M1.n == n) M = &M1; else if (M2.n == n) M = &M2; else if (M1.n == 0) { mdct_init(&M1, n); M = &M1; } - else { + else { if (M2.n) __asm int 3; mdct_init(&M2, n); M = &M2; @@ -2600,34 +2624,33 @@ static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A, while (z > base) { float k00,k11; - - k00 = z[-0] - z[-8]; - k11 = z[-1] - z[-9]; - z[-0] = z[-0] + z[-8]; - z[-1] = z[-1] + z[-9]; - z[-8] = k00; - z[-9] = k11 ; - - k00 = z[ -2] - z[-10]; - k11 = z[ -3] - z[-11]; - z[ -2] = z[ -2] + z[-10]; - z[ -3] = z[ -3] + z[-11]; - z[-10] = (k00+k11) * A2; - z[-11] = (k11-k00) * A2; - - k00 = z[-12] - z[ -4]; // reverse to avoid a unary negation + float l00,l11; + + k00 = z[-0] - z[ -8]; + k11 = z[-1] - z[ -9]; + l00 = z[-2] - z[-10]; + l11 = z[-3] - z[-11]; + z[ -0] = z[-0] + z[ -8]; + z[ -1] = z[-1] + z[ -9]; + z[ -2] = z[-2] + z[-10]; + z[ -3] = z[-3] + z[-11]; + z[ -8] = k00; + z[ -9] = k11; + z[-10] = (l00+l11) * A2; + z[-11] = (l11-l00) * A2; + + k00 = z[ -4] - z[-12]; k11 = z[ -5] - z[-13]; + l00 = z[ -6] - z[-14]; + l11 = z[ -7] - z[-15]; z[ -4] = z[ -4] + z[-12]; z[ -5] = z[ -5] + z[-13]; - z[-12] = k11; - z[-13] = k00; - - k00 = z[-14] - z[ -6]; // reverse to avoid a unary negation - k11 = z[ -7] - z[-15]; z[ -6] = z[ -6] + z[-14]; z[ -7] = z[ -7] + z[-15]; - z[-14] = (k00+k11) * A2; - z[-15] = (k00-k11) * A2; + z[-12] = k11; + z[-13] = -k00; + z[-14] = (l11-l00) * A2; + z[-15] = (l00+l11) * -A2; iter_54(z); iter_54(z-8); @@ -2662,7 +2685,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) // once I combined the passes. // so there's a missing 'times 2' here (for adding X to itself). - // this propogates through linearly to the end, where the numbers + // this propagates through linearly to the end, where the numbers // are 1/2 too small, and need to be compensated for. { @@ -2812,7 +2835,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) d1[0] = u[k4+1]; d0[1] = u[k4+2]; d0[0] = u[k4+3]; - + d0 -= 4; d1 -= 4; bitrev += 2; @@ -2893,7 +2916,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) float p0,p1,p2,p3; p3 = e[6]*B[7] - e[7]*B[6]; - p2 = -e[6]*B[6] - e[7]*B[7]; + p2 = -e[6]*B[6] - e[7]*B[7]; d0[0] = p3; d1[3] = - p3; @@ -2901,7 +2924,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) d3[3] = p2; p1 = e[4]*B[5] - e[5]*B[4]; - p0 = -e[4]*B[4] - e[5]*B[5]; + p0 = -e[4]*B[4] - e[5]*B[5]; d0[1] = p1; d1[2] = - p1; @@ -2909,7 +2932,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) d3[2] = p0; p3 = e[2]*B[3] - e[3]*B[2]; - p2 = -e[2]*B[2] - e[3]*B[3]; + p2 = -e[2]*B[2] - e[3]*B[3]; d0[2] = p3; d1[1] = - p3; @@ -2917,7 +2940,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) d3[1] = p2; p1 = e[0]*B[1] - e[1]*B[0]; - p0 = -e[0]*B[0] - e[1]*B[1]; + p0 = -e[0]*B[0] - e[1]*B[1]; d0[3] = p1; d1[0] = - p1; @@ -3070,7 +3093,6 @@ static float *get_window(vorb *f, int len) len <<= 1; if (len == f->blocksize_0) return f->window[0]; if (len == f->blocksize_1) return f->window[1]; - assert(0); return NULL; } @@ -3093,6 +3115,7 @@ static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *f for (q=1; q < g->values; ++q) { j = g->sorted_order[q]; #ifndef STB_VORBIS_NO_DEFER_FLOOR + STBV_NOTUSED(step2_flag); if (finalY[j] >= 0) #else if (step2_flag[j]) @@ -3195,6 +3218,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, // WINDOWING + STBV_NOTUSED(left_end); n = f->blocksize[m->blockflag]; map = &f->mapping[m->mapping]; @@ -3392,7 +3416,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, // this isn't to spec, but spec would require us to read ahead // and decode the size of all current frames--could be done, // but presumably it's not a commonly used feature - f->current_loc = -n2; // start of first frame is positioned for discard + f->current_loc = 0u - n2; // start of first frame is positioned for discard (NB this is an intentional unsigned overflow/wrap-around) // we might have to discard samples "from" the next frame too, // if we're lapping a large block then a small at the start? f->discard_samples_deferred = n - right_end; @@ -3421,7 +3445,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, if (f->last_seg_which == f->end_seg_with_known_loc) { // if we have a valid current loc, and this is final: if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) { - uint32 current_end = f->known_loc_for_packet - (n-right_end); + uint32 current_end = f->known_loc_for_packet; // then let's infer the size of the (probably) short final frame if (current_end < f->current_loc + (right_end-left_start)) { if (current_end < f->current_loc) { @@ -3430,7 +3454,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, } else { *len = current_end - f->current_loc; } - *len += left_start; + *len += left_start; // this doesn't seem right, but has no ill effect on my test files if (*len > right_end) *len = right_end; // this should never happen f->current_loc += *len; return TRUE; @@ -3476,6 +3500,7 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) if (f->previous_length) { int i,j, n = f->previous_length; float *w = get_window(f, n); + if (w == NULL) return 0; for (i=0; i < f->channels; ++i) { for (j=0; j < n; ++j) f->channel_buffers[i][left+j] = @@ -3523,7 +3548,7 @@ static int vorbis_pump_first_frame(stb_vorbis *f) } #ifndef STB_VORBIS_NO_PUSHDATA_API -static int is_whole_packet_present(stb_vorbis *f, int end_page) +static int is_whole_packet_present(stb_vorbis *f) { // make sure that we have the packet available before continuing... // this requires a full ogg parse, but we know we can fetch from f->stream @@ -3543,15 +3568,13 @@ static int is_whole_packet_present(stb_vorbis *f, int end_page) break; } // either this continues, or it ends it... - if (end_page) - if (s < f->segment_count-1) return error(f, VORBIS_invalid_stream); if (s == f->segment_count) s = -1; // set 'crosses page' flag if (p > f->stream_end) return error(f, VORBIS_need_more_data); first = FALSE; } for (; s == -1;) { - uint8 *q; + uint8 *q; int n; // check that we have the page header ready @@ -3577,8 +3600,6 @@ static int is_whole_packet_present(stb_vorbis *f, int end_page) if (q[s] < 255) break; } - if (end_page) - if (s < n-1) return error(f, VORBIS_invalid_stream); if (s == n) s = -1; // set 'crosses page' flag if (p > f->stream_end) return error(f, VORBIS_need_more_data); @@ -3595,6 +3616,7 @@ static int start_decoder(vorb *f) int longest_floorlist=0; // first page, first packet + f->first_decode = TRUE; if (!start_page(f)) return FALSE; // validate page flag @@ -3603,7 +3625,22 @@ static int start_decoder(vorb *f) if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page); // check for expected packet length if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page); - if (f->segments[0] != 30) return error(f, VORBIS_invalid_first_page); + if (f->segments[0] != 30) { + // check for the Ogg skeleton fishead identifying header to refine our error + if (f->segments[0] == 64 && + getn(f, header, 6) && + header[0] == 'f' && + header[1] == 'i' && + header[2] == 's' && + header[3] == 'h' && + header[4] == 'e' && + header[5] == 'a' && + get8(f) == 'd' && + get8(f) == '\0') return error(f, VORBIS_ogg_skeleton_not_supported); + else + return error(f, VORBIS_invalid_first_page); + } + // read packet // check packet header if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page); @@ -3637,6 +3674,48 @@ static int start_decoder(vorb *f) if (!start_page(f)) return FALSE; if (!start_packet(f)) return FALSE; + + if (!next_segment(f)) return FALSE; + + if (get8_packet(f) != VORBIS_packet_comment) return error(f, VORBIS_invalid_setup); + for (i=0; i < 6; ++i) header[i] = get8_packet(f); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); + //file vendor + len = get32_packet(f); + f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1)); + if (f->vendor == NULL) return error(f, VORBIS_outofmem); + for(i=0; i < len; ++i) { + f->vendor[i] = get8_packet(f); + } + f->vendor[len] = (char)'\0'; + //user comments + f->comment_list_length = get32_packet(f); + f->comment_list = NULL; + if (f->comment_list_length > 0) + { + f->comment_list = (char**) setup_malloc(f, sizeof(char*) * (f->comment_list_length)); + if (f->comment_list == NULL) return error(f, VORBIS_outofmem); + } + + for(i=0; i < f->comment_list_length; ++i) { + len = get32_packet(f); + f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1)); + if (f->comment_list[i] == NULL) return error(f, VORBIS_outofmem); + + for(j=0; j < len; ++j) { + f->comment_list[i][j] = get8_packet(f); + } + f->comment_list[i][len] = (char)'\0'; + } + + // framing_flag + x = get8_packet(f); + if (!(x & 1)) return error(f, VORBIS_invalid_setup); + + + skip(f, f->bytes_in_seg); + f->bytes_in_seg = 0; + do { len = next_segment(f); skip(f, len); @@ -3648,7 +3727,7 @@ static int start_decoder(vorb *f) #ifndef STB_VORBIS_NO_PUSHDATA_API if (IS_PUSH_MODE(f)) { - if (!is_whole_packet_present(f, TRUE)) { + if (!is_whole_packet_present(f)) { // convert error in ogg header to write type if (f->error == VORBIS_invalid_stream) f->error = VORBIS_invalid_setup; @@ -3702,6 +3781,7 @@ static int start_decoder(vorb *f) while (current_entry < c->entries) { int limit = c->entries - current_entry; int n = get_bits(f, ilog(limit)); + if (current_length >= 32) return error(f, VORBIS_invalid_setup); if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); } memset(lengths + current_entry, current_length, n); current_entry += n; @@ -3805,7 +3885,9 @@ static int start_decoder(vorb *f) c->value_bits = get_bits(f, 4)+1; c->sequence_p = get_bits(f,1); if (c->lookup_type == 1) { - c->lookup_values = lookup1_values(c->entries, c->dimensions); + int values = lookup1_values(c->entries, c->dimensions); + if (values < 0) return error(f, VORBIS_invalid_setup); + c->lookup_values = (uint32) values; } else { c->lookup_values = c->entries * c->dimensions; } @@ -3835,8 +3917,7 @@ static int start_decoder(vorb *f) unsigned int div=1; for (k=0; k < c->dimensions; ++k) { int off = (z / div) % c->lookup_values; - float val = mults[off]; - val = mults[off]*c->delta_value + c->minimum_value + last; + float val = mults[off]*c->delta_value + c->minimum_value + last; c->multiplicands[j*c->dimensions + k] = val; if (c->sequence_p) last = val; @@ -3904,7 +3985,7 @@ static int start_decoder(vorb *f) } else { stbv__floor_ordering p[31*8+2]; Floor1 *g = &f->floor_config[i].floor1; - int max_class = -1; + int max_class = -1; g->partitions = get_bits(f, 5); for (j=0; j < g->partitions; ++j) { g->partition_class_list[j] = get_bits(f, 4); @@ -3919,7 +4000,7 @@ static int start_decoder(vorb *f) if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup); } for (k=0; k < 1 << g->class_subclasses[j]; ++k) { - g->subclass_books[j][k] = get_bits(f,8)-1; + g->subclass_books[j][k] = (int16)get_bits(f,8)-1; if (g->subclass_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); } } @@ -3941,11 +4022,14 @@ static int start_decoder(vorb *f) p[j].id = j; } qsort(p, g->values, sizeof(p[0]), point_compare); + for (j=0; j < g->values-1; ++j) + if (p[j].x == p[j+1].x) + return error(f, VORBIS_invalid_setup); for (j=0; j < g->values; ++j) g->sorted_order[j] = (uint8) p[j].id; // precompute the neighbors for (j=2; j < g->values; ++j) { - int low,hi; + int low = 0,hi = 0; neighbors(g->Xlist, j, &low,&hi); g->neighbors[j][0] = low; g->neighbors[j][1] = hi; @@ -4014,7 +4098,7 @@ static int start_decoder(vorb *f) if (f->mapping == NULL) return error(f, VORBIS_outofmem); memset(f->mapping, 0, f->mapping_count * sizeof(*f->mapping)); for (i=0; i < f->mapping_count; ++i) { - Mapping *m = f->mapping + i; + Mapping *m = f->mapping + i; int mapping_type = get_bits(f,16); if (mapping_type != 0) return error(f, VORBIS_invalid_setup); m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan)); @@ -4027,6 +4111,7 @@ static int start_decoder(vorb *f) max_submaps = m->submaps; if (get_bits(f,1)) { m->coupling_steps = get_bits(f,8)+1; + if (m->coupling_steps > f->channels) return error(f, VORBIS_invalid_setup); for (k=0; k < m->coupling_steps; ++k) { m->chan[k].magnitude = get_bits(f, ilog(f->channels-1)); m->chan[k].angle = get_bits(f, ilog(f->channels-1)); @@ -4080,6 +4165,7 @@ static int start_decoder(vorb *f) f->previous_window[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); f->finalY[i] = (int16 *) setup_malloc(f, sizeof(int16) * longest_floorlist); if (f->channel_buffers[i] == NULL || f->previous_window[i] == NULL || f->finalY[i] == NULL) return error(f, VORBIS_outofmem); + memset(f->channel_buffers[i], 0, sizeof(float) * f->blocksize_1); #ifdef STB_VORBIS_NO_DEFER_FLOOR f->floor_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); if (f->floor_buffers[i] == NULL) return error(f, VORBIS_outofmem); @@ -4107,7 +4193,10 @@ static int start_decoder(vorb *f) int i,max_part_read=0; for (i=0; i < f->residue_count; ++i) { Residue *r = f->residue_config + i; - int n_read = r->end - r->begin; + unsigned int actual_size = f->blocksize_1 / 2; + unsigned int limit_r_begin = r->begin < actual_size ? r->begin : actual_size; + unsigned int limit_r_end = r->end < actual_size ? r->end : actual_size; + int n_read = limit_r_end - limit_r_begin; int part_read = n_read / r->part_size; if (part_read > max_part_read) max_part_read = part_read; @@ -4118,12 +4207,13 @@ static int start_decoder(vorb *f) classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *)); #endif + // maximum reasonable partition size is f->blocksize_1 + f->temp_memory_required = classify_mem; if (imdct_mem > f->temp_memory_required) f->temp_memory_required = imdct_mem; } - f->first_decode = TRUE; if (f->alloc.alloc_buffer) { assert(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes); @@ -4132,7 +4222,17 @@ static int start_decoder(vorb *f) return error(f, VORBIS_outofmem); } - f->first_audio_page_offset = stb_vorbis_get_file_offset(f); + // @TODO: stb_vorbis_seek_start expects first_audio_page_offset to point to a page + // without PAGEFLAG_continued_packet, so this either points to the first page, or + // the page after the end of the headers. It might be cleaner to point to a page + // in the middle of the headers, when that's the page where the first audio packet + // starts, but we'd have to also correctly skip the end of any continued packet in + // stb_vorbis_seek_start. + if (f->next_seg == -1) { + f->first_audio_page_offset = stb_vorbis_get_file_offset(f); + } else { + f->first_audio_page_offset = 0; + } return TRUE; } @@ -4140,6 +4240,13 @@ static int start_decoder(vorb *f) static void vorbis_deinit(stb_vorbis *p) { int i,j; + + setup_free(p, p->vendor); + for (i=0; i < p->comment_list_length; ++i) { + setup_free(p, p->comment_list[i]); + } + setup_free(p, p->comment_list); + if (p->residue_config) { for (i=0; i < p->residue_count; ++i) { Residue *r = p->residue_config+i; @@ -4205,7 +4312,7 @@ static void vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z) memset(p, 0, sizeof(*p)); // NULL out all malloc'd pointers to start if (z) { p->alloc = *z; - p->alloc.alloc_buffer_length_in_bytes = (p->alloc.alloc_buffer_length_in_bytes+3) & ~3; + p->alloc.alloc_buffer_length_in_bytes &= ~7; p->temp_offset = p->alloc.alloc_buffer_length_in_bytes; } p->eof = 0; @@ -4239,6 +4346,15 @@ stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f) return d; } +stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f) +{ + stb_vorbis_comment d; + d.vendor = f->vendor; + d.comment_list_length = f->comment_list_length; + d.comment_list = f->comment_list; + return d; +} + int stb_vorbis_get_error(stb_vorbis *f) { int e = f->error; @@ -4380,7 +4496,7 @@ int stb_vorbis_decode_frame_pushdata( f->error = VORBIS__no_error; // check that we have the entire packet in memory - if (!is_whole_packet_present(f, FALSE)) { + if (!is_whole_packet_present(f)) { *samples = 0; return 0; } @@ -4442,6 +4558,7 @@ stb_vorbis *stb_vorbis_open_pushdata( *error = VORBIS_need_more_data; else *error = p.error; + vorbis_deinit(&p); return NULL; } f = vorbis_alloc(&p); @@ -4499,7 +4616,7 @@ static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last) header[i] = get8(f); if (f->eof) return 0; if (header[4] != 0) goto invalid; - goal = header[22] + (header[23] << 8) + (header[24]<<16) + (header[25]<<24); + goal = header[22] + (header[23] << 8) + (header[24]<<16) + ((uint32)header[25]<<24); for (i=22; i < 26; ++i) header[i] = 0; crc = 0; @@ -4585,7 +4702,7 @@ static int get_seek_page_info(stb_vorbis *f, ProbedPage *z) return 1; } -// rarely used function to seek back to the preceeding page while finding the +// rarely used function to seek back to the preceding page while finding the // start of a packet static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset) { @@ -4616,8 +4733,8 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) { ProbedPage left, right, mid; int i, start_seg_with_known_loc, end_pos, page_start; - uint32 delta, stream_length, padding; - double offset, bytes_per_sample; + uint32 delta, stream_length, padding, last_sample_limit; + double offset = 0.0, bytes_per_sample = 0.0; int probe = 0; // find the last page and validate the target sample @@ -4630,9 +4747,9 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) // indicates should be the granule position (give or take one)). padding = ((f->blocksize_1 - f->blocksize_0) >> 2); if (sample_number < padding) - sample_number = 0; + last_sample_limit = 0; else - sample_number -= padding; + last_sample_limit = sample_number - padding; left = f->p_first; while (left.last_decoded_sample == ~0U) { @@ -4645,9 +4762,12 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) assert(right.last_decoded_sample != ~0U); // starting from the start is handled differently - if (sample_number <= left.last_decoded_sample) { - if (stb_vorbis_seek_start(f)) + if (last_sample_limit <= left.last_decoded_sample) { + if (stb_vorbis_seek_start(f)) { + if (f->current_loc > sample_number) + return error(f, VORBIS_seek_failed); return 1; + } return 0; } @@ -4664,10 +4784,10 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) // first probe (interpolate) double data_bytes = right.page_end - left.page_start; bytes_per_sample = data_bytes / right.last_decoded_sample; - offset = left.page_start + bytes_per_sample * (sample_number - left.last_decoded_sample); + offset = left.page_start + bytes_per_sample * (last_sample_limit - left.last_decoded_sample); } else { // second probe (try to bound the other side) - double error = ((double) sample_number - mid.last_decoded_sample) * bytes_per_sample; + double error = ((double) last_sample_limit - mid.last_decoded_sample) * bytes_per_sample; if (error >= 0 && error < 8000) error = 8000; if (error < 0 && error > -8000) error = -8000; offset += error * 2; @@ -4698,14 +4818,16 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) } // if we've just found the last page again then we're in a tricky file, - // and we're close enough. - if (mid.page_start == right.page_start) - break; - - if (sample_number < mid.last_decoded_sample) - right = mid; - else - left = mid; + // and we're close enough (if it wasn't an interpolation probe). + if (mid.page_start == right.page_start) { + if (probe >= 2 || delta <= 65536) + break; + } else { + if (last_sample_limit < mid.last_decoded_sample) + right = mid; + else + left = mid; + } ++probe; } @@ -4821,8 +4943,8 @@ int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number) flush_packet(f); } } - // the next frame will start with the sample - assert(f->current_loc == sample_number); + // the next frame should start with the sample + if (f->current_loc != sample_number) return error(f, VORBIS_seek_failed); return 1; } @@ -4898,7 +5020,7 @@ unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) // set. whoops! break; } - previous_safe = last_page_loc+1; + //previous_safe = last_page_loc+1; // NOTE: not used after this point, but note for debugging last_page_loc = stb_vorbis_get_file_offset(f); } @@ -4992,8 +5114,14 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, con stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) { - FILE *f = fopen(filename, "rb"); - if (f) + FILE *f; +#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) + if (0 != fopen_s(&f, filename, "rb")) + f = NULL; +#else + f = fopen(filename, "rb"); +#endif + if (f) return stb_vorbis_open_file(f, TRUE, error, alloc); if (error) *error = VORBIS_file_open_failure; return NULL; @@ -5003,7 +5131,10 @@ stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const st stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc) { stb_vorbis *f, p; - if (data == NULL) return NULL; + if (!data) { + if (error) *error = VORBIS_unexpected_eof; + return NULL; + } vorbis_init(&p, alloc); p.stream = (uint8 *) data; p.stream_end = (uint8 *) data + len; @@ -5056,7 +5187,7 @@ static int8 channel_position[7][6] = #define MAGIC(SHIFT) (1.5f * (1 << (23-SHIFT)) + 0.5f/(1 << SHIFT)) #define ADDEND(SHIFT) (((150-SHIFT) << 23) + (1 << 22)) #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) (temp.f = (x) + MAGIC(s), temp.i - ADDEND(s)) - #define check_endianness() + #define check_endianness() #else #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) ((int) ((x) * (1 << (s)))) #define check_endianness() @@ -5078,11 +5209,11 @@ static void copy_samples(short *dest, float *src, int len) static void compute_samples(int mask, short *output, int num_c, float **data, int d_offset, int len) { - #define BUFFER_SIZE 32 - float buffer[BUFFER_SIZE]; - int i,j,o,n = BUFFER_SIZE; + #define STB_BUFFER_SIZE 32 + float buffer[STB_BUFFER_SIZE]; + int i,j,o,n = STB_BUFFER_SIZE; check_endianness(); - for (o = 0; o < len; o += BUFFER_SIZE) { + for (o = 0; o < len; o += STB_BUFFER_SIZE) { memset(buffer, 0, sizeof(buffer)); if (o + n > len) n = len - o; for (j=0; j < num_c; ++j) { @@ -5099,16 +5230,17 @@ static void compute_samples(int mask, short *output, int num_c, float **data, in output[o+i] = v; } } + #undef STB_BUFFER_SIZE } static void compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len) { - #define BUFFER_SIZE 32 - float buffer[BUFFER_SIZE]; - int i,j,o,n = BUFFER_SIZE >> 1; + #define STB_BUFFER_SIZE 32 + float buffer[STB_BUFFER_SIZE]; + int i,j,o,n = STB_BUFFER_SIZE >> 1; // o is the offset in the source data check_endianness(); - for (o = 0; o < len; o += BUFFER_SIZE >> 1) { + for (o = 0; o < len; o += STB_BUFFER_SIZE >> 1) { // o2 is the offset in the output data int o2 = o << 1; memset(buffer, 0, sizeof(buffer)); @@ -5138,6 +5270,7 @@ static void compute_stereo_samples(short *output, int num_c, float **data, int d output[o2+i] = v; } } + #undef STB_BUFFER_SIZE } static void convert_samples_short(int buf_c, short **buffer, int b_offset, int data_c, float **data, int d_offset, int samples) @@ -5158,7 +5291,7 @@ static void convert_samples_short(int buf_c, short **buffer, int b_offset, int d int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num_samples) { - float **output; + float **output = NULL; int len = stb_vorbis_get_frame_float(f, NULL, &output); if (len > num_samples) len = num_samples; if (len) @@ -5210,8 +5343,6 @@ int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short float **outputs; int len = num_shorts / channels; int n=0; - int z = f->channels; - if (z > channels) z = channels; while (n < len) { int k = f->channel_buffer_end - f->channel_buffer_start; if (n+k >= len) k = len - n; @@ -5230,8 +5361,6 @@ int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, in { float **outputs; int n=0; - int z = f->channels; - if (z > channels) z = channels; while (n < len) { int k = f->channel_buffer_end - f->channel_buffer_start; if (n+k >= len) k = len - n; @@ -5381,20 +5510,28 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in #endif // STB_VORBIS_NO_PULLDATA_API /* Version history - 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory - 1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version - 1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks; + 1.17 - 2019-07-08 - fix CVE-2019-13217, -13218, -13219, -13220, -13221, -13222, -13223 + found with Mayhem by ForAllSecure + 1.16 - 2019-03-04 - fix warnings + 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found + 1.14 - 2018-02-11 - delete bogus dealloca usage + 1.13 - 2018-01-29 - fix truncation of last frame (hopefully) + 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files + 1.11 - 2017-07-23 - fix MinGW compilation + 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory + 1.09 - 2016-04-04 - back out 'avoid discarding last frame' fix from previous version + 1.08 - 2016-04-02 - fixed multiple warnings; fix setup memory leaks; avoid discarding last frame of audio data - 1.07 - 2015/01/16 - fixed some warnings, fix mingw, const-correct API - some more crash fixes when out of memory or with corrupt files - 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson) + 1.07 - 2015-01-16 - fixed some warnings, fix mingw, const-correct API + some more crash fixes when out of memory or with corrupt files + 1.06 - 2015-08-31 - full, correct support for seeking API (Dougall Johnson) some crash fixes when out of memory or with corrupt files - 1.05 - 2015/04/19 - don't define __forceinline if it's redundant - 1.04 - 2014/08/27 - fix missing const-correct case in API - 1.03 - 2014/08/07 - Warning fixes - 1.02 - 2014/07/09 - Declare qsort compare function _cdecl on windows - 1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float - 1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in multichannel + 1.05 - 2015-04-19 - don't define __forceinline if it's redundant + 1.04 - 2014-08-27 - fix missing const-correct case in API + 1.03 - 2014-08-07 - Warning fixes + 1.02 - 2014-07-09 - Declare qsort compare function _cdecl on windows + 1.01 - 2014-06-18 - fix stb_vorbis_get_samples_float + 1.0 - 2014-05-26 - fix memory leaks; fix warnings; fix bugs in multichannel (API change) report sample rate for decode-full-file funcs 0.99996 - bracket #include for macintosh compilation by Laurent Gomila 0.99995 - use union instead of pointer-cast for fast-float-to-int to avoid alias-optimization problem @@ -5442,38 +5579,38 @@ This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------ ALTERNATIVE A - MIT License Copyright (c) 2017 Sean Barrett -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */ diff --git a/nico/tweaks.nim b/nico/tweaks.nim index c4eec41..711d82f 100644 --- a/nico/tweaks.nim +++ b/nico/tweaks.nim @@ -1,11 +1,9 @@ -import json -import tables +import std/[json, tables, strutils] +import std/os except `/` import nico import nico/console import nico/gui2 import nico/vec -import strutils -import os except `/` type TweakKind = enum diff --git a/nico/utils.nim b/nico/utils.nim index 421393f..c3167e1 100644 --- a/nico/utils.nim +++ b/nico/utils.nim @@ -1,6 +1,5 @@ +import std/[strutils, strscans] import nico -import strutils -import strscans type TextAlign* = enum taLeft @@ -82,7 +81,7 @@ proc richPrintWidthOneLine*(text: string, startChar = 0, endChar = -1): int = if code.startsWith("spr"): var sprId, palA, palB: int var (sw,sh) = spriteSize() - if scanf(code, "spr($i,$i,$i)", sprId, sw, sh) or + if scanf(code, "spr($i,$i,$i)", sprId, sw, sh) or scanf(code, "spr($i)pal($i,$i)", sprId, palA, palB) or scanf(code, "spr($i)", sprId): result += sw diff --git a/nico/vec.nim b/nico/vec.nim index c2a34a6..877459d 100644 --- a/nico/vec.nim +++ b/nico/vec.nim @@ -1,6 +1,4 @@ -import std/math -import std/hashes - +import std/[math, hashes] import nico type diff --git a/tests/nim.cfg b/tests/nim.cfg new file mode 100644 index 0000000..0f840a1 --- /dev/null +++ b/tests/nim.cfg @@ -0,0 +1 @@ +--path:".."