diff --git a/audio/skill/beige3.mp3 b/audio/skill/beige3.mp3 index 703f83ad4..70b89b408 100644 Binary files a/audio/skill/beige3.mp3 and b/audio/skill/beige3.mp3 differ diff --git a/audio/skill/beige4.mp3 b/audio/skill/beige4.mp3 index 70b89b408..f5f592dc0 100644 Binary files a/audio/skill/beige4.mp3 and b/audio/skill/beige4.mp3 differ diff --git a/audio/skill/beige6.mp3 b/audio/skill/beige6.mp3 deleted file mode 100644 index f5f592dc0..000000000 Binary files a/audio/skill/beige6.mp3 and /dev/null differ diff --git a/audio/skill/baonue24.mp3 b/audio/skill/boss_baolin.mp3 similarity index 100% rename from audio/skill/baonue24.mp3 rename to audio/skill/boss_baolin.mp3 diff --git a/audio/skill/boss_baonu1.mp3 b/audio/skill/boss_baonu1.mp3 new file mode 100755 index 000000000..84a0c133a Binary files /dev/null and b/audio/skill/boss_baonu1.mp3 differ diff --git a/audio/skill/boss_baonu2.mp3 b/audio/skill/boss_baonu2.mp3 new file mode 100755 index 000000000..cf23ef558 Binary files /dev/null and b/audio/skill/boss_baonu2.mp3 differ diff --git a/audio/skill/boss_guihan1.mp3 b/audio/skill/boss_guihan1.mp3 new file mode 100755 index 000000000..8458208d4 Binary files /dev/null and b/audio/skill/boss_guihan1.mp3 differ diff --git a/audio/skill/boss_guihan2.mp3 b/audio/skill/boss_guihan2.mp3 new file mode 100755 index 000000000..d843ac393 Binary files /dev/null and b/audio/skill/boss_guihan2.mp3 differ diff --git a/audio/skill/boss_honglian1.mp3 b/audio/skill/boss_honglian1.mp3 new file mode 100755 index 000000000..65bc43cbf Binary files /dev/null and b/audio/skill/boss_honglian1.mp3 differ diff --git a/audio/skill/boss_honglian2.mp3 b/audio/skill/boss_honglian2.mp3 new file mode 100755 index 000000000..8d84a7d9d Binary files /dev/null and b/audio/skill/boss_honglian2.mp3 differ diff --git a/audio/skill/boss_hujia1.mp3 b/audio/skill/boss_hujia1.mp3 new file mode 100644 index 000000000..703f83ad4 Binary files /dev/null and b/audio/skill/boss_hujia1.mp3 differ diff --git a/audio/skill/beige5.mp3 b/audio/skill/boss_hujia2.mp3 similarity index 100% rename from audio/skill/beige5.mp3 rename to audio/skill/boss_hujia2.mp3 diff --git a/audio/skill/boss_jizhi1.mp3 b/audio/skill/boss_jizhi1.mp3 new file mode 100755 index 000000000..b9bd7f2f0 Binary files /dev/null and b/audio/skill/boss_jizhi1.mp3 differ diff --git a/audio/skill/boss_jizhi2.mp3 b/audio/skill/boss_jizhi2.mp3 new file mode 100755 index 000000000..4ae10a53c Binary files /dev/null and b/audio/skill/boss_jizhi2.mp3 differ diff --git a/audio/skill/boss_leiji1.mp3 b/audio/skill/boss_leiji1.mp3 new file mode 100755 index 000000000..522a3545c Binary files /dev/null and b/audio/skill/boss_leiji1.mp3 differ diff --git a/audio/skill/boss_leiji2.mp3 b/audio/skill/boss_leiji2.mp3 new file mode 100755 index 000000000..88bf999f5 Binary files /dev/null and b/audio/skill/boss_leiji2.mp3 differ diff --git a/audio/skill/boss_qiangzheng1.mp3 b/audio/skill/boss_qiangzheng1.mp3 new file mode 100644 index 000000000..33f27a2aa Binary files /dev/null and b/audio/skill/boss_qiangzheng1.mp3 differ diff --git a/audio/skill/baonue23.mp3 b/audio/skill/boss_qiangzheng2.mp3 similarity index 100% rename from audio/skill/baonue23.mp3 rename to audio/skill/boss_qiangzheng2.mp3 diff --git a/audio/skill/boss_shengshou.mp3 b/audio/skill/boss_shengshou.mp3 new file mode 100755 index 000000000..70c7f6fdd Binary files /dev/null and b/audio/skill/boss_shengshou.mp3 differ diff --git a/audio/skill/boss_tianyu.mp3 b/audio/skill/boss_tianyu.mp3 new file mode 100755 index 000000000..303577141 Binary files /dev/null and b/audio/skill/boss_tianyu.mp3 differ diff --git a/audio/skill/boss_xianyin1.mp3 b/audio/skill/boss_xianyin1.mp3 new file mode 100755 index 000000000..9a2871488 Binary files /dev/null and b/audio/skill/boss_xianyin1.mp3 differ diff --git a/audio/skill/boss_xianyin2.mp3 b/audio/skill/boss_xianyin2.mp3 new file mode 100755 index 000000000..7f0f9ed13 Binary files /dev/null and b/audio/skill/boss_xianyin2.mp3 differ diff --git a/audio/skill/fengwu1.mp3 b/audio/skill/fengwu1.mp3 new file mode 100755 index 000000000..030c2de50 Binary files /dev/null and b/audio/skill/fengwu1.mp3 differ diff --git a/audio/skill/fengwu2.mp3 b/audio/skill/fengwu2.mp3 new file mode 100755 index 000000000..f8cf0219b Binary files /dev/null and b/audio/skill/fengwu2.mp3 differ diff --git a/audio/skill/guizhen1.mp3 b/audio/skill/guizhen1.mp3 new file mode 100755 index 000000000..6b670129b Binary files /dev/null and b/audio/skill/guizhen1.mp3 differ diff --git a/audio/skill/guizhen2.mp3 b/audio/skill/guizhen2.mp3 new file mode 100755 index 000000000..9d3f1a7b3 Binary files /dev/null and b/audio/skill/guizhen2.mp3 differ diff --git a/audio/skill/huanhua1.mp3 b/audio/skill/huanhua1.mp3 new file mode 100755 index 000000000..4a196e8ad Binary files /dev/null and b/audio/skill/huanhua1.mp3 differ diff --git a/audio/skill/huanhua2.mp3 b/audio/skill/huanhua2.mp3 new file mode 100755 index 000000000..b7731c547 Binary files /dev/null and b/audio/skill/huanhua2.mp3 differ diff --git a/audio/skill/huashen21.mp3 b/audio/skill/huashen21.mp3 index 4a196e8ad..bd7b33084 100755 Binary files a/audio/skill/huashen21.mp3 and b/audio/skill/huashen21.mp3 differ diff --git a/audio/skill/huashen22.mp3 b/audio/skill/huashen22.mp3 index b7731c547..6485d20a6 100755 Binary files a/audio/skill/huashen22.mp3 and b/audio/skill/huashen22.mp3 differ diff --git a/audio/skill/jiaoxia1.mp3 b/audio/skill/jiaoxia1.mp3 new file mode 100755 index 000000000..75b4404f6 Binary files /dev/null and b/audio/skill/jiaoxia1.mp3 differ diff --git a/audio/skill/jiaoxia2.mp3 b/audio/skill/jiaoxia2.mp3 new file mode 100755 index 000000000..d744754a7 Binary files /dev/null and b/audio/skill/jiaoxia2.mp3 differ diff --git a/audio/skill/jidian1.mp3 b/audio/skill/jidian1.mp3 new file mode 100755 index 000000000..6876b45dc Binary files /dev/null and b/audio/skill/jidian1.mp3 differ diff --git a/audio/skill/jidian2.mp3 b/audio/skill/jidian2.mp3 new file mode 100755 index 000000000..ada348912 Binary files /dev/null and b/audio/skill/jidian2.mp3 differ diff --git a/audio/skill/jueqing1.mp3 b/audio/skill/jueqing1.mp3 old mode 100644 new mode 100755 index 2654c334a..399ec85e7 Binary files a/audio/skill/jueqing1.mp3 and b/audio/skill/jueqing1.mp3 differ diff --git a/audio/skill/jueqing2.mp3 b/audio/skill/jueqing2.mp3 old mode 100644 new mode 100755 index fcecd31c7..4ba9dc149 Binary files a/audio/skill/jueqing2.mp3 and b/audio/skill/jueqing2.mp3 differ diff --git a/audio/skill/lianji.mp3 b/audio/skill/lianji.mp3 new file mode 100755 index 000000000..39b5c225d Binary files /dev/null and b/audio/skill/lianji.mp3 differ diff --git a/audio/skill/lingbo1.mp3 b/audio/skill/lingbo1.mp3 new file mode 100755 index 000000000..d1c021273 Binary files /dev/null and b/audio/skill/lingbo1.mp3 differ diff --git a/audio/skill/lingbo2.mp3 b/audio/skill/lingbo2.mp3 new file mode 100755 index 000000000..4f1b9d928 Binary files /dev/null and b/audio/skill/lingbo2.mp3 differ diff --git a/audio/skill/mazui.mp3 b/audio/skill/mazui.mp3 new file mode 100755 index 000000000..55f3637b7 Binary files /dev/null and b/audio/skill/mazui.mp3 differ diff --git a/audio/skill/qiwu.mp3 b/audio/skill/qiwu.mp3 new file mode 100755 index 000000000..1f5aac095 Binary files /dev/null and b/audio/skill/qiwu.mp3 differ diff --git a/audio/skill/shangshix1.mp3 b/audio/skill/shangshix1.mp3 new file mode 100755 index 000000000..c0161b49b Binary files /dev/null and b/audio/skill/shangshix1.mp3 differ diff --git a/audio/skill/shangshix2.mp3 b/audio/skill/shangshix2.mp3 new file mode 100755 index 000000000..5eb743302 Binary files /dev/null and b/audio/skill/shangshix2.mp3 differ diff --git a/audio/skill/tashui1.mp3 b/audio/skill/tashui1.mp3 new file mode 100755 index 000000000..75b4404f6 Binary files /dev/null and b/audio/skill/tashui1.mp3 differ diff --git a/audio/skill/tashui2.mp3 b/audio/skill/tashui2.mp3 new file mode 100755 index 000000000..d744754a7 Binary files /dev/null and b/audio/skill/tashui2.mp3 differ diff --git a/audio/skill/tiandao.mp3 b/audio/skill/tiandao.mp3 new file mode 100755 index 000000000..bc26c03d2 Binary files /dev/null and b/audio/skill/tiandao.mp3 differ diff --git a/audio/skill/wuqin1.mp3 b/audio/skill/wuqin1.mp3 new file mode 100755 index 000000000..6d32c3dd0 Binary files /dev/null and b/audio/skill/wuqin1.mp3 differ diff --git a/audio/skill/wuqin2.mp3 b/audio/skill/wuqin2.mp3 new file mode 100755 index 000000000..a1bc4b7c7 Binary files /dev/null and b/audio/skill/wuqin2.mp3 differ diff --git a/audio/skill/wuxin1.mp3 b/audio/skill/wuxin1.mp3 new file mode 100755 index 000000000..5916f9654 Binary files /dev/null and b/audio/skill/wuxin1.mp3 differ diff --git a/audio/skill/wuxin2.mp3 b/audio/skill/wuxin2.mp3 new file mode 100755 index 000000000..4e7a4d779 Binary files /dev/null and b/audio/skill/wuxin2.mp3 differ diff --git a/audio/skill/yuehun1.mp3 b/audio/skill/yuehun1.mp3 new file mode 100755 index 000000000..7a4a50a8c Binary files /dev/null and b/audio/skill/yuehun1.mp3 differ diff --git a/audio/skill/yuehun2.mp3 b/audio/skill/yuehun2.mp3 new file mode 100755 index 000000000..23bfcf973 Binary files /dev/null and b/audio/skill/yuehun2.mp3 differ diff --git a/card/extra.js b/card/extra.js index 3ee85c14a..69ee78d42 100755 --- a/card/extra.js +++ b/card/extra.js @@ -62,9 +62,11 @@ card.extra={ if(player.num('h','sha')>1){ if(player.num('e','zhuge')) return 0; if(player.skills.contains('paoxiao')) return 0; - if(player.skills.contains('tanlnin3')) return 0; - if(player.skills.contains('zhaxiang2')) return 0; if(player.skills.contains('fengnu')) return 0; + if(!player.getStat().card.sha){ + if(player.skills.contains('tanlnin3')) return 0; + if(player.skills.contains('zhaxiang2')) return 0; + } } if(shas.length){ for(var i=0;i0) return 1; } } diff --git a/card/standard.js b/card/standard.js index 379f799d4..8dc34bc48 100755 --- a/card/standard.js +++ b/card/standard.js @@ -115,7 +115,12 @@ card.standard={ }, order:3, result:{ - target:-1.5, + target:function(player,target){ + if(player.skills.contains('jiu')&&!target.num('e','baiyin')){ + return -3; + } + return -1.5; + }, }, tag:{ respond:1, @@ -212,7 +217,7 @@ card.standard={ if(nh<=target.hp){ keep=true; } - else if(nh==target.hp+1&&target.hp>=3&&target.num('h','tao')<=1){ + else if(nh==target.hp+1&&target.hp>=2&&target.num('h','tao')<=1){ keep=true; } if(target.hp>=2&&keep&&target.hasFriend()){ @@ -582,6 +587,12 @@ card.standard={ if(game.players[i].ai.shown==0) num++; } if(num>1) return 0; + var nh=target.num('h'); + if(lib.config.mode=='identity'){ + if(target.isZhu&&nh<=2&&target.hp<=1) return -100; + } + if(nh==0) return -2; + if(nh==1) return -1.7 return -1.5; }, }, @@ -635,6 +646,12 @@ card.standard={ if(game.players[i].ai.shown==0) num++; } if(num>1) return 0; + var nh=target.num('h'); + if(lib.config.mode=='identity'){ + if(target.isZhu&&nh<=2&&target.hp<=1) return -100; + } + if(nh==0) return -2; + if(nh==1) return -1.7 return -1.5; }, }, @@ -855,6 +872,13 @@ card.standard={ }, result:{ target:function(player,target){ + var es=target.get('e'); + var nh=target.num('h'); + var noe=(es.length==0); + var noe2=(es.length==1&&es[0].name=='baiyin'&&target.hp-1) return -1; + if(num>-1) return -0.01; if(target.hp<3) num--; - if(target.hp<2) num--; - if(target.hp<1) num--; if(target.isTurnedOver()) num/=2; - return num; + var dist=get.distance(player,target,'absolute'); + if(dist<1) dist=1; + return num/Math.sqrt(dist); } }, tag:{ @@ -1440,6 +1464,14 @@ card.standard={ if(typeof aiii=='number') return aiii; } if(Math.abs(ai.get.attitude(_status.event.player,trigger.player))<3) return 0; + if(trigger.player.skills.contains('guanxing')) return 0; + if(trigger.card.name!='lebu'&&trigger.card.name!='bingliang'){ + if(trigger.player!=_status.event.player){ + return 0; + } + } + var eff=ai.get.effect(trigger.player,trigger.card,trigger.player,player); + if(eff>=0) return 0; return state*ai.get.attitude(_status.event.player,trigger.player); }, source:trigger.player diff --git a/card/swd.js b/card/swd.js index ada93b41e..cf6004bc7 100755 --- a/card/swd.js +++ b/card/swd.js @@ -448,6 +448,12 @@ card.swd={ if(game.players[i].ai.shown==0) num++; } if(num>1) return 0; + var nh=target.num('h'); + if(lib.config.mode=='identity'){ + if(target.isZhu&&nh<=2&&target.hp<=1) return -100; + } + if(nh==0) return -2; + if(nh==1) return -1.7 return -1.5; }, }, @@ -503,6 +509,12 @@ card.swd={ if(game.players[i].ai.shown==0) num++; } if(num>1) return 0; + var nh=target.num('h'); + if(lib.config.mode=='identity'){ + if(target.isZhu&&nh<=2&&target.hp<=1) return -100; + } + if(nh==0) return -2; + if(nh==1) return -1.7 return -1.5; }, }, diff --git a/character/boss.js b/character/boss.js index 21f09df45..ca708ec76 100644 --- a/character/boss.js +++ b/character/boss.js @@ -51,6 +51,9 @@ character.boss={ trigger.untrigger(); trigger.finish(); }, + ai:{ + noh:true, + }, group:'boss_juejing2' }, boss_juejing2:{ @@ -77,7 +80,7 @@ character.boss={ }; "step 1" if(result.bool){ - player.logSkill('diyleiji',result.targets,'thunder'); + player.logSkill('boss_leiji',result.targets,'thunder'); event.target=result.targets[0]; event.target.judge(function(card){ // var suit=get.suit(card); @@ -132,6 +135,7 @@ character.boss={ } }, wuqin:{ + audio:2, trigger:{player:'phaseEnd'}, filter:function(event,player){ return player.num('h')==0; @@ -141,9 +145,11 @@ character.boss={ } }, boss_baolin:{ + audio:true, inherit:'juece', }, boss_qiangzheng:{ + audio:2, trigger:{player:'phaseEnd'}, forced:true, unique:true, @@ -171,6 +177,7 @@ character.boss={ } }, guizhen:{ + audio:2, trigger:{player:'loseEnd'}, frequent:true, filter:function(event,player){ @@ -248,6 +255,7 @@ character.boss={ inherit:'guiji' }, fengwu:{ + audio:2, unique:true, enable:'phaseUse', usable:1, @@ -292,6 +300,7 @@ character.boss={ } }, huanhua:{ + audio:2, trigger:{global:'gameDrawAfter'}, forced:true, unique:true, @@ -356,6 +365,7 @@ character.boss={ } }, jidian:{ + audio:2, trigger:{source:'damageAfter'}, direct:true, unique:true, @@ -385,9 +395,11 @@ character.boss={ } }, tinqin:{ + audio:false, inherit:'manjuan' }, boss_hujia:{ + audio:2, trigger:{player:'phaseEnd'}, direct:true, unique:true, @@ -431,6 +443,7 @@ character.boss={ } }, boss_guihan:{ + audio:2, unique:true, enable:'chooseToUse', mark:true, @@ -565,6 +578,7 @@ character.boss={ } }, boss_shengshou:{ + audio:true, trigger:{player:'useCard'}, frequent:true, unique:true, @@ -583,6 +597,7 @@ character.boss={ }, }, boss_honglian:{ + audio:2, trigger:{player:'phaseEnd'}, forced:true, unique:true, @@ -612,9 +627,11 @@ character.boss={ } }, boss_tianyu:{ + audio:true, inherit:'suoling' }, boss_jizhi:{ + audio:2, trigger:{player:'useCard'}, frequent:true, unique:true, @@ -686,6 +703,7 @@ character.boss={ } }, tashui:{ + audio:2, trigger:{player:['useCard','respondAfter']}, direct:true, unique:true, @@ -721,6 +739,7 @@ character.boss={ trigger:{player:['loseEnd','changeHp']}, forced:true, unique:true, + audio:2, filter:function(event,player){ return player.num('h')<4; }, @@ -739,7 +758,8 @@ character.boss={ return [0,1]; } } - } + }, + noh:true, } }, shangshix2:{ @@ -762,9 +782,11 @@ character.boss={ }, wuxin:{ inherit:'miles_xueyi', - group:'swd_wuxie' + group:'swd_wuxie', + audio:2, }, shenwei:{ + audio:2, unique:true, trigger:{player:'phaseDrawBegin'}, forced:true, @@ -791,6 +813,7 @@ character.boss={ trigger:{player:'changeHp'}, forced:true, priority:100, + audio:2, filter:function(event,player){ return player.hp<=4 }, diff --git a/character/diy.js b/character/diy.js index a16825ea3..c293bda2e 100755 --- a/character/diy.js +++ b/character/diy.js @@ -659,10 +659,10 @@ character.diy={ translate:{ diy_caocao:'曹操', diy_menghuo:'孟获', - diy_huangzhong:'黄忠', - diy_xuhuang:'徐晃', - diy_dianwei:'典韦', - diy_weiyan:'魏延', + diy_huangzhong:'黄汉升', + diy_xuhuang:'徐公明', + diy_dianwei:'新典韦', + diy_weiyan:'魏文长', xicai:'惜才', diyjianxiong:'奸雄', diy_feishi:'费诗', @@ -675,7 +675,7 @@ character.diy={ diy_zhouyu:'周公瑾', diy_lukang:'陆抗', diy_caiwenji:'蔡昭姬', - diy_zhenji:'甄姬', + diy_zhenji:'甄宓', siji:'伺机', ciqiu:'刺酋', ciqiu2:'刺酋', diff --git a/character/extra.js b/character/extra.js index ba9733771..dad164ddd 100755 --- a/character/extra.js +++ b/character/extra.js @@ -170,13 +170,11 @@ character.extra={ }, player:function(card,player){ if(_status.currentPhase!=player) return; - if(card.name=='wuzhong'||card.name=='yiyi'|| - card.name=='yuanjiao'||card.name=='shunshou') return; + if(get.type(card)=='basic'||get.type(card,'trick')=='trick') return; if(player.hp<=2) return; if(!player.skills.contains('jilue')||player.storage.renjie==0){ return [0,0,0,0]; } - } } } diff --git a/character/gujian.js b/character/gujian.js index 7ba59897f..ae4ce30f3 100755 --- a/character/gujian.js +++ b/character/gujian.js @@ -924,6 +924,7 @@ character.gujian={ content:'time' }, ai:{ + noh:true, threaten:0.8, effect:{ target:function(card,player,target){ diff --git a/character/jiange.js b/character/jiange.js index afed3a4b9..0580aaeda 100755 --- a/character/jiange.js +++ b/character/jiange.js @@ -456,6 +456,7 @@ character.jiange={ } }, qiwu:{ + audio:true, trigger:{player:'useCard'}, forced:true, filter:function(event,player){ diff --git a/character/mountain.js b/character/mountain.js index 3fc4019a0..3464948da 100755 --- a/character/mountain.js +++ b/character/mountain.js @@ -806,7 +806,7 @@ character.mountain={ } }, beige:{ - audio:6, + audio:4, trigger:{global:'damageEnd'}, filter:function(event,player){ return (event.card&&event.card.name=='sha'&&event.source&& diff --git a/character/refresh.js b/character/refresh.js index 66524e53d..d1e5bc620 100755 --- a/character/refresh.js +++ b/character/refresh.js @@ -32,7 +32,7 @@ character.refresh={ }, content:function(){ 'step 0' - trigger.player.chooseTarget(function(card,player,target){ + trigger.player.chooseTarget(function(card,playerx,target){ return player.canUse({name:'juedou'},target)&&target!=trigger.player; },'是否发动【利奴】?').ai=function(target){ return ai.get.effect(target,{name:'juedou'},player,trigger.player)-2; @@ -487,7 +487,8 @@ character.refresh={ target:function(card){ if(card.name=='guohe'||card.name=='liuxinghuoyu') return 0.5; } - } + }, + noh:true, } }, retishen:{ @@ -1227,28 +1228,28 @@ character.refresh={ } }, translate:{ - re_zhangliao:'张辽', - re_huangyueying:'黄月英', - re_simayi:'司马懿', - re_xuzhu:'许褚', - re_xiahoudun:'夏侯惇', - re_lvmeng:'吕蒙', - re_zhouyu:'周瑜', - re_luxun:'陆逊', - re_zhaoyun:'赵云', - re_guanyu:'关羽', - re_zhangfei:'张飞', - re_machao:'马超', - re_caocao:'曹操', - re_guojia:'郭嘉', - re_lvbu:'吕布', - re_xushu:'徐庶', - re_huanggai:'黄盖', - re_gongsunzan:'公孙瓒', - re_daqiao:'大乔', - re_ganning:'甘宁', - re_huatuo:'华佗', - re_lidian:'李典', + re_zhangliao:'界张辽', + re_huangyueying:'新黄月英', + re_simayi:'界司马懿', + re_xuzhu:'界许褚', + re_xiahoudun:'界夏侯惇', + re_lvmeng:'界吕蒙', + re_zhouyu:'界周瑜', + re_luxun:'界陆逊', + re_zhaoyun:'界赵云', + re_guanyu:'界关羽', + re_zhangfei:'界张飞', + re_machao:'界马超', + re_caocao:'界曹操', + re_guojia:'界郭嘉', + re_lvbu:'界吕布', + re_xushu:'界徐庶', + re_huanggai:'界黄盖', + re_gongsunzan:'界公孙瓒', + re_daqiao:'界大乔', + re_ganning:'界甘宁', + re_huatuo:'界华佗', + re_lidian:'界李典', qinxue:'勤学', retuxi:'突袭·新', reluoyi:'裸衣·新', diff --git a/character/sp.js b/character/sp.js index d2210049e..36d6b1493 100755 --- a/character/sp.js +++ b/character/sp.js @@ -895,7 +895,7 @@ character.sp={ next.ai=function(card){ return maxval-ai.get.value(card); }; - next.logSkill='manjuan'; + next.logSkill=event.name; event.cards=cards; } "step 2" @@ -3308,12 +3308,12 @@ character.sp={ translate:{ chenlin:'陈琳', yuanshu:'袁术', - re_yuanshu:'袁术', + re_yuanshu:'新袁术', gongsunzan:'公孙瓒', - sp_diaochan:'貂蝉', + sp_diaochan:'sp貂蝉', yangxiu:'杨修', - sp_zhaoyun:'赵云', - jsp_zhaoyun:'赵云', + sp_zhaoyun:'sp赵云', + jsp_zhaoyun:'界sp赵云', caohong:'曹洪', liuxie:'刘协', xiahouba:'夏侯霸', @@ -3328,10 +3328,10 @@ character.sp={ tianfeng:'田丰', sp_pangtong:'庞统', maliang:'马良', - sp_caoren:'曹仁', + sp_caoren:'sp曹仁', yuejin:'乐进', mifuren:'糜夫人', - sp_dongzhuo:'董卓', + sp_dongzhuo:'sp董卓', chendong:'陈武董袭', jiangfei:'蒋琬费祎', jiangqing:'蒋钦', @@ -3344,7 +3344,7 @@ character.sp={ sp_pangde:'庞德', sp_sunshangxiang:'孙尚香', zhugedan:'诸葛诞', - sp_machao:'马超', + sp_machao:'sp马超', sp_jiangwei:'姜维', zhangbao:'张宝', yangxiou:'杨修', @@ -3353,7 +3353,7 @@ character.sp={ zhanglu:'张鲁', wutugu:'兀突骨', mateng:'马腾', - sp_caiwenji:'蔡文姬', + sp_caiwenji:'sp蔡文姬', zhugeguo:'诸葛果', yuhua:'羽化', diff --git a/character/standard.js b/character/standard.js index 4de9fc714..c69d8425c 100755 --- a/character/standard.js +++ b/character/standard.js @@ -806,6 +806,12 @@ character.standard={ }, content:function(){} }, + test:{ + subSkills:{ + t1:{}, + t2:{} + } + }, longdan:{ group:['longdan1','longdan2'] }, @@ -1194,6 +1200,12 @@ character.standard={ target:function(card){ if(card.name=='guohe'||card.name=='liuxinghuoyu') return 0.5; } + }, + noh:true, + skillTagFilter:function(player,tag){ + if(tag=='noh'){ + if(player.num('h')!=1) return false; + } } } }, diff --git a/character/swd.js b/character/swd.js index 9ac65abcd..7e1cb2dfa 100755 --- a/character/swd.js +++ b/character/swd.js @@ -726,7 +726,7 @@ character.swd={ } "step 1" if(result.bool){ - trigger.player.chooseToDiscard({type:'basic'},'入梦:弃置一张基本牌或路过出牌及弃牌阶段').ai=function(card){ + trigger.player.chooseToDiscard({type:'basic'},'入梦:弃置一张基本牌或跳过出牌及弃牌阶段').ai=function(card){ return 5-ai.get.value(card); } } @@ -2586,6 +2586,7 @@ character.swd={ } }, lianji:{ + audio:true, enable:'phaseUse', usable:1, filterTarget:function(card,player,target){ @@ -3063,6 +3064,7 @@ character.swd={ } }, tiandao:{ + audio:true, trigger:{global:'judge'}, direct:true, filter:function(event,player){ @@ -6459,6 +6461,7 @@ character.swd={ } }, swd_xiuluo:{ + audio:2, trigger:{player:'phaseBegin'}, direct:true, filter:function(event,player){ @@ -7568,6 +7571,7 @@ character.swd={ } }, mazui:{ + audio:true, enable:'phaseUse', usable:1, filterCard:{color:'black'}, diff --git a/character/woods.js b/character/woods.js index 6f26d384d..5afe5b0b8 100755 --- a/character/woods.js +++ b/character/woods.js @@ -216,6 +216,7 @@ character.woods={ target:function(card,player,target){ if(get.tag(card,'damage')){ if(player.skills.contains('jueqing')) return [1,-2]; + if(target.hp<=1) return; var hastarget=false; var hasfriend=false; var turnfriend=false; @@ -607,7 +608,7 @@ character.woods={ global:'baonue2' }, baonue2:{ - audio:4, + audio:2, forceaudio:true, trigger:{source:'damageEnd'}, filter:function(event,player){ @@ -671,6 +672,9 @@ character.woods={ order:1, result:{ player:function(player){ + if(lib.config.mode=='identity'&&game.zhu.isZhu&&player.identity=='fan'){ + if(game.zhu.hp==1&&game.zhu.num('h')<=2) return 1; + } var num=0; for(var i=0;i0&&player!=target; + return target.num('he')>0; }, function(target){ return -ai.get.attitude(_status.event.player,target); diff --git a/character/zhuogui.js b/character/zhuogui.js index 8373ee746..7b4d3c6d4 100755 --- a/character/zhuogui.js +++ b/character/zhuogui.js @@ -218,6 +218,7 @@ character.zhuogui={ } }, qiangzheng:{ + audio:2, trigger:{player:'phaseEnd'}, direct:true, forced:true, diff --git a/game/background.js b/game/background.js index 8a944fba4..5b7c36c5f 100755 --- a/game/background.js +++ b/game/background.js @@ -56,6 +56,7 @@ } } window.resetGameTimeout=setTimeout(function(){ + if(window.inSplash) return; if(confirm('游戏似乎未正常载入,是否重置游戏?')){ localStorage.clear(); window.location.reload(); diff --git a/game/config.js b/game/config.js index 04d71603d..4d57efec3 100755 --- a/game/config.js +++ b/game/config.js @@ -210,6 +210,9 @@ window.config={ glow_phase:'yellow', skin:{}, + hiddenModePack:[], + hiddenCharacterPack:[], + hiddenCardPack:[], theme:'woodden', layout:'mobile', @@ -262,6 +265,8 @@ window.config={ bannedcards:[], bannedpile:{}, addedpile:{}, + customCharacterPack:{}, + customCardPack:{}, mode:'identity', mode_config:{ diff --git a/game/game.js b/game/game.js index 197288826..6d0d836cc 100755 --- a/game/game.js +++ b/game/game.js @@ -16,12 +16,15 @@ dieClose:[] }; var lib={ - version:1.63, + version:1.70, changeLog:[ - '折叠手牌', - '触屏拖拽', - '自定义背景', - 'bug修复' + '折叠手牌显示花色', + 'AI改进', + '武将图修改', + 'boss配音', + '隐藏模式、武将、卡牌包', + '开始界面', + '自定义武将' ], configprefix:'noname_0.9_', updates:[], @@ -29,6 +32,11 @@ video:[], arenaReady:[], _onDB:[], + customCharacters:[], + customCards:[], + skilllist:[], + characterPack:{}, + cardPack:{}, onDB:function(func){ if(lib.db){ func(); @@ -37,6 +45,32 @@ lib._onDB.push(func); } }, + setTranslate:function(name){ + if(name.indexOf(':')==-1){ + lib.translate[name]=name; + } + else{ + lib.translate[name]=name.slice(name.indexOf(':')+1); + } + }, + checkCharacterName:function(name){ + if(lib.character[name]){ + if(!lib.customCharacters.contains(name)) return true; + for(var i in lib.config.customCharacterPack){ + if(lib.config.customCharacterPack[i].character.contains(name)) return true; + } + } + return false; + }, + checkSkillName:function(name){ + if(lib.skill[name]){ + if(!lib.skill[name].createInfo) return true; + for(var i in lib.config.customCharacterPack){ + if(lib.config.customCharacterPack[i].skill.contains(name)) return true; + } + } + return false; + }, listenEnd:function(node){ if(!node._listeningEnd){ node._listeningEnd=true; @@ -160,6 +194,10 @@ auto:'切换托管' } }, + show_splash:{ + name:'显示开始界面', + init:false, + }, game_speed:{ name:'游戏速度', init:'mid', @@ -1164,10 +1202,33 @@ }, clear:true }, + reset_hiddenpack:{ + name:'重置隐藏扩展包', + onclick:function(){ + if(this.innerHTML!='已重置'){ + this.innerHTML='已重置' + game.saveConfig('hiddenModePack',[]); + game.saveConfig('hiddenCharacterPack',[]); + game.saveConfig('hiddenCardPack',[]); + var that=this; + setTimeout(function(){ + that.innerHTML='重置隐藏扩展包'; + },500); + } + }, + clear:true + }, reset_tutorial:{ name:'重置新手向导', onclick:function(){ - game.saveConfig('new_tutorial',false); + if(this.innerHTML!='已重置'){ + this.innerHTML='已重置' + game.saveConfig('new_tutorial',false); + var that=this; + setTimeout(function(){ + that.innerHTML='重置新手向导'; + },500); + } }, clear:true }, @@ -2302,20 +2363,26 @@ var charlist=['standard','wind','fire','woods','mountain','guozhan','sp','yijiang','extra','refresh']; for(i in character.pack){ - lib.config.all.characters.push(i); - lib.translate[i+'_character_config']=character.pack[i]; + if(lib.config.hiddenCharacterPack.indexOf(i)==-1){ + lib.config.all.characters.push(i); + lib.translate[i+'_character_config']=character.pack[i]; + } } for(i in card.pack){ - lib.config.all.cards.push(i); - lib.translate[i+'_card_config']=card.pack[i]; + if(lib.config.hiddenCardPack.indexOf(i)==-1){ + lib.config.all.cards.push(i); + lib.translate[i+'_card_config']=card.pack[i]; + } } for(i in play.pack){ lib.config.all.plays.push(i); lib.translate[i+'_play_config']=play.pack[i]; } for(i in mode.pack){ - lib.config.all.mode.push(i); - lib.translate[i]=mode.pack[i]; + if(lib.config.hiddenModePack.indexOf(i)==-1){ + lib.config.all.mode.push(i); + lib.translate[i]=mode.pack[i]; + } } if(background&&background.pack){ for(i in background.pack){ @@ -2343,7 +2410,13 @@ } delete lib.help2; - lib.init.js('mode',lib.config.mode); + if(localStorage.getItem(lib.configprefix+'playbackmode')){ + lib.init.js('mode',lib.config.mode); + } + else if((localStorage.getItem(lib.configprefix+'directstart')||!lib.config.show_splash) + &&lib.config.all.mode.indexOf(lib.config.mode)!=-1){ + lib.init.js('mode',lib.config.mode); + } lib.init.js('card',lib.config.all.cards); lib.init.js('character',lib.config.all.characters); lib.init.js('play',lib.config.plays); @@ -2386,7 +2459,7 @@ } if(window.indexedDB){ - var request = window.indexedDB.open(lib.configprefix+'data', 2); + var request = window.indexedDB.open(lib.configprefix+'data',3); request.onupgradeneeded=function(e){ var db=e.target.result; if(!db.objectStoreNames.contains('video')){ @@ -2407,9 +2480,6 @@ if(!db.objectStoreNames.contains('skill')){ db.createObjectStore('skill'); } - if(!db.objectStoreNames.contains('translate')){ - db.createObjectStore('translate'); - } }; request.onsuccess=function(e){ var db=e.target.result; @@ -2417,6 +2487,44 @@ for(var i=0;i'; } - if(character2){ + if(character2&&lib.character[character2]){ var info2=lib.character[character2]; this.classList.add('fullskin2'); this.node.avatar2.setBackground(character2,'character'); @@ -7566,7 +7702,7 @@ this.node.info.innerHTML=lib.card[card[2]].modinfo; } else{ - this.node.info.innerHTML=get.translation(card[0])+' '+card[1]; + this.node.info.innerHTML=get.translation(card[0])+' '+card[1]; } if(lib.card[card[2]].addinfo){ this.node.addinfo=ui.create.div('.addinfo',this); @@ -8258,7 +8394,7 @@ ghujia:{ intro:{ content:function(content,player){ - return '已有'+get.cnNumber(player.hujia)+'点护甲值'; + return '已有'+get.cnNumber(player.hujia)+'点护甲值

每点护甲可以抵挡一点伤害

'; } } }, @@ -8619,6 +8755,52 @@ ui.backgroundMusic.src='audio/background/'+music+'.mp3'; } }, + import:function(type,obj){ + if(type=='character'){ + if(lib.config.customCharacterPack[obj.name]){ + alert('武将包已存在'); + return; + } + var pack={ + name:obj.name, + character:[], + skill:[], + }; + for(var i in obj.character){ + if(lib.checkCharacterName(i)){ + alert('武将名重复:'+i); + continue; + } + game.putDB('character',i,obj.character[i]); + lib.character[i]=obj.character[i]; + lib.customCharacters.add(i); + pack.character.push(i); + lib.setTranslate(i); + } + for(var i in obj.skill){ + if(lib.checkSkillName(i)){ + alert('技能名重复:'+i); + continue; + } + var info=obj.skill[i]; + try{ + eval('lib.skill["'+info.name+'"]={'+info.content+'}'); + } + catch(e){ + console.log(e); + lib.skill[info.name]={}; + } + lib.skill[info.name].createInfo=info; + lib.setTranslate(i); + lib.translate[info.name+'_info']=info.description; + game.putDB('skill',info.name,info); + pack.skill.push(i); + } + lib.config.customCharacterPack[obj.name]=pack; + game.saveConfig('customCharacterPack',lib.config.customCharacterPack); + } + game.importedPack=obj; + }, export:function(textToWrite,name){ var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'}); var fileNameToSaveAs = name||'noname'; @@ -8630,6 +8812,59 @@ downloadLink.click(); }, + exportCharacters:function(packname,list){ + var zipReady=function(){ + var zip=new JSZip(); + var imageLoaded=0; + var character={ + name:packname||'noname', + character:{}, + skill:{}, + }; + var load=function(img){ + var blob = zip.generate({type:"blob"}); + var fileNameToSaveAs = packname||'noname'; + + var downloadLink = document.createElement("a"); + downloadLink.download = fileNameToSaveAs; + downloadLink.innerHTML = "Download File"; + downloadLink.href = window.URL.createObjectURL(blob); + + downloadLink.click(); + }; + for(var i=0;i=0;i--){ - // if(list[i]){ - // list[i].animate('start'); - // node.parentNode.parentNode.insertBefore(list[i],node.parentNode.nextSibling); - // } - // } - // node.clicked=true; - // setTimeout(function(){ - // node.clicked=false; - // },600); - // } - // - // - // var newgame=[]; - // newgame._configstr='newgame'; - // folditems.push(newgame); - // ui.config.appendChild(ui.create.line2('新游戏',function(){ - // if(this.clicked) return; - // if(lib.config.newgame){ - // game.saveConfig('newgame',false); - // fold(newgame); - // } - // else{ - // game.saveConfig('newgame',true); - // unfold(this,newgame); - // } - // - // })); - // var span1='
-
'; - // var span2='
·
'; - // var clickmode=function(){ - // game.saveConfig('mode',this.parentNode.link); - // game.reload(); - // }; - // for(var i=0;i>',page,function(){ if(expanded){ @@ -13554,6 +13062,23 @@ page.appendChild(hiddenNodes[k]); } } + else{ + hasexpand=false; + } + var hidemode=ui.create.div('.config.more','隐藏此模式',page,function(){ + if(this.innerHTML=='隐藏此模式'){ + this.innerHTML='此模式将在重启后隐藏'; + lib.config.hiddenModePack.add(mode); + } + else{ + this.innerHTML='隐藏此模式'; + lib.config.hiddenModePack.remove(mode); + } + game.saveConfig('hiddenModePack',lib.config.hiddenModePack); + }); + if(hasexpand){ + hidemode.classList.add('auto-hide'); + } if(info.config.update){ info.config.update(config,map); } @@ -13767,6 +13292,7 @@ } } catch(e){ + console.log(e); alert('导入失败'); return; } @@ -13851,12 +13377,13 @@ var clickMode=function(){ var active=this.parentNode.querySelector('.active'); - if(active===this){ - return; + if(active){ + if(active===this){ + return; + } + active.classList.remove('active'); + active.link.remove(); } - active.classList.remove('active'); - active.link.remove(); - active=this; this.classList.add('active'); rightPane.appendChild(this.link); }; @@ -13866,6 +13393,7 @@ if(node.link){ if(node.mode.indexOf('mode_')==0) continue; if(node.mode=='custom') continue; + if(lib.config.customCharacterPack[node.mode]) continue; if(lib.config.characters.contains(node.mode)){ node.classList.remove('off'); node.link.firstChild.classList.add('on'); @@ -13889,10 +13417,13 @@ updateNodes(); }; - var createModeConfig=function(mode,position){ + var createModeConfig=function(mode,position,position2){ var info=lib.characterPack[mode]; var page=ui.create.div(''); var node=ui.create.div('.menubutton.large',lib.translate[mode+'_character_config'],position,clickMode); + if(position2){ + position.insertBefore(node,position2); + } node.link=page; node.mode=mode; var list=[]; @@ -13905,7 +13436,7 @@ init:lib.config.characters.contains(mode), onclick:togglePack }); - if(mode.indexOf('mode_')!=0){ + if(mode.indexOf('mode_')!=0&&!lib.config.customCharacterPack[mode]){ page.appendChild(cfgnode); } var banCharacter=function(){ @@ -13943,6 +13474,45 @@ } } page.classList.add('menu-buttons'); + if(lib.config.customCharacterPack[mode]){ + ui.create.div('.config.more','删除武将包',page,function(){ + if(this.innerHTML=='删除武将包'){ + this.innerHTML='确认删除'; + var that=this; + setTimeout(function(){ + that.innerHTML='删除武将包'; + },1000); + } + else{ + var pack=lib.config.customCharacterPack[mode]; + delete lib.config.customCharacterPack[mode]; + game.saveConfig('customCharacterPack',lib.config.customCharacterPack); + page.remove(); + node.remove(); + for(var i=0;i>',page,function(){ + var currentEditing=null; + var packExporting=false; + + var clickButton=function(){ + if(packExporting){ + this.classList.toggle('selected'); + return; + } + resetImport(); + resetEditor(); + if(currentEditing==this){ + currentEditing=null; + return; + } + else{ + currentEditing=this; + } + toggle.classList.add('on'); + newCharacter.style.display=''; + fakeme.classList.add('inited'); + delete fakeme.image; + fakeme.setBackground(this.link,'character'); + newCharacter.querySelector('.new_name').value=this.link; + var info=lib.character[this.link]; + newCharacter.querySelector('.new_hp').value=info[2]; + sexes.value=info[0]; + groups.value=info[1]; + + var skills=info[3]; + for(var i=0;i>',page,function(){ this.classList.toggle('on'); + if(this.classList.contains('on')){ + importCharacter.style.display=''; + resetEditor(); + resetExport(); + currentEditing=null; + } + else{ + importCharacter.style.display='none'; + } + }); + var resetImport=function(){ + importCharacter.style.display='none'; + toggle3.classList.remove('on') + } + importCharacter=ui.create.div('.new_character.export.import',page); + importCharacter.style.display='none'; + ui.create.div('','',importCharacter); + importCharacter.firstChild.lastChild.onclick=function(){ + var fileToLoad=this.previousSibling.files[0]; + if(fileToLoad){ + var zipReady=function(){ + var fileReader = new FileReader(); + fileReader.onload = function(fileLoadedEvent) + { + var data = fileLoadedEvent.target.result; + var zip=new JSZip(); + zip.load(data); + var str=zip.file('pack.js').asText(); + try{ + eval(str); + if(!game.importedPack) throw('err'); + for(var i in game.importedPack.character){ + var buttons=page.querySelectorAll('.button.character'); + for(var j=0;j>',page,function(){ + this.classList.toggle('on'); + if(this.classList.contains('on')){ + exportCharacter.style.display=''; + resetEditor(); + resetImport(); + currentEditing=null; + packExporting=true; + } + else{ + exportCharacter.style.display='none'; + packExporting=false; + } + }); + var resetExport=function(){ + packExporting=false; + exportCharacter.style.display='none'; + toggle2.classList.remove('on'); + var selected=page.querySelectorAll('.button.character.selected'); + var list=[]; + for(var i=0;i',exportCharacter); + exportCharacter.firstChild.lastChild.onclick=function(){ + var name=this.previousSibling.value; + var selected=page.querySelectorAll('.button.character.selected'); + var list=[]; + var list2=[]; + for(var i=0;i>',page,function(){ + this.classList.toggle('on'); + if(this.classList.contains('on')){ + newCharacter.style.display=''; + resetExport(); + resetImport(); + } + else{ + newCharacter.style.display='none'; + } + }); + var resetEditor=function(){ + toggle.classList.remove('on'); + newCharacter.style.display='none'; + fakeme.classList.remove('inited'); + delete fakeme.image; + fakeme.style.backgroundImage=''; + var inputs=newCharacter.querySelectorAll('input'); + for(var i=0;i',newCharacter).style.paddingTop='10px'; + ui.create.div('.indent','体力:',newCharacter).style.paddingTop='10px'; + var sexes=ui.create.selectlist([ + ['male','男'], + ['female','女'], + ['none','无'], + ],null,ui.create.div('.indent','性别:',newCharacter)); + var groups=ui.create.selectlist([ + ['wei','魏'], + ['shu','蜀'], + ['wu','吴'], + ['qun','群'], + ],null,ui.create.div('.indent','势力:',newCharacter)); + var addSkill=ui.create.div('.add_skill','添加技能
',newCharacter); + var list=[]; + for(var i in lib.character){ + if(lib.character[i][3].length); + list.push([i,lib.translate[i]]); + } + list.sort(function(a,b){ + a=a[0];b=b[0]; + var aa=a,bb=b; + if(aa.indexOf('_')!=-1){ + aa=aa.slice(aa.indexOf('_')+1); + } + if(bb.indexOf('_')!=-1){ + bb=bb.slice(bb.indexOf('_')+1); + } + if(aa!=bb){ + return aa>bb?1:-1; + } + return a>b?1:-1; + }); + var list2=[]; + var skills=lib.character[list[0][0]][3]; + for(var i=0;i创建技能...
',newCharacter); + createSkill.firstChild.listen(function(){ + createSkill.lastChild.classList.toggle('hidden'); + if(createSkill.lastChild.classList.contains('hidden')){ + this.innerHTML='创建技能...'; + skillList.style.top=''; + } + else{ + this.innerHTML='创建技能'; + skillList.style.top='410px'; + } + }); + var newSkill=document.createElement('textarea'); + createSkill.lastChild.appendChild(newSkill); + createSkill.lastChild.innerHTML+='
'; + ui.create.div('','技能名称:',createSkill.lastChild); + createSkill.lastChild.innerHTML+='
'; + ui.create.div('','技能描述:
',createSkill.lastChild); + createSkill.lastChild.lastChild.lastChild.style.marginTop='5px'; + createSkill.lastChild.lastChild.lastChild.onclick=function(){ + var node; + var name=createSkill.lastChild.querySelector('.skillname').value; + var description=createSkill.lastChild.querySelector('.skilldescription').value; + var content=createSkill.lastChild.querySelector('textarea').value; + if(!name||!description) return; + if(lib.checkSkillName(name)){ + alert('技能名重复'); + return; + } + for(var i=0;i5){ delete _status.tempunpopup; @@ -16010,6 +16079,7 @@ } }, windowmousedown:function(e){ + if(window.inSplash) return; if(e.button==2) return; _status.mousedown=true; var dialogs=ui.window.querySelectorAll('#window>.dialog.popped:not(.static)'); @@ -16102,6 +16172,7 @@ } }, windowmouseup:function(e){ + if(window.inSplash) return; if(_status.draggingdialog){ var ddialog=_status.draggingdialog; if(ddialog._dragorigin&&ddialog._dragtransform){ @@ -16210,7 +16281,9 @@ } }, hoverplayer:function(e){ - return get.nodeintro(this,true); + var node=get.nodeintro(this,true); + node.style.zIndex=21; + return node; }, longpressdown:function(e){ if(_status.longpressed) return; @@ -17467,6 +17540,7 @@ return false; }, right:function(){ + if(window.inSplash) return false; if(lib.config.touchscreen) return; if(_status.noright){ _status.noright=false; @@ -17565,7 +17639,7 @@ hs2.push(ui.handcards2Container.firstChild.childNodes[i]); } } - var offset1; + var offset1,offset12=0; if(!lib.config.fold_card){ offset1=112; ui.handcards1Container.classList.add('scrollh'); @@ -17580,15 +17654,26 @@ ui.handcards1Container.classList.remove('scrollh'); } } + if(offset1<100){ + offset12=100-offset1; + } for(var i=0;i40){ + offset12=90-hs1[i].node.info.offsetWidth; + hs1[i].node.name.style.transform='translateY(17px)'; + } + else{ + hs1[i].node.name.style.transform=''; + } + hs1[i].node.info.style.transform='translateX(-'+offset12+'px)'; } ui.handcards1Container.firstChild.style.width=(offset1*(hs1.length-1)+118)+'px'; - var offset2; + var offset2,offset22=0; if(!lib.config.fold_card){ offset2=112; ui.handcards2Container.classList.add('scrollh'); @@ -17603,11 +17688,22 @@ ui.handcards2Container.classList.remove('scrollh'); } } + if(offset2<100){ + offset22=100-offset2; + } for(var i=0;i40){ + offset22=90-hs2[i].node.info.offsetWidth; + hs2[i].node.name.style.transform='translateY(17px)'; + } + else{ + hs2[i].node.name.style.transform=''; + } + hs2[i].node.info.style.transform='translateX(-'+offset22+'px)'; } ui.handcards2Container.firstChild.style.width=(offset2*(hs2.length-1)+118)+'px'; }, @@ -19345,7 +19441,14 @@ ext=ext||'.jpg'; subfolder=subfolder||'default' if(type){ - if(type=='character'&&lib.config.skin[name]){ + if(type=='character'&&lib.customCharacters.contains(name)){ + src=""; + var node=this; + game.getDB('image','character:'+name,function(src){ + node.style.backgroundImage="url('"+src+"')"; + }); + } + else if(type=='character'&&lib.config.skin[name]){ src='image/skin/'+name+'/'+lib.config.skin[name]+ext; } else{ @@ -19811,7 +19914,6 @@ } ui.background=document.querySelector('.background.static'); ui.background.classList.remove('static'); - ui.dynamicBackground=document.querySelector('.background.dynamic'); lib.onDB(function(){ if(lib.config.image_background=='custom'){ @@ -19828,262 +19930,285 @@ }); } }); - var i,j,k; - for(i in mode[lib.config.mode].element){ - if(!lib.element[i]) lib.element[i]=[]; - for(j in mode[lib.config.mode].element[i]){ - if(j=='init'){ - if(!lib.element[i].inits) lib.element[i].inits=[]; - lib.element[i].inits.push(lib.init.eval(mode[lib.config.mode].element[i][j])); + + var proceed=function(){ + var i,j,k; + for(i in mode[lib.config.mode].element){ + if(!lib.element[i]) lib.element[i]=[]; + for(j in mode[lib.config.mode].element[i]){ + if(j=='init'){ + if(!lib.element[i].inits) lib.element[i].inits=[]; + lib.element[i].inits.push(lib.init.eval(mode[lib.config.mode].element[i][j])); + } + else{ + lib.element[i][j]=lib.init.eval(mode[lib.config.mode].element[i][j]); + } + } + } + for(i in mode[lib.config.mode].ai){ + if(typeof mode[lib.config.mode].ai[i]=='object'){ + if(ai[i]==undefined) ai[i]={}; + for(j in mode[lib.config.mode].ai[i]){ + ai[i][j]=lib.init.eval(mode[lib.config.mode].ai[i][j]); + } } else{ - lib.element[i][j]=lib.init.eval(mode[lib.config.mode].element[i][j]); + ai[i]=lib.init.eval(mode[lib.config.mode].ai[i]); } } - } - for(i in mode[lib.config.mode].ai){ - if(typeof mode[lib.config.mode].ai[i]=='object'){ - if(ai[i]==undefined) ai[i]={}; - for(j in mode[lib.config.mode].ai[i]){ - ai[i][j]=lib.init.eval(mode[lib.config.mode].ai[i][j]); - } - } - else{ - ai[i]=lib.init.eval(mode[lib.config.mode].ai[i]); - } - } - for(i in mode[lib.config.mode].ui){ - if(typeof mode[lib.config.mode].ui[i]=='object'){ - if(ui[i]==undefined) ui[i]={}; - for(j in mode[lib.config.mode].ui[i]){ - ui[i][j]=lib.init.eval(mode[lib.config.mode].ui[i][j]); - } - } - else{ - ui[i]=lib.init.eval(mode[lib.config.mode].ui[i]); - } - } - for(i in mode[lib.config.mode].game){ - game[i]=lib.init.eval(mode[lib.config.mode].game[i]); - } - for(i in mode[lib.config.mode].get){ - get[i]=lib.init.eval(mode[lib.config.mode].get[i]); - } - lib.config.current_mode=mode[lib.config.mode].config||[]; - lib.config.mode_choice=mode[lib.config.mode].config; - lib.rank=window.characterRank; - delete window.characterRank; - for(i in mode[lib.config.mode]){ - if(i=='element') continue; - if(i=='game') continue; - if(i=='ai') continue; - if(i=='ui') continue; - if(i=='get') continue; - if(i=='config') continue; - if(lib[i]==undefined) lib[i]=(get.objtype(mode[lib.config.mode][i])=='array')?[]:{}; - for(j in mode[lib.config.mode][i]){ - lib[i][j]=lib.init.eval(mode[lib.config.mode][i][j]); - } - } - lib.skilllist=[]; - if(!lib.characterPack) lib.characterPack={}; - for(i in character){ - if(character[i].character){ - lib.characterPack[i]=character[i].character - } - if(character[i].forbid&&character[i].forbid.contains(lib.config.mode)) continue; - if(character[i].mode&&character[i].mode.contains(lib.config.mode)==false) continue; - for(j in character[i]){ - if(j=='mode'||j=='forbid') continue; - if(j=='character'&&!lib.config.characters.contains(i)){ - if(lib.config.mode=='chess'&&get.config('chess_mode')=='leader'){ - for(k in character[i][j]){ - lib.hiddenCharacters.push(k); - } - } - else if(lib.config.mode!='boss'||i!='boss'){ - continue; + for(i in mode[lib.config.mode].ui){ + if(typeof mode[lib.config.mode].ui[i]=='object'){ + if(ui[i]==undefined) ui[i]={}; + for(j in mode[lib.config.mode].ui[i]){ + ui[i][j]=lib.init.eval(mode[lib.config.mode].ui[i][j]); } } - for(k in character[i][j]){ - if(j=='character'){ - if(!character[i][j][k][4]){ - character[i][j][k][4]=[]; - } - if(character[i][j][k][4].contains('boss')|| - character[i][j][k][4].contains('hiddenboss')){ - lib.config.forbidai.add(k); - } - // if(lib.config.only_fullskin&&lib.isNewLayout()&&lib.config.mode!='chess'){ - // if(!character[i][j][k][4].contains('fullskin')&&!character[i][j][k][4].contains('minskin')){ - // continue; - // } - // } - if(lib.config.banned.contains(k)){ - if(lib.config.mode=='chess'&&get.config('chess_mode')=='leader'){ + else{ + ui[i]=lib.init.eval(mode[lib.config.mode].ui[i]); + } + } + for(i in mode[lib.config.mode].game){ + game[i]=lib.init.eval(mode[lib.config.mode].game[i]); + } + for(i in mode[lib.config.mode].get){ + get[i]=lib.init.eval(mode[lib.config.mode].get[i]); + } + lib.config.current_mode=mode[lib.config.mode].config||[]; + lib.config.mode_choice=mode[lib.config.mode].config; + + lib.rank=window.characterRank; + delete window.characterRank; + for(i in mode[lib.config.mode]){ + if(i=='element') continue; + if(i=='game') continue; + if(i=='ai') continue; + if(i=='ui') continue; + if(i=='get') continue; + if(i=='config') continue; + if(lib[i]==undefined) lib[i]=(get.objtype(mode[lib.config.mode][i])=='array')?[]:{}; + for(j in mode[lib.config.mode][i]){ + lib[i][j]=lib.init.eval(mode[lib.config.mode][i][j]); + } + } + for(i in character){ + if(character[i].character){ + lib.characterPack[i]=character[i].character + } + if(character[i].forbid&&character[i].forbid.contains(lib.config.mode)) continue; + if(character[i].mode&&character[i].mode.contains(lib.config.mode)==false) continue; + for(j in character[i]){ + if(j=='mode'||j=='forbid') continue; + if(j=='character'&&!lib.config.characters.contains(i)){ + if(lib.config.mode=='chess'&&get.config('chess_mode')=='leader'){ + for(k in character[i][j]){ lib.hiddenCharacters.push(k); } - else{ - continue; + } + else if(lib.config.mode!='boss'||i!='boss'){ + continue; + } + } + for(k in character[i][j]){ + if(j=='character'){ + if(!character[i][j][k][4]){ + character[i][j][k][4]=[]; + } + if(character[i][j][k][4].contains('boss')|| + character[i][j][k][4].contains('hiddenboss')){ + lib.config.forbidai.add(k); + } + if(lib.config.banned.contains(k)){ + if(lib.config.mode=='chess'&&get.config('chess_mode')=='leader'){ + lib.hiddenCharacters.push(k); + } + else{ + continue; + } + } + for(var l=0;l + +(c) 2009-2014 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/master/LICENSE +*/ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.JSZip=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } + else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); + + } + + return output; +}; + +// public method for decoding +exports.decode = function(input, utf8) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + } + + return output; + +}; + +},{}],2:[function(_dereq_,module,exports){ +'use strict'; +function CompressedObject() { + this.compressedSize = 0; + this.uncompressedSize = 0; + this.crc32 = 0; + this.compressionMethod = null; + this.compressedContent = null; +} + +CompressedObject.prototype = { + /** + * Return the decompressed content in an unspecified format. + * The format will depend on the decompressor. + * @return {Object} the decompressed content. + */ + getContent: function() { + return null; // see implementation + }, + /** + * Return the compressed content in an unspecified format. + * The format will depend on the compressed conten source. + * @return {Object} the compressed content. + */ + getCompressedContent: function() { + return null; // see implementation + } +}; +module.exports = CompressedObject; + +},{}],3:[function(_dereq_,module,exports){ +'use strict'; +exports.STORE = { + magic: "\x00\x00", + compress: function(content, compressionOptions) { + return content; // no compression + }, + uncompress: function(content) { + return content; // no compression + }, + compressInputType: null, + uncompressInputType: null +}; +exports.DEFLATE = _dereq_('./flate'); + +},{"./flate":8}],4:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('./utils'); + +var table = [ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +]; + +/** + * + * Javascript crc32 + * http://www.webtoolkit.info/ + * + */ +module.exports = function crc32(input, crc) { + if (typeof input === "undefined" || !input.length) { + return 0; + } + + var isArray = utils.getTypeOf(input) !== "string"; + + if (typeof(crc) == "undefined") { + crc = 0; + } + var x = 0; + var y = 0; + var b = 0; + + crc = crc ^ (-1); + for (var i = 0, iTop = input.length; i < iTop; i++) { + b = isArray ? input[i] : input.charCodeAt(i); + y = (crc ^ b) & 0xFF; + x = table[y]; + crc = (crc >>> 8) ^ x; + } + + return crc ^ (-1); +}; +// vim: set shiftwidth=4 softtabstop=4: + +},{"./utils":21}],5:[function(_dereq_,module,exports){ +'use strict'; +var utils = _dereq_('./utils'); + +function DataReader(data) { + this.data = null; // type : see implementation + this.length = 0; + this.index = 0; +} +DataReader.prototype = { + /** + * Check that the offset will not go too far. + * @param {string} offset the additional offset to check. + * @throws {Error} an Error if the offset is out of bounds. + */ + checkOffset: function(offset) { + this.checkIndex(this.index + offset); + }, + /** + * Check that the specifed index will not be too far. + * @param {string} newIndex the index to check. + * @throws {Error} an Error if the index is out of bounds. + */ + checkIndex: function(newIndex) { + if (this.length < newIndex || newIndex < 0) { + throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); + } + }, + /** + * Change the index. + * @param {number} newIndex The new index. + * @throws {Error} if the new index is out of the data. + */ + setIndex: function(newIndex) { + this.checkIndex(newIndex); + this.index = newIndex; + }, + /** + * Skip the next n bytes. + * @param {number} n the number of bytes to skip. + * @throws {Error} if the new index is out of the data. + */ + skip: function(n) { + this.setIndex(this.index + n); + }, + /** + * Get the byte at the specified index. + * @param {number} i the index to use. + * @return {number} a byte. + */ + byteAt: function(i) { + // see implementations + }, + /** + * Get the next number with a given byte size. + * @param {number} size the number of bytes to read. + * @return {number} the corresponding number. + */ + readInt: function(size) { + var result = 0, + i; + this.checkOffset(size); + for (i = this.index + size - 1; i >= this.index; i--) { + result = (result << 8) + this.byteAt(i); + } + this.index += size; + return result; + }, + /** + * Get the next string with a given byte size. + * @param {number} size the number of bytes to read. + * @return {string} the corresponding string. + */ + readString: function(size) { + return utils.transformTo("string", this.readData(size)); + }, + /** + * Get raw data without conversion, bytes. + * @param {number} size the number of bytes to read. + * @return {Object} the raw data, implementation specific. + */ + readData: function(size) { + // see implementations + }, + /** + * Find the last occurence of a zip signature (4 bytes). + * @param {string} sig the signature to find. + * @return {number} the index of the last occurence, -1 if not found. + */ + lastIndexOfSignature: function(sig) { + // see implementations + }, + /** + * Get the next date. + * @return {Date} the date. + */ + readDate: function() { + var dostime = this.readInt(4); + return new Date( + ((dostime >> 25) & 0x7f) + 1980, // year + ((dostime >> 21) & 0x0f) - 1, // month + (dostime >> 16) & 0x1f, // day + (dostime >> 11) & 0x1f, // hour + (dostime >> 5) & 0x3f, // minute + (dostime & 0x1f) << 1); // second + } +}; +module.exports = DataReader; + +},{"./utils":21}],6:[function(_dereq_,module,exports){ +'use strict'; +exports.base64 = false; +exports.binary = false; +exports.dir = false; +exports.createFolders = false; +exports.date = null; +exports.compression = null; +exports.compressionOptions = null; +exports.comment = null; +exports.unixPermissions = null; +exports.dosPermissions = null; + +},{}],7:[function(_dereq_,module,exports){ +'use strict'; +var utils = _dereq_('./utils'); + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2binary = function(str) { + return utils.string2binary(str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2Uint8Array = function(str) { + return utils.transformTo("uint8array", str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.uint8Array2String = function(array) { + return utils.transformTo("string", array); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2Blob = function(str) { + var buffer = utils.transformTo("arraybuffer", str); + return utils.arrayBuffer2Blob(buffer); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.arrayBuffer2Blob = function(buffer) { + return utils.arrayBuffer2Blob(buffer); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.transformTo = function(outputType, input) { + return utils.transformTo(outputType, input); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.getTypeOf = function(input) { + return utils.getTypeOf(input); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.checkSupport = function(type) { + return utils.checkSupport(type); +}; + +/** + * @deprecated + * This value will be removed in a future version without replacement. + */ +exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS; + +/** + * @deprecated + * This value will be removed in a future version without replacement. + */ +exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS; + + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.pretty = function(str) { + return utils.pretty(str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.findCompression = function(compressionMethod) { + return utils.findCompression(compressionMethod); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.isRegExp = function (object) { + return utils.isRegExp(object); +}; + + +},{"./utils":21}],8:[function(_dereq_,module,exports){ +'use strict'; +var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); + +var pako = _dereq_("pako"); +exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; +exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; + +exports.magic = "\x08\x00"; +exports.compress = function(input, compressionOptions) { + return pako.deflateRaw(input, { + level : compressionOptions.level || -1 // default compression + }); +}; +exports.uncompress = function(input) { + return pako.inflateRaw(input); +}; + +},{"pako":24}],9:[function(_dereq_,module,exports){ +'use strict'; + +var base64 = _dereq_('./base64'); + +/** +Usage: + zip = new JSZip(); + zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing"); + zip.folder("images").file("smile.gif", base64Data, {base64: true}); + zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); + zip.remove("tempfile"); + + base64zip = zip.generate(); + +**/ + +/** + * Representation a of zip file in js + * @constructor + * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). + * @param {Object=} options the options for creating this objects (optional). + */ +function JSZip(data, options) { + // if this constructor is used without `new`, it adds `new` before itself: + if(!(this instanceof JSZip)) return new JSZip(data, options); + + // object containing the files : + // { + // "folder/" : {...}, + // "folder/data.txt" : {...} + // } + this.files = {}; + + this.comment = null; + + // Where we are in the hierarchy + this.root = ""; + if (data) { + this.load(data, options); + } + this.clone = function() { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }; +} +JSZip.prototype = _dereq_('./object'); +JSZip.prototype.load = _dereq_('./load'); +JSZip.support = _dereq_('./support'); +JSZip.defaults = _dereq_('./defaults'); + +/** + * @deprecated + * This namespace will be removed in a future version without replacement. + */ +JSZip.utils = _dereq_('./deprecatedPublicUtils'); + +JSZip.base64 = { + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + encode : function(input) { + return base64.encode(input); + }, + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + decode : function(input) { + return base64.decode(input); + } +}; +JSZip.compressions = _dereq_('./compressions'); +module.exports = JSZip; + +},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(_dereq_,module,exports){ +'use strict'; +var base64 = _dereq_('./base64'); +var ZipEntries = _dereq_('./zipEntries'); +module.exports = function(data, options) { + var files, zipEntries, i, input; + options = options || {}; + if (options.base64) { + data = base64.decode(data); + } + + zipEntries = new ZipEntries(data, options); + files = zipEntries.files; + for (i = 0; i < files.length; i++) { + input = files[i]; + this.file(input.fileName, input.decompressed, { + binary: true, + optimizedBinaryString: true, + date: input.date, + dir: input.dir, + comment : input.fileComment.length ? input.fileComment : null, + unixPermissions : input.unixPermissions, + dosPermissions : input.dosPermissions, + createFolders: options.createFolders + }); + } + if (zipEntries.zipComment.length) { + this.comment = zipEntries.zipComment; + } + + return this; +}; + +},{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){ +(function (Buffer){ +'use strict'; +module.exports = function(data, encoding){ + return new Buffer(data, encoding); +}; +module.exports.test = function(b){ + return Buffer.isBuffer(b); +}; + +}).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined)) +},{}],12:[function(_dereq_,module,exports){ +'use strict'; +var Uint8ArrayReader = _dereq_('./uint8ArrayReader'); + +function NodeBufferReader(data) { + this.data = data; + this.length = this.data.length; + this.index = 0; +} +NodeBufferReader.prototype = new Uint8ArrayReader(); + +/** + * @see DataReader.readData + */ +NodeBufferReader.prototype.readData = function(size) { + this.checkOffset(size); + var result = this.data.slice(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = NodeBufferReader; + +},{"./uint8ArrayReader":18}],13:[function(_dereq_,module,exports){ +'use strict'; +var support = _dereq_('./support'); +var utils = _dereq_('./utils'); +var crc32 = _dereq_('./crc32'); +var signature = _dereq_('./signature'); +var defaults = _dereq_('./defaults'); +var base64 = _dereq_('./base64'); +var compressions = _dereq_('./compressions'); +var CompressedObject = _dereq_('./compressedObject'); +var nodeBuffer = _dereq_('./nodeBuffer'); +var utf8 = _dereq_('./utf8'); +var StringWriter = _dereq_('./stringWriter'); +var Uint8ArrayWriter = _dereq_('./uint8ArrayWriter'); + +/** + * Returns the raw data of a ZipObject, decompress the content if necessary. + * @param {ZipObject} file the file to use. + * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + */ +var getRawData = function(file) { + if (file._data instanceof CompressedObject) { + file._data = file._data.getContent(); + file.options.binary = true; + file.options.base64 = false; + + if (utils.getTypeOf(file._data) === "uint8array") { + var copy = file._data; + // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array. + // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file). + file._data = new Uint8Array(copy.length); + // with an empty Uint8Array, Opera fails with a "Offset larger than array size" + if (copy.length !== 0) { + file._data.set(copy, 0); + } + } + } + return file._data; +}; + +/** + * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it. + * @param {ZipObject} file the file to use. + * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + */ +var getBinaryData = function(file) { + var result = getRawData(file), + type = utils.getTypeOf(result); + if (type === "string") { + if (!file.options.binary) { + // unicode text ! + // unicode string => binary string is a painful process, check if we can avoid it. + if (support.nodebuffer) { + return nodeBuffer(result, "utf-8"); + } + } + return file.asBinary(); + } + return result; +}; + +/** + * Transform this._data into a string. + * @param {function} filter a function String -> String, applied if not null on the result. + * @return {String} the string representing this._data. + */ +var dataToString = function(asUTF8) { + var result = getRawData(this); + if (result === null || typeof result === "undefined") { + return ""; + } + // if the data is a base64 string, we decode it before checking the encoding ! + if (this.options.base64) { + result = base64.decode(result); + } + if (asUTF8 && this.options.binary) { + // JSZip.prototype.utf8decode supports arrays as input + // skip to array => string step, utf8decode will do it. + result = out.utf8decode(result); + } + else { + // no utf8 transformation, do the array => string step. + result = utils.transformTo("string", result); + } + + if (!asUTF8 && !this.options.binary) { + result = utils.transformTo("string", out.utf8encode(result)); + } + return result; +}; +/** + * A simple object representing a file in the zip file. + * @constructor + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data + * @param {Object} options the options of the file + */ +var ZipObject = function(name, data, options) { + this.name = name; + this.dir = options.dir; + this.date = options.date; + this.comment = options.comment; + this.unixPermissions = options.unixPermissions; + this.dosPermissions = options.dosPermissions; + + this._data = data; + this.options = options; + + /* + * This object contains initial values for dir and date. + * With them, we can check if the user changed the deprecated metadata in + * `ZipObject#options` or not. + */ + this._initialMetadata = { + dir : options.dir, + date : options.date + }; +}; + +ZipObject.prototype = { + /** + * Return the content as UTF8 string. + * @return {string} the UTF8 string. + */ + asText: function() { + return dataToString.call(this, true); + }, + /** + * Returns the binary content. + * @return {string} the content as binary. + */ + asBinary: function() { + return dataToString.call(this, false); + }, + /** + * Returns the content as a nodejs Buffer. + * @return {Buffer} the content as a Buffer. + */ + asNodeBuffer: function() { + var result = getBinaryData(this); + return utils.transformTo("nodebuffer", result); + }, + /** + * Returns the content as an Uint8Array. + * @return {Uint8Array} the content as an Uint8Array. + */ + asUint8Array: function() { + var result = getBinaryData(this); + return utils.transformTo("uint8array", result); + }, + /** + * Returns the content as an ArrayBuffer. + * @return {ArrayBuffer} the content as an ArrayBufer. + */ + asArrayBuffer: function() { + return this.asUint8Array().buffer; + } +}; + +/** + * Transform an integer into a string in hexadecimal. + * @private + * @param {number} dec the number to convert. + * @param {number} bytes the number of bytes to generate. + * @returns {string} the result. + */ +var decToHex = function(dec, bytes) { + var hex = "", + i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 0xff); + dec = dec >>> 8; + } + return hex; +}; + +/** + * Merge the objects passed as parameters into a new one. + * @private + * @param {...Object} var_args All objects to merge. + * @return {Object} a new object with the data of the others. + */ +var extend = function() { + var result = {}, i, attr; + for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers + for (attr in arguments[i]) { + if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { + result[attr] = arguments[i][attr]; + } + } + } + return result; +}; + +/** + * Transforms the (incomplete) options from the user into the complete + * set of options to create a file. + * @private + * @param {Object} o the options from the user. + * @return {Object} the complete set of options. + */ +var prepareFileAttrs = function(o) { + o = o || {}; + if (o.base64 === true && (o.binary === null || o.binary === undefined)) { + o.binary = true; + } + o = extend(o, defaults); + o.date = o.date || new Date(); + if (o.compression !== null) o.compression = o.compression.toUpperCase(); + + return o; +}; + +/** + * Add a file in the current folder. + * @private + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file + * @param {Object} o the options of the file + * @return {Object} the new file. + */ +var fileAdd = function(name, data, o) { + // be sure sub folders exist + var dataType = utils.getTypeOf(data), + parent; + + o = prepareFileAttrs(o); + + if (typeof o.unixPermissions === "string") { + o.unixPermissions = parseInt(o.unixPermissions, 8); + } + + // UNX_IFDIR 0040000 see zipinfo.c + if (o.unixPermissions && (o.unixPermissions & 0x4000)) { + o.dir = true; + } + // Bit 4 Directory + if (o.dosPermissions && (o.dosPermissions & 0x0010)) { + o.dir = true; + } + + if (o.dir) { + name = forceTrailingSlash(name); + } + + if (o.createFolders && (parent = parentFolder(name))) { + folderAdd.call(this, parent, true); + } + + if (o.dir || data === null || typeof data === "undefined") { + o.base64 = false; + o.binary = false; + data = null; + dataType = null; + } + else if (dataType === "string") { + if (o.binary && !o.base64) { + // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask + if (o.optimizedBinaryString !== true) { + // this is a string, not in a base64 format. + // Be sure that this is a correct "binary string" + data = utils.string2binary(data); + } + } + } + else { // arraybuffer, uint8array, ... + o.base64 = false; + o.binary = true; + + if (!dataType && !(data instanceof CompressedObject)) { + throw new Error("The data of '" + name + "' is in an unsupported format !"); + } + + // special case : it's way easier to work with Uint8Array than with ArrayBuffer + if (dataType === "arraybuffer") { + data = utils.transformTo("uint8array", data); + } + } + + var object = new ZipObject(name, data, o); + this.files[name] = object; + return object; +}; + +/** + * Find the parent folder of the path. + * @private + * @param {string} path the path to use + * @return {string} the parent folder, or "" + */ +var parentFolder = function (path) { + if (path.slice(-1) == '/') { + path = path.substring(0, path.length - 1); + } + var lastSlash = path.lastIndexOf('/'); + return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; +}; + + +/** + * Returns the path with a slash at the end. + * @private + * @param {String} path the path to check. + * @return {String} the path with a trailing slash. + */ +var forceTrailingSlash = function(path) { + // Check the name ends with a / + if (path.slice(-1) != "/") { + path += "/"; // IE doesn't like substr(-1) + } + return path; +}; +/** + * Add a (sub) folder in the current folder. + * @private + * @param {string} name the folder's name + * @param {boolean=} [createFolders] If true, automatically create sub + * folders. Defaults to false. + * @return {Object} the new folder. + */ +var folderAdd = function(name, createFolders) { + createFolders = (typeof createFolders !== 'undefined') ? createFolders : false; + + name = forceTrailingSlash(name); + + // Does this folder already exist? + if (!this.files[name]) { + fileAdd.call(this, name, null, { + dir: true, + createFolders: createFolders + }); + } + return this.files[name]; +}; + +/** + * Generate a JSZip.CompressedObject for a given zipOject. + * @param {ZipObject} file the object to read. + * @param {JSZip.compression} compression the compression to use. + * @param {Object} compressionOptions the options to use when compressing. + * @return {JSZip.CompressedObject} the compressed result. + */ +var generateCompressedObjectFrom = function(file, compression, compressionOptions) { + var result = new CompressedObject(), + content; + + // the data has not been decompressed, we might reuse things ! + if (file._data instanceof CompressedObject) { + result.uncompressedSize = file._data.uncompressedSize; + result.crc32 = file._data.crc32; + + if (result.uncompressedSize === 0 || file.dir) { + compression = compressions['STORE']; + result.compressedContent = ""; + result.crc32 = 0; + } + else if (file._data.compressionMethod === compression.magic) { + result.compressedContent = file._data.getCompressedContent(); + } + else { + content = file._data.getContent(); + // need to decompress / recompress + result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); + } + } + else { + // have uncompressed data + content = getBinaryData(file); + if (!content || content.length === 0 || file.dir) { + compression = compressions['STORE']; + content = ""; + } + result.uncompressedSize = content.length; + result.crc32 = crc32(content); + result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); + } + + result.compressedSize = result.compressedContent.length; + result.compressionMethod = compression.magic; + + return result; +}; + + + + +/** + * Generate the UNIX part of the external file attributes. + * @param {Object} unixPermissions the unix permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : + * + * TTTTsstrwxrwxrwx0000000000ADVSHR + * ^^^^____________________________ file type, see zipinfo.c (UNX_*) + * ^^^_________________________ setuid, setgid, sticky + * ^^^^^^^^^________________ permissions + * ^^^^^^^^^^______ not used ? + * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only + */ +var generateUnixExternalFileAttr = function (unixPermissions, isDir) { + + var result = unixPermissions; + if (!unixPermissions) { + // I can't use octal values in strict mode, hence the hexa. + // 040775 => 0x41fd + // 0100664 => 0x81b4 + result = isDir ? 0x41fd : 0x81b4; + } + + return (result & 0xFFFF) << 16; +}; + +/** + * Generate the DOS part of the external file attributes. + * @param {Object} dosPermissions the dos permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * Bit 0 Read-Only + * Bit 1 Hidden + * Bit 2 System + * Bit 3 Volume Label + * Bit 4 Directory + * Bit 5 Archive + */ +var generateDosExternalFileAttr = function (dosPermissions, isDir) { + + // the dir flag is already set for compatibility + + return (dosPermissions || 0) & 0x3F; +}; + +/** + * Generate the various parts used in the construction of the final zip file. + * @param {string} name the file name. + * @param {ZipObject} file the file content. + * @param {JSZip.CompressedObject} compressedObject the compressed object. + * @param {number} offset the current offset from the start of the zip file. + * @param {String} platform let's pretend we are this platform (change platform dependents fields) + * @return {object} the zip parts. + */ +var generateZipParts = function(name, file, compressedObject, offset, platform) { + var data = compressedObject.compressedContent, + utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), + comment = file.comment || "", + utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), + useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, + useUTF8ForComment = utfEncodedComment.length !== comment.length, + o = file.options, + dosTime, + dosDate, + extraFields = "", + unicodePathExtraField = "", + unicodeCommentExtraField = "", + dir, date; + + + // handle the deprecated options.dir + if (file._initialMetadata.dir !== file.dir) { + dir = file.dir; + } else { + dir = o.dir; + } + + // handle the deprecated options.date + if(file._initialMetadata.date !== file.date) { + date = file.date; + } else { + date = o.date; + } + + var extFileAttr = 0; + var versionMadeBy = 0; + if (dir) { + // dos or unix, we set the dos dir flag + extFileAttr |= 0x00010; + } + if(platform === "UNIX") { + versionMadeBy = 0x031E; // UNIX, version 3.0 + extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); + } else { // DOS or other, fallback to DOS + versionMadeBy = 0x0014; // DOS, version 2.0 + extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); + } + + // date + // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html + + dosTime = date.getHours(); + dosTime = dosTime << 6; + dosTime = dosTime | date.getMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | date.getSeconds() / 2; + + dosDate = date.getFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | (date.getMonth() + 1); + dosDate = dosDate << 5; + dosDate = dosDate | date.getDate(); + + if (useUTF8ForFileName) { + // set the unicode path extra field. unzip needs at least one extra + // field to correctly handle unicode path, so using the path is as good + // as any other information. This could improve the situation with + // other archive managers too. + // This field is usually used without the utf8 flag, with a non + // unicode path in the header (winrar, winzip). This helps (a bit) + // with the messy Windows' default compressed folders feature but + // breaks on p7zip which doesn't seek the unicode path extra field. + // So for now, UTF-8 everywhere ! + unicodePathExtraField = + // Version + decToHex(1, 1) + + // NameCRC32 + decToHex(crc32(utfEncodedFileName), 4) + + // UnicodeName + utfEncodedFileName; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x70" + + // size + decToHex(unicodePathExtraField.length, 2) + + // content + unicodePathExtraField; + } + + if(useUTF8ForComment) { + + unicodeCommentExtraField = + // Version + decToHex(1, 1) + + // CommentCRC32 + decToHex(this.crc32(utfEncodedComment), 4) + + // UnicodeName + utfEncodedComment; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x63" + + // size + decToHex(unicodeCommentExtraField.length, 2) + + // content + unicodeCommentExtraField; + } + + var header = ""; + + // version needed to extract + header += "\x0A\x00"; + // general purpose bit flag + // set bit 11 if utf8 + header += (useUTF8ForFileName || useUTF8ForComment) ? "\x00\x08" : "\x00\x00"; + // compression method + header += compressedObject.compressionMethod; + // last mod file time + header += decToHex(dosTime, 2); + // last mod file date + header += decToHex(dosDate, 2); + // crc-32 + header += decToHex(compressedObject.crc32, 4); + // compressed size + header += decToHex(compressedObject.compressedSize, 4); + // uncompressed size + header += decToHex(compressedObject.uncompressedSize, 4); + // file name length + header += decToHex(utfEncodedFileName.length, 2); + // extra field length + header += decToHex(extraFields.length, 2); + + + var fileRecord = signature.LOCAL_FILE_HEADER + header + utfEncodedFileName + extraFields; + + var dirRecord = signature.CENTRAL_FILE_HEADER + + // version made by (00: DOS) + decToHex(versionMadeBy, 2) + + // file header (common to file and central directory) + header + + // file comment length + decToHex(utfEncodedComment.length, 2) + + // disk number start + "\x00\x00" + + // internal file attributes TODO + "\x00\x00" + + // external file attributes + decToHex(extFileAttr, 4) + + // relative offset of local header + decToHex(offset, 4) + + // file name + utfEncodedFileName + + // extra field + extraFields + + // file comment + utfEncodedComment; + + return { + fileRecord: fileRecord, + dirRecord: dirRecord, + compressedObject: compressedObject + }; +}; + + +// return the actual prototype of JSZip +var out = { + /** + * Read an existing zip and merge the data in the current JSZip object. + * The implementation is in jszip-load.js, don't forget to include it. + * @param {String|ArrayBuffer|Uint8Array|Buffer} stream The stream to load + * @param {Object} options Options for loading the stream. + * options.base64 : is the stream in base64 ? default : false + * @return {JSZip} the current JSZip object + */ + load: function(stream, options) { + throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); + }, + + /** + * Filter nested files/folders with the specified function. + * @param {Function} search the predicate to use : + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + * @return {Array} An array of matching elements. + */ + filter: function(search) { + var result = [], + filename, relativePath, file, fileClone; + for (filename in this.files) { + if (!this.files.hasOwnProperty(filename)) { + continue; + } + file = this.files[filename]; + // return a new object, don't let the user mess with our internal objects :) + fileClone = new ZipObject(file.name, file._data, extend(file.options)); + relativePath = filename.slice(this.root.length, filename.length); + if (filename.slice(0, this.root.length) === this.root && // the file is in the current root + search(relativePath, fileClone)) { // and the file matches the function + result.push(fileClone); + } + } + return result; + }, + + /** + * Add a file to the zip file, or search a file. + * @param {string|RegExp} name The name of the file to add (if data is defined), + * the name of the file to find (if no data) or a regex to match files. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded + * @param {Object} o File options + * @return {JSZip|Object|Array} this JSZip object (when adding a file), + * a file (when searching by string) or an array of files (when searching by regex). + */ + file: function(name, data, o) { + if (arguments.length === 1) { + if (utils.isRegExp(name)) { + var regexp = name; + return this.filter(function(relativePath, file) { + return !file.dir && regexp.test(relativePath); + }); + } + else { // text + return this.filter(function(relativePath, file) { + return !file.dir && relativePath === name; + })[0] || null; + } + } + else { // more than one argument : we have data ! + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, + + /** + * Add a directory to the zip file, or search. + * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. + * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. + */ + folder: function(arg) { + if (!arg) { + return this; + } + + if (utils.isRegExp(arg)) { + return this.filter(function(relativePath, file) { + return file.dir && arg.test(relativePath); + }); + } + + // else, name is a new folder + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + + // Allow chaining by returning a new object with this folder as the root + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, + + /** + * Delete a file, or a directory and all sub-files, from the zip + * @param {string} name the name of the file to delete + * @return {JSZip} this JSZip object + */ + remove: function(name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + // Look for any folders + if (name.slice(-1) != "/") { + name += "/"; + } + file = this.files[name]; + } + + if (file && !file.dir) { + // file + delete this.files[name]; + } else { + // maybe a folder, delete recursively + var kids = this.filter(function(relativePath, file) { + return file.name.slice(0, name.length) === name; + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } + } + + return this; + }, + + /** + * Generate the complete zip file + * @param {Object} options the options to generate the zip file : + * - base64, (deprecated, use type instead) true to generate base64. + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file + */ + generate: function(options) { + options = extend(options || {}, { + base64: true, + compression: "STORE", + compressionOptions : null, + type: "base64", + platform: "DOS", + comment: null, + mimeType: 'application/zip' + }); + + utils.checkSupport(options.type); + + // accept nodejs `process.platform` + if( + options.platform === 'darwin' || + options.platform === 'freebsd' || + options.platform === 'linux' || + options.platform === 'sunos' + ) { + options.platform = "UNIX"; + } + if (options.platform === 'win32') { + options.platform = "DOS"; + } + + var zipData = [], + localDirLength = 0, + centralDirLength = 0, + writer, i, + utfEncodedComment = utils.transformTo("string", this.utf8encode(options.comment || this.comment || "")); + + // first, generate all the zip parts. + for (var name in this.files) { + if (!this.files.hasOwnProperty(name)) { + continue; + } + var file = this.files[name]; + + var compressionName = file.options.compression || options.compression.toUpperCase(); + var compression = compressions[compressionName]; + if (!compression) { + throw new Error(compressionName + " is not a valid compression method !"); + } + var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; + + var compressedObject = generateCompressedObjectFrom.call(this, file, compression, compressionOptions); + + var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength, options.platform); + localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize; + centralDirLength += zipPart.dirRecord.length; + zipData.push(zipPart); + } + + var dirEnd = ""; + + // end of central dir signature + dirEnd = signature.CENTRAL_DIRECTORY_END + + // number of this disk + "\x00\x00" + + // number of the disk with the start of the central directory + "\x00\x00" + + // total number of entries in the central directory on this disk + decToHex(zipData.length, 2) + + // total number of entries in the central directory + decToHex(zipData.length, 2) + + // size of the central directory 4 bytes + decToHex(centralDirLength, 4) + + // offset of start of central directory with respect to the starting disk number + decToHex(localDirLength, 4) + + // .ZIP file comment length + decToHex(utfEncodedComment.length, 2) + + // .ZIP file comment + utfEncodedComment; + + + // we have all the parts (and the total length) + // time to create a writer ! + var typeName = options.type.toLowerCase(); + if(typeName==="uint8array"||typeName==="arraybuffer"||typeName==="blob"||typeName==="nodebuffer") { + writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length); + }else{ + writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length); + } + + for (i = 0; i < zipData.length; i++) { + writer.append(zipData[i].fileRecord); + writer.append(zipData[i].compressedObject.compressedContent); + } + for (i = 0; i < zipData.length; i++) { + writer.append(zipData[i].dirRecord); + } + + writer.append(dirEnd); + + var zip = writer.finalize(); + + + + switch(options.type.toLowerCase()) { + // case "zip is an Uint8Array" + case "uint8array" : + case "arraybuffer" : + case "nodebuffer" : + return utils.transformTo(options.type.toLowerCase(), zip); + case "blob" : + return utils.arrayBuffer2Blob(utils.transformTo("arraybuffer", zip), options.mimeType); + // case "zip is a string" + case "base64" : + return (options.base64) ? base64.encode(zip) : zip; + default : // case "string" : + return zip; + } + + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + crc32: function (input, crc) { + return crc32(input, crc); + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + utf8encode: function (string) { + return utils.transformTo("string", utf8.utf8encode(string)); + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + utf8decode: function (input) { + return utf8.utf8decode(input); + } +}; +module.exports = out; + +},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(_dereq_,module,exports){ +'use strict'; +exports.LOCAL_FILE_HEADER = "PK\x03\x04"; +exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; +exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; +exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; +exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; +exports.DATA_DESCRIPTOR = "PK\x07\x08"; + +},{}],15:[function(_dereq_,module,exports){ +'use strict'; +var DataReader = _dereq_('./dataReader'); +var utils = _dereq_('./utils'); + +function StringReader(data, optimizedBinaryString) { + this.data = data; + if (!optimizedBinaryString) { + this.data = utils.string2binary(this.data); + } + this.length = this.data.length; + this.index = 0; +} +StringReader.prototype = new DataReader(); +/** + * @see DataReader.byteAt + */ +StringReader.prototype.byteAt = function(i) { + return this.data.charCodeAt(i); +}; +/** + * @see DataReader.lastIndexOfSignature + */ +StringReader.prototype.lastIndexOfSignature = function(sig) { + return this.data.lastIndexOf(sig); +}; +/** + * @see DataReader.readData + */ +StringReader.prototype.readData = function(size) { + this.checkOffset(size); + // this will work because the constructor applied the "& 0xff" mask. + var result = this.data.slice(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = StringReader; + +},{"./dataReader":5,"./utils":21}],16:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('./utils'); + +/** + * An object to write any content to a string. + * @constructor + */ +var StringWriter = function() { + this.data = []; +}; +StringWriter.prototype = { + /** + * Append any content to the current string. + * @param {Object} input the content to add. + */ + append: function(input) { + input = utils.transformTo("string", input); + this.data.push(input); + }, + /** + * Finalize the construction an return the result. + * @return {string} the generated string. + */ + finalize: function() { + return this.data.join(""); + } +}; + +module.exports = StringWriter; + +},{"./utils":21}],17:[function(_dereq_,module,exports){ +(function (Buffer){ +'use strict'; +exports.base64 = true; +exports.array = true; +exports.string = true; +exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; +// contains true if JSZip can read/generate nodejs Buffer, false otherwise. +// Browserify will provide a Buffer implementation for browsers, which is +// an augmented Uint8Array (i.e., can be used as either Buffer or U8). +exports.nodebuffer = typeof Buffer !== "undefined"; +// contains true if JSZip can read/generate Uint8Array, false otherwise. +exports.uint8array = typeof Uint8Array !== "undefined"; + +if (typeof ArrayBuffer === "undefined") { + exports.blob = false; +} +else { + var buffer = new ArrayBuffer(0); + try { + exports.blob = new Blob([buffer], { + type: "application/zip" + }).size === 0; + } + catch (e) { + try { + var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + exports.blob = builder.getBlob('application/zip').size === 0; + } + catch (e) { + exports.blob = false; + } + } +} + +}).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined)) +},{}],18:[function(_dereq_,module,exports){ +'use strict'; +var DataReader = _dereq_('./dataReader'); + +function Uint8ArrayReader(data) { + if (data) { + this.data = data; + this.length = this.data.length; + this.index = 0; + } +} +Uint8ArrayReader.prototype = new DataReader(); +/** + * @see DataReader.byteAt + */ +Uint8ArrayReader.prototype.byteAt = function(i) { + return this.data[i]; +}; +/** + * @see DataReader.lastIndexOfSignature + */ +Uint8ArrayReader.prototype.lastIndexOfSignature = function(sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3); + for (var i = this.length - 4; i >= 0; --i) { + if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { + return i; + } + } + + return -1; +}; +/** + * @see DataReader.readData + */ +Uint8ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. + return new Uint8Array(0); + } + var result = this.data.subarray(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = Uint8ArrayReader; + +},{"./dataReader":5}],19:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('./utils'); + +/** + * An object to write any content to an Uint8Array. + * @constructor + * @param {number} length The length of the array. + */ +var Uint8ArrayWriter = function(length) { + this.data = new Uint8Array(length); + this.index = 0; +}; +Uint8ArrayWriter.prototype = { + /** + * Append any content to the current array. + * @param {Object} input the content to add. + */ + append: function(input) { + if (input.length !== 0) { + // with an empty Uint8Array, Opera fails with a "Offset larger than array size" + input = utils.transformTo("uint8array", input); + this.data.set(input, this.index); + this.index += input.length; + } + }, + /** + * Finalize the construction an return the result. + * @return {Uint8Array} the generated array. + */ + finalize: function() { + return this.data; + } +}; + +module.exports = Uint8ArrayWriter; + +},{"./utils":21}],20:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('./utils'); +var support = _dereq_('./support'); +var nodeBuffer = _dereq_('./nodeBuffer'); + +/** + * The following functions come from pako, from pako/lib/utils/strings + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +var _utf8len = new Array(256); +for (var i=0; i<256; i++) { + _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start + +// convert string to array (typed, when possible) +var string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + if (support.uint8array) { + buf = new Uint8Array(buf_len); + } else { + buf = new Array(buf_len); + } + + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +var utf8border = function(buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +// convert array to string +var buf2string = function (buf) { + var str, i, out, c, c_len; + var len = buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); + + for (out=0, i=0; i 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + // shrinkBuf(utf16buf, out) + if (utf16buf.length !== out) { + if(utf16buf.subarray) { + utf16buf = utf16buf.subarray(0, out); + } else { + utf16buf.length = out; + } + } + + // return String.fromCharCode.apply(null, utf16buf); + return utils.applyFromCharCode(utf16buf); +}; + + +// That's all for the pako functions. + + +/** + * Transform a javascript string into an array (typed if possible) of bytes, + * UTF-8 encoded. + * @param {String} str the string to encode + * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. + */ +exports.utf8encode = function utf8encode(str) { + if (support.nodebuffer) { + return nodeBuffer(str, "utf-8"); + } + + return string2buf(str); +}; + + +/** + * Transform a bytes array (or a representation) representing an UTF-8 encoded + * string into a javascript string. + * @param {Array|Uint8Array|Buffer} buf the data de decode + * @return {String} the decoded string. + */ +exports.utf8decode = function utf8decode(buf) { + if (support.nodebuffer) { + return utils.transformTo("nodebuffer", buf).toString("utf-8"); + } + + buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); + + // return buf2string(buf); + // Chrome prefers to work with "small" chunks of data + // for the method buf2string. + // Firefox and Chrome has their own shortcut, IE doesn't seem to really care. + var result = [], k = 0, len = buf.length, chunk = 65536; + while (k < len) { + var nextBoundary = utf8border(buf, Math.min(k + chunk, len)); + if (support.uint8array) { + result.push(buf2string(buf.subarray(k, nextBoundary))); + } else { + result.push(buf2string(buf.slice(k, nextBoundary))); + } + k = nextBoundary; + } + return result.join(""); + +}; +// vim: set shiftwidth=4 softtabstop=4: + +},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(_dereq_,module,exports){ +'use strict'; +var support = _dereq_('./support'); +var compressions = _dereq_('./compressions'); +var nodeBuffer = _dereq_('./nodeBuffer'); +/** + * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. + * @param {string} str the string to transform. + * @return {String} the binary string. + */ +exports.string2binary = function(str) { + var result = ""; + for (var i = 0; i < str.length; i++) { + result += String.fromCharCode(str.charCodeAt(i) & 0xff); + } + return result; +}; +exports.arrayBuffer2Blob = function(buffer, mimeType) { + exports.checkSupport("blob"); + mimeType = mimeType || 'application/zip'; + + try { + // Blob constructor + return new Blob([buffer], { + type: mimeType + }); + } + catch (e) { + + try { + // deprecated, browser only, old way + var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + return builder.getBlob(mimeType); + } + catch (e) { + + // well, fuck ?! + throw new Error("Bug : can't construct the Blob."); + } + } + + +}; +/** + * The identity function. + * @param {Object} input the input. + * @return {Object} the same input. + */ +function identity(input) { + return input; +} + +/** + * Fill in an array with a string. + * @param {String} str the string to use. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. + */ +function stringToArrayLike(str, array) { + for (var i = 0; i < str.length; ++i) { + array[i] = str.charCodeAt(i) & 0xFF; + } + return array; +} + +/** + * Transform an array-like object to a string. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ +function arrayLikeToString(array) { + // Performances notes : + // -------------------- + // String.fromCharCode.apply(null, array) is the fastest, see + // see http://jsperf.com/converting-a-uint8array-to-a-string/2 + // but the stack is limited (and we can get huge arrays !). + // + // result += String.fromCharCode(array[i]); generate too many strings ! + // + // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 + var chunk = 65536; + var result = [], + len = array.length, + type = exports.getTypeOf(array), + k = 0, + canUseApply = true; + try { + switch(type) { + case "uint8array": + String.fromCharCode.apply(null, new Uint8Array(0)); + break; + case "nodebuffer": + String.fromCharCode.apply(null, nodeBuffer(0)); + break; + } + } catch(e) { + canUseApply = false; + } + + // no apply : slow and painful algorithm + // default browser on android 4.* + if (!canUseApply) { + var resultStr = ""; + for(var i = 0; i < array.length;i++) { + resultStr += String.fromCharCode(array[i]); + } + return resultStr; + } + while (k < len && chunk > 1) { + try { + if (type === "array" || type === "nodebuffer") { + result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); + } + else { + result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); + } + k += chunk; + } + catch (e) { + chunk = Math.floor(chunk / 2); + } + } + return result.join(""); +} + +exports.applyFromCharCode = arrayLikeToString; + + +/** + * Copy the data from an array-like to an other array-like. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. + */ +function arrayLikeToArrayLike(arrayFrom, arrayTo) { + for (var i = 0; i < arrayFrom.length; i++) { + arrayTo[i] = arrayFrom[i]; + } + return arrayTo; +} + +// a matrix containing functions to transform everything into everything. +var transform = {}; + +// string to ? +transform["string"] = { + "string": identity, + "array": function(input) { + return stringToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["string"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return stringToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": function(input) { + return stringToArrayLike(input, nodeBuffer(input.length)); + } +}; + +// array to ? +transform["array"] = { + "string": arrayLikeToString, + "array": identity, + "arraybuffer": function(input) { + return (new Uint8Array(input)).buffer; + }, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodeBuffer(input); + } +}; + +// arraybuffer to ? +transform["arraybuffer"] = { + "string": function(input) { + return arrayLikeToString(new Uint8Array(input)); + }, + "array": function(input) { + return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); + }, + "arraybuffer": identity, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodeBuffer(new Uint8Array(input)); + } +}; + +// uint8array to ? +transform["uint8array"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return input.buffer; + }, + "uint8array": identity, + "nodebuffer": function(input) { + return nodeBuffer(input); + } +}; + +// nodebuffer to ? +transform["nodebuffer"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["nodebuffer"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return arrayLikeToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": identity +}; + +/** + * Transform an input into any type. + * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. + * If no output type is specified, the unmodified input will be returned. + * @param {String} outputType the output type. + * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. + * @throws {Error} an Error if the browser doesn't support the requested output type. + */ +exports.transformTo = function(outputType, input) { + if (!input) { + // undefined, null, etc + // an empty string won't harm. + input = ""; + } + if (!outputType) { + return input; + } + exports.checkSupport(outputType); + var inputType = exports.getTypeOf(input); + var result = transform[inputType][outputType](input); + return result; +}; + +/** + * Return the type of the input. + * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. + * @param {Object} input the input to identify. + * @return {String} the (lowercase) type of the input. + */ +exports.getTypeOf = function(input) { + if (typeof input === "string") { + return "string"; + } + if (Object.prototype.toString.call(input) === "[object Array]") { + return "array"; + } + if (support.nodebuffer && nodeBuffer.test(input)) { + return "nodebuffer"; + } + if (support.uint8array && input instanceof Uint8Array) { + return "uint8array"; + } + if (support.arraybuffer && input instanceof ArrayBuffer) { + return "arraybuffer"; + } +}; + +/** + * Throw an exception if the type is not supported. + * @param {String} type the type to check. + * @throws {Error} an Error if the browser doesn't support the requested type. + */ +exports.checkSupport = function(type) { + var supported = support[type.toLowerCase()]; + if (!supported) { + throw new Error(type + " is not supported by this browser"); + } +}; +exports.MAX_VALUE_16BITS = 65535; +exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 + +/** + * Prettify a string read as binary. + * @param {string} str the string to prettify. + * @return {string} a pretty string. + */ +exports.pretty = function(str) { + var res = '', + code, i; + for (i = 0; i < (str || "").length; i++) { + code = str.charCodeAt(i); + res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); + } + return res; +}; + +/** + * Find a compression registered in JSZip. + * @param {string} compressionMethod the method magic to find. + * @return {Object|null} the JSZip compression object, null if none found. + */ +exports.findCompression = function(compressionMethod) { + for (var method in compressions) { + if (!compressions.hasOwnProperty(method)) { + continue; + } + if (compressions[method].magic === compressionMethod) { + return compressions[method]; + } + } + return null; +}; +/** +* Cross-window, cross-Node-context regular expression detection +* @param {Object} object Anything +* @return {Boolean} true if the object is a regular expression, +* false otherwise +*/ +exports.isRegExp = function (object) { + return Object.prototype.toString.call(object) === "[object RegExp]"; +}; + + +},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(_dereq_,module,exports){ +'use strict'; +var StringReader = _dereq_('./stringReader'); +var NodeBufferReader = _dereq_('./nodeBufferReader'); +var Uint8ArrayReader = _dereq_('./uint8ArrayReader'); +var utils = _dereq_('./utils'); +var sig = _dereq_('./signature'); +var ZipEntry = _dereq_('./zipEntry'); +var support = _dereq_('./support'); +var jszipProto = _dereq_('./object'); +// class ZipEntries {{{ +/** + * All the entries in the zip file. + * @constructor + * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntries(data, loadOptions) { + this.files = []; + this.loadOptions = loadOptions; + if (data) { + this.load(data); + } +} +ZipEntries.prototype = { + /** + * Check that the reader is on the speficied signature. + * @param {string} expectedSignature the expected signature. + * @throws {Error} if it is an other signature. + */ + checkSignature: function(expectedSignature) { + var signature = this.reader.readString(4); + if (signature !== expectedSignature) { + throw new Error("Corrupted zip or bug : unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); + } + }, + /** + * Read the end of the central directory. + */ + readBlockEndOfCentral: function() { + this.diskNumber = this.reader.readInt(2); + this.diskWithCentralDirStart = this.reader.readInt(2); + this.centralDirRecordsOnThisDisk = this.reader.readInt(2); + this.centralDirRecords = this.reader.readInt(2); + this.centralDirSize = this.reader.readInt(4); + this.centralDirOffset = this.reader.readInt(4); + + this.zipCommentLength = this.reader.readInt(2); + // warning : the encoding depends of the system locale + // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. + // On a windows machine, this field is encoded with the localized windows code page. + this.zipComment = this.reader.readString(this.zipCommentLength); + // To get consistent behavior with the generation part, we will assume that + // this is utf8 encoded. + this.zipComment = jszipProto.utf8decode(this.zipComment); + }, + /** + * Read the end of the Zip 64 central directory. + * Not merged with the method readEndOfCentral : + * The end of central can coexist with its Zip64 brother, + * I don't want to read the wrong number of bytes ! + */ + readBlockZip64EndOfCentral: function() { + this.zip64EndOfCentralSize = this.reader.readInt(8); + this.versionMadeBy = this.reader.readString(2); + this.versionNeeded = this.reader.readInt(2); + this.diskNumber = this.reader.readInt(4); + this.diskWithCentralDirStart = this.reader.readInt(4); + this.centralDirRecordsOnThisDisk = this.reader.readInt(8); + this.centralDirRecords = this.reader.readInt(8); + this.centralDirSize = this.reader.readInt(8); + this.centralDirOffset = this.reader.readInt(8); + + this.zip64ExtensibleData = {}; + var extraDataSize = this.zip64EndOfCentralSize - 44, + index = 0, + extraFieldId, + extraFieldLength, + extraFieldValue; + while (index < extraDataSize) { + extraFieldId = this.reader.readInt(2); + extraFieldLength = this.reader.readInt(4); + extraFieldValue = this.reader.readString(extraFieldLength); + this.zip64ExtensibleData[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Read the end of the Zip 64 central directory locator. + */ + readBlockZip64EndOfCentralLocator: function() { + this.diskWithZip64CentralDirStart = this.reader.readInt(4); + this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); + this.disksCount = this.reader.readInt(4); + if (this.disksCount > 1) { + throw new Error("Multi-volumes zip are not supported"); + } + }, + /** + * Read the local files, based on the offset read in the central part. + */ + readLocalFiles: function() { + var i, file; + for (i = 0; i < this.files.length; i++) { + file = this.files[i]; + this.reader.setIndex(file.localHeaderOffset); + this.checkSignature(sig.LOCAL_FILE_HEADER); + file.readLocalPart(this.reader); + file.handleUTF8(); + file.processAttributes(); + } + }, + /** + * Read the central directory. + */ + readCentralDir: function() { + var file; + + this.reader.setIndex(this.centralDirOffset); + while (this.reader.readString(4) === sig.CENTRAL_FILE_HEADER) { + file = new ZipEntry({ + zip64: this.zip64 + }, this.loadOptions); + file.readCentralPart(this.reader); + this.files.push(file); + } + }, + /** + * Read the end of central directory. + */ + readEndOfCentral: function() { + var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); + if (offset === -1) { + // Check if the content is a truncated zip or complete garbage. + // A "LOCAL_FILE_HEADER" is not required at the beginning (auto + // extractible zip for example) but it can give a good hint. + // If an ajax request was used without responseType, we will also + // get unreadable data. + var isGarbage = true; + try { + this.reader.setIndex(0); + this.checkSignature(sig.LOCAL_FILE_HEADER); + isGarbage = false; + } catch (e) {} + + if (isGarbage) { + throw new Error("Can't find end of central directory : is this a zip file ? " + + "If it is, see http://stuk.github.io/jszip/documentation/howto/read_zip.html"); + } else { + throw new Error("Corrupted zip : can't find end of central directory"); + } + } + this.reader.setIndex(offset); + this.checkSignature(sig.CENTRAL_DIRECTORY_END); + this.readBlockEndOfCentral(); + + + /* extract from the zip spec : + 4) If one of the fields in the end of central directory + record is too small to hold required data, the field + should be set to -1 (0xFFFF or 0xFFFFFFFF) and the + ZIP64 format record should be created. + 5) The end of central directory record and the + Zip64 end of central directory locator record must + reside on the same disk when splitting or spanning + an archive. + */ + if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { + this.zip64 = true; + + /* + Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from + the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents + all numbers as 64-bit double precision IEEE 754 floating point numbers. + So, we have 53bits for integers and bitwise operations treat everything as 32bits. + see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators + and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 + */ + + // should look for a zip64 EOCD locator + offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + if (offset === -1) { + throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); + } + this.reader.setIndex(offset); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + this.readBlockZip64EndOfCentralLocator(); + + // now the zip64 EOCD record + this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + this.readBlockZip64EndOfCentral(); + } + }, + prepareReader: function(data) { + var type = utils.getTypeOf(data); + if (type === "string" && !support.uint8array) { + this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString); + } + else if (type === "nodebuffer") { + this.reader = new NodeBufferReader(data); + } + else { + this.reader = new Uint8ArrayReader(utils.transformTo("uint8array", data)); + } + }, + /** + * Read a zip file and create ZipEntries. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. + */ + load: function(data) { + this.prepareReader(data); + this.readEndOfCentral(); + this.readCentralDir(); + this.readLocalFiles(); + } +}; +// }}} end of ZipEntries +module.exports = ZipEntries; + +},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(_dereq_,module,exports){ +'use strict'; +var StringReader = _dereq_('./stringReader'); +var utils = _dereq_('./utils'); +var CompressedObject = _dereq_('./compressedObject'); +var jszipProto = _dereq_('./object'); + +var MADE_BY_DOS = 0x00; +var MADE_BY_UNIX = 0x03; + +// class ZipEntry {{{ +/** + * An entry in the zip file. + * @constructor + * @param {Object} options Options of the current file. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntry(options, loadOptions) { + this.options = options; + this.loadOptions = loadOptions; +} +ZipEntry.prototype = { + /** + * say if the file is encrypted. + * @return {boolean} true if the file is encrypted, false otherwise. + */ + isEncrypted: function() { + // bit 1 is set + return (this.bitFlag & 0x0001) === 0x0001; + }, + /** + * say if the file has utf-8 filename/comment. + * @return {boolean} true if the filename/comment is in utf-8, false otherwise. + */ + useUTF8: function() { + // bit 11 is set + return (this.bitFlag & 0x0800) === 0x0800; + }, + /** + * Prepare the function used to generate the compressed content from this ZipFile. + * @param {DataReader} reader the reader to use. + * @param {number} from the offset from where we should read the data. + * @param {number} length the length of the data to read. + * @return {Function} the callback to get the compressed content (the type depends of the DataReader class). + */ + prepareCompressedContent: function(reader, from, length) { + return function() { + var previousIndex = reader.index; + reader.setIndex(from); + var compressedFileData = reader.readData(length); + reader.setIndex(previousIndex); + + return compressedFileData; + }; + }, + /** + * Prepare the function used to generate the uncompressed content from this ZipFile. + * @param {DataReader} reader the reader to use. + * @param {number} from the offset from where we should read the data. + * @param {number} length the length of the data to read. + * @param {JSZip.compression} compression the compression used on this file. + * @param {number} uncompressedSize the uncompressed size to expect. + * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class). + */ + prepareContent: function(reader, from, length, compression, uncompressedSize) { + return function() { + + var compressedFileData = utils.transformTo(compression.uncompressInputType, this.getCompressedContent()); + var uncompressedFileData = compression.uncompress(compressedFileData); + + if (uncompressedFileData.length !== uncompressedSize) { + throw new Error("Bug : uncompressed data size mismatch"); + } + + return uncompressedFileData; + }; + }, + /** + * Read the local part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readLocalPart: function(reader) { + var compression, localExtraFieldsLength; + + // we already know everything from the central dir ! + // If the central dir data are false, we are doomed. + // On the bright side, the local part is scary : zip64, data descriptors, both, etc. + // The less data we get here, the more reliable this should be. + // Let's skip the whole header and dash to the data ! + reader.skip(22); + // in some zip created on windows, the filename stored in the central dir contains \ instead of /. + // Strangely, the filename here is OK. + // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes + // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... + // Search "unzip mismatching "local" filename continuing with "central" filename version" on + // the internet. + // + // I think I see the logic here : the central directory is used to display + // content and the local directory is used to extract the files. Mixing / and \ + // may be used to display \ to windows users and use / when extracting the files. + // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 + this.fileNameLength = reader.readInt(2); + localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir + this.fileName = reader.readString(this.fileNameLength); + reader.skip(localExtraFieldsLength); + + if (this.compressedSize == -1 || this.uncompressedSize == -1) { + throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize == -1 || uncompressedSize == -1)"); + } + + compression = utils.findCompression(this.compressionMethod); + if (compression === null) { // no compression found + throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + this.fileName + ")"); + } + this.decompressed = new CompressedObject(); + this.decompressed.compressedSize = this.compressedSize; + this.decompressed.uncompressedSize = this.uncompressedSize; + this.decompressed.crc32 = this.crc32; + this.decompressed.compressionMethod = this.compressionMethod; + this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression); + this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize); + + // we need to compute the crc32... + if (this.loadOptions.checkCRC32) { + this.decompressed = utils.transformTo("string", this.decompressed.getContent()); + if (jszipProto.crc32(this.decompressed) !== this.crc32) { + throw new Error("Corrupted zip : CRC32 mismatch"); + } + } + }, + + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readCentralPart: function(reader) { + this.versionMadeBy = reader.readInt(2); + this.versionNeeded = reader.readInt(2); + this.bitFlag = reader.readInt(2); + this.compressionMethod = reader.readString(2); + this.date = reader.readDate(); + this.crc32 = reader.readInt(4); + this.compressedSize = reader.readInt(4); + this.uncompressedSize = reader.readInt(4); + this.fileNameLength = reader.readInt(2); + this.extraFieldsLength = reader.readInt(2); + this.fileCommentLength = reader.readInt(2); + this.diskNumberStart = reader.readInt(2); + this.internalFileAttributes = reader.readInt(2); + this.externalFileAttributes = reader.readInt(4); + this.localHeaderOffset = reader.readInt(4); + + if (this.isEncrypted()) { + throw new Error("Encrypted zip are not supported"); + } + + this.fileName = reader.readString(this.fileNameLength); + this.readExtraFields(reader); + this.parseZIP64ExtraField(reader); + this.fileComment = reader.readString(this.fileCommentLength); + }, + + /** + * Parse the external file attributes and get the unix/dos permissions. + */ + processAttributes: function () { + this.unixPermissions = null; + this.dosPermissions = null; + var madeBy = this.versionMadeBy >> 8; + + // Check if we have the DOS directory flag set. + // We look for it in the DOS and UNIX permissions + // but some unknown platform could set it as a compatibility flag. + this.dir = this.externalFileAttributes & 0x0010 ? true : false; + + if(madeBy === MADE_BY_DOS) { + // first 6 bits (0 to 5) + this.dosPermissions = this.externalFileAttributes & 0x3F; + } + + if(madeBy === MADE_BY_UNIX) { + this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF; + // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); + } + + // fail safe : if the name ends with a / it probably means a folder + if (!this.dir && this.fileName.slice(-1) === '/') { + this.dir = true; + } + }, + + /** + * Parse the ZIP64 extra field and merge the info in the current ZipEntry. + * @param {DataReader} reader the reader to use. + */ + parseZIP64ExtraField: function(reader) { + + if (!this.extraFields[0x0001]) { + return; + } + + // should be something, preparing the extra reader + var extraReader = new StringReader(this.extraFields[0x0001].value); + + // I really hope that these 64bits integer can fit in 32 bits integer, because js + // won't let us have more. + if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { + this.uncompressedSize = extraReader.readInt(8); + } + if (this.compressedSize === utils.MAX_VALUE_32BITS) { + this.compressedSize = extraReader.readInt(8); + } + if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { + this.localHeaderOffset = extraReader.readInt(8); + } + if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { + this.diskNumberStart = extraReader.readInt(4); + } + }, + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readExtraFields: function(reader) { + var start = reader.index, + extraFieldId, + extraFieldLength, + extraFieldValue; + + this.extraFields = this.extraFields || {}; + + while (reader.index < start + this.extraFieldsLength) { + extraFieldId = reader.readInt(2); + extraFieldLength = reader.readInt(2); + extraFieldValue = reader.readString(extraFieldLength); + + this.extraFields[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Apply an UTF8 transformation if needed. + */ + handleUTF8: function() { + if (this.useUTF8()) { + this.fileName = jszipProto.utf8decode(this.fileName); + this.fileComment = jszipProto.utf8decode(this.fileComment); + } else { + var upath = this.findExtraFieldUnicodePath(); + if (upath !== null) { + this.fileName = upath; + } + var ucomment = this.findExtraFieldUnicodeComment(); + if (ucomment !== null) { + this.fileComment = ucomment; + } + } + }, + + /** + * Find the unicode path declared in the extra field, if any. + * @return {String} the unicode path, null otherwise. + */ + findExtraFieldUnicodePath: function() { + var upathField = this.extraFields[0x7075]; + if (upathField) { + var extraReader = new StringReader(upathField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the filename changed, this field is out of date. + if (jszipProto.crc32(this.fileName) !== extraReader.readInt(4)) { + return null; + } + + return jszipProto.utf8decode(extraReader.readString(upathField.length - 5)); + } + return null; + }, + + /** + * Find the unicode comment declared in the extra field, if any. + * @return {String} the unicode comment, null otherwise. + */ + findExtraFieldUnicodeComment: function() { + var ucommentField = this.extraFields[0x6375]; + if (ucommentField) { + var extraReader = new StringReader(ucommentField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the comment changed, this field is out of date. + if (jszipProto.crc32(this.fileComment) !== extraReader.readInt(4)) { + return null; + } + + return jszipProto.utf8decode(extraReader.readString(ucommentField.length - 5)); + } + return null; + } +}; +module.exports = ZipEntry; + +},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(_dereq_,module,exports){ +// Top level file is just a mixin of submodules & constants +'use strict'; + +var assign = _dereq_('./lib/utils/common').assign; + +var deflate = _dereq_('./lib/deflate'); +var inflate = _dereq_('./lib/inflate'); +var constants = _dereq_('./lib/zlib/constants'); + +var pako = {}; + +assign(pako, deflate, inflate, constants); + +module.exports = pako; +},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(_dereq_,module,exports){ +'use strict'; + + +var zlib_deflate = _dereq_('./zlib/deflate.js'); +var utils = _dereq_('./utils/common'); +var strings = _dereq_('./utils/strings'); +var msg = _dereq_('./zlib/messages'); +var zstream = _dereq_('./zlib/zstream'); + + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + +var Z_NO_FLUSH = 0; +var Z_FINISH = 4; + +var Z_OK = 0; +var Z_STREAM_END = 1; + +var Z_DEFAULT_COMPRESSION = -1; + +var Z_DEFAULT_STRATEGY = 0; + +var Z_DEFLATED = 8; + +/* ===========================================================================*/ + + +/** + * class Deflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[deflate]], + * [[deflateRaw]] and [[gzip]]. + **/ + +/* internal + * Deflate.chunks -> Array + * + * Chunks of output data, if [[Deflate#onData]] not overriden. + **/ + +/** + * Deflate.result -> Uint8Array|Array + * + * Compressed result, generated by default [[Deflate#onData]] + * and [[Deflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Deflate#push]] with `Z_FINISH` / `true` param). + **/ + +/** + * Deflate.err -> Number + * + * Error code after deflate finished. 0 (Z_OK) on success. + * You will not need it in real life, because deflate errors + * are possible only on wrong options or bad `onData` / `onEnd` + * custom handlers. + **/ + +/** + * Deflate.msg -> String + * + * Error message, if [[Deflate.err]] != 0 + **/ + + +/** + * new Deflate(options) + * - options (Object): zlib deflate options. + * + * Creates new deflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `level` + * - `windowBits` + * - `memLevel` + * - `strategy` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw deflate + * - `gzip` (Boolean) - create gzip wrapper + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * - `header` (Object) - custom header for gzip + * - `text` (Boolean) - true if compressed data believed to be text + * - `time` (Number) - modification time, unix timestamp + * - `os` (Number) - operation system code + * - `extra` (Array) - array of bytes with extra data (max 65536) + * - `name` (String) - file name (binary string) + * - `comment` (String) - comment (binary string) + * - `hcrc` (Boolean) - true if header crc should be added + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var deflate = new pako.Deflate({ level: 3}); + * + * deflate.push(chunk1, false); + * deflate.push(chunk2, true); // true -> last chunk + * + * if (deflate.err) { throw new Error(deflate.err); } + * + * console.log(deflate.result); + * ``` + **/ +var Deflate = function(options) { + + this.options = utils.assign({ + level: Z_DEFAULT_COMPRESSION, + method: Z_DEFLATED, + chunkSize: 16384, + windowBits: 15, + memLevel: 8, + strategy: Z_DEFAULT_STRATEGY, + to: '' + }, options || {}); + + var opt = this.options; + + if (opt.raw && (opt.windowBits > 0)) { + opt.windowBits = -opt.windowBits; + } + + else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { + opt.windowBits += 16; + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new zstream(); + this.strm.avail_out = 0; + + var status = zlib_deflate.deflateInit2( + this.strm, + opt.level, + opt.method, + opt.windowBits, + opt.memLevel, + opt.strategy + ); + + if (status !== Z_OK) { + throw new Error(msg[status]); + } + + if (opt.header) { + zlib_deflate.deflateSetHeader(this.strm, opt.header); + } +}; + +/** + * Deflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|String): input data. Strings will be converted to + * utf8 byte sequence. + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH. + * + * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with + * new compressed chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That flush internal pending buffers and call + * [[Deflate#onEnd]]. + * + * On fail call [[Deflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * array format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Deflate.prototype.push = function(data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status, _mode; + + if (this.ended) { return false; } + + _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH); + + // Convert data if needed + if (typeof data === 'string') { + // If we need to compress text, change encoding to utf8. + strm.input = strings.string2buf(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + status = zlib_deflate.deflate(strm, _mode); /* no bad return value */ + + if (status !== Z_STREAM_END && status !== Z_OK) { + this.onEnd(status); + this.ended = true; + return false; + } + if (strm.avail_out === 0 || (strm.avail_in === 0 && _mode === Z_FINISH)) { + if (this.options.to === 'string') { + this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out))); + } else { + this.onData(utils.shrinkBuf(strm.output, strm.next_out)); + } + } + } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END); + + // Finalize on the last chunk. + if (_mode === Z_FINISH) { + status = zlib_deflate.deflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === Z_OK; + } + + return true; +}; + + +/** + * Deflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): ouput data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Deflate.prototype.onData = function(chunk) { + this.chunks.push(chunk); +}; + + +/** + * Deflate#onEnd(status) -> Void + * - status (Number): deflate status. 0 (Z_OK) on success, + * other if not. + * + * Called once after you tell deflate that input stream complete + * or error happenned. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Deflate.prototype.onEnd = function(status) { + // On success - join + if (status === Z_OK) { + if (this.options.to === 'string') { + this.result = this.chunks.join(''); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * deflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * Compress `data` with deflate alrorythm and `options`. + * + * Supported options are: + * + * - level + * - windowBits + * - memLevel + * - strategy + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , data = Uint8Array([1,2,3,4,5,6,7,8,9]); + * + * console.log(pako.deflate(data)); + * ``` + **/ +function deflate(input, options) { + var deflator = new Deflate(options); + + deflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (deflator.err) { throw deflator.msg; } + + return deflator.result; +} + + +/** + * deflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function deflateRaw(input, options) { + options = options || {}; + options.raw = true; + return deflate(input, options); +} + + +/** + * gzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but create gzip wrapper instead of + * deflate one. + **/ +function gzip(input, options) { + options = options || {}; + options.gzip = true; + return deflate(input, options); +} + + +exports.Deflate = Deflate; +exports.deflate = deflate; +exports.deflateRaw = deflateRaw; +exports.gzip = gzip; +},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(_dereq_,module,exports){ +'use strict'; + + +var zlib_inflate = _dereq_('./zlib/inflate.js'); +var utils = _dereq_('./utils/common'); +var strings = _dereq_('./utils/strings'); +var c = _dereq_('./zlib/constants'); +var msg = _dereq_('./zlib/messages'); +var zstream = _dereq_('./zlib/zstream'); +var gzheader = _dereq_('./zlib/gzheader'); + + +/** + * class Inflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[inflate]] + * and [[inflateRaw]]. + **/ + +/* internal + * inflate.chunks -> Array + * + * Chunks of output data, if [[Inflate#onData]] not overriden. + **/ + +/** + * Inflate.result -> Uint8Array|Array|String + * + * Uncompressed result, generated by default [[Inflate#onData]] + * and [[Inflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Inflate#push]] with `Z_FINISH` / `true` param). + **/ + +/** + * Inflate.err -> Number + * + * Error code after inflate finished. 0 (Z_OK) on success. + * Should be checked if broken data possible. + **/ + +/** + * Inflate.msg -> String + * + * Error message, if [[Inflate.err]] != 0 + **/ + + +/** + * new Inflate(options) + * - options (Object): zlib inflate options. + * + * Creates new inflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `windowBits` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw inflate + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * By default, when no options set, autodetect deflate/gzip data format via + * wrapper header. + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var inflate = new pako.Inflate({ level: 3}); + * + * inflate.push(chunk1, false); + * inflate.push(chunk2, true); // true -> last chunk + * + * if (inflate.err) { throw new Error(inflate.err); } + * + * console.log(inflate.result); + * ``` + **/ +var Inflate = function(options) { + + this.options = utils.assign({ + chunkSize: 16384, + windowBits: 0, + to: '' + }, options || {}); + + var opt = this.options; + + // Force window size for `raw` data, if not set directly, + // because we have no header for autodetect. + if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { + opt.windowBits = -opt.windowBits; + if (opt.windowBits === 0) { opt.windowBits = -15; } + } + + // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate + if ((opt.windowBits >= 0) && (opt.windowBits < 16) && + !(options && options.windowBits)) { + opt.windowBits += 32; + } + + // Gzip header has no info about windows size, we can do autodetect only + // for deflate. So, if window size not set, force it to max when gzip possible + if ((opt.windowBits > 15) && (opt.windowBits < 48)) { + // bit 3 (16) -> gzipped data + // bit 4 (32) -> autodetect gzip/deflate + if ((opt.windowBits & 15) === 0) { + opt.windowBits |= 15; + } + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new zstream(); + this.strm.avail_out = 0; + + var status = zlib_inflate.inflateInit2( + this.strm, + opt.windowBits + ); + + if (status !== c.Z_OK) { + throw new Error(msg[status]); + } + + this.header = new gzheader(); + + zlib_inflate.inflateGetHeader(this.strm, this.header); +}; + +/** + * Inflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|String): input data + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH. + * + * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with + * new output chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That flush internal pending buffers and call + * [[Inflate#onEnd]]. + * + * On fail call [[Inflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Inflate.prototype.push = function(data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status, _mode; + var next_out_utf8, tail, utf8str; + + if (this.ended) { return false; } + _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH); + + // Convert data if needed + if (typeof data === 'string') { + // Only binary strings can be decompressed on practice + strm.input = strings.binstring2buf(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + + status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */ + + if (status !== c.Z_STREAM_END && status !== c.Z_OK) { + this.onEnd(status); + this.ended = true; + return false; + } + + if (strm.next_out) { + if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && _mode === c.Z_FINISH)) { + + if (this.options.to === 'string') { + + next_out_utf8 = strings.utf8border(strm.output, strm.next_out); + + tail = strm.next_out - next_out_utf8; + utf8str = strings.buf2string(strm.output, next_out_utf8); + + // move tail + strm.next_out = tail; + strm.avail_out = chunkSize - tail; + if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); } + + this.onData(utf8str); + + } else { + this.onData(utils.shrinkBuf(strm.output, strm.next_out)); + } + } + } + } while ((strm.avail_in > 0) && status !== c.Z_STREAM_END); + + if (status === c.Z_STREAM_END) { + _mode = c.Z_FINISH; + } + // Finalize on the last chunk. + if (_mode === c.Z_FINISH) { + status = zlib_inflate.inflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === c.Z_OK; + } + + return true; +}; + + +/** + * Inflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): ouput data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Inflate.prototype.onData = function(chunk) { + this.chunks.push(chunk); +}; + + +/** + * Inflate#onEnd(status) -> Void + * - status (Number): inflate status. 0 (Z_OK) on success, + * other if not. + * + * Called once after you tell inflate that input stream complete + * or error happenned. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Inflate.prototype.onEnd = function(status) { + // On success - join + if (status === c.Z_OK) { + if (this.options.to === 'string') { + // Glue & convert here, until we teach pako to send + // utf8 alligned strings to onData + this.result = this.chunks.join(''); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * inflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Decompress `data` with inflate/ungzip and `options`. Autodetect + * format via wrapper header by default. That's why we don't provide + * separate `ungzip` method. + * + * Supported options are: + * + * - windowBits + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , input = pako.deflate([1,2,3,4,5,6,7,8,9]) + * , output; + * + * try { + * output = pako.inflate(input); + * } catch (err) + * console.log(err); + * } + * ``` + **/ +function inflate(input, options) { + var inflator = new Inflate(options); + + inflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (inflator.err) { throw inflator.msg; } + + return inflator.result; +} + + +/** + * inflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * The same as [[inflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function inflateRaw(input, options) { + options = options || {}; + options.raw = true; + return inflate(input, options); +} + + +/** + * ungzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Just shortcut to [[inflate]], because it autodetects format + * by header.content. Done for convenience. + **/ + + +exports.Inflate = Inflate; +exports.inflate = inflate; +exports.inflateRaw = inflateRaw; +exports.ungzip = inflate; + +},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(_dereq_,module,exports){ +'use strict'; + + +var TYPED_OK = (typeof Uint8Array !== 'undefined') && + (typeof Uint16Array !== 'undefined') && + (typeof Int32Array !== 'undefined'); + + +exports.assign = function (obj /*from1, from2, from3, ...*/) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { continue; } + + if (typeof(source) !== 'object') { + throw new TypeError(source + 'must be non-object'); + } + + for (var p in source) { + if (source.hasOwnProperty(p)) { + obj[p] = source[p]; + } + } + } + + return obj; +}; + + +// reduce buffer size, avoiding mem copy +exports.shrinkBuf = function (buf, size) { + if (buf.length === size) { return buf; } + if (buf.subarray) { return buf.subarray(0, size); } + buf.length = size; + return buf; +}; + + +var fnTyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + if (src.subarray && dest.subarray) { + dest.set(src.subarray(src_offs, src_offs+len), dest_offs); + return; + } + // Fallback to ordinary array + for(var i=0; i= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start + + +// convert string to array (typed, when possible) +exports.string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + buf = new utils.Buf8(buf_len); + + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Helper (used in 2 places) +function buf2binstring(buf, len) { + // use fallback for big arrays to avoid stack overflow + if (len < 65537) { + if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) { + return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len)); + } + } + + var result = ''; + for(var i=0; i < len; i++) { + result += String.fromCharCode(buf[i]); + } + return result; +} + + +// Convert byte array to binary string +exports.buf2binstring = function(buf) { + return buf2binstring(buf, buf.length); +}; + + +// Convert binary string (typed, when possible) +exports.binstring2buf = function(str) { + var buf = new utils.Buf8(str.length); + for(var i=0, len=buf.length; i < len; i++) { + buf[i] = str.charCodeAt(i); + } + return buf; +}; + + +// convert array to string +exports.buf2string = function (buf, max) { + var i, out, c, c_len; + var len = max || buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); + + for (out=0, i=0; i 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + return buf2binstring(utf16buf, out); +}; + + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +exports.utf8border = function(buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +},{"./common":27}],29:[function(_dereq_,module,exports){ +'use strict'; + +// Note: adler32 takes 12% for level 0 and 2% for level 6. +// It doesn't worth to make additional optimizationa as in original. +// Small size is preferable. + +function adler32(adler, buf, len, pos) { + var s1 = (adler & 0xffff) |0 + , s2 = ((adler >>> 16) & 0xffff) |0 + , n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; + + do { + s1 = (s1 + buf[pos++]) |0; + s2 = (s2 + s1) |0; + } while (--n); + + s1 %= 65521; + s2 %= 65521; + } + + return (s1 | (s2 << 16)) |0; +} + + +module.exports = adler32; +},{}],30:[function(_dereq_,module,exports){ +module.exports = { + + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + //Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + + + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + + /* The deflate compression method */ + Z_DEFLATED: 8 + //Z_NULL: null // Use -1 or null inline, depending on var type +}; +},{}],31:[function(_dereq_,module,exports){ +'use strict'; + +// Note: we can't get significant speed boost here. +// So write code to minimize size - no pregenerated tables +// and array tools dependencies. + + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for(var n =0; n < 256; n++){ + c = n; + for(var k =0; k < 8; k++){ + c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable + , end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + + +module.exports = crc32; +},{}],32:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('../utils/common'); +var trees = _dereq_('./trees'); +var adler32 = _dereq_('./adler32'); +var crc32 = _dereq_('./crc32'); +var msg = _dereq_('./messages'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +var Z_NO_FLUSH = 0; +var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +//var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +//var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +//var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + + +/* compression levels */ +//var Z_NO_COMPRESSION = 0; +//var Z_BEST_SPEED = 1; +//var Z_BEST_COMPRESSION = 9; +var Z_DEFAULT_COMPRESSION = -1; + + +var Z_FILTERED = 1; +var Z_HUFFMAN_ONLY = 2; +var Z_RLE = 3; +var Z_FIXED = 4; +var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +//var Z_BINARY = 0; +//var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + + +/* The deflate compression method */ +var Z_DEFLATED = 8; + +/*============================================================================*/ + + +var MAX_MEM_LEVEL = 9; +/* Maximum value for memLevel in deflateInit2 */ +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_MEM_LEVEL = 8; + + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ +var LITERALS = 256; +/* number of literal bytes 0..255 */ +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ +var D_CODES = 30; +/* number of distance codes */ +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ +var HEAP_SIZE = 2*L_CODES + 1; +/* maximum heap size */ +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + +var PRESET_DICT = 0x20; + +var INIT_STATE = 42; +var EXTRA_STATE = 69; +var NAME_STATE = 73; +var COMMENT_STATE = 91; +var HCRC_STATE = 103; +var BUSY_STATE = 113; +var FINISH_STATE = 666; + +var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ +var BS_BLOCK_DONE = 2; /* block flush performed */ +var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ +var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ + +var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. + +function err(strm, errorCode) { + strm.msg = msg[errorCode]; + return errorCode; +} + +function rank(f) { + return ((f) << 1) - ((f) > 4 ? 9 : 0); +} + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->output buffer and copying into it. + * (See also read_buf()). + */ +function flush_pending(strm) { + var s = strm.state; + + //_tr_flush_bits(s); + var len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { return; } + + utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } +} + + +function flush_block_only (s, last) { + trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); + s.block_start = s.strstart; + flush_pending(s.strm); +} + + +function put_byte(s, b) { + s.pending_buf[s.pending++] = b; +} + + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +function putShortMSB(s, b) { +// put_byte(s, (Byte)(b >> 8)); +// put_byte(s, (Byte)(b & 0xff)); + s.pending_buf[s.pending++] = (b >>> 8) & 0xff; + s.pending_buf[s.pending++] = b & 0xff; +} + + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->input buffer and copying from it. + * (See also flush_pending()). + */ +function read_buf(strm, buf, start, size) { + var len = strm.avail_in; + + if (len > size) { len = size; } + if (len === 0) { return 0; } + + strm.avail_in -= len; + + utils.arraySet(buf, strm.input, strm.next_in, len, start); + if (strm.state.wrap === 1) { + strm.adler = adler32(strm.adler, buf, len, start); + } + + else if (strm.state.wrap === 2) { + strm.adler = crc32(strm.adler, buf, len, start); + } + + strm.next_in += len; + strm.total_in += len; + + return len; +} + + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +function longest_match(s, cur_match) { + var chain_length = s.max_chain_length; /* max hash chain length */ + var scan = s.strstart; /* current string */ + var match; /* matched string */ + var len; /* length of current match */ + var best_len = s.prev_length; /* best match length so far */ + var nice_match = s.nice_match; /* stop if match long enough */ + var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? + s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; + + var _win = s.window; // shortcut + + var wmask = s.w_mask; + var prev = s.prev; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + + var strend = s.strstart + MAX_MATCH; + var scan_end1 = _win[scan + best_len - 1]; + var scan_end = _win[scan + best_len]; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if (nice_match > s.lookahead) { nice_match = s.lookahead; } + + // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + // Assert(cur_match < s->strstart, "no future"); + match = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ + + if (_win[match + best_len] !== scan_end || + _win[match + best_len - 1] !== scan_end1 || + _win[match] !== _win[scan] || + _win[++match] !== _win[scan + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2; + match++; + // Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + /*jshint noempty:false*/ + } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + scan < strend); + + // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); + + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; +} + + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +function fill_window(s) { + var _w_size = s.w_size; + var p, n, m, more, str; + + //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s.window_size - s.lookahead - s.strstart; + + // JS ints have 32 bit, block below not needed + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} + + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { + + utils.arraySet(s.window, s.window, _w_size, _w_size, 0); + s.match_start -= _w_size; + s.strstart -= _w_size; + /* we now have strstart >= MAX_DIST */ + s.block_start -= _w_size; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = (m >= _w_size ? m - _w_size : 0); + } while (--n); + + n = _w_size; + p = n; + do { + m = s.prev[--p]; + s.prev[p] = (m >= _w_size ? m - _w_size : 0); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + //Assert(more >= 2, "more < 2"); + n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); + s.lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; +//#if MIN_MATCH != 3 +// Call update_hash() MIN_MATCH-3 more times +//#endif + while (s.insert) { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH-1]) & s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { + break; + } + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ +// if (s.high_water < s.window_size) { +// var curr = s.strstart + s.lookahead; +// var init = 0; +// +// if (s.high_water < curr) { +// /* Previous high water mark below current data -- zero WIN_INIT +// * bytes or up to end of window, whichever is less. +// */ +// init = s.window_size - curr; +// if (init > WIN_INIT) +// init = WIN_INIT; +// zmemzero(s->window + curr, (unsigned)init); +// s->high_water = curr + init; +// } +// else if (s->high_water < (ulg)curr + WIN_INIT) { +// /* High water mark at or above current data, but below current data +// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up +// * to end of window, whichever is less. +// */ +// init = (ulg)curr + WIN_INIT - s->high_water; +// if (init > s->window_size - s->high_water) +// init = s->window_size - s->high_water; +// zmemzero(s->window + s->high_water, (unsigned)init); +// s->high_water += init; +// } +// } +// +// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, +// "not enough room for search"); +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +function deflate_stored(s, flush) { + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + var max_block_size = 0xffff; + + if (max_block_size > s.pending_buf_size - 5) { + max_block_size = s.pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s.lookahead <= 1) { + + //Assert(s->strstart < s->w_size+MAX_DIST(s) || + // s->block_start >= (long)s->w_size, "slide too late"); +// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || +// s.block_start >= s.w_size)) { +// throw new Error("slide too late"); +// } + + fill_window(s); + if (s.lookahead === 0 && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + + if (s.lookahead === 0) { + break; + } + /* flush the current block */ + } + //Assert(s->block_start >= 0L, "block gone"); +// if (s.block_start < 0) throw new Error("block gone"); + + s.strstart += s.lookahead; + s.lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + var max_start = s.block_start + max_block_size; + + if (s.strstart === 0 || s.strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s.lookahead = s.strstart - max_start; + s.strstart = max_start; + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + + + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + + s.insert = 0; + + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + + if (s.strstart > s.block_start) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_NEED_MORE; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +function deflate_fast(s, flush) { + var hash_head; /* head of the hash chain */ + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; /* flush the current block */ + } + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + if (s.match_length >= MIN_MATCH) { + // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only + + /*** _tr_tally_dist(s, s.strstart - s.match_start, + s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { + s.match_length--; /* string at strstart already in table */ + do { + s.strstart++; + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s.match_length !== 0); + s.strstart++; + } else + { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; + +//#if MIN_MATCH != 3 +// Call UPDATE_HASH() MIN_MATCH-3 more times +//#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s.window[s.strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = ((s.strstart < (MIN_MATCH-1)) ? s.strstart : MIN_MATCH-1); + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +function deflate_slow(s, flush) { + var hash_head; /* head of hash chain */ + var bflush; /* set if current block must be flushed */ + + var max_insert; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + */ + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH-1; + + if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && + s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + + if (s.match_length <= 5 && + (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s.match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { + max_insert = s.strstart + s.lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + //check_match(s, s.strstart-1, s.prev_match, s.prev_length); + + /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH, bflush);***/ + bflush = trees._tr_tally(s, s.strstart - 1- s.prev_match, s.prev_length - MIN_MATCH); + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s.lookahead -= s.prev_length-1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH-1; + s.strstart++; + + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + } else if (s.match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); + + if (bflush) { + /*** FLUSH_BLOCK_ONLY(s, 0) ***/ + flush_block_only(s, false); + /***/ + } + s.strstart++; + s.lookahead--; + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s.match_available = 1; + s.strstart++; + s.lookahead--; + } + } + //Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s.match_available) { + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); + + s.match_available = 0; + } + s.insert = s.strstart < MIN_MATCH-1 ? s.strstart : MIN_MATCH-1; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_BLOCK_DONE; +} + + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +function deflate_rle(s, flush) { + var bflush; /* set if current block must be flushed */ + var prev; /* byte at distance one to match */ + var scan, strend; /* scan goes up to strend for length of run */ + + var _win = s.window; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { + strend = s.strstart + MAX_MATCH; + do { + /*jshint noempty:false*/ + } while (prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + scan < strend); + s.match_length = MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; + } + } + //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s.match_length >= MIN_MATCH) { + //check_match(s, s.strstart, s.strstart - 1, s.match_length); + + /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +function deflate_huff(s, flush) { + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s.lookahead === 0) { + fill_window(s); + if (s.lookahead === 0) { + if (flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s.match_length = 0; + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +var Config = function (good_length, max_lazy, nice_length, max_chain, func) { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; +}; + +var configuration_table; + +configuration_table = [ + /* good lazy nice chain */ + new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ + new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ + new Config(4, 5, 16, 8, deflate_fast), /* 2 */ + new Config(4, 6, 32, 32, deflate_fast), /* 3 */ + + new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ + new Config(8, 16, 32, 32, deflate_slow), /* 5 */ + new Config(8, 16, 128, 128, deflate_slow), /* 6 */ + new Config(8, 32, 128, 256, deflate_slow), /* 7 */ + new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ + new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ +]; + + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +function lm_init(s) { + s.window_size = 2 * s.w_size; + + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + + /* Set the default configuration parameters: + */ + s.max_lazy_match = configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = configuration_table[s.level].max_chain; + + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; +} + + +function DeflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.status = 0; /* as the name implies */ + this.pending_buf = null; /* output still pending */ + this.pending_buf_size = 0; /* size of pending_buf */ + this.pending_out = 0; /* next pending byte to output to the stream */ + this.pending = 0; /* nb of bytes in the pending buffer */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.gzhead = null; /* gzip header information to write */ + this.gzindex = 0; /* where in extra, name, or comment */ + this.method = Z_DEFLATED; /* can only be DEFLATED */ + this.last_flush = -1; /* value of flush param for previous deflate call */ + + this.w_size = 0; /* LZ77 window size (32K by default) */ + this.w_bits = 0; /* log2(w_size) (8..16) */ + this.w_mask = 0; /* w_size - 1 */ + + this.window = null; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. + */ + + this.window_size = 0; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + this.prev = null; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + this.head = null; /* Heads of the hash chains or NIL. */ + + this.ins_h = 0; /* hash index of string to be inserted */ + this.hash_size = 0; /* number of elements in hash table */ + this.hash_bits = 0; /* log2(hash_size) */ + this.hash_mask = 0; /* hash_size-1 */ + + this.hash_shift = 0; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + this.block_start = 0; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + this.match_length = 0; /* length of best match */ + this.prev_match = 0; /* previous match */ + this.match_available = 0; /* set if previous match exists */ + this.strstart = 0; /* start of string to insert */ + this.match_start = 0; /* start of matching string */ + this.lookahead = 0; /* number of valid bytes ahead in window */ + + this.prev_length = 0; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + this.max_chain_length = 0; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + this.max_lazy_match = 0; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ + // That's alias to max_lazy_match, don't use directly + //this.max_insert_length = 0; + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + this.level = 0; /* compression level (1..9) */ + this.strategy = 0; /* favor or force Huffman coding*/ + + this.good_match = 0; + /* Use a faster search when the previous match is longer than this */ + + this.nice_match = 0; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + + /* Didn't use ct_data typedef below to suppress compiler warning */ + + // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + // Use flat array of DOUBLE size, with interleaved fata, + // because JS does not support effective + this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new utils.Buf16((2*D_CODES+1) * 2); + this.bl_tree = new utils.Buf16((2*BL_CODES+1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); + + this.l_desc = null; /* desc. for literal tree */ + this.d_desc = null; /* desc. for distance tree */ + this.bl_desc = null; /* desc. for bit length tree */ + + //ush bl_count[MAX_BITS+1]; + this.bl_count = new utils.Buf16(MAX_BITS+1); + /* number of codes at each bit length for an optimal tree */ + + //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + this.heap = new utils.Buf16(2*L_CODES+1); /* heap used to build the Huffman trees */ + zero(this.heap); + + this.heap_len = 0; /* number of elements in the heap */ + this.heap_max = 0; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + this.depth = new utils.Buf16(2*L_CODES+1); //uch depth[2*L_CODES+1]; + zero(this.depth); + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + this.l_buf = 0; /* buffer index for literals or lengths */ + + this.lit_bufsize = 0; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + this.last_lit = 0; /* running index in l_buf */ + + this.d_buf = 0; + /* Buffer index for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + this.opt_len = 0; /* bit length of current block with optimal trees */ + this.static_len = 0; /* bit length of current block with static trees */ + this.matches = 0; /* number of string matches in current block */ + this.insert = 0; /* bytes at end of window left to insert */ + + + this.bi_buf = 0; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + this.bi_valid = 0; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + // Used for window memory init. We safely ignore it for JS. That makes + // sense only for pointers and memory check tools. + //this.high_water = 0; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ +} + + +function deflateResetKeep(strm) { + var s; + + if (!strm || !strm.state) { + return err(strm, Z_STREAM_ERROR); + } + + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; + + s = strm.state; + s.pending = 0; + s.pending_out = 0; + + if (s.wrap < 0) { + s.wrap = -s.wrap; + /* was made negative by deflate(..., Z_FINISH); */ + } + s.status = (s.wrap ? INIT_STATE : BUSY_STATE); + strm.adler = (s.wrap === 2) ? + 0 // crc32(0, Z_NULL, 0) + : + 1; // adler32(0, Z_NULL, 0) + s.last_flush = Z_NO_FLUSH; + trees._tr_init(s); + return Z_OK; +} + + +function deflateReset(strm) { + var ret = deflateResetKeep(strm); + if (ret === Z_OK) { + lm_init(strm.state); + } + return ret; +} + + +function deflateSetHeader(strm, head) { + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } + strm.state.gzhead = head; + return Z_OK; +} + + +function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { + if (!strm) { // === Z_NULL + return Z_STREAM_ERROR; + } + var wrap = 1; + + if (level === Z_DEFAULT_COMPRESSION) { + level = 6; + } + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } + + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } + + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return err(strm, Z_STREAM_ERROR); + } + + + if (windowBits === 8) { + windowBits = 9; + } + /* until 256-byte window bug fixed */ + + var s = new DeflateState(); + + strm.state = s; + s.strm = strm; + + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; + + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); + + s.window = new utils.Buf8(s.w_size * 2); + s.head = new utils.Buf16(s.hash_size); + s.prev = new utils.Buf16(s.w_size); + + // Don't need mem init magic for JS. + //s.high_water = 0; /* nothing written to s->window yet */ + + s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + s.pending_buf_size = s.lit_bufsize * 4; + s.pending_buf = new utils.Buf8(s.pending_buf_size); + + s.d_buf = s.lit_bufsize >> 1; + s.l_buf = (1 + 2) * s.lit_bufsize; + + s.level = level; + s.strategy = strategy; + s.method = method; + + return deflateReset(strm); +} + +function deflateInit(strm, level) { + return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} + + +function deflate(strm, flush) { + var old_flush, s; + var beg, val; // for gzip header write only + + if (!strm || !strm.state || + flush > Z_BLOCK || flush < 0) { + return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; + } + + s = strm.state; + + if (!strm.output || + (!strm.input && strm.avail_in !== 0) || + (s.status === FINISH_STATE && flush !== Z_FINISH)) { + return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); + } + + s.strm = strm; /* just in case */ + old_flush = s.last_flush; + s.last_flush = flush; + + /* Write the header */ + if (s.status === INIT_STATE) { + + if (s.wrap === 2) { // GZIP header + strm.adler = 0; //crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { // s->gzhead == Z_NULL + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + } + else { + put_byte(s, (s.gzhead.text ? 1 : 0) + + (s.gzhead.hcrc ? 2 : 0) + + (!s.gzhead.extra ? 0 : 4) + + (!s.gzhead.name ? 0 : 8) + + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 0xff); + put_byte(s, (s.gzhead.time >> 8) & 0xff); + put_byte(s, (s.gzhead.time >> 16) & 0xff); + put_byte(s, (s.gzhead.time >> 24) & 0xff); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, s.gzhead.os & 0xff); + if (s.gzhead.extra && s.gzhead.extra.length) { + put_byte(s, s.gzhead.extra.length & 0xff); + put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); + } + if (s.gzhead.hcrc) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); + } + s.gzindex = 0; + s.status = EXTRA_STATE; + } + } + else // DEFLATE header + { + var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; + var level_flags = -1; + + if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= (level_flags << 6); + if (s.strstart !== 0) { header |= PRESET_DICT; } + header += 31 - (header % 31); + + s.status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + strm.adler = 1; // adler32(0L, Z_NULL, 0); + } + } + +//#ifdef GZIP + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + + while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + break; + } + } + put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); + s.gzindex++; + } + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (s.gzindex === s.gzhead.extra.length) { + s.gzindex = 0; + s.status = NAME_STATE; + } + } + else { + s.status = NAME_STATE; + } + } + if (s.status === NAME_STATE) { + if (s.gzhead.name/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.name.length) { + val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg){ + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.gzindex = 0; + s.status = COMMENT_STATE; + } + } + else { + s.status = COMMENT_STATE; + } + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.comment.length) { + val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.status = HCRC_STATE; + } + } + else { + s.status = HCRC_STATE; + } + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); + } + if (s.pending + 2 <= s.pending_buf_size) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + strm.adler = 0; //crc32(0L, Z_NULL, 0); + s.status = BUSY_STATE; + } + } + else { + s.status = BUSY_STATE; + } + } +//#endif + + /* Flush as much pending output as possible */ + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s.last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && + flush !== Z_FINISH) { + return err(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm.avail_in !== 0 || s.lookahead !== 0 || + (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { + var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : + (s.strategy === Z_RLE ? deflate_rle(s, flush) : + configuration_table[s.level].func(s, flush)); + + if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { + s.status = FINISH_STATE; + } + if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { + if (strm.avail_out === 0) { + s.last_flush = -1; + /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate === BS_BLOCK_DONE) { + if (flush === Z_PARTIAL_FLUSH) { + trees._tr_align(s); + } + else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + + trees._tr_stored_block(s, 0, 0, false); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush === Z_FULL_FLUSH) { + /*** CLEAR_HASH(s); ***/ /* forget history */ + zero(s.head); // Fill with NIL (= 0); + + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + //Assert(strm->avail_out > 0, "bug2"); + //if (strm.avail_out <= 0) { throw new Error("bug2");} + + if (flush !== Z_FINISH) { return Z_OK; } + if (s.wrap <= 0) { return Z_STREAM_END; } + + /* Write the trailer */ + if (s.wrap === 2) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + put_byte(s, (strm.adler >> 16) & 0xff); + put_byte(s, (strm.adler >> 24) & 0xff); + put_byte(s, strm.total_in & 0xff); + put_byte(s, (strm.total_in >> 8) & 0xff); + put_byte(s, (strm.total_in >> 16) & 0xff); + put_byte(s, (strm.total_in >> 24) & 0xff); + } + else + { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s.wrap > 0) { s.wrap = -s.wrap; } + /* write the trailer only once! */ + return s.pending !== 0 ? Z_OK : Z_STREAM_END; +} + +function deflateEnd(strm) { + var status; + + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + status = strm.state.status; + if (status !== INIT_STATE && + status !== EXTRA_STATE && + status !== NAME_STATE && + status !== COMMENT_STATE && + status !== HCRC_STATE && + status !== BUSY_STATE && + status !== FINISH_STATE + ) { + return err(strm, Z_STREAM_ERROR); + } + + strm.state = null; + + return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state + */ +//function deflateCopy(dest, source) { +// +//} + +exports.deflateInit = deflateInit; +exports.deflateInit2 = deflateInit2; +exports.deflateReset = deflateReset; +exports.deflateResetKeep = deflateResetKeep; +exports.deflateSetHeader = deflateSetHeader; +exports.deflate = deflate; +exports.deflateEnd = deflateEnd; +exports.deflateInfo = 'pako deflate (from Nodeca project)'; + +/* Not implemented +exports.deflateBound = deflateBound; +exports.deflateCopy = deflateCopy; +exports.deflateSetDictionary = deflateSetDictionary; +exports.deflateParams = deflateParams; +exports.deflatePending = deflatePending; +exports.deflatePrime = deflatePrime; +exports.deflateTune = deflateTune; +*/ +},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(_dereq_,module,exports){ +'use strict'; + + +function GZheader() { + /* true if compressed data believed to be text */ + this.text = 0; + /* modification time */ + this.time = 0; + /* extra flags (not used when writing a gzip file) */ + this.xflags = 0; + /* operating system */ + this.os = 0; + /* pointer to extra field or Z_NULL if none */ + this.extra = null; + /* extra field length (valid if extra != Z_NULL) */ + this.extra_len = 0; // Actually, we don't need it in JS, + // but leave for few code modifications + + // + // Setup limits is not necessary because in js we should not preallocate memory + // for inflate use constant limit in 65536 bytes + // + + /* space at extra (only when reading header) */ + // this.extra_max = 0; + /* pointer to zero-terminated file name or Z_NULL */ + this.name = ''; + /* space at name (only when reading header) */ + // this.name_max = 0; + /* pointer to zero-terminated comment or Z_NULL */ + this.comment = ''; + /* space at comment (only when reading header) */ + // this.comm_max = 0; + /* true if there was or will be a header crc */ + this.hcrc = 0; + /* true when done reading gzip header (not used when writing a gzip file) */ + this.done = false; +} + +module.exports = GZheader; +},{}],34:[function(_dereq_,module,exports){ +'use strict'; + +// See state defs from inflate.js +var BAD = 30; /* got a data error -- remain here until reset */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ +module.exports = function inflate_fast(strm, start) { + var state; + var _in; /* local strm.input */ + var last; /* have enough input while in < last */ + var _out; /* local strm.output */ + var beg; /* inflate()'s initial strm.output */ + var end; /* while out < end, enough space available */ +//#ifdef INFLATE_STRICT + var dmax; /* maximum distance from zlib header */ +//#endif + var wsize; /* window size or zero if not using window */ + var whave; /* valid bytes in the window */ + var wnext; /* window write index */ + var window; /* allocated sliding window, if wsize != 0 */ + var hold; /* local strm.hold */ + var bits; /* local strm.bits */ + var lcode; /* local strm.lencode */ + var dcode; /* local strm.distcode */ + var lmask; /* mask for first level of length codes */ + var dmask; /* mask for first level of distance codes */ + var here; /* retrieved table entry */ + var op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + var len; /* match length, unused bytes */ + var dist; /* match distance */ + var from; /* where to copy match from */ + var from_source; + + + var input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); +//#ifdef INFLATE_STRICT + dmax = state.dmax; +//#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + + here = lcode[hold & lmask]; + + dolen: + for (;;) { // Goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + if (op === 0) { /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff/*here.val*/; + } + else if (op & 16) { /* length base */ + len = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; + } + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: + for (;;) { // goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + + if (op & 16) { /* distance base */ + dist = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + } + dist += hold & ((1 << op) - 1); +//#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } +//#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = _out - beg; /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// if (len <= op - whave) { +// do { +// output[_out++] = 0; +// } while (--len); +// continue top; +// } +// len -= op - whave; +// do { +// output[_out++] = 0; +// } while (--op > whave); +// if (op === 0) { +// from = _out - dist; +// do { +// output[_out++] = output[from++]; +// } while (--len); +// continue top; +// } +//#endif + } + from = 0; // window index + from_source = window; + if (wnext === 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = 0; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { + output[_out++] = from_source[from++]; + } + } + } + else { + from = _out - dist; /* copy direct from output */ + do { /* minimum length is three */ + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { + output[_out++] = output[from++]; + } + } + } + } + else if ((op & 64) === 0) { /* 2nd level distance code */ + here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dodist; + } + else { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } + else if ((op & 64) === 0) { /* 2nd level length code */ + here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dolen; + } + else if (op & 32) { /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE; + break top; + } + else { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); + strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); + state.hold = hold; + state.bits = bits; + return; +}; + +},{}],35:[function(_dereq_,module,exports){ +'use strict'; + + +var utils = _dereq_('../utils/common'); +var adler32 = _dereq_('./adler32'); +var crc32 = _dereq_('./crc32'); +var inflate_fast = _dereq_('./inffast'); +var inflate_table = _dereq_('./inftrees'); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +//var Z_NO_FLUSH = 0; +//var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +//var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + +/* The deflate compression method */ +var Z_DEFLATED = 8; + + +/* STATES ====================================================================*/ +/* ===========================================================================*/ + + +var HEAD = 1; /* i: waiting for magic header */ +var FLAGS = 2; /* i: waiting for method and flags (gzip) */ +var TIME = 3; /* i: waiting for modification time (gzip) */ +var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ +var EXLEN = 5; /* i: waiting for extra length (gzip) */ +var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ +var NAME = 7; /* i: waiting for end of file name (gzip) */ +var COMMENT = 8; /* i: waiting for end of comment (gzip) */ +var HCRC = 9; /* i: waiting for header crc (gzip) */ +var DICTID = 10; /* i: waiting for dictionary check value */ +var DICT = 11; /* waiting for inflateSetDictionary() call */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ +var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ +var STORED = 14; /* i: waiting for stored size (length and complement) */ +var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ +var COPY = 16; /* i/o: waiting for input or output to copy stored block */ +var TABLE = 17; /* i: waiting for dynamic block table lengths */ +var LENLENS = 18; /* i: waiting for code length code lengths */ +var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ +var LEN_ = 20; /* i: same as LEN below, but only first time in */ +var LEN = 21; /* i: waiting for length/lit/eob code */ +var LENEXT = 22; /* i: waiting for length extra bits */ +var DIST = 23; /* i: waiting for distance code */ +var DISTEXT = 24; /* i: waiting for distance extra bits */ +var MATCH = 25; /* o: waiting for output space to copy string */ +var LIT = 26; /* o: waiting for output space to write literal */ +var CHECK = 27; /* i: waiting for 32-bit check value */ +var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ +var DONE = 29; /* finished check, done -- remain here until reset */ +var BAD = 30; /* got a data error -- remain here until reset */ +var MEM = 31; /* got an inflate() memory error -- remain here until reset */ +var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ + +/* ===========================================================================*/ + + + +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_WBITS = MAX_WBITS; + + +function ZSWAP32(q) { + return (((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24)); +} + + +function InflateState() { + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib) */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = null; /* starting table for length/literal codes */ + this.distcode = null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ + this.work = new utils.Buf16(288); /* work area for code table building */ + + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ + this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ +} + +function inflateResetKeep(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ''; /*Z_NULL*/ + if (state.wrap) { /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null/*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); + state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +function inflateReset(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + +} + +function inflateReset2(strm, windowBits) { + var wrap; + var state; + + /* get the state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; + } + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; + } + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; + } + + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); +} + +function inflateInit2(strm, windowBits) { + var ret; + var state; + + if (!strm) { return Z_STREAM_ERROR; } + //strm.msg = Z_NULL; /* in case we return an error */ + + state = new InflateState(); + + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.window = null/*Z_NULL*/; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null/*Z_NULL*/; + } + return ret; +} + +function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); +} + + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +var virgin = true; + +var lenfix, distfix; // We have no pointers in JS, so keep tables separate + +function fixedtables(state) { + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + var sym; + + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); + + /* literal/length table */ + sym = 0; + while (sym < 144) { state.lens[sym++] = 8; } + while (sym < 256) { state.lens[sym++] = 9; } + while (sym < 280) { state.lens[sym++] = 7; } + while (sym < 288) { state.lens[sym++] = 8; } + + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {bits: 9}); + + /* distance table */ + sym = 0; + while (sym < 32) { state.lens[sym++] = 5; } + + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {bits: 5}); + + /* do this just once */ + virgin = false; + } + + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; +} + + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +function updatewindow(strm, src, end, copy) { + var dist; + var state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new utils.Buf8(state.wsize); + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + utils.arraySet(state.window,src, end - state.wsize, state.wsize, 0); + state.wnext = 0; + state.whave = state.wsize; + } + else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; + } + //zmemcpy(state->window + state->wnext, end - copy, dist); + utils.arraySet(state.window,src, end - copy, dist, state.wnext); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + utils.arraySet(state.window,src, end - copy, copy, 0); + state.wnext = copy; + state.whave = state.wsize; + } + else { + state.wnext += dist; + if (state.wnext === state.wsize) { state.wnext = 0; } + if (state.whave < state.wsize) { state.whave += dist; } + } + } + return 0; +} + +function inflate(strm, flush) { + var state; + var input, output; // input/output buffers + var next; /* next input INDEX */ + var put; /* next output INDEX */ + var have, left; /* available input and output */ + var hold; /* bit buffer */ + var bits; /* bits in bit buffer */ + var _in, _out; /* save starting available input and output */ + var copy; /* number of stored or match bytes to copy */ + var from; /* where to copy match bytes from */ + var from_source; + var here = 0; /* current decoding table entry */ + var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //var last; /* parent table entry */ + var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + var len; /* length to copy for repeats, bits to drop */ + var ret; /* return code */ + var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ + var opts; + + var n; // temporary var for NEED_BITS + + var order = /* permutation of code lengths */ + [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + + + if (!strm || !strm.state || !strm.output || + (!strm.input && strm.avail_in !== 0)) { + return Z_STREAM_ERROR; + } + + state = strm.state; + if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ + + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK; + + inf_leave: // goto emulation + for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ + state.check = 0/*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = FLAGS; + break; + } + state.flags = 0; /* expect zlib header */ + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { + strm.msg = 'incorrect header check'; + state.mode = BAD; + break; + } + if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f)/*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } + else if (len > state.wbits) { + strm.msg = 'invalid window size'; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = 'unknown header flags set'; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = ((hold >> 8) & 1); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if (state.flags & 0x0200) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32(state.check, hbuf, 4, 0); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = (hold & 0xff); + state.head.os = (hold >> 8); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + else if (state.head) { + state.head.extra = null/*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { copy = have; } + if (copy) { + if (state.head) { + len = state.head.extra_len - state.length; + if (!state.head.extra) { + // Use untyped array for more conveniend processing later + state.head.extra = new Array(state.head.extra_len); + } + utils.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); + } + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + state.length -= copy; + } + if (state.length) { break inf_leave; } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.name_max*/)) { + state.head.name += String.fromCharCode(len); + } + } while (len && copy < have); + + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.comm_max*/)) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy < have); + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.check & 0xffff)) { + strm.msg = 'header crc mismatch'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + if (state.head) { + state.head.hcrc = ((state.flags >> 9) & 1); + state.head.done = true; + } + strm.adler = state.check = 0 /*crc32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = ZSWAP32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT; + } + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + /* falls through */ + case TYPE: + if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = (hold & 0x01)/*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch ((hold & 0x03)/*BITS(2)*/) { + case 0: /* stored block */ + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2: /* dynamic block */ + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = 'invalid block type'; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { + strm.msg = 'invalid stored block lengths'; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { copy = have; } + if (copy > left) { copy = left; } + if (copy === 0) { break inf_leave; } + //--- zmemcpy(put, next, copy); --- + utils.arraySet(output, input, next, copy, put); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// +//#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = 'too many length or distance symbols'; + state.mode = BAD; + break; + } +//#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = {bits: state.lenbits}; + ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = 'invalid code lengths set'; + state.mode = BAD; + break; + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.lens[state.have++] = here_val; + } + else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + if (state.have === 0) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + len = state.lens[state.have - 1]; + copy = 3 + (hold & 0x03);//BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } + else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f);//BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if (state.have + copy > state.nlen + state.ndist) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; + } + } + } + + /* handle error breaks in while */ + if (state.mode === BAD) { break; } + + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = 'invalid code -- missing end-of-block'; + state.mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = {bits: state.lenbits}; + ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = 'invalid literal/lengths set'; + state.mode = BAD; + break; + } + + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = {bits: state.distbits}; + ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = 'invalid distances set'; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inflate_fast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) -1)]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.lencode[last_val + + ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = state.distcode[hold & ((1 << state.distbits) -1)];/*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.distcode[last_val + + ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = (here_op) & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.offset += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } +//#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +//#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { break inf_leave; } + copy = _out - left; + if (state.offset > copy) { /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// Trace((stderr, "inflate.c too far\n")); +// copy -= state.whave; +// if (copy > state.length) { copy = state.length; } +// if (copy > left) { copy = left; } +// left -= copy; +// state.length -= copy; +// do { +// output[put++] = 0; +// } while (--copy); +// if (state.length === 0) { state.mode = LEN; } +// break; +//#endif + } + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; + } + else { + from = state.wnext - copy; + } + if (copy > state.length) { copy = state.length; } + from_source = state.window; + } + else { /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { copy = left; } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { state.mode = LEN; } + break; + case LIT: + if (left === 0) { break inf_leave; } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + // Use '|' insdead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; + } + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = + /*UPDATE(state.check, put - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); + + } + _out = left; + // NB: crc32 stored as signed 32-bit int, ZSWAP32 returns signed too + if ((state.flags ? hold : ZSWAP32(hold)) !== state.check) { + strm.msg = 'incorrect data check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.total & 0xffffffff)) { + strm.msg = 'incorrect length check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR; + } + } + + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH))) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { + state.mode = MEM; + return Z_MEM_ERROR; + } + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + + (state.mode === TYPE ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { + ret = Z_BUF_ERROR; + } + return ret; +} + +function inflateEnd(strm) { + + if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { + return Z_STREAM_ERROR; + } + + var state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK; +} + +function inflateGetHeader(strm, head) { + var state; + + /* check state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } + + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK; +} + + +exports.inflateReset = inflateReset; +exports.inflateReset2 = inflateReset2; +exports.inflateResetKeep = inflateResetKeep; +exports.inflateInit = inflateInit; +exports.inflateInit2 = inflateInit2; +exports.inflate = inflate; +exports.inflateEnd = inflateEnd; +exports.inflateGetHeader = inflateGetHeader; +exports.inflateInfo = 'pako inflate (from Nodeca project)'; + +/* Not implemented +exports.inflateCopy = inflateCopy; +exports.inflateGetDictionary = inflateGetDictionary; +exports.inflateMark = inflateMark; +exports.inflatePrime = inflatePrime; +exports.inflateSetDictionary = inflateSetDictionary; +exports.inflateSync = inflateSync; +exports.inflateSyncPoint = inflateSyncPoint; +exports.inflateUndermine = inflateUndermine; +*/ +},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(_dereq_,module,exports){ +'use strict'; + + +var utils = _dereq_('../utils/common'); + +var MAXBITS = 15; +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +var lbase = [ /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +]; + +var lext = [ /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 +]; + +var dbase = [ /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0 +]; + +var dext = [ /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64 +]; + +module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) +{ + var bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + var len = 0; /* a code's length in bits */ + var sym = 0; /* index of code symbols */ + var min = 0, max = 0; /* minimum and maximum code lengths */ + var root = 0; /* number of index bits for root table */ + var curr = 0; /* number of index bits for current table */ + var drop = 0; /* code bits to drop for sub-table */ + var left = 0; /* number of prefix codes available */ + var used = 0; /* code entries in table used */ + var huff = 0; /* Huffman code */ + var incr; /* for incrementing code, index */ + var fill; /* index for replicating entries */ + var low; /* low bits for current root entry */ + var mask; /* mask for low root bits */ + var next; /* next available space in table */ + var base = null; /* base value table to use */ + var base_index = 0; +// var shoextra; /* extra bits table to use */ + var end; /* use base and extra for symbol > end */ + var count = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */ + var extra = null; + var extra_index = 0; + + var here_bits, here_op, here_val; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { break; } + } + if (root > max) { + root = max; + } + if (max === 0) { /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { break; } + } + if (root < min) { + root = min; + } + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES || max !== 1)) { + return -1; /* incomplete set */ + } + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES) { + base = extra = work; /* dummy value--not used */ + end = 19; + } else if (type === LENS) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + } else { /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + var i=0; + /* process all codes and make table entries */ + for (;;) { + i++; + /* create table entry */ + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; + } + else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } + else { + here_op = 32 + 64; /* end of block */ + here_val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { break; } + len = lens[lens_index + work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { break; } + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1 << curr; + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + } + + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; +}; + +},{"../utils/common":27}],37:[function(_dereq_,module,exports){ +'use strict'; + +module.exports = { + '2': 'need dictionary', /* Z_NEED_DICT 2 */ + '1': 'stream end', /* Z_STREAM_END 1 */ + '0': '', /* Z_OK 0 */ + '-1': 'file error', /* Z_ERRNO (-1) */ + '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ + '-3': 'data error', /* Z_DATA_ERROR (-3) */ + '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ + '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ + '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ +}; +},{}],38:[function(_dereq_,module,exports){ +'use strict'; + + +var utils = _dereq_('../utils/common'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +//var Z_FILTERED = 1; +//var Z_HUFFMAN_ONLY = 2; +//var Z_RLE = 3; +var Z_FIXED = 4; +//var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +var Z_BINARY = 0; +var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + +/*============================================================================*/ + + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + +// From zutil.h + +var STORED_BLOCK = 0; +var STATIC_TREES = 1; +var DYN_TREES = 2; +/* The three kinds of block type */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +/* The minimum and maximum match lengths */ + +// From deflate.h +/* =========================================================================== + * Internal compression state. + */ + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ + +var LITERALS = 256; +/* number of literal bytes 0..255 */ + +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ + +var D_CODES = 30; +/* number of distance codes */ + +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ + +var HEAP_SIZE = 2*L_CODES + 1; +/* maximum heap size */ + +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var Buf_size = 16; +/* size of bit buffer in bi_buf */ + + +/* =========================================================================== + * Constants + */ + +var MAX_BL_BITS = 7; +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +var END_BLOCK = 256; +/* end of block literal code */ + +var REP_3_6 = 16; +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +var REPZ_3_10 = 17; +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +var REPZ_11_138 = 18; +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +var extra_lbits = /* extra bits for each length code */ + [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; + +var extra_dbits = /* extra bits for each distance code */ + [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; + +var extra_blbits = /* extra bits for each bit length code */ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; + +var bl_order = + [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +// We pre-fill arrays with 0 to avoid uninitialized gaps + +var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ + +// !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 +var static_ltree = new Array((L_CODES+2) * 2); +zero(static_ltree); +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +var static_dtree = new Array(D_CODES * 2); +zero(static_dtree); +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +var _dist_code = new Array(DIST_CODE_LEN); +zero(_dist_code); +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +var _length_code = new Array(MAX_MATCH-MIN_MATCH+1); +zero(_length_code); +/* length code for each normalized match length (0 == MIN_MATCH) */ + +var base_length = new Array(LENGTH_CODES); +zero(base_length); +/* First normalized length for each code (0 = MIN_MATCH) */ + +var base_dist = new Array(D_CODES); +zero(base_dist); +/* First normalized distance for each code (0 = distance of 1) */ + + +var StaticTreeDesc = function (static_tree, extra_bits, extra_base, elems, max_length) { + + this.static_tree = static_tree; /* static tree or NULL */ + this.extra_bits = extra_bits; /* extra bits for each code or NULL */ + this.extra_base = extra_base; /* base index for extra_bits */ + this.elems = elems; /* max number of elements in the tree */ + this.max_length = max_length; /* max bit length for the codes */ + + // show if `static_tree` has data or dummy - needed for monomorphic objects + this.has_stree = static_tree && static_tree.length; +}; + + +var static_l_desc; +var static_d_desc; +var static_bl_desc; + + +var TreeDesc = function(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; /* the dynamic tree */ + this.max_code = 0; /* largest code with non zero frequency */ + this.stat_desc = stat_desc; /* the corresponding static tree */ +}; + + + +function d_code(dist) { + return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; +} + + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +function put_short (s, w) { +// put_byte(s, (uch)((w) & 0xff)); +// put_byte(s, (uch)((ush)(w) >> 8)); + s.pending_buf[s.pending++] = (w) & 0xff; + s.pending_buf[s.pending++] = (w >>> 8) & 0xff; +} + + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +function send_bits(s, value, length) { + if (s.bi_valid > (Buf_size - length)) { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + put_short(s, s.bi_buf); + s.bi_buf = value >> (Buf_size - s.bi_valid); + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + s.bi_valid += length; + } +} + + +function send_code(s, c, tree) { + send_bits(s, tree[c*2]/*.Code*/, tree[c*2 + 1]/*.Len*/); +} + + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +function bi_reverse(code, len) { + var res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; +} + + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +function bi_flush(s) { + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; + + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 0xff; + s.bi_buf >>= 8; + s.bi_valid -= 8; + } +} + + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +function gen_bitlen(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var max_code = desc.max_code; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var extra = desc.stat_desc.extra_bits; + var base = desc.stat_desc.extra_base; + var max_length = desc.stat_desc.max_length; + var h; /* heap index */ + var n, m; /* iterate over the tree elements */ + var bits; /* bit length */ + var xbits; /* extra bits */ + var f; /* frequency */ + var overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) { + s.bl_count[bits] = 0; + } + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s.heap[s.heap_max]*2 + 1]/*.Len*/ = 0; /* root of the heap */ + + for (h = s.heap_max+1; h < HEAP_SIZE; h++) { + n = s.heap[h]; + bits = tree[tree[n*2 +1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n*2 + 1]/*.Len*/ = bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) { continue; } /* not a leaf node */ + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n-base]; + } + f = tree[n * 2]/*.Freq*/; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += f * (stree[n*2 + 1]/*.Len*/ + xbits); + } + } + if (overflow === 0) { return; } + + // Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s.bl_count[bits] === 0) { bits--; } + s.bl_count[bits]--; /* move one leaf down the tree */ + s.bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { continue; } + if (tree[m*2 + 1]/*.Len*/ !== bits) { + // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s.opt_len += (bits - tree[m*2 + 1]/*.Len*/)*tree[m*2]/*.Freq*/; + tree[m*2 + 1]/*.Len*/ = bits; + } + n--; + } + } +} + + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +function gen_codes(tree, max_code, bl_count) +// ct_data *tree; /* the tree to decorate */ +// int max_code; /* largest code with non zero frequency */ +// ushf *bl_count; /* number of codes at each bit length */ +{ + var next_code = new Array(MAX_BITS+1); /* next code value for each bit length */ + var code = 0; /* running code value */ + var bits; /* bit index */ + var n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) { + bl_count[bits] = 0; + } + + n = 0; + while (n <= 143) { + static_ltree[n*2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n*2 + 1]/*.Len*/ = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n*2 + 1]/*.Len*/ = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n*2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n*2 + 1]/*.Len*/ = 5; + static_dtree[n*2]/*.Code*/ = bi_reverse(n, 5); + } + + // Now data ready and we can init static trees + static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS); + static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); + static_bl_desc =new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); + + //static_init_done = true; +} + + +/* =========================================================================== + * Initialize a new block. + */ +function init_block(s) { + var n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n*2]/*.Freq*/ = 0; } + for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n*2]/*.Freq*/ = 0; } + for (n = 0; n < BL_CODES; n++) { s.bl_tree[n*2]/*.Freq*/ = 0; } + + s.dyn_ltree[END_BLOCK*2]/*.Freq*/ = 1; + s.opt_len = s.static_len = 0; + s.last_lit = s.matches = 0; +} + + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +function bi_windup(s) +{ + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + //put_byte(s, (Byte)s->bi_buf); + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +function copy_block(s, buf, len, header) +//DeflateState *s; +//charf *buf; /* the input data */ +//unsigned len; /* its length */ +//int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, len); + put_short(s, ~len); + } +// while (len--) { +// put_byte(s, *buf++); +// } + utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); + s.pending += len; +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +function smaller(tree, n, m, depth) { + var _n2 = n*2; + var _m2 = m*2; + return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || + (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); +} + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +function pqdownheap(s, tree, k) +// deflate_state *s; +// ct_data *tree; /* the tree to restore */ +// int k; /* node to move down */ +{ + var v = s.heap[k]; + var j = k << 1; /* left son of k */ + while (j <= s.heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s.heap_len && + smaller(tree, s.heap[j+1], s.heap[j], s.depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s.heap[j], s.depth)) { break; } + + /* Exchange v with the smallest son */ + s.heap[k] = s.heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s.heap[k] = v; +} + + +// inlined manually +// var SMALLEST = 1; + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +function compress_block(s, ltree, dtree) +// deflate_state *s; +// const ct_data *ltree; /* literal tree */ +// const ct_data *dtree; /* distance tree */ +{ + var dist; /* distance of matched string */ + var lc; /* match length or unmatched char (if dist == 0) */ + var lx = 0; /* running index in l_buf */ + var code; /* the code to send */ + var extra; /* number of extra bits to send */ + + if (s.last_lit !== 0) { + do { + dist = (s.pending_buf[s.d_buf + lx*2] << 8) | (s.pending_buf[s.d_buf + lx*2 + 1]); + lc = s.pending_buf[s.l_buf + lx]; + lx++; + + if (dist === 0) { + send_code(s, lc, ltree); /* send a literal byte */ + //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + //Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + // "pendingBuf overflow"); + + } while (lx < s.last_lit); + } + + send_code(s, END_BLOCK, ltree); +} + + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +function build_tree(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var elems = desc.stat_desc.elems; + var n, m; /* iterate over heap elements */ + var max_code = -1; /* largest code with non zero frequency */ + var node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n * 2]/*.Freq*/ !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + + } else { + tree[n*2 + 1]/*.Len*/ = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); + tree[node * 2]/*.Freq*/ = 1; + s.depth[node] = 0; + s.opt_len--; + + if (has_stree) { + s.static_len -= stree[node*2 + 1]/*.Len*/; + } + /* node is 0 or 1 so it does not have extra bits */ + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + //pqremove(s, tree, n); /* n = node of least frequency */ + /*** pqremove ***/ + n = s.heap[1/*SMALLEST*/]; + s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; + pqdownheap(s, tree, 1/*SMALLEST*/); + /***/ + + m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ + + s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; + + /* Create a new node father of n and m */ + tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; + s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; + tree[n*2 + 1]/*.Dad*/ = tree[m*2 + 1]/*.Dad*/ = node; + + /* and insert the new node in the heap */ + s.heap[1/*SMALLEST*/] = node++; + pqdownheap(s, tree, 1/*SMALLEST*/); + + } while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes(tree, max_code, s.bl_count); +} + + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +function scan_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + tree[(max_code+1)*2 + 1]/*.Len*/ = 0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n+1)*2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + s.bl_tree[curlen * 2]/*.Freq*/ += count; + + } else if (curlen !== 0) { + + if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } + s.bl_tree[REP_3_6*2]/*.Freq*/++; + + } else if (count <= 10) { + s.bl_tree[REPZ_3_10*2]/*.Freq*/++; + + } else { + s.bl_tree[REPZ_11_138*2]/*.Freq*/++; + } + + count = 0; + prevlen = curlen; + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +function send_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n+1)*2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); + + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; + } + //Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count-11, 7); + } + + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +function build_bl_tree(s) { + var max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, s.bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s.bl_tree[bl_order[max_blindex]*2 + 1]/*.Len*/ !== 0) { + break; + } + } + /* Update opt_len to include the bit length tree and counts */ + s.opt_len += 3*(max_blindex+1) + 5+5+4; + //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // s->opt_len, s->static_len)); + + return max_blindex; +} + + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +function send_all_trees(s, lcodes, dcodes, blcodes) +// deflate_state *s; +// int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + var rank; /* index in bl_order */ + + //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + //Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s.bl_tree[bl_order[rank]*2 + 1]/*.Len*/, 3); + } + //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_ltree, lcodes-1); /* literal tree */ + //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_dtree, dcodes-1); /* distance tree */ + //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +function detect_data_type(s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + var black_mask = 0xf3ffc07f; + var n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>>= 1) { + if ((black_mask & 1) && (s.dyn_ltree[n*2]/*.Freq*/ !== 0)) { + return Z_BINARY; + } + } + + /* Check for textual ("white-listed") bytes. */ + if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || + s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + for (n = 32; n < LITERALS; n++) { + if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + } + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + + +var static_init_done = false; + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +function _tr_init(s) +{ + + if (!static_init_done) { + tr_static_init(); + static_init_done = true; + } + + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); + + s.bi_buf = 0; + s.bi_valid = 0; + + /* Initialize the first block of the first file: */ + init_block(s); +} + + +/* =========================================================================== + * Send a stored block + */ +function _tr_stored_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+(last ? 1 : 0), 3); /* send block type */ + copy_block(s, buf, stored_len, true); /* with header */ +} + + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +function _tr_align(s) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); +} + + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +function _tr_flush_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block, or NULL if too old */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + var max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s.level > 0) { + + /* Check if the file is binary or text */ + if (s.strm.data_type === Z_UNKNOWN) { + s.strm.data_type = detect_data_type(s); + } + + /* Construct the literal and distance trees */ + build_tree(s, s.l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + + build_tree(s, s.d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s.opt_len+3+7) >>> 3; + static_lenb = (s.static_len+3+7) >>> 3; + + // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + // s->last_lit)); + + if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } + + } else { + // Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if ((stored_len+4 <= opt_lenb) && (buf !== -1)) { + /* 4: two words for the lengths */ + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + + } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { + + send_bits(s, (STATIC_TREES<<1) + (last ? 1 : 0), 3); + compress_block(s, static_ltree, static_dtree); + + } else { + send_bits(s, (DYN_TREES<<1) + (last ? 1 : 0), 3); + send_all_trees(s, s.l_desc.max_code+1, s.d_desc.max_code+1, max_blindex+1); + compress_block(s, s.dyn_ltree, s.dyn_dtree); + } + // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); + } + // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + // s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +function _tr_tally(s, dist, lc) +// deflate_state *s; +// unsigned dist; /* distance of matched string */ +// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + //var out_length, in_length, dcode; + + s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; + s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; + + s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; + s.last_lit++; + + if (dist === 0) { + /* lc is the unmatched char */ + s.dyn_ltree[lc*2]/*.Freq*/++; + } else { + s.matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + //Assert((ush)dist < (ush)MAX_DIST(s) && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s.dyn_ltree[(_length_code[lc]+LITERALS+1) * 2]/*.Freq*/++; + s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility + +//#ifdef TRUNCATE_BLOCK +// /* Try to guess if it is profitable to stop the current block here */ +// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { +// /* Compute an upper bound for the compressed length */ +// out_length = s.last_lit*8; +// in_length = s.strstart - s.block_start; +// +// for (dcode = 0; dcode < D_CODES; dcode++) { +// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); +// } +// out_length >>>= 3; +// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", +// // s->last_lit, in_length, out_length, +// // 100L - out_length*100L/in_length)); +// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { +// return true; +// } +// } +//#endif + + return (s.last_lit === s.lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +exports._tr_init = _tr_init; +exports._tr_stored_block = _tr_stored_block; +exports._tr_flush_block = _tr_flush_block; +exports._tr_tally = _tr_tally; +exports._tr_align = _tr_align; +},{"../utils/common":27}],39:[function(_dereq_,module,exports){ +'use strict'; + + +function ZStream() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = ''/*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2/*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; +} + +module.exports = ZStream; +},{}]},{},[9]) +(9) +}); \ No newline at end of file diff --git a/image/character/diy_weiyan.jpg b/image/character/diy_weiyan.jpg index 0f97f5595..8b1ae5409 100644 Binary files a/image/character/diy_weiyan.jpg and b/image/character/diy_weiyan.jpg differ diff --git a/image/character/gjqt_aruan.jpg b/image/character/gjqt_aruan.jpg index f2305aed4..a980cc70c 100644 Binary files a/image/character/gjqt_aruan.jpg and b/image/character/gjqt_aruan.jpg differ diff --git a/image/character/jg_huangyueying.jpg b/image/character/jg_huangyueying.jpg index d57237e28..0810ecb40 100644 Binary files a/image/character/jg_huangyueying.jpg and b/image/character/jg_huangyueying.jpg differ diff --git a/image/character/jg_simayi.jpg b/image/character/jg_simayi.jpg index 3474c6760..fbecf3462 100644 Binary files a/image/character/jg_simayi.jpg and b/image/character/jg_simayi.jpg differ diff --git a/image/character/jg_zhanghe.jpg b/image/character/jg_zhanghe.jpg index e0936e0df..ae7190cb2 100644 Binary files a/image/character/jg_zhanghe.jpg and b/image/character/jg_zhanghe.jpg differ diff --git a/image/character/jg_zhugeliang.jpg b/image/character/jg_zhugeliang.jpg index 895442acf..f4bae5bec 100644 Binary files a/image/character/jg_zhugeliang.jpg and b/image/character/jg_zhugeliang.jpg differ diff --git a/image/character/jianyong.jpg b/image/character/jianyong.jpg index e7f32051a..7dc96eda2 100644 Binary files a/image/character/jianyong.jpg and b/image/character/jianyong.jpg differ diff --git a/image/character/lingtong.jpg b/image/character/lingtong.jpg index b0d27a8d7..37fbd1eb9 100644 Binary files a/image/character/lingtong.jpg and b/image/character/lingtong.jpg differ diff --git a/image/character/liufeng.jpg b/image/character/liufeng.jpg index de994ae42..921db9244 100644 Binary files a/image/character/liufeng.jpg and b/image/character/liufeng.jpg differ diff --git a/image/character/madai.jpg b/image/character/madai.jpg index 88b76e7a9..a7969c0da 100644 Binary files a/image/character/madai.jpg and b/image/character/madai.jpg differ diff --git a/image/character/pal_changqing.jpg b/image/character/pal_changqing.jpg index 6151fd477..558afa3d6 100644 Binary files a/image/character/pal_changqing.jpg and b/image/character/pal_changqing.jpg differ diff --git a/image/character/re_ganning.jpg b/image/character/re_ganning.jpg index 487ea94b3..8446ac268 100644 Binary files a/image/character/re_ganning.jpg and b/image/character/re_ganning.jpg differ diff --git a/image/character/re_guanyu.jpg b/image/character/re_guanyu.jpg index 7e77336fe..0416300ed 100644 Binary files a/image/character/re_guanyu.jpg and b/image/character/re_guanyu.jpg differ diff --git a/image/character/re_huanggai.jpg b/image/character/re_huanggai.jpg index a9cec93f9..c62153e52 100644 Binary files a/image/character/re_huanggai.jpg and b/image/character/re_huanggai.jpg differ diff --git a/image/character/re_luxun.jpg b/image/character/re_luxun.jpg index 7c04506d8..93b5b9930 100644 Binary files a/image/character/re_luxun.jpg and b/image/character/re_luxun.jpg differ diff --git a/image/character/re_lvbu.jpg b/image/character/re_lvbu.jpg index e4f882a7b..7e4e07ee9 100644 Binary files a/image/character/re_lvbu.jpg and b/image/character/re_lvbu.jpg differ diff --git a/image/character/re_lvmeng.jpg b/image/character/re_lvmeng.jpg index 03286152a..0a5cac57b 100644 Binary files a/image/character/re_lvmeng.jpg and b/image/character/re_lvmeng.jpg differ diff --git a/image/character/re_simayi.jpg b/image/character/re_simayi.jpg index 97ef2710d..0fad7b9bb 100644 Binary files a/image/character/re_simayi.jpg and b/image/character/re_simayi.jpg differ diff --git a/image/character/re_xiahoudun.jpg b/image/character/re_xiahoudun.jpg index 2cef2eac4..fb875a18a 100644 Binary files a/image/character/re_xiahoudun.jpg and b/image/character/re_xiahoudun.jpg differ diff --git a/image/character/re_yuanshu.jpg b/image/character/re_yuanshu.jpg index 49a681682..59b8bd5ad 100644 Binary files a/image/character/re_yuanshu.jpg and b/image/character/re_yuanshu.jpg differ diff --git a/image/character/shen_guanyu.jpg b/image/character/shen_guanyu.jpg index 1d542034b..8291802b6 100644 Binary files a/image/character/shen_guanyu.jpg and b/image/character/shen_guanyu.jpg differ diff --git a/image/character/shen_lvmeng.jpg b/image/character/shen_lvmeng.jpg index 1fdb4472c..3b8f2ce8a 100644 Binary files a/image/character/shen_lvmeng.jpg and b/image/character/shen_lvmeng.jpg differ diff --git a/image/character/shen_simayi.jpg b/image/character/shen_simayi.jpg index 444c1ed7c..dcbcc8008 100644 Binary files a/image/character/shen_simayi.jpg and b/image/character/shen_simayi.jpg differ diff --git a/image/character/shen_zhaoyun.jpg b/image/character/shen_zhaoyun.jpg index 3cba1bf91..7e235df64 100644 Binary files a/image/character/shen_zhaoyun.jpg and b/image/character/shen_zhaoyun.jpg differ diff --git a/image/character/sp_machao.jpg b/image/character/sp_machao.jpg index b876dbcc1..b51b9dbd0 100644 Binary files a/image/character/sp_machao.jpg and b/image/character/sp_machao.jpg differ diff --git a/image/character/sunjian.jpg b/image/character/sunjian.jpg index 1f765db65..658e0531e 100644 Binary files a/image/character/sunjian.jpg and b/image/character/sunjian.jpg differ diff --git a/image/character/swd_heran.jpg b/image/character/swd_heran.jpg deleted file mode 100644 index d06c4c6d2..000000000 Binary files a/image/character/swd_heran.jpg and /dev/null differ diff --git a/image/character/swd_pepin.jpg b/image/character/swd_pepin.jpg deleted file mode 100644 index a404ac7b1..000000000 Binary files a/image/character/swd_pepin.jpg and /dev/null differ diff --git a/image/character/swd_philis.jpg b/image/character/swd_philis.jpg deleted file mode 100644 index 36a9bb309..000000000 Binary files a/image/character/swd_philis.jpg and /dev/null differ diff --git a/image/character/swd_septem.jpg b/image/character/swd_septem.jpg index 54019c39d..88ce94187 100644 Binary files a/image/character/swd_septem.jpg and b/image/character/swd_septem.jpg differ diff --git a/image/character/yj_jushou.jpg b/image/character/yj_jushou.jpg index 642f87ce7..acc1c3f3d 100644 Binary files a/image/character/yj_jushou.jpg and b/image/character/yj_jushou.jpg differ diff --git a/image/character/yxs_yangyuhuan.jpg b/image/character/yxs_yangyuhuan.jpg index eb552f069..b0fee3f64 100644 Binary files a/image/character/yxs_yangyuhuan.jpg and b/image/character/yxs_yangyuhuan.jpg differ diff --git a/image/character/zhangfei.jpg b/image/character/zhangfei.jpg index 786c2473e..313bd1d9e 100644 Binary files a/image/character/zhangfei.jpg and b/image/character/zhangfei.jpg differ diff --git a/image/splash/boss.jpg b/image/splash/boss.jpg new file mode 100644 index 000000000..831f16d76 Binary files /dev/null and b/image/splash/boss.jpg differ diff --git a/image/splash/chess.jpg b/image/splash/chess.jpg new file mode 100644 index 000000000..d21325dcb Binary files /dev/null and b/image/splash/chess.jpg differ diff --git a/image/splash/guozhan.jpg b/image/splash/guozhan.jpg new file mode 100644 index 000000000..99580a498 Binary files /dev/null and b/image/splash/guozhan.jpg differ diff --git a/image/splash/identity.jpg b/image/splash/identity.jpg new file mode 100644 index 000000000..d0447ab57 Binary files /dev/null and b/image/splash/identity.jpg differ diff --git a/image/splash/stone.jpg b/image/splash/stone.jpg new file mode 100644 index 000000000..cc51b9c6c Binary files /dev/null and b/image/splash/stone.jpg differ diff --git a/image/splash/versus.jpg b/image/splash/versus.jpg new file mode 100644 index 000000000..f3352706e Binary files /dev/null and b/image/splash/versus.jpg differ diff --git a/layout/default/layout.css b/layout/default/layout.css index ec2254119..76c931b3d 100755 --- a/layout/default/layout.css +++ b/layout/default/layout.css @@ -26,6 +26,42 @@ table{table-layout: fixed;} } #window.noclick_important *{pointer-events: none !important;} #window.noclick_important .noclick_click_important div{pointer-events: auto !important} +#splash{ + width:100%; + height: 300px; + left:0; + top:calc(50% - 150px); + position: absolute; + text-align: center; + overflow: visible; + transition: all 0.3s; +} +#splash>div{ + width:100px; + height:100%; + margin-left:10px; + margin-right:10px; + position: relative; + transition: all 0.5s; +} +#splash>div.hidden{ + transform: translateY(-200px); +} +#splash>div>.splashtext{ + font-family: 'huangcao','xinwei'; + font-size: 50px; + position: absolute; + right: 7px; + bottom: 7px; + z-index: 1; +} +#splash>div>.avatar{ + width:86px; + height:calc(100% - 14px); + left:7px; + top:7px; + background-size:cover; +} #arena[data-global_font='xiaozhuan']{ font-family: 'xiaozhuan'; } @@ -244,6 +280,10 @@ body>.background{z-index:-2} .card>.name{top:9px;left: 6px;text-align: center;} .card>.name2{display:none;} .card>.intro{top:85px;right: 0;} +div:not(.handcards)>.card>.info, +.handcards>.card:last-child>.info, +div:not(.handcards)>.card>.name, +.handcards>.card:last-child>.name{transform: none !important} .card>.image{ width: 100%; height: 100%; @@ -1087,7 +1127,7 @@ div[data-color="unknownm"]{ -webkit-filter:saturate(2); }*/ .card.fullskin>.info{ - top: 7px; + top: 8px; right: 6px; color: rgba(0,0,0,0.8); text-shadow: none; diff --git a/layout/default/menu.css b/layout/default/menu.css index 7ba55a25a..16300a3dc 100644 --- a/layout/default/menu.css +++ b/layout/default/menu.css @@ -387,11 +387,136 @@ +.menu-buttons>.new_character{ + display: block; + position: relative; + width: 100%; +} +.menu-buttons>.new_character>.avatar{ + top:8px; + left:12px; + position: absolute; + width: 100px; + height: 120px; + background-size: cover; +} +.menu-buttons>.new_character>.avatar>input{ + z-index: 3; + border-radius: 8px; + opacity: 0; + width: 100%; + height: 100%; + left:0; + top:0; + position: absolute; +} +.menu-buttons>.new_character>.avatar>.select_avatar{ + font-family: 'xinwei'; + font-size: 20px; + width: 100%; + height: 20px; + line-height: 20px; + top:50px; + left:0; + text-align: center; +} +.menu-buttons>.new_character>.avatar.inited>.select_avatar{ + display: none; +} +.menu-buttons>.new_character>.indent{ + display: block; + margin-left: 123px; + width: calc(100% - 135px); + position: relative; + padding-top: 7px; + text-align: left; + white-space: nowrap; +} +.menu-buttons>.new_character>.indent>input{ + width: 60px; +} +.menu-buttons>.new_character>div>select{ + margin-right: 3px; +} +.menu-buttons>.new_character>.add_skill{ + position: absolute; + left: 12px; + top:145px; + text-align: left; + line-height: 20px; +} +.menu-buttons>.new_character>.add_skill.create{ + top: 195px; +} +.menu-buttons>.new_character>.add_skill.create>div{ + position: relative; +} +.menu-buttons>.new_character>.add_skill.create>div.hidden{ + display: none; +} +.menu-buttons>.new_character>.add_skill.create>div>textarea{ + resize: none; + width: 200px; + height: 100px; + margin-top: 5px; +} +.menu-buttons>.new_character>.add_skill.create>div>div{ + position: relative; + margin-top: 5px; +} +.menu-buttons>.new_character>.add_skill.create>div>div>input{ + width: 120px; +} +.menu-buttons>.new_character>.skill_list{ + position: absolute; + left: 12px; + top: 215px; + text-align: left; + height: auto; + width: calc(100% - 20px); + padding-bottom: 30px; + transition: all 0s; +} +.menu-buttons>.new_character>.skill_list>div{ + position: relative; + width: 100%; + margin: 0; + padding: 0; + height: auto; +} +.menu-buttons>.new_character>.skill_list>div>div{ + position: relative; +} +.menu-buttons>.new_character>.skill_list>div:first-child{ + margin-bottom: 10px; +} +.menu-buttons>.new_character>.skill_list>div:first-child>div{ + width: calc(50% - 10px); + margin-right: 10px; + margin-top: 6px; +} +.menu-buttons>.new_character>.skill_list>div:first-child>div>div{ + position: relative; +} +.menu-buttons>.new_character>.skill_list>div:first-child>div>div:last-child{ + float: right; +} - - - - +.menu-buttons>.new_character.export{ + text-align: left; +} +.menu-buttons>.new_character.export>div{ + position: relative; + margin-left: 12px; + margin-top: 5px; +} +.menu-buttons>.new_character.export>div>input{ + width: 100px; + margin-right: 5px; +} +.menu-buttons>.new_character.export.import>div>input{ + width: 153px; +} .menubutton{ box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; diff --git a/manifest.json b/manifest.json index fc493bda8..71ba0f4c1 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name": "noname", - "xwalk_version": "1.6.3", + "xwalk_version": "1.7.0", "start_url": "index.html", "icons": [ { diff --git a/mode/archive/boss.js b/mode/archive/boss.js deleted file mode 100755 index b388b9ceb..000000000 --- a/mode/archive/boss.js +++ /dev/null @@ -1,329 +0,0 @@ -mode.boss={ - game:{ - load:function(){ - var next=game.createEvent('load',false); - next.content=function(){ - "step 0" - game.import('identity'); - "step 1" - delete lib.config.current_mode.change_identity; - ui.create.arena(); - ui.auto.hide(); - ui.create.cards(); - game.finishCards(); - game.delay(); - "step 2" - game.prepareGame(); - "step 3" - var player=_status.first||game.zhu; - event.trigger('gameStart'); - game.gameDraw(player); - game.bossPhaseLoop(player); - } - }, - bossPhaseLoop:function(){ - var next=game.createEvent('phaseLoop'); - next.player=game.zhu; - next.content=function(){ - "step 0" - if(player.classList.contains('chongzheng')){ - player.classList.remove('chongzheng'); - } - else{ - player.phase(); - } - "step 1" - if(_status.level.chongzheng!=undefined&&event.player==game.zhu){ - for(var i=0;i0?player.node.handcards1:player.node.handcards2; - card.fix(); - var j=0; - if(lib.config.strict_sort){ - for(j=0;jlib.config.sort_card(position.childNodes[j])) break; - } - } - } - card.animate('start'); - position.insertBefore(card,position.childNodes[j]); - } - game.dead[i].update(); - } - else{ - game.dead[i].revive(); - game.dead[i].classList.add('chongzheng'); - game.dead[i].hp=game.dead[i].maxHp; - if(game.dead[i].hp<4){ - game.dead[i].draw(3); - } - else{ - game.dead[i].draw(2); - } - i--; - } - } - } - if(_status.loopType==1){ - if(event.player==game.zhu){ - if(_status.next==undefined) _status.next=game.zhu.next; - event.player=_status.next; - } - else{ - if(player.next==game.zhu){ - _status.next=game.zhu.next; - } - else{ - _status.next=player.next; - } - event.player=game.zhu; - } - } - else{ - var players,i; - if(game.players.contains(event.player.next)==false){ - players=get.players(lib.sort.position); - if(players[players.length-1].position=event.player.position){ - event.player=game.players[i];break; - } - } - } - } - else{ - event.player=event.player.next; - } - } - event.goto(0); - } - }, - prepareGame:function(){ - var next=game.createEvent('prepareGame',false); - next.showConfig=true; - next.ai=function(player,list){ - player.init(list[0]); - }; - next.content=function(){ - "step 0" - var i; - var dialog=ui.create.dialog(); - for(i=0;i0&&game.zhu.classList.contains('dead')){ - game.over(true); - } - else{ - game.over(false); - } - } - }, - decideZhu:function(){ - var next=game.createEvent('decideZhu',false); - next.player=game.players.randomGet(); - next.content=function(){ - "step 0" - player.chooseControl('jiaodizhu','bujiao'); - event.player=player.next; - "step 1" - player.previous.mark(result.control); - if(result.control=='jiaodizhu') _status.jiao=true; - if(_status.jiao){ - player.chooseControl('qiangdizhu','buqiang'); - } - else{ - player.chooseControl('jiaodizhu','bujiao'); - } - event.player=player.next; - "step 2" - player.previous.mark(result.control); - if(result.control=='jiaodizhu') _status.jiao=true; - if(_status.jiao){ - player.chooseControl('qiangdizhu','buqiang'); - } - else{ - player.chooseControl('jiaodizhu','bujiao'); - } - "step 3" - player.mark(result.control); - } - }, - }, - translate:{ - poker_big:' ', - poker_little:' ', - poker_heart:' ', - poker_diamond:' ', - poker_club:' ', - poker_spade:' ', - jiaodizhu:'叫地主', - bujiao:'不叫', - qiangdizhu:'抢地主', - buqiang:'不抢', - }, - element:{ - player:{ - dieSpeak:function(){ - switch(this.identity){ - case 'zhu': this.popup('吾降矣',2000);break; - case 'zhong': this.popup('呃啊',2000);break; - case 'nei': this.popup('啊,被看穿了',2000);break; - case 'fan': this.popup('饶命啊',2000);break; - } - }, - dieAfter:function(source){ - this.dieSpeak(); - if(get.config('show_identity')) this.setIdentity(this.identity); - if(this==game.zhu||game.players.length==1) game.checkResult(); - else if(get.population('fan')+get.population('nei')==0) game.checkResult(); - else if(this.identity=='fan'&&source) source.draw(3); - else if(this.identity=='zhong'&&source&&source.identity=='zhu'){ - source.discard(source.handcards.concat(source.equips)); - } - } - } - }, - ai:{ - get:{ - attitude:function(from,to){ - if(_status.currentPhase==from&&from.storage.tempIgnore&&from.storage.tempIgnore.contains(to)) return 0; - var situation=ai.get.situation(); - switch(from.identity){ - case 'zhu': - switch(to.identity){ - case 'zhu': return 10; - case 'zhong': return 6; - case 'nei': - if(game.players.length==2) return -10; - return get.population('fan'); - case 'fan': return -4; - } - case 'zhong': - switch(to.identity){ - case 'zhu': return 10; - case 'zhong': return get.population('fan')>0?4:-1; - case 'nei': return Math.min(3,-ai.get.situation()); - case 'fan': return -8; - } - case 'nei': - switch(to.identity){ - case 'zhu': - if(game.players.length==2) return -10; - if(to.hp<=0) return 10; - return get.population('fan')+Math.max(0,3-game.zhu.hp); - case 'zhong': - if(get.population('fan')==0) return -5; - if((game.zhu&&game.zhu.hp<=3)||ai.get.situation()<0) return 0; - return -1; - case 'nei': - if(from==to) return 10; - return -1; - case 'fan': - if((game.zhu&&game.zhu.hp<=2)||ai.get.situation()<-1) return -4; - if((game.zhu&&game.zhu.hp<=3)||ai.get.situation()<0) return -2; - if((game.zhu&&game.zhu.hp>4)||ai.get.situation()>0) return 1; - return 0; - } - case 'fan': - switch(to.identity){ - case 'zhu': return -10; - case 'zhong': return -4; - case 'nei': return ai.get.situation(); - case 'fan': return 5; - } - } - }, - situation:function(absolute){ - var i,j,player; - var zhuzhong=0,total=0,zhu,fan=0; - for(i=0;i30) result--; - if(zhu<6&&fan>15) result--; - if(zhu<4) result--; - return result; - }, - population:function(identity){ - return get.population(identity); - } - } - }, - character:{ - dizhu:['male',0,'shu',[]], - nongmin:['male',0,'qun',[]], - }, - card:{ - poker_big:{}, - poker_little:{}, - poker_heart:{}, - poker_diamond:{}, - poker_club:{}, - poker_spade:{}, - }, - list:[ - ['heart',1,'poker_heart'], - ['diamond',1,'poker_diamond'], - ['club',1,'poker_club'], - ['spade',1,'poker_spade'], - ['heart',2,'poker_heart'], - ['diamond',2,'poker_diamond'], - ['club',2,'poker_club'], - ['spade',2,'poker_spade'], - ['heart',3,'poker_heart'], - ['diamond',3,'poker_diamond'], - ['club',3,'poker_club'], - ['spade',3,'poker_spade'], - ['heart',4,'poker_heart'], - ['diamond',4,'poker_diamond'], - ['club',4,'poker_club'], - ['spade',4,'poker_spade'], - ['heart',5,'poker_heart'], - ['diamond',5,'poker_diamond'], - ['club',5,'poker_club'], - ['spade',5,'poker_spade'], - ['heart',6,'poker_heart'], - ['diamond',6,'poker_diamond'], - ['club',6,'poker_club'], - ['spade',6,'poker_spade'], - ['heart',7,'poker_heart'], - ['diamond',7,'poker_diamond'], - ['club',7,'poker_club'], - ['spade',7,'poker_spade'], - ['heart',8,'poker_heart'], - ['diamond',8,'poker_diamond'], - ['club',8,'poker_club'], - ['spade',8,'poker_spade'], - ['heart',9,'poker_heart'], - ['diamond',9,'poker_diamond'], - ['club',9,'poker_club'], - ['spade',9,'poker_spade'], - ['heart',10,'poker_heart'], - ['diamond',10,'poker_diamond'], - ['club',10,'poker_club'], - ['spade',10,'poker_spade'], - ['heart',11,'poker_heart'], - ['diamond',11,'poker_diamond'], - ['club',11,'poker_club'], - ['spade',11,'poker_spade'], - ['heart',12,'poker_heart'], - ['diamond',12,'poker_diamond'], - ['club',12,'poker_club'], - ['spade',12,'poker_spade'], - ['heart',13,'poker_heart'], - ['diamond',13,'poker_diamond'], - ['club',13,'poker_club'], - ['spade',13,'poker_spade'], - ['',14,'poker_little'], - ['',15,'poker_big'], - ] -} diff --git a/mode/archive/infinity.js b/mode/archive/infinity.js deleted file mode 100755 index ed9e2c555..000000000 --- a/mode/archive/infinity.js +++ /dev/null @@ -1,401 +0,0 @@ -mode.infinity={ - game:{ - start:function(){ - var next=game.createEvent('game',false); - next.content=function(){ - "step 0" - if(lib.storage.choice==undefined) game.save('choice',18); - if(lib.storage.zhu==undefined) game.save('zhu',true); - if(lib.storage.only_zhu==undefined) game.save('only_zhu',true); - ui.create.arena(); - ui.auto.hide(); - game.delay(); - "step 1" - game.chooseCharacter(); - "step 2" - event.trigger('gameStart'); - game.gameDraw(game.players[0]); - _status.round=0; - if(lib.storage.zhu){ - _status.currentSide=true; - game.versusPhaseLoop((_status.currentSide==game.me.side)?game.friendZhu:game.enemyZhu); - } - else{ - game.versusPhaseLoop(game.players[Math.floor(Math.random()*game.players.length)]); - } - } - }, - chooseCharacter:function(){ - var next=game.createEvent('chooseCharacter',false); - next.showConfig=true; - next.content=function(){ - "step 0" - event.check=function(){ - this.dialog.style.top='40px'; - this.dialog.style.height='calc(100% - 80px)'; - this.dialog.classList.add('noslide'); - for(var i=0;i=dialog.versus_number.link+dialog.replace_number.link){ - if(!ui.confirm) ui.confirm=ui.create.control('start',_status.event.confirm); - } - else if(ui.confirm){ - ui.confirm.close(); - } - game.save('number',dialog.versus_number.link); - game.save('replace_number',dialog.replace_number.link); - game.save('choice',dialog.choice.link); - var count,i; - if(dialog.buttons.length>lib.storage.choice){ - count=dialog.buttons.length-lib.storage.choice; - var removed=[]; - for(i=dialog.buttons.length-1;i>=0&&count>0;i--){ - if(dialog.buttons[i].classList.contains('target')==false&& - dialog.buttons[i].classList.contains('glow')==false){ - dialog.buttons[i].remove(); - _status.list.remove(dialog.buttons[i].link); - removed.push(dialog.buttons[i].link) - dialog.buttons.splice(i,1); - count--; - } - } - for(i=0;i=2*Math.max(game.friend.length,game.enemy.length)){ - _status.round=0; - for(var i=0;ib.num('j')) return 1; - return a.hp-b.hp; - }) - event.player=list[0]; - event.goto(0); - } - else{ - game.me.chooseTarget('选择要行动的角色',true,function(card,player,target){ - return (target.classList.contains('acted')==false&&target.side==game.me.side); - }) - } - } - else{ - event.player=event.player.next; - event.goto(0); - } - "step 2" - event.player=result.targets[0]; - event.goto(0); - } - }, - replacePlayer:function(player){ - var next=game.createEvent('replacePlayer'); - next.source=player; - next.content=function(){ - "step 0" - var list=(source.side==game.me.side)?_status.friend:_status.enemy; - if(list.length==0){ - game.friend.remove(source); - game.enemy.remove(source); - if(game.friend.length==0) game.over(false); - else if(game.enemy.length==0) game.over(true); - if(game.friendZhu&&game.friendZhu.classList.contains('dead')&&game.friend.length){ - game.friendZhu=game.friend[0]; - game.friendZhu.setIdentity(_status.color+'Zhu'); - } - if(game.enemyZhu&&game.enemyZhu.classList.contains('dead')&&game.enemy.length){ - game.enemyZhu=game.enemy[0]; - game.enemyZhu.setIdentity(!_status.color+'Zhu'); - } - event.finish(); - return; - } - if(source.side==game.me.side&&list.length>1&&game.me==game.friendZhu&& - lib.storage.replace==false&&!_status.auto){ - event.dialog=ui.create.dialog('选择替补角色',[list,'character']); - event.filterButton=function(){return true;}; - event.player=game.me; - event.forced=true; - event.custom.replace.confirm=function(){ - event.character=ui.selected.buttons[0].link; - event.dialog.close(); - if(ui.confirm) ui.confirm.close(); - delete event.player; - game.resume(); - } - game.check(); - game.pause(); - // game.me.chooseButton(dialog,true); - } - else{ - event.character=list[Math.floor(Math.random()*list.length)]; - } - "step 1" - // if(result&&result.buttons&&result.buttons.length) event.character=result.buttons[0].link; - _status.friend.remove(event.character); - _status.enemy.remove(event.character); - source.revive(); - source.init(event.character); - source.draw(4); - // console.log(_status.event.parent.parent.parent.name) - _status.event.parent.parent.parent.untrigger(true); - } - }, - swapSeat:function(){ - ; - } - }, - translate:{ - trueZhu:"帅", - falseZhu:"将", - trueZhong:"兵", - falseZhong:"卒", - trueColor:"#ffddb9", - falseColor:"#b0d0e2", - versus_zhu_config:'启用主将', - versus_only_zhu_config:'只当主将', - versus_replace_config:'自动换人', - versus_assign_enemy_config:'指定对手', - versus_number_config:'对阵人数', - replace_number_config:'替补人数', - choice_config:'候选人数' - }, - element:{ - player:{ - dieSpeak:function(){ - switch(this.identity){ - case 'zhu': this.popup('吾降矣',2000);break; - case 'zhong': this.popup('呃啊',2000);break; - } - }, - dieAfter:function(source){ - this.dieSpeak(); - if(this.side==game.me.side){ - _status.friendDied++; - } - else{ - _status.enemyDied++; - } - _status.friendCount.innerHTML='我方阵亡:'+get.cnNumber(_status.friendDied,true); - _status.enemyCount.innerHTML='敌方阵亡:'+get.cnNumber(_status.enemyDied,true); - if(game.friend.length==1&&this==game.friend[0]&&_status.friend.length==0){ - game.over(false); - } - else if(game.enemy.length==1&&this==game.enemy[0]&&_status.enemy.length==0){ - game.over(true); - } - else{ - if(source&&lib.storage.zhu){ - if(source.side!=this.side){ - source.draw(3); - } - else{ - source.discard(source.get('he')); - } - } - else{ - game.delay(); - } - game.replacePlayer(this); - } - - } - } - }, - ai:{ - get:{ - attitude:function(from,to){ - if(from.side==to.side){ - if(to.identity=='zhu') return 6; - return 6; - } - if(to.identity=='zhu') return -6; - return -6; - }, - } - }, - config:{ - change_choice:true, - ban_weak:true, - } -} diff --git a/mode/archive/mowang.js b/mode/archive/mowang.js deleted file mode 100755 index b25160a34..000000000 --- a/mode/archive/mowang.js +++ /dev/null @@ -1,538 +0,0 @@ -mode.mowang={ - game:{ - start:function(){ - var next=game.createEvent('game',false); - next.content=function(){ - "step 0" - game.import('boss'); - "step 1" - game.load(); - } - }, - }, - character:{ - boss_zuiqiangshenhua:['male','qun',8,['mashu','wushuang','baonu'],['boss']], - boss_baonuzhanshen:['male','qun',4,['mashu','wushuang','xiuluo','shenwei','shenji'],['boss']], - boss_gaodayihao:['male','shu',1,['gd_juejing','gd_longhun'],['boss']], - boss_nianshou:['male','qun',10,['nianrui','qixiang1','qixiang2','jixing'],['boss']], - boss_hanxu:['male','qun',8,['chonglian','jiankong'],['boss']], - boss_taiyangshen:['male','wei',8,['youqing','riguang','ty_wuxie','kaikeng'],['boss']], - boss_paracel:['female','wei',6,['zhiji','liuli','feiying','ganglie','kongcheng','zaiqi'],['boss']], - boss_ailue:['female','qun',6,['shuihu','guiyin'],['boss']], - boss_nvwang:['female','wei',6,['wangshou','luanji','wanggong'],['boss']], - boss_qiongmei:['female','qun',3,['qiongmei','xiyu'],['boss']], - }, - skill:{ - taoyuan:{ - inherit:'biyue' - }, - baonu:{ - trigger:{player:'changeHp'}, - forced:true, - filter:function(event,player){ - return player.hp<=4 - }, - content:function(){ - var hp=player.hp; - player.init('boss_baonuzhanshen'); - player.hp=hp; - player.update(); - while(_status.event.name!='phaseLoop'){ - _status.event=_status.event.parent; - } - _status.event.player=player; - _status.event.step=0; - _status.loopType=0; - } - }, - xiuluo:{ - trigger:{player:'phaseBegin'}, - frequent:true, - filter:function(event,player){ - return player.num('j')>0; - }, - content:function(){ - player.chooseToDiscard(2,'hj',function(card){ - if(ui.selected.cards.length==0) return true; - if(get.position(ui.selected.cards[0])=='h'){ - if(get.position(card)!='j') return false; - } - if(get.position(ui.selected.cards[0])=='j'){ - if(get.position(card)!='h') return false; - } - return get.suit(card)==get.suit(ui.selected.cards[0]) - },'是否一张手牌来弃置一张花色相同的判定牌?').ai=function(card){ - return 11-ai.get.value(card); - } - } - }, - shenwei:{ - group:['shenwei1','shenwei2'] - }, - shenwei1:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - content:function(){ - trigger.num+=2; - } - }, - shenwei2:{ - mod:{ - maxHandcard:function(player,current){ - return current+2; - } - } - }, - shenji:{ - mod:{ - selectTarget:function(card,player,range){ - if(!player.get('e','1')&&card.name=='sha') range[1]=3; - }, - } - }, - nianrui:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - content:function(){ - trigger.num+=2; - } - }, - jixing:{ - trigger:{player:'phaseBegin'}, - forced:true, - content:function(){ - player.recover(2); - } - }, - qixiang1:{ - trigger:{player:'judge'}, - forced:true, - filter:function(event,player){ - if(event.card){ - return (event.card.name=='lebu'||event.card.viewAs=='lebu'); - } - }, - content:function(){ - player.addTempSkill('qixiang3','phaseJudgeAfter'); - } - }, - qixiang2:{ - trigger:{player:'judge'}, - forced:true, - filter:function(event,player){ - if(event.card){ - return (event.card.name=='bingliang'||event.card.viewAs=='bingliang'); - } - }, - content:function(){ - player.addTempSkill('qixiang3','phaseJudgeAfter'); - } - }, - qixiang3:{ - mod:{ - suit:function(card,suit){ - if(suit=='diamond') return 'heart'; - if(suit=='spade') return 'club'; - } - } - }, - hlg_dieDraw:{ - trigger:{global:'dieAfter'}, - filter:function(event,player){ - return player!=game.zhu; - }, - prompt:'是否摸一张牌?', - content:function(){ - player.draw(); - } - }, - hlg_chongzhu:{ - enable:'phaseUse', - filter:function(event,player){ - var cards=player.get('h'); - for(var i=0;i3) trigger.source.hp=3; - trigger.source.update(); - } - }, - jiankong:{ - trigger:{global:'drawEnd'}, - frequent:true, - filter:function(event,player){ - return event.player!=player; - }, - content:function(){ - player.draw(); - } - }, - ns_damage:{ - trigger:{player:'damageEnd'}, - forced:true, - popup:false, - filter:function(event,player){ - return player==game.zhu - }, - content:function(){ - player.hp=player.maxHp; - player.update(); - } - }, - youqing:{ - trigger:{player:'loseHpBefore'}, - forced:true, - content:function(){ - trigger.finish(); - trigger.untrigger(); - } - }, - riguang:{ - enable:'phaseUse', - selectTarget:-1, - usable:1, - filterTarget:function(card,player,target){ - return target!=player; - }, - content:function(){ - "step 0" - target.chooseToRespond({name:'shan'}); - "step 1" - if(result.bool==false){ - target.damage('fire'); - } - }, - ai:{ - result:{ - target:-1.5, - }, - order:9, - } - }, - ty_wuxie:{ - trigger:{player:'phaseBegin'}, - forced:true, - content:function(){ - player.gain(player.judges.slice(0)); - } - }, - kaikeng:{ - trigger:{global:['respondEnd','discardEnd']}, - frequent:true, - filter:function(event,player){ - return event.player!=player; - }, - content:function(){ - player.draw(); - } - }, - shuihu:{ - trigger:{player:'phaseDrawBefore'}, - content:function(){ - trigger.untrigger(); - trigger.finish(); - for(var i=0;i0){ - event.cards.push(result.card); - if(lib.config.auto_skill==false){ - player.chooseBool('是否再次发动?'); - } - else{ - event._result={bool:true}; - } - } - else{ - player.gain(event.cards); - event.finish(); - } - "step 2" - if(result.bool){ - event.goto(0); - } - else{ - player.gain(event.cards); - } - } - }, - xiyu:{ - trigger:{player:'damageBefore'}, - filter:function(event,player){ - if(!event.source) return false; - return player.num('h')<=event.source.num('h')|| - player.num('h')<=event.source.hp; - }, - content:function(){ - trigger.untrigger(); - trigger.finish(); - trigger.source.draw(); - } - }, - gd_juejing:{ - group:['gd_juejing1','gd_juejing2'] - }, - gd_juejing1:{ - trigger:{player:'phaseDrawBegin'}, - priority:-10, - forced:true, - content:function(){ - trigger.num=0; - } - }, - gd_juejing2:{ - trigger:{player:'loseEnd'}, - forced:true, - filter:function(event,player){ - return (player.num('h')<4); - }, - content:function(){ - player.draw(4-player.num('h')); - } - }, - gd_longhun:{ - group:['gd_longhun1','gd_longhun2','gd_longhun3','gd_longhun4'] - }, - gd_longhun1:{ - enable:['chooseToUse','chooseToRespond'], - prompt:'将一张红桃牌当桃使用', - viewAs:{name:'tao'}, - filterCard:function(card){ - return get.suit(card)=='heart'; - } - }, - gd_longhun2:{ - enable:['chooseToUse','chooseToRespond'], - prompt:'将一张方片牌当火杀使用或打出', - viewAs:{name:'sha',nature:'fire'}, - filterCard:function(card){ - return get.suit(card)=='diamond'; - } - }, - gd_longhun3:{ - enable:['chooseToUse','chooseToRespond'], - prompt:'将一张黑桃牌当无懈可击使用', - viewAs:{name:'wuxie'}, - filterCard:function(card){ - return get.suit(card)=='spade'; - } - }, - gd_longhun4:{ - enable:['chooseToUse','chooseToRespond'], - prompt:'将一张梅花牌当闪打出', - viewAs:{name:'shan'}, - filterCard:function(card){ - return get.suit(card)=='club'; - } - } - }, - translate:{ - boss_zuiqiangshenhua:'神吕布·最强神话', - boss_baonuzhanshen:'神吕布·暴怒战神', - baonu:'暴怒', - baonu2:'暴怒', - baonu3:'暴怒', - hlg_dieDraw:'重整', - hlg_chongzhu:'重铸', - xiuluo:'修罗', - shenwei:'神威', - shenwei1:'神威', - shenwei2:'神威', - chonglian:'重练', - jiankong:'监控', - jiankong_info:'每当有其他角色摸牌,你可以立即摸一张牌', - chonglian_info:'锁定技,对你造成伤害的角色立即失去所有技能,若体力上限高于3则降至3', - xiuluo_info:'回合开始阶段,你可以弃一张手牌来弃置你判断区里的一张延时类锦囊(必须花色相同)', - shenwei_info:'锁定技,摸牌阶段,你额外摸两张牌,你的手牌上限+2', - shenji:'没装备武器时,你使用的杀可指定至多3名角色为目标', - boss_nianshou:'年兽', - nianrui:'年瑞', - qixiang1:'祺祥', - qixiang2:'祺祥', - jixing:'吉兴', - nianrui_info:'摸牌阶段,你额外摸两张牌', - jixing_info:'回合开始阶段,你回复两点体力', - qixiang1_info:'乐不思蜀判定时,你的方块判定牌视为红桃;兵粮寸断判定时,你的黑桃判定牌视为草花', - boss_hanxu:'韩旭', - boss_taiyangshen:'太阳神', - youqing:'有情', - youqing_info:'锁定技,你不能流失体力', - riguang:'日光', - riguang_info:'出牌阶段,你可令所有角色今次打出一张闪,否则受到一点火焰伤害,每阶段限一次', - ty_wuxie:'无懈', - ty_wuxie_info:'锁定技,回合开始阶段,你将所有判定区内的牌收入手牌', - kaikeng:'开坑', - kaikeng_info:'每当有其他角色打出或弃置卡牌,你可以立即摸一张牌', - boss_paracel:'Paracel', - boss_ailue:'宇文天启', - shuihu:'水浒', - guiyin:'鬼隐', - shuihu_info:'你可以放弃摸牌,并从每名其他角色中抽取一张手牌', - guiyin_info:'你可以跳过出牌阶段和弃牌阶段,并摸X张牌,X为场上现存角色数的一半,向下取整', - boss_nvwang:'女王受·虫', - wangshou:'王受', - wangshou_info:'锁定技,每当你受到一次伤害,你立即摸3张牌', - wanggong:'王攻', - wanggong_info:'锁定技,每当你受杀死一名角色,你立即摸3张牌', - boss_qiongmei:'爱上穹妹的某', - qiongmei:'穹妹', - qiongmei_info:'回合结束阶段,你可以进行判定,若不为黑桃则可以继续判定,判定结束后将判定成功的牌收入手牌', - xiyu:'惜玉', - xiyu_info:'每当你即将受到伤害时,若你的手牌数不大于伤害来源的手牌数或体力值,你可以防止此伤害,并令伤害来源摸一张牌', - boss_gaodayihao:'高达一号', - gd_juejing:'绝境', - gd_juejing1:'绝境', - gd_juejing2:'绝境', - gd_longhun:'龙魂', - gd_longhun1:'龙魂 ♥︎', - gd_longhun2:'龙魂 ♦︎', - gd_longhun3:'龙魂 ♠︎', - gd_longhun4:'龙魂 ♣︎', - gd_juejing_info:'锁定技,摸牌阶段,你不摸牌,你的手牌数永远为4。', - gd_longhun_info:'你的牌可以按以下规则使用或打出:红桃当桃,方块当火杀,梅花当闪,黑桃当无懈可击', - }, - scene:[ - { - title:'虎牢关', - versus:3, - boss:'boss_zuiqiangshenhua', - global:['hlg_chongzhu','hlg_dieDraw'], - disable:['_chongzhu'], - forbid:['caiwenji'], - maxShuffle:1, - loopType:1, - chongzheng:6 - }, - { - title:'高达一号', - versus:7, - boss:'boss_gaodayihao', - }, - { - title:'年兽(计时)', - boss:'boss_nianshou', - versus:3, - prepare:function(){ - _status.damage=0; - var node=ui.create.div(ui.system); - node.innerHTML=300; - var count=300; - var timer=setInterval(function(){ - if(count){ - count--;node.innerHTML=count; - } - else{ - clearInterval(timer); - if(!_status.over) game.over(); - } - },1000); - }, - global:['ns_damage'] - }, - { - title:'年兽', - boss:'boss_nianshou', - versus:3, - }, - { - title:'韩旭', - boss:'boss_hanxu', - versus:7, - remove:['zhuge'] - }, - { - title:'太阳神', - boss:'boss_taiyangshen', - versus:7, - }, - { - title:'Paracel', - boss:'boss_paracel', - versus:3, - }, - { - title:'宇文天启', - boss:'boss_ailue', - versus:6, - }, - { - title:'女王受·虫', - boss:'boss_nvwang', - versus:3, - }, - { - title:'爱上穹妹的某', - boss:'boss_qiongmei', - versus:6, - }, - ], -} diff --git a/mode/archive/scene.js b/mode/archive/scene.js deleted file mode 100755 index 4be16f184..000000000 --- a/mode/archive/scene.js +++ /dev/null @@ -1,146 +0,0 @@ -mode.scene={ - game:{ - load:function(){ - var next=game.createEvent('load',false); - next.content=function(){ - "step 0" - game.import('identity'); - "step 1" - ui.create.arena(); - ui.auto.hide(); - ui.create.cards(); - game.finishCards(); - game.delay(); - "step 2" - game.prepareGame(); - "step 3" - var player=_status.first||game.players[Math.floor(Math.random()*game.players.length)]; - game.gameDraw(player); - game.phaseLoop(player); - } - }, - checkResult:function(){ - game.over(ai.get.population('zhong')==0); - }, - prepareGame:function(){ - var next=game.createEvent('prepareGame',false); - next.content=function(){ - "step 0" - var dialog=ui.create.dialog(); - for(var i=0;ilib.progress.length-1){ - game.save('progress',lib.progress.length-1); - } - var progress=lib.progress[lib.storage.progress]; - game.pause(); - if(typeof progress=='object'||typeof progress=='string'){ - var left=true; - var add=true; - if(ui.avatar){ - if(ui.avatar.name!=progress[0]){ - if(!ui.avatar.right) left=false; - ui.avatar.delete(); - delete ui.avatar; - } - else add=false; - } - if(add&&lib.character[progress[0]]){ - ui.avatar=ui.create.div('.avatar',ui.arena).animate('start'); - ui.avatar.setBackground(progress[0],'character'); - ui.avatar.style.top='calc(100% / 3 - 100px / 3)'; - if(left){ - ui.avatar.style.left='calc(5% + 120px)'; - } - else{ - ui.avatar.style.left='calc(95% - 214px)'; - ui.avatar.right=true; - } - ui.avatar.name=progress[0]; - } - var dialog; - if(typeof progress=='object'){ - if(progress.length>1){ - dialog=ui.create.dialog(get.translation(progress[0]),progress[1]); - } - else{ - dialog=ui.create.dialog(get.translation(progress[0])); - } - } - else{ - dialog=ui.create.dialog(progress); - } - dialog.listen(function(){ - if(_status.clicked) return; - this.close(); - game.addProgress(); - event.redo(); - game.resume(); - }); - } - else if(lib.storage.progress==lib.storage.savedprogress){ - _status.paused=false; - _status.battle=progress; - } - else{ - if(ui.avatar){ - ui.avatar.delete(); - delete ui.avatar; - } - _status.battle=progress; - var dialog=ui.create.dialog('战斗:'+lib.battle[progress].name,lib.battle[progress].intro); - dialog.listen(function(){ - if(_status.clicked) return; - this.close(); - game.resume(); - }); - } - "step 3" - ui.choose.delete(); - delete lib.card.zhuge; - ui.create.cards(); - game.finishCards(); - game.delay(); - "step 4" - if(get.config('save_progress')&&lib.storage.saved) game.loadGame(); - else game.prepareGame(); - "step 5" - event.trigger('gameStart'); - if(get.config('save_progress')&&lib.storage.saved&& - lib.storage.progress==lib.storage.savedprogress){ - var card; - for(var i=0;i0) game.players[i].node.handcards1.appendChild(card); - else game.players[i].node.handcards2.appendChild(card); - } - } - for(var j=0;j20) {alert('!!!');break;} - } - while(player!=game.me); - game.save('player',current.dataset.position); - game.save('players',players); - game.save('jpa',game.me.jpa); - game.save('jpe',game.me.jpe); - game.save('jp',game.me.jp); - game.save('learned',game.me.learned); - game.save('learned1',game.me.learned1); - game.save('learned2',game.me.learned2); - game.save('learned3',game.me.learned3); - game.save('learned4',game.me.learned4); - game.save('learned5',game.me.learned5); - game.save('learned6',game.me.learned6); - game.save('learned7',game.me.learned7); - game.save('saved',true); - game.save('savedprogress',lib.storage.progress); - }, - addProgress:function(){ - if(lib.storage.progress+1>lib.progress.length-1){ - game.save('progress',lib.progress.length-1); - game.save('maxprogress',lib.progress.length-1); - } - else{ - game.save('progress',lib.storage.progress+1); - if(typeof lib.storage.maxprogress!='number'||lib.storage.maxprogressgame.me.jp){ - if(that.node2) return; - that.node2=ui.create.div('.toggle',that).animate('start'); - that.node2.innerHTML='点数不足'; - that.node2.style.right='56px'; - setTimeout(function(){ - that.node2.delete(); - delete that.node2; - },1000); - return; - } - toggle.innerHTML='已学习'; - game.me.jp-=num; - game.me.learned[j].push(toggle.skill); - ui.jp.innerHTML=game.me.jp; - } - }); - node.childNodes[1].skill=i; - ui.learned[i]=node; - dialog.add(node); - } - }(j)) - dialog.add(ui.create.div('.placeholder')); - } - dialog.add(ui.create.line('摸两张牌',100,function(){ - var node=this.parentNode; - if(node.clicked) return; - if(game.me.jp<100){ - if(node.node2) return; - node.node2=ui.create.div('.toggle',node).animate('start'); - node.node2.innerHTML='点数不足'; - node.node2.style.right='56px'; - setTimeout(function(){ - node.node2.delete(); - delete node.node2; - },1000); - return; - } - node.clicked=true; - node.querySelector('.toggle').innerHTML='已选择' - game.me.jpa-=100; - game.me.jp-=100; - ui.jp.innerHTML=game.me.jp; - ui.jpa.innerHTML=game.me.jpa; - game.me.draw(2); - })); - dialog.add(ui.create.line('回复体力',100,function(){ - var node=this.parentNode; - if(node.clicked) return; - if(game.me.jp<100){ - if(node.node2) return; - node.node2=ui.create.div('.toggle',node).animate('start'); - node.node2.innerHTML='点数不足'; - node.node2.style.right='56px'; - setTimeout(function(){ - node.node2.delete(); - delete node.node2; - },1000); - return; - } - node.clicked=true; - node.querySelector('.toggle').innerHTML='已选择' - game.me.jpa-=100; - game.me.jp-=100; - ui.jp.innerHTML=game.me.jp; - ui.jpa.innerHTML=game.me.jpa; - game.me.recover(); - })); - if(game.me.maxHp<5){ - dialog.add(ui.create.line('体力上限',1000,function(){ - var node=this.parentNode; - if(node.clicked) return; - if(game.me.jp<1000){ - if(node.node2) return; - node.node2=ui.create.div('.toggle',node).animate('start'); - node.node2.innerHTML='点数不足'; - node.node2.style.right='56px'; - setTimeout(function(){ - node.node2.delete(); - delete node.node2; - },1000); - return; - } - node.clicked=true; - node.querySelector('.toggle').innerHTML='已选择' - game.me.jpa-=1000; - game.me.jp-=1000; - ui.jp.innerHTML=game.me.jp; - ui.jpa.innerHTML=game.me.jpa; - game.me.maxHp++; - game.me.update(); - })); - } - dialog.add(ui.create.div('.placeholder')); - dialog.add(ui.create.line('重置技能',function(){ - var i,j; - for(i in lib.player){ - while(game.me.learned[i].length>1){ - j=game.me.learned[i].pop(); - ui.learned[j].childNodes[1].innerHTML=lib.player[i][j]; - } - } - game.me.jpa=Math.ceil(0.9*game.me.jpa); - game.me.jp=game.me.jpa; - game.me.jpe=0; - for(i=0;i<10;i++){ - if(i==2||i==5||i==8) continue; - dialog.content.childNodes[i].querySelector('.toggle').innerHTML='无'; - dialog.content.childNodes[i].querySelector('.toggle').link='无'; - } - ui.jp.innerHTML=game.me.jp; - ui.jpa.innerHTML=game.me.jpa; - ui.jpe.innerHTML=0; - })); - var jp=ui.create.line('剩余点数',game.me.jp); - ui.jp=jp.childNodes[1]; - dialog.add(jp); - var jpe=ui.create.line('装备技能',game.me.jpe); - ui.jpe=jpe.childNodes[1]; - dialog.add(jpe); - var jpa=ui.create.line('技能点数',game.me.jpa); - ui.jpa=jpa.childNodes[1]; - dialog.add(jpa); - var control=ui.create.control('完成',function(){ - game.me.clearSkills(); - var link; - for(var i=0;i<10;i++){ - if(i==2||i==5||i==8) continue; - link=dialog.content.childNodes[i].querySelector('.toggle').link; - switch(dialog.content.childNodes[i].firstChild.innerHTML){ - case '主动技能一':game.me.learned1=link;break; - case '主动技能二':game.me.learned2=link;break; - case '被动技能一':game.me.learned3=link;break; - case '被动技能二':game.me.learned4=link;break; - case '锁定技能一':game.me.learned5=link;break; - case '锁定技能二':game.me.learned6=link;break; - case '限定技':game.me.learned7=link;break; - } - if(link!='无') game.me.addSkill(link); - } - control.close(); - dialog.close(); - event.finish(); - game.resume(); - }) - game.pause(); - "step 1" - while(ui.dialogs.length){ - ui.dialogs[0].close(); - } - while(ui.controls.length){ - ui.controls[0].close(); - } - } - }, - infinity_jp:{ - init:function(){ - game.me.storage.infinity_jp=true; - }, - group:['jp_damage','jp_kill','jp_use','jp_skill'], - intro:{ - content:function(intro,player){ - return '技能点数:'+player.jp+'/'+player.jpa; - } - } - }, - infinity_add:{ - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - filter:function(){ - return _status.list.length&&game.players.length<8; - }, - content:function(){ - var position,player; - var num=get.population('zhong')+1+Math.min(3,Math.floor(game.me.jpa/1000))-get.population('fan'); - if(get.population('zhong')>1) num--; - if(num>0&&Math.random()player.jp) n=player.jp; - game.me.popup('技能点数 -'+n); - game.log(get.translation(game.me)+'扣减了'+n+'点技能点数'); - player.jp-=n; - player.jpa-=n; - } - }, - jp_damage:{ - trigger:{source:'damageAfter'}, - forced:true, - popup:false, - content:function(){ - player.jp+=Math.floor(trigger.num*30*(1.5-get.difficulty()/6)); - player.jpa+=Math.floor(trigger.num*30*(1.5-get.difficulty()/6)); - game.log(get.translation(game.me)+'获得了'+Math.floor(trigger.num*30*(1.5-get.difficulty()/6))+'点技能点数'); - } - }, - jp_kill:{ - trigger:{source:'dieAfter'}, - forced:true, - popup:false, - content:function(){ - player.jp+=Math.floor(100*(1.5-get.difficulty()/6)); - player.jpa+=Math.floor(100*(1.5-get.difficulty()/6)); - game.log(get.translation(game.me)+'获得了'+Math.floor(100*(1.5-get.difficulty()/6))+'点技能点数'); - game.me.draw(4-get.difficulty()); - } - }, - jp_use:{ - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - content:function(){ - player.jp+=Math.floor(10*(1.5-get.difficulty()/6)); - player.jpa+=Math.floor(10*(1.5-get.difficulty()/6)); - game.log(get.translation(game.me)+'获得了'+Math.floor(10*(1.5-get.difficulty()/6))+'点技能点数'); - } - }, - jp_skill:{ - trigger:{player:'useSkillAfter'}, - forced:true, - popup:false, - content:function(){ - player.jp+=Math.floor(20*(1.5-get.difficulty()/6)); - player.jpa+=Math.floor(20*(1.5-get.difficulty()/6)); - game.log(get.translation(game.me)+'获得了'+Math.floor(20*(1.5-get.difficulty()/6))+'点技能点数'); - } - }, - dushi:{ - trigger:{source:'damageBefore'}, - forced:true, - priority:10, - content:function(){ - trigger.untrigger(); - trigger.finish(); - trigger.player.loseHp(trigger.num); - } - }, - yizhong:{ - trigger:{target:'shaBefore'}, - forced:true, - filter:function(event,player){ - if(player.get('e','2')) return false; - return (event.card.name=='sha'&&get.color(event.card)=='black') - }, - content:function(){ - trigger.untrigger(); - trigger.finish(); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(target.get('e','2')) return; - if(card.name=='sha'&&get.color(card)=='black') return 0; - } - } - } - }, - }, - translate:{ - fan:'敌', - zhu:'将', - zhong:'友', - nei:'中', - initiative1_config:'主动技能一', - initiative2_config:'主动技能二', - trigger1_config:'被动技能一', - trigger2_config:'被动技能二', - lock1_config:'锁定技能一', - lock2_config:'锁定技能二', - limited_config:'限定技', - infinity_jp:'技能', - czt_linghubing:'令狐士兵', - czt_linghubing2:'令狐士兵', - czt_linghujiang:'令狐军官', - czt_duanmu:'端木老人', - czt_mindafu:'闵大夫', - czt_beigongdafu:'北宫大夫', - czt_she:'蛇', - czt_zhizhu:'蜘蛛', - czt_she2:'蛇', - czt_zhizhu2:'蜘蛛', - czt_jiaojisi:'蛟祭司', - czt_guchongji:'鼓虫机', - czt_mujiagui:'木甲龟', - czt_mujiafangzhen:'木甲方阵', - dushi:'毒噬', - yizhong:'毅重', - yizhong_info:'锁定技,当你没有防具时,黑色的杀对你无效', - dushi_info:'锁定技,你即将造成的伤害均视为体力流失', - czt_jinbing:'晋军士兵', - czt_jinbing2:'晋军士兵', - czt_linghuguojun:'令狐国君', - }, - character:{ - czt_linghubing:['male','wei',2,[]], - czt_linghubing2:['male','wei',3,[]], - czt_linghujiang:['male','wei',5,[]], - czt_duanmu:['male','wei',0,[]], - czt_she:['male','qun',2,['dushi']], - czt_zhizhu:['male','qun',1,['dushi']], - czt_she2:['male','qun',3,['dushi']], - czt_zhizhu2:['male','qun',2,['dushi']], - czt_jiaojisi:['male','wei',0,[]], - czt_mindafu:['male','wei',0,[]], - czt_beigongdafu:['male','wei',0,[]], - czt_linghuguojun:['male','wei',0,[]], - czt_guchongji:['male','shu',3,['wushuang']], - czt_mujiafangzhen:['male','shu',3,['luanji','shensu']], - czt_mujiagui:['male','shu',4,['yizhong']], - czt_jinbing:['male','shu',3,['mashu']], - czt_jinbing2:['male','shu',4,['mengjin']], - }, - config:{ - difficulty:true, - player_number:false, - double_character:false, - change_choice:false, - free_choose:false, - change_identity:false, - swap:false, - save_progress:true, - ai_identity:false, - revive:false, - }, - progress:[ - '令狐国', - ['swd_cheyun','怎搞的,最近老做这梦…… '], - ['swd_cheyun','而且每次都会梦到大哥哥…… '], - ['swd_cheyun','你说这到底是怎么回事呢,云狐…… '], - ['czt_linghujiang','喂,车家的小娃儿! '], - ['swd_cheyun','啊,是你们……? '], - ['swd_cheyun','国君他……是不是答应我的请求了?'], - ['czt_linghujiang','国君是答应了…… '], - ['czt_linghujiang','你可要搞清楚,车氏小娃!'], - ['czt_linghujiang','若非晋人就快打来了,不然没人愿意让你使用这怪东西! '], - ['swd_cheyun','好过分!人家这才不是什么怪东西! '], - ['swd_cheyun','这是爷爷的木甲术,是爷爷木甲术制造出来的云狐! '], - ['swd_cheyun','光一只云狐,就可以抵得过好几乘的兵车! '], - ['czt_linghujiang','哦,是吗?'], - ['czt_linghujiang','别忘了~当初就是因为你祖父研究这些玩意儿,你们车氏全族才会被抄灭!'], - ['swd_cheyun','哼~才不是呢!'], - ['swd_cheyun','是北宫大夫陷害爷爷,说他研究什么不祥的东西,国君才下令爷爷自戕的!'], - ['czt_linghujiang','哼,劝你最好少说北宫大夫的不是!'], - ['swd_cheyun','可是明明就是——'], - ['czt_linghujiang','好啦,没空同你啰唆了!'], - ['czt_linghujiang','你不是还向国君请求可以出入你们车氏昔日故宅的铜令符?'], - ['得到铜令符',''], - ['czt_linghujiang','啧~怎么?你那是什么表情?'], - ['swd_cheyun','哼~我一定会好好证明给北宫大夫和你们看看的!'], - ['czt_linghujiang','随你便~根本就没人期待你能做些什么! '], - ['czt_linghujiang','我们得去忙防御工事了,你好自为之吧~~'], - ['czt_linghubing','奉劝你,小娃儿~'], - ['czt_linghubing','可别以为上战场打仗,是你平日的家家酒儿戏!'], - ['swd_cheyun','真讨厌,神气什么嘛~~可恶!'], - ['swd_cheyun','等著瞧,我一定会让你们全都刮目相看的!'], - ['swd_cheyun','云狐~我等一下就去替你拿铜令符,带你回我们的老家去了!'], - ['swd_cheyun','那里有爷爷的木甲工房,可以把你变得更厉害!'], - ['swd_cheyun','对了……我得先回茅屋去告诉端木爷这事。'], - 1, - '端木茅屋', - ['swd_cheyun','端木爷~端木爷~我回来啦!'], - ['czt_duanmu','咳……咳咳…… '], - ['czt_duanmu','咳……咳咳…… '], - ['czt_duanmu','你这些日子,究竟是跑到哪去了?'], - ['swd_cheyun','嘻~端木爷,您猜猜看嘛!'], - ['czt_duanmu','唉,不是端木爷爱叨念你……'], - ['czt_duanmu','如今端木爷人病了,目力脚力都差了…… '], - ['czt_duanmu','再没法子像过去那样,成天四处去找你……'], - ['swd_cheyun','端木爷,您就猜一下下嘛~'], - ['czt_duanmu','唉……猜个什么猜呀?'], - ['czt_duanmu','一定又是去找你那个云狐的木料…… '], - ['czt_duanmu','唉,早告诉过你好几次,不要老是这样…… '], - ['czt_duanmu','只是去找木料就罢了,还穿什么新衣裳?'], - ['swd_cheyun','嘻,所以说端木爷完全猜错了~~猜错了! '], - ['swd_cheyun','嘻,端木爷~人家是去都城,找国君! '], - ['czt_duanmu','去都城,找国君?'], - ['czt_duanmu','不要以为端木爷病昏了,你就可以随便编个藉口来蒙骗端木爷……'], - ['swd_cheyun','哼,人家才没骗您呢!'], - ['swd_cheyun','端木爷,您看这个——— '], - ['czt_duanmu','这……又是什么?'], - ['swd_cheyun','是国君给我的铜令符!'], - ['swd_cheyun','我现在可以自由返回我们老家那里去了哦~嘻! '], - ['czt_duanmu','国君他……竟会答应你的要求?'], - ['swd_cheyun','对呀~所以您瞧,人家的本事够厉害吧!'], - ['czt_duanmu','呃……这实在令人难以置信啊!'], - ['swd_cheyun','端木爷有没有大大吃了一惊呢? '], - ['swd_cheyun','从今天起,人家就可以光明正大去爷爷的木甲工房哦!'], - ['swd_cheyun','也就是爷爷竹简上,提到的那个地方……'], - ['czt_duanmu','唉,老实说,有时候端木爷真忍不住要怀疑…… '], - ['czt_duanmu','当初把老主人关于木甲术的那些竹简交给了你,是否是对的…… '], - ['swd_cheyun','端木爷怎么这么说呢?'], - ['swd_cheyun','谁叫端木爷自己没想到,人家能把爷爷他的云狐,真的成功做了出来?'], - ['swd_cheyun','端木爷应该替爷爷和人家高兴才对嘛~~ '], - ['czt_duanmu','唉……话是如此没错!'], - ['czt_duanmu','但你们车氏一族,当初就是因为研究木甲术才遭奸人陷害的啊……'], - ['czt_duanmu','全族只有你因年纪小,才勉强能用砍掉双脚的刖刑换过一死…… '], - ['swd_cheyun','可是,端木爷……那才不是木甲术的错啊!'], - ['swd_cheyun','爷爷他根本就是被北宫大夫故意陷害的! '], - ['swd_cheyun','所以我一定要证明给国君他们看看——— '], - ['swd_cheyun','让他们都晓得,爷爷的木甲术才不是什么坏东西!'], - ['czt_duanmu','端木爷知道你的苦心,可是…… '], - ['czt_duanmu','你所不知道的,是人心的险恶…… '], - ['swd_cheyun','人心的险恶……? '], - ['czt_duanmu','唉,算了……这并不是你这年纪所该知道的事情。'], - ['czt_duanmu','那接下来,你打算如何做? '], - ['swd_cheyun','我要前去爷爷的木甲工房,找一份他曾提到过的木甲要术。'], - ['swd_cheyun','因为它可以提升云狐的力量! '], - ['czt_duanmu','………… '], - ['swd_cheyun','因为现在有坏人要来攻打我们的都城,'], - ['swd_cheyun','所以我想到,如果我能带著云狐,去帮大家一起对抗他们…… '], - ['swd_cheyun','只要有了功劳,国君一定会愿意恢复我们车氏的名誉!'], - ['czt_duanmu','唉,傻孩子…… '], - ['czt_duanmu','人世间的事,岂有你想的那般简单呀? '], - ['swd_cheyun','这有什么不对的嘛! '], - ['swd_cheyun','如果我们国家被人家给灭了,不就真的永远也没机会替爷爷他平复了?'], - ['czt_duanmu','傻孩子……晋国是当今全天下的霸主呀!'], - ['czt_duanmu','连凶神恶煞、天下无敌的楚国人,都才刚刚被他们打败……你这不过是去送死罢了!'], - ['swd_cheyun','哼,人家才不管啦~ '], - ['swd_cheyun','人家好不容易才让国君答应,说可以一起帮忙抵抗敌人……'], - ['swd_cheyun','打死我,也绝不要错过这样难得宝贵的机会!'], - ['czt_duanmu','但、但是…… '], - ['swd_cheyun','反正不管怎么样,人家一定都要去的!'], - ['swd_cheyun','就算端木爷再怎么反对也一样! '], - ['czt_duanmu','慢、慢著…… '], - ['czt_duanmu','你要去哪里? '], - ['swd_cheyun','当然是想办法去爷爷的木甲工房呀! '], - ['swd_cheyun','人家晋国的军队,再过几天后就要打来了'], - ['swd_cheyun','人家要及时找到爷爷说的那个木甲要术,让云狐变得更厉害才行!'], - ['czt_duanmu','等一下啊…… '], - ['czt_duanmu','万一……万一你根本找不到那东西呢? '], - ['swd_cheyun','那简单嘛~就直接上战场去帮大家的忙!'], - ['swd_cheyun','反正人家的云狐才没有那么弱! '], - ['swd_cheyun','端木爷您就请别担心啦~ '], - ['czt_duanmu','老主人,这下该如何是好,到底该如何是好呢……'], - '竹林', - ['swd_cheyun','原来要去爷爷安设在地底下的木甲工房……'], - ['swd_cheyun','还需要一块被偷埋在这个断崖树下的玉玦当引子,才进得去啊…… '], - ['swd_cheyun','端木爷也真是的,那么多年都不告诉我这件事……直到刚刚才告诉我! '], - ['swd_cheyun','爷爷也好过分,在竹简上连提都没提——真是差一点害我白忙一场了!'], - ['swd_cheyun','我得赶快把它给找到才成! '], - ['端木茅屋'], - ['swd_cheyun','端木爷,我找到了您埋藏的玉玦了! '], - ['swd_cheyun','这玉玦该怎么用呢? '], - ['czt_duanmu','嗯,端木爷想一想…… '], - ['czt_duanmu','你先去车氏故宅,找到一道通往地下的青铜密门'], - ['czt_duanmu','里面便是老主人昔日的木甲工房了。 '], - ['swd_cheyun','哼~不过端木爷竟然事到临头,才告诉人家有这块玉玦,真是过分!'], - ['czt_duanmu','傻孩子……端木爷这是为了你好啊!'], - ['czt_duanmu','毕竟端木爷不希望你步入了老主人的后尘…… '], - ['swd_cheyun','难怪我有几次半夜偷偷翻墙溜进那里,想去找爷爷的木甲工房, '], - ['swd_cheyun','结果却什么也没有发现! '], - ['czt_duanmu','唉……若不是端木爷担心你战场上会遇到危险, '], - ['czt_duanmu','不然端木爷可真的是不愿告诉你的…… '], - ['swd_cheyun','可是……万一端木爷您都不说, '], - ['swd_cheyun','那爷爷昔日的心血,我不就永远都不知道了吗? '], - ['czt_duanmu','唉……当初若不是端木爷去把这玉玦藏了起来,'], - ['czt_duanmu','国君和北宫氏早就派人去地下,烧光老主人的心血了! '], - ['czt_duanmu','如今又何来什么木甲工房,还会在那里呢? '], - ['swd_cheyun','嗯……我懂了,谢谢端木爷! '], - ['czt_duanmu','说到这…… '], - ['czt_duanmu','端木爷记得,老主人在工房之内似乎设有一些木甲守卫…… '], - ['czt_duanmu','听老主人说,那是一些他特意装上青铜外壳的木甲兽,用来防止外人擅入,'], - ['czt_duanmu','你进去以后,可得千万小心不要触动了它们, '], - ['czt_duanmu','否则,它们或许会把你当作外人来防的! '], - ['swd_cheyun','嗯,我知道了! '], - ['czt_duanmu','好吧……那你快去快回吧! '], - ['czt_duanmu','自己多小心,可别让端木爷挂心……'], - ['swd_cheyun','我会非常小心的,请端木爷您放心! '], - ['swd_cheyun','那人家出发了哦~ '], - '车氏故宅', - ['车芸来到故宅前,遇到两名守卫拦阻'], - ['czt_linghubing','木脚的小娃,你又跑来想做什么啊?'], - ['czt_linghubing2','走开~快走开!'], - ['swd_cheyun','等一下,你们看看这是什么?'], - ['czt_linghubing','铜令符…………?'], - ['czt_linghubing','小鬼,你是从哪里拣来的?'], - ['czt_linghubing2','哼~我看搞不好还是偷来的'], - ['swd_cheyun','你们乱说什么啊?'], - ['swd_cheyun','这是我来都城,特地请国君给我的~'], - ['swd_cheyun','国君准许我可以进出我的老家了!'], - ['czt_linghubing','你说这是国君给你的铜令符?'], - ['czt_linghubing','哼~我们只听北宫大夫的话而已,这里是他的采邑了!'], - ['czt_linghubing2','国君他算哪根葱啊?'], - ['swd_cheyun','啊?'], - ['czt_linghubing','走开走开,臭娃儿!'], - ['czt_linghubing2','你再不走,我们就把你抓起来,直接交给北宫大夫发落!'], - ['czt_linghubing2','没错~到时可不止双脚而已,搞不好连你双手也都要被剁掉了!'], - ['swd_cheyun','可恶,你们————'], - ['swd_cheyun','哼,这真的是国君的令符,对吗?'], - ['czt_linghubing','没错啊!'], - ['czt_linghubing','不过我们不接受,你还是早些滚开吧!'], - ['swd_cheyun','太好了,我已经听到想听到的答案了!'], - ['czt_linghubing','答案…………?'], - ['车芸召唤出云狐'], - ['swd_cheyun','既然国君都准许我过去了————'], - ['swd_cheyun','所以把你们打跑,国君也不会责备…………对吧?'], - ['swd_cheyun','听话,乖云狐,'], - ['swd_cheyun','让他们知道爷爷木甲术的厉害!'], - 0, - ['战斗胜利,两名守卫逃跑'], - ['swd_cheyun','终于知道人家木甲术的厉害了吧'], - ['swd_cheyun','好了,终于可以安心去爷爷的木甲工房了!'], - ['swd_cheyun','我回来了……爷爷! '], - ['swd_cheyun','真怀念以前小时候,大家都还在这里的日子…… '], - ['swd_cheyun','但是如今这里都荒废了,爷爷…… '], - ['swd_cheyun','不过,我一定会努力为您以及大家洗雪冤屈…… '], - ['swd_cheyun','至少也要让所有人都知道,爷爷您的木甲术绝不是什么坏的东西…… '], - ['swd_cheyun','所以爷爷您在九泉之下,请保佑我…… '], - ['swd_cheyun','请大家保佑我…… '], - '木甲工房', - ['swd_cheyun','哗……… '], - ['swd_cheyun','这就是爷爷您的木甲工房吗……?'], - ['swd_cheyun','没想到竟然这么大!'], - ['swd_cheyun','真是不敢相信…… '], - ['swd_cheyun','爷爷,原来您比我想像中的还更了不起……'], - ['swd_cheyun','家要更努力了,绝对不能辜负了您…… '], - ['swd_cheyun','因为……我是您的孙女儿啊! '], - ['石室'], - ['swd_cheyun','哗…… '], - ['swd_cheyun','这就是爷爷说的石室? '], - ['swd_cheyun','真是了不起~ '], - ['swd_cheyun','不知爷爷当初是怎造出来的! '], - ['swd_cheyun','哎呀? '], - ['swd_cheyun','出口的石门竟然自己关了起来…… '], - ['swd_cheyun','这是怎么回事啊……这下子我不就出不去了?'], - ['swd_cheyun','对了……这应该也是一个爷爷他用来防止别人随便进来的设计吧? '], - ['swd_cheyun','但现在却先把自己孙女儿第一个给困住了……这下该怎办才好呢? '], - ['swd_cheyun','算了,怕它什么~ '], - ['swd_cheyun','我还是先去找到爷爷的木甲要术要紧! '], - ['车芸扳动一个机关,木甲要术出现'], - ['swd_cheyun','哗……原来还有这样的机关呀? '], - ['swd_cheyun','那个在铜瓮水面上翻来滚去的竹简,该不会就是爷爷他的木甲要术? '], - ['swd_cheyun','哈哈~真没想到爷爷还弄出这么有趣的花样! '], - ['swd_cheyun','我快过去看看吧! '], - ['得到木甲要术'], - ['另一侧的石门打开'], - ['swd_cheyun','哗,这真的是爷爷的木甲要术竹简呢…… '], - ['swd_cheyun','收获真不少……真是太好了! '], - ['swd_cheyun','不过话说回来,爷爷怎么那么糊涂呢,一点防备都没有…… '], - ['swd_cheyun','这么重要的东西,竟然人家随随便便转一下铜榫,就自己浮了出来! '], - ['swd_cheyun','真是的~~万一被坏人拿走了怎么办呢? '], - ['swd_cheyun','好!以后~我绝不可以像爷爷这么糊涂! '], - ['木甲工房'], - ['车芸走出石门,一个木甲守卫机关出现'], - ['swd_cheyun','这是什么东西呀……? '], - ['swd_cheyun','有包上青铜外壳的木甲兽……难不成这个是…… '], - ['swd_cheyun','端木爷说的,爷爷以前制造出来负责看守这里的青铜木甲守卫?'], - ['swd_cheyun','原来这一边的通道,是有木甲守卫的呀? '], - ['swd_cheyun','我刚刚可错怪爷爷了……'], - ['swd_cheyun','哎呀……? '], - ['swd_cheyun','等一下……等一下! '], - ['swd_cheyun','我是你们主人的孙女儿啊,并不是什么坏人呀! '], - ['swd_cheyun','糟糕,它好像完全听不懂呀……怎么办?'], - 2, - 3, - 4, - 5, - 6, - ['车氏故宅'], - ['swd_cheyun','爷爷,爹娘…… '], - ['swd_cheyun','谢谢你们保佑我能平安取得了木甲要术…… '], - ['swd_cheyun','我和云狐一定会好好努力,建立功劳,'], - ['swd_cheyun','让所有人都知道,爷爷您研究的木甲术是真的能保护我们国家的! '], - ['swd_cheyun','而绝不是大家误会的什么不好的坏东西…… '], - ['swd_cheyun','我走了……爷爷,爹娘!'], - ['swd_cheyun','请你们继续保佑我…… '], - ['swd_cheyun','保佑我能顺利…… '], - ['端木茅屋'], - ['swd_cheyun','端木爷,我回来了~ '], - ['czt_duanmu','你终于回来了?'], - ['czt_duanmu','怎去了这么久,让端木爷好担心啊! '], - ['swd_cheyun','人家不小心启动木甲守卫了嘛,所以多花了一些时间! '], - ['czt_duanmu','啊,那你没受伤吧? '], - ['swd_cheyun','哼,人家才没那么没用呢! '], - ['swd_cheyun','不过爷爷的木甲工房,真的是好了不起呢! '], - ['czt_duanmu','那当然了…… '], - ['swd_cheyun','但是为什么那些木甲守卫,每一个看起来都那么简陋呀? '], - ['czt_duanmu','简陋?'], - ['swd_cheyun','是呀~跟云狐比起来,实在差太多了嘛! '], - ['swd_cheyun','等一下,我来想一想看有哪些…… '], - ['swd_cheyun','嗯,有一些奇怪的铜乌龟…… '], - ['swd_cheyun','还有一些吊著线,会飘来荡去的螳螂方块! '], - ['czt_duanmu','唉……那些都是老主人他最早制作的木甲兽啊! '], - ['czt_duanmu','所以比不上云狐,是当然的! '], - ['swd_cheyun','最早制作的木甲兽? '], - ['czt_duanmu','老主人为人念旧,所以也不忍抛弃它们,'], - ['czt_duanmu','于是就给它们套上了青铜外壳,担任那边的守卫。 '], - ['swd_cheyun','喔,原来是这样啊? '], - ['czt_duanmu','是啊,不然能构想出云狐的老主人,岂会只有如此的造诣? '], - ['swd_cheyun','对了,端木爷~ '], - ['swd_cheyun','除了乌龟和螳螂,人家还看见有用两脚站立的木甲兽呢!'], - ['swd_cheyun','不过也很简陋就是了! '], - ['czt_duanmu','嗯,好像曾有听老主人提起过他最大的心愿…… '], - ['czt_duanmu','好像就是希望自己木甲术的造诣,哪一日能到达传说中木甲术之祖偃师的境界哪!'], - ['swd_cheyun','爷爷的竹简内有提到这个人,但只有名字而已…… '], - ['swd_cheyun','他是怎样的一个人啊? '], - ['czt_duanmu','听说在百年之前,偃师用木甲术所制作之木人'], - ['czt_duanmu','便能栩栩如生,轻巧如云…… '], - ['czt_duanmu','老主人便是年轻时代阅读过相关文献,才开始对木甲术有兴趣, '], - ['czt_duanmu','他便一心以此为目标,希望自己能逐步接近偃师造诣…… '], - ['czt_duanmu','可惜云狐才刚构思完没多久,老主人便被国君敕令自裁…… '], - ['czt_duanmu','所以,老主人便永远再无法实现他的心愿…… '], - ['swd_cheyun','(原来爷爷最大的心愿,是要用木甲术制造出栩栩如生的木人啊?) '], - ['swd_cheyun','(说不定哪天,我可以替爷爷实现心愿!)'], - ['czt_duanmu','对了,晋人何时会攻打我们的都城呢?'], - ['swd_cheyun','可以这几日就到了吧'], - ['swd_cheyun','不过不管他们什么时候来,人家都不怕了~'], - ['czt_duanmu','别轻敌啊,对方可是天下最强的晋国呀!'], - ['czt_duanmu','你若有什么意外,端木爷可是无端到黄泉下面对你的老主人呀!'], - ['swd_cheyun','端木爷,这个你就别担心~~'], - ['swd_cheyun','请您留在这是,等着听我的好消息就行了。'], - '令狐国都城', - ['czt_linghujiang','刚刚接获通报,晋军已经突破了东郭外的防线'], - ['czt_linghujiang','你们立刻去那里守城,明白吗?'], - ['众士兵','是!'], - ['czt_linghubing2','禀告大人,西北角晋人的攻势十分猛烈!情势吃紧!'], - ['czt_linghujiang','你说什么?'], - ['czt_linghubing2','肯求大人,能立刻增援人手!'], - ['czt_linghujiang','可恨的晋狗,如此嚣张四处灭人社稷…………'], - ['czt_linghujiang','你们全部改去西郭北角!'], - ['众士兵','是!'], - ['czt_linghujiang','好的,去吧…………'], - ['swd_cheyun','等一下————'], - ['swd_cheyun','人家特地带着云狐,要求来帮忙的呀!'], - ['swd_cheyun','可是你们为什么从刚才到现在,一直都不差人家一起去呢?'], - ['czt_linghujiang','差你去…………?'], - ['czt_linghujiang','你们几个,快去西北角,不得延耽!'], - ['czt_linghujiang','莫让晋狗他们得逞,攻破都城!'], - ['众士兵','是!'], - ['swd_cheyun','………… '], - ['czt_linghujiang','车氏小娃,你你到底烦不烦人啊?'], - ['swd_cheyun','云狐明明可以帮大家很多忙的!'], - ['czt_linghujiang','你少啰嗦!'], - ['czt_linghujiang','北宫大人已经吩咐,不得让你有机会去战场!'], - ['swd_cheyun','你说什么?'], - ['czt_linghujiang','北宫大人早已交代下来………… '], - ['czt_linghujiang','你们车氏那套妖诡之术,会得罪上天!'], - ['czt_linghujiang','届时将会给社稷,带来更大之厄运! '], - ['swd_cheyun','原来你们一开始,就没打算让我…………'], - ['czt_linghujiang','哼!你明白了就好!'], - ['czt_linghujiang','奉劝你安分点,以免连累身边其他人!'], - ['令狐军官离开'], - - ['swd_cheyun','真可恶,福气什么嘛!'], - ['swd_cheyun','这下子我们该怎么办呢,云狐?'], - ['swd_cheyun','好不容易才让你变得稍微强了一些呢…………'], - ['swd_cheyun','到底要做什么才好呢?'], - ['swd_cheyun','还是去别处找找有什么能帮忙的,'], - ['swd_cheyun','我就不相信,真的没有需要我的地方!'], - - ['swd_cheyun','咦,那不是北宫大夫吗?'], - ['swd_cheyun','哼!在人家背后偷偷搞鬼,'], - ['swd_cheyun','故意不让人家有机会让人家建立功劳'], - ['swd_cheyun','现在又在这儿,跟别人吵些什么?'], - ['swd_cheyun','好,我来偷听一下~~'], - ['czt_mindafu','北宫大人,您这样的说法,下官实在难以接受啊!'], - ['czt_mindafu','如今都城将被晋人所攻破,为何您还不愿接受在下的建议呢?'], - ['czt_beigongdafu','闵大夫,请您弄明白些!'], - ['czt_beigongdafu','国君地位尊贵,身负社稷之重,'], - ['czt_beigongdafu','岂可让他如你建议这般,轻言犯险?'], - ['czt_mindafu','但是北宫大人,世子方才不幸已经阵亡于战场上!'], - ['czt_mindafu','如今若国君也遭难,那我令狐国社稷可真要从此断绝宗祀、永远灭亡了!'], - ['czt_beigongdafu','闵大夫,邦国之事自有本卿负责作主,请您勿再多言!'], - ['czt_beigongdafu','请您立即把出城地道,全掩盖起来!'], - ['czt_beigongdafu','若您那些地道真能让国君出逃出城,也能让晋军攻进来!'], - ['czt_beigongdafu','半个时辰之后,本卿将再派人来看,'], - ['czt_beigongdafu','到时候,您最好莫让本卿发现它们还在那里!'], - ['czt_mindafu','北宫大人,您难道真不知道轻重缓急?'], - ['czt_mindafu','万一国君他被晋人俘虏了———— '], - ['czt_beigongdafu','闵大夫,庙堂之事,自有我们北宫氏作主!'], - ['czt_beigongdafu','若您再多言,就请好自为之吧!'], - ['czt_mindafu','你————'], - ['czt_beigongdafu','抱歉,本卿不再多说了。'], - ['czt_beigongdafu','告辞! '], - - ['czt_beigongdafu','哎唷!'], - ['czt_beigongdafu','这可不是车氏的小娃吗?'], - ['czt_beigongdafu','竟敢趁着本卿前去晋国与太辰宫交涉,不在都城之际,'], - ['czt_beigongdafu','自己偷偷跑去见国君啊?'], - ['czt_beigongdafu','和那个老头一样,挺大胆子的嘛!'], - - ['czt_mindafu','可恨啊…………'], - ['czt_mindafu','国之将亡,庙堂必有邪侫!'], - ['czt_mindafu','若我社稷真的亡了,就是亡在北宫氏你等邪侫之手!'], - - ['swd_cheyun','请问一下…………'], - ['czt_mindafu','咦,你是…………?'], - ['swd_cheyun','我是车大夫他的孙女儿,车芸。'], - ['czt_mindafu','你是,已故的车大夫他的孙女儿?'], - ['swd_cheyun','是的~~'], - ['czt_mindafu','我想起来了!'], - ['czt_mindafu','听说,车氏有个忠心的老家臣,散心积蓄贿赂北宫大夫………… '], - ['czt_mindafu','才终于勉强挽回了车氏孤女的性命。 '], - ['czt_mindafu','想来那位车氏孤女,就是你吗?'], - ['czt_mindafu','哈哈,真没想到,如今已经长这么大了!'], - ['czt_mindafu','不过听说你们一老一少,不都一起避居于昔日采邑附近的山林间吗?'], - ['swd_cheyun','是啊,但是听说有坏人要攻打我们的国家,'], - ['swd_cheyun','所以我才想到,该带着爷爷他的云狐来都城,帮大家一同抵抗。'], - ['swd_cheyun','云狐…………?'], - ['swd_cheyun','是的,那是爷爷当初想出的木甲兵器,'], - ['swd_cheyun','爷爷生前已经构想得差不多了,我就替爷爷,把它给做了出来。'], - ['czt_mindafu','我想起来了,对了,是木甲术没错!'], - ['czt_mindafu','我听你爷爷提起过,但从未亲眼看过。'], - ['swd_cheyun','那我让您瞧瞧看~~'], - ['车芸召唤出云狐'], - ['czt_mindafu','这是…………'], - ['czt_mindafu','了不起,原来这就是车大夫所说的木甲兵器吗?'], - ['czt_mindafu','真的实在太惊人,太不可思议了!'], - ['czt_mindafu','没想到车大夫所说的都是真的!'], - ['swd_cheyun','爷爷说过,他的云狐,就算好几乘兵车,也不是它的对手'], - ['swd_cheyun','它如果跑起来,连兵车也追不上呢!'], - ['czt_mindafu','等等…………你既有如此厉害的兵器,'], - ['czt_mindafu','为何没帮大家一起抵御外敌?'], - ['swd_cheyun','都是北宫大夫呀! '], - ['swd_cheyun','他故意不让人家有机会帮忙的! '], - ['czt_mindafu','北宫大夫?'], - ['czt_mindafu','唉…………又是北宫大夫那厮!'], - ['czt_mindafu','其实我刚才也是和他在争辩,'], - ['czt_mindafu','对了,你来得正好,'], - ['czt_mindafu','你愿意帮我一个大忙吗?'], - ['swd_cheyun','当然好啊!'], - ['swd_cheyun','我本来就是希望能帮得上忙的!'], - ['czt_mindafu','那太好了'], - ['czt_mindafu','那请你到城墙边的木台下,那里有些地道的出入口。'], - ['czt_mindafu','我会在那里告诉你该怎么做'], - - ['swd_cheyun','闵大夫,刚才你说要我帮什么忙?'], - ['czt_mindafu','要麻烦你的,便是希望你下去这出城地道,'], - ['czt_mindafu','探一探是否有危险。'], - ['swd_cheyun','出城地道?'], - ['czt_mindafu','是的,你莫小看些事!'], - ['czt_mindafu','敌人攻势猛烈,都城旦夕不保'], - ['czt_mindafu','我担心国君被俘,社稷将因此而绝祀………… '], - ['czt_mindafu','若能由此顺利逃出,或可去出奔秦国或楚国,另谋他途。'], - ['swd_cheyun','听起来,好像我们快要输了吗?'], - ['czt_mindafu','嗯,这也是没办法的事,令人痛心!'], - ['czt_mindafu','晋人最近以各种奇奇怪怪的名义,四处征伐各诸侯国…………'], - ['czt_mindafu','即使强大如荆楚,也都不是他们的对手。'], - ['czt_mindafu','而天子和昔日霸主齐国,更不敢站出来主持公道,个个视而不见!'], - ['swd_cheyun','这我不是很懂………… '], - ['czt_mindafu','不打紧,'], - ['czt_mindafu','对了,我想麻烦你下去的这个地道,'], - ['czt_mindafu','其实它是昔日都城一次内乱,当时所发掘的…………'], - ['czt_mindafu','若我没记错,它可直通至城郊半里之外的山林地………… '], - ['swd_cheyun','这地道有这么远啊呀?'], - ['czt_mindafu','是的,但毕竟荒废一段时日了,不是是否仍然畅通。'], - ['czt_mindafu','说不定晋人也早发现了它…………所以需要有人前去探路。'], - ['czt_mindafu','必须确认安全无恙,都好说服国君由此避难'], - ['swd_cheyun','我明白了…………'], - ['swd_cheyun','可是既然这么重要,为什么没有早一点派人下去走一下呢?'], - ['czt_mindafu','唉…………'], - ['czt_mindafu','你刚才看到的争执就是为了些事!'], - ['czt_mindafu','北宫大夫以防御吃紧为由,把之前我派去探路的士兵,都背地里调走!'], - ['czt_mindafu','他还要我在半个时辰之内,掩盖掉这个地道…………'], - ['czt_mindafu','这地道可是国君最后逃生希望所系啊! '], - ['swd_cheyun','这样一说,我好像大概懂了………… '], - ['swd_cheyun','我必须赶快替国君确认一下,这地道到底安不安全,对不对? '], - ['swd_cheyun','是的'], - ['swd_cheyun','可是如果我在半路发现了敌人,该怎么办?'], - ['swd_cheyun','那你立刻返回都城内,'], - ['swd_cheyun','通知我将入口封掩起来!'], - ['swd_cheyun','嗯,没问题,云狐它跑得很快的。'], - - '地道', - 7, - 8, - 9, - ['swd_cheyun','等一等…………'], - ['swd_cheyun','好像听到有什么声音…………?'], - ['swd_cheyun','该不会是…………'], - - ['swd_cheyun','啊!'], - ['czt_jinbing','果然有人在这地道内!'], - ['czt_jinbing2','看来是想从这里逃出围城的小丫头!'], - ['czt_jinbing','得把她捉起来才行!'], - ['swd_cheyun','可恶,原来这地道早被发现了'], - 10, - - ['swd_cheyun','不好,这条地道已经被人发现了,该怎么办?'], - ['swd_cheyun','得赶紧回去通知闵大夫,快把地道给封起来!'], - - ['swd_cheyun','啊,这是怎么回事?'], - ['czt_mindafu','原来是车大夫的孙女………… '], - ['czt_mindafu','来得正好,前方情况怎样? '], - ['swd_cheyun','他们已经发现了这条地道!'], - ['swd_cheyun','我就是赶回来,要告诉您此事的!'], - ['czt_mindafu','可恨,上天难不成真要亡我社稷啊!'], - ['swd_cheyun','我想,我们还是赶快回都城去'], - ['czt_mindafu',' 都城回不去了…………'], - ['swd_cheyun','我们的都城被攻陷了?'], - ['czt_mindafu','是的…………'], - ['czt_mindafu','所以我只好带着国君,来此地避难………… '], - ['swd_cheyun','可是我们都城,怎么会那么容易被攻破啊?'], - ['czt_mindafu','因为这次晋国竟然派了太辰宫的九龙子祭官来参战………… '], - ['czt_mindafu','他们懂得许多奇异的妖术…………'], - ['czt_mindafu','我们士兵一触碰便全倒在地,无法再战!'], - ['czt_mindafu','于是四方城门,一下子都沦陷了…………'], - ['swd_cheyun','那…………北宫大夫他呢?'], - ['czt_mindafu','北宫那个叛徒,他投降晋人去了!'], - ['swd_cheyun','什么————'], - ['czt_mindafu','这块战争之前,他便利用出使晋国的机会,和他们有所勾结'], - ['czt_mindafu','他们早就协议好,要里应外合,出卖国君!'], - ['czt_mindafu','所以他才多方阻挠我,不让国君及早出奔他国!'], - ['swd_cheyun','北宫大夫他怎么会这么过分!'], - ['swd_cheyun','国君不是一直对他非常信任吗?'], - ['czt_linghuguojun','这一切都是寡人的错…………'], - ['czt_linghuguojun','都怪寡人信任些人,才害得社稷倾覆…………'], - ['czt_linghuguojun','寡人惭愧…………'], - ['czt_mindafu','国君…………'], - ['czt_mindafu','国君…………其实我们社稷的存亡,仍是有希望的!'], - ['czt_mindafu','如今秦、晋楚交恶,二国对晋国都十分不满。'], - ['czt_mindafu','只要您能顺利逃出此地,相信社稷仍有复兴之望!'], - ['czt_linghuguojun','追兵马上会发现这里的,此地根本躲不久啊…………'], - ['czt_linghuguojun','何况他们也不见得愿意帮助寡人………… '], - ['czt_mindafu','对了,车大夫的孙女儿'], - ['czt_mindafu','可否麻烦你,替国君开个道吗?'], - ['czt_mindafu','只要您能顺利逃出此地,相信社稷仍有复兴之望!'], - ['swd_cheyun','好,我这就去替国君开路!'], - ['czt_mindafu','嗯,那一切全看你了!'], - ['czt_mindafu','国君惊魂未定,我稍后便会带着国君慢慢前进。'], - ['czt_mindafu','你尽管向前走吧!'], - ['目前只写到这里,更多内容敬请期待^_^'] - ], - background:[ - ['linghu',33], - ['daditu1',1], - ['duanmu',75], - ['bamboo',6], - ['duanmu',29], - ['guzhai2',33], - ['guzhai',7], - ['gongfang',8], - ['shishi',25], - ['gongfang',16], - ['guzhai',9], - ['duanmu',44], - ['linghu2',31], - ['linghu3',6], - ['linghu4',24], - ['linghu5',5], - ['linghu6',3], - ['linghu7',40], - ['linghu8',36], - ['didao',7], - ['didao2',6], - ['didao',2], - ['didao3',70], - ], - battle:[ - { - name:'令狐守卫', - enemy:['czt_linghubing','czt_linghubing2'], - intro:'敌人:令狐守卫*2', - }, - { - name:'毒蛇蜘蛛', - enemy:['czt_she','czt_zhizhu'], - intro:'敌人:毒蛇*1;蜘蛛*1', - }, - { - name:'鼓虫机', - intro:'敌人:鼓虫机*1', - enemy:['czt_guchongji'], - }, - { - name:'木甲方阵', - enemy:['czt_mujiafangzhen'], - intro:'敌人:木甲方阵*1', - }, - { - name:'木甲龟', - intro:'敌人:木甲龟*1', - enemy:['czt_mujiagui'], - }, - { - name:'木甲组合一', - intro:'敌人:木甲方阵*1,鼓虫机*1', - enemy:['czt_mujiafangzhen','czt_guchongji'], - }, - { - name:'木甲组合二', - intro:'敌人:木甲方阵*1,木甲龟*1,鼓虫机*1', - enemy:['czt_mujiafangzhen','czt_guchongji','czt_mujiagui'], - }, - { - name:'地道毒虫一', - intro:'敌人:蛇*2,蜘蛛*2', - enemy:['czt_she2','czt_she2','czt_zhizhu2','czt_zhizhu2'], - }, - { - name:'地道毒虫二', - intro:'敌人:蛇*1,蜘蛛*3', - enemy:['czt_she2','czt_zhizhu2','czt_zhizhu2','czt_zhizhu2','czt_zhizhu2'], - }, - { - name:'地道毒虫三', - intro:'敌人:蛇*3,蜘蛛*3', - enemy:['czt_she2','czt_she2','czt_she2','czt_zhizhu2','czt_zhizhu2','czt_zhizhu2'], - }, - { - name:'晋军士兵', - intro:'敌人:晋军士兵*2', - enemy:['czt_jinbing','czt_jinbing2'], - }, - ], -} diff --git a/mode/archive/wuxian.js b/mode/archive/wuxian.js deleted file mode 100755 index e04def98a..000000000 --- a/mode/archive/wuxian.js +++ /dev/null @@ -1,772 +0,0 @@ -mode.infinity={ - game:{ - start:function(){ - var next=game.createEvent('load',false); - next.content=function(){ - "step 0" - game.import('identity'); - if(!lib.storage.version||lib.storage.version<0.833){ - localStorage.setItem(lib.config.mode,"{}"); - } - "step 1" - ui.create.arena(); - ui.auto.hide(); - ui.create.cards(); - game.finishCards(); - game.delay(); - "step 2" - if(get.config('save_progress')&&lib.storage.saved) game.loadGame(); - else game.prepareGame(); - "step 3" - event.trigger('gameStart'); - if(get.config('save_progress')&&lib.storage.saved){ - var card; - for(var i=0;i0) game.players[i].node.handcards1.appendChild(card); - else game.players[i].node.handcards2.appendChild(card); - } - } - for(var j=0;j20) {alert('!!!');break;} - } - while(player!=game.me); - game.save('player',current.dataset.position); - game.save('players',players); - game.save('jpa',game.me.jpa); - game.save('jpe',game.me.jpe); - game.save('jp',game.me.jp); - game.save('learned',game.me.learned); - game.save('learned1',game.me.learned1); - game.save('learned2',game.me.learned2); - game.save('learned3',game.me.learned3); - game.save('learned4',game.me.learned4); - game.save('learned5',game.me.learned5); - game.save('learned6',game.me.learned6); - game.save('learned7',game.me.learned7); - game.save('saved',true); - }, - clearProgress:function(){ - localStorage.setItem(lib.config.mode,"{}"); - lib.storage={}; - }, - onOver:function(){ - ui.create.control('继续',function(){ - while(ui.dialogs.length) ui.dialogs[0].close(); - while(ui.controls.length) ui.controls[0].close(); - _status.over=false; - if(game.me.isDead()){ - game.me.revive(game.me.maxHp); - game.me.draw(4); - } - else{ - var player=game.addPlayer(); - player.init(_status.list.randomGet()); - _status.list.remove(player.name); - if(Math.random()2&&get.population('fan')>0){ - game.removePlayer(this); - } - else if(game.players.length+game.dead.length>2&&this.identity!='fan'&&get.population('fan')>0){ - game.removePlayer(this); - } - else{ - var player=game.replacePlayer(this,_status.list.randomGet()); - player.draw(get.difficulty()); - player.identity='fan'; - player.identityShown=true; - player.setIdentity(); - _status.list.remove(player.name); - } - } - if(this.identity=='zhong'&&source==game.me) game.me.discard(game.me.get('h')); - if(source&&this.identity=='fan'){ - if(source.identity=='fan') source.draw(get.difficulty()); - else source.draw(4-get.difficulty()); - } - game.checkResult(); - } - } - }, - skill:{ - infinity_learn:{ - trigger:{player:'phaseBefore'}, - forced:true, - popup:false, - priority:20, - filter:function(){ - return !_status.auto; - }, - content:function(){ - "step 0" - if(_status.auto) return; - var dialog=ui.create.dialog(),i,j; - var addJpe=function(){ - game.me.jpe=0; - var link,skills=[]; - for(var i=0;i<10;i++){ - if(i==2||i==5||i==8) continue; - link=dialog.content.childNodes[i].querySelector('.toggle').link; - if(link!='无') skills.push(link); - } - var skills2={}; - for(var i in lib.player){ - for(var j in lib.player[i]){ - skills2[j]=lib.player[i][j]; - } - } - for(var i=0;igame.me.jp){ - if(that.node2) return; - that.node2=ui.create.div('.toggle',that).animate('start'); - that.node2.innerHTML='点数不足'; - that.node2.style.right='56px'; - setTimeout(function(){ - that.node2.delete(); - delete that.node2; - },1000); - return; - } - toggle.innerHTML='已学习'; - game.me.jp-=num; - game.me.learned[j].push(toggle.skill); - ui.jp.innerHTML=game.me.jp; - } - }); - node.childNodes[1].skill=i; - ui.learned[i]=node; - dialog.add(node); - } - }(j)) - dialog.add(ui.create.div('.placeholder')); - } - dialog.add(ui.create.line('摸两张牌',100,function(){ - var node=this.parentNode; - if(node.clicked) return; - if(game.me.jp<100){ - if(node.node2) return; - node.node2=ui.create.div('.toggle',node).animate('start'); - node.node2.innerHTML='点数不足'; - node.node2.style.right='56px'; - setTimeout(function(){ - node.node2.delete(); - delete node.node2; - },1000); - return; - } - node.clicked=true; - node.querySelector('.toggle').innerHTML='已选择' - game.me.jpa-=100; - game.me.jp-=100; - ui.jp.innerHTML=game.me.jp; - ui.jpa.innerHTML=game.me.jpa; - game.me.draw(2); - })); - dialog.add(ui.create.line('回复体力',100,function(){ - var node=this.parentNode; - if(node.clicked) return; - if(game.me.jp<100){ - if(node.node2) return; - node.node2=ui.create.div('.toggle',node).animate('start'); - node.node2.innerHTML='点数不足'; - node.node2.style.right='56px'; - setTimeout(function(){ - node.node2.delete(); - delete node.node2; - },1000); - return; - } - node.clicked=true; - node.querySelector('.toggle').innerHTML='已选择' - game.me.jpa-=100; - game.me.jp-=100; - ui.jp.innerHTML=game.me.jp; - ui.jpa.innerHTML=game.me.jpa; - game.me.recover(); - })); - if(game.me.maxHp<5){ - dialog.add(ui.create.line('体力上限',1000,function(){ - var node=this.parentNode; - if(node.clicked) return; - if(game.me.jp<1000){ - if(node.node2) return; - node.node2=ui.create.div('.toggle',node).animate('start'); - node.node2.innerHTML='点数不足'; - node.node2.style.right='56px'; - setTimeout(function(){ - node.node2.delete(); - delete node.node2; - },1000); - return; - } - node.clicked=true; - node.querySelector('.toggle').innerHTML='已选择' - game.me.jpa-=1000; - game.me.jp-=1000; - ui.jp.innerHTML=game.me.jp; - ui.jpa.innerHTML=game.me.jpa; - game.me.maxHp++; - game.me.update(); - })); - } - dialog.add(ui.create.div('.placeholder')); - dialog.add(ui.create.line('重置技能',function(){ - var i,j; - for(i in lib.player){ - while(game.me.learned[i].length>1){ - j=game.me.learned[i].pop(); - ui.learned[j].childNodes[1].innerHTML=lib.player[i][j]; - } - } - game.me.jpa=Math.ceil(0.9*game.me.jpa); - game.me.jp=game.me.jpa; - game.me.jpe=0; - for(i=0;i<10;i++){ - if(i==2||i==5||i==8) continue; - dialog.content.childNodes[i].querySelector('.toggle').innerHTML='无'; - dialog.content.childNodes[i].querySelector('.toggle').link='无'; - } - ui.jp.innerHTML=game.me.jp; - ui.jpa.innerHTML=game.me.jpa; - ui.jpe.innerHTML=0; - })); - var jp=ui.create.line('剩余点数',game.me.jp); - ui.jp=jp.childNodes[1]; - dialog.add(jp); - var jpe=ui.create.line('装备技能',game.me.jpe); - ui.jpe=jpe.childNodes[1]; - dialog.add(jpe); - var jpa=ui.create.line('技能点数',game.me.jpa); - ui.jpa=jpa.childNodes[1]; - dialog.add(jpa); - var control=ui.create.control('完成',function(){ - game.me.clearSkills(); - var link; - for(var i=0;i<10;i++){ - if(i==2||i==5||i==8) continue; - link=dialog.content.childNodes[i].querySelector('.toggle').link; - switch(dialog.content.childNodes[i].firstChild.innerHTML){ - case '主动技能一':game.me.learned1=link;break; - case '主动技能二':game.me.learned2=link;break; - case '被动技能一':game.me.learned3=link;break; - case '被动技能二':game.me.learned4=link;break; - case '锁定技能一':game.me.learned5=link;break; - case '锁定技能二':game.me.learned6=link;break; - case '限定技':game.me.learned7=link;break; - } - if(link!='无') game.me.addSkill(link); - } - control.close(); - dialog.close(); - event.finish(); - game.resume(); - }) - game.pause(); - "step 1" - while(ui.dialogs.length){ - ui.dialogs[0].close(); - } - while(ui.controls.length){ - ui.controls[0].close(); - } - } - }, - infinity_jp:{ - init:function(){ - game.me.storage.infinity_jp=true; - }, - group:['jp_damage','jp_kill','jp_use','jp_skill'], - intro:{ - content:function(intro,player){ - return '技能点数:'+player.jp+'/'+player.jpa; - } - } - }, - infinity_add:{ - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - filter:function(){ - return game.players.length<8; - }, - content:function(){ - var position,player; - var num=get.population('zhong')+1+Math.min(3,Math.floor(game.me.jpa/1000))-get.population('fan'); - if(get.population('zhong')>1) num--; - if(num>0&&Math.random()0){ for(var i=0;i0&&!this.spy){ + if(effect>0){ if(effect<1) c=0.5; else c=1; if(targets.length==1&&targets[0]==this); @@ -837,11 +839,6 @@ mode.identity={ else if(targets.length==1) this.ai.shown-=0.2; else this.ai.shown-=0.1; } - else if(this.spy){ - if(this.ai.shown>0.5) this.ai.shown=0.5; - if(targets.length==1&&targets[0]!=this) this.ai.shown-=0.2; - else this.ai.shown-=0.1; - } } if(this!=game.me) this.ai.shown*=2; if(this.ai.shown>0.95) this.ai.shown=0.95; @@ -867,7 +864,7 @@ mode.identity={ } var difficulty=0; if(to==game.me) difficulty=2-get.difficulty(); - if(get.config('ai_identity')||from==to||!lib.config.ai_guess||(to.identityShown&&!to.spy)){ + if(get.config('ai_identity')||from==to||!lib.config.ai_guess||(to.identityShown)){ return ai.get.realAttitude(from,to)+difficulty*1.5; } else{ @@ -931,8 +928,24 @@ mode.identity={ if(strategy==6) return -1; if(strategy==5) return 10; if(to.hp<=0) return 10; - if(situation>1) num=0; - else num=get.population('fan')+Math.max(0,3-game.zhu.hp); + if(get.population('fan')==1){ + var fan; + for(var i=0;i1&&to.hp>fan.hp&&to.num('he')>fan.num('he')){ + return -3; + } + } + return 0; + } + else{ + if(situation>1||get.population('fan')==0) num=0; + else num=get.population('fan')+Math.max(0,3-game.zhu.hp); + } if(strategy==2) num--; if(strategy==3) num++; return num; @@ -988,6 +1001,7 @@ mode.identity={ case 'zhong': return -7; case 'mingzhong':return -5; case 'nei': + if(get.population('fan')==1) return 0; if(get.population('zhong')+get.population('mingzhong')==0) return -7; if(game.zhu&&game.zhu.hp<=2) return -1; return Math.min(3,situation); diff --git a/mode/stone.js b/mode/stone.js index 07709656c..442a0854a 100755 --- a/mode/stone.js +++ b/mode/stone.js @@ -367,12 +367,16 @@ mode.stone={ var next=game.createEvent('game',false); next.content=function(){ "step 0" + if(lib.db&&!_status.characterLoaded){ + _status.waitingForCharacters=true; + game.pause(); + } + "step 1" lib.init.css('layout/mode/','stone'); game.initStone(); var playback=localStorage.getItem(lib.configprefix+'playback'); if(playback){ - ui.create.arena(); ui.create.me(); ui.arena.style.display='none'; ui.system.style.display='none'; @@ -395,13 +399,13 @@ mode.stone={ game.delay(); } ui.arena.classList.add('stone'); - "step 1" + "step 2" for(var i=0;idiv>div,#mebg,.control,.player,.card,.avatar,.avatar2,.button,#window>.dialog.popped, -.player.unseen .equips:not(*:empty),.menu, +.player.unseen .equips:not(*:empty),.menu,#splash>div, #arena.mobile:not(.chess) .player[data-position='0'] .equips{ box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; background-image: linear-gradient(#4b4b4b, #464646); diff --git a/theme/simple/style.css b/theme/simple/style.css index 147e895c3..5c7c10442 100755 --- a/theme/simple/style.css +++ b/theme/simple/style.css @@ -15,7 +15,7 @@ body{ display: block; } #system>div>div,#mebg,.control,.player,.card,.avatar,.avatar2,.button,#window>.dialog.popped, -.player.unseen .equips:not(*:empty),.menu,.menubutton, +.player.unseen .equips:not(*:empty),.menu,.menubutton,#splash>div, #arena.mobile:not(.chess) .player[data-position='0'] .equips{ box-shadow: rgba(0, 0, 0, 0.4) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; background-image: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)); diff --git a/theme/woodden/style.css b/theme/woodden/style.css index 4d7224a96..3d4aede48 100755 --- a/theme/woodden/style.css +++ b/theme/woodden/style.css @@ -3,7 +3,7 @@ html{ text-shadow: black 0 0 2px; background: url('grid.png'),linear-gradient(#6c7989, #434b55) fixed; } -#system>div>div,#mebg,.control,.player,.card,.avatar,.avatar2,.button,.dialog>.bar,.menu, +#system>div>div,#mebg,.control,.player,.card,.avatar,.avatar2,.button,.dialog>.bar,.menu,#splash>div, #arena.mobile:not(.chess) .player[data-position='0'] .equips{ box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; border-radius: 8px; @@ -17,6 +17,9 @@ html{ color:rgba(77, 60, 51,0.8); text-shadow:none; } +#splash>div{ + background:url('wood2.png'); +} .player.unseen .equips:not(*:empty){ background: url('wood.png');