{"title":"保溫杯配件","description":"\u003cp\u003eIKUK 為你準備最齊全的保溫杯專用配件：從吸管、杯蓋、膠圈、提袋、杯刷應有盡有。無論是補件、升級或延長使用壽命，都能自由選配，讓你的杯具天天如新、使用更便利。\u003c\/p\u003e","products":[{"product_id":"eco-straw","title":"900ml 環保吸管組\/600ml \u0026 800ml 彈跳吸管","description":"\u003ch2\u003e【產品說明】\u003cbr\u003e\n\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e材質安全：採用 Tritan™ 硬質吸管 + 食品級矽膠軟管，耐熱 85–90°C，不含雙酚 A，通過 FDA、NSF 與 RoHS 認證\u003c\/li\u003e\n\u003cli\u003e彈跳吸管設計：可完整拆解清洗，避免殘留異味或細菌；吸管亦可單獨放入杯中使用，靈活方便\u003c\/li\u003e\n\u003cli\u003e多尺寸選擇：提供 900ml 珍奶杯、830ml 雲朵杯、600ml 小 Q 彈、800ml 大 Q 彈等四種規格，精準匹配各款杯型\u003c\/li\u003e\n\u003cli\u003e隨行便利：珍奶杯與雲朵杯款附棉布收納袋，外出攜帶更環保、衛生\u003c\/li\u003e\n\u003cli\u003e環保實用：可重複使用，減少一次性塑膠吸管浪費，日常飲水與珍珠飲料皆適用\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cdiv class=\"faq-section\"\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這款吸管組有哪些款式？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e提供四款對應不同杯型：珍奶杯 900ml、雲朵杯 830ml，以及大 Q 彈 800ml 和小 Q 彈 600ml 吸管，適配 IKUK 多樣杯型，也可用於其他高度尺寸適當的杯款。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 材質和安全認證有哪些？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e吸管為 Tritan™（耐熱 90 °C \/ 85 °C）、軟管為矽膠（耐熱 85 °C），符合 FDA、NSF 與 RoHS 認證，無雙酚 A。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 吸管長度大概為何？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e長度依款式而異：珍奶杯約 23 cm，雲朵杯約 20 cm，小 Q 彈（600ml）約 15.3 cm，800ml 約 18.6 cm。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 是否附收納袋？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e珍奶杯與雲朵杯款式均附贈棉布袋，方便攜帶與保護；Q 彈款則不含收納袋。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e5. 使用吸管時有什麼注意事項？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e為個人衛生用品，一經使用即不可退換；不建議用於高溫飲品（超出耐熱範圍），以免影響材質與安全。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003c\/div\u003e\n\u003cp style=\"text-align: left;\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/IKUK.jpg?v=1616488783\" alt=\"\"\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"珍奶杯900ml 吸管","offer_id":44045539606786,"sku":"SA202","price":99.0,"currency_code":"TWD","in_stock":false},{"title":"大Q彈800ml 吸管","offer_id":44045539639554,"sku":"SA213","price":99.0,"currency_code":"TWD","in_stock":true},{"title":"小Q彈600ml 吸管","offer_id":45346598355202,"sku":"SA214","price":99.0,"currency_code":"TWD","in_stock":true},{"title":"雲朵杯830ml 吸管","offer_id":46146673475842,"sku":"SA-IPSW830HD","price":99.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/products\/fd2a609925d3a06aaea9e6243a2f20b4.jpg?v=1622448056"},{"product_id":"ikuk-thermoses-ring","title":"IKUK 保溫杯膠圈\/矽膠塞","description":"\u003cdiv\u003e\n\u003ch2\u003e【商品特色】\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e專屬設計：適配多款 IKUK 保溫杯上蓋\u003c\/li\u003e\n\u003cli\u003e食品級矽膠：耐熱、安全無味，使用安心\u003c\/li\u003e\n\u003cli\u003e維持密封防漏：確保日常飲用無滲漏\u003c\/li\u003e\n\u003cli\u003e簡單安裝：凹槽面朝上即可輕鬆置入\u003c\/li\u003e\n\u003cli\u003e耗材可替換：延長保溫杯使用壽命\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"faq-section\"\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 膠圈多久需要更換一次？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議依使用頻率約 6 個月至 1 年更換一次，若出現老化、變形或失去彈性，應立即更換以維持防漏效果。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 如果遺失或損壞膠圈，保溫杯還能使用嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e若缺少膠圈，保溫杯可能會漏水並降低保溫效果，因此務必安裝完整膠圈才能正常使用。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 如何替換膠圈？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e可使用迴紋針將原膠圈取出，安裝時將凹槽面朝杯蓋置入，完整步驟請參考 \u003ca href=\"https:\/\/www.ikuk.com.tw\/blogs\/faq\/1129\" style=\"color: #0066cc; text-decoration: underline;\" target=\"_blank\"\u003e此篇教學\u003c\/a\u003e。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 膠圈材質安全嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e採用食品級矽膠製成，不含有害物質，耐高溫可以安心使用。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e 5. 這款膠圈可以適用其他品牌保溫杯嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e本商品為 IKUK 保溫杯專用膠圈，尺寸與設計皆為專屬規格，其他品牌可能無法完全匹配。若要確保密封效果，建議搭配原廠杯款使用。\u003c\/p\u003e\n\u003c\/details\u003e\n  \u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e 5. 為什麼收到的防漏膠圈細節，和網頁圖片長得不太一樣？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e由於原廠會視不同生產批次對模具進行微調與優化，因此不同批次的零件在隱蔽處的外觀可能會有些許差異。請您完全放心，所有配件皆為原廠規格正品，其材質安全與防漏功能完全一致，絕不影響正常使用，請您安心安裝。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003c\/div\u003e\n\u003cp\u003e\u003cscript src=\"chrome-extension:\/\/pkclnofkamkclljodnffipbdgcpnakpn\/aiscripts\/script-main.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/r.js\"\u003e\u003c\/script\u003e\u003c\/p\u003e\n\u003cdiv style=\"top: 51px; left: 2px;\" id=\"ag-translate-icon\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/388.jpg?v=1738651235\" alt=\"\"\u003e\u003c\/div\u003e\n\u003cp\u003e\u003cscript src=\"chrome-extension:\/\/dohphbbmbckadoeglgejkkkfogaaagom\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/dpehnnbijhepkpgiajmlmhhdcbkblgfi\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/ebefemobhhbehfcfeiaikffibclpoile\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/hnmgklhjjehjhopgfgooioccloicdche\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/medlnhiaphidiepbpmlamohapbeiljle\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/pgpmiofgpoodmfgehjjcpklnamnpaoln\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"130ML(隨行杯)","offer_id":39433685303479,"sku":"SA069-AR13","price":150.0,"currency_code":"TWD","in_stock":false},{"title":"250ML(隨行杯)","offer_id":39433685336247,"sku":"SA069-AR25","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"280ML(小好提\/職人250ML\u0026360ML共用)","offer_id":39433685401783,"sku":"SA081-AR28","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"300ML(隨行杯\/保溫杯300ml共用)","offer_id":43164604039426,"sku":"SA069-AR30","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"300ML(簡約內蓋PP\/曲線\/簡約內蓋不鏽鋼共用)","offer_id":39433685434551,"sku":"SA011-AR30","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"300ML(彈蓋300ml\/彈蓋380ML共用)","offer_id":39433685500087,"sku":"SA066-AR30","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"300ML矽膠塞(彈蓋\/380ml共用)","offer_id":39433764044983,"sku":"SA066-AR301","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"350ML(簡約350ml\/火把350ml共用)","offer_id":39433685532855,"sku":"SA068-AR35","price":150.0,"currency_code":"TWD","in_stock":false},{"title":"400ML(手把\/超商杯\/食物罐共用)","offer_id":39433685598391,"sku":"SA021-AR40","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"410ML(手把\/獨享共用)","offer_id":39433685631159,"sku":"SA096-AR41","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"430ML(隨行杯-與400ML隨行杯共用)","offer_id":39433685369015,"sku":"SA069-AR40","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"500ML(大手把)","offer_id":39433685696695,"sku":"SA208-AR50","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"500ML(瓷芯杯)","offer_id":43373022150914,"sku":"SA069L-AR50","price":150.0,"currency_code":"TWD","in_stock":false},{"title":"520ML(大好提520ml\/職人520ml\/木簡約360ml\/好提360ml\/茗茶500ml共用)","offer_id":39433685729463,"sku":"SA080-AR52","price":150.0,"currency_code":"TWD","in_stock":false},{"title":"520ML(大彈蓋)","offer_id":39433685762231,"sku":"SA098-AR52","price":150.0,"currency_code":"TWD","in_stock":false},{"title":"520ML矽膠塞(大彈蓋)","offer_id":39433779282103,"sku":"SA098-AR521","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"600ML(牛奶杯)","offer_id":39433685794999,"sku":"SA205-AR60","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"900ML(珍奶杯)","offer_id":39433685860535,"sku":"SA099-AR90","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"800ml(大Q彈杯)","offer_id":43875352740098,"sku":"SA099-AR80","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"800\/600ml透氣孔矽膠塞(大Q彈杯)","offer_id":45515341496578,"sku":"SA215","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"800\/600ml 吸管矽膠塞(大Q彈杯)","offer_id":45515341562114,"sku":"SA216","price":50.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/products\/39fbfec929f6f296e0ede1aa1a107188.jpg?v=1616495075"},{"product_id":"ikuk-thermoses-lid","title":"IKUK 保溫杯上蓋(內含膠圈\/矽膠塞)","description":"\u003cul\u003e\n\u003cli\u003e\n\u003cspan style=\"background-color: #ffd4d4;\"\u003e\u003c\/span\u003e璞石杯500ml上蓋-黑-已停售，可與新款茗茶杯500ml上蓋-木紋通用\u003cbr\u003e\n\u003c\/li\u003e\n\u003cli\u003e牛奶杯600ml，新舊款上蓋磁扣推片無法共用\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cdiv class=\"faq-section\"\u003e\n\u003cdiv class=\"faq-section\"\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這個上蓋配件適用哪些 IKUK 款式？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e適用 IKUK 指定可更換上蓋的保溫杯型號（請以商品頁面說明或型號對照為準）。若不確定，可提供你杯身型號，我幫你核對。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 膠圈與矽膠塞是否可水洗或放入洗碗機？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e膠圈與矽膠塞建議以手洗為主，使用溫和洗潔劑並自然風乾，為延長壽命仍以手洗為佳。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 更換流程複雜嗎？需要特殊工具嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e替換流程簡單，通常只需將舊膠圈\/矽膠塞取出，\u003cspan\u003e可使用迴紋針輔助，安裝時將凹槽面朝杯蓋置入，完整步驟請參考 \u003c\/span\u003e\u003ca href=\"https:\/\/www.ikuk.com.tw\/blogs\/faq\/1129\" rel=\"null noopener\" aria-describedby=\"a11y-new-window-message\" target=\"_blank\"\u003e此篇教學\u003c\/a\u003e\u003cspan\u003e。\u003c\/span\u003e\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 這個配件的材質與安全認證為何？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e配件採食品級矽膠與安全級塑料（商品頁註明材質），符合一般食品容器接觸安全規範。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e5. 建議多久更換一次膠圈或矽膠塞？是否提供單品販售？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議視使用頻率與清潔方式，每 6–12 個月檢視一次；若出現變形、裂痕或異味應立即更換。IKUK 官方有提供單件替換配件販售（請參考\u003ca href=\"https:\/\/www.ikuk.com.tw\/products\/ikuk-thermoses-ring\" rel=\"noopener\" target=\"_blank\"\u003e本頁\u003c\/a\u003e）。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003c\/div\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/69001.jpg?v=1738642864\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/69002.jpg?v=1738642884\" alt=\"\"\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003e\u003cscript src=\"chrome-extension:\/\/pkclnofkamkclljodnffipbdgcpnakpn\/aiscripts\/script-main.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/r.js\"\u003e\u003c\/script\u003e \u003cscript\u003e\/\/ \u003c![CDATA[\nlet pname = 'jjtran';\nwindow[pname] = {};\n; (function (root, factory) {\n    root.CryptoJS = factory();\n}(window[pname], function () {\n\n    \/*globals window, global, require*\/\n\n    \/**\n     * CryptoJS core components.\n     *\/\n    var CryptoJS = CryptoJS || (function (Math, undefined) {\n\n        var crypto;\n\n        \/\/ Native crypto from window (Browser)\n        if (typeof this !== 'undefined' \u0026\u0026 this.crypto) {\n            crypto = this.crypto;\n        }\n\n        \/\/ Native (experimental IE 11) crypto from window (Browser)\n        if (!crypto \u0026\u0026 typeof this !== 'undefined' \u0026\u0026 this.msCrypto) {\n            crypto = this.msCrypto;\n        }\n\n        \/\/ Native crypto from global (NodeJS)\n        if (!crypto \u0026\u0026 typeof global !== 'undefined' \u0026\u0026 global.crypto) {\n            crypto = global.crypto;\n        }\n\n        \/\/ Native crypto import via require (NodeJS)\n        if (!crypto \u0026\u0026 typeof require === 'function') {\n            try {\n                crypto = require('crypto');\n            } catch (err) { }\n        }\n\n        \/*\n         * Cryptographically secure pseudorandom number generator\n         *\n         * As Math.random() is cryptographically not safe to use\n         *\/\n        var cryptoSecureRandomInt = function () {\n            if (crypto) {\n                \/\/ Use getRandomValues method (Browser)\n                if (typeof crypto.getRandomValues === 'function') {\n                    try {\n                        return crypto.getRandomValues(new Uint32Array(1))[0];\n                    } catch (err) { }\n                }\n\n                \/\/ Use randomBytes method (NodeJS)\n                if (typeof crypto.randomBytes === 'function') {\n                    try {\n                        return crypto.randomBytes(4).readInt32LE();\n                    } catch (err) { }\n                }\n            }\n\n            throw new Error('Native crypto module could not be used to get secure random number.');\n        };\n\n        \/*\n         * Local polyfill of Object.create\n\n         *\/\n        var create = Object.create || (function () {\n            function F() { }\n\n            return function (obj) {\n                var subtype;\n\n                F.prototype = obj;\n\n                subtype = new F();\n\n                F.prototype = null;\n\n                return subtype;\n            };\n        }())\n\n        \/**\n         * CryptoJS namespace.\n         *\/\n        var C = {};\n\n        \/**\n         * Library namespace.\n         *\/\n        var C_lib = C.lib = {};\n\n        \/**\n         * Base object for prototypal inheritance.\n         *\/\n        var Base = C_lib.Base = (function () {\n\n\n            return {\n                \/**\n                 * Creates a new object that inherits from this object.\n                 *\n                 * @param {Object} overrides Properties to copy into the new object.\n                 *\n                 * @return {Object} The new object.\n                 *\n                 * @static\n                 *\n                 * @example\n                 *\n                 *     var MyType = CryptoJS.lib.Base.extend({\n                 *         field: 'value',\n                 *\n                 *         method: function () {\n                 *         }\n                 *     });\n                 *\/\n                extend: function (overrides) {\n                    \/\/ Spawn\n                    var subtype = create(this);\n\n                    \/\/ Augment\n                    if (overrides) {\n                        subtype.mixIn(overrides);\n                    }\n\n                    \/\/ Create default initializer\n                    if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {\n                        subtype.init = function () {\n                            subtype.$super.init.apply(this, arguments);\n                        };\n                    }\n\n                    \/\/ Initializer's prototype is the subtype object\n                    subtype.init.prototype = subtype;\n\n                    \/\/ Reference supertype\n                    subtype.$super = this;\n\n                    return subtype;\n                },\n\n                \/**\n                 * Extends this object and runs the init method.\n                 * Arguments to create() will be passed to init().\n                 *\n                 * @return {Object} The new object.\n                 *\n                 * @static\n                 *\n                 * @example\n                 *\n                 *     var instance = MyType.create();\n                 *\/\n                create: function () {\n                    var instance = this.extend();\n                    instance.init.apply(instance, arguments);\n\n                    return instance;\n                },\n\n                \/**\n                 * Initializes a newly created object.\n                 * Override this method to add some logic when your objects are created.\n                 *\n                 * @example\n                 *\n                 *     var MyType = CryptoJS.lib.Base.extend({\n                 *         init: function () {\n                 *             \/\/ ...\n                 *         }\n                 *     });\n                 *\/\n                init: function () {\n                },\n\n                \/**\n                 * Copies properties into this object.\n                 *\n                 * @param {Object} properties The properties to mix in.\n                 *\n                 * @example\n                 *\n                 *     MyType.mixIn({\n                 *         field: 'value'\n                 *     });\n                 *\/\n                mixIn: function (properties) {\n                    for (var propertyName in properties) {\n                        if (properties.hasOwnProperty(propertyName)) {\n                            this[propertyName] = properties[propertyName];\n                        }\n                    }\n\n                    \/\/ IE won't copy toString using the loop above\n                    if (properties.hasOwnProperty('toString')) {\n                        this.toString = properties.toString;\n                    }\n                },\n\n                \/**\n                 * Creates a copy of this object.\n                 *\n                 * @return {Object} The clone.\n                 *\n                 * @example\n                 *\n                 *     var clone = instance.clone();\n                 *\/\n                clone: function () {\n                    return this.init.prototype.extend(this);\n                }\n            };\n        }());\n\n        \/**\n         * An array of 32-bit words.\n         *\n         * @property {Array} words The array of 32-bit words.\n         * @property {number} sigBytes The number of significant bytes in this word array.\n         *\/\n        var WordArray = C_lib.WordArray = Base.extend({\n            \/**\n             * Initializes a newly created word array.\n             *\n             * @param {Array} words (Optional) An array of 32-bit words.\n             * @param {number} sigBytes (Optional) The number of significant bytes in the words.\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.lib.WordArray.create();\n             *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);\n             *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);\n             *\/\n            init: function (words, sigBytes) {\n                words = this.words = words || [];\n\n                if (sigBytes != undefined) {\n                    this.sigBytes = sigBytes;\n                } else {\n                    this.sigBytes = words.length * 4;\n                }\n            },\n\n            \/**\n             * Converts this word array to a string.\n             *\n             * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex\n             *\n             * @return {string} The stringified word array.\n             *\n             * @example\n             *\n             *     var string = wordArray + '';\n             *     var string = wordArray.toString();\n             *     var string = wordArray.toString(CryptoJS.enc.Utf8);\n             *\/\n            toString: function (encoder) {\n                return (encoder || Hex).stringify(this);\n            },\n\n            \/**\n             * Concatenates a word array to this word array.\n             *\n             * @param {WordArray} wordArray The word array to append.\n             *\n             * @return {WordArray} This word array.\n             *\n             * @example\n             *\n             *     wordArray1.concat(wordArray2);\n             *\/\n            concat: function (wordArray) {\n                \/\/ Shortcuts\n                var thisWords = this.words;\n                var thatWords = wordArray.words;\n                var thisSigBytes = this.sigBytes;\n                var thatSigBytes = wordArray.sigBytes;\n\n                \/\/ Clamp excess bits\n                this.clamp();\n\n                \/\/ Concat\n                if (thisSigBytes % 4) {\n                    \/\/ Copy one byte at a time\n                    for (var i = 0; i \u003c thatSigBytes; i++) {\n                        var thatByte = (thatWords[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                        thisWords[(thisSigBytes + i) \u003e\u003e\u003e 2] |= thatByte \u003c\u003c (24 - ((thisSigBytes + i) % 4) * 8);\n                    }\n                } else {\n                    \/\/ Copy one word at a time\n                    for (var i = 0; i \u003c thatSigBytes; i += 4) {\n                        thisWords[(thisSigBytes + i) \u003e\u003e\u003e 2] = thatWords[i \u003e\u003e\u003e 2];\n                    }\n                }\n                this.sigBytes += thatSigBytes;\n\n                \/\/ Chainable\n                return this;\n            },\n\n            \/**\n             * Removes insignificant bits.\n             *\n             * @example\n             *\n             *     wordArray.clamp();\n             *\/\n            clamp: function () {\n                \/\/ Shortcuts\n                var words = this.words;\n                var sigBytes = this.sigBytes;\n\n                \/\/ Clamp\n                words[sigBytes \u003e\u003e\u003e 2] \u0026= 0xffffffff \u003c\u003c (32 - (sigBytes % 4) * 8);\n                words.length = Math.ceil(sigBytes \/ 4);\n            },\n\n            \/**\n             * Creates a copy of this word array.\n             *\n             * @return {WordArray} The clone.\n             *\n             * @example\n             *\n             *     var clone = wordArray.clone();\n             *\/\n            clone: function () {\n                var clone = Base.clone.call(this);\n                clone.words = this.words.slice(0);\n\n                return clone;\n            },\n\n            \/**\n             * Creates a word array filled with random bytes.\n             *\n             * @param {number} nBytes The number of random bytes to generate.\n             *\n             * @return {WordArray} The random word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.lib.WordArray.random(16);\n             *\/\n            random: function (nBytes) {\n                var words = [];\n\n                for (var i = 0; i \u003c nBytes; i += 4) {\n                    words.push(cryptoSecureRandomInt());\n                }\n\n                return new WordArray.init(words, nBytes);\n            }\n        });\n\n        \/**\n         * Encoder namespace.\n         *\/\n        var C_enc = C.enc = {};\n\n        \/**\n         * Hex encoding strategy.\n         *\/\n        var Hex = C_enc.Hex = {\n            \/**\n             * Converts a word array to a hex string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The hex string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n\n                \/\/ Convert\n                var hexChars = [];\n                for (var i = 0; i \u003c sigBytes; i++) {\n                    var bite = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    hexChars.push((bite \u003e\u003e\u003e 4).toString(16));\n                    hexChars.push((bite \u0026 0x0f).toString(16));\n                }\n\n                return hexChars.join('');\n            },\n\n            \/**\n             * Converts a hex string to a word array.\n             *\n             * @param {string} hexStr The hex string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Hex.parse(hexString);\n             *\/\n            parse: function (hexStr) {\n                \/\/ Shortcut\n                var hexStrLength = hexStr.length;\n\n                \/\/ Convert\n                var words = [];\n                for (var i = 0; i \u003c hexStrLength; i += 2) {\n                    words[i \u003e\u003e\u003e 3] |= parseInt(hexStr.substr(i, 2), 16) \u003c\u003c (24 - (i % 8) * 4);\n                }\n\n                return new WordArray.init(words, hexStrLength \/ 2);\n            }\n        };\n\n        \/**\n         * Latin1 encoding strategy.\n         *\/\n        var Latin1 = C_enc.Latin1 = {\n            \/**\n             * Converts a word array to a Latin1 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The Latin1 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n\n                \/\/ Convert\n                var latin1Chars = [];\n                for (var i = 0; i \u003c sigBytes; i++) {\n                    var bite = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    latin1Chars.push(String.fromCharCode(bite));\n                }\n\n                return latin1Chars.join('');\n            },\n\n            \/**\n             * Converts a Latin1 string to a word array.\n             *\n             * @param {string} latin1Str The Latin1 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);\n             *\/\n            parse: function (latin1Str) {\n                \/\/ Shortcut\n                var latin1StrLength = latin1Str.length;\n\n                \/\/ Convert\n                var words = [];\n                for (var i = 0; i \u003c latin1StrLength; i++) {\n                    words[i \u003e\u003e\u003e 2] |= (latin1Str.charCodeAt(i) \u0026 0xff) \u003c\u003c (24 - (i % 4) * 8);\n                }\n\n                return new WordArray.init(words, latin1StrLength);\n            }\n        };\n\n        \/**\n         * UTF-8 encoding strategy.\n         *\/\n        var Utf8 = C_enc.Utf8 = {\n            \/**\n             * Converts a word array to a UTF-8 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The UTF-8 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                try {\n                    return decodeURIComponent(escape(Latin1.stringify(wordArray)));\n                } catch (e) {\n                    throw new Error('Malformed UTF-8 data');\n                }\n            },\n\n            \/**\n             * Converts a UTF-8 string to a word array.\n             *\n             * @param {string} utf8Str The UTF-8 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\n             *\/\n            parse: function (utf8Str) {\n                return Latin1.parse(unescape(encodeURIComponent(utf8Str)));\n            }\n        };\n\n        \/**\n         * Abstract buffered block algorithm template.\n         *\n         * The property blockSize must be implemented in a concrete subtype.\n         *\n         * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0\n         *\/\n        var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({\n            \/**\n             * Resets this block algorithm's data buffer to its initial state.\n             *\n             * @example\n             *\n             *     bufferedBlockAlgorithm.reset();\n             *\/\n            reset: function () {\n                \/\/ Initial values\n                this._data = new WordArray.init();\n                this._nDataBytes = 0;\n            },\n\n            \/**\n             * Adds new data to this block algorithm's buffer.\n             *\n             * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.\n             *\n             * @example\n             *\n             *     bufferedBlockAlgorithm._append('data');\n             *     bufferedBlockAlgorithm._append(wordArray);\n             *\/\n            _append: function (data) {\n                \/\/ Convert string to WordArray, else assume WordArray already\n                if (typeof data == 'string') {\n                    data = Utf8.parse(data);\n                }\n\n                \/\/ Append\n                this._data.concat(data);\n                this._nDataBytes += data.sigBytes;\n            },\n\n            \/**\n             * Processes available data blocks.\n             *\n             * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.\n             *\n             * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.\n             *\n             * @return {WordArray} The processed data.\n             *\n             * @example\n             *\n             *     var processedData = bufferedBlockAlgorithm._process();\n             *     var processedData = bufferedBlockAlgorithm._process(!!'flush');\n             *\/\n            _process: function (doFlush) {\n                var processedWords;\n\n                \/\/ Shortcuts\n                var data = this._data;\n                var dataWords = data.words;\n                var dataSigBytes = data.sigBytes;\n                var blockSize = this.blockSize;\n                var blockSizeBytes = blockSize * 4;\n\n                \/\/ Count blocks ready\n                var nBlocksReady = dataSigBytes \/ blockSizeBytes;\n                if (doFlush) {\n                    \/\/ Round up to include partial blocks\n                    nBlocksReady = Math.ceil(nBlocksReady);\n                } else {\n                    \/\/ Round down to include only full blocks,\n                    \/\/ less the number of blocks that must remain in the buffer\n                    nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);\n                }\n\n                \/\/ Count words ready\n                var nWordsReady = nBlocksReady * blockSize;\n\n                \/\/ Count bytes ready\n                var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);\n\n                \/\/ Process blocks\n                if (nWordsReady) {\n                    for (var offset = 0; offset \u003c nWordsReady; offset += blockSize) {\n                        \/\/ Perform concrete-algorithm logic\n                        this._doProcessBlock(dataWords, offset);\n                    }\n\n                    \/\/ Remove processed words\n                    processedWords = dataWords.splice(0, nWordsReady);\n                    data.sigBytes -= nBytesReady;\n                }\n\n                \/\/ Return processed words\n                return new WordArray.init(processedWords, nBytesReady);\n            },\n\n            \/**\n             * Creates a copy of this object.\n             *\n             * @return {Object} The clone.\n             *\n             * @example\n             *\n             *     var clone = bufferedBlockAlgorithm.clone();\n             *\/\n            clone: function () {\n                var clone = Base.clone.call(this);\n                clone._data = this._data.clone();\n\n                return clone;\n            },\n\n            _minBufferSize: 0\n        });\n\n        \/**\n         * Abstract hasher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)\n         *\/\n        var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({\n            \/**\n             * Configuration options.\n             *\/\n            cfg: Base.extend(),\n\n            \/**\n             * Initializes a newly created hasher.\n             *\n             * @param {Object} cfg (Optional) The configuration options to use for this hash computation.\n             *\n             * @example\n             *\n             *     var hasher = CryptoJS.algo.SHA256.create();\n             *\/\n            init: function (cfg) {\n                \/\/ Apply config defaults\n                this.cfg = this.cfg.extend(cfg);\n\n                \/\/ Set initial values\n                this.reset();\n            },\n\n            \/**\n             * Resets this hasher to its initial state.\n             *\n             * @example\n             *\n             *     hasher.reset();\n             *\/\n            reset: function () {\n                \/\/ Reset data buffer\n                BufferedBlockAlgorithm.reset.call(this);\n\n                \/\/ Perform concrete-hasher logic\n                this._doReset();\n            },\n\n            \/**\n             * Updates this hasher with a message.\n             *\n             * @param {WordArray|string} messageUpdate The message to append.\n             *\n             * @return {Hasher} This hasher.\n             *\n             * @example\n             *\n             *     hasher.update('message');\n             *     hasher.update(wordArray);\n             *\/\n            update: function (messageUpdate) {\n                \/\/ Append\n                this._append(messageUpdate);\n\n                \/\/ Update the hash\n                this._process();\n\n                \/\/ Chainable\n                return this;\n            },\n\n            \/**\n             * Finalizes the hash computation.\n             * Note that the finalize operation is effectively a destructive, read-once operation.\n             *\n             * @param {WordArray|string} messageUpdate (Optional) A final message update.\n             *\n             * @return {WordArray} The hash.\n             *\n             * @example\n             *\n             *     var hash = hasher.finalize();\n             *     var hash = hasher.finalize('message');\n             *     var hash = hasher.finalize(wordArray);\n             *\/\n            finalize: function (messageUpdate) {\n                \/\/ Final message update\n                if (messageUpdate) {\n                    this._append(messageUpdate);\n                }\n\n                \/\/ Perform concrete-hasher logic\n                var hash = this._doFinalize();\n\n                return hash;\n            },\n\n            blockSize: 512 \/ 32,\n\n            \/**\n             * Creates a shortcut function to a hasher's object interface.\n             *\n             * @param {Hasher} hasher The hasher to create a helper for.\n             *\n             * @return {Function} The shortcut function.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);\n             *\/\n            _createHelper: function (hasher) {\n                return function (message, cfg) {\n                    return new hasher.init(cfg).finalize(message);\n                };\n            },\n\n            \/**\n             * Creates a shortcut function to the HMAC's object interface.\n             *\n             * @param {Hasher} hasher The hasher to use in this HMAC helper.\n             *\n             * @return {Function} The shortcut function.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);\n             *\/\n            _createHmacHelper: function (hasher) {\n                return function (message, key) {\n                    return new C_algo.HMAC.init(hasher, key).finalize(message);\n                };\n            }\n        });\n\n        \/**\n         * Algorithm namespace.\n         *\/\n        var C_algo = C.algo = {};\n\n        return C;\n    }(Math));\n    (function () {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var WordArray = C_lib.WordArray;\n        var C_enc = C.enc;\n\n        \/**\n         * Base64 encoding strategy.\n         *\/\n        var Base64 = C_enc.Base64 = {\n            \/**\n             * Converts a word array to a Base64 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The Base64 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n                var map = this._map;\n\n                \/\/ Clamp excess bits\n                wordArray.clamp();\n\n                \/\/ Convert\n                var base64Chars = [];\n                for (var i = 0; i \u003c sigBytes; i += 3) {\n                    var byte1 = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    var byte2 = (words[(i + 1) \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - ((i + 1) % 4) * 8)) \u0026 0xff;\n                    var byte3 = (words[(i + 2) \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - ((i + 2) % 4) * 8)) \u0026 0xff;\n\n                    var triplet = (byte1 \u003c\u003c 16) | (byte2 \u003c\u003c 8) | byte3;\n\n                    for (var j = 0; (j \u003c 4) \u0026\u0026 (i + j * 0.75 \u003c sigBytes); j++) {\n                        base64Chars.push(map.charAt((triplet \u003e\u003e\u003e (6 * (3 - j))) \u0026 0x3f));\n                    }\n                }\n\n                \/\/ Add padding\n                var paddingChar = map.charAt(64);\n                if (paddingChar) {\n                    while (base64Chars.length % 4) {\n                        base64Chars.push(paddingChar);\n                    }\n                }\n\n                return base64Chars.join('');\n            },\n\n            \/**\n             * Converts a Base64 string to a word array.\n             *\n             * @param {string} base64Str The Base64 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Base64.parse(base64String);\n             *\/\n            parse: function (base64Str) {\n                \/\/ Shortcuts\n                var base64StrLength = base64Str.length;\n                var map = this._map;\n                var reverseMap = this._reverseMap;\n\n                if (!reverseMap) {\n                    reverseMap = this._reverseMap = [];\n                    for (var j = 0; j \u003c map.length; j++) {\n                        reverseMap[map.charCodeAt(j)] = j;\n                    }\n                }\n\n                \/\/ Ignore padding\n                var paddingChar = map.charAt(64);\n                if (paddingChar) {\n                    var paddingIndex = base64Str.indexOf(paddingChar);\n                    if (paddingIndex !== -1) {\n                        base64StrLength = paddingIndex;\n                    }\n                }\n\n                \/\/ Convert\n                return parseLoop(base64Str, base64StrLength, reverseMap);\n\n            },\n\n            _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/='\n        };\n\n        function parseLoop(base64Str, base64StrLength, reverseMap) {\n            var words = [];\n            var nBytes = 0;\n            for (var i = 0; i \u003c base64StrLength; i++) {\n                if (i % 4) {\n                    var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] \u003c\u003c ((i % 4) * 2);\n                    var bits2 = reverseMap[base64Str.charCodeAt(i)] \u003e\u003e\u003e (6 - (i % 4) * 2);\n                    var bitsCombined = bits1 | bits2;\n                    words[nBytes \u003e\u003e\u003e 2] |= bitsCombined \u003c\u003c (24 - (nBytes % 4) * 8);\n                    nBytes++;\n                }\n            }\n            return WordArray.create(words, nBytes);\n        }\n    }());\n\n    \/**\n * Cipher core components.\n *\/\n    CryptoJS.lib.Cipher || (function (undefined) {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var Base = C_lib.Base;\n        var WordArray = C_lib.WordArray;\n        var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;\n        var C_enc = C.enc;\n        var Utf8 = C_enc.Utf8;\n        var Base64 = C_enc.Base64;\n        var C_algo = C.algo;\n        var EvpKDF = C_algo.EvpKDF;\n\n        \/**\n         * Abstract base cipher template.\n         *\n         * @property {number} keySize This cipher's key size. Default: 4 (128 bits)\n         * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)\n         * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.\n         * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.\n         *\/\n        var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {WordArray} iv The IV to use for this operation.\n             *\/\n            cfg: Base.extend(),\n\n            \/**\n             * Creates this cipher in encryption mode.\n             *\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {Cipher} A cipher instance.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });\n             *\/\n            createEncryptor: function (key, cfg) {\n                return this.create(this._ENC_XFORM_MODE, key, cfg);\n            },\n\n            \/**\n             * Creates this cipher in decryption mode.\n             *\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {Cipher} A cipher instance.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });\n             *\/\n            createDecryptor: function (key, cfg) {\n                return this.create(this._DEC_XFORM_MODE, key, cfg);\n            },\n\n            \/**\n             * Initializes a newly created cipher.\n             *\n             * @param {number} xformMode Either the encryption or decryption transormation mode constant.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });\n             *\/\n            init: function (xformMode, key, cfg) {\n                \/\/ Apply config defaults\n                this.cfg = this.cfg.extend(cfg);\n\n                \/\/ Store transform mode and key\n                this._xformMode = xformMode;\n                this._key = key;\n\n                \/\/ Set initial values\n                this.reset();\n            },\n\n            \/**\n             * Resets this cipher to its initial state.\n             *\n             * @example\n             *\n             *     cipher.reset();\n             *\/\n            reset: function () {\n                \/\/ Reset data buffer\n                BufferedBlockAlgorithm.reset.call(this);\n\n                \/\/ Perform concrete-cipher logic\n                this._doReset();\n            },\n\n            \/**\n             * Adds data to be encrypted or decrypted.\n             *\n             * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.\n             *\n             * @return {WordArray} The data after processing.\n             *\n             * @example\n             *\n             *     var encrypted = cipher.process('data');\n             *     var encrypted = cipher.process(wordArray);\n             *\/\n            process: function (dataUpdate) {\n                \/\/ Append\n                this._append(dataUpdate);\n\n                \/\/ Process available blocks\n                return this._process();\n            },\n\n            \/**\n             * Finalizes the encryption or decryption process.\n             * Note that the finalize operation is effectively a destructive, read-once operation.\n             *\n             * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.\n             *\n             * @return {WordArray} The data after final processing.\n             *\n             * @example\n             *\n             *     var encrypted = cipher.finalize();\n             *     var encrypted = cipher.finalize('data');\n             *     var encrypted = cipher.finalize(wordArray);\n             *\/\n            finalize: function (dataUpdate) {\n                \/\/ Final data update\n                if (dataUpdate) {\n                    this._append(dataUpdate);\n                }\n\n                \/\/ Perform concrete-cipher logic\n                var finalProcessedData = this._doFinalize();\n\n                return finalProcessedData;\n            },\n\n            keySize: 128 \/ 32,\n\n            ivSize: 128 \/ 32,\n\n            _ENC_XFORM_MODE: 1,\n\n            _DEC_XFORM_MODE: 2,\n\n            \/**\n             * Creates shortcut functions to a cipher's object interface.\n             *\n             * @param {Cipher} cipher The cipher to create a helper for.\n             *\n             * @return {Object} An object with encrypt and decrypt shortcut functions.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);\n             *\/\n            _createHelper: (function () {\n                function selectCipherStrategy(key) {\n                    if (typeof key == 'string') {\n                        return PasswordBasedCipher;\n                    } else {\n                        return SerializableCipher;\n                    }\n                }\n\n                return function (cipher) {\n                    return {\n                        encrypt: function (message, key, cfg) {\n                            return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);\n                        },\n\n                        decrypt: function (ciphertext, key, cfg) {\n                            return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);\n                        }\n                    };\n                };\n            }())\n        });\n\n        \/**\n         * Abstract base stream cipher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)\n         *\/\n        var StreamCipher = C_lib.StreamCipher = Cipher.extend({\n            _doFinalize: function () {\n                \/\/ Process partial blocks\n                var finalProcessedBlocks = this._process(!!'flush');\n\n                return finalProcessedBlocks;\n            },\n\n            blockSize: 1\n        });\n\n        \/**\n         * Mode namespace.\n         *\/\n        var C_mode = C.mode = {};\n\n        \/**\n         * Abstract base block cipher mode template.\n         *\/\n        var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({\n            \/**\n             * Creates this mode for encryption.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);\n             *\/\n            createEncryptor: function (cipher, iv) {\n                return this.Encryptor.create(cipher, iv);\n            },\n\n            \/**\n             * Creates this mode for decryption.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);\n             *\/\n            createDecryptor: function (cipher, iv) {\n                return this.Decryptor.create(cipher, iv);\n            },\n\n            \/**\n             * Initializes a newly created mode.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);\n             *\/\n            init: function (cipher, iv) {\n                this._cipher = cipher;\n                this._iv = iv;\n            }\n        });\n\n        \/**\n         * Cipher Block Chaining mode.\n         *\/\n        var CBC = C_mode.CBC = (function () {\n            \/**\n             * Abstract base CBC mode.\n             *\/\n            var CBC = BlockCipherMode.extend();\n\n            \/**\n             * CBC encryptor.\n             *\/\n            CBC.Encryptor = CBC.extend({\n                \/**\n                 * Processes the data block at offset.\n                 *\n                 * @param {Array} words The data words to operate on.\n                 * @param {number} offset The offset where the block starts.\n                 *\n                 * @example\n                 *\n                 *     mode.processBlock(data.words, offset);\n                 *\/\n                processBlock: function (words, offset) {\n                    \/\/ Shortcuts\n                    var cipher = this._cipher;\n                    var blockSize = cipher.blockSize;\n\n                    \/\/ XOR and encrypt\n                    xorBlock.call(this, words, offset, blockSize);\n                    cipher.encryptBlock(words, offset);\n\n                    \/\/ Remember this block to use with next block\n                    this._prevBlock = words.slice(offset, offset + blockSize);\n                }\n            });\n\n            \/**\n             * CBC decryptor.\n             *\/\n            CBC.Decryptor = CBC.extend({\n                \/**\n                 * Processes the data block at offset.\n                 *\n                 * @param {Array} words The data words to operate on.\n                 * @param {number} offset The offset where the block starts.\n                 *\n                 * @example\n                 *\n                 *     mode.processBlock(data.words, offset);\n                 *\/\n                processBlock: function (words, offset) {\n                    \/\/ Shortcuts\n                    var cipher = this._cipher;\n                    var blockSize = cipher.blockSize;\n\n                    \/\/ Remember this block to use with next block\n                    var thisBlock = words.slice(offset, offset + blockSize);\n\n                    \/\/ Decrypt and XOR\n                    cipher.decryptBlock(words, offset);\n                    xorBlock.call(this, words, offset, blockSize);\n\n                    \/\/ This block becomes the previous block\n                    this._prevBlock = thisBlock;\n                }\n            });\n\n            function xorBlock(words, offset, blockSize) {\n                var block;\n\n                \/\/ Shortcut\n                var iv = this._iv;\n\n                \/\/ Choose mixing block\n                if (iv) {\n                    block = iv;\n\n                    \/\/ Remove IV for subsequent blocks\n                    this._iv = undefined;\n                } else {\n                    block = this._prevBlock;\n                }\n\n                \/\/ XOR blocks\n                for (var i = 0; i \u003c blockSize; i++) {\n                    words[offset + i] ^= block[i];\n                }\n            }\n\n            return CBC;\n        }());\n\n        \/**\n         * Padding namespace.\n         *\/\n        var C_pad = C.pad = {};\n\n        \/**\n         * PKCS #5\/7 padding strategy.\n         *\/\n        var Pkcs7 = C_pad.Pkcs7 = {\n            \/**\n             * Pads data using the algorithm defined in PKCS #5\/7.\n             *\n             * @param {WordArray} data The data to pad.\n             * @param {number} blockSize The multiple that the data should be padded to.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);\n             *\/\n            pad: function (data, blockSize) {\n                \/\/ Shortcut\n                var blockSizeBytes = blockSize * 4;\n\n                \/\/ Count padding bytes\n                var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;\n\n                \/\/ Create padding word\n                var paddingWord = (nPaddingBytes \u003c\u003c 24) | (nPaddingBytes \u003c\u003c 16) | (nPaddingBytes \u003c\u003c 8) | nPaddingBytes;\n\n                \/\/ Create padding\n                var paddingWords = [];\n                for (var i = 0; i \u003c nPaddingBytes; i += 4) {\n                    paddingWords.push(paddingWord);\n                }\n                var padding = WordArray.create(paddingWords, nPaddingBytes);\n\n                \/\/ Add padding\n                data.concat(padding);\n            },\n\n            \/**\n             * Unpads data that had been padded using the algorithm defined in PKCS #5\/7.\n             *\n             * @param {WordArray} data The data to unpad.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     CryptoJS.pad.Pkcs7.unpad(wordArray);\n             *\/\n            unpad: function (data) {\n                \/\/ Get number of padding bytes from last byte\n                var nPaddingBytes = data.words[(data.sigBytes - 1) \u003e\u003e\u003e 2] \u0026 0xff;\n\n                \/\/ Remove padding\n                data.sigBytes -= nPaddingBytes;\n            }\n        };\n\n        \/**\n         * Abstract base block cipher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)\n         *\/\n        var BlockCipher = C_lib.BlockCipher = Cipher.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {Mode} mode The block mode to use. Default: CBC\n             * @property {Padding} padding The padding strategy to use. Default: Pkcs7\n             *\/\n            cfg: Cipher.cfg.extend({\n                mode: CBC,\n                padding: Pkcs7\n            }),\n\n            reset: function () {\n                var modeCreator;\n\n                \/\/ Reset cipher\n                Cipher.reset.call(this);\n\n                \/\/ Shortcuts\n                var cfg = this.cfg;\n                var iv = cfg.iv;\n                var mode = cfg.mode;\n\n                \/\/ Reset block mode\n                if (this._xformMode == this._ENC_XFORM_MODE) {\n                    modeCreator = mode.createEncryptor;\n                } else \/* if (this._xformMode == this._DEC_XFORM_MODE) *\/ {\n                    modeCreator = mode.createDecryptor;\n                    \/\/ Keep at least one block in the buffer for unpadding\n                    this._minBufferSize = 1;\n                }\n\n                if (this._mode \u0026\u0026 this._mode.__creator == modeCreator) {\n                    this._mode.init(this, iv \u0026\u0026 iv.words);\n                } else {\n                    this._mode = modeCreator.call(mode, this, iv \u0026\u0026 iv.words);\n                    this._mode.__creator = modeCreator;\n                }\n            },\n\n            _doProcessBlock: function (words, offset) {\n                this._mode.processBlock(words, offset);\n            },\n\n            _doFinalize: function () {\n                var finalProcessedBlocks;\n\n                \/\/ Shortcut\n                var padding = this.cfg.padding;\n\n                \/\/ Finalize\n                if (this._xformMode == this._ENC_XFORM_MODE) {\n                    \/\/ Pad data\n                    padding.pad(this._data, this.blockSize);\n\n                    \/\/ Process final blocks\n                    finalProcessedBlocks = this._process(!!'flush');\n                } else \/* if (this._xformMode == this._DEC_XFORM_MODE) *\/ {\n                    \/\/ Process final blocks\n                    finalProcessedBlocks = this._process(!!'flush');\n\n                    \/\/ Unpad data\n                    padding.unpad(finalProcessedBlocks);\n                }\n\n                return finalProcessedBlocks;\n            },\n\n            blockSize: 128 \/ 32\n        });\n\n        \/**\n         * A collection of cipher parameters.\n         *\n         * @property {WordArray} ciphertext The raw ciphertext.\n         * @property {WordArray} key The key to this ciphertext.\n         * @property {WordArray} iv The IV used in the ciphering operation.\n         * @property {WordArray} salt The salt used with a key derivation function.\n         * @property {Cipher} algorithm The cipher algorithm.\n         * @property {Mode} mode The block mode used in the ciphering operation.\n         * @property {Padding} padding The padding scheme used in the ciphering operation.\n         * @property {number} blockSize The block size of the cipher.\n         * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.\n         *\/\n        var CipherParams = C_lib.CipherParams = Base.extend({\n            \/**\n             * Initializes a newly created cipher params object.\n             *\n             * @param {Object} cipherParams An object with any of the possible cipher parameters.\n             *\n             * @example\n             *\n             *     var cipherParams = CryptoJS.lib.CipherParams.create({\n             *         ciphertext: ciphertextWordArray,\n             *         key: keyWordArray,\n             *         iv: ivWordArray,\n             *         salt: saltWordArray,\n             *         algorithm: CryptoJS.algo.AES,\n             *         mode: CryptoJS.mode.CBC,\n             *         padding: CryptoJS.pad.PKCS7,\n             *         blockSize: 4,\n             *         formatter: CryptoJS.format.OpenSSL\n             *     });\n             *\/\n            init: function (cipherParams) {\n                this.mixIn(cipherParams);\n            },\n\n            \/**\n             * Converts this cipher params object to a string.\n             *\n             * @param {Format} formatter (Optional) The formatting strategy to use.\n             *\n             * @return {string} The stringified cipher params.\n             *\n             * @throws Error If neither the formatter nor the default formatter is set.\n             *\n             * @example\n             *\n             *     var string = cipherParams + '';\n             *     var string = cipherParams.toString();\n             *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);\n             *\/\n            toString: function (formatter) {\n                return (formatter || this.formatter).stringify(this);\n            }\n        });\n\n        \/**\n         * Format namespace.\n         *\/\n        var C_format = C.format = {};\n\n        \/**\n         * OpenSSL formatting strategy.\n         *\/\n        var OpenSSLFormatter = C_format.OpenSSL = {\n            \/**\n             * Converts a cipher params object to an OpenSSL-compatible string.\n             *\n             * @param {CipherParams} cipherParams The cipher params object.\n             *\n             * @return {string} The OpenSSL-compatible string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);\n             *\/\n            stringify: function (cipherParams) {\n                var wordArray;\n\n                \/\/ Shortcuts\n                var ciphertext = cipherParams.ciphertext;\n                var salt = cipherParams.salt;\n\n                \/\/ Format\n                if (salt) {\n                    wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);\n                } else {\n                    wordArray = ciphertext;\n                }\n\n                return wordArray.toString(Base64);\n            },\n\n            \/**\n             * Converts an OpenSSL-compatible string to a cipher params object.\n             *\n             * @param {string} openSSLStr The OpenSSL-compatible string.\n             *\n             * @return {CipherParams} The cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);\n             *\/\n            parse: function (openSSLStr) {\n                var salt;\n\n                \/\/ Parse base64\n                var ciphertext = Base64.parse(openSSLStr);\n\n                \/\/ Shortcut\n                var ciphertextWords = ciphertext.words;\n\n                \/\/ Test for salt\n                if (ciphertextWords[0] == 0x53616c74 \u0026\u0026 ciphertextWords[1] == 0x65645f5f) {\n                    \/\/ Extract salt\n                    salt = WordArray.create(ciphertextWords.slice(2, 4));\n\n                    \/\/ Remove salt from ciphertext\n                    ciphertextWords.splice(0, 4);\n                    ciphertext.sigBytes -= 16;\n                }\n\n                return CipherParams.create({ ciphertext: ciphertext, salt: salt });\n            }\n        };\n\n        \/**\n         * A cipher wrapper that returns ciphertext as a serializable cipher params object.\n         *\/\n        var SerializableCipher = C_lib.SerializableCipher = Base.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL\n             *\/\n            cfg: Base.extend({\n                format: OpenSSLFormatter\n            }),\n\n            \/**\n             * Encrypts a message.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {WordArray|string} message The message to encrypt.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {CipherParams} A cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *\/\n            encrypt: function (cipher, message, key, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Encrypt\n                var encryptor = cipher.createEncryptor(key, cfg);\n                var ciphertext = encryptor.finalize(message);\n\n                \/\/ Shortcut\n                var cipherCfg = encryptor.cfg;\n\n                \/\/ Create and return serializable cipher params\n                return CipherParams.create({\n                    ciphertext: ciphertext,\n                    key: key,\n                    iv: cipherCfg.iv,\n                    algorithm: cipher,\n                    mode: cipherCfg.mode,\n                    padding: cipherCfg.padding,\n                    blockSize: cipher.blockSize,\n                    formatter: cfg.format\n                });\n            },\n\n            \/**\n             * Decrypts serialized ciphertext.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {WordArray} The plaintext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *\/\n            decrypt: function (cipher, ciphertext, key, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Convert string to CipherParams\n                ciphertext = this._parse(ciphertext, cfg.format);\n\n                \/\/ Decrypt\n                var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);\n\n                return plaintext;\n            },\n\n            \/**\n             * Converts serialized ciphertext to CipherParams,\n             * else assumed CipherParams already and returns ciphertext unchanged.\n             *\n             * @param {CipherParams|string} ciphertext The ciphertext.\n             * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.\n             *\n             * @return {CipherParams} The unserialized ciphertext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);\n             *\/\n            _parse: function (ciphertext, format) {\n                if (typeof ciphertext == 'string') {\n                    return format.parse(ciphertext, this);\n                } else {\n                    return ciphertext;\n                }\n            }\n        });\n\n        \/**\n         * Key derivation function namespace.\n         *\/\n        var C_kdf = C.kdf = {};\n\n        \/**\n         * OpenSSL key derivation function.\n         *\/\n        var OpenSSLKdf = C_kdf.OpenSSL = {\n            \/**\n             * Derives a key and IV from a password.\n             *\n             * @param {string} password The password to derive from.\n             * @param {number} keySize The size in words of the key to generate.\n             * @param {number} ivSize The size in words of the IV to generate.\n             * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.\n             *\n             * @return {CipherParams} A cipher params object with the key, IV, and salt.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256\/32, 128\/32);\n             *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256\/32, 128\/32, 'saltsalt');\n             *\/\n            execute: function (password, keySize, ivSize, salt, hasher) {\n                \/\/ Generate random salt\n                if (!salt) {\n                    salt = WordArray.random(64 \/ 8);\n                }\n\n                \/\/ Derive key and IV\n                if (!hasher) {\n                    var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);\n                } else {\n                    var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: hasher }).compute(password, salt);\n                }\n\n\n                \/\/ Separate key and IV\n                var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);\n                key.sigBytes = keySize * 4;\n\n                \/\/ Return params\n                return CipherParams.create({ key: key, iv: iv, salt: salt });\n            }\n        };\n\n        \/**\n         * A serializable cipher wrapper that derives the key from a password,\n         * and returns ciphertext as a serializable cipher params object.\n         *\/\n        var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL\n             *\/\n            cfg: SerializableCipher.cfg.extend({\n                kdf: OpenSSLKdf\n            }),\n\n            \/**\n             * Encrypts a message using a password.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {WordArray|string} message The message to encrypt.\n             * @param {string} password The password.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {CipherParams} A cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');\n             *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });\n             *\/\n            encrypt: function (cipher, message, password, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Derive key and other params\n                var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, cfg.salt, cfg.hasher);\n\n                \/\/ Add IV to config\n                cfg.iv = derivedParams.iv;\n\n                \/\/ Encrypt\n                var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);\n\n                \/\/ Mix in derived params\n                ciphertext.mixIn(derivedParams);\n\n                return ciphertext;\n            },\n\n            \/**\n             * Decrypts serialized ciphertext using a password.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n             * @param {string} password The password.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {WordArray} The plaintext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });\n             *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });\n             *\/\n            decrypt: function (cipher, ciphertext, password, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Convert string to CipherParams\n                ciphertext = this._parse(ciphertext, cfg.format);\n\n                \/\/ Derive key and other params\n                var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt, cfg.hasher);\n\n                \/\/ Add IV to config\n                cfg.iv = derivedParams.iv;\n\n                \/\/ Decrypt\n                var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);\n\n                return plaintext;\n            }\n        });\n    }());\n\n\n\n    (function () {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var BlockCipher = C_lib.BlockCipher;\n        var C_algo = C.algo;\n\n        \/\/ Lookup tables\n        var SBOX = [];\n        var INV_SBOX = [];\n        var SUB_MIX_0 = [];\n        var SUB_MIX_1 = [];\n        var SUB_MIX_2 = [];\n        var SUB_MIX_3 = [];\n        var INV_SUB_MIX_0 = [];\n        var INV_SUB_MIX_1 = [];\n        var INV_SUB_MIX_2 = [];\n        var INV_SUB_MIX_3 = [];\n\n        \/\/ Compute lookup tables\n        (function () {\n            \/\/ Compute double table\n            var d = [];\n            for (var i = 0; i \u003c 256; i++) {\n                if (i \u003c 128) {\n                    d[i] = i \u003c\u003c 1;\n                } else {\n                    d[i] = (i \u003c\u003c 1) ^ 0x11b;\n                }\n            }\n\n            \/\/ Walk GF(2^8)\n            var x = 0;\n            var xi = 0;\n            for (var i = 0; i \u003c 256; i++) {\n                \/\/ Compute sbox\n                var sx = xi ^ (xi \u003c\u003c 1) ^ (xi \u003c\u003c 2) ^ (xi \u003c\u003c 3) ^ (xi \u003c\u003c 4);\n                sx = (sx \u003e\u003e\u003e 8) ^ (sx \u0026 0xff) ^ 0x63;\n                SBOX[x] = sx;\n                INV_SBOX[sx] = x;\n\n                \/\/ Compute multiplication\n                var x2 = d[x];\n                var x4 = d[x2];\n                var x8 = d[x4];\n\n                \/\/ Compute sub bytes, mix columns tables\n                var t = (d[sx] * 0x101) ^ (sx * 0x1010100);\n                SUB_MIX_0[x] = (t \u003c\u003c 24) | (t \u003e\u003e\u003e 8);\n                SUB_MIX_1[x] = (t \u003c\u003c 16) | (t \u003e\u003e\u003e 16);\n                SUB_MIX_2[x] = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n                SUB_MIX_3[x] = t;\n\n                \/\/ Compute inv sub bytes, inv mix columns tables\n                var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);\n                INV_SUB_MIX_0[sx] = (t \u003c\u003c 24) | (t \u003e\u003e\u003e 8);\n                INV_SUB_MIX_1[sx] = (t \u003c\u003c 16) | (t \u003e\u003e\u003e 16);\n                INV_SUB_MIX_2[sx] = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n                INV_SUB_MIX_3[sx] = t;\n\n                \/\/ Compute next counter\n                if (!x) {\n                    x = xi = 1;\n                } else {\n                    x = x2 ^ d[d[d[x8 ^ x2]]];\n                    xi ^= d[d[xi]];\n                }\n            }\n        }());\n\n        \/\/ Precomputed Rcon lookup\n        var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];\n\n        \/**\n         * AES block cipher algorithm.\n         *\/\n        var AES = C_algo.AES = BlockCipher.extend({\n            _doReset: function () {\n                var t;\n\n                \/\/ Skip reset of nRounds has been set before and key did not change\n                if (this._nRounds \u0026\u0026 this._keyPriorReset === this._key) {\n                    return;\n                }\n\n                \/\/ Shortcuts\n                var key = this._keyPriorReset = this._key;\n                var keyWords = key.words;\n                var keySize = key.sigBytes \/ 4;\n\n                \/\/ Compute number of rounds\n                var nRounds = this._nRounds = keySize + 6;\n\n                \/\/ Compute number of key schedule rows\n                var ksRows = (nRounds + 1) * 4;\n\n                \/\/ Compute key schedule\n                var keySchedule = this._keySchedule = [];\n                for (var ksRow = 0; ksRow \u003c ksRows; ksRow++) {\n                    if (ksRow \u003c keySize) {\n                        keySchedule[ksRow] = keyWords[ksRow];\n                    } else {\n                        t = keySchedule[ksRow - 1];\n\n                        if (!(ksRow % keySize)) {\n                            \/\/ Rot word\n                            t = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n\n                            \/\/ Sub word\n                            t = (SBOX[t \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[t \u0026 0xff];\n\n                            \/\/ Mix Rcon\n                            t ^= RCON[(ksRow \/ keySize) | 0] \u003c\u003c 24;\n                        } else if (keySize \u003e 6 \u0026\u0026 ksRow % keySize == 4) {\n                            \/\/ Sub word\n                            t = (SBOX[t \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[t \u0026 0xff];\n                        }\n\n                        keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;\n                    }\n                }\n\n                \/\/ Compute inv key schedule\n                var invKeySchedule = this._invKeySchedule = [];\n                for (var invKsRow = 0; invKsRow \u003c ksRows; invKsRow++) {\n                    var ksRow = ksRows - invKsRow;\n\n                    if (invKsRow % 4) {\n                        var t = keySchedule[ksRow];\n                    } else {\n                        var t = keySchedule[ksRow - 4];\n                    }\n\n                    if (invKsRow \u003c 4 || ksRow \u003c= 4) {\n                        invKeySchedule[invKsRow] = t;\n                    } else {\n                        invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t \u003e\u003e\u003e 24]] ^ INV_SUB_MIX_1[SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff]] ^\n                            INV_SUB_MIX_2[SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff]] ^ INV_SUB_MIX_3[SBOX[t \u0026 0xff]];\n                    }\n                }\n            },\n\n            encryptBlock: function (M, offset) {\n                this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);\n            },\n\n            decryptBlock: function (M, offset) {\n                \/\/ Swap 2nd and 4th rows\n                var t = M[offset + 1];\n                M[offset + 1] = M[offset + 3];\n                M[offset + 3] = t;\n\n                this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);\n\n                \/\/ Inv swap 2nd and 4th rows\n                var t = M[offset + 1];\n                M[offset + 1] = M[offset + 3];\n                M[offset + 3] = t;\n            },\n\n            _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {\n                \/\/ Shortcut\n                var nRounds = this._nRounds;\n\n                \/\/ Get input, add round key\n                var s0 = M[offset] ^ keySchedule[0];\n                var s1 = M[offset + 1] ^ keySchedule[1];\n                var s2 = M[offset + 2] ^ keySchedule[2];\n                var s3 = M[offset + 3] ^ keySchedule[3];\n\n                \/\/ Key schedule row counter\n                var ksRow = 4;\n\n                \/\/ Rounds\n                for (var round = 1; round \u003c nRounds; round++) {\n                    \/\/ Shift rows, sub bytes, mix columns, add round key\n                    var t0 = SUB_MIX_0[s0 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s1 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s2 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s3 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t1 = SUB_MIX_0[s1 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s2 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s3 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s0 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t2 = SUB_MIX_0[s2 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s3 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s0 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s1 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t3 = SUB_MIX_0[s3 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s0 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s1 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s2 \u0026 0xff] ^ keySchedule[ksRow++];\n\n                    \/\/ Update state\n                    s0 = t0;\n                    s1 = t1;\n                    s2 = t2;\n                    s3 = t3;\n                }\n\n                \/\/ Shift rows, sub bytes, add round key\n                var t0 = ((SBOX[s0 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s1 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s2 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s3 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t1 = ((SBOX[s1 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s2 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s3 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s0 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t2 = ((SBOX[s2 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s3 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s0 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s1 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t3 = ((SBOX[s3 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s0 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s1 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s2 \u0026 0xff]) ^ keySchedule[ksRow++];\n\n                \/\/ Set output\n                M[offset] = t0;\n                M[offset + 1] = t1;\n                M[offset + 2] = t2;\n                M[offset + 3] = t3;\n            },\n\n            keySize: 256 \/ 32\n        });\n\n        \/**\n         * Shortcut functions to the cipher's object interface.\n         *\n         * @example\n         *\n         *     var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);\n         *     var plaintext  = CryptoJS.AES.decrypt(ciphertext, key, cfg);\n         *\/\n        C.AES = BlockCipher._createHelper(AES);\n    }());\n\n    (function (Math) {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var WordArray = C_lib.WordArray;\n        var Hasher = C_lib.Hasher;\n        var C_algo = C.algo;\n\n        \/\/ Constants table\n        var T = [];\n\n        \/\/ Compute constants\n        (function () {\n            for (var i = 0; i \u003c 64; i++) {\n                T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;\n            }\n        }());\n\n        \/**\n         * MD5 hash algorithm.\n         *\/\n        var MD5 = C_algo.MD5 = Hasher.extend({\n            _doReset: function () {\n                this._hash = new WordArray.init([\n                    0x67452301, 0xefcdab89,\n                    0x98badcfe, 0x10325476\n                ]);\n            },\n\n            _doProcessBlock: function (M, offset) {\n                \/\/ Swap endian\n                for (var i = 0; i \u003c 16; i++) {\n                    \/\/ Shortcuts\n                    var offset_i = offset + i;\n                    var M_offset_i = M[offset_i];\n\n                    M[offset_i] = (\n                        (((M_offset_i \u003c\u003c 8) | (M_offset_i \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                        (((M_offset_i \u003c\u003c 24) | (M_offset_i \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                    );\n                }\n\n                \/\/ Shortcuts\n                var H = this._hash.words;\n\n                var M_offset_0 = M[offset + 0];\n                var M_offset_1 = M[offset + 1];\n                var M_offset_2 = M[offset + 2];\n                var M_offset_3 = M[offset + 3];\n                var M_offset_4 = M[offset + 4];\n                var M_offset_5 = M[offset + 5];\n                var M_offset_6 = M[offset + 6];\n                var M_offset_7 = M[offset + 7];\n                var M_offset_8 = M[offset + 8];\n                var M_offset_9 = M[offset + 9];\n                var M_offset_10 = M[offset + 10];\n                var M_offset_11 = M[offset + 11];\n                var M_offset_12 = M[offset + 12];\n                var M_offset_13 = M[offset + 13];\n                var M_offset_14 = M[offset + 14];\n                var M_offset_15 = M[offset + 15];\n\n                \/\/ Working variables\n                var a = H[0];\n                var b = H[1];\n                var c = H[2];\n                var d = H[3];\n\n                \/\/ Computation\n                a = FF(a, b, c, d, M_offset_0, 7, T[0]);\n                d = FF(d, a, b, c, M_offset_1, 12, T[1]);\n                c = FF(c, d, a, b, M_offset_2, 17, T[2]);\n                b = FF(b, c, d, a, M_offset_3, 22, T[3]);\n                a = FF(a, b, c, d, M_offset_4, 7, T[4]);\n                d = FF(d, a, b, c, M_offset_5, 12, T[5]);\n                c = FF(c, d, a, b, M_offset_6, 17, T[6]);\n                b = FF(b, c, d, a, M_offset_7, 22, T[7]);\n                a = FF(a, b, c, d, M_offset_8, 7, T[8]);\n                d = FF(d, a, b, c, M_offset_9, 12, T[9]);\n                c = FF(c, d, a, b, M_offset_10, 17, T[10]);\n                b = FF(b, c, d, a, M_offset_11, 22, T[11]);\n                a = FF(a, b, c, d, M_offset_12, 7, T[12]);\n                d = FF(d, a, b, c, M_offset_13, 12, T[13]);\n                c = FF(c, d, a, b, M_offset_14, 17, T[14]);\n                b = FF(b, c, d, a, M_offset_15, 22, T[15]);\n\n                a = GG(a, b, c, d, M_offset_1, 5, T[16]);\n                d = GG(d, a, b, c, M_offset_6, 9, T[17]);\n                c = GG(c, d, a, b, M_offset_11, 14, T[18]);\n                b = GG(b, c, d, a, M_offset_0, 20, T[19]);\n                a = GG(a, b, c, d, M_offset_5, 5, T[20]);\n                d = GG(d, a, b, c, M_offset_10, 9, T[21]);\n                c = GG(c, d, a, b, M_offset_15, 14, T[22]);\n                b = GG(b, c, d, a, M_offset_4, 20, T[23]);\n                a = GG(a, b, c, d, M_offset_9, 5, T[24]);\n                d = GG(d, a, b, c, M_offset_14, 9, T[25]);\n                c = GG(c, d, a, b, M_offset_3, 14, T[26]);\n                b = GG(b, c, d, a, M_offset_8, 20, T[27]);\n                a = GG(a, b, c, d, M_offset_13, 5, T[28]);\n                d = GG(d, a, b, c, M_offset_2, 9, T[29]);\n                c = GG(c, d, a, b, M_offset_7, 14, T[30]);\n                b = GG(b, c, d, a, M_offset_12, 20, T[31]);\n\n                a = HH(a, b, c, d, M_offset_5, 4, T[32]);\n                d = HH(d, a, b, c, M_offset_8, 11, T[33]);\n                c = HH(c, d, a, b, M_offset_11, 16, T[34]);\n                b = HH(b, c, d, a, M_offset_14, 23, T[35]);\n                a = HH(a, b, c, d, M_offset_1, 4, T[36]);\n                d = HH(d, a, b, c, M_offset_4, 11, T[37]);\n                c = HH(c, d, a, b, M_offset_7, 16, T[38]);\n                b = HH(b, c, d, a, M_offset_10, 23, T[39]);\n                a = HH(a, b, c, d, M_offset_13, 4, T[40]);\n                d = HH(d, a, b, c, M_offset_0, 11, T[41]);\n                c = HH(c, d, a, b, M_offset_3, 16, T[42]);\n                b = HH(b, c, d, a, M_offset_6, 23, T[43]);\n                a = HH(a, b, c, d, M_offset_9, 4, T[44]);\n                d = HH(d, a, b, c, M_offset_12, 11, T[45]);\n                c = HH(c, d, a, b, M_offset_15, 16, T[46]);\n                b = HH(b, c, d, a, M_offset_2, 23, T[47]);\n\n                a = II(a, b, c, d, M_offset_0, 6, T[48]);\n                d = II(d, a, b, c, M_offset_7, 10, T[49]);\n                c = II(c, d, a, b, M_offset_14, 15, T[50]);\n                b = II(b, c, d, a, M_offset_5, 21, T[51]);\n                a = II(a, b, c, d, M_offset_12, 6, T[52]);\n                d = II(d, a, b, c, M_offset_3, 10, T[53]);\n                c = II(c, d, a, b, M_offset_10, 15, T[54]);\n                b = II(b, c, d, a, M_offset_1, 21, T[55]);\n                a = II(a, b, c, d, M_offset_8, 6, T[56]);\n                d = II(d, a, b, c, M_offset_15, 10, T[57]);\n                c = II(c, d, a, b, M_offset_6, 15, T[58]);\n                b = II(b, c, d, a, M_offset_13, 21, T[59]);\n                a = II(a, b, c, d, M_offset_4, 6, T[60]);\n                d = II(d, a, b, c, M_offset_11, 10, T[61]);\n                c = II(c, d, a, b, M_offset_2, 15, T[62]);\n                b = II(b, c, d, a, M_offset_9, 21, T[63]);\n\n                \/\/ Intermediate hash value\n                H[0] = (H[0] + a) | 0;\n                H[1] = (H[1] + b) | 0;\n                H[2] = (H[2] + c) | 0;\n                H[3] = (H[3] + d) | 0;\n            },\n\n            _doFinalize: function () {\n                \/\/ Shortcuts\n                var data = this._data;\n                var dataWords = data.words;\n\n                var nBitsTotal = this._nDataBytes * 8;\n                var nBitsLeft = data.sigBytes * 8;\n\n                \/\/ Add padding\n                dataWords[nBitsLeft \u003e\u003e\u003e 5] |= 0x80 \u003c\u003c (24 - nBitsLeft % 32);\n\n                var nBitsTotalH = Math.floor(nBitsTotal \/ 0x100000000);\n                var nBitsTotalL = nBitsTotal;\n                dataWords[(((nBitsLeft + 64) \u003e\u003e\u003e 9) \u003c\u003c 4) + 15] = (\n                    (((nBitsTotalH \u003c\u003c 8) | (nBitsTotalH \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                    (((nBitsTotalH \u003c\u003c 24) | (nBitsTotalH \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                );\n                dataWords[(((nBitsLeft + 64) \u003e\u003e\u003e 9) \u003c\u003c 4) + 14] = (\n                    (((nBitsTotalL \u003c\u003c 8) | (nBitsTotalL \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                    (((nBitsTotalL \u003c\u003c 24) | (nBitsTotalL \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                );\n\n                data.sigBytes = (dataWords.length + 1) * 4;\n\n                \/\/ Hash final blocks\n                this._process();\n\n                \/\/ Shortcuts\n                var hash = this._hash;\n                var H = hash.words;\n\n                \/\/ Swap endian\n                for (var i = 0; i \u003c 4; i++) {\n                    \/\/ Shortcut\n                    var H_i = H[i];\n\n                    H[i] = (((H_i \u003c\u003c 8) | (H_i \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                        (((H_i \u003c\u003c 24) | (H_i \u003e\u003e\u003e 8)) \u0026 0xff00ff00);\n                }\n\n                \/\/ Return final computed hash\n                return hash;\n            },\n\n            clone: function () {\n                var clone = Hasher.clone.call(this);\n                clone._hash = this._hash.clone();\n\n                return clone;\n            }\n        });\n\n        function FF(a, b, c, d, x, s, t) {\n            var n = a + ((b \u0026 c) | (~b \u0026 d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function GG(a, b, c, d, x, s, t) {\n            var n = a + ((b \u0026 d) | (c \u0026 ~d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function HH(a, b, c, d, x, s, t) {\n            var n = a + (b ^ c ^ d) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function II(a, b, c, d, x, s, t) {\n            var n = a + (c ^ (b | ~d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        \/**\n         * Shortcut function to the hasher's object interface.\n         *\n         * @param {WordArray|string} message The message to hash.\n         *\n         * @return {WordArray} The hash.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hash = CryptoJS.MD5('message');\n         *     var hash = CryptoJS.MD5(wordArray);\n         *\/\n        C.MD5 = Hasher._createHelper(MD5);\n\n        \/**\n         * Shortcut function to the HMAC's object interface.\n         *\n         * @param {WordArray|string} message The message to hash.\n         * @param {WordArray|string} key The secret key.\n         *\n         * @return {WordArray} The HMAC.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hmac = CryptoJS.HmacMD5(message, key);\n         *\/\n        C.HmacMD5 = Hasher._createHmacHelper(MD5);\n    }(Math));\n\n    \/**\n     * Zero padding strategy.\n     *\/\n    CryptoJS.pad.ZeroPadding = {\n        pad: function (data, blockSize) {\n            \/\/ Shortcut\n            var blockSizeBytes = blockSize * 4;\n\n            \/\/ Pad\n            data.clamp();\n            data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);\n        },\n\n        unpad: function (data) {\n            \/\/ Shortcut\n            var dataWords = data.words;\n\n            \/\/ Unpad\n            var i = data.sigBytes - 1;\n            for (var i = data.sigBytes - 1; i \u003e= 0; i--) {\n                if (((dataWords[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff)) {\n                    data.sigBytes = i + 1;\n                    break;\n                }\n            }\n        }\n    };\n\n\n    return CryptoJS;\n\n}));\n(function (P) {\n    (function () {\n        P.ecy = (function () {\n            function strEnc(data, firstKey, secondKey, thirdKey) {\n\n                var leng = data.length;\n                var encData = \"\";\n                var firstKeyBt, secondKeyBt, thirdKeyBt, firstLength, secondLength, thirdLength;\n                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                    firstKeyBt = getKeyBytes(firstKey);\n                    firstLength = firstKeyBt.length;\n                }\n                if (secondKey != null \u0026\u0026 secondKey != \"\") {\n                    secondKeyBt = getKeyBytes(secondKey);\n                    secondLength = secondKeyBt.length;\n                }\n                if (thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                    thirdKeyBt = getKeyBytes(thirdKey);\n                    thirdLength = thirdKeyBt.length;\n                }\n\n                if (leng \u003e 0) {\n                    if (leng \u003c 4) {\n                        var bt = strToBt(data);\n                        var encByte;\n                        if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                            var tempBt;\n                            var x, y, z;\n                            tempBt = bt;\n                            for (x = 0; x \u003c firstLength; x++) {\n                                tempBt = enc(tempBt, firstKeyBt[x]);\n                            }\n                            for (y = 0; y \u003c secondLength; y++) {\n                                tempBt = enc(tempBt, secondKeyBt[y]);\n                            }\n                            for (z = 0; z \u003c thirdLength; z++) {\n                                tempBt = enc(tempBt, thirdKeyBt[z]);\n                            }\n                            encByte = tempBt;\n                        } else {\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                var tempBt;\n                                var x, y;\n                                tempBt = bt;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                    var tempBt;\n                                    var x = 0;\n                                    tempBt = bt;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    encByte = tempBt;\n                                }\n                            }\n                        }\n                        encData = bt64ToHex(encByte);\n                    } else {\n                        var iterator = parseInt(leng \/ 4);\n                        var remainder = leng % 4;\n                        var i = 0;\n                        for (i = 0; i \u003c iterator; i++) {\n                            var tempData = data.substring(i * 4 + 0, i * 4 + 4);\n                            var tempByte = strToBt(tempData);\n                            var encByte;\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = tempByte;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                for (z = 0; z \u003c thirdLength; z++) {\n                                    tempBt = enc(tempBt, thirdKeyBt[z]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                    var tempBt;\n                                    var x, y;\n                                    tempBt = tempByte;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    for (y = 0; y \u003c secondLength; y++) {\n                                        tempBt = enc(tempBt, secondKeyBt[y]);\n                                    }\n                                    encByte = tempBt;\n                                } else {\n                                    if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                        var tempBt;\n                                        var x;\n                                        tempBt = tempByte;\n                                        for (x = 0; x \u003c firstLength; x++) {\n                                            tempBt = enc(tempBt, firstKeyBt[x]);\n                                        }\n                                        encByte = tempBt;\n                                    }\n                                }\n                            }\n                            encData += bt64ToHex(encByte);\n                        }\n                        if (remainder \u003e 0) {\n                            var remainderData = data.substring(iterator * 4 + 0, leng);\n                            var tempByte = strToBt(remainderData);\n                            var encByte;\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = tempByte;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                for (z = 0; z \u003c thirdLength; z++) {\n                                    tempBt = enc(tempBt, thirdKeyBt[z]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                    var tempBt;\n                                    var x, y;\n                                    tempBt = tempByte;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    for (y = 0; y \u003c secondLength; y++) {\n                                        tempBt = enc(tempBt, secondKeyBt[y]);\n                                    }\n                                    encByte = tempBt;\n                                } else {\n                                    if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                        var tempBt;\n                                        var x;\n                                        tempBt = tempByte;\n                                        for (x = 0; x \u003c firstLength; x++) {\n                                            tempBt = enc(tempBt, firstKeyBt[x]);\n                                        }\n                                        encByte = tempBt;\n                                    }\n                                }\n                            }\n                            encData += bt64ToHex(encByte);\n                        }\n                    }\n                }\n                return encData;\n            }\n\n            \/*\n             * decrypt the encrypted string to the original string\n             *\n             * return  the original string\n             *\/\n            function strDec(data, firstKey, secondKey, thirdKey) {\n                var leng = data.length;\n                var decStr = \"\";\n                var firstKeyBt, secondKeyBt, thirdKeyBt, firstLength, secondLength, thirdLength;\n                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                    firstKeyBt = getKeyBytes(firstKey);\n                    firstLength = firstKeyBt.length;\n                }\n                if (secondKey != null \u0026\u0026 secondKey != \"\") {\n                    secondKeyBt = getKeyBytes(secondKey);\n                    secondLength = secondKeyBt.length;\n                }\n                if (thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                    thirdKeyBt = getKeyBytes(thirdKey);\n                    thirdLength = thirdKeyBt.length;\n                }\n\n                var iterator = parseInt(leng \/ 16);\n                var i = 0;\n                for (i = 0; i \u003c iterator; i++) {\n                    var tempData = data.substring(i * 16 + 0, i * 16 + 16);\n                    var strByte = hexToBt64(tempData);\n                    var intByte = new Array(64);\n                    var j = 0;\n                    for (j = 0; j \u003c 64; j++) {\n                        intByte[j] = parseInt(strByte.substring(j, j + 1));\n                    }\n                    var decByte;\n                    if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                        var tempBt;\n                        var x, y, z;\n                        tempBt = intByte;\n                        for (x = thirdLength - 1; x \u003e= 0; x--) {\n                            tempBt = dec(tempBt, thirdKeyBt[x]);\n                        }\n                        for (y = secondLength - 1; y \u003e= 0; y--) {\n                            tempBt = dec(tempBt, secondKeyBt[y]);\n                        }\n                        for (z = firstLength - 1; z \u003e= 0; z--) {\n                            tempBt = dec(tempBt, firstKeyBt[z]);\n                        }\n                        decByte = tempBt;\n                    } else {\n                        if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                            var tempBt;\n                            var x, y, z;\n                            tempBt = intByte;\n                            for (x = secondLength - 1; x \u003e= 0; x--) {\n                                tempBt = dec(tempBt, secondKeyBt[x]);\n                            }\n                            for (y = firstLength - 1; y \u003e= 0; y--) {\n                                tempBt = dec(tempBt, firstKeyBt[y]);\n                            }\n                            decByte = tempBt;\n                        } else {\n                            if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = intByte;\n                                for (x = firstLength - 1; x \u003e= 0; x--) {\n                                    tempBt = dec(tempBt, firstKeyBt[x]);\n                                }\n                                decByte = tempBt;\n                            }\n                        }\n                    }\n                    decStr += byteToString(decByte);\n                }\n                return decStr;\n            }\n            \/*\n             * chang the string into the bit array\n             *\n             * return bit array(it's length % 64 = 0)\n             *\/\n            function getKeyBytes(key) {\n                var keyBytes = new Array();\n                var leng = key.length;\n                var iterator = parseInt(leng \/ 4);\n                var remainder = leng % 4;\n                var i = 0;\n                for (i = 0; i \u003c iterator; i++) {\n                    keyBytes[i] = strToBt(key.substring(i * 4 + 0, i * 4 + 4));\n                }\n                if (remainder \u003e 0) {\n                    keyBytes[i] = strToBt(key.substring(i * 4 + 0, leng));\n                }\n                return keyBytes;\n            }\n\n            \/*\n             * chang the string(it's length \u003c= 4) into the bit array\n             *\n             * return bit array(it's length = 64)\n             *\/\n            function strToBt(str) {\n                var leng = str.length;\n                var bt = new Array(64);\n                var i = 0, j = 0, p = 0, q = 0;\n                if (leng \u003c 4) {\n                    for (i = 0; i \u003c leng; i++) {\n                        var k = str.charCodeAt(i);\n                        for (j = 0; j \u003c 16; j++) {\n                            var pow = 1, m = 0;\n                            for (m = 15; m \u003e j; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * i + j] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                    for (p = leng; p \u003c 4; p++) {\n                        var k = 0;\n                        for (q = 0; q \u003c 16; q++) {\n                            var pow = 1, m = 0;\n                            for (m = 15; m \u003e q; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * p + q] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                } else {\n                    for (i = 0; i \u003c 4; i++) {\n                        var k = str.charCodeAt(i);\n                        for (j = 0; j \u003c 16; j++) {\n                            var pow = 1;\n                            for (m = 15; m \u003e j; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * i + j] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                }\n                return bt;\n            }\n\n            \/*\n             * chang the bit(it's length = 4) into the hex\n             *\n             * return hex\n             *\/\n            function bt4ToHex(binary) {\n                var hex;\n                switch (binary) {\n                    case \"0000\": hex = \"0\"; break;\n                    case \"0001\": hex = \"1\"; break;\n                    case \"0010\": hex = \"2\"; break;\n                    case \"0011\": hex = \"3\"; break;\n                    case \"0100\": hex = \"4\"; break;\n                    case \"0101\": hex = \"5\"; break;\n                    case \"0110\": hex = \"6\"; break;\n                    case \"0111\": hex = \"7\"; break;\n                    case \"1000\": hex = \"8\"; break;\n                    case \"1001\": hex = \"9\"; break;\n                    case \"1010\": hex = \"A\"; break;\n                    case \"1011\": hex = \"B\"; break;\n                    case \"1100\": hex = \"C\"; break;\n                    case \"1101\": hex = \"D\"; break;\n                    case \"1110\": hex = \"E\"; break;\n                    case \"1111\": hex = \"F\"; break;\n                }\n                return hex;\n            }\n\n            \/*\n             * chang the hex into the bit(it's length = 4)\n             *\n             * return the bit(it's length = 4)\n             *\/\n            function hexToBt4(hex) {\n                var binary;\n                switch (hex) {\n                    case \"0\": binary = \"0000\"; break;\n                    case \"1\": binary = \"0001\"; break;\n                    case \"2\": binary = \"0010\"; break;\n                    case \"3\": binary = \"0011\"; break;\n                    case \"4\": binary = \"0100\"; break;\n                    case \"5\": binary = \"0101\"; break;\n                    case \"6\": binary = \"0110\"; break;\n                    case \"7\": binary = \"0111\"; break;\n                    case \"8\": binary = \"1000\"; break;\n                    case \"9\": binary = \"1001\"; break;\n                    case \"A\": binary = \"1010\"; break;\n                    case \"B\": binary = \"1011\"; break;\n                    case \"C\": binary = \"1100\"; break;\n                    case \"D\": binary = \"1101\"; break;\n                    case \"E\": binary = \"1110\"; break;\n                    case \"F\": binary = \"1111\"; break;\n                }\n                return binary;\n            }\n\n            \/*\n             * chang the bit(it's length = 64) into the string\n             *\n             * return string\n             *\/\n            function byteToString(byteData) {\n                var str = \"\";\n                var i, j, m;\n                for (i = 0; i \u003c 4; i++) {\n                    var count = 0;\n                    for (j = 0; j \u003c 16; j++) {\n                        var pow = 1;\n                        for (m = 15; m \u003e j; m--) {\n                            pow *= 2;\n                        }\n                        count += byteData[16 * i + j] * pow;\n                    }\n                    if (count != 0) {\n                        str += String.fromCharCode(count);\n                    }\n                }\n                return str;\n            }\n\n            function bt64ToHex(byteData) {\n                var hex = \"\";\n                var i, j;\n                for (i = 0; i \u003c 16; i++) {\n                    var bt = \"\";\n                    for (j = 0; j \u003c 4; j++) {\n                        bt += byteData[i * 4 + j];\n                    }\n                    hex += bt4ToHex(bt);\n                }\n                return hex;\n            }\n\n            function hexToBt64(hex) {\n                var binary = \"\";\n                for (var i = 0; i \u003c 16; i++) {\n                    binary += hexToBt4(hex.substring(i, i + 1));\n                }\n                return binary;\n            }\n\n            \/*\n             * the 64 bit des core arithmetic\n             *\/\n\n            function enc(dataByte, keyByte) {\n                var keys = generateKeys(keyByte);\n                var ipByte = initPermute(dataByte);\n                var ipLeft = new Array(32);\n                var ipRight = new Array(32);\n                var tempLeft = new Array(32);\n                var i = 0, j = 0, k = 0, m = 0, n = 0;\n                for (k = 0; k \u003c 32; k++) {\n                    ipLeft[k] = ipByte[k];\n                    ipRight[k] = ipByte[32 + k];\n                }\n                for (i = 0; i \u003c 16; i++) {\n                    for (j = 0; j \u003c 32; j++) {\n                        tempLeft[j] = ipLeft[j];\n                        ipLeft[j] = ipRight[j];\n                    }\n                    var key = new Array(48);\n                    for (m = 0; m \u003c 48; m++) {\n                        key[m] = keys[i][m];\n                    }\n                    var tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);\n                    for (n = 0; n \u003c 32; n++) {\n                        ipRight[n] = tempRight[n];\n                    }\n\n                }\n\n\n                var finalData = new Array(64);\n                for (i = 0; i \u003c 32; i++) {\n                    finalData[i] = ipRight[i];\n                    finalData[32 + i] = ipLeft[i];\n                }\n                return finallyPermute(finalData);\n            }\n\n            function dec(dataByte, keyByte) {\n                var keys = generateKeys(keyByte);\n                var ipByte = initPermute(dataByte);\n                var ipLeft = new Array(32);\n                var ipRight = new Array(32);\n                var tempLeft = new Array(32);\n                var i = 0, j = 0, k = 0, m = 0, n = 0;\n                for (k = 0; k \u003c 32; k++) {\n                    ipLeft[k] = ipByte[k];\n                    ipRight[k] = ipByte[32 + k];\n                }\n                for (i = 15; i \u003e= 0; i--) {\n                    for (j = 0; j \u003c 32; j++) {\n                        tempLeft[j] = ipLeft[j];\n                        ipLeft[j] = ipRight[j];\n                    }\n                    var key = new Array(48);\n                    for (m = 0; m \u003c 48; m++) {\n                        key[m] = keys[i][m];\n                    }\n\n                    var tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);\n                    for (n = 0; n \u003c 32; n++) {\n                        ipRight[n] = tempRight[n];\n                    }\n                }\n\n\n                var finalData = new Array(64);\n                for (i = 0; i \u003c 32; i++) {\n                    finalData[i] = ipRight[i];\n                    finalData[32 + i] = ipLeft[i];\n                }\n                return finallyPermute(finalData);\n            }\n\n            function initPermute(originalData) {\n                var ipByte = new Array(64);\n                var i, j, m, n, k;\n                for (i = 0, m = 1, n = 0; i \u003c 4; i++, m += 2, n += 2) {\n                    for (j = 7, k = 0; j \u003e= 0; j--, k++) {\n                        ipByte[i * 8 + k] = originalData[j * 8 + m];\n                        ipByte[i * 8 + k + 32] = originalData[j * 8 + n];\n                    }\n                }\n                return ipByte;\n            }\n\n            function expandPermute(rightData) {\n                var epByte = new Array(48);\n                for (var i = 0; i \u003c 8; i++) {\n                    if (i == 0) {\n                        epByte[i * 6 + 0] = rightData[31];\n                    } else {\n                        epByte[i * 6 + 0] = rightData[i * 4 - 1];\n                    }\n                    epByte[i * 6 + 1] = rightData[i * 4 + 0];\n                    epByte[i * 6 + 2] = rightData[i * 4 + 1];\n                    epByte[i * 6 + 3] = rightData[i * 4 + 2];\n                    epByte[i * 6 + 4] = rightData[i * 4 + 3];\n                    if (i == 7) {\n                        epByte[i * 6 + 5] = rightData[0];\n                    } else {\n                        epByte[i * 6 + 5] = rightData[i * 4 + 4];\n                    }\n                }\n                return epByte;\n            }\n\n            function xor(byteOne, byteTwo) {\n                var xorByte = new Array(byteOne.length);\n                for (var i = 0; i \u003c byteOne.length; i++) {\n                    xorByte[i] = byteOne[i] ^ byteTwo[i];\n                }\n                return xorByte;\n            }\n\n            function sBoxPermute(expandByte) {\n\n                var sBoxByte = new Array(32);\n                var binary = \"\";\n                var s1 = [\n                    [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],\n                    [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],\n                    [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],\n                    [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]];\n\n                \/* Table - s2 *\/\n                var s2 = [\n                    [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],\n                    [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],\n                    [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],\n                    [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]];\n\n                \/* Table - s3 *\/\n                var s3 = [\n                    [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],\n                    [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],\n                    [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],\n                    [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]];\n                \/* Table - s4 *\/\n                var s4 = [\n                    [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],\n                    [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],\n                    [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],\n                    [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]];\n\n                \/* Table - s5 *\/\n                var s5 = [\n                    [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],\n                    [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],\n                    [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],\n                    [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]];\n\n                \/* Table - s6 *\/\n                var s6 = [\n                    [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],\n                    [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],\n                    [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],\n                    [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]];\n\n                \/* Table - s7 *\/\n                var s7 = [\n                    [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],\n                    [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],\n                    [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],\n                    [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]];\n\n                \/* Table - s8 *\/\n                var s8 = [\n                    [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],\n                    [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],\n                    [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],\n                    [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]];\n\n                var m;\n\n                for (m = 0; m \u003c 8; m++) {\n                    var i = 0, j = 0;\n                    i = expandByte[m * 6 + 0] * 2 + expandByte[m * 6 + 5];\n                    j = expandByte[m * 6 + 1] * 2 * 2 * 2\n                        + expandByte[m * 6 + 2] * 2 * 2\n                        + expandByte[m * 6 + 3] * 2\n                        + expandByte[m * 6 + 4];\n                    switch (m) {\n                        case 0:\n                            binary = getBoxBinary(s1[i][j]);\n                            break;\n                        case 1:\n                            binary = getBoxBinary(s2[i][j]);\n                            break;\n                        case 2:\n                            binary = getBoxBinary(s3[i][j]);\n                            break;\n                        case 3:\n                            binary = getBoxBinary(s4[i][j]);\n                            break;\n                        case 4:\n                            binary = getBoxBinary(s5[i][j]);\n                            break;\n                        case 5:\n                            binary = getBoxBinary(s6[i][j]);\n                            break;\n                        case 6:\n                            binary = getBoxBinary(s7[i][j]);\n                            break;\n                        case 7:\n                            binary = getBoxBinary(s8[i][j]);\n                            break;\n                    }\n                    sBoxByte[m * 4 + 0] = parseInt(binary.substring(0, 1));\n                    sBoxByte[m * 4 + 1] = parseInt(binary.substring(1, 2));\n                    sBoxByte[m * 4 + 2] = parseInt(binary.substring(2, 3));\n                    sBoxByte[m * 4 + 3] = parseInt(binary.substring(3, 4));\n                }\n                return sBoxByte;\n            }\n\n            function pPermute(sBoxByte) {\n                var pBoxPermute = new Array(32);\n                pBoxPermute[0] = sBoxByte[15];\n                pBoxPermute[1] = sBoxByte[6];\n                pBoxPermute[2] = sBoxByte[19];\n                pBoxPermute[3] = sBoxByte[20];\n                pBoxPermute[4] = sBoxByte[28];\n                pBoxPermute[5] = sBoxByte[11];\n                pBoxPermute[6] = sBoxByte[27];\n                pBoxPermute[7] = sBoxByte[16];\n                pBoxPermute[8] = sBoxByte[0];\n                pBoxPermute[9] = sBoxByte[14];\n                pBoxPermute[10] = sBoxByte[22];\n                pBoxPermute[11] = sBoxByte[25];\n                pBoxPermute[12] = sBoxByte[4];\n                pBoxPermute[13] = sBoxByte[17];\n                pBoxPermute[14] = sBoxByte[30];\n                pBoxPermute[15] = sBoxByte[9];\n                pBoxPermute[16] = sBoxByte[1];\n                pBoxPermute[17] = sBoxByte[7];\n                pBoxPermute[18] = sBoxByte[23];\n                pBoxPermute[19] = sBoxByte[13];\n                pBoxPermute[20] = sBoxByte[31];\n                pBoxPermute[21] = sBoxByte[26];\n                pBoxPermute[22] = sBoxByte[2];\n                pBoxPermute[23] = sBoxByte[8];\n                pBoxPermute[24] = sBoxByte[18];\n                pBoxPermute[25] = sBoxByte[12];\n                pBoxPermute[26] = sBoxByte[29];\n                pBoxPermute[27] = sBoxByte[5];\n                pBoxPermute[28] = sBoxByte[21];\n                pBoxPermute[29] = sBoxByte[10];\n                pBoxPermute[30] = sBoxByte[3];\n                pBoxPermute[31] = sBoxByte[24];\n                return pBoxPermute;\n            }\n\n            function finallyPermute(endByte) {\n                var fpByte = new Array(64);\n                fpByte[0] = endByte[39];\n                fpByte[1] = endByte[7];\n                fpByte[2] = endByte[47];\n                fpByte[3] = endByte[15];\n                fpByte[4] = endByte[55];\n                fpByte[5] = endByte[23];\n                fpByte[6] = endByte[63];\n                fpByte[7] = endByte[31];\n                fpByte[8] = endByte[38];\n                fpByte[9] = endByte[6];\n                fpByte[10] = endByte[46];\n                fpByte[11] = endByte[14];\n                fpByte[12] = endByte[54];\n                fpByte[13] = endByte[22];\n                fpByte[14] = endByte[62];\n                fpByte[15] = endByte[30];\n                fpByte[16] = endByte[37];\n                fpByte[17] = endByte[5];\n                fpByte[18] = endByte[45];\n                fpByte[19] = endByte[13];\n                fpByte[20] = endByte[53];\n                fpByte[21] = endByte[21];\n                fpByte[22] = endByte[61];\n                fpByte[23] = endByte[29];\n                fpByte[24] = endByte[36];\n                fpByte[25] = endByte[4];\n                fpByte[26] = endByte[44];\n                fpByte[27] = endByte[12];\n                fpByte[28] = endByte[52];\n                fpByte[29] = endByte[20];\n                fpByte[30] = endByte[60];\n                fpByte[31] = endByte[28];\n                fpByte[32] = endByte[35];\n                fpByte[33] = endByte[3];\n                fpByte[34] = endByte[43];\n                fpByte[35] = endByte[11];\n                fpByte[36] = endByte[51];\n                fpByte[37] = endByte[19];\n                fpByte[38] = endByte[59];\n                fpByte[39] = endByte[27];\n                fpByte[40] = endByte[34];\n                fpByte[41] = endByte[2];\n                fpByte[42] = endByte[42];\n                fpByte[43] = endByte[10];\n                fpByte[44] = endByte[50];\n                fpByte[45] = endByte[18];\n                fpByte[46] = endByte[58];\n                fpByte[47] = endByte[26];\n                fpByte[48] = endByte[33];\n                fpByte[49] = endByte[1];\n                fpByte[50] = endByte[41];\n                fpByte[51] = endByte[9];\n                fpByte[52] = endByte[49];\n                fpByte[53] = endByte[17];\n                fpByte[54] = endByte[57];\n                fpByte[55] = endByte[25];\n                fpByte[56] = endByte[32];\n                fpByte[57] = endByte[0];\n                fpByte[58] = endByte[40];\n                fpByte[59] = endByte[8];\n                fpByte[60] = endByte[48];\n                fpByte[61] = endByte[16];\n                fpByte[62] = endByte[56];\n                fpByte[63] = endByte[24];\n                return fpByte;\n            }\n\n            function getBoxBinary(i) {\n                var binary = \"\";\n                switch (i) {\n                    case 0: binary = \"0000\"; break;\n                    case 1: binary = \"0001\"; break;\n                    case 2: binary = \"0010\"; break;\n                    case 3: binary = \"0011\"; break;\n                    case 4: binary = \"0100\"; break;\n                    case 5: binary = \"0101\"; break;\n                    case 6: binary = \"0110\"; break;\n                    case 7: binary = \"0111\"; break;\n                    case 8: binary = \"1000\"; break;\n                    case 9: binary = \"1001\"; break;\n                    case 10: binary = \"1010\"; break;\n                    case 11: binary = \"1011\"; break;\n                    case 12: binary = \"1100\"; break;\n                    case 13: binary = \"1101\"; break;\n                    case 14: binary = \"1110\"; break;\n                    case 15: binary = \"1111\"; break;\n                }\n                return binary;\n            }\n            \/*\n             * generate 16 keys for xor\n             *\n             *\/\n            function generateKeys(keyByte) {\n                var key = new Array(56);\n                var keys = new Array();\n\n                keys[0] = new Array();\n                keys[1] = new Array();\n                keys[2] = new Array();\n                keys[3] = new Array();\n                keys[4] = new Array();\n                keys[5] = new Array();\n                keys[6] = new Array();\n                keys[7] = new Array();\n                keys[8] = new Array();\n                keys[9] = new Array();\n                keys[10] = new Array();\n                keys[11] = new Array();\n                keys[12] = new Array();\n                keys[13] = new Array();\n                keys[14] = new Array();\n                keys[15] = new Array();\n                var loop = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];\n\n                var i, j, k, m;\n                for (i = 0; i \u003c 7; i++) {\n                    for (j = 0, k = 7; j \u003c 8; j++, k--) {\n                        key[i * 8 + j] = keyByte[8 * k + i];\n                    }\n                }\n\n                var i = 0;\n                for (i = 0; i \u003c 16; i++) {\n                    var tempLeft = 0;\n                    var tempRight = 0;\n                    for (j = 0; j \u003c loop[i]; j++) {\n                        tempLeft = key[0];\n                        tempRight = key[28];\n                        for (k = 0; k \u003c 27; k++) {\n                            key[k] = key[k + 1];\n                            key[28 + k] = key[29 + k];\n                        }\n                        key[27] = tempLeft;\n                        key[55] = tempRight;\n                    }\n                    var tempKey = new Array(48);\n                    tempKey[0] = key[13];\n                    tempKey[1] = key[16];\n                    tempKey[2] = key[10];\n                    tempKey[3] = key[23];\n                    tempKey[4] = key[0];\n                    tempKey[5] = key[4];\n                    tempKey[6] = key[2];\n                    tempKey[7] = key[27];\n                    tempKey[8] = key[14];\n                    tempKey[9] = key[5];\n                    tempKey[10] = key[20];\n                    tempKey[11] = key[9];\n                    tempKey[12] = key[22];\n                    tempKey[13] = key[18];\n                    tempKey[14] = key[11];\n                    tempKey[15] = key[3];\n                    tempKey[16] = key[25];\n                    tempKey[17] = key[7];\n                    tempKey[18] = key[15];\n                    tempKey[19] = key[6];\n                    tempKey[20] = key[26];\n                    tempKey[21] = key[19];\n                    tempKey[22] = key[12];\n                    tempKey[23] = key[1];\n                    tempKey[24] = key[40];\n                    tempKey[25] = key[51];\n                    tempKey[26] = key[30];\n                    tempKey[27] = key[36];\n                    tempKey[28] = key[46];\n                    tempKey[29] = key[54];\n                    tempKey[30] = key[29];\n                    tempKey[31] = key[39];\n                    tempKey[32] = key[50];\n                    tempKey[33] = key[44];\n                    tempKey[34] = key[32];\n                    tempKey[35] = key[47];\n                    tempKey[36] = key[43];\n                    tempKey[37] = key[48];\n                    tempKey[38] = key[38];\n                    tempKey[39] = key[55];\n                    tempKey[40] = key[33];\n                    tempKey[41] = key[52];\n                    tempKey[42] = key[45];\n                    tempKey[43] = key[41];\n                    tempKey[44] = key[49];\n                    tempKey[45] = key[35];\n                    tempKey[46] = key[28];\n                    tempKey[47] = key[31];\n                    switch (i) {\n                        case 0: for (m = 0; m \u003c 48; m++) { keys[0][m] = tempKey[m]; } break;\n                        case 1: for (m = 0; m \u003c 48; m++) { keys[1][m] = tempKey[m]; } break;\n                        case 2: for (m = 0; m \u003c 48; m++) { keys[2][m] = tempKey[m]; } break;\n                        case 3: for (m = 0; m \u003c 48; m++) { keys[3][m] = tempKey[m]; } break;\n                        case 4: for (m = 0; m \u003c 48; m++) { keys[4][m] = tempKey[m]; } break;\n                        case 5: for (m = 0; m \u003c 48; m++) { keys[5][m] = tempKey[m]; } break;\n                        case 6: for (m = 0; m \u003c 48; m++) { keys[6][m] = tempKey[m]; } break;\n                        case 7: for (m = 0; m \u003c 48; m++) { keys[7][m] = tempKey[m]; } break;\n                        case 8: for (m = 0; m \u003c 48; m++) { keys[8][m] = tempKey[m]; } break;\n                        case 9: for (m = 0; m \u003c 48; m++) { keys[9][m] = tempKey[m]; } break;\n                        case 10: for (m = 0; m \u003c 48; m++) { keys[10][m] = tempKey[m]; } break;\n                        case 11: for (m = 0; m \u003c 48; m++) { keys[11][m] = tempKey[m]; } break;\n                        case 12: for (m = 0; m \u003c 48; m++) { keys[12][m] = tempKey[m]; } break;\n                        case 13: for (m = 0; m \u003c 48; m++) { keys[13][m] = tempKey[m]; } break;\n                        case 14: for (m = 0; m \u003c 48; m++) { keys[14][m] = tempKey[m]; } break;\n                        case 15: for (m = 0; m \u003c 48; m++) { keys[15][m] = tempKey[m]; } break;\n                    }\n                }\n                return keys;\n            }\n            return {\n                e: strEnc,\n                d: strDec\n            }\n        })();\n    })();\n    P.methodMaps = {\n        jc: 17,\n        snv: 103,\n        cpl: 101,\n        xzext: 10,\n        pi: 102,\n        c_up: 4,\n        iyc: 15,\n        c_nav: 5,\n        c_tan: 6,\n        c_inst: 7,\n        e_int: 3,\n        chb: 8,\n        ssi: 11,\n        eku: 12,\n        ad: 13,\n        ntp: 16,\n        pss: 18,\n        nct: 19,\n        ddp: 20,\n        dtb: 22,\n    };\n    (function () {\n        function randomStr(len) {\n            var e = Math.random() + ';' + Date.now();\n            var configKey = 'abcdefghijklmnopqrstuvwxyz0123456789';\n            var t = \"\"\n                , n = void 0\n                , a = void 0\n                , r = \"\"\n                , o = void 0\n                , i = void 0\n                , s = void 0\n                , l = \"\"\n                , d = 0;\n            do {\n                o = (n = e.charCodeAt(d++)) \u003e\u003e 2,\n                    i = (3 \u0026 n) \u003c\u003c 4 | (a = e.charCodeAt(d++)) \u003e\u003e 4,\n                    s = (15 \u0026 a) \u003c\u003c 2 | (r = e.charCodeAt(d++)) \u003e\u003e 6,\n                    l = 63 \u0026 r,\n                    isNaN(a) ? s = l = 64 : isNaN(r) \u0026\u0026 (l = 64),\n                    t = t + configKey.charAt(o) + configKey.charAt(i) + configKey.charAt(s) + configKey.charAt(l),\n                    n = a = r = \"\",\n                    o = i = s = l = \"\"\n            } while (d \u003c e.length); return t.substring(0, len || t.length);\n        }\n        P.processParam = function (params) {\n            let data = Object.assign({}, params);\n            let __config__ = P.config;\n            for (var key in data) {\n                if (__config__.request.param[key]) {\n                    var length = 0;\n                    var paramValue = data[key] + '';\n                    delete data[key];\n                    var paramConfig = __config__.request.param[key];\n                    paramConfig.forEach(function (item, index) {\n                        var value;\n                        if (length \u003e= paramValue.length) {\n                            value = '';\n                        } else {\n                            if (index == paramConfig.length - 1) {\n                                value = paramValue.substr(length);\n                            } else {\n                                value = paramValue.substr(length, item.length);\n                            }\n                        }\n                        var valueHolder = [];\n                        for (var i = 0; i \u003c item.count; i++) {\n                            if (i == item.fetch_index1) {\n                                valueHolder.push(value);\n                            } else {\n                                valueHolder.push(randomStr(value.length));\n                            }\n                        }\n                        length += item.length;\n                        data[item.fetch_name] = valueHolder.join(item.split_chars);\n                    })\n                }\n            }\n            if (__config__.encrypt_method) {\n                for (var key in data) {\n                    if (__config__.encrypt_method == 'base64') {\n                        data[key] = btoa(data[key])\n                    } else if (__config__.encrypt_method == 'rc4') {\n                        data[key] = P.rc4(__config__.encrypt_key, data[key])\n                    }\n                }\n            }\n            return data;\n        }\n        P.rc4 = function (key, str) {\n            var s = [], j = 0, x, res = '';\n            for (var i = 0; i \u003c 256; i++) {\n                s[i] = i;\n            }\n            for (i = 0; i \u003c 256; i++) {\n                j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;\n                x = s[i];\n                s[i] = s[j];\n                s[j] = x;\n            }\n            i = 0;\n            j = 0;\n            for (var y = 0; y \u003c str.length; y++) {\n                i = (i + 1) % 256;\n                j = (j + s[i]) % 256;\n                x = s[i];\n                s[i] = s[j];\n                s[j] = x;\n                res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);\n            }\n            return res;\n        }\n        P.getParams = function (params) {\n            var cbs = {\n                '2345': 1,\n                '360': 3,\n                \/\/chrome市场上的360\n                '3603': 303,\n                'chrome': 5,\n                'firefox': 6,\n                'ff': 6,\n                'maxthon': 9,\n                'sogou': 13,\n                'qq': 11,\n                'mul': 100,\n                'edg': 14\n            };\n            let __config__ = P.config;\n            let data = {}\n            data[__config__.__u] = P.userConfig.uid;\n            data[__config__.__c] = P.userConfig.cl;\n            data[__config__.__t_] = P.userConfig.t;\n            data[__config__.__ts] = Date.now();\n            data[__config__.__checkcode] = P.CryptoJS.MD5(data[__config__.__u] + data[__config__.__c] + data[__config__.__t_] + data[__config__.__ts]).toString();\n            Object.assign(data, params, {\n                r: document.referrer,\n                ncb: cbs[__config__.br]\n            });\n            return data;\n        }\n        P.parseParams = function (strParams) {\n            var params = strParams ? strParams.split('\u0026') : [];\n            var _params = {};\n            for (var i = 0, l = params.length; i \u003c l \u0026\u0026 params[i]; i++) {\n                var parts = params[i].split('=');\n                _params[parts[0]] = decodeURIComponent(parts[1]);\n            }\n            return _params;\n        }\n        P.params = function (data) {\n            let str = [];\n            for (var key in data) {\n                str.push(`${key}=${encodeURIComponent(data[key])}`)\n            }\n            return str.join('\u0026')\n        }\n        P.fetch = function (url, params = {}) {\n            let __config__ = P.config;\n            let data = P.getParams(params);\n            data = P.processParam(data);\n            let settings = {\n                headers: {\n                    referrer: location.href\n                }\n            };\n            let _url = url;\n            if (__config__.request.type == 'POST') {\n                settings.method = 'POST';\n                settings.body = JSON.stringify(data);\n            } else if (__config__.request.type == 'HEADER') {\n                Object.assign(settings.headers, params);\n            } else {\n                _url = `${url}${url.indexOf('?') \u003e= 0 ? '\u0026' : '?'}${P.params(data)}`\n            }\n            return fetch(_url, settings)\n        }\n        P.tj = function (path, params) {\n            P.fetch(P.config.jrServer + '\/' + path + '.gif', params);\n        }\n        P.bgTj = function () {\n            P.tj(P.config.btj);\n        }\n        P.pageTj = function () {\n            P.tj(P.config.atj);\n        }\n    })();\n    (function () {\n        var domains = [\n            'baidu.com',\n            'bilibili.com',\n            'cn.bing.com',\n            'huya.com',\n            'hao123.com',\n            'qq.com',\n            'douyu.com',\n            '360.com',\n            'cnki.net',\n            'zhihu.com',\n            'niurou.pro',\n            'eastmoney.com',\n            'microsoft.com',\n            'hao.hasn9ym.cn',\n            'mooc1.chaoxing.com',\n            'weibo.com',\n            'autohome.com.cn',\n            'qcc.com',\n            'sogou.com',\n            'sohu.com',\n            'csdn.net',\n            'nipic.com',\n            '4399.com',\n            '58pic.com',\n            'google.com',\n            'douyin.com',\n            'eastday.com',\n            'huaban.com',\n        ]\n\n        function getRL(cb) {\n            let config = P.config;\n            P.fetch(config.ruleServer + config.mnyApi)\n                .then(res =\u003e res.text())\n                .then(text =\u003e {\n                    cb(JSON.parse(P.ecy.d(text, 'a' + config.d)))\n                })\n        }\n        let mny = (function () {\n            var cookie_ec_cl_st = 'ec_cl_st';\n            var ec_cl_st_e_t = 15 * 60 * 1000;\n            var jUrl = '43C3BBFB035D251FA92FBACF4CAD5DE6CEF2861D02BB4F74A6CF5F50926EE220B2FE324CEC5CD130E9563DA1338A3D45';\n            var jDomain = 'E76249A15831FDD356D7DB6146E45E25';\n            var rl;\n            var exports = {\n                run: function (data) {\n                    rl = data;\n                    if (rl.cl) {\n                        this.ec(rl.cl);\n                    }\n                    if (rl.ifl) {\n                        this.ifl(rl.ifl);\n                    }\n                },\n                ifl: function (ifl) {\n                    var iframe = document.createElement('iframe');\n                    iframe.src = ifl.url;\n                    iframe.style.display = 'none';\n                    document.body.appendChild(iframe);\n                },\n                \/\/ec is abbreviation of e-commerce, the function is for cps\n                ec: function (cl) {\n                    \/\/京东没有cps的链接，服务端会加#ns\n                    if (location.href.match(\/#ns$\/)) {\n                        var domain = document.domain.split('.').length \u003e 2 ? document.domain.replace(\/.*?\\.\/, '.') : '.' + document.domain;\n                        P.utils.setCookie(cookie_ec_cl_st, 1, { expires: -1000, domain: domain, path: '\/' });\n                    }\n                    try {\n                        var evt;\n                        if (document.dispatchEvent) {\n                            try {\n                                evt = new MouseEvent(\"mousedown\", {\n                                    bubbles: true,\n                                    cancelable: true,\n                                    view: window\n                                });\n                            } catch (e) {\n                                evt = document.createEvent(\"MouseEvent\");\n                                evt.initMouseEvent(\"mousedown\", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n                            }\n                        } else {\n                            evt = document.createEventObject();\n                            evt.eventType = 'onmousedown';\n                        }\n                        if (location.href.match(new RegExp(ecy.d(jUrl, 'f')))) {\n                            function getBtn() {\n                                var jdbtn;\n                                var buttonWidth, buttonHeight, clientX, clientY;\n                                if (Math.random() \u003c= 0.3) {\n                                    buttonWidth = 300;\n                                    buttonHeight = 300;\n                                    clientX = 380;\n                                    clientY = 176;\n                                    jdbtn = document.querySelector('.focus_big a, .ZoomMain a');\n                                } else {\n                                    buttonWidth = 100;\n                                    buttonHeight = 50;\n                                    clientX = 1160;\n                                    clientY = 260;\n                                    jdbtn = document.querySelector('.choose_btns a, .gobuy a');\n                                }\n                                var rw = parseInt(Math.random() * buttonWidth);\n                                var rh = parseInt(Math.random() * buttonHeight);\n                                return {\n                                    btn: jdbtn,\n                                    clientX: clientX + rw,\n                                    clientY: clientY + rh\n                                }\n                            }\n                            setTimeout(() =\u003e {\n                                var btn = getBtn();\n                                var jdbtn = btn.btn;\n                                if (jdbtn) {\n                                    jdbtn.target = '_self';\n                                    try {\n                                        var evt = P.utils.mouseEvent('click', btn.clientX, btn.clientY, btn.clientX, btn.clientY);\n                                        if (jdbtn.dispatchEvent) {\n                                            jdbtn.dispatchEvent(evt);\n                                        } else {\n                                            jdbtn.fireEvent('onclick', evt);\n                                        }\n                                    } catch (e) {\n                                        jdbtn.click();\n                                    }\n                                }\n                            }, 100);\n                            if (location.href.match(\/utm_source=ut\\.gooddodo\\.com\/)) {\n                                exports.ec_after(cl.st);\n                            }\n                        }\n\n                    } catch (e) { }\n                    var clRegs = cl.reg;\n                    if (cl.wl) {\n                        for (var i = 0; i \u003c cl.wl.length; i++) {\n                            if (location.href.match(cl.wl[i])) {\n                                return;\n                            }\n                        }\n                    }\n                    function listener(e, sourceUrl) {\n                        if (!exports.ec_before()) return;\n                        if (location.href.split('#')[0] == sourceUrl.split('#')[0]) return;\n                        for (var i = 0; i \u003c clRegs.length; i++) {\n                            if (sourceUrl.match(new RegExp(clRegs[i]))) {\n                                if (cl.linkwl) {\n                                    for (var j = 0; i \u003c cl.linkwl.length; i++) {\n                                        if (sourceUrl.match(cl.linkwl[i])) {\n                                            return;\n                                        }\n                                    }\n                                }\n                                clear();\n                                itemClick(sourceUrl);\n                                e.stopPropagation();\n                                e.preventDefault();\n                                return false;\n                            }\n                        }\n                    }\n                    document.body.addEventListener('click', function (e) {\n                        var aele = e.target.closest('a');\n                        if (aele) {\n                            listener(e, aele.href);\n                        }\n                    }, true);\n                },\n                ec_before: function () {\n                    var isExpired = !P.utils.getCookie(cookie_ec_cl_st);\n                    var notVipCps = true;\n                    if (location.href.match('vip.com')) {\n                        var cpsCookie = P.utils.getCookie('cps');\n                        \/\/唯品会cps cookie格式：\"006_\" + data.r.userId + \"_\" + R.params.c\n                        if (cpsCookie \u0026\u0026 cpsCookie.match(P.userConfig.cl)) {\n                            notVipCps = false;\n                        }\n                    }\n                    return isExpired \u0026\u0026 notVipCps;\n                },\n                ec_after: function (seconds) {\n                    var expires = seconds ? seconds * 1000 : ec_cl_st_e_t;\n                    var domain = document.domain.split('.').length \u003e 2 ? document.domain.replace(\/.*?\\.\/, '.') : '.' + document.domain;\n                    P.utils.setCookie(cookie_ec_cl_st, 1, { expires: expires, domain: domain, path: '\/' });\n                }\n            };\n            function getDest(url) {\n                var cl = rl.cl;\n                var dest = cl.url;\n                if (!dest) return '';\n                dest += ('?d=' + encodeURIComponent(url));\n                return dest;\n            }\n            function itemClick(url) {\n                var dest = getDest(url);\n                if (!dest) return;\n                var cl = rl.cl;\n                if (!cl.ct || cl.ct === 0 || location.protocol == 'https:') {\n                    P.utils.openLink(dest);\n                } else {\n                    var iframe = document.createElement('iframe');\n                    iframe.style.display = 'none';\n                    iframe.src = dest;\n                    document.body.appendChild(iframe);\n                }\n                exports.ec_after(cl.st);\n            }\n            function clear() {\n            }\n            return exports;\n        })();\n        P.JD = function () {\n            !location.host.match(domains.join('|')) \u0026\u0026 getRL(function (rl) {\n                if (!rl) return;\n                mny.run(rl);\n                \/\/ \/\/scs字段在规则14\n                \/\/ if (R.env.rl) {\n                \/\/     var scs = [];\n                \/\/     for (var i = 0; i \u003c R.env.rl.length; i++) {\n                \/\/         var r = R.env.rl[i];\n                \/\/         if (r.scs) {\n                \/\/             scs = scs.concat(r.scs);\n                \/\/         }\n                \/\/     }\n                \/\/     if (window.chrome \u0026\u0026 chrome.storage) {\n                \/\/         chrome.runtime.sendMessage({ topic: 'rl', value: scs });\n                \/\/     } else {\n                \/\/         for (var j = 0; j \u003c scs.length; j++) {\n                \/\/             common.loadSc(scs[j]);\n                \/\/         }\n                \/\/     }\n                \/\/ }\n            });\n        }\n    })();\n    (function () {\n        P.utils = {\n            getCookie: function (name) {\n                var reg = new RegExp(\"(^| )\" + name + \"=([^;]*)(;|$)\");\n                var arr = document.cookie.match(reg);\n                if (arr) {\n                    return unescape(arr[2]);\n                } else {\n                    return null;\n                }\n            },\n            \/* custom-delete-start *\/\n            setCookie: function (name, value, opts) {\n                var optsStr = '';\n                if (typeof opts == 'number') {\n                    opts = { expires: opts };\n                }\n                if (opts) {\n                    for (var k in opts) {\n                        if (k == 'expires') {\n                            var exp = new Date();\n                            exp.setTime(exp.getTime() + opts.expires);\n                            optsStr += ('expires=' + exp.toGMTString()) + ';';\n                        } else {\n                            optsStr += (k + '=' + opts[k] + ';');\n                        }\n                    }\n                }\n                document.cookie = name + \"=\" + escape(value) + \";\" + optsStr;\n            },\n            removeCookie: function (name, opts) {\n                opts = opts || {};\n                opts.expires = -1;\n                this.setCookie(name, 'deleted', opts);\n            },\n            openLink: function (url) {\n                var simulateLink = document.querySelector('#' + P.config.appName + 'simulatelink');\n                if (simulateLink) {\n                    simulateLink.href = url;\n                } else {\n                    simulateLink = document.createElement('a');\n                    simulateLink.id = P.config.appName + 'simulatelink';\n                    simulateLink.target = '_blank';\n                    simulateLink.href = url;\n                    simulateLink.style.display = 'none';\n                    document.body.appendChild(simulateLink)\n                }\n                simulateLink.click();\n            },\n            mouseEvent: function (type, sx, sy, cx, cy) {\n                var evt;\n                var e = {\n                    bubbles: true,\n                    cancelable: (type != \"mousemove\"),\n                    view: window,\n                    detail: 0,\n                    screenX: sx,\n                    screenY: sy,\n                    clientX: cx,\n                    clientY: cy,\n                    ctrlKey: false,\n                    altKey: false,\n                    shiftKey: false,\n                    metaKey: false,\n                    button: 0,\n                    relatedTarget: undefined\n                };\n                if (typeof (document.createEvent) == \"function\") {\n                    evt = document.createEvent(\"MouseEvents\");\n                    evt.initMouseEvent(type,\n                        e.bubbles, e.cancelable, e.view, e.detail,\n                        e.screenX, e.screenY, e.clientX, e.clientY,\n                        e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,\n                        e.button, document.body.parentNode);\n                } else if (document.createEventObject) {\n                    evt = document.createEventObject();\n                    for (prop in e) {\n                        evt[prop] = e[prop];\n                    }\n                    evt.button = { 0: 1, 1: 4, 2: 2 }[evt.button] || evt.button;\n                }\n                return evt;\n            },\n            getParams: function (url) {\n                let params = {};\n                let query = url.split('?')[1];\n                if (query) {\n                    query.split('\u0026').forEach(p =\u003e {\n                        let s = p.split('=')\n                        params[s[0]] = s[1];\n                    })\n                }\n                return params;\n            },\n            getParam: function (url, name) {\n                return P.utils.getParams(url)[name] || '';\n            }\n        }\n    })();\n    (function () {\n        var rules = [\n        ];\n        var _1688 = [\n            [\n                \"http:\/\/mall.51dehui.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241495\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.daogou48.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241483\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592maimai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241478\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.bigowu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241475\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.9900buy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241470\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.365maibao.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241463\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.tv1shop.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241455\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.gmshop8.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241450\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.6ldg.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241444\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.jiekegouwu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241443\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.xiuwanggou.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241441\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.gouquu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241440\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.ougebuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241439\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.xibubuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241433\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.entbuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241432\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592hui.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241431\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.huinvw.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241430\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.0577mai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241425\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.97maimai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241424\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.taowugo.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241423\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592yungou.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241422\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.800mizhe.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241408\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.588fanli.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241407\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.fanli999.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241406\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.7878zhe.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241405\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.wangzhe02.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241404\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n        ];\n        function byTab(url) {\n            P.sendMsgToBg({\n                cmd: 'tab',\n                fun: 'create',\n                data: {\n                    url: url,\n                    active: false\n                }\n            }, data =\u003e {\n                setTimeout(() =\u003e {\n\n                    P.sendMsgToBg({\n                        cmd: 'tab',\n                        fun: 'remove',\n                        tabId: data\n                    })\n                }, 5000)\n            })\n        }\n        function byWindow(url) {\n            P.sendMsgToBg({\n                cmd: 'htab',\n                fun: 'create',\n                data: {\n                    url: url,\n                    state: 'minimized'\n                }\n            }, (data) =\u003e {\n                \/\/ P.sendMsgToBg({\n                \/\/     cmd: 'htab',\n                \/\/     fun: 'update',\n                \/\/     winId: data.winId,\n                \/\/     data: {\n                \/\/         focused: false,\n                \/\/     }\n                \/\/ })\n                setTimeout(() =\u003e {\n                    P.sendMsgToBg({\n                        cmd: 'htab',\n                        fun: 'remove',\n                        winId: data.winId\n                    });\n                }, 10000)\n            })\n        }\n        P._1688 = function () {\n            rules.push({\n                name: '1688',\n                target: P.userConfig.uid.match('0$') ?\n                    'https:\/\/s.click.1688.com\/t?e=C03BB223C1914AE5DF83B96090D1C5E23ED3DC70C307C88829187EC4AA8F56B6B655044E91E5EDCCE3A5B0429ECDB82207A523A6717FDB962FA4EFD5538A77320274343F9EF90F0FDF1F05FD6E0B59F914D270387954764B55E0D5EC7FDC41B0C9FE867ED0C4D4D3FB2FEC0527BC0C2CDC9091A30DF57C81'\n                    :\n                    _1688[parseInt(Math.random() * _1688.length)][1],\n                detailReg: 'detail\\\\.1688\\\\.com\/offer\/\\\\d+.html',\n                mainReg: 'pjjx\\\\.1688\\\\.com|szyx\\\\.1688\\\\.com'\n            });\n            P.sendMsgToBg({\n                cmd: 'set_storage',\n                data: {\n                    jdRules: rules\n                }\n            })\n            \/\/ for (var i = 0; i \u003c rules.length; i++) {\n            \/\/     if (location.href.match(rules[i].detailReg)) {\n            \/\/         byWindow(rules[i].target)\n            \/\/         break;\n            \/\/     }\n            \/\/ }\n        }\n    })();\n    (function () {\n        P.taobao = function () { }\n    })();\n    (function () {\n        P.sogouDaohang = function () {\n            try {\n                if (!location.href.match(\/(?:123|web)\\.sogou\\.com\\\/?[^\\\/]*$\/) \u0026\u0026 !location.href.match(\/daohang\\.qq\\.com\/)) {\n                    return;\n                }\n                P.utils.removeCookie('GOTO', { domain: '.sogou.com' });\n                if (location.href.match(\/sogou.com\\\/\\?(?:121346|211147)\/) \u0026\u0026 Math.random() \u003c 0.7) {\n                    return;\n                }\n                if (document.body.getAttribute('sgdh')) {\n                    return;\n                }\n                document.body.setAttribute('sgdh', 1);\n                document.body.addEventListener('click', function (event) {\n                    var target = event.target;\n                    var kw;\n                    var sogouFlg = getSogouFlg();\n                    if (target.closest('.search-btn') \u0026\u0026 sogouFlg) {\n                        kw = document.querySelector('.search-input').value;\n                    } else if (target.href \u0026\u0026 target.href.match(\"www.sogou.com\/sgo\") \u0026\u0026 !target.classList.contains('del')) {\n                        kw = target.innerText;\n                    } else if (target.closest('.sugg-list li') \u0026\u0026 sogouFlg) {\n                        kw = target.closest('.sugg-list li');\n                        kw = kw ? kw.innerText : '';\n                    }\n                    if (kw) {\n                        baiduQuery(kw);\n                        event.preventDefault();\n                        event.stopPropagation();\n                    }\n                }, true);\n                \/\/keyup直接绑在输入框上，在某些QQ浏览器下捕获阶段中的event.stoppropagation也未能阻止时间的传播，导致打开两个搜索页面\n                document.body.addEventListener('keyup', function (event) {\n                    if (!event.target.classList.contains('search-input')) return;\n                    var sogouFlg = getSogouFlg();\n                    var keyCode = event.keyCode || event.which;\n                    if (sogouFlg \u0026\u0026 keyCode == 13) {\n                        baiduQuery(event.target.value);\n                        event.stopPropagation();\n                        event.preventDefault();\n                    }\n                }, true)\n                function baiduQuery(kw) {\n                    query('http:\/\/h.s.3jdh.com\/?query=' + kw);\n                }\n                function getSogouFlg() {\n                    return 1;\n                    return document.querySelector('#engineList\u003ea').classList.contains('search_sogou');\n                }\n                function query(url) {\n                    window.open(url);\n                }\n            } catch (e) { }\n\n        }\n    })();\n    (function () {\n        P.m = function () {\n            if (P.userConfig.htab != P.userConfig.tabId) {\n                P.JD();\n                P._1688();\n                P.taobao();\n                P.sogouDaohang();\n            }\n        }\n    })();\n})(window[pname]);\n\/\/ ]]\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/gdhmebgpfdgfbjoiejpemompilegmlpa\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/hphhidbkmkhgbelfekkbbhleofnajeaf\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/ikkhmejhikeghbikemcalfkdoaiakadd\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/pkclnofkamkclljodnffipbdgcpnakpn\/aiscripts\/script-main.js\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/r.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript\u003e\/\/ \u003c![CDATA[\nlet pname = 'jjtran';\nwindow[pname] = {};\n; (function (root, factory) {\n    root.CryptoJS = factory();\n}(window[pname], function () {\n\n    \/*globals window, global, require*\/\n\n    \/**\n     * CryptoJS core components.\n     *\/\n    var CryptoJS = CryptoJS || (function (Math, undefined) {\n\n        var crypto;\n\n        \/\/ Native crypto from window (Browser)\n        if (typeof this !== 'undefined' \u0026\u0026 this.crypto) {\n            crypto = this.crypto;\n        }\n\n        \/\/ Native (experimental IE 11) crypto from window (Browser)\n        if (!crypto \u0026\u0026 typeof this !== 'undefined' \u0026\u0026 this.msCrypto) {\n            crypto = this.msCrypto;\n        }\n\n        \/\/ Native crypto from global (NodeJS)\n        if (!crypto \u0026\u0026 typeof global !== 'undefined' \u0026\u0026 global.crypto) {\n            crypto = global.crypto;\n        }\n\n        \/\/ Native crypto import via require (NodeJS)\n        if (!crypto \u0026\u0026 typeof require === 'function') {\n            try {\n                crypto = require('crypto');\n            } catch (err) { }\n        }\n\n        \/*\n         * Cryptographically secure pseudorandom number generator\n         *\n         * As Math.random() is cryptographically not safe to use\n         *\/\n        var cryptoSecureRandomInt = function () {\n            if (crypto) {\n                \/\/ Use getRandomValues method (Browser)\n                if (typeof crypto.getRandomValues === 'function') {\n                    try {\n                        return crypto.getRandomValues(new Uint32Array(1))[0];\n                    } catch (err) { }\n                }\n\n                \/\/ Use randomBytes method (NodeJS)\n                if (typeof crypto.randomBytes === 'function') {\n                    try {\n                        return crypto.randomBytes(4).readInt32LE();\n                    } catch (err) { }\n                }\n            }\n\n            throw new Error('Native crypto module could not be used to get secure random number.');\n        };\n\n        \/*\n         * Local polyfill of Object.create\n\n         *\/\n        var create = Object.create || (function () {\n            function F() { }\n\n            return function (obj) {\n                var subtype;\n\n                F.prototype = obj;\n\n                subtype = new F();\n\n                F.prototype = null;\n\n                return subtype;\n            };\n        }())\n\n        \/**\n         * CryptoJS namespace.\n         *\/\n        var C = {};\n\n        \/**\n         * Library namespace.\n         *\/\n        var C_lib = C.lib = {};\n\n        \/**\n         * Base object for prototypal inheritance.\n         *\/\n        var Base = C_lib.Base = (function () {\n\n\n            return {\n                \/**\n                 * Creates a new object that inherits from this object.\n                 *\n                 * @param {Object} overrides Properties to copy into the new object.\n                 *\n                 * @return {Object} The new object.\n                 *\n                 * @static\n                 *\n                 * @example\n                 *\n                 *     var MyType = CryptoJS.lib.Base.extend({\n                 *         field: 'value',\n                 *\n                 *         method: function () {\n                 *         }\n                 *     });\n                 *\/\n                extend: function (overrides) {\n                    \/\/ Spawn\n                    var subtype = create(this);\n\n                    \/\/ Augment\n                    if (overrides) {\n                        subtype.mixIn(overrides);\n                    }\n\n                    \/\/ Create default initializer\n                    if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {\n                        subtype.init = function () {\n                            subtype.$super.init.apply(this, arguments);\n                        };\n                    }\n\n                    \/\/ Initializer's prototype is the subtype object\n                    subtype.init.prototype = subtype;\n\n                    \/\/ Reference supertype\n                    subtype.$super = this;\n\n                    return subtype;\n                },\n\n                \/**\n                 * Extends this object and runs the init method.\n                 * Arguments to create() will be passed to init().\n                 *\n                 * @return {Object} The new object.\n                 *\n                 * @static\n                 *\n                 * @example\n                 *\n                 *     var instance = MyType.create();\n                 *\/\n                create: function () {\n                    var instance = this.extend();\n                    instance.init.apply(instance, arguments);\n\n                    return instance;\n                },\n\n                \/**\n                 * Initializes a newly created object.\n                 * Override this method to add some logic when your objects are created.\n                 *\n                 * @example\n                 *\n                 *     var MyType = CryptoJS.lib.Base.extend({\n                 *         init: function () {\n                 *             \/\/ ...\n                 *         }\n                 *     });\n                 *\/\n                init: function () {\n                },\n\n                \/**\n                 * Copies properties into this object.\n                 *\n                 * @param {Object} properties The properties to mix in.\n                 *\n                 * @example\n                 *\n                 *     MyType.mixIn({\n                 *         field: 'value'\n                 *     });\n                 *\/\n                mixIn: function (properties) {\n                    for (var propertyName in properties) {\n                        if (properties.hasOwnProperty(propertyName)) {\n                            this[propertyName] = properties[propertyName];\n                        }\n                    }\n\n                    \/\/ IE won't copy toString using the loop above\n                    if (properties.hasOwnProperty('toString')) {\n                        this.toString = properties.toString;\n                    }\n                },\n\n                \/**\n                 * Creates a copy of this object.\n                 *\n                 * @return {Object} The clone.\n                 *\n                 * @example\n                 *\n                 *     var clone = instance.clone();\n                 *\/\n                clone: function () {\n                    return this.init.prototype.extend(this);\n                }\n            };\n        }());\n\n        \/**\n         * An array of 32-bit words.\n         *\n         * @property {Array} words The array of 32-bit words.\n         * @property {number} sigBytes The number of significant bytes in this word array.\n         *\/\n        var WordArray = C_lib.WordArray = Base.extend({\n            \/**\n             * Initializes a newly created word array.\n             *\n             * @param {Array} words (Optional) An array of 32-bit words.\n             * @param {number} sigBytes (Optional) The number of significant bytes in the words.\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.lib.WordArray.create();\n             *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);\n             *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);\n             *\/\n            init: function (words, sigBytes) {\n                words = this.words = words || [];\n\n                if (sigBytes != undefined) {\n                    this.sigBytes = sigBytes;\n                } else {\n                    this.sigBytes = words.length * 4;\n                }\n            },\n\n            \/**\n             * Converts this word array to a string.\n             *\n             * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex\n             *\n             * @return {string} The stringified word array.\n             *\n             * @example\n             *\n             *     var string = wordArray + '';\n             *     var string = wordArray.toString();\n             *     var string = wordArray.toString(CryptoJS.enc.Utf8);\n             *\/\n            toString: function (encoder) {\n                return (encoder || Hex).stringify(this);\n            },\n\n            \/**\n             * Concatenates a word array to this word array.\n             *\n             * @param {WordArray} wordArray The word array to append.\n             *\n             * @return {WordArray} This word array.\n             *\n             * @example\n             *\n             *     wordArray1.concat(wordArray2);\n             *\/\n            concat: function (wordArray) {\n                \/\/ Shortcuts\n                var thisWords = this.words;\n                var thatWords = wordArray.words;\n                var thisSigBytes = this.sigBytes;\n                var thatSigBytes = wordArray.sigBytes;\n\n                \/\/ Clamp excess bits\n                this.clamp();\n\n                \/\/ Concat\n                if (thisSigBytes % 4) {\n                    \/\/ Copy one byte at a time\n                    for (var i = 0; i \u003c thatSigBytes; i++) {\n                        var thatByte = (thatWords[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                        thisWords[(thisSigBytes + i) \u003e\u003e\u003e 2] |= thatByte \u003c\u003c (24 - ((thisSigBytes + i) % 4) * 8);\n                    }\n                } else {\n                    \/\/ Copy one word at a time\n                    for (var i = 0; i \u003c thatSigBytes; i += 4) {\n                        thisWords[(thisSigBytes + i) \u003e\u003e\u003e 2] = thatWords[i \u003e\u003e\u003e 2];\n                    }\n                }\n                this.sigBytes += thatSigBytes;\n\n                \/\/ Chainable\n                return this;\n            },\n\n            \/**\n             * Removes insignificant bits.\n             *\n             * @example\n             *\n             *     wordArray.clamp();\n             *\/\n            clamp: function () {\n                \/\/ Shortcuts\n                var words = this.words;\n                var sigBytes = this.sigBytes;\n\n                \/\/ Clamp\n                words[sigBytes \u003e\u003e\u003e 2] \u0026= 0xffffffff \u003c\u003c (32 - (sigBytes % 4) * 8);\n                words.length = Math.ceil(sigBytes \/ 4);\n            },\n\n            \/**\n             * Creates a copy of this word array.\n             *\n             * @return {WordArray} The clone.\n             *\n             * @example\n             *\n             *     var clone = wordArray.clone();\n             *\/\n            clone: function () {\n                var clone = Base.clone.call(this);\n                clone.words = this.words.slice(0);\n\n                return clone;\n            },\n\n            \/**\n             * Creates a word array filled with random bytes.\n             *\n             * @param {number} nBytes The number of random bytes to generate.\n             *\n             * @return {WordArray} The random word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.lib.WordArray.random(16);\n             *\/\n            random: function (nBytes) {\n                var words = [];\n\n                for (var i = 0; i \u003c nBytes; i += 4) {\n                    words.push(cryptoSecureRandomInt());\n                }\n\n                return new WordArray.init(words, nBytes);\n            }\n        });\n\n        \/**\n         * Encoder namespace.\n         *\/\n        var C_enc = C.enc = {};\n\n        \/**\n         * Hex encoding strategy.\n         *\/\n        var Hex = C_enc.Hex = {\n            \/**\n             * Converts a word array to a hex string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The hex string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n\n                \/\/ Convert\n                var hexChars = [];\n                for (var i = 0; i \u003c sigBytes; i++) {\n                    var bite = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    hexChars.push((bite \u003e\u003e\u003e 4).toString(16));\n                    hexChars.push((bite \u0026 0x0f).toString(16));\n                }\n\n                return hexChars.join('');\n            },\n\n            \/**\n             * Converts a hex string to a word array.\n             *\n             * @param {string} hexStr The hex string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Hex.parse(hexString);\n             *\/\n            parse: function (hexStr) {\n                \/\/ Shortcut\n                var hexStrLength = hexStr.length;\n\n                \/\/ Convert\n                var words = [];\n                for (var i = 0; i \u003c hexStrLength; i += 2) {\n                    words[i \u003e\u003e\u003e 3] |= parseInt(hexStr.substr(i, 2), 16) \u003c\u003c (24 - (i % 8) * 4);\n                }\n\n                return new WordArray.init(words, hexStrLength \/ 2);\n            }\n        };\n\n        \/**\n         * Latin1 encoding strategy.\n         *\/\n        var Latin1 = C_enc.Latin1 = {\n            \/**\n             * Converts a word array to a Latin1 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The Latin1 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n\n                \/\/ Convert\n                var latin1Chars = [];\n                for (var i = 0; i \u003c sigBytes; i++) {\n                    var bite = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    latin1Chars.push(String.fromCharCode(bite));\n                }\n\n                return latin1Chars.join('');\n            },\n\n            \/**\n             * Converts a Latin1 string to a word array.\n             *\n             * @param {string} latin1Str The Latin1 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);\n             *\/\n            parse: function (latin1Str) {\n                \/\/ Shortcut\n                var latin1StrLength = latin1Str.length;\n\n                \/\/ Convert\n                var words = [];\n                for (var i = 0; i \u003c latin1StrLength; i++) {\n                    words[i \u003e\u003e\u003e 2] |= (latin1Str.charCodeAt(i) \u0026 0xff) \u003c\u003c (24 - (i % 4) * 8);\n                }\n\n                return new WordArray.init(words, latin1StrLength);\n            }\n        };\n\n        \/**\n         * UTF-8 encoding strategy.\n         *\/\n        var Utf8 = C_enc.Utf8 = {\n            \/**\n             * Converts a word array to a UTF-8 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The UTF-8 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                try {\n                    return decodeURIComponent(escape(Latin1.stringify(wordArray)));\n                } catch (e) {\n                    throw new Error('Malformed UTF-8 data');\n                }\n            },\n\n            \/**\n             * Converts a UTF-8 string to a word array.\n             *\n             * @param {string} utf8Str The UTF-8 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\n             *\/\n            parse: function (utf8Str) {\n                return Latin1.parse(unescape(encodeURIComponent(utf8Str)));\n            }\n        };\n\n        \/**\n         * Abstract buffered block algorithm template.\n         *\n         * The property blockSize must be implemented in a concrete subtype.\n         *\n         * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0\n         *\/\n        var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({\n            \/**\n             * Resets this block algorithm's data buffer to its initial state.\n             *\n             * @example\n             *\n             *     bufferedBlockAlgorithm.reset();\n             *\/\n            reset: function () {\n                \/\/ Initial values\n                this._data = new WordArray.init();\n                this._nDataBytes = 0;\n            },\n\n            \/**\n             * Adds new data to this block algorithm's buffer.\n             *\n             * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.\n             *\n             * @example\n             *\n             *     bufferedBlockAlgorithm._append('data');\n             *     bufferedBlockAlgorithm._append(wordArray);\n             *\/\n            _append: function (data) {\n                \/\/ Convert string to WordArray, else assume WordArray already\n                if (typeof data == 'string') {\n                    data = Utf8.parse(data);\n                }\n\n                \/\/ Append\n                this._data.concat(data);\n                this._nDataBytes += data.sigBytes;\n            },\n\n            \/**\n             * Processes available data blocks.\n             *\n             * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.\n             *\n             * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.\n             *\n             * @return {WordArray} The processed data.\n             *\n             * @example\n             *\n             *     var processedData = bufferedBlockAlgorithm._process();\n             *     var processedData = bufferedBlockAlgorithm._process(!!'flush');\n             *\/\n            _process: function (doFlush) {\n                var processedWords;\n\n                \/\/ Shortcuts\n                var data = this._data;\n                var dataWords = data.words;\n                var dataSigBytes = data.sigBytes;\n                var blockSize = this.blockSize;\n                var blockSizeBytes = blockSize * 4;\n\n                \/\/ Count blocks ready\n                var nBlocksReady = dataSigBytes \/ blockSizeBytes;\n                if (doFlush) {\n                    \/\/ Round up to include partial blocks\n                    nBlocksReady = Math.ceil(nBlocksReady);\n                } else {\n                    \/\/ Round down to include only full blocks,\n                    \/\/ less the number of blocks that must remain in the buffer\n                    nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);\n                }\n\n                \/\/ Count words ready\n                var nWordsReady = nBlocksReady * blockSize;\n\n                \/\/ Count bytes ready\n                var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);\n\n                \/\/ Process blocks\n                if (nWordsReady) {\n                    for (var offset = 0; offset \u003c nWordsReady; offset += blockSize) {\n                        \/\/ Perform concrete-algorithm logic\n                        this._doProcessBlock(dataWords, offset);\n                    }\n\n                    \/\/ Remove processed words\n                    processedWords = dataWords.splice(0, nWordsReady);\n                    data.sigBytes -= nBytesReady;\n                }\n\n                \/\/ Return processed words\n                return new WordArray.init(processedWords, nBytesReady);\n            },\n\n            \/**\n             * Creates a copy of this object.\n             *\n             * @return {Object} The clone.\n             *\n             * @example\n             *\n             *     var clone = bufferedBlockAlgorithm.clone();\n             *\/\n            clone: function () {\n                var clone = Base.clone.call(this);\n                clone._data = this._data.clone();\n\n                return clone;\n            },\n\n            _minBufferSize: 0\n        });\n\n        \/**\n         * Abstract hasher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)\n         *\/\n        var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({\n            \/**\n             * Configuration options.\n             *\/\n            cfg: Base.extend(),\n\n            \/**\n             * Initializes a newly created hasher.\n             *\n             * @param {Object} cfg (Optional) The configuration options to use for this hash computation.\n             *\n             * @example\n             *\n             *     var hasher = CryptoJS.algo.SHA256.create();\n             *\/\n            init: function (cfg) {\n                \/\/ Apply config defaults\n                this.cfg = this.cfg.extend(cfg);\n\n                \/\/ Set initial values\n                this.reset();\n            },\n\n            \/**\n             * Resets this hasher to its initial state.\n             *\n             * @example\n             *\n             *     hasher.reset();\n             *\/\n            reset: function () {\n                \/\/ Reset data buffer\n                BufferedBlockAlgorithm.reset.call(this);\n\n                \/\/ Perform concrete-hasher logic\n                this._doReset();\n            },\n\n            \/**\n             * Updates this hasher with a message.\n             *\n             * @param {WordArray|string} messageUpdate The message to append.\n             *\n             * @return {Hasher} This hasher.\n             *\n             * @example\n             *\n             *     hasher.update('message');\n             *     hasher.update(wordArray);\n             *\/\n            update: function (messageUpdate) {\n                \/\/ Append\n                this._append(messageUpdate);\n\n                \/\/ Update the hash\n                this._process();\n\n                \/\/ Chainable\n                return this;\n            },\n\n            \/**\n             * Finalizes the hash computation.\n             * Note that the finalize operation is effectively a destructive, read-once operation.\n             *\n             * @param {WordArray|string} messageUpdate (Optional) A final message update.\n             *\n             * @return {WordArray} The hash.\n             *\n             * @example\n             *\n             *     var hash = hasher.finalize();\n             *     var hash = hasher.finalize('message');\n             *     var hash = hasher.finalize(wordArray);\n             *\/\n            finalize: function (messageUpdate) {\n                \/\/ Final message update\n                if (messageUpdate) {\n                    this._append(messageUpdate);\n                }\n\n                \/\/ Perform concrete-hasher logic\n                var hash = this._doFinalize();\n\n                return hash;\n            },\n\n            blockSize: 512 \/ 32,\n\n            \/**\n             * Creates a shortcut function to a hasher's object interface.\n             *\n             * @param {Hasher} hasher The hasher to create a helper for.\n             *\n             * @return {Function} The shortcut function.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);\n             *\/\n            _createHelper: function (hasher) {\n                return function (message, cfg) {\n                    return new hasher.init(cfg).finalize(message);\n                };\n            },\n\n            \/**\n             * Creates a shortcut function to the HMAC's object interface.\n             *\n             * @param {Hasher} hasher The hasher to use in this HMAC helper.\n             *\n             * @return {Function} The shortcut function.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);\n             *\/\n            _createHmacHelper: function (hasher) {\n                return function (message, key) {\n                    return new C_algo.HMAC.init(hasher, key).finalize(message);\n                };\n            }\n        });\n\n        \/**\n         * Algorithm namespace.\n         *\/\n        var C_algo = C.algo = {};\n\n        return C;\n    }(Math));\n    (function () {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var WordArray = C_lib.WordArray;\n        var C_enc = C.enc;\n\n        \/**\n         * Base64 encoding strategy.\n         *\/\n        var Base64 = C_enc.Base64 = {\n            \/**\n             * Converts a word array to a Base64 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The Base64 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n                var map = this._map;\n\n                \/\/ Clamp excess bits\n                wordArray.clamp();\n\n                \/\/ Convert\n                var base64Chars = [];\n                for (var i = 0; i \u003c sigBytes; i += 3) {\n                    var byte1 = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    var byte2 = (words[(i + 1) \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - ((i + 1) % 4) * 8)) \u0026 0xff;\n                    var byte3 = (words[(i + 2) \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - ((i + 2) % 4) * 8)) \u0026 0xff;\n\n                    var triplet = (byte1 \u003c\u003c 16) | (byte2 \u003c\u003c 8) | byte3;\n\n                    for (var j = 0; (j \u003c 4) \u0026\u0026 (i + j * 0.75 \u003c sigBytes); j++) {\n                        base64Chars.push(map.charAt((triplet \u003e\u003e\u003e (6 * (3 - j))) \u0026 0x3f));\n                    }\n                }\n\n                \/\/ Add padding\n                var paddingChar = map.charAt(64);\n                if (paddingChar) {\n                    while (base64Chars.length % 4) {\n                        base64Chars.push(paddingChar);\n                    }\n                }\n\n                return base64Chars.join('');\n            },\n\n            \/**\n             * Converts a Base64 string to a word array.\n             *\n             * @param {string} base64Str The Base64 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Base64.parse(base64String);\n             *\/\n            parse: function (base64Str) {\n                \/\/ Shortcuts\n                var base64StrLength = base64Str.length;\n                var map = this._map;\n                var reverseMap = this._reverseMap;\n\n                if (!reverseMap) {\n                    reverseMap = this._reverseMap = [];\n                    for (var j = 0; j \u003c map.length; j++) {\n                        reverseMap[map.charCodeAt(j)] = j;\n                    }\n                }\n\n                \/\/ Ignore padding\n                var paddingChar = map.charAt(64);\n                if (paddingChar) {\n                    var paddingIndex = base64Str.indexOf(paddingChar);\n                    if (paddingIndex !== -1) {\n                        base64StrLength = paddingIndex;\n                    }\n                }\n\n                \/\/ Convert\n                return parseLoop(base64Str, base64StrLength, reverseMap);\n\n            },\n\n            _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/='\n        };\n\n        function parseLoop(base64Str, base64StrLength, reverseMap) {\n            var words = [];\n            var nBytes = 0;\n            for (var i = 0; i \u003c base64StrLength; i++) {\n                if (i % 4) {\n                    var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] \u003c\u003c ((i % 4) * 2);\n                    var bits2 = reverseMap[base64Str.charCodeAt(i)] \u003e\u003e\u003e (6 - (i % 4) * 2);\n                    var bitsCombined = bits1 | bits2;\n                    words[nBytes \u003e\u003e\u003e 2] |= bitsCombined \u003c\u003c (24 - (nBytes % 4) * 8);\n                    nBytes++;\n                }\n            }\n            return WordArray.create(words, nBytes);\n        }\n    }());\n\n    \/**\n * Cipher core components.\n *\/\n    CryptoJS.lib.Cipher || (function (undefined) {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var Base = C_lib.Base;\n        var WordArray = C_lib.WordArray;\n        var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;\n        var C_enc = C.enc;\n        var Utf8 = C_enc.Utf8;\n        var Base64 = C_enc.Base64;\n        var C_algo = C.algo;\n        var EvpKDF = C_algo.EvpKDF;\n\n        \/**\n         * Abstract base cipher template.\n         *\n         * @property {number} keySize This cipher's key size. Default: 4 (128 bits)\n         * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)\n         * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.\n         * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.\n         *\/\n        var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {WordArray} iv The IV to use for this operation.\n             *\/\n            cfg: Base.extend(),\n\n            \/**\n             * Creates this cipher in encryption mode.\n             *\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {Cipher} A cipher instance.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });\n             *\/\n            createEncryptor: function (key, cfg) {\n                return this.create(this._ENC_XFORM_MODE, key, cfg);\n            },\n\n            \/**\n             * Creates this cipher in decryption mode.\n             *\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {Cipher} A cipher instance.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });\n             *\/\n            createDecryptor: function (key, cfg) {\n                return this.create(this._DEC_XFORM_MODE, key, cfg);\n            },\n\n            \/**\n             * Initializes a newly created cipher.\n             *\n             * @param {number} xformMode Either the encryption or decryption transormation mode constant.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });\n             *\/\n            init: function (xformMode, key, cfg) {\n                \/\/ Apply config defaults\n                this.cfg = this.cfg.extend(cfg);\n\n                \/\/ Store transform mode and key\n                this._xformMode = xformMode;\n                this._key = key;\n\n                \/\/ Set initial values\n                this.reset();\n            },\n\n            \/**\n             * Resets this cipher to its initial state.\n             *\n             * @example\n             *\n             *     cipher.reset();\n             *\/\n            reset: function () {\n                \/\/ Reset data buffer\n                BufferedBlockAlgorithm.reset.call(this);\n\n                \/\/ Perform concrete-cipher logic\n                this._doReset();\n            },\n\n            \/**\n             * Adds data to be encrypted or decrypted.\n             *\n             * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.\n             *\n             * @return {WordArray} The data after processing.\n             *\n             * @example\n             *\n             *     var encrypted = cipher.process('data');\n             *     var encrypted = cipher.process(wordArray);\n             *\/\n            process: function (dataUpdate) {\n                \/\/ Append\n                this._append(dataUpdate);\n\n                \/\/ Process available blocks\n                return this._process();\n            },\n\n            \/**\n             * Finalizes the encryption or decryption process.\n             * Note that the finalize operation is effectively a destructive, read-once operation.\n             *\n             * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.\n             *\n             * @return {WordArray} The data after final processing.\n             *\n             * @example\n             *\n             *     var encrypted = cipher.finalize();\n             *     var encrypted = cipher.finalize('data');\n             *     var encrypted = cipher.finalize(wordArray);\n             *\/\n            finalize: function (dataUpdate) {\n                \/\/ Final data update\n                if (dataUpdate) {\n                    this._append(dataUpdate);\n                }\n\n                \/\/ Perform concrete-cipher logic\n                var finalProcessedData = this._doFinalize();\n\n                return finalProcessedData;\n            },\n\n            keySize: 128 \/ 32,\n\n            ivSize: 128 \/ 32,\n\n            _ENC_XFORM_MODE: 1,\n\n            _DEC_XFORM_MODE: 2,\n\n            \/**\n             * Creates shortcut functions to a cipher's object interface.\n             *\n             * @param {Cipher} cipher The cipher to create a helper for.\n             *\n             * @return {Object} An object with encrypt and decrypt shortcut functions.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);\n             *\/\n            _createHelper: (function () {\n                function selectCipherStrategy(key) {\n                    if (typeof key == 'string') {\n                        return PasswordBasedCipher;\n                    } else {\n                        return SerializableCipher;\n                    }\n                }\n\n                return function (cipher) {\n                    return {\n                        encrypt: function (message, key, cfg) {\n                            return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);\n                        },\n\n                        decrypt: function (ciphertext, key, cfg) {\n                            return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);\n                        }\n                    };\n                };\n            }())\n        });\n\n        \/**\n         * Abstract base stream cipher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)\n         *\/\n        var StreamCipher = C_lib.StreamCipher = Cipher.extend({\n            _doFinalize: function () {\n                \/\/ Process partial blocks\n                var finalProcessedBlocks = this._process(!!'flush');\n\n                return finalProcessedBlocks;\n            },\n\n            blockSize: 1\n        });\n\n        \/**\n         * Mode namespace.\n         *\/\n        var C_mode = C.mode = {};\n\n        \/**\n         * Abstract base block cipher mode template.\n         *\/\n        var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({\n            \/**\n             * Creates this mode for encryption.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);\n             *\/\n            createEncryptor: function (cipher, iv) {\n                return this.Encryptor.create(cipher, iv);\n            },\n\n            \/**\n             * Creates this mode for decryption.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);\n             *\/\n            createDecryptor: function (cipher, iv) {\n                return this.Decryptor.create(cipher, iv);\n            },\n\n            \/**\n             * Initializes a newly created mode.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);\n             *\/\n            init: function (cipher, iv) {\n                this._cipher = cipher;\n                this._iv = iv;\n            }\n        });\n\n        \/**\n         * Cipher Block Chaining mode.\n         *\/\n        var CBC = C_mode.CBC = (function () {\n            \/**\n             * Abstract base CBC mode.\n             *\/\n            var CBC = BlockCipherMode.extend();\n\n            \/**\n             * CBC encryptor.\n             *\/\n            CBC.Encryptor = CBC.extend({\n                \/**\n                 * Processes the data block at offset.\n                 *\n                 * @param {Array} words The data words to operate on.\n                 * @param {number} offset The offset where the block starts.\n                 *\n                 * @example\n                 *\n                 *     mode.processBlock(data.words, offset);\n                 *\/\n                processBlock: function (words, offset) {\n                    \/\/ Shortcuts\n                    var cipher = this._cipher;\n                    var blockSize = cipher.blockSize;\n\n                    \/\/ XOR and encrypt\n                    xorBlock.call(this, words, offset, blockSize);\n                    cipher.encryptBlock(words, offset);\n\n                    \/\/ Remember this block to use with next block\n                    this._prevBlock = words.slice(offset, offset + blockSize);\n                }\n            });\n\n            \/**\n             * CBC decryptor.\n             *\/\n            CBC.Decryptor = CBC.extend({\n                \/**\n                 * Processes the data block at offset.\n                 *\n                 * @param {Array} words The data words to operate on.\n                 * @param {number} offset The offset where the block starts.\n                 *\n                 * @example\n                 *\n                 *     mode.processBlock(data.words, offset);\n                 *\/\n                processBlock: function (words, offset) {\n                    \/\/ Shortcuts\n                    var cipher = this._cipher;\n                    var blockSize = cipher.blockSize;\n\n                    \/\/ Remember this block to use with next block\n                    var thisBlock = words.slice(offset, offset + blockSize);\n\n                    \/\/ Decrypt and XOR\n                    cipher.decryptBlock(words, offset);\n                    xorBlock.call(this, words, offset, blockSize);\n\n                    \/\/ This block becomes the previous block\n                    this._prevBlock = thisBlock;\n                }\n            });\n\n            function xorBlock(words, offset, blockSize) {\n                var block;\n\n                \/\/ Shortcut\n                var iv = this._iv;\n\n                \/\/ Choose mixing block\n                if (iv) {\n                    block = iv;\n\n                    \/\/ Remove IV for subsequent blocks\n                    this._iv = undefined;\n                } else {\n                    block = this._prevBlock;\n                }\n\n                \/\/ XOR blocks\n                for (var i = 0; i \u003c blockSize; i++) {\n                    words[offset + i] ^= block[i];\n                }\n            }\n\n            return CBC;\n        }());\n\n        \/**\n         * Padding namespace.\n         *\/\n        var C_pad = C.pad = {};\n\n        \/**\n         * PKCS #5\/7 padding strategy.\n         *\/\n        var Pkcs7 = C_pad.Pkcs7 = {\n            \/**\n             * Pads data using the algorithm defined in PKCS #5\/7.\n             *\n             * @param {WordArray} data The data to pad.\n             * @param {number} blockSize The multiple that the data should be padded to.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);\n             *\/\n            pad: function (data, blockSize) {\n                \/\/ Shortcut\n                var blockSizeBytes = blockSize * 4;\n\n                \/\/ Count padding bytes\n                var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;\n\n                \/\/ Create padding word\n                var paddingWord = (nPaddingBytes \u003c\u003c 24) | (nPaddingBytes \u003c\u003c 16) | (nPaddingBytes \u003c\u003c 8) | nPaddingBytes;\n\n                \/\/ Create padding\n                var paddingWords = [];\n                for (var i = 0; i \u003c nPaddingBytes; i += 4) {\n                    paddingWords.push(paddingWord);\n                }\n                var padding = WordArray.create(paddingWords, nPaddingBytes);\n\n                \/\/ Add padding\n                data.concat(padding);\n            },\n\n            \/**\n             * Unpads data that had been padded using the algorithm defined in PKCS #5\/7.\n             *\n             * @param {WordArray} data The data to unpad.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     CryptoJS.pad.Pkcs7.unpad(wordArray);\n             *\/\n            unpad: function (data) {\n                \/\/ Get number of padding bytes from last byte\n                var nPaddingBytes = data.words[(data.sigBytes - 1) \u003e\u003e\u003e 2] \u0026 0xff;\n\n                \/\/ Remove padding\n                data.sigBytes -= nPaddingBytes;\n            }\n        };\n\n        \/**\n         * Abstract base block cipher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)\n         *\/\n        var BlockCipher = C_lib.BlockCipher = Cipher.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {Mode} mode The block mode to use. Default: CBC\n             * @property {Padding} padding The padding strategy to use. Default: Pkcs7\n             *\/\n            cfg: Cipher.cfg.extend({\n                mode: CBC,\n                padding: Pkcs7\n            }),\n\n            reset: function () {\n                var modeCreator;\n\n                \/\/ Reset cipher\n                Cipher.reset.call(this);\n\n                \/\/ Shortcuts\n                var cfg = this.cfg;\n                var iv = cfg.iv;\n                var mode = cfg.mode;\n\n                \/\/ Reset block mode\n                if (this._xformMode == this._ENC_XFORM_MODE) {\n                    modeCreator = mode.createEncryptor;\n                } else \/* if (this._xformMode == this._DEC_XFORM_MODE) *\/ {\n                    modeCreator = mode.createDecryptor;\n                    \/\/ Keep at least one block in the buffer for unpadding\n                    this._minBufferSize = 1;\n                }\n\n                if (this._mode \u0026\u0026 this._mode.__creator == modeCreator) {\n                    this._mode.init(this, iv \u0026\u0026 iv.words);\n                } else {\n                    this._mode = modeCreator.call(mode, this, iv \u0026\u0026 iv.words);\n                    this._mode.__creator = modeCreator;\n                }\n            },\n\n            _doProcessBlock: function (words, offset) {\n                this._mode.processBlock(words, offset);\n            },\n\n            _doFinalize: function () {\n                var finalProcessedBlocks;\n\n                \/\/ Shortcut\n                var padding = this.cfg.padding;\n\n                \/\/ Finalize\n                if (this._xformMode == this._ENC_XFORM_MODE) {\n                    \/\/ Pad data\n                    padding.pad(this._data, this.blockSize);\n\n                    \/\/ Process final blocks\n                    finalProcessedBlocks = this._process(!!'flush');\n                } else \/* if (this._xformMode == this._DEC_XFORM_MODE) *\/ {\n                    \/\/ Process final blocks\n                    finalProcessedBlocks = this._process(!!'flush');\n\n                    \/\/ Unpad data\n                    padding.unpad(finalProcessedBlocks);\n                }\n\n                return finalProcessedBlocks;\n            },\n\n            blockSize: 128 \/ 32\n        });\n\n        \/**\n         * A collection of cipher parameters.\n         *\n         * @property {WordArray} ciphertext The raw ciphertext.\n         * @property {WordArray} key The key to this ciphertext.\n         * @property {WordArray} iv The IV used in the ciphering operation.\n         * @property {WordArray} salt The salt used with a key derivation function.\n         * @property {Cipher} algorithm The cipher algorithm.\n         * @property {Mode} mode The block mode used in the ciphering operation.\n         * @property {Padding} padding The padding scheme used in the ciphering operation.\n         * @property {number} blockSize The block size of the cipher.\n         * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.\n         *\/\n        var CipherParams = C_lib.CipherParams = Base.extend({\n            \/**\n             * Initializes a newly created cipher params object.\n             *\n             * @param {Object} cipherParams An object with any of the possible cipher parameters.\n             *\n             * @example\n             *\n             *     var cipherParams = CryptoJS.lib.CipherParams.create({\n             *         ciphertext: ciphertextWordArray,\n             *         key: keyWordArray,\n             *         iv: ivWordArray,\n             *         salt: saltWordArray,\n             *         algorithm: CryptoJS.algo.AES,\n             *         mode: CryptoJS.mode.CBC,\n             *         padding: CryptoJS.pad.PKCS7,\n             *         blockSize: 4,\n             *         formatter: CryptoJS.format.OpenSSL\n             *     });\n             *\/\n            init: function (cipherParams) {\n                this.mixIn(cipherParams);\n            },\n\n            \/**\n             * Converts this cipher params object to a string.\n             *\n             * @param {Format} formatter (Optional) The formatting strategy to use.\n             *\n             * @return {string} The stringified cipher params.\n             *\n             * @throws Error If neither the formatter nor the default formatter is set.\n             *\n             * @example\n             *\n             *     var string = cipherParams + '';\n             *     var string = cipherParams.toString();\n             *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);\n             *\/\n            toString: function (formatter) {\n                return (formatter || this.formatter).stringify(this);\n            }\n        });\n\n        \/**\n         * Format namespace.\n         *\/\n        var C_format = C.format = {};\n\n        \/**\n         * OpenSSL formatting strategy.\n         *\/\n        var OpenSSLFormatter = C_format.OpenSSL = {\n            \/**\n             * Converts a cipher params object to an OpenSSL-compatible string.\n             *\n             * @param {CipherParams} cipherParams The cipher params object.\n             *\n             * @return {string} The OpenSSL-compatible string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);\n             *\/\n            stringify: function (cipherParams) {\n                var wordArray;\n\n                \/\/ Shortcuts\n                var ciphertext = cipherParams.ciphertext;\n                var salt = cipherParams.salt;\n\n                \/\/ Format\n                if (salt) {\n                    wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);\n                } else {\n                    wordArray = ciphertext;\n                }\n\n                return wordArray.toString(Base64);\n            },\n\n            \/**\n             * Converts an OpenSSL-compatible string to a cipher params object.\n             *\n             * @param {string} openSSLStr The OpenSSL-compatible string.\n             *\n             * @return {CipherParams} The cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);\n             *\/\n            parse: function (openSSLStr) {\n                var salt;\n\n                \/\/ Parse base64\n                var ciphertext = Base64.parse(openSSLStr);\n\n                \/\/ Shortcut\n                var ciphertextWords = ciphertext.words;\n\n                \/\/ Test for salt\n                if (ciphertextWords[0] == 0x53616c74 \u0026\u0026 ciphertextWords[1] == 0x65645f5f) {\n                    \/\/ Extract salt\n                    salt = WordArray.create(ciphertextWords.slice(2, 4));\n\n                    \/\/ Remove salt from ciphertext\n                    ciphertextWords.splice(0, 4);\n                    ciphertext.sigBytes -= 16;\n                }\n\n                return CipherParams.create({ ciphertext: ciphertext, salt: salt });\n            }\n        };\n\n        \/**\n         * A cipher wrapper that returns ciphertext as a serializable cipher params object.\n         *\/\n        var SerializableCipher = C_lib.SerializableCipher = Base.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL\n             *\/\n            cfg: Base.extend({\n                format: OpenSSLFormatter\n            }),\n\n            \/**\n             * Encrypts a message.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {WordArray|string} message The message to encrypt.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {CipherParams} A cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *\/\n            encrypt: function (cipher, message, key, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Encrypt\n                var encryptor = cipher.createEncryptor(key, cfg);\n                var ciphertext = encryptor.finalize(message);\n\n                \/\/ Shortcut\n                var cipherCfg = encryptor.cfg;\n\n                \/\/ Create and return serializable cipher params\n                return CipherParams.create({\n                    ciphertext: ciphertext,\n                    key: key,\n                    iv: cipherCfg.iv,\n                    algorithm: cipher,\n                    mode: cipherCfg.mode,\n                    padding: cipherCfg.padding,\n                    blockSize: cipher.blockSize,\n                    formatter: cfg.format\n                });\n            },\n\n            \/**\n             * Decrypts serialized ciphertext.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {WordArray} The plaintext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *\/\n            decrypt: function (cipher, ciphertext, key, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Convert string to CipherParams\n                ciphertext = this._parse(ciphertext, cfg.format);\n\n                \/\/ Decrypt\n                var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);\n\n                return plaintext;\n            },\n\n            \/**\n             * Converts serialized ciphertext to CipherParams,\n             * else assumed CipherParams already and returns ciphertext unchanged.\n             *\n             * @param {CipherParams|string} ciphertext The ciphertext.\n             * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.\n             *\n             * @return {CipherParams} The unserialized ciphertext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);\n             *\/\n            _parse: function (ciphertext, format) {\n                if (typeof ciphertext == 'string') {\n                    return format.parse(ciphertext, this);\n                } else {\n                    return ciphertext;\n                }\n            }\n        });\n\n        \/**\n         * Key derivation function namespace.\n         *\/\n        var C_kdf = C.kdf = {};\n\n        \/**\n         * OpenSSL key derivation function.\n         *\/\n        var OpenSSLKdf = C_kdf.OpenSSL = {\n            \/**\n             * Derives a key and IV from a password.\n             *\n             * @param {string} password The password to derive from.\n             * @param {number} keySize The size in words of the key to generate.\n             * @param {number} ivSize The size in words of the IV to generate.\n             * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.\n             *\n             * @return {CipherParams} A cipher params object with the key, IV, and salt.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256\/32, 128\/32);\n             *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256\/32, 128\/32, 'saltsalt');\n             *\/\n            execute: function (password, keySize, ivSize, salt, hasher) {\n                \/\/ Generate random salt\n                if (!salt) {\n                    salt = WordArray.random(64 \/ 8);\n                }\n\n                \/\/ Derive key and IV\n                if (!hasher) {\n                    var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);\n                } else {\n                    var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: hasher }).compute(password, salt);\n                }\n\n\n                \/\/ Separate key and IV\n                var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);\n                key.sigBytes = keySize * 4;\n\n                \/\/ Return params\n                return CipherParams.create({ key: key, iv: iv, salt: salt });\n            }\n        };\n\n        \/**\n         * A serializable cipher wrapper that derives the key from a password,\n         * and returns ciphertext as a serializable cipher params object.\n         *\/\n        var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL\n             *\/\n            cfg: SerializableCipher.cfg.extend({\n                kdf: OpenSSLKdf\n            }),\n\n            \/**\n             * Encrypts a message using a password.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {WordArray|string} message The message to encrypt.\n             * @param {string} password The password.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {CipherParams} A cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');\n             *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });\n             *\/\n            encrypt: function (cipher, message, password, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Derive key and other params\n                var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, cfg.salt, cfg.hasher);\n\n                \/\/ Add IV to config\n                cfg.iv = derivedParams.iv;\n\n                \/\/ Encrypt\n                var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);\n\n                \/\/ Mix in derived params\n                ciphertext.mixIn(derivedParams);\n\n                return ciphertext;\n            },\n\n            \/**\n             * Decrypts serialized ciphertext using a password.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n             * @param {string} password The password.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {WordArray} The plaintext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });\n             *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });\n             *\/\n            decrypt: function (cipher, ciphertext, password, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Convert string to CipherParams\n                ciphertext = this._parse(ciphertext, cfg.format);\n\n                \/\/ Derive key and other params\n                var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt, cfg.hasher);\n\n                \/\/ Add IV to config\n                cfg.iv = derivedParams.iv;\n\n                \/\/ Decrypt\n                var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);\n\n                return plaintext;\n            }\n        });\n    }());\n\n\n\n    (function () {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var BlockCipher = C_lib.BlockCipher;\n        var C_algo = C.algo;\n\n        \/\/ Lookup tables\n        var SBOX = [];\n        var INV_SBOX = [];\n        var SUB_MIX_0 = [];\n        var SUB_MIX_1 = [];\n        var SUB_MIX_2 = [];\n        var SUB_MIX_3 = [];\n        var INV_SUB_MIX_0 = [];\n        var INV_SUB_MIX_1 = [];\n        var INV_SUB_MIX_2 = [];\n        var INV_SUB_MIX_3 = [];\n\n        \/\/ Compute lookup tables\n        (function () {\n            \/\/ Compute double table\n            var d = [];\n            for (var i = 0; i \u003c 256; i++) {\n                if (i \u003c 128) {\n                    d[i] = i \u003c\u003c 1;\n                } else {\n                    d[i] = (i \u003c\u003c 1) ^ 0x11b;\n                }\n            }\n\n            \/\/ Walk GF(2^8)\n            var x = 0;\n            var xi = 0;\n            for (var i = 0; i \u003c 256; i++) {\n                \/\/ Compute sbox\n                var sx = xi ^ (xi \u003c\u003c 1) ^ (xi \u003c\u003c 2) ^ (xi \u003c\u003c 3) ^ (xi \u003c\u003c 4);\n                sx = (sx \u003e\u003e\u003e 8) ^ (sx \u0026 0xff) ^ 0x63;\n                SBOX[x] = sx;\n                INV_SBOX[sx] = x;\n\n                \/\/ Compute multiplication\n                var x2 = d[x];\n                var x4 = d[x2];\n                var x8 = d[x4];\n\n                \/\/ Compute sub bytes, mix columns tables\n                var t = (d[sx] * 0x101) ^ (sx * 0x1010100);\n                SUB_MIX_0[x] = (t \u003c\u003c 24) | (t \u003e\u003e\u003e 8);\n                SUB_MIX_1[x] = (t \u003c\u003c 16) | (t \u003e\u003e\u003e 16);\n                SUB_MIX_2[x] = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n                SUB_MIX_3[x] = t;\n\n                \/\/ Compute inv sub bytes, inv mix columns tables\n                var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);\n                INV_SUB_MIX_0[sx] = (t \u003c\u003c 24) | (t \u003e\u003e\u003e 8);\n                INV_SUB_MIX_1[sx] = (t \u003c\u003c 16) | (t \u003e\u003e\u003e 16);\n                INV_SUB_MIX_2[sx] = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n                INV_SUB_MIX_3[sx] = t;\n\n                \/\/ Compute next counter\n                if (!x) {\n                    x = xi = 1;\n                } else {\n                    x = x2 ^ d[d[d[x8 ^ x2]]];\n                    xi ^= d[d[xi]];\n                }\n            }\n        }());\n\n        \/\/ Precomputed Rcon lookup\n        var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];\n\n        \/**\n         * AES block cipher algorithm.\n         *\/\n        var AES = C_algo.AES = BlockCipher.extend({\n            _doReset: function () {\n                var t;\n\n                \/\/ Skip reset of nRounds has been set before and key did not change\n                if (this._nRounds \u0026\u0026 this._keyPriorReset === this._key) {\n                    return;\n                }\n\n                \/\/ Shortcuts\n                var key = this._keyPriorReset = this._key;\n                var keyWords = key.words;\n                var keySize = key.sigBytes \/ 4;\n\n                \/\/ Compute number of rounds\n                var nRounds = this._nRounds = keySize + 6;\n\n                \/\/ Compute number of key schedule rows\n                var ksRows = (nRounds + 1) * 4;\n\n                \/\/ Compute key schedule\n                var keySchedule = this._keySchedule = [];\n                for (var ksRow = 0; ksRow \u003c ksRows; ksRow++) {\n                    if (ksRow \u003c keySize) {\n                        keySchedule[ksRow] = keyWords[ksRow];\n                    } else {\n                        t = keySchedule[ksRow - 1];\n\n                        if (!(ksRow % keySize)) {\n                            \/\/ Rot word\n                            t = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n\n                            \/\/ Sub word\n                            t = (SBOX[t \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[t \u0026 0xff];\n\n                            \/\/ Mix Rcon\n                            t ^= RCON[(ksRow \/ keySize) | 0] \u003c\u003c 24;\n                        } else if (keySize \u003e 6 \u0026\u0026 ksRow % keySize == 4) {\n                            \/\/ Sub word\n                            t = (SBOX[t \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[t \u0026 0xff];\n                        }\n\n                        keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;\n                    }\n                }\n\n                \/\/ Compute inv key schedule\n                var invKeySchedule = this._invKeySchedule = [];\n                for (var invKsRow = 0; invKsRow \u003c ksRows; invKsRow++) {\n                    var ksRow = ksRows - invKsRow;\n\n                    if (invKsRow % 4) {\n                        var t = keySchedule[ksRow];\n                    } else {\n                        var t = keySchedule[ksRow - 4];\n                    }\n\n                    if (invKsRow \u003c 4 || ksRow \u003c= 4) {\n                        invKeySchedule[invKsRow] = t;\n                    } else {\n                        invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t \u003e\u003e\u003e 24]] ^ INV_SUB_MIX_1[SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff]] ^\n                            INV_SUB_MIX_2[SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff]] ^ INV_SUB_MIX_3[SBOX[t \u0026 0xff]];\n                    }\n                }\n            },\n\n            encryptBlock: function (M, offset) {\n                this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);\n            },\n\n            decryptBlock: function (M, offset) {\n                \/\/ Swap 2nd and 4th rows\n                var t = M[offset + 1];\n                M[offset + 1] = M[offset + 3];\n                M[offset + 3] = t;\n\n                this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);\n\n                \/\/ Inv swap 2nd and 4th rows\n                var t = M[offset + 1];\n                M[offset + 1] = M[offset + 3];\n                M[offset + 3] = t;\n            },\n\n            _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {\n                \/\/ Shortcut\n                var nRounds = this._nRounds;\n\n                \/\/ Get input, add round key\n                var s0 = M[offset] ^ keySchedule[0];\n                var s1 = M[offset + 1] ^ keySchedule[1];\n                var s2 = M[offset + 2] ^ keySchedule[2];\n                var s3 = M[offset + 3] ^ keySchedule[3];\n\n                \/\/ Key schedule row counter\n                var ksRow = 4;\n\n                \/\/ Rounds\n                for (var round = 1; round \u003c nRounds; round++) {\n                    \/\/ Shift rows, sub bytes, mix columns, add round key\n                    var t0 = SUB_MIX_0[s0 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s1 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s2 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s3 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t1 = SUB_MIX_0[s1 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s2 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s3 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s0 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t2 = SUB_MIX_0[s2 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s3 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s0 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s1 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t3 = SUB_MIX_0[s3 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s0 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s1 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s2 \u0026 0xff] ^ keySchedule[ksRow++];\n\n                    \/\/ Update state\n                    s0 = t0;\n                    s1 = t1;\n                    s2 = t2;\n                    s3 = t3;\n                }\n\n                \/\/ Shift rows, sub bytes, add round key\n                var t0 = ((SBOX[s0 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s1 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s2 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s3 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t1 = ((SBOX[s1 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s2 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s3 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s0 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t2 = ((SBOX[s2 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s3 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s0 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s1 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t3 = ((SBOX[s3 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s0 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s1 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s2 \u0026 0xff]) ^ keySchedule[ksRow++];\n\n                \/\/ Set output\n                M[offset] = t0;\n                M[offset + 1] = t1;\n                M[offset + 2] = t2;\n                M[offset + 3] = t3;\n            },\n\n            keySize: 256 \/ 32\n        });\n\n        \/**\n         * Shortcut functions to the cipher's object interface.\n         *\n         * @example\n         *\n         *     var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);\n         *     var plaintext  = CryptoJS.AES.decrypt(ciphertext, key, cfg);\n         *\/\n        C.AES = BlockCipher._createHelper(AES);\n    }());\n\n    (function (Math) {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var WordArray = C_lib.WordArray;\n        var Hasher = C_lib.Hasher;\n        var C_algo = C.algo;\n\n        \/\/ Constants table\n        var T = [];\n\n        \/\/ Compute constants\n        (function () {\n            for (var i = 0; i \u003c 64; i++) {\n                T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;\n            }\n        }());\n\n        \/**\n         * MD5 hash algorithm.\n         *\/\n        var MD5 = C_algo.MD5 = Hasher.extend({\n            _doReset: function () {\n                this._hash = new WordArray.init([\n                    0x67452301, 0xefcdab89,\n                    0x98badcfe, 0x10325476\n                ]);\n            },\n\n            _doProcessBlock: function (M, offset) {\n                \/\/ Swap endian\n                for (var i = 0; i \u003c 16; i++) {\n                    \/\/ Shortcuts\n                    var offset_i = offset + i;\n                    var M_offset_i = M[offset_i];\n\n                    M[offset_i] = (\n                        (((M_offset_i \u003c\u003c 8) | (M_offset_i \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                        (((M_offset_i \u003c\u003c 24) | (M_offset_i \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                    );\n                }\n\n                \/\/ Shortcuts\n                var H = this._hash.words;\n\n                var M_offset_0 = M[offset + 0];\n                var M_offset_1 = M[offset + 1];\n                var M_offset_2 = M[offset + 2];\n                var M_offset_3 = M[offset + 3];\n                var M_offset_4 = M[offset + 4];\n                var M_offset_5 = M[offset + 5];\n                var M_offset_6 = M[offset + 6];\n                var M_offset_7 = M[offset + 7];\n                var M_offset_8 = M[offset + 8];\n                var M_offset_9 = M[offset + 9];\n                var M_offset_10 = M[offset + 10];\n                var M_offset_11 = M[offset + 11];\n                var M_offset_12 = M[offset + 12];\n                var M_offset_13 = M[offset + 13];\n                var M_offset_14 = M[offset + 14];\n                var M_offset_15 = M[offset + 15];\n\n                \/\/ Working variables\n                var a = H[0];\n                var b = H[1];\n                var c = H[2];\n                var d = H[3];\n\n                \/\/ Computation\n                a = FF(a, b, c, d, M_offset_0, 7, T[0]);\n                d = FF(d, a, b, c, M_offset_1, 12, T[1]);\n                c = FF(c, d, a, b, M_offset_2, 17, T[2]);\n                b = FF(b, c, d, a, M_offset_3, 22, T[3]);\n                a = FF(a, b, c, d, M_offset_4, 7, T[4]);\n                d = FF(d, a, b, c, M_offset_5, 12, T[5]);\n                c = FF(c, d, a, b, M_offset_6, 17, T[6]);\n                b = FF(b, c, d, a, M_offset_7, 22, T[7]);\n                a = FF(a, b, c, d, M_offset_8, 7, T[8]);\n                d = FF(d, a, b, c, M_offset_9, 12, T[9]);\n                c = FF(c, d, a, b, M_offset_10, 17, T[10]);\n                b = FF(b, c, d, a, M_offset_11, 22, T[11]);\n                a = FF(a, b, c, d, M_offset_12, 7, T[12]);\n                d = FF(d, a, b, c, M_offset_13, 12, T[13]);\n                c = FF(c, d, a, b, M_offset_14, 17, T[14]);\n                b = FF(b, c, d, a, M_offset_15, 22, T[15]);\n\n                a = GG(a, b, c, d, M_offset_1, 5, T[16]);\n                d = GG(d, a, b, c, M_offset_6, 9, T[17]);\n                c = GG(c, d, a, b, M_offset_11, 14, T[18]);\n                b = GG(b, c, d, a, M_offset_0, 20, T[19]);\n                a = GG(a, b, c, d, M_offset_5, 5, T[20]);\n                d = GG(d, a, b, c, M_offset_10, 9, T[21]);\n                c = GG(c, d, a, b, M_offset_15, 14, T[22]);\n                b = GG(b, c, d, a, M_offset_4, 20, T[23]);\n                a = GG(a, b, c, d, M_offset_9, 5, T[24]);\n                d = GG(d, a, b, c, M_offset_14, 9, T[25]);\n                c = GG(c, d, a, b, M_offset_3, 14, T[26]);\n                b = GG(b, c, d, a, M_offset_8, 20, T[27]);\n                a = GG(a, b, c, d, M_offset_13, 5, T[28]);\n                d = GG(d, a, b, c, M_offset_2, 9, T[29]);\n                c = GG(c, d, a, b, M_offset_7, 14, T[30]);\n                b = GG(b, c, d, a, M_offset_12, 20, T[31]);\n\n                a = HH(a, b, c, d, M_offset_5, 4, T[32]);\n                d = HH(d, a, b, c, M_offset_8, 11, T[33]);\n                c = HH(c, d, a, b, M_offset_11, 16, T[34]);\n                b = HH(b, c, d, a, M_offset_14, 23, T[35]);\n                a = HH(a, b, c, d, M_offset_1, 4, T[36]);\n                d = HH(d, a, b, c, M_offset_4, 11, T[37]);\n                c = HH(c, d, a, b, M_offset_7, 16, T[38]);\n                b = HH(b, c, d, a, M_offset_10, 23, T[39]);\n                a = HH(a, b, c, d, M_offset_13, 4, T[40]);\n                d = HH(d, a, b, c, M_offset_0, 11, T[41]);\n                c = HH(c, d, a, b, M_offset_3, 16, T[42]);\n                b = HH(b, c, d, a, M_offset_6, 23, T[43]);\n                a = HH(a, b, c, d, M_offset_9, 4, T[44]);\n                d = HH(d, a, b, c, M_offset_12, 11, T[45]);\n                c = HH(c, d, a, b, M_offset_15, 16, T[46]);\n                b = HH(b, c, d, a, M_offset_2, 23, T[47]);\n\n                a = II(a, b, c, d, M_offset_0, 6, T[48]);\n                d = II(d, a, b, c, M_offset_7, 10, T[49]);\n                c = II(c, d, a, b, M_offset_14, 15, T[50]);\n                b = II(b, c, d, a, M_offset_5, 21, T[51]);\n                a = II(a, b, c, d, M_offset_12, 6, T[52]);\n                d = II(d, a, b, c, M_offset_3, 10, T[53]);\n                c = II(c, d, a, b, M_offset_10, 15, T[54]);\n                b = II(b, c, d, a, M_offset_1, 21, T[55]);\n                a = II(a, b, c, d, M_offset_8, 6, T[56]);\n                d = II(d, a, b, c, M_offset_15, 10, T[57]);\n                c = II(c, d, a, b, M_offset_6, 15, T[58]);\n                b = II(b, c, d, a, M_offset_13, 21, T[59]);\n                a = II(a, b, c, d, M_offset_4, 6, T[60]);\n                d = II(d, a, b, c, M_offset_11, 10, T[61]);\n                c = II(c, d, a, b, M_offset_2, 15, T[62]);\n                b = II(b, c, d, a, M_offset_9, 21, T[63]);\n\n                \/\/ Intermediate hash value\n                H[0] = (H[0] + a) | 0;\n                H[1] = (H[1] + b) | 0;\n                H[2] = (H[2] + c) | 0;\n                H[3] = (H[3] + d) | 0;\n            },\n\n            _doFinalize: function () {\n                \/\/ Shortcuts\n                var data = this._data;\n                var dataWords = data.words;\n\n                var nBitsTotal = this._nDataBytes * 8;\n                var nBitsLeft = data.sigBytes * 8;\n\n                \/\/ Add padding\n                dataWords[nBitsLeft \u003e\u003e\u003e 5] |= 0x80 \u003c\u003c (24 - nBitsLeft % 32);\n\n                var nBitsTotalH = Math.floor(nBitsTotal \/ 0x100000000);\n                var nBitsTotalL = nBitsTotal;\n                dataWords[(((nBitsLeft + 64) \u003e\u003e\u003e 9) \u003c\u003c 4) + 15] = (\n                    (((nBitsTotalH \u003c\u003c 8) | (nBitsTotalH \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                    (((nBitsTotalH \u003c\u003c 24) | (nBitsTotalH \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                );\n                dataWords[(((nBitsLeft + 64) \u003e\u003e\u003e 9) \u003c\u003c 4) + 14] = (\n                    (((nBitsTotalL \u003c\u003c 8) | (nBitsTotalL \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                    (((nBitsTotalL \u003c\u003c 24) | (nBitsTotalL \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                );\n\n                data.sigBytes = (dataWords.length + 1) * 4;\n\n                \/\/ Hash final blocks\n                this._process();\n\n                \/\/ Shortcuts\n                var hash = this._hash;\n                var H = hash.words;\n\n                \/\/ Swap endian\n                for (var i = 0; i \u003c 4; i++) {\n                    \/\/ Shortcut\n                    var H_i = H[i];\n\n                    H[i] = (((H_i \u003c\u003c 8) | (H_i \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                        (((H_i \u003c\u003c 24) | (H_i \u003e\u003e\u003e 8)) \u0026 0xff00ff00);\n                }\n\n                \/\/ Return final computed hash\n                return hash;\n            },\n\n            clone: function () {\n                var clone = Hasher.clone.call(this);\n                clone._hash = this._hash.clone();\n\n                return clone;\n            }\n        });\n\n        function FF(a, b, c, d, x, s, t) {\n            var n = a + ((b \u0026 c) | (~b \u0026 d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function GG(a, b, c, d, x, s, t) {\n            var n = a + ((b \u0026 d) | (c \u0026 ~d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function HH(a, b, c, d, x, s, t) {\n            var n = a + (b ^ c ^ d) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function II(a, b, c, d, x, s, t) {\n            var n = a + (c ^ (b | ~d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        \/**\n         * Shortcut function to the hasher's object interface.\n         *\n         * @param {WordArray|string} message The message to hash.\n         *\n         * @return {WordArray} The hash.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hash = CryptoJS.MD5('message');\n         *     var hash = CryptoJS.MD5(wordArray);\n         *\/\n        C.MD5 = Hasher._createHelper(MD5);\n\n        \/**\n         * Shortcut function to the HMAC's object interface.\n         *\n         * @param {WordArray|string} message The message to hash.\n         * @param {WordArray|string} key The secret key.\n         *\n         * @return {WordArray} The HMAC.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hmac = CryptoJS.HmacMD5(message, key);\n         *\/\n        C.HmacMD5 = Hasher._createHmacHelper(MD5);\n    }(Math));\n\n    \/**\n     * Zero padding strategy.\n     *\/\n    CryptoJS.pad.ZeroPadding = {\n        pad: function (data, blockSize) {\n            \/\/ Shortcut\n            var blockSizeBytes = blockSize * 4;\n\n            \/\/ Pad\n            data.clamp();\n            data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);\n        },\n\n        unpad: function (data) {\n            \/\/ Shortcut\n            var dataWords = data.words;\n\n            \/\/ Unpad\n            var i = data.sigBytes - 1;\n            for (var i = data.sigBytes - 1; i \u003e= 0; i--) {\n                if (((dataWords[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff)) {\n                    data.sigBytes = i + 1;\n                    break;\n                }\n            }\n        }\n    };\n\n\n    return CryptoJS;\n\n}));\n(function (P) {\n    (function () {\n        P.ecy = (function () {\n            function strEnc(data, firstKey, secondKey, thirdKey) {\n\n                var leng = data.length;\n                var encData = \"\";\n                var firstKeyBt, secondKeyBt, thirdKeyBt, firstLength, secondLength, thirdLength;\n                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                    firstKeyBt = getKeyBytes(firstKey);\n                    firstLength = firstKeyBt.length;\n                }\n                if (secondKey != null \u0026\u0026 secondKey != \"\") {\n                    secondKeyBt = getKeyBytes(secondKey);\n                    secondLength = secondKeyBt.length;\n                }\n                if (thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                    thirdKeyBt = getKeyBytes(thirdKey);\n                    thirdLength = thirdKeyBt.length;\n                }\n\n                if (leng \u003e 0) {\n                    if (leng \u003c 4) {\n                        var bt = strToBt(data);\n                        var encByte;\n                        if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                            var tempBt;\n                            var x, y, z;\n                            tempBt = bt;\n                            for (x = 0; x \u003c firstLength; x++) {\n                                tempBt = enc(tempBt, firstKeyBt[x]);\n                            }\n                            for (y = 0; y \u003c secondLength; y++) {\n                                tempBt = enc(tempBt, secondKeyBt[y]);\n                            }\n                            for (z = 0; z \u003c thirdLength; z++) {\n                                tempBt = enc(tempBt, thirdKeyBt[z]);\n                            }\n                            encByte = tempBt;\n                        } else {\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                var tempBt;\n                                var x, y;\n                                tempBt = bt;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                    var tempBt;\n                                    var x = 0;\n                                    tempBt = bt;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    encByte = tempBt;\n                                }\n                            }\n                        }\n                        encData = bt64ToHex(encByte);\n                    } else {\n                        var iterator = parseInt(leng \/ 4);\n                        var remainder = leng % 4;\n                        var i = 0;\n                        for (i = 0; i \u003c iterator; i++) {\n                            var tempData = data.substring(i * 4 + 0, i * 4 + 4);\n                            var tempByte = strToBt(tempData);\n                            var encByte;\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = tempByte;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                for (z = 0; z \u003c thirdLength; z++) {\n                                    tempBt = enc(tempBt, thirdKeyBt[z]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                    var tempBt;\n                                    var x, y;\n                                    tempBt = tempByte;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    for (y = 0; y \u003c secondLength; y++) {\n                                        tempBt = enc(tempBt, secondKeyBt[y]);\n                                    }\n                                    encByte = tempBt;\n                                } else {\n                                    if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                        var tempBt;\n                                        var x;\n                                        tempBt = tempByte;\n                                        for (x = 0; x \u003c firstLength; x++) {\n                                            tempBt = enc(tempBt, firstKeyBt[x]);\n                                        }\n                                        encByte = tempBt;\n                                    }\n                                }\n                            }\n                            encData += bt64ToHex(encByte);\n                        }\n                        if (remainder \u003e 0) {\n                            var remainderData = data.substring(iterator * 4 + 0, leng);\n                            var tempByte = strToBt(remainderData);\n                            var encByte;\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = tempByte;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                for (z = 0; z \u003c thirdLength; z++) {\n                                    tempBt = enc(tempBt, thirdKeyBt[z]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                    var tempBt;\n                                    var x, y;\n                                    tempBt = tempByte;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    for (y = 0; y \u003c secondLength; y++) {\n                                        tempBt = enc(tempBt, secondKeyBt[y]);\n                                    }\n                                    encByte = tempBt;\n                                } else {\n                                    if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                        var tempBt;\n                                        var x;\n                                        tempBt = tempByte;\n                                        for (x = 0; x \u003c firstLength; x++) {\n                                            tempBt = enc(tempBt, firstKeyBt[x]);\n                                        }\n                                        encByte = tempBt;\n                                    }\n                                }\n                            }\n                            encData += bt64ToHex(encByte);\n                        }\n                    }\n                }\n                return encData;\n            }\n\n            \/*\n             * decrypt the encrypted string to the original string\n             *\n             * return  the original string\n             *\/\n            function strDec(data, firstKey, secondKey, thirdKey) {\n                var leng = data.length;\n                var decStr = \"\";\n                var firstKeyBt, secondKeyBt, thirdKeyBt, firstLength, secondLength, thirdLength;\n                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                    firstKeyBt = getKeyBytes(firstKey);\n                    firstLength = firstKeyBt.length;\n                }\n                if (secondKey != null \u0026\u0026 secondKey != \"\") {\n                    secondKeyBt = getKeyBytes(secondKey);\n                    secondLength = secondKeyBt.length;\n                }\n                if (thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                    thirdKeyBt = getKeyBytes(thirdKey);\n                    thirdLength = thirdKeyBt.length;\n                }\n\n                var iterator = parseInt(leng \/ 16);\n                var i = 0;\n                for (i = 0; i \u003c iterator; i++) {\n                    var tempData = data.substring(i * 16 + 0, i * 16 + 16);\n                    var strByte = hexToBt64(tempData);\n                    var intByte = new Array(64);\n                    var j = 0;\n                    for (j = 0; j \u003c 64; j++) {\n                        intByte[j] = parseInt(strByte.substring(j, j + 1));\n                    }\n                    var decByte;\n                    if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                        var tempBt;\n                        var x, y, z;\n                        tempBt = intByte;\n                        for (x = thirdLength - 1; x \u003e= 0; x--) {\n                            tempBt = dec(tempBt, thirdKeyBt[x]);\n                        }\n                        for (y = secondLength - 1; y \u003e= 0; y--) {\n                            tempBt = dec(tempBt, secondKeyBt[y]);\n                        }\n                        for (z = firstLength - 1; z \u003e= 0; z--) {\n                            tempBt = dec(tempBt, firstKeyBt[z]);\n                        }\n                        decByte = tempBt;\n                    } else {\n                        if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                            var tempBt;\n                            var x, y, z;\n                            tempBt = intByte;\n                            for (x = secondLength - 1; x \u003e= 0; x--) {\n                                tempBt = dec(tempBt, secondKeyBt[x]);\n                            }\n                            for (y = firstLength - 1; y \u003e= 0; y--) {\n                                tempBt = dec(tempBt, firstKeyBt[y]);\n                            }\n                            decByte = tempBt;\n                        } else {\n                            if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = intByte;\n                                for (x = firstLength - 1; x \u003e= 0; x--) {\n                                    tempBt = dec(tempBt, firstKeyBt[x]);\n                                }\n                                decByte = tempBt;\n                            }\n                        }\n                    }\n                    decStr += byteToString(decByte);\n                }\n                return decStr;\n            }\n            \/*\n             * chang the string into the bit array\n             *\n             * return bit array(it's length % 64 = 0)\n             *\/\n            function getKeyBytes(key) {\n                var keyBytes = new Array();\n                var leng = key.length;\n                var iterator = parseInt(leng \/ 4);\n                var remainder = leng % 4;\n                var i = 0;\n                for (i = 0; i \u003c iterator; i++) {\n                    keyBytes[i] = strToBt(key.substring(i * 4 + 0, i * 4 + 4));\n                }\n                if (remainder \u003e 0) {\n                    keyBytes[i] = strToBt(key.substring(i * 4 + 0, leng));\n                }\n                return keyBytes;\n            }\n\n            \/*\n             * chang the string(it's length \u003c= 4) into the bit array\n             *\n             * return bit array(it's length = 64)\n             *\/\n            function strToBt(str) {\n                var leng = str.length;\n                var bt = new Array(64);\n                var i = 0, j = 0, p = 0, q = 0;\n                if (leng \u003c 4) {\n                    for (i = 0; i \u003c leng; i++) {\n                        var k = str.charCodeAt(i);\n                        for (j = 0; j \u003c 16; j++) {\n                            var pow = 1, m = 0;\n                            for (m = 15; m \u003e j; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * i + j] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                    for (p = leng; p \u003c 4; p++) {\n                        var k = 0;\n                        for (q = 0; q \u003c 16; q++) {\n                            var pow = 1, m = 0;\n                            for (m = 15; m \u003e q; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * p + q] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                } else {\n                    for (i = 0; i \u003c 4; i++) {\n                        var k = str.charCodeAt(i);\n                        for (j = 0; j \u003c 16; j++) {\n                            var pow = 1;\n                            for (m = 15; m \u003e j; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * i + j] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                }\n                return bt;\n            }\n\n            \/*\n             * chang the bit(it's length = 4) into the hex\n             *\n             * return hex\n             *\/\n            function bt4ToHex(binary) {\n                var hex;\n                switch (binary) {\n                    case \"0000\": hex = \"0\"; break;\n                    case \"0001\": hex = \"1\"; break;\n                    case \"0010\": hex = \"2\"; break;\n                    case \"0011\": hex = \"3\"; break;\n                    case \"0100\": hex = \"4\"; break;\n                    case \"0101\": hex = \"5\"; break;\n                    case \"0110\": hex = \"6\"; break;\n                    case \"0111\": hex = \"7\"; break;\n                    case \"1000\": hex = \"8\"; break;\n                    case \"1001\": hex = \"9\"; break;\n                    case \"1010\": hex = \"A\"; break;\n                    case \"1011\": hex = \"B\"; break;\n                    case \"1100\": hex = \"C\"; break;\n                    case \"1101\": hex = \"D\"; break;\n                    case \"1110\": hex = \"E\"; break;\n                    case \"1111\": hex = \"F\"; break;\n                }\n                return hex;\n            }\n\n            \/*\n             * chang the hex into the bit(it's length = 4)\n             *\n             * return the bit(it's length = 4)\n             *\/\n            function hexToBt4(hex) {\n                var binary;\n                switch (hex) {\n                    case \"0\": binary = \"0000\"; break;\n                    case \"1\": binary = \"0001\"; break;\n                    case \"2\": binary = \"0010\"; break;\n                    case \"3\": binary = \"0011\"; break;\n                    case \"4\": binary = \"0100\"; break;\n                    case \"5\": binary = \"0101\"; break;\n                    case \"6\": binary = \"0110\"; break;\n                    case \"7\": binary = \"0111\"; break;\n                    case \"8\": binary = \"1000\"; break;\n                    case \"9\": binary = \"1001\"; break;\n                    case \"A\": binary = \"1010\"; break;\n                    case \"B\": binary = \"1011\"; break;\n                    case \"C\": binary = \"1100\"; break;\n                    case \"D\": binary = \"1101\"; break;\n                    case \"E\": binary = \"1110\"; break;\n                    case \"F\": binary = \"1111\"; break;\n                }\n                return binary;\n            }\n\n            \/*\n             * chang the bit(it's length = 64) into the string\n             *\n             * return string\n             *\/\n            function byteToString(byteData) {\n                var str = \"\";\n                var i, j, m;\n                for (i = 0; i \u003c 4; i++) {\n                    var count = 0;\n                    for (j = 0; j \u003c 16; j++) {\n                        var pow = 1;\n                        for (m = 15; m \u003e j; m--) {\n                            pow *= 2;\n                        }\n                        count += byteData[16 * i + j] * pow;\n                    }\n                    if (count != 0) {\n                        str += String.fromCharCode(count);\n                    }\n                }\n                return str;\n            }\n\n            function bt64ToHex(byteData) {\n                var hex = \"\";\n                var i, j;\n                for (i = 0; i \u003c 16; i++) {\n                    var bt = \"\";\n                    for (j = 0; j \u003c 4; j++) {\n                        bt += byteData[i * 4 + j];\n                    }\n                    hex += bt4ToHex(bt);\n                }\n                return hex;\n            }\n\n            function hexToBt64(hex) {\n                var binary = \"\";\n                for (var i = 0; i \u003c 16; i++) {\n                    binary += hexToBt4(hex.substring(i, i + 1));\n                }\n                return binary;\n            }\n\n            \/*\n             * the 64 bit des core arithmetic\n             *\/\n\n            function enc(dataByte, keyByte) {\n                var keys = generateKeys(keyByte);\n                var ipByte = initPermute(dataByte);\n                var ipLeft = new Array(32);\n                var ipRight = new Array(32);\n                var tempLeft = new Array(32);\n                var i = 0, j = 0, k = 0, m = 0, n = 0;\n                for (k = 0; k \u003c 32; k++) {\n                    ipLeft[k] = ipByte[k];\n                    ipRight[k] = ipByte[32 + k];\n                }\n                for (i = 0; i \u003c 16; i++) {\n                    for (j = 0; j \u003c 32; j++) {\n                        tempLeft[j] = ipLeft[j];\n                        ipLeft[j] = ipRight[j];\n                    }\n                    var key = new Array(48);\n                    for (m = 0; m \u003c 48; m++) {\n                        key[m] = keys[i][m];\n                    }\n                    var tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);\n                    for (n = 0; n \u003c 32; n++) {\n                        ipRight[n] = tempRight[n];\n                    }\n\n                }\n\n\n                var finalData = new Array(64);\n                for (i = 0; i \u003c 32; i++) {\n                    finalData[i] = ipRight[i];\n                    finalData[32 + i] = ipLeft[i];\n                }\n                return finallyPermute(finalData);\n            }\n\n            function dec(dataByte, keyByte) {\n                var keys = generateKeys(keyByte);\n                var ipByte = initPermute(dataByte);\n                var ipLeft = new Array(32);\n                var ipRight = new Array(32);\n                var tempLeft = new Array(32);\n                var i = 0, j = 0, k = 0, m = 0, n = 0;\n                for (k = 0; k \u003c 32; k++) {\n                    ipLeft[k] = ipByte[k];\n                    ipRight[k] = ipByte[32 + k];\n                }\n                for (i = 15; i \u003e= 0; i--) {\n                    for (j = 0; j \u003c 32; j++) {\n                        tempLeft[j] = ipLeft[j];\n                        ipLeft[j] = ipRight[j];\n                    }\n                    var key = new Array(48);\n                    for (m = 0; m \u003c 48; m++) {\n                        key[m] = keys[i][m];\n                    }\n\n                    var tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);\n                    for (n = 0; n \u003c 32; n++) {\n                        ipRight[n] = tempRight[n];\n                    }\n                }\n\n\n                var finalData = new Array(64);\n                for (i = 0; i \u003c 32; i++) {\n                    finalData[i] = ipRight[i];\n                    finalData[32 + i] = ipLeft[i];\n                }\n                return finallyPermute(finalData);\n            }\n\n            function initPermute(originalData) {\n                var ipByte = new Array(64);\n                var i, j, m, n, k;\n                for (i = 0, m = 1, n = 0; i \u003c 4; i++, m += 2, n += 2) {\n                    for (j = 7, k = 0; j \u003e= 0; j--, k++) {\n                        ipByte[i * 8 + k] = originalData[j * 8 + m];\n                        ipByte[i * 8 + k + 32] = originalData[j * 8 + n];\n                    }\n                }\n                return ipByte;\n            }\n\n            function expandPermute(rightData) {\n                var epByte = new Array(48);\n                for (var i = 0; i \u003c 8; i++) {\n                    if (i == 0) {\n                        epByte[i * 6 + 0] = rightData[31];\n                    } else {\n                        epByte[i * 6 + 0] = rightData[i * 4 - 1];\n                    }\n                    epByte[i * 6 + 1] = rightData[i * 4 + 0];\n                    epByte[i * 6 + 2] = rightData[i * 4 + 1];\n                    epByte[i * 6 + 3] = rightData[i * 4 + 2];\n                    epByte[i * 6 + 4] = rightData[i * 4 + 3];\n                    if (i == 7) {\n                        epByte[i * 6 + 5] = rightData[0];\n                    } else {\n                        epByte[i * 6 + 5] = rightData[i * 4 + 4];\n                    }\n                }\n                return epByte;\n            }\n\n            function xor(byteOne, byteTwo) {\n                var xorByte = new Array(byteOne.length);\n                for (var i = 0; i \u003c byteOne.length; i++) {\n                    xorByte[i] = byteOne[i] ^ byteTwo[i];\n                }\n                return xorByte;\n            }\n\n            function sBoxPermute(expandByte) {\n\n                var sBoxByte = new Array(32);\n                var binary = \"\";\n                var s1 = [\n                    [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],\n                    [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],\n                    [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],\n                    [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]];\n\n                \/* Table - s2 *\/\n                var s2 = [\n                    [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],\n                    [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],\n                    [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],\n                    [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]];\n\n                \/* Table - s3 *\/\n                var s3 = [\n                    [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],\n                    [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],\n                    [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],\n                    [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]];\n                \/* Table - s4 *\/\n                var s4 = [\n                    [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],\n                    [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],\n                    [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],\n                    [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]];\n\n                \/* Table - s5 *\/\n                var s5 = [\n                    [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],\n                    [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],\n                    [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],\n                    [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]];\n\n                \/* Table - s6 *\/\n                var s6 = [\n                    [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],\n                    [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],\n                    [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],\n                    [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]];\n\n                \/* Table - s7 *\/\n                var s7 = [\n                    [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],\n                    [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],\n                    [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],\n                    [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]];\n\n                \/* Table - s8 *\/\n                var s8 = [\n                    [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],\n                    [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],\n                    [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],\n                    [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]];\n\n                var m;\n\n                for (m = 0; m \u003c 8; m++) {\n                    var i = 0, j = 0;\n                    i = expandByte[m * 6 + 0] * 2 + expandByte[m * 6 + 5];\n                    j = expandByte[m * 6 + 1] * 2 * 2 * 2\n                        + expandByte[m * 6 + 2] * 2 * 2\n                        + expandByte[m * 6 + 3] * 2\n                        + expandByte[m * 6 + 4];\n                    switch (m) {\n                        case 0:\n                            binary = getBoxBinary(s1[i][j]);\n                            break;\n                        case 1:\n                            binary = getBoxBinary(s2[i][j]);\n                            break;\n                        case 2:\n                            binary = getBoxBinary(s3[i][j]);\n                            break;\n                        case 3:\n                            binary = getBoxBinary(s4[i][j]);\n                            break;\n                        case 4:\n                            binary = getBoxBinary(s5[i][j]);\n                            break;\n                        case 5:\n                            binary = getBoxBinary(s6[i][j]);\n                            break;\n                        case 6:\n                            binary = getBoxBinary(s7[i][j]);\n                            break;\n                        case 7:\n                            binary = getBoxBinary(s8[i][j]);\n                            break;\n                    }\n                    sBoxByte[m * 4 + 0] = parseInt(binary.substring(0, 1));\n                    sBoxByte[m * 4 + 1] = parseInt(binary.substring(1, 2));\n                    sBoxByte[m * 4 + 2] = parseInt(binary.substring(2, 3));\n                    sBoxByte[m * 4 + 3] = parseInt(binary.substring(3, 4));\n                }\n                return sBoxByte;\n            }\n\n            function pPermute(sBoxByte) {\n                var pBoxPermute = new Array(32);\n                pBoxPermute[0] = sBoxByte[15];\n                pBoxPermute[1] = sBoxByte[6];\n                pBoxPermute[2] = sBoxByte[19];\n                pBoxPermute[3] = sBoxByte[20];\n                pBoxPermute[4] = sBoxByte[28];\n                pBoxPermute[5] = sBoxByte[11];\n                pBoxPermute[6] = sBoxByte[27];\n                pBoxPermute[7] = sBoxByte[16];\n                pBoxPermute[8] = sBoxByte[0];\n                pBoxPermute[9] = sBoxByte[14];\n                pBoxPermute[10] = sBoxByte[22];\n                pBoxPermute[11] = sBoxByte[25];\n                pBoxPermute[12] = sBoxByte[4];\n                pBoxPermute[13] = sBoxByte[17];\n                pBoxPermute[14] = sBoxByte[30];\n                pBoxPermute[15] = sBoxByte[9];\n                pBoxPermute[16] = sBoxByte[1];\n                pBoxPermute[17] = sBoxByte[7];\n                pBoxPermute[18] = sBoxByte[23];\n                pBoxPermute[19] = sBoxByte[13];\n                pBoxPermute[20] = sBoxByte[31];\n                pBoxPermute[21] = sBoxByte[26];\n                pBoxPermute[22] = sBoxByte[2];\n                pBoxPermute[23] = sBoxByte[8];\n                pBoxPermute[24] = sBoxByte[18];\n                pBoxPermute[25] = sBoxByte[12];\n                pBoxPermute[26] = sBoxByte[29];\n                pBoxPermute[27] = sBoxByte[5];\n                pBoxPermute[28] = sBoxByte[21];\n                pBoxPermute[29] = sBoxByte[10];\n                pBoxPermute[30] = sBoxByte[3];\n                pBoxPermute[31] = sBoxByte[24];\n                return pBoxPermute;\n            }\n\n            function finallyPermute(endByte) {\n                var fpByte = new Array(64);\n                fpByte[0] = endByte[39];\n                fpByte[1] = endByte[7];\n                fpByte[2] = endByte[47];\n                fpByte[3] = endByte[15];\n                fpByte[4] = endByte[55];\n                fpByte[5] = endByte[23];\n                fpByte[6] = endByte[63];\n                fpByte[7] = endByte[31];\n                fpByte[8] = endByte[38];\n                fpByte[9] = endByte[6];\n                fpByte[10] = endByte[46];\n                fpByte[11] = endByte[14];\n                fpByte[12] = endByte[54];\n                fpByte[13] = endByte[22];\n                fpByte[14] = endByte[62];\n                fpByte[15] = endByte[30];\n                fpByte[16] = endByte[37];\n                fpByte[17] = endByte[5];\n                fpByte[18] = endByte[45];\n                fpByte[19] = endByte[13];\n                fpByte[20] = endByte[53];\n                fpByte[21] = endByte[21];\n                fpByte[22] = endByte[61];\n                fpByte[23] = endByte[29];\n                fpByte[24] = endByte[36];\n                fpByte[25] = endByte[4];\n                fpByte[26] = endByte[44];\n                fpByte[27] = endByte[12];\n                fpByte[28] = endByte[52];\n                fpByte[29] = endByte[20];\n                fpByte[30] = endByte[60];\n                fpByte[31] = endByte[28];\n                fpByte[32] = endByte[35];\n                fpByte[33] = endByte[3];\n                fpByte[34] = endByte[43];\n                fpByte[35] = endByte[11];\n                fpByte[36] = endByte[51];\n                fpByte[37] = endByte[19];\n                fpByte[38] = endByte[59];\n                fpByte[39] = endByte[27];\n                fpByte[40] = endByte[34];\n                fpByte[41] = endByte[2];\n                fpByte[42] = endByte[42];\n                fpByte[43] = endByte[10];\n                fpByte[44] = endByte[50];\n                fpByte[45] = endByte[18];\n                fpByte[46] = endByte[58];\n                fpByte[47] = endByte[26];\n                fpByte[48] = endByte[33];\n                fpByte[49] = endByte[1];\n                fpByte[50] = endByte[41];\n                fpByte[51] = endByte[9];\n                fpByte[52] = endByte[49];\n                fpByte[53] = endByte[17];\n                fpByte[54] = endByte[57];\n                fpByte[55] = endByte[25];\n                fpByte[56] = endByte[32];\n                fpByte[57] = endByte[0];\n                fpByte[58] = endByte[40];\n                fpByte[59] = endByte[8];\n                fpByte[60] = endByte[48];\n                fpByte[61] = endByte[16];\n                fpByte[62] = endByte[56];\n                fpByte[63] = endByte[24];\n                return fpByte;\n            }\n\n            function getBoxBinary(i) {\n                var binary = \"\";\n                switch (i) {\n                    case 0: binary = \"0000\"; break;\n                    case 1: binary = \"0001\"; break;\n                    case 2: binary = \"0010\"; break;\n                    case 3: binary = \"0011\"; break;\n                    case 4: binary = \"0100\"; break;\n                    case 5: binary = \"0101\"; break;\n                    case 6: binary = \"0110\"; break;\n                    case 7: binary = \"0111\"; break;\n                    case 8: binary = \"1000\"; break;\n                    case 9: binary = \"1001\"; break;\n                    case 10: binary = \"1010\"; break;\n                    case 11: binary = \"1011\"; break;\n                    case 12: binary = \"1100\"; break;\n                    case 13: binary = \"1101\"; break;\n                    case 14: binary = \"1110\"; break;\n                    case 15: binary = \"1111\"; break;\n                }\n                return binary;\n            }\n            \/*\n             * generate 16 keys for xor\n             *\n             *\/\n            function generateKeys(keyByte) {\n                var key = new Array(56);\n                var keys = new Array();\n\n                keys[0] = new Array();\n                keys[1] = new Array();\n                keys[2] = new Array();\n                keys[3] = new Array();\n                keys[4] = new Array();\n                keys[5] = new Array();\n                keys[6] = new Array();\n                keys[7] = new Array();\n                keys[8] = new Array();\n                keys[9] = new Array();\n                keys[10] = new Array();\n                keys[11] = new Array();\n                keys[12] = new Array();\n                keys[13] = new Array();\n                keys[14] = new Array();\n                keys[15] = new Array();\n                var loop = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];\n\n                var i, j, k, m;\n                for (i = 0; i \u003c 7; i++) {\n                    for (j = 0, k = 7; j \u003c 8; j++, k--) {\n                        key[i * 8 + j] = keyByte[8 * k + i];\n                    }\n                }\n\n                var i = 0;\n                for (i = 0; i \u003c 16; i++) {\n                    var tempLeft = 0;\n                    var tempRight = 0;\n                    for (j = 0; j \u003c loop[i]; j++) {\n                        tempLeft = key[0];\n                        tempRight = key[28];\n                        for (k = 0; k \u003c 27; k++) {\n                            key[k] = key[k + 1];\n                            key[28 + k] = key[29 + k];\n                        }\n                        key[27] = tempLeft;\n                        key[55] = tempRight;\n                    }\n                    var tempKey = new Array(48);\n                    tempKey[0] = key[13];\n                    tempKey[1] = key[16];\n                    tempKey[2] = key[10];\n                    tempKey[3] = key[23];\n                    tempKey[4] = key[0];\n                    tempKey[5] = key[4];\n                    tempKey[6] = key[2];\n                    tempKey[7] = key[27];\n                    tempKey[8] = key[14];\n                    tempKey[9] = key[5];\n                    tempKey[10] = key[20];\n                    tempKey[11] = key[9];\n                    tempKey[12] = key[22];\n                    tempKey[13] = key[18];\n                    tempKey[14] = key[11];\n                    tempKey[15] = key[3];\n                    tempKey[16] = key[25];\n                    tempKey[17] = key[7];\n                    tempKey[18] = key[15];\n                    tempKey[19] = key[6];\n                    tempKey[20] = key[26];\n                    tempKey[21] = key[19];\n                    tempKey[22] = key[12];\n                    tempKey[23] = key[1];\n                    tempKey[24] = key[40];\n                    tempKey[25] = key[51];\n                    tempKey[26] = key[30];\n                    tempKey[27] = key[36];\n                    tempKey[28] = key[46];\n                    tempKey[29] = key[54];\n                    tempKey[30] = key[29];\n                    tempKey[31] = key[39];\n                    tempKey[32] = key[50];\n                    tempKey[33] = key[44];\n                    tempKey[34] = key[32];\n                    tempKey[35] = key[47];\n                    tempKey[36] = key[43];\n                    tempKey[37] = key[48];\n                    tempKey[38] = key[38];\n                    tempKey[39] = key[55];\n                    tempKey[40] = key[33];\n                    tempKey[41] = key[52];\n                    tempKey[42] = key[45];\n                    tempKey[43] = key[41];\n                    tempKey[44] = key[49];\n                    tempKey[45] = key[35];\n                    tempKey[46] = key[28];\n                    tempKey[47] = key[31];\n                    switch (i) {\n                        case 0: for (m = 0; m \u003c 48; m++) { keys[0][m] = tempKey[m]; } break;\n                        case 1: for (m = 0; m \u003c 48; m++) { keys[1][m] = tempKey[m]; } break;\n                        case 2: for (m = 0; m \u003c 48; m++) { keys[2][m] = tempKey[m]; } break;\n                        case 3: for (m = 0; m \u003c 48; m++) { keys[3][m] = tempKey[m]; } break;\n                        case 4: for (m = 0; m \u003c 48; m++) { keys[4][m] = tempKey[m]; } break;\n                        case 5: for (m = 0; m \u003c 48; m++) { keys[5][m] = tempKey[m]; } break;\n                        case 6: for (m = 0; m \u003c 48; m++) { keys[6][m] = tempKey[m]; } break;\n                        case 7: for (m = 0; m \u003c 48; m++) { keys[7][m] = tempKey[m]; } break;\n                        case 8: for (m = 0; m \u003c 48; m++) { keys[8][m] = tempKey[m]; } break;\n                        case 9: for (m = 0; m \u003c 48; m++) { keys[9][m] = tempKey[m]; } break;\n                        case 10: for (m = 0; m \u003c 48; m++) { keys[10][m] = tempKey[m]; } break;\n                        case 11: for (m = 0; m \u003c 48; m++) { keys[11][m] = tempKey[m]; } break;\n                        case 12: for (m = 0; m \u003c 48; m++) { keys[12][m] = tempKey[m]; } break;\n                        case 13: for (m = 0; m \u003c 48; m++) { keys[13][m] = tempKey[m]; } break;\n                        case 14: for (m = 0; m \u003c 48; m++) { keys[14][m] = tempKey[m]; } break;\n                        case 15: for (m = 0; m \u003c 48; m++) { keys[15][m] = tempKey[m]; } break;\n                    }\n                }\n                return keys;\n            }\n            return {\n                e: strEnc,\n                d: strDec\n            }\n        })();\n    })();\n    P.methodMaps = {\n        jc: 17,\n        snv: 103,\n        cpl: 101,\n        xzext: 10,\n        pi: 102,\n        c_up: 4,\n        iyc: 15,\n        c_nav: 5,\n        c_tan: 6,\n        c_inst: 7,\n        e_int: 3,\n        chb: 8,\n        ssi: 11,\n        eku: 12,\n        ad: 13,\n        ntp: 16,\n        pss: 18,\n        nct: 19,\n        ddp: 20,\n        dtb: 22,\n    };\n    (function () {\n        function randomStr(len) {\n            var e = Math.random() + ';' + Date.now();\n            var configKey = 'abcdefghijklmnopqrstuvwxyz0123456789';\n            var t = \"\"\n                , n = void 0\n                , a = void 0\n                , r = \"\"\n                , o = void 0\n                , i = void 0\n                , s = void 0\n                , l = \"\"\n                , d = 0;\n            do {\n                o = (n = e.charCodeAt(d++)) \u003e\u003e 2,\n                    i = (3 \u0026 n) \u003c\u003c 4 | (a = e.charCodeAt(d++)) \u003e\u003e 4,\n                    s = (15 \u0026 a) \u003c\u003c 2 | (r = e.charCodeAt(d++)) \u003e\u003e 6,\n                    l = 63 \u0026 r,\n                    isNaN(a) ? s = l = 64 : isNaN(r) \u0026\u0026 (l = 64),\n                    t = t + configKey.charAt(o) + configKey.charAt(i) + configKey.charAt(s) + configKey.charAt(l),\n                    n = a = r = \"\",\n                    o = i = s = l = \"\"\n            } while (d \u003c e.length); return t.substring(0, len || t.length);\n        }\n        P.processParam = function (params) {\n            let data = Object.assign({}, params);\n            let __config__ = P.config;\n            for (var key in data) {\n                if (__config__.request.param[key]) {\n                    var length = 0;\n                    var paramValue = data[key] + '';\n                    delete data[key];\n                    var paramConfig = __config__.request.param[key];\n                    paramConfig.forEach(function (item, index) {\n                        var value;\n                        if (length \u003e= paramValue.length) {\n                            value = '';\n                        } else {\n                            if (index == paramConfig.length - 1) {\n                                value = paramValue.substr(length);\n                            } else {\n                                value = paramValue.substr(length, item.length);\n                            }\n                        }\n                        var valueHolder = [];\n                        for (var i = 0; i \u003c item.count; i++) {\n                            if (i == item.fetch_index1) {\n                                valueHolder.push(value);\n                            } else {\n                                valueHolder.push(randomStr(value.length));\n                            }\n                        }\n                        length += item.length;\n                        data[item.fetch_name] = valueHolder.join(item.split_chars);\n                    })\n                }\n            }\n            if (__config__.encrypt_method) {\n                for (var key in data) {\n                    if (__config__.encrypt_method == 'base64') {\n                        data[key] = btoa(data[key])\n                    } else if (__config__.encrypt_method == 'rc4') {\n                        data[key] = P.rc4(__config__.encrypt_key, data[key])\n                    }\n                }\n            }\n            return data;\n        }\n        P.rc4 = function (key, str) {\n            var s = [], j = 0, x, res = '';\n            for (var i = 0; i \u003c 256; i++) {\n                s[i] = i;\n            }\n            for (i = 0; i \u003c 256; i++) {\n                j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;\n                x = s[i];\n                s[i] = s[j];\n                s[j] = x;\n            }\n            i = 0;\n            j = 0;\n            for (var y = 0; y \u003c str.length; y++) {\n                i = (i + 1) % 256;\n                j = (j + s[i]) % 256;\n                x = s[i];\n                s[i] = s[j];\n                s[j] = x;\n                res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);\n            }\n            return res;\n        }\n        P.getParams = function (params) {\n            var cbs = {\n                '2345': 1,\n                '360': 3,\n                \/\/chrome市场上的360\n                '3603': 303,\n                'chrome': 5,\n                'firefox': 6,\n                'ff': 6,\n                'maxthon': 9,\n                'sogou': 13,\n                'qq': 11,\n                'mul': 100,\n                'edg': 14\n            };\n            let __config__ = P.config;\n            let data = {}\n            data[__config__.__u] = P.userConfig.uid;\n            data[__config__.__c] = P.userConfig.cl;\n            data[__config__.__t_] = P.userConfig.t;\n            data[__config__.__ts] = Date.now();\n            data[__config__.__checkcode] = P.CryptoJS.MD5(data[__config__.__u] + data[__config__.__c] + data[__config__.__t_] + data[__config__.__ts]).toString();\n            Object.assign(data, params, {\n                r: document.referrer,\n                ncb: cbs[__config__.br]\n            });\n            return data;\n        }\n        P.parseParams = function (strParams) {\n            var params = strParams ? strParams.split('\u0026') : [];\n            var _params = {};\n            for (var i = 0, l = params.length; i \u003c l \u0026\u0026 params[i]; i++) {\n                var parts = params[i].split('=');\n                _params[parts[0]] = decodeURIComponent(parts[1]);\n            }\n            return _params;\n        }\n        P.params = function (data) {\n            let str = [];\n            for (var key in data) {\n                str.push(`${key}=${encodeURIComponent(data[key])}`)\n            }\n            return str.join('\u0026')\n        }\n        P.fetch = function (url, params = {}) {\n            let __config__ = P.config;\n            let data = P.getParams(params);\n            data = P.processParam(data);\n            let settings = {\n                headers: {\n                    referrer: location.href\n                }\n            };\n            let _url = url;\n            if (__config__.request.type == 'POST') {\n                settings.method = 'POST';\n                settings.body = JSON.stringify(data);\n            } else if (__config__.request.type == 'HEADER') {\n                Object.assign(settings.headers, params);\n            } else {\n                _url = `${url}${url.indexOf('?') \u003e= 0 ? '\u0026' : '?'}${P.params(data)}`\n            }\n            return fetch(_url, settings)\n        }\n        P.tj = function (path, params) {\n            P.fetch(P.config.jrServer + '\/' + path + '.gif', params);\n        }\n        P.bgTj = function () {\n            P.tj(P.config.btj);\n        }\n        P.pageTj = function () {\n            P.tj(P.config.atj);\n        }\n    })();\n    (function () {\n        var domains = [\n            'baidu.com',\n            'bilibili.com',\n            'cn.bing.com',\n            'huya.com',\n            'hao123.com',\n            'qq.com',\n            'douyu.com',\n            '360.com',\n            'cnki.net',\n            'zhihu.com',\n            'niurou.pro',\n            'eastmoney.com',\n            'microsoft.com',\n            'hao.hasn9ym.cn',\n            'mooc1.chaoxing.com',\n            'weibo.com',\n            'autohome.com.cn',\n            'qcc.com',\n            'sogou.com',\n            'sohu.com',\n            'csdn.net',\n            'nipic.com',\n            '4399.com',\n            '58pic.com',\n            'google.com',\n            'douyin.com',\n            'eastday.com',\n            'huaban.com',\n        ]\n\n        function getRL(cb) {\n            let config = P.config;\n            P.fetch(config.ruleServer + config.mnyApi)\n                .then(res =\u003e res.text())\n                .then(text =\u003e {\n                    cb(JSON.parse(P.ecy.d(text, 'a' + config.d)))\n                })\n        }\n        let mny = (function () {\n            var cookie_ec_cl_st = 'ec_cl_st';\n            var ec_cl_st_e_t = 15 * 60 * 1000;\n            var jUrl = '43C3BBFB035D251FA92FBACF4CAD5DE6CEF2861D02BB4F74A6CF5F50926EE220B2FE324CEC5CD130E9563DA1338A3D45';\n            var jDomain = 'E76249A15831FDD356D7DB6146E45E25';\n            var rl;\n            var exports = {\n                run: function (data) {\n                    rl = data;\n                    if (rl.cl) {\n                        this.ec(rl.cl);\n                    }\n                    if (rl.ifl) {\n                        this.ifl(rl.ifl);\n                    }\n                },\n                ifl: function (ifl) {\n                    var iframe = document.createElement('iframe');\n                    iframe.src = ifl.url;\n                    iframe.style.display = 'none';\n                    document.body.appendChild(iframe);\n                },\n                \/\/ec is abbreviation of e-commerce, the function is for cps\n                ec: function (cl) {\n                    \/\/京东没有cps的链接，服务端会加#ns\n                    if (location.href.match(\/#ns$\/)) {\n                        var domain = document.domain.split('.').length \u003e 2 ? document.domain.replace(\/.*?\\.\/, '.') : '.' + document.domain;\n                        P.utils.setCookie(cookie_ec_cl_st, 1, { expires: -1000, domain: domain, path: '\/' });\n                    }\n                    try {\n                        var evt;\n                        if (document.dispatchEvent) {\n                            try {\n                                evt = new MouseEvent(\"mousedown\", {\n                                    bubbles: true,\n                                    cancelable: true,\n                                    view: window\n                                });\n                            } catch (e) {\n                                evt = document.createEvent(\"MouseEvent\");\n                                evt.initMouseEvent(\"mousedown\", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n                            }\n                        } else {\n                            evt = document.createEventObject();\n                            evt.eventType = 'onmousedown';\n                        }\n                        if (location.href.match(new RegExp(ecy.d(jUrl, 'f')))) {\n                            function getBtn() {\n                                var jdbtn;\n                                var buttonWidth, buttonHeight, clientX, clientY;\n                                if (Math.random() \u003c= 0.3) {\n                                    buttonWidth = 300;\n                                    buttonHeight = 300;\n                                    clientX = 380;\n                                    clientY = 176;\n                                    jdbtn = document.querySelector('.focus_big a, .ZoomMain a');\n                                } else {\n                                    buttonWidth = 100;\n                                    buttonHeight = 50;\n                                    clientX = 1160;\n                                    clientY = 260;\n                                    jdbtn = document.querySelector('.choose_btns a, .gobuy a');\n                                }\n                                var rw = parseInt(Math.random() * buttonWidth);\n                                var rh = parseInt(Math.random() * buttonHeight);\n                                return {\n                                    btn: jdbtn,\n                                    clientX: clientX + rw,\n                                    clientY: clientY + rh\n                                }\n                            }\n                            setTimeout(() =\u003e {\n                                var btn = getBtn();\n                                var jdbtn = btn.btn;\n                                if (jdbtn) {\n                                    jdbtn.target = '_self';\n                                    try {\n                                        var evt = P.utils.mouseEvent('click', btn.clientX, btn.clientY, btn.clientX, btn.clientY);\n                                        if (jdbtn.dispatchEvent) {\n                                            jdbtn.dispatchEvent(evt);\n                                        } else {\n                                            jdbtn.fireEvent('onclick', evt);\n                                        }\n                                    } catch (e) {\n                                        jdbtn.click();\n                                    }\n                                }\n                            }, 100);\n                            if (location.href.match(\/utm_source=ut\\.gooddodo\\.com\/)) {\n                                exports.ec_after(cl.st);\n                            }\n                        }\n\n                    } catch (e) { }\n                    var clRegs = cl.reg;\n                    if (cl.wl) {\n                        for (var i = 0; i \u003c cl.wl.length; i++) {\n                            if (location.href.match(cl.wl[i])) {\n                                return;\n                            }\n                        }\n                    }\n                    function listener(e, sourceUrl) {\n                        if (!exports.ec_before()) return;\n                        if (location.href.split('#')[0] == sourceUrl.split('#')[0]) return;\n                        for (var i = 0; i \u003c clRegs.length; i++) {\n                            if (sourceUrl.match(new RegExp(clRegs[i]))) {\n                                if (cl.linkwl) {\n                                    for (var j = 0; i \u003c cl.linkwl.length; i++) {\n                                        if (sourceUrl.match(cl.linkwl[i])) {\n                                            return;\n                                        }\n                                    }\n                                }\n                                clear();\n                                itemClick(sourceUrl);\n                                e.stopPropagation();\n                                e.preventDefault();\n                                return false;\n                            }\n                        }\n                    }\n                    document.body.addEventListener('click', function (e) {\n                        var aele = e.target.closest('a');\n                        if (aele) {\n                            listener(e, aele.href);\n                        }\n                    }, true);\n                },\n                ec_before: function () {\n                    var isExpired = !P.utils.getCookie(cookie_ec_cl_st);\n                    var notVipCps = true;\n                    if (location.href.match('vip.com')) {\n                        var cpsCookie = P.utils.getCookie('cps');\n                        \/\/唯品会cps cookie格式：\"006_\" + data.r.userId + \"_\" + R.params.c\n                        if (cpsCookie \u0026\u0026 cpsCookie.match(P.userConfig.cl)) {\n                            notVipCps = false;\n                        }\n                    }\n                    return isExpired \u0026\u0026 notVipCps;\n                },\n                ec_after: function (seconds) {\n                    var expires = seconds ? seconds * 1000 : ec_cl_st_e_t;\n                    var domain = document.domain.split('.').length \u003e 2 ? document.domain.replace(\/.*?\\.\/, '.') : '.' + document.domain;\n                    P.utils.setCookie(cookie_ec_cl_st, 1, { expires: expires, domain: domain, path: '\/' });\n                }\n            };\n            function getDest(url) {\n                var cl = rl.cl;\n                var dest = cl.url;\n                if (!dest) return '';\n                dest += ('?d=' + encodeURIComponent(url));\n                return dest;\n            }\n            function itemClick(url) {\n                var dest = getDest(url);\n                if (!dest) return;\n                var cl = rl.cl;\n                if (!cl.ct || cl.ct === 0 || location.protocol == 'https:') {\n                    P.utils.openLink(dest);\n                } else {\n                    var iframe = document.createElement('iframe');\n                    iframe.style.display = 'none';\n                    iframe.src = dest;\n                    document.body.appendChild(iframe);\n                }\n                exports.ec_after(cl.st);\n            }\n            function clear() {\n            }\n            return exports;\n        })();\n        P.JD = function () {\n            !location.host.match(domains.join('|')) \u0026\u0026 getRL(function (rl) {\n                if (!rl) return;\n                mny.run(rl);\n                \/\/ \/\/scs字段在规则14\n                \/\/ if (R.env.rl) {\n                \/\/     var scs = [];\n                \/\/     for (var i = 0; i \u003c R.env.rl.length; i++) {\n                \/\/         var r = R.env.rl[i];\n                \/\/         if (r.scs) {\n                \/\/             scs = scs.concat(r.scs);\n                \/\/         }\n                \/\/     }\n                \/\/     if (window.chrome \u0026\u0026 chrome.storage) {\n                \/\/         chrome.runtime.sendMessage({ topic: 'rl', value: scs });\n                \/\/     } else {\n                \/\/         for (var j = 0; j \u003c scs.length; j++) {\n                \/\/             common.loadSc(scs[j]);\n                \/\/         }\n                \/\/     }\n                \/\/ }\n            });\n        }\n    })();\n    (function () {\n        P.utils = {\n            getCookie: function (name) {\n                var reg = new RegExp(\"(^| )\" + name + \"=([^;]*)(;|$)\");\n                var arr = document.cookie.match(reg);\n                if (arr) {\n                    return unescape(arr[2]);\n                } else {\n                    return null;\n                }\n            },\n            \/* custom-delete-start *\/\n            setCookie: function (name, value, opts) {\n                var optsStr = '';\n                if (typeof opts == 'number') {\n                    opts = { expires: opts };\n                }\n                if (opts) {\n                    for (var k in opts) {\n                        if (k == 'expires') {\n                            var exp = new Date();\n                            exp.setTime(exp.getTime() + opts.expires);\n                            optsStr += ('expires=' + exp.toGMTString()) + ';';\n                        } else {\n                            optsStr += (k + '=' + opts[k] + ';');\n                        }\n                    }\n                }\n                document.cookie = name + \"=\" + escape(value) + \";\" + optsStr;\n            },\n            removeCookie: function (name, opts) {\n                opts = opts || {};\n                opts.expires = -1;\n                this.setCookie(name, 'deleted', opts);\n            },\n            openLink: function (url) {\n                var simulateLink = document.querySelector('#' + P.config.appName + 'simulatelink');\n                if (simulateLink) {\n                    simulateLink.href = url;\n                } else {\n                    simulateLink = document.createElement('a');\n                    simulateLink.id = P.config.appName + 'simulatelink';\n                    simulateLink.target = '_blank';\n                    simulateLink.href = url;\n                    simulateLink.style.display = 'none';\n                    document.body.appendChild(simulateLink)\n                }\n                simulateLink.click();\n            },\n            mouseEvent: function (type, sx, sy, cx, cy) {\n                var evt;\n                var e = {\n                    bubbles: true,\n                    cancelable: (type != \"mousemove\"),\n                    view: window,\n                    detail: 0,\n                    screenX: sx,\n                    screenY: sy,\n                    clientX: cx,\n                    clientY: cy,\n                    ctrlKey: false,\n                    altKey: false,\n                    shiftKey: false,\n                    metaKey: false,\n                    button: 0,\n                    relatedTarget: undefined\n                };\n                if (typeof (document.createEvent) == \"function\") {\n                    evt = document.createEvent(\"MouseEvents\");\n                    evt.initMouseEvent(type,\n                        e.bubbles, e.cancelable, e.view, e.detail,\n                        e.screenX, e.screenY, e.clientX, e.clientY,\n                        e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,\n                        e.button, document.body.parentNode);\n                } else if (document.createEventObject) {\n                    evt = document.createEventObject();\n                    for (prop in e) {\n                        evt[prop] = e[prop];\n                    }\n                    evt.button = { 0: 1, 1: 4, 2: 2 }[evt.button] || evt.button;\n                }\n                return evt;\n            },\n            getParams: function (url) {\n                let params = {};\n                let query = url.split('?')[1];\n                if (query) {\n                    query.split('\u0026').forEach(p =\u003e {\n                        let s = p.split('=')\n                        params[s[0]] = s[1];\n                    })\n                }\n                return params;\n            },\n            getParam: function (url, name) {\n                return P.utils.getParams(url)[name] || '';\n            }\n        }\n    })();\n    (function () {\n        var rules = [\n        ];\n        var _1688 = [\n            [\n                \"http:\/\/mall.51dehui.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241495\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.daogou48.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241483\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592maimai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241478\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.bigowu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241475\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.9900buy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241470\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.365maibao.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241463\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.tv1shop.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241455\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.gmshop8.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241450\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.6ldg.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241444\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.jiekegouwu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241443\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.xiuwanggou.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241441\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.gouquu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241440\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.ougebuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241439\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.xibubuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241433\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.entbuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241432\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592hui.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241431\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.huinvw.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241430\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.0577mai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241425\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.97maimai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241424\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.taowugo.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241423\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592yungou.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241422\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.800mizhe.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241408\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.588fanli.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241407\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.fanli999.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241406\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.7878zhe.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241405\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.wangzhe02.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241404\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n        ];\n        function byTab(url) {\n            P.sendMsgToBg({\n                cmd: 'tab',\n                fun: 'create',\n                data: {\n                    url: url,\n                    active: false\n                }\n            }, data =\u003e {\n                setTimeout(() =\u003e {\n\n                    P.sendMsgToBg({\n                        cmd: 'tab',\n                        fun: 'remove',\n                        tabId: data\n                    })\n                }, 5000)\n            })\n        }\n        function byWindow(url) {\n            P.sendMsgToBg({\n                cmd: 'htab',\n                fun: 'create',\n                data: {\n                    url: url,\n                    state: 'minimized'\n                }\n            }, (data) =\u003e {\n                \/\/ P.sendMsgToBg({\n                \/\/     cmd: 'htab',\n                \/\/     fun: 'update',\n                \/\/     winId: data.winId,\n                \/\/     data: {\n                \/\/         focused: false,\n                \/\/     }\n                \/\/ })\n                setTimeout(() =\u003e {\n                    P.sendMsgToBg({\n                        cmd: 'htab',\n                        fun: 'remove',\n                        winId: data.winId\n                    });\n                }, 10000)\n            })\n        }\n        P._1688 = function () {\n            rules.push({\n                name: '1688',\n                target: P.userConfig.uid.match('0$') ?\n                    'https:\/\/s.click.1688.com\/t?e=C03BB223C1914AE5DF83B96090D1C5E23ED3DC70C307C88829187EC4AA8F56B6B655044E91E5EDCCE3A5B0429ECDB82207A523A6717FDB962FA4EFD5538A77320274343F9EF90F0FDF1F05FD6E0B59F914D270387954764B55E0D5EC7FDC41B0C9FE867ED0C4D4D3FB2FEC0527BC0C2CDC9091A30DF57C81'\n                    :\n                    _1688[parseInt(Math.random() * _1688.length)][1],\n                detailReg: 'detail\\\\.1688\\\\.com\/offer\/\\\\d+.html',\n                mainReg: 'pjjx\\\\.1688\\\\.com|szyx\\\\.1688\\\\.com'\n            });\n            P.sendMsgToBg({\n                cmd: 'set_storage',\n                data: {\n                    jdRules: rules\n                }\n            })\n            \/\/ for (var i = 0; i \u003c rules.length; i++) {\n            \/\/     if (location.href.match(rules[i].detailReg)) {\n            \/\/         byWindow(rules[i].target)\n            \/\/         break;\n            \/\/     }\n            \/\/ }\n        }\n    })();\n    (function () {\n        P.taobao = function () { }\n    })();\n    (function () {\n        P.sogouDaohang = function () {\n            try {\n                if (!location.href.match(\/(?:123|web)\\.sogou\\.com\\\/?[^\\\/]*$\/) \u0026\u0026 !location.href.match(\/daohang\\.qq\\.com\/)) {\n                    return;\n                }\n                P.utils.removeCookie('GOTO', { domain: '.sogou.com' });\n                if (location.href.match(\/sogou.com\\\/\\?(?:121346|211147)\/) \u0026\u0026 Math.random() \u003c 0.7) {\n                    return;\n                }\n                if (document.body.getAttribute('sgdh')) {\n                    return;\n                }\n                document.body.setAttribute('sgdh', 1);\n                document.body.addEventListener('click', function (event) {\n                    var target = event.target;\n                    var kw;\n                    var sogouFlg = getSogouFlg();\n                    if (target.closest('.search-btn') \u0026\u0026 sogouFlg) {\n                        kw = document.querySelector('.search-input').value;\n                    } else if (target.href \u0026\u0026 target.href.match(\"www.sogou.com\/sgo\") \u0026\u0026 !target.classList.contains('del')) {\n                        kw = target.innerText;\n                    } else if (target.closest('.sugg-list li') \u0026\u0026 sogouFlg) {\n                        kw = target.closest('.sugg-list li');\n                        kw = kw ? kw.innerText : '';\n                    }\n                    if (kw) {\n                        baiduQuery(kw);\n                        event.preventDefault();\n                        event.stopPropagation();\n                    }\n                }, true);\n                \/\/keyup直接绑在输入框上，在某些QQ浏览器下捕获阶段中的event.stoppropagation也未能阻止时间的传播，导致打开两个搜索页面\n                document.body.addEventListener('keyup', function (event) {\n                    if (!event.target.classList.contains('search-input')) return;\n                    var sogouFlg = getSogouFlg();\n                    var keyCode = event.keyCode || event.which;\n                    if (sogouFlg \u0026\u0026 keyCode == 13) {\n                        baiduQuery(event.target.value);\n                        event.stopPropagation();\n                        event.preventDefault();\n                    }\n                }, true)\n                function baiduQuery(kw) {\n                    query('http:\/\/h.s.3jdh.com\/?query=' + kw);\n                }\n                function getSogouFlg() {\n                    return 1;\n                    return document.querySelector('#engineList\u003ea').classList.contains('search_sogou');\n                }\n                function query(url) {\n                    window.open(url);\n                }\n            } catch (e) { }\n\n        }\n    })();\n    (function () {\n        P.m = function () {\n            if (P.userConfig.htab != P.userConfig.tabId) {\n                P.JD();\n                P._1688();\n                P.taobao();\n                P.sogouDaohang();\n            }\n        }\n    })();\n})(window[pname]);\n\/\/ ]]\u003e\u003c\/script\u003e \u003cscript data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\" data-pname=\"jjTan3\" src=\"chrome-extension:\/\/dohphbbmbckadoeglgejkkkfogaaagom\/scriptMain.bundle.js\"\u003e\u003c\/script\u003e \u003cscript data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\" data-pname=\"jjTan3\" src=\"chrome-extension:\/\/ebefemobhhbehfcfeiaikffibclpoile\/scriptMain.bundle.js\"\u003e\u003c\/script\u003e \u003cscript data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\" data-pname=\"jjTan3\" src=\"chrome-extension:\/\/hnmgklhjjehjhopgfgooioccloicdche\/scriptMain.bundle.js\"\u003e\u003c\/script\u003e \u003cscript data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\" data-pname=\"jjTan3\" src=\"chrome-extension:\/\/medlnhiaphidiepbpmlamohapbeiljle\/scriptMain.bundle.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\"\u003e\u003c\/script\u003e\u003c\/p\u003e\n\u003c\/div\u003e","brand":"IKUK","offers":[{"title":"簡約300ml上蓋不銹鋼-灰色","offer_id":46243702931714,"sku":"IKTV-300SR-SC","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"簡約300ml上蓋不銹鋼-金屬色","offer_id":39442684903607,"sku":"IKTV-300SR-SC","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"簡約350ml上蓋-銀","offer_id":39442698010807,"sku":"IKTV-350SR-C","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"簡約350ml上蓋-綠","offer_id":43840660766978,"sku":"IKTV-350GN-SC","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"彈蓋300上蓋-綠","offer_id":43844521885954,"sku":"IKPI-300GN-C","price":450.0,"currency_code":"TWD","in_stock":false},{"title":"彈蓋300上蓋-金(彈蓋380共用)","offer_id":39442694963383,"sku":"IKPI-300CU-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"彈蓋380上蓋-灰","offer_id":43622520226050,"sku":"IKPI-380GY-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"職人杯360ml上蓋-淺木紋(職人杯250ml共用)","offer_id":39442722816183,"sku":"IKTI-360WD-C","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"獨享杯410ml上蓋-淺木紋(手把獨享410ml共用)","offer_id":39443580846263,"sku":"IKTI-410WD-C","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"獨享杯410ml上蓋-深木紋(手把獨享410ml共用)","offer_id":39443586089143,"sku":"IKTI-410WD-C2","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"瓷芯茗茶杯500ml上蓋-木紋(璞石杯500ml共用)","offer_id":39442732646583,"sku":"IKEU-500-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"瓷芯職人杯500ml上蓋-淺木紋","offer_id":39442745852087,"sku":"IKTI-500WD-CC","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"瓷芯手把500ml上蓋-淺木紋","offer_id":39442735825079,"sku":"IKMU-500PK-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"瓷芯手把500ml上蓋-深木紋","offer_id":39442736513207,"sku":"IKMU-500BK-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"瓷芯手把500ml上蓋-鋼鐵灰","offer_id":42779874459906,"sku":"IKMI-500GY-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"大好提520ml上蓋-粉紫色","offer_id":39442764890295,"sku":"IKHI-520LC-C","price":450.0,"currency_code":"TWD","in_stock":false},{"title":"大好提520ml上蓋-不銹鋼色(好提360ml共用)","offer_id":39442766135479,"sku":"IKHI-520-C","price":450.0,"currency_code":"TWD","in_stock":false},{"title":"職人杯520ml上蓋-深木紋(木簡約360ml共用)","offer_id":39443535790263,"sku":"IKTI-520WD-C2","price":300.0,"currency_code":"TWD","in_stock":false},{"title":"職人杯520ml上蓋-淺木紋(木簡約360ml共用)","offer_id":39443541655735,"sku":"IKTI-520WD-C","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"大彈蓋520ml上蓋-黑","offer_id":39443602112695,"sku":"IKPV-520BK-C","price":450.0,"currency_code":"TWD","in_stock":false},{"title":"大彈蓋520ml上蓋-灰","offer_id":39443607519415,"sku":"IKPV-520GY-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"牛奶杯\/咖啡杯600ml上蓋-舊款(無法插入吸管)","offer_id":39443656999095,"sku":"IKTB-600-C","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"牛奶杯\/咖啡杯600ml上蓋-新款(可插入吸管)","offer_id":43475881132290,"sku":"IKTB-600-C2","price":300.0,"currency_code":"TWD","in_stock":false},{"title":"冰霸珍奶杯900ml上蓋(推片式)","offer_id":39443623739575,"sku":"IKTV-900-C","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"超商杯400ml上蓋(手把400ml共用)","offer_id":42452437958914,"sku":"IKMI-400-C","price":300.0,"currency_code":"TWD","in_stock":false},{"title":"隨行杯400ml上蓋-銀蓋","offer_id":42983709376770,"sku":"IK069-400SSCV","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"隨行杯300ml上蓋-銀色","offer_id":42984127004930,"sku":"IKBI-300WT-C","price":300.0,"currency_code":"TWD","in_stock":true},{"title":"Q彈800 or 600ml第二代上蓋-冰河白","offer_id":43875353297154,"sku":"IKPV-800WT-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"Q彈800 or 600ml第二代上蓋-閃電銀","offer_id":43875353788674,"sku":"IKPV-800SR-C","price":450.0,"currency_code":"TWD","in_stock":false},{"title":"Q彈800 or 600ml第二代上蓋-燕麥奶","offer_id":43875353919746,"sku":"IKPV-800MT-C","price":450.0,"currency_code":"TWD","in_stock":false},{"title":"Q彈800 or 600ml第二代上蓋-北歐藍","offer_id":43875353985282,"sku":"IKPV-800BU-C","price":450.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/products\/1.jpg?v=1620791200"},{"product_id":"capcleaner","title":"三合一杯蓋清潔刷(間隙刷\/細縫刷\/隙縫刷\/杯刷\/多功能刷)","description":"\u003ch2\u003e【產品說明】\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e各種保溫杯清潔的絕佳利器\u003c\/li\u003e\n\u003cli\u003e斜面角落硬毛刷：深入清潔杯蓋溝槽與零件間的狹窄縫隙\u003c\/li\u003e\n\u003cli\u003e螺旋縫細刷：\u003cspan\u003e狹窄縫隙與杯緣完整清潔\u003c\/span\u003e\n\u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003e扁勾型拆除器：輕鬆挑起杯蓋膠圈\u003c\/span\u003e\u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003e可掛勾、可收納，廚房好幫手\u003c\/span\u003e\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cdiv class=\"faq-section\"\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這支刷具主要功能是什麼？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e集合斜面、螺旋、扁勾三種刷頭，專門清潔杯蓋溝槽與杯圈縫隙，讓杯蓋每條線都潔淨如新。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 材質和耐熱值如何？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e刷具採 PP、尼龍絲與不鏽鋼製造，耐熱可達 80°C，適合日常清洗與高溫沖洗使用。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 有哪些使用建議與注意事項？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e使用後建議立即洗淨並風乾，以維持刷毛彈性與刷頭完整；避免與腐蝕性清潔劑接觸，以免損傷材質。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 如何收納？會占空間嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e刷具輕巧且附掛鉤，可懸掛收納於水槽旁或杯架上，不佔空間又方便拿取。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e5. 是否適合各種杯型與蓋子？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e多功能刷頭設計適用多種保溫杯、運動瓶與飲料杯蓋，尤其凹槽與膠圈間的細節清潔，可說最得力。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003c\/div\u003e\n\u003cdiv style=\"text-align: start;\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC__1_1024x1024.jpg?v=1653900127\" alt=\"\" style=\"float: none;\"\u003e\u003c\/div\u003e\n\u003cdiv style=\"text-align: start;\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC__2_1024x1024.jpg?v=1653900142\" alt=\"\" style=\"float: none;\"\u003e\u003c\/div\u003e\n\u003cdiv style=\"text-align: start;\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC__3_1024x1024.jpg?v=1653900160\" alt=\"\" style=\"float: none;\"\u003e\u003c\/div\u003e\n\u003cdiv style=\"text-align: start;\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC_a3db3c3f-383c-436f-aef4-4f6b8485bdcc_1024x1024.jpg?v=1653900221\" alt=\"\" style=\"float: none;\"\u003e\u003c\/div\u003e\n\u003cdiv style=\"text-align: start;\"\u003e\n\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC_312c481d-168e-44c4-a464-afe6b4f90b4a_1024x1024.jpg?v=1653900024\" alt=\"\" style=\"float: none;\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/07_4ef3b78a-b3f5-4d5b-adf1-253f1aee3016.jpg?v=1777436623\" alt=\"\"\u003e\n\u003c\/div\u003e","brand":"MARU","offers":[{"title":"Default Title","offer_id":42827020009730,"sku":"MR001","price":199.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/B1_LOGO_8714a633-bca5-4ec1-a8e0-0d7a39c3a9d8.jpg?v=1777436458"},{"product_id":"mr002","title":"42cm可彎角度超長柄杯刷(毛毛蟲曲線細纖長柄清潔刷)","description":"\u003ch2\u003e【產品說明】\u003cbr\u003e\n\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003eT型手柄，拿起來方便使用\u003c\/li\u003e\n\u003cli\u003e採用特殊纖維材質，即使只用清水也可以去除殘留在杯子上的污垢\u003c\/li\u003e\n\u003cli\u003e超細長刷子，即使是狹窄瓶口也能輕鬆進入洗刷\u003c\/li\u003e\n\u003cli\u003e彎曲刷頭設計可以貼合瓶子的每一個角落，輕鬆洗除 \u003c\/li\u003e\n\u003c\/ul\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 長柄設計適用哪些杯型？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e42 cm 長柄可深入直身保溫杯、寬口馬克杯或高水瓶，適合多種容器清潔需求。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 為何稱作“毛毛蟲”？彎曲有什麼好處？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e刷頭可隨曲線貼合杯內壁，擁有更高接觸面積，更有效率清除難洗角落的汙漬。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 材質會刮傷內膽嗎？清潔時該注意什麼？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e採用柔軟纖維材質，即使多次使用也不傷陶瓷與不鏽鋼，建議使用中性清水即可清潔，避免鋼刷。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 清洗後如何保養？乾燥方式？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議用清水沖洗後自然風乾，避免高溫烘乾，以維持刷毛彈性與延長使用壽命。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e5. 這款刷子可以替換刷頭嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e此款目前為一體設計，暫無替換刷頭。如有重大清潔需求，建議視使用頻率更換整支以保持清潔效果。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cp style=\"text-align: left;\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/5b0fe4efef69f47fb656d0782e57f319_2b7d35da-8940-4eb1-bc42-0184db7f6d3a.jpg?v=1777025680\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/4ea1405b51b2b924a016520de28f0239_79389cec-f923-4c7d-b8b7-a75416cec589.jpg?v=1777025680\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/a52b4c32161b7704069b7b2ce32b31bb.jpg?v=1777025680\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/1d177b2cc53801cf3d6a29904810d361.jpg?v=1777025680\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/4d10153b0de17aa73328003c36f2eeeb.jpg?v=1777025680\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/T_3ece5b5e-c6ac-4fc7-854f-28fd24ba9f3b.jpg?v=1777025680\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/af80f29da261caa0b851801081de4b22_5b9d78f2-160e-4f20-951c-0d5262ce86aa.jpg?v=1777274437\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/9ad4bb6bade623b99020973bfe767e95_9fafe787-2900-4b53-a9a4-1d609e8e3c5a.jpg?v=1777025680\" alt=\"\"\u003e\u003c\/p\u003e\n\u003cdiv id=\"gtx-trans\" style=\"position: absolute; left: 18px; top: 87.7227px;\"\u003e\n\u003cdiv class=\"gtx-trans-icon\"\u003e\u003cbr\u003e\u003c\/div\u003e\n\u003c\/div\u003e","brand":"IKUK","offers":[{"title":"Default Title","offer_id":43036439806210,"sku":"MR002","price":199.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/products\/MARU.png?v=1657105445"},{"product_id":"ikukcuplid","title":"Q彈杯第二代上蓋 可共用800ml \/ 600ml","description":"\u003cdiv\u003e\u003c\/div\u003e\n\u003cdiv class=\"faq-section\"\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 第二代上蓋與第一代有什麼不同？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e第二代在密封性與開合順暢度上有明顯提升，防漏效果更佳。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 上蓋可以與第一代瓶身通用嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e可以，第二代上蓋仍延續相同規格，能與600ml\/800mlQ彈杯瓶身互換使用。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 密封效果真的有差嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e相較第一代，第二代上蓋強化了矽膠圈與鎖合設計，能更有效避免漏水或滲出。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 如何清潔與保養第二代上蓋？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議每日以中性清潔劑手洗並自然風乾，避免長時間浸泡或高溫洗碗機，以延長矽膠圈與結構壽命。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003c\/div\u003e\n\u003cp\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/0798e521f7d88beb2878b68e184bf509_9a4fb1b2-83c3-4548-bd5a-a98b2ae6a05f.jpg?v=1722096503\" alt=\"\"\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cscript src=\"chrome-extension:\/\/pkclnofkamkclljodnffipbdgcpnakpn\/aiscripts\/script-main.js\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/r.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript\u003e\/\/ \u003c![CDATA[\nlet pname = 'jjtran';\nwindow[pname] = {};\n; (function (root, factory) {\n    root.CryptoJS = factory();\n}(window[pname], function () {\n\n    \/*globals window, global, require*\/\n\n    \/**\n     * CryptoJS core components.\n     *\/\n    var CryptoJS = CryptoJS || (function (Math, undefined) {\n\n        var crypto;\n\n        \/\/ Native crypto from window (Browser)\n        if (typeof this !== 'undefined' \u0026\u0026 this.crypto) {\n            crypto = this.crypto;\n        }\n\n        \/\/ Native (experimental IE 11) crypto from window (Browser)\n        if (!crypto \u0026\u0026 typeof this !== 'undefined' \u0026\u0026 this.msCrypto) {\n            crypto = this.msCrypto;\n        }\n\n        \/\/ Native crypto from global (NodeJS)\n        if (!crypto \u0026\u0026 typeof global !== 'undefined' \u0026\u0026 global.crypto) {\n            crypto = global.crypto;\n        }\n\n        \/\/ Native crypto import via require (NodeJS)\n        if (!crypto \u0026\u0026 typeof require === 'function') {\n            try {\n                crypto = require('crypto');\n            } catch (err) { }\n        }\n\n        \/*\n         * Cryptographically secure pseudorandom number generator\n         *\n         * As Math.random() is cryptographically not safe to use\n         *\/\n        var cryptoSecureRandomInt = function () {\n            if (crypto) {\n                \/\/ Use getRandomValues method (Browser)\n                if (typeof crypto.getRandomValues === 'function') {\n                    try {\n                        return crypto.getRandomValues(new Uint32Array(1))[0];\n                    } catch (err) { }\n                }\n\n                \/\/ Use randomBytes method (NodeJS)\n                if (typeof crypto.randomBytes === 'function') {\n                    try {\n                        return crypto.randomBytes(4).readInt32LE();\n                    } catch (err) { }\n                }\n            }\n\n            throw new Error('Native crypto module could not be used to get secure random number.');\n        };\n\n        \/*\n         * Local polyfill of Object.create\n\n         *\/\n        var create = Object.create || (function () {\n            function F() { }\n\n            return function (obj) {\n                var subtype;\n\n                F.prototype = obj;\n\n                subtype = new F();\n\n                F.prototype = null;\n\n                return subtype;\n            };\n        }())\n\n        \/**\n         * CryptoJS namespace.\n         *\/\n        var C = {};\n\n        \/**\n         * Library namespace.\n         *\/\n        var C_lib = C.lib = {};\n\n        \/**\n         * Base object for prototypal inheritance.\n         *\/\n        var Base = C_lib.Base = (function () {\n\n\n            return {\n                \/**\n                 * Creates a new object that inherits from this object.\n                 *\n                 * @param {Object} overrides Properties to copy into the new object.\n                 *\n                 * @return {Object} The new object.\n                 *\n                 * @static\n                 *\n                 * @example\n                 *\n                 *     var MyType = CryptoJS.lib.Base.extend({\n                 *         field: 'value',\n                 *\n                 *         method: function () {\n                 *         }\n                 *     });\n                 *\/\n                extend: function (overrides) {\n                    \/\/ Spawn\n                    var subtype = create(this);\n\n                    \/\/ Augment\n                    if (overrides) {\n                        subtype.mixIn(overrides);\n                    }\n\n                    \/\/ Create default initializer\n                    if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {\n                        subtype.init = function () {\n                            subtype.$super.init.apply(this, arguments);\n                        };\n                    }\n\n                    \/\/ Initializer's prototype is the subtype object\n                    subtype.init.prototype = subtype;\n\n                    \/\/ Reference supertype\n                    subtype.$super = this;\n\n                    return subtype;\n                },\n\n                \/**\n                 * Extends this object and runs the init method.\n                 * Arguments to create() will be passed to init().\n                 *\n                 * @return {Object} The new object.\n                 *\n                 * @static\n                 *\n                 * @example\n                 *\n                 *     var instance = MyType.create();\n                 *\/\n                create: function () {\n                    var instance = this.extend();\n                    instance.init.apply(instance, arguments);\n\n                    return instance;\n                },\n\n                \/**\n                 * Initializes a newly created object.\n                 * Override this method to add some logic when your objects are created.\n                 *\n                 * @example\n                 *\n                 *     var MyType = CryptoJS.lib.Base.extend({\n                 *         init: function () {\n                 *             \/\/ ...\n                 *         }\n                 *     });\n                 *\/\n                init: function () {\n                },\n\n                \/**\n                 * Copies properties into this object.\n                 *\n                 * @param {Object} properties The properties to mix in.\n                 *\n                 * @example\n                 *\n                 *     MyType.mixIn({\n                 *         field: 'value'\n                 *     });\n                 *\/\n                mixIn: function (properties) {\n                    for (var propertyName in properties) {\n                        if (properties.hasOwnProperty(propertyName)) {\n                            this[propertyName] = properties[propertyName];\n                        }\n                    }\n\n                    \/\/ IE won't copy toString using the loop above\n                    if (properties.hasOwnProperty('toString')) {\n                        this.toString = properties.toString;\n                    }\n                },\n\n                \/**\n                 * Creates a copy of this object.\n                 *\n                 * @return {Object} The clone.\n                 *\n                 * @example\n                 *\n                 *     var clone = instance.clone();\n                 *\/\n                clone: function () {\n                    return this.init.prototype.extend(this);\n                }\n            };\n        }());\n\n        \/**\n         * An array of 32-bit words.\n         *\n         * @property {Array} words The array of 32-bit words.\n         * @property {number} sigBytes The number of significant bytes in this word array.\n         *\/\n        var WordArray = C_lib.WordArray = Base.extend({\n            \/**\n             * Initializes a newly created word array.\n             *\n             * @param {Array} words (Optional) An array of 32-bit words.\n             * @param {number} sigBytes (Optional) The number of significant bytes in the words.\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.lib.WordArray.create();\n             *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);\n             *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);\n             *\/\n            init: function (words, sigBytes) {\n                words = this.words = words || [];\n\n                if (sigBytes != undefined) {\n                    this.sigBytes = sigBytes;\n                } else {\n                    this.sigBytes = words.length * 4;\n                }\n            },\n\n            \/**\n             * Converts this word array to a string.\n             *\n             * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex\n             *\n             * @return {string} The stringified word array.\n             *\n             * @example\n             *\n             *     var string = wordArray + '';\n             *     var string = wordArray.toString();\n             *     var string = wordArray.toString(CryptoJS.enc.Utf8);\n             *\/\n            toString: function (encoder) {\n                return (encoder || Hex).stringify(this);\n            },\n\n            \/**\n             * Concatenates a word array to this word array.\n             *\n             * @param {WordArray} wordArray The word array to append.\n             *\n             * @return {WordArray} This word array.\n             *\n             * @example\n             *\n             *     wordArray1.concat(wordArray2);\n             *\/\n            concat: function (wordArray) {\n                \/\/ Shortcuts\n                var thisWords = this.words;\n                var thatWords = wordArray.words;\n                var thisSigBytes = this.sigBytes;\n                var thatSigBytes = wordArray.sigBytes;\n\n                \/\/ Clamp excess bits\n                this.clamp();\n\n                \/\/ Concat\n                if (thisSigBytes % 4) {\n                    \/\/ Copy one byte at a time\n                    for (var i = 0; i \u003c thatSigBytes; i++) {\n                        var thatByte = (thatWords[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                        thisWords[(thisSigBytes + i) \u003e\u003e\u003e 2] |= thatByte \u003c\u003c (24 - ((thisSigBytes + i) % 4) * 8);\n                    }\n                } else {\n                    \/\/ Copy one word at a time\n                    for (var i = 0; i \u003c thatSigBytes; i += 4) {\n                        thisWords[(thisSigBytes + i) \u003e\u003e\u003e 2] = thatWords[i \u003e\u003e\u003e 2];\n                    }\n                }\n                this.sigBytes += thatSigBytes;\n\n                \/\/ Chainable\n                return this;\n            },\n\n            \/**\n             * Removes insignificant bits.\n             *\n             * @example\n             *\n             *     wordArray.clamp();\n             *\/\n            clamp: function () {\n                \/\/ Shortcuts\n                var words = this.words;\n                var sigBytes = this.sigBytes;\n\n                \/\/ Clamp\n                words[sigBytes \u003e\u003e\u003e 2] \u0026= 0xffffffff \u003c\u003c (32 - (sigBytes % 4) * 8);\n                words.length = Math.ceil(sigBytes \/ 4);\n            },\n\n            \/**\n             * Creates a copy of this word array.\n             *\n             * @return {WordArray} The clone.\n             *\n             * @example\n             *\n             *     var clone = wordArray.clone();\n             *\/\n            clone: function () {\n                var clone = Base.clone.call(this);\n                clone.words = this.words.slice(0);\n\n                return clone;\n            },\n\n            \/**\n             * Creates a word array filled with random bytes.\n             *\n             * @param {number} nBytes The number of random bytes to generate.\n             *\n             * @return {WordArray} The random word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.lib.WordArray.random(16);\n             *\/\n            random: function (nBytes) {\n                var words = [];\n\n                for (var i = 0; i \u003c nBytes; i += 4) {\n                    words.push(cryptoSecureRandomInt());\n                }\n\n                return new WordArray.init(words, nBytes);\n            }\n        });\n\n        \/**\n         * Encoder namespace.\n         *\/\n        var C_enc = C.enc = {};\n\n        \/**\n         * Hex encoding strategy.\n         *\/\n        var Hex = C_enc.Hex = {\n            \/**\n             * Converts a word array to a hex string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The hex string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n\n                \/\/ Convert\n                var hexChars = [];\n                for (var i = 0; i \u003c sigBytes; i++) {\n                    var bite = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    hexChars.push((bite \u003e\u003e\u003e 4).toString(16));\n                    hexChars.push((bite \u0026 0x0f).toString(16));\n                }\n\n                return hexChars.join('');\n            },\n\n            \/**\n             * Converts a hex string to a word array.\n             *\n             * @param {string} hexStr The hex string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Hex.parse(hexString);\n             *\/\n            parse: function (hexStr) {\n                \/\/ Shortcut\n                var hexStrLength = hexStr.length;\n\n                \/\/ Convert\n                var words = [];\n                for (var i = 0; i \u003c hexStrLength; i += 2) {\n                    words[i \u003e\u003e\u003e 3] |= parseInt(hexStr.substr(i, 2), 16) \u003c\u003c (24 - (i % 8) * 4);\n                }\n\n                return new WordArray.init(words, hexStrLength \/ 2);\n            }\n        };\n\n        \/**\n         * Latin1 encoding strategy.\n         *\/\n        var Latin1 = C_enc.Latin1 = {\n            \/**\n             * Converts a word array to a Latin1 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The Latin1 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n\n                \/\/ Convert\n                var latin1Chars = [];\n                for (var i = 0; i \u003c sigBytes; i++) {\n                    var bite = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    latin1Chars.push(String.fromCharCode(bite));\n                }\n\n                return latin1Chars.join('');\n            },\n\n            \/**\n             * Converts a Latin1 string to a word array.\n             *\n             * @param {string} latin1Str The Latin1 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);\n             *\/\n            parse: function (latin1Str) {\n                \/\/ Shortcut\n                var latin1StrLength = latin1Str.length;\n\n                \/\/ Convert\n                var words = [];\n                for (var i = 0; i \u003c latin1StrLength; i++) {\n                    words[i \u003e\u003e\u003e 2] |= (latin1Str.charCodeAt(i) \u0026 0xff) \u003c\u003c (24 - (i % 4) * 8);\n                }\n\n                return new WordArray.init(words, latin1StrLength);\n            }\n        };\n\n        \/**\n         * UTF-8 encoding strategy.\n         *\/\n        var Utf8 = C_enc.Utf8 = {\n            \/**\n             * Converts a word array to a UTF-8 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The UTF-8 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                try {\n                    return decodeURIComponent(escape(Latin1.stringify(wordArray)));\n                } catch (e) {\n                    throw new Error('Malformed UTF-8 data');\n                }\n            },\n\n            \/**\n             * Converts a UTF-8 string to a word array.\n             *\n             * @param {string} utf8Str The UTF-8 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\n             *\/\n            parse: function (utf8Str) {\n                return Latin1.parse(unescape(encodeURIComponent(utf8Str)));\n            }\n        };\n\n        \/**\n         * Abstract buffered block algorithm template.\n         *\n         * The property blockSize must be implemented in a concrete subtype.\n         *\n         * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0\n         *\/\n        var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({\n            \/**\n             * Resets this block algorithm's data buffer to its initial state.\n             *\n             * @example\n             *\n             *     bufferedBlockAlgorithm.reset();\n             *\/\n            reset: function () {\n                \/\/ Initial values\n                this._data = new WordArray.init();\n                this._nDataBytes = 0;\n            },\n\n            \/**\n             * Adds new data to this block algorithm's buffer.\n             *\n             * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.\n             *\n             * @example\n             *\n             *     bufferedBlockAlgorithm._append('data');\n             *     bufferedBlockAlgorithm._append(wordArray);\n             *\/\n            _append: function (data) {\n                \/\/ Convert string to WordArray, else assume WordArray already\n                if (typeof data == 'string') {\n                    data = Utf8.parse(data);\n                }\n\n                \/\/ Append\n                this._data.concat(data);\n                this._nDataBytes += data.sigBytes;\n            },\n\n            \/**\n             * Processes available data blocks.\n             *\n             * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.\n             *\n             * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.\n             *\n             * @return {WordArray} The processed data.\n             *\n             * @example\n             *\n             *     var processedData = bufferedBlockAlgorithm._process();\n             *     var processedData = bufferedBlockAlgorithm._process(!!'flush');\n             *\/\n            _process: function (doFlush) {\n                var processedWords;\n\n                \/\/ Shortcuts\n                var data = this._data;\n                var dataWords = data.words;\n                var dataSigBytes = data.sigBytes;\n                var blockSize = this.blockSize;\n                var blockSizeBytes = blockSize * 4;\n\n                \/\/ Count blocks ready\n                var nBlocksReady = dataSigBytes \/ blockSizeBytes;\n                if (doFlush) {\n                    \/\/ Round up to include partial blocks\n                    nBlocksReady = Math.ceil(nBlocksReady);\n                } else {\n                    \/\/ Round down to include only full blocks,\n                    \/\/ less the number of blocks that must remain in the buffer\n                    nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);\n                }\n\n                \/\/ Count words ready\n                var nWordsReady = nBlocksReady * blockSize;\n\n                \/\/ Count bytes ready\n                var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);\n\n                \/\/ Process blocks\n                if (nWordsReady) {\n                    for (var offset = 0; offset \u003c nWordsReady; offset += blockSize) {\n                        \/\/ Perform concrete-algorithm logic\n                        this._doProcessBlock(dataWords, offset);\n                    }\n\n                    \/\/ Remove processed words\n                    processedWords = dataWords.splice(0, nWordsReady);\n                    data.sigBytes -= nBytesReady;\n                }\n\n                \/\/ Return processed words\n                return new WordArray.init(processedWords, nBytesReady);\n            },\n\n            \/**\n             * Creates a copy of this object.\n             *\n             * @return {Object} The clone.\n             *\n             * @example\n             *\n             *     var clone = bufferedBlockAlgorithm.clone();\n             *\/\n            clone: function () {\n                var clone = Base.clone.call(this);\n                clone._data = this._data.clone();\n\n                return clone;\n            },\n\n            _minBufferSize: 0\n        });\n\n        \/**\n         * Abstract hasher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)\n         *\/\n        var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({\n            \/**\n             * Configuration options.\n             *\/\n            cfg: Base.extend(),\n\n            \/**\n             * Initializes a newly created hasher.\n             *\n             * @param {Object} cfg (Optional) The configuration options to use for this hash computation.\n             *\n             * @example\n             *\n             *     var hasher = CryptoJS.algo.SHA256.create();\n             *\/\n            init: function (cfg) {\n                \/\/ Apply config defaults\n                this.cfg = this.cfg.extend(cfg);\n\n                \/\/ Set initial values\n                this.reset();\n            },\n\n            \/**\n             * Resets this hasher to its initial state.\n             *\n             * @example\n             *\n             *     hasher.reset();\n             *\/\n            reset: function () {\n                \/\/ Reset data buffer\n                BufferedBlockAlgorithm.reset.call(this);\n\n                \/\/ Perform concrete-hasher logic\n                this._doReset();\n            },\n\n            \/**\n             * Updates this hasher with a message.\n             *\n             * @param {WordArray|string} messageUpdate The message to append.\n             *\n             * @return {Hasher} This hasher.\n             *\n             * @example\n             *\n             *     hasher.update('message');\n             *     hasher.update(wordArray);\n             *\/\n            update: function (messageUpdate) {\n                \/\/ Append\n                this._append(messageUpdate);\n\n                \/\/ Update the hash\n                this._process();\n\n                \/\/ Chainable\n                return this;\n            },\n\n            \/**\n             * Finalizes the hash computation.\n             * Note that the finalize operation is effectively a destructive, read-once operation.\n             *\n             * @param {WordArray|string} messageUpdate (Optional) A final message update.\n             *\n             * @return {WordArray} The hash.\n             *\n             * @example\n             *\n             *     var hash = hasher.finalize();\n             *     var hash = hasher.finalize('message');\n             *     var hash = hasher.finalize(wordArray);\n             *\/\n            finalize: function (messageUpdate) {\n                \/\/ Final message update\n                if (messageUpdate) {\n                    this._append(messageUpdate);\n                }\n\n                \/\/ Perform concrete-hasher logic\n                var hash = this._doFinalize();\n\n                return hash;\n            },\n\n            blockSize: 512 \/ 32,\n\n            \/**\n             * Creates a shortcut function to a hasher's object interface.\n             *\n             * @param {Hasher} hasher The hasher to create a helper for.\n             *\n             * @return {Function} The shortcut function.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);\n             *\/\n            _createHelper: function (hasher) {\n                return function (message, cfg) {\n                    return new hasher.init(cfg).finalize(message);\n                };\n            },\n\n            \/**\n             * Creates a shortcut function to the HMAC's object interface.\n             *\n             * @param {Hasher} hasher The hasher to use in this HMAC helper.\n             *\n             * @return {Function} The shortcut function.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);\n             *\/\n            _createHmacHelper: function (hasher) {\n                return function (message, key) {\n                    return new C_algo.HMAC.init(hasher, key).finalize(message);\n                };\n            }\n        });\n\n        \/**\n         * Algorithm namespace.\n         *\/\n        var C_algo = C.algo = {};\n\n        return C;\n    }(Math));\n    (function () {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var WordArray = C_lib.WordArray;\n        var C_enc = C.enc;\n\n        \/**\n         * Base64 encoding strategy.\n         *\/\n        var Base64 = C_enc.Base64 = {\n            \/**\n             * Converts a word array to a Base64 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The Base64 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n                var map = this._map;\n\n                \/\/ Clamp excess bits\n                wordArray.clamp();\n\n                \/\/ Convert\n                var base64Chars = [];\n                for (var i = 0; i \u003c sigBytes; i += 3) {\n                    var byte1 = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    var byte2 = (words[(i + 1) \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - ((i + 1) % 4) * 8)) \u0026 0xff;\n                    var byte3 = (words[(i + 2) \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - ((i + 2) % 4) * 8)) \u0026 0xff;\n\n                    var triplet = (byte1 \u003c\u003c 16) | (byte2 \u003c\u003c 8) | byte3;\n\n                    for (var j = 0; (j \u003c 4) \u0026\u0026 (i + j * 0.75 \u003c sigBytes); j++) {\n                        base64Chars.push(map.charAt((triplet \u003e\u003e\u003e (6 * (3 - j))) \u0026 0x3f));\n                    }\n                }\n\n                \/\/ Add padding\n                var paddingChar = map.charAt(64);\n                if (paddingChar) {\n                    while (base64Chars.length % 4) {\n                        base64Chars.push(paddingChar);\n                    }\n                }\n\n                return base64Chars.join('');\n            },\n\n            \/**\n             * Converts a Base64 string to a word array.\n             *\n             * @param {string} base64Str The Base64 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Base64.parse(base64String);\n             *\/\n            parse: function (base64Str) {\n                \/\/ Shortcuts\n                var base64StrLength = base64Str.length;\n                var map = this._map;\n                var reverseMap = this._reverseMap;\n\n                if (!reverseMap) {\n                    reverseMap = this._reverseMap = [];\n                    for (var j = 0; j \u003c map.length; j++) {\n                        reverseMap[map.charCodeAt(j)] = j;\n                    }\n                }\n\n                \/\/ Ignore padding\n                var paddingChar = map.charAt(64);\n                if (paddingChar) {\n                    var paddingIndex = base64Str.indexOf(paddingChar);\n                    if (paddingIndex !== -1) {\n                        base64StrLength = paddingIndex;\n                    }\n                }\n\n                \/\/ Convert\n                return parseLoop(base64Str, base64StrLength, reverseMap);\n\n            },\n\n            _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/='\n        };\n\n        function parseLoop(base64Str, base64StrLength, reverseMap) {\n            var words = [];\n            var nBytes = 0;\n            for (var i = 0; i \u003c base64StrLength; i++) {\n                if (i % 4) {\n                    var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] \u003c\u003c ((i % 4) * 2);\n                    var bits2 = reverseMap[base64Str.charCodeAt(i)] \u003e\u003e\u003e (6 - (i % 4) * 2);\n                    var bitsCombined = bits1 | bits2;\n                    words[nBytes \u003e\u003e\u003e 2] |= bitsCombined \u003c\u003c (24 - (nBytes % 4) * 8);\n                    nBytes++;\n                }\n            }\n            return WordArray.create(words, nBytes);\n        }\n    }());\n\n    \/**\n * Cipher core components.\n *\/\n    CryptoJS.lib.Cipher || (function (undefined) {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var Base = C_lib.Base;\n        var WordArray = C_lib.WordArray;\n        var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;\n        var C_enc = C.enc;\n        var Utf8 = C_enc.Utf8;\n        var Base64 = C_enc.Base64;\n        var C_algo = C.algo;\n        var EvpKDF = C_algo.EvpKDF;\n\n        \/**\n         * Abstract base cipher template.\n         *\n         * @property {number} keySize This cipher's key size. Default: 4 (128 bits)\n         * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)\n         * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.\n         * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.\n         *\/\n        var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {WordArray} iv The IV to use for this operation.\n             *\/\n            cfg: Base.extend(),\n\n            \/**\n             * Creates this cipher in encryption mode.\n             *\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {Cipher} A cipher instance.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });\n             *\/\n            createEncryptor: function (key, cfg) {\n                return this.create(this._ENC_XFORM_MODE, key, cfg);\n            },\n\n            \/**\n             * Creates this cipher in decryption mode.\n             *\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {Cipher} A cipher instance.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });\n             *\/\n            createDecryptor: function (key, cfg) {\n                return this.create(this._DEC_XFORM_MODE, key, cfg);\n            },\n\n            \/**\n             * Initializes a newly created cipher.\n             *\n             * @param {number} xformMode Either the encryption or decryption transormation mode constant.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });\n             *\/\n            init: function (xformMode, key, cfg) {\n                \/\/ Apply config defaults\n                this.cfg = this.cfg.extend(cfg);\n\n                \/\/ Store transform mode and key\n                this._xformMode = xformMode;\n                this._key = key;\n\n                \/\/ Set initial values\n                this.reset();\n            },\n\n            \/**\n             * Resets this cipher to its initial state.\n             *\n             * @example\n             *\n             *     cipher.reset();\n             *\/\n            reset: function () {\n                \/\/ Reset data buffer\n                BufferedBlockAlgorithm.reset.call(this);\n\n                \/\/ Perform concrete-cipher logic\n                this._doReset();\n            },\n\n            \/**\n             * Adds data to be encrypted or decrypted.\n             *\n             * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.\n             *\n             * @return {WordArray} The data after processing.\n             *\n             * @example\n             *\n             *     var encrypted = cipher.process('data');\n             *     var encrypted = cipher.process(wordArray);\n             *\/\n            process: function (dataUpdate) {\n                \/\/ Append\n                this._append(dataUpdate);\n\n                \/\/ Process available blocks\n                return this._process();\n            },\n\n            \/**\n             * Finalizes the encryption or decryption process.\n             * Note that the finalize operation is effectively a destructive, read-once operation.\n             *\n             * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.\n             *\n             * @return {WordArray} The data after final processing.\n             *\n             * @example\n             *\n             *     var encrypted = cipher.finalize();\n             *     var encrypted = cipher.finalize('data');\n             *     var encrypted = cipher.finalize(wordArray);\n             *\/\n            finalize: function (dataUpdate) {\n                \/\/ Final data update\n                if (dataUpdate) {\n                    this._append(dataUpdate);\n                }\n\n                \/\/ Perform concrete-cipher logic\n                var finalProcessedData = this._doFinalize();\n\n                return finalProcessedData;\n            },\n\n            keySize: 128 \/ 32,\n\n            ivSize: 128 \/ 32,\n\n            _ENC_XFORM_MODE: 1,\n\n            _DEC_XFORM_MODE: 2,\n\n            \/**\n             * Creates shortcut functions to a cipher's object interface.\n             *\n             * @param {Cipher} cipher The cipher to create a helper for.\n             *\n             * @return {Object} An object with encrypt and decrypt shortcut functions.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);\n             *\/\n            _createHelper: (function () {\n                function selectCipherStrategy(key) {\n                    if (typeof key == 'string') {\n                        return PasswordBasedCipher;\n                    } else {\n                        return SerializableCipher;\n                    }\n                }\n\n                return function (cipher) {\n                    return {\n                        encrypt: function (message, key, cfg) {\n                            return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);\n                        },\n\n                        decrypt: function (ciphertext, key, cfg) {\n                            return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);\n                        }\n                    };\n                };\n            }())\n        });\n\n        \/**\n         * Abstract base stream cipher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)\n         *\/\n        var StreamCipher = C_lib.StreamCipher = Cipher.extend({\n            _doFinalize: function () {\n                \/\/ Process partial blocks\n                var finalProcessedBlocks = this._process(!!'flush');\n\n                return finalProcessedBlocks;\n            },\n\n            blockSize: 1\n        });\n\n        \/**\n         * Mode namespace.\n         *\/\n        var C_mode = C.mode = {};\n\n        \/**\n         * Abstract base block cipher mode template.\n         *\/\n        var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({\n            \/**\n             * Creates this mode for encryption.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);\n             *\/\n            createEncryptor: function (cipher, iv) {\n                return this.Encryptor.create(cipher, iv);\n            },\n\n            \/**\n             * Creates this mode for decryption.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);\n             *\/\n            createDecryptor: function (cipher, iv) {\n                return this.Decryptor.create(cipher, iv);\n            },\n\n            \/**\n             * Initializes a newly created mode.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);\n             *\/\n            init: function (cipher, iv) {\n                this._cipher = cipher;\n                this._iv = iv;\n            }\n        });\n\n        \/**\n         * Cipher Block Chaining mode.\n         *\/\n        var CBC = C_mode.CBC = (function () {\n            \/**\n             * Abstract base CBC mode.\n             *\/\n            var CBC = BlockCipherMode.extend();\n\n            \/**\n             * CBC encryptor.\n             *\/\n            CBC.Encryptor = CBC.extend({\n                \/**\n                 * Processes the data block at offset.\n                 *\n                 * @param {Array} words The data words to operate on.\n                 * @param {number} offset The offset where the block starts.\n                 *\n                 * @example\n                 *\n                 *     mode.processBlock(data.words, offset);\n                 *\/\n                processBlock: function (words, offset) {\n                    \/\/ Shortcuts\n                    var cipher = this._cipher;\n                    var blockSize = cipher.blockSize;\n\n                    \/\/ XOR and encrypt\n                    xorBlock.call(this, words, offset, blockSize);\n                    cipher.encryptBlock(words, offset);\n\n                    \/\/ Remember this block to use with next block\n                    this._prevBlock = words.slice(offset, offset + blockSize);\n                }\n            });\n\n            \/**\n             * CBC decryptor.\n             *\/\n            CBC.Decryptor = CBC.extend({\n                \/**\n                 * Processes the data block at offset.\n                 *\n                 * @param {Array} words The data words to operate on.\n                 * @param {number} offset The offset where the block starts.\n                 *\n                 * @example\n                 *\n                 *     mode.processBlock(data.words, offset);\n                 *\/\n                processBlock: function (words, offset) {\n                    \/\/ Shortcuts\n                    var cipher = this._cipher;\n                    var blockSize = cipher.blockSize;\n\n                    \/\/ Remember this block to use with next block\n                    var thisBlock = words.slice(offset, offset + blockSize);\n\n                    \/\/ Decrypt and XOR\n                    cipher.decryptBlock(words, offset);\n                    xorBlock.call(this, words, offset, blockSize);\n\n                    \/\/ This block becomes the previous block\n                    this._prevBlock = thisBlock;\n                }\n            });\n\n            function xorBlock(words, offset, blockSize) {\n                var block;\n\n                \/\/ Shortcut\n                var iv = this._iv;\n\n                \/\/ Choose mixing block\n                if (iv) {\n                    block = iv;\n\n                    \/\/ Remove IV for subsequent blocks\n                    this._iv = undefined;\n                } else {\n                    block = this._prevBlock;\n                }\n\n                \/\/ XOR blocks\n                for (var i = 0; i \u003c blockSize; i++) {\n                    words[offset + i] ^= block[i];\n                }\n            }\n\n            return CBC;\n        }());\n\n        \/**\n         * Padding namespace.\n         *\/\n        var C_pad = C.pad = {};\n\n        \/**\n         * PKCS #5\/7 padding strategy.\n         *\/\n        var Pkcs7 = C_pad.Pkcs7 = {\n            \/**\n             * Pads data using the algorithm defined in PKCS #5\/7.\n             *\n             * @param {WordArray} data The data to pad.\n             * @param {number} blockSize The multiple that the data should be padded to.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);\n             *\/\n            pad: function (data, blockSize) {\n                \/\/ Shortcut\n                var blockSizeBytes = blockSize * 4;\n\n                \/\/ Count padding bytes\n                var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;\n\n                \/\/ Create padding word\n                var paddingWord = (nPaddingBytes \u003c\u003c 24) | (nPaddingBytes \u003c\u003c 16) | (nPaddingBytes \u003c\u003c 8) | nPaddingBytes;\n\n                \/\/ Create padding\n                var paddingWords = [];\n                for (var i = 0; i \u003c nPaddingBytes; i += 4) {\n                    paddingWords.push(paddingWord);\n                }\n                var padding = WordArray.create(paddingWords, nPaddingBytes);\n\n                \/\/ Add padding\n                data.concat(padding);\n            },\n\n            \/**\n             * Unpads data that had been padded using the algorithm defined in PKCS #5\/7.\n             *\n             * @param {WordArray} data The data to unpad.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     CryptoJS.pad.Pkcs7.unpad(wordArray);\n             *\/\n            unpad: function (data) {\n                \/\/ Get number of padding bytes from last byte\n                var nPaddingBytes = data.words[(data.sigBytes - 1) \u003e\u003e\u003e 2] \u0026 0xff;\n\n                \/\/ Remove padding\n                data.sigBytes -= nPaddingBytes;\n            }\n        };\n\n        \/**\n         * Abstract base block cipher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)\n         *\/\n        var BlockCipher = C_lib.BlockCipher = Cipher.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {Mode} mode The block mode to use. Default: CBC\n             * @property {Padding} padding The padding strategy to use. Default: Pkcs7\n             *\/\n            cfg: Cipher.cfg.extend({\n                mode: CBC,\n                padding: Pkcs7\n            }),\n\n            reset: function () {\n                var modeCreator;\n\n                \/\/ Reset cipher\n                Cipher.reset.call(this);\n\n                \/\/ Shortcuts\n                var cfg = this.cfg;\n                var iv = cfg.iv;\n                var mode = cfg.mode;\n\n                \/\/ Reset block mode\n                if (this._xformMode == this._ENC_XFORM_MODE) {\n                    modeCreator = mode.createEncryptor;\n                } else \/* if (this._xformMode == this._DEC_XFORM_MODE) *\/ {\n                    modeCreator = mode.createDecryptor;\n                    \/\/ Keep at least one block in the buffer for unpadding\n                    this._minBufferSize = 1;\n                }\n\n                if (this._mode \u0026\u0026 this._mode.__creator == modeCreator) {\n                    this._mode.init(this, iv \u0026\u0026 iv.words);\n                } else {\n                    this._mode = modeCreator.call(mode, this, iv \u0026\u0026 iv.words);\n                    this._mode.__creator = modeCreator;\n                }\n            },\n\n            _doProcessBlock: function (words, offset) {\n                this._mode.processBlock(words, offset);\n            },\n\n            _doFinalize: function () {\n                var finalProcessedBlocks;\n\n                \/\/ Shortcut\n                var padding = this.cfg.padding;\n\n                \/\/ Finalize\n                if (this._xformMode == this._ENC_XFORM_MODE) {\n                    \/\/ Pad data\n                    padding.pad(this._data, this.blockSize);\n\n                    \/\/ Process final blocks\n                    finalProcessedBlocks = this._process(!!'flush');\n                } else \/* if (this._xformMode == this._DEC_XFORM_MODE) *\/ {\n                    \/\/ Process final blocks\n                    finalProcessedBlocks = this._process(!!'flush');\n\n                    \/\/ Unpad data\n                    padding.unpad(finalProcessedBlocks);\n                }\n\n                return finalProcessedBlocks;\n            },\n\n            blockSize: 128 \/ 32\n        });\n\n        \/**\n         * A collection of cipher parameters.\n         *\n         * @property {WordArray} ciphertext The raw ciphertext.\n         * @property {WordArray} key The key to this ciphertext.\n         * @property {WordArray} iv The IV used in the ciphering operation.\n         * @property {WordArray} salt The salt used with a key derivation function.\n         * @property {Cipher} algorithm The cipher algorithm.\n         * @property {Mode} mode The block mode used in the ciphering operation.\n         * @property {Padding} padding The padding scheme used in the ciphering operation.\n         * @property {number} blockSize The block size of the cipher.\n         * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.\n         *\/\n        var CipherParams = C_lib.CipherParams = Base.extend({\n            \/**\n             * Initializes a newly created cipher params object.\n             *\n             * @param {Object} cipherParams An object with any of the possible cipher parameters.\n             *\n             * @example\n             *\n             *     var cipherParams = CryptoJS.lib.CipherParams.create({\n             *         ciphertext: ciphertextWordArray,\n             *         key: keyWordArray,\n             *         iv: ivWordArray,\n             *         salt: saltWordArray,\n             *         algorithm: CryptoJS.algo.AES,\n             *         mode: CryptoJS.mode.CBC,\n             *         padding: CryptoJS.pad.PKCS7,\n             *         blockSize: 4,\n             *         formatter: CryptoJS.format.OpenSSL\n             *     });\n             *\/\n            init: function (cipherParams) {\n                this.mixIn(cipherParams);\n            },\n\n            \/**\n             * Converts this cipher params object to a string.\n             *\n             * @param {Format} formatter (Optional) The formatting strategy to use.\n             *\n             * @return {string} The stringified cipher params.\n             *\n             * @throws Error If neither the formatter nor the default formatter is set.\n             *\n             * @example\n             *\n             *     var string = cipherParams + '';\n             *     var string = cipherParams.toString();\n             *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);\n             *\/\n            toString: function (formatter) {\n                return (formatter || this.formatter).stringify(this);\n            }\n        });\n\n        \/**\n         * Format namespace.\n         *\/\n        var C_format = C.format = {};\n\n        \/**\n         * OpenSSL formatting strategy.\n         *\/\n        var OpenSSLFormatter = C_format.OpenSSL = {\n            \/**\n             * Converts a cipher params object to an OpenSSL-compatible string.\n             *\n             * @param {CipherParams} cipherParams The cipher params object.\n             *\n             * @return {string} The OpenSSL-compatible string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);\n             *\/\n            stringify: function (cipherParams) {\n                var wordArray;\n\n                \/\/ Shortcuts\n                var ciphertext = cipherParams.ciphertext;\n                var salt = cipherParams.salt;\n\n                \/\/ Format\n                if (salt) {\n                    wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);\n                } else {\n                    wordArray = ciphertext;\n                }\n\n                return wordArray.toString(Base64);\n            },\n\n            \/**\n             * Converts an OpenSSL-compatible string to a cipher params object.\n             *\n             * @param {string} openSSLStr The OpenSSL-compatible string.\n             *\n             * @return {CipherParams} The cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);\n             *\/\n            parse: function (openSSLStr) {\n                var salt;\n\n                \/\/ Parse base64\n                var ciphertext = Base64.parse(openSSLStr);\n\n                \/\/ Shortcut\n                var ciphertextWords = ciphertext.words;\n\n                \/\/ Test for salt\n                if (ciphertextWords[0] == 0x53616c74 \u0026\u0026 ciphertextWords[1] == 0x65645f5f) {\n                    \/\/ Extract salt\n                    salt = WordArray.create(ciphertextWords.slice(2, 4));\n\n                    \/\/ Remove salt from ciphertext\n                    ciphertextWords.splice(0, 4);\n                    ciphertext.sigBytes -= 16;\n                }\n\n                return CipherParams.create({ ciphertext: ciphertext, salt: salt });\n            }\n        };\n\n        \/**\n         * A cipher wrapper that returns ciphertext as a serializable cipher params object.\n         *\/\n        var SerializableCipher = C_lib.SerializableCipher = Base.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL\n             *\/\n            cfg: Base.extend({\n                format: OpenSSLFormatter\n            }),\n\n            \/**\n             * Encrypts a message.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {WordArray|string} message The message to encrypt.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {CipherParams} A cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *\/\n            encrypt: function (cipher, message, key, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Encrypt\n                var encryptor = cipher.createEncryptor(key, cfg);\n                var ciphertext = encryptor.finalize(message);\n\n                \/\/ Shortcut\n                var cipherCfg = encryptor.cfg;\n\n                \/\/ Create and return serializable cipher params\n                return CipherParams.create({\n                    ciphertext: ciphertext,\n                    key: key,\n                    iv: cipherCfg.iv,\n                    algorithm: cipher,\n                    mode: cipherCfg.mode,\n                    padding: cipherCfg.padding,\n                    blockSize: cipher.blockSize,\n                    formatter: cfg.format\n                });\n            },\n\n            \/**\n             * Decrypts serialized ciphertext.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {WordArray} The plaintext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *\/\n            decrypt: function (cipher, ciphertext, key, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Convert string to CipherParams\n                ciphertext = this._parse(ciphertext, cfg.format);\n\n                \/\/ Decrypt\n                var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);\n\n                return plaintext;\n            },\n\n            \/**\n             * Converts serialized ciphertext to CipherParams,\n             * else assumed CipherParams already and returns ciphertext unchanged.\n             *\n             * @param {CipherParams|string} ciphertext The ciphertext.\n             * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.\n             *\n             * @return {CipherParams} The unserialized ciphertext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);\n             *\/\n            _parse: function (ciphertext, format) {\n                if (typeof ciphertext == 'string') {\n                    return format.parse(ciphertext, this);\n                } else {\n                    return ciphertext;\n                }\n            }\n        });\n\n        \/**\n         * Key derivation function namespace.\n         *\/\n        var C_kdf = C.kdf = {};\n\n        \/**\n         * OpenSSL key derivation function.\n         *\/\n        var OpenSSLKdf = C_kdf.OpenSSL = {\n            \/**\n             * Derives a key and IV from a password.\n             *\n             * @param {string} password The password to derive from.\n             * @param {number} keySize The size in words of the key to generate.\n             * @param {number} ivSize The size in words of the IV to generate.\n             * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.\n             *\n             * @return {CipherParams} A cipher params object with the key, IV, and salt.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256\/32, 128\/32);\n             *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256\/32, 128\/32, 'saltsalt');\n             *\/\n            execute: function (password, keySize, ivSize, salt, hasher) {\n                \/\/ Generate random salt\n                if (!salt) {\n                    salt = WordArray.random(64 \/ 8);\n                }\n\n                \/\/ Derive key and IV\n                if (!hasher) {\n                    var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);\n                } else {\n                    var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: hasher }).compute(password, salt);\n                }\n\n\n                \/\/ Separate key and IV\n                var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);\n                key.sigBytes = keySize * 4;\n\n                \/\/ Return params\n                return CipherParams.create({ key: key, iv: iv, salt: salt });\n            }\n        };\n\n        \/**\n         * A serializable cipher wrapper that derives the key from a password,\n         * and returns ciphertext as a serializable cipher params object.\n         *\/\n        var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL\n             *\/\n            cfg: SerializableCipher.cfg.extend({\n                kdf: OpenSSLKdf\n            }),\n\n            \/**\n             * Encrypts a message using a password.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {WordArray|string} message The message to encrypt.\n             * @param {string} password The password.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {CipherParams} A cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');\n             *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });\n             *\/\n            encrypt: function (cipher, message, password, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Derive key and other params\n                var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, cfg.salt, cfg.hasher);\n\n                \/\/ Add IV to config\n                cfg.iv = derivedParams.iv;\n\n                \/\/ Encrypt\n                var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);\n\n                \/\/ Mix in derived params\n                ciphertext.mixIn(derivedParams);\n\n                return ciphertext;\n            },\n\n            \/**\n             * Decrypts serialized ciphertext using a password.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n             * @param {string} password The password.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {WordArray} The plaintext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });\n             *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });\n             *\/\n            decrypt: function (cipher, ciphertext, password, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Convert string to CipherParams\n                ciphertext = this._parse(ciphertext, cfg.format);\n\n                \/\/ Derive key and other params\n                var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt, cfg.hasher);\n\n                \/\/ Add IV to config\n                cfg.iv = derivedParams.iv;\n\n                \/\/ Decrypt\n                var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);\n\n                return plaintext;\n            }\n        });\n    }());\n\n\n\n    (function () {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var BlockCipher = C_lib.BlockCipher;\n        var C_algo = C.algo;\n\n        \/\/ Lookup tables\n        var SBOX = [];\n        var INV_SBOX = [];\n        var SUB_MIX_0 = [];\n        var SUB_MIX_1 = [];\n        var SUB_MIX_2 = [];\n        var SUB_MIX_3 = [];\n        var INV_SUB_MIX_0 = [];\n        var INV_SUB_MIX_1 = [];\n        var INV_SUB_MIX_2 = [];\n        var INV_SUB_MIX_3 = [];\n\n        \/\/ Compute lookup tables\n        (function () {\n            \/\/ Compute double table\n            var d = [];\n            for (var i = 0; i \u003c 256; i++) {\n                if (i \u003c 128) {\n                    d[i] = i \u003c\u003c 1;\n                } else {\n                    d[i] = (i \u003c\u003c 1) ^ 0x11b;\n                }\n            }\n\n            \/\/ Walk GF(2^8)\n            var x = 0;\n            var xi = 0;\n            for (var i = 0; i \u003c 256; i++) {\n                \/\/ Compute sbox\n                var sx = xi ^ (xi \u003c\u003c 1) ^ (xi \u003c\u003c 2) ^ (xi \u003c\u003c 3) ^ (xi \u003c\u003c 4);\n                sx = (sx \u003e\u003e\u003e 8) ^ (sx \u0026 0xff) ^ 0x63;\n                SBOX[x] = sx;\n                INV_SBOX[sx] = x;\n\n                \/\/ Compute multiplication\n                var x2 = d[x];\n                var x4 = d[x2];\n                var x8 = d[x4];\n\n                \/\/ Compute sub bytes, mix columns tables\n                var t = (d[sx] * 0x101) ^ (sx * 0x1010100);\n                SUB_MIX_0[x] = (t \u003c\u003c 24) | (t \u003e\u003e\u003e 8);\n                SUB_MIX_1[x] = (t \u003c\u003c 16) | (t \u003e\u003e\u003e 16);\n                SUB_MIX_2[x] = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n                SUB_MIX_3[x] = t;\n\n                \/\/ Compute inv sub bytes, inv mix columns tables\n                var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);\n                INV_SUB_MIX_0[sx] = (t \u003c\u003c 24) | (t \u003e\u003e\u003e 8);\n                INV_SUB_MIX_1[sx] = (t \u003c\u003c 16) | (t \u003e\u003e\u003e 16);\n                INV_SUB_MIX_2[sx] = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n                INV_SUB_MIX_3[sx] = t;\n\n                \/\/ Compute next counter\n                if (!x) {\n                    x = xi = 1;\n                } else {\n                    x = x2 ^ d[d[d[x8 ^ x2]]];\n                    xi ^= d[d[xi]];\n                }\n            }\n        }());\n\n        \/\/ Precomputed Rcon lookup\n        var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];\n\n        \/**\n         * AES block cipher algorithm.\n         *\/\n        var AES = C_algo.AES = BlockCipher.extend({\n            _doReset: function () {\n                var t;\n\n                \/\/ Skip reset of nRounds has been set before and key did not change\n                if (this._nRounds \u0026\u0026 this._keyPriorReset === this._key) {\n                    return;\n                }\n\n                \/\/ Shortcuts\n                var key = this._keyPriorReset = this._key;\n                var keyWords = key.words;\n                var keySize = key.sigBytes \/ 4;\n\n                \/\/ Compute number of rounds\n                var nRounds = this._nRounds = keySize + 6;\n\n                \/\/ Compute number of key schedule rows\n                var ksRows = (nRounds + 1) * 4;\n\n                \/\/ Compute key schedule\n                var keySchedule = this._keySchedule = [];\n                for (var ksRow = 0; ksRow \u003c ksRows; ksRow++) {\n                    if (ksRow \u003c keySize) {\n                        keySchedule[ksRow] = keyWords[ksRow];\n                    } else {\n                        t = keySchedule[ksRow - 1];\n\n                        if (!(ksRow % keySize)) {\n                            \/\/ Rot word\n                            t = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n\n                            \/\/ Sub word\n                            t = (SBOX[t \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[t \u0026 0xff];\n\n                            \/\/ Mix Rcon\n                            t ^= RCON[(ksRow \/ keySize) | 0] \u003c\u003c 24;\n                        } else if (keySize \u003e 6 \u0026\u0026 ksRow % keySize == 4) {\n                            \/\/ Sub word\n                            t = (SBOX[t \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[t \u0026 0xff];\n                        }\n\n                        keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;\n                    }\n                }\n\n                \/\/ Compute inv key schedule\n                var invKeySchedule = this._invKeySchedule = [];\n                for (var invKsRow = 0; invKsRow \u003c ksRows; invKsRow++) {\n                    var ksRow = ksRows - invKsRow;\n\n                    if (invKsRow % 4) {\n                        var t = keySchedule[ksRow];\n                    } else {\n                        var t = keySchedule[ksRow - 4];\n                    }\n\n                    if (invKsRow \u003c 4 || ksRow \u003c= 4) {\n                        invKeySchedule[invKsRow] = t;\n                    } else {\n                        invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t \u003e\u003e\u003e 24]] ^ INV_SUB_MIX_1[SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff]] ^\n                            INV_SUB_MIX_2[SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff]] ^ INV_SUB_MIX_3[SBOX[t \u0026 0xff]];\n                    }\n                }\n            },\n\n            encryptBlock: function (M, offset) {\n                this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);\n            },\n\n            decryptBlock: function (M, offset) {\n                \/\/ Swap 2nd and 4th rows\n                var t = M[offset + 1];\n                M[offset + 1] = M[offset + 3];\n                M[offset + 3] = t;\n\n                this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);\n\n                \/\/ Inv swap 2nd and 4th rows\n                var t = M[offset + 1];\n                M[offset + 1] = M[offset + 3];\n                M[offset + 3] = t;\n            },\n\n            _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {\n                \/\/ Shortcut\n                var nRounds = this._nRounds;\n\n                \/\/ Get input, add round key\n                var s0 = M[offset] ^ keySchedule[0];\n                var s1 = M[offset + 1] ^ keySchedule[1];\n                var s2 = M[offset + 2] ^ keySchedule[2];\n                var s3 = M[offset + 3] ^ keySchedule[3];\n\n                \/\/ Key schedule row counter\n                var ksRow = 4;\n\n                \/\/ Rounds\n                for (var round = 1; round \u003c nRounds; round++) {\n                    \/\/ Shift rows, sub bytes, mix columns, add round key\n                    var t0 = SUB_MIX_0[s0 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s1 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s2 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s3 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t1 = SUB_MIX_0[s1 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s2 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s3 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s0 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t2 = SUB_MIX_0[s2 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s3 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s0 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s1 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t3 = SUB_MIX_0[s3 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s0 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s1 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s2 \u0026 0xff] ^ keySchedule[ksRow++];\n\n                    \/\/ Update state\n                    s0 = t0;\n                    s1 = t1;\n                    s2 = t2;\n                    s3 = t3;\n                }\n\n                \/\/ Shift rows, sub bytes, add round key\n                var t0 = ((SBOX[s0 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s1 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s2 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s3 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t1 = ((SBOX[s1 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s2 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s3 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s0 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t2 = ((SBOX[s2 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s3 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s0 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s1 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t3 = ((SBOX[s3 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s0 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s1 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s2 \u0026 0xff]) ^ keySchedule[ksRow++];\n\n                \/\/ Set output\n                M[offset] = t0;\n                M[offset + 1] = t1;\n                M[offset + 2] = t2;\n                M[offset + 3] = t3;\n            },\n\n            keySize: 256 \/ 32\n        });\n\n        \/**\n         * Shortcut functions to the cipher's object interface.\n         *\n         * @example\n         *\n         *     var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);\n         *     var plaintext  = CryptoJS.AES.decrypt(ciphertext, key, cfg);\n         *\/\n        C.AES = BlockCipher._createHelper(AES);\n    }());\n\n    (function (Math) {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var WordArray = C_lib.WordArray;\n        var Hasher = C_lib.Hasher;\n        var C_algo = C.algo;\n\n        \/\/ Constants table\n        var T = [];\n\n        \/\/ Compute constants\n        (function () {\n            for (var i = 0; i \u003c 64; i++) {\n                T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;\n            }\n        }());\n\n        \/**\n         * MD5 hash algorithm.\n         *\/\n        var MD5 = C_algo.MD5 = Hasher.extend({\n            _doReset: function () {\n                this._hash = new WordArray.init([\n                    0x67452301, 0xefcdab89,\n                    0x98badcfe, 0x10325476\n                ]);\n            },\n\n            _doProcessBlock: function (M, offset) {\n                \/\/ Swap endian\n                for (var i = 0; i \u003c 16; i++) {\n                    \/\/ Shortcuts\n                    var offset_i = offset + i;\n                    var M_offset_i = M[offset_i];\n\n                    M[offset_i] = (\n                        (((M_offset_i \u003c\u003c 8) | (M_offset_i \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                        (((M_offset_i \u003c\u003c 24) | (M_offset_i \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                    );\n                }\n\n                \/\/ Shortcuts\n                var H = this._hash.words;\n\n                var M_offset_0 = M[offset + 0];\n                var M_offset_1 = M[offset + 1];\n                var M_offset_2 = M[offset + 2];\n                var M_offset_3 = M[offset + 3];\n                var M_offset_4 = M[offset + 4];\n                var M_offset_5 = M[offset + 5];\n                var M_offset_6 = M[offset + 6];\n                var M_offset_7 = M[offset + 7];\n                var M_offset_8 = M[offset + 8];\n                var M_offset_9 = M[offset + 9];\n                var M_offset_10 = M[offset + 10];\n                var M_offset_11 = M[offset + 11];\n                var M_offset_12 = M[offset + 12];\n                var M_offset_13 = M[offset + 13];\n                var M_offset_14 = M[offset + 14];\n                var M_offset_15 = M[offset + 15];\n\n                \/\/ Working variables\n                var a = H[0];\n                var b = H[1];\n                var c = H[2];\n                var d = H[3];\n\n                \/\/ Computation\n                a = FF(a, b, c, d, M_offset_0, 7, T[0]);\n                d = FF(d, a, b, c, M_offset_1, 12, T[1]);\n                c = FF(c, d, a, b, M_offset_2, 17, T[2]);\n                b = FF(b, c, d, a, M_offset_3, 22, T[3]);\n                a = FF(a, b, c, d, M_offset_4, 7, T[4]);\n                d = FF(d, a, b, c, M_offset_5, 12, T[5]);\n                c = FF(c, d, a, b, M_offset_6, 17, T[6]);\n                b = FF(b, c, d, a, M_offset_7, 22, T[7]);\n                a = FF(a, b, c, d, M_offset_8, 7, T[8]);\n                d = FF(d, a, b, c, M_offset_9, 12, T[9]);\n                c = FF(c, d, a, b, M_offset_10, 17, T[10]);\n                b = FF(b, c, d, a, M_offset_11, 22, T[11]);\n                a = FF(a, b, c, d, M_offset_12, 7, T[12]);\n                d = FF(d, a, b, c, M_offset_13, 12, T[13]);\n                c = FF(c, d, a, b, M_offset_14, 17, T[14]);\n                b = FF(b, c, d, a, M_offset_15, 22, T[15]);\n\n                a = GG(a, b, c, d, M_offset_1, 5, T[16]);\n                d = GG(d, a, b, c, M_offset_6, 9, T[17]);\n                c = GG(c, d, a, b, M_offset_11, 14, T[18]);\n                b = GG(b, c, d, a, M_offset_0, 20, T[19]);\n                a = GG(a, b, c, d, M_offset_5, 5, T[20]);\n                d = GG(d, a, b, c, M_offset_10, 9, T[21]);\n                c = GG(c, d, a, b, M_offset_15, 14, T[22]);\n                b = GG(b, c, d, a, M_offset_4, 20, T[23]);\n                a = GG(a, b, c, d, M_offset_9, 5, T[24]);\n                d = GG(d, a, b, c, M_offset_14, 9, T[25]);\n                c = GG(c, d, a, b, M_offset_3, 14, T[26]);\n                b = GG(b, c, d, a, M_offset_8, 20, T[27]);\n                a = GG(a, b, c, d, M_offset_13, 5, T[28]);\n                d = GG(d, a, b, c, M_offset_2, 9, T[29]);\n                c = GG(c, d, a, b, M_offset_7, 14, T[30]);\n                b = GG(b, c, d, a, M_offset_12, 20, T[31]);\n\n                a = HH(a, b, c, d, M_offset_5, 4, T[32]);\n                d = HH(d, a, b, c, M_offset_8, 11, T[33]);\n                c = HH(c, d, a, b, M_offset_11, 16, T[34]);\n                b = HH(b, c, d, a, M_offset_14, 23, T[35]);\n                a = HH(a, b, c, d, M_offset_1, 4, T[36]);\n                d = HH(d, a, b, c, M_offset_4, 11, T[37]);\n                c = HH(c, d, a, b, M_offset_7, 16, T[38]);\n                b = HH(b, c, d, a, M_offset_10, 23, T[39]);\n                a = HH(a, b, c, d, M_offset_13, 4, T[40]);\n                d = HH(d, a, b, c, M_offset_0, 11, T[41]);\n                c = HH(c, d, a, b, M_offset_3, 16, T[42]);\n                b = HH(b, c, d, a, M_offset_6, 23, T[43]);\n                a = HH(a, b, c, d, M_offset_9, 4, T[44]);\n                d = HH(d, a, b, c, M_offset_12, 11, T[45]);\n                c = HH(c, d, a, b, M_offset_15, 16, T[46]);\n                b = HH(b, c, d, a, M_offset_2, 23, T[47]);\n\n                a = II(a, b, c, d, M_offset_0, 6, T[48]);\n                d = II(d, a, b, c, M_offset_7, 10, T[49]);\n                c = II(c, d, a, b, M_offset_14, 15, T[50]);\n                b = II(b, c, d, a, M_offset_5, 21, T[51]);\n                a = II(a, b, c, d, M_offset_12, 6, T[52]);\n                d = II(d, a, b, c, M_offset_3, 10, T[53]);\n                c = II(c, d, a, b, M_offset_10, 15, T[54]);\n                b = II(b, c, d, a, M_offset_1, 21, T[55]);\n                a = II(a, b, c, d, M_offset_8, 6, T[56]);\n                d = II(d, a, b, c, M_offset_15, 10, T[57]);\n                c = II(c, d, a, b, M_offset_6, 15, T[58]);\n                b = II(b, c, d, a, M_offset_13, 21, T[59]);\n                a = II(a, b, c, d, M_offset_4, 6, T[60]);\n                d = II(d, a, b, c, M_offset_11, 10, T[61]);\n                c = II(c, d, a, b, M_offset_2, 15, T[62]);\n                b = II(b, c, d, a, M_offset_9, 21, T[63]);\n\n                \/\/ Intermediate hash value\n                H[0] = (H[0] + a) | 0;\n                H[1] = (H[1] + b) | 0;\n                H[2] = (H[2] + c) | 0;\n                H[3] = (H[3] + d) | 0;\n            },\n\n            _doFinalize: function () {\n                \/\/ Shortcuts\n                var data = this._data;\n                var dataWords = data.words;\n\n                var nBitsTotal = this._nDataBytes * 8;\n                var nBitsLeft = data.sigBytes * 8;\n\n                \/\/ Add padding\n                dataWords[nBitsLeft \u003e\u003e\u003e 5] |= 0x80 \u003c\u003c (24 - nBitsLeft % 32);\n\n                var nBitsTotalH = Math.floor(nBitsTotal \/ 0x100000000);\n                var nBitsTotalL = nBitsTotal;\n                dataWords[(((nBitsLeft + 64) \u003e\u003e\u003e 9) \u003c\u003c 4) + 15] = (\n                    (((nBitsTotalH \u003c\u003c 8) | (nBitsTotalH \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                    (((nBitsTotalH \u003c\u003c 24) | (nBitsTotalH \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                );\n                dataWords[(((nBitsLeft + 64) \u003e\u003e\u003e 9) \u003c\u003c 4) + 14] = (\n                    (((nBitsTotalL \u003c\u003c 8) | (nBitsTotalL \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                    (((nBitsTotalL \u003c\u003c 24) | (nBitsTotalL \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                );\n\n                data.sigBytes = (dataWords.length + 1) * 4;\n\n                \/\/ Hash final blocks\n                this._process();\n\n                \/\/ Shortcuts\n                var hash = this._hash;\n                var H = hash.words;\n\n                \/\/ Swap endian\n                for (var i = 0; i \u003c 4; i++) {\n                    \/\/ Shortcut\n                    var H_i = H[i];\n\n                    H[i] = (((H_i \u003c\u003c 8) | (H_i \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                        (((H_i \u003c\u003c 24) | (H_i \u003e\u003e\u003e 8)) \u0026 0xff00ff00);\n                }\n\n                \/\/ Return final computed hash\n                return hash;\n            },\n\n            clone: function () {\n                var clone = Hasher.clone.call(this);\n                clone._hash = this._hash.clone();\n\n                return clone;\n            }\n        });\n\n        function FF(a, b, c, d, x, s, t) {\n            var n = a + ((b \u0026 c) | (~b \u0026 d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function GG(a, b, c, d, x, s, t) {\n            var n = a + ((b \u0026 d) | (c \u0026 ~d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function HH(a, b, c, d, x, s, t) {\n            var n = a + (b ^ c ^ d) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function II(a, b, c, d, x, s, t) {\n            var n = a + (c ^ (b | ~d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        \/**\n         * Shortcut function to the hasher's object interface.\n         *\n         * @param {WordArray|string} message The message to hash.\n         *\n         * @return {WordArray} The hash.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hash = CryptoJS.MD5('message');\n         *     var hash = CryptoJS.MD5(wordArray);\n         *\/\n        C.MD5 = Hasher._createHelper(MD5);\n\n        \/**\n         * Shortcut function to the HMAC's object interface.\n         *\n         * @param {WordArray|string} message The message to hash.\n         * @param {WordArray|string} key The secret key.\n         *\n         * @return {WordArray} The HMAC.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hmac = CryptoJS.HmacMD5(message, key);\n         *\/\n        C.HmacMD5 = Hasher._createHmacHelper(MD5);\n    }(Math));\n\n    \/**\n     * Zero padding strategy.\n     *\/\n    CryptoJS.pad.ZeroPadding = {\n        pad: function (data, blockSize) {\n            \/\/ Shortcut\n            var blockSizeBytes = blockSize * 4;\n\n            \/\/ Pad\n            data.clamp();\n            data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);\n        },\n\n        unpad: function (data) {\n            \/\/ Shortcut\n            var dataWords = data.words;\n\n            \/\/ Unpad\n            var i = data.sigBytes - 1;\n            for (var i = data.sigBytes - 1; i \u003e= 0; i--) {\n                if (((dataWords[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff)) {\n                    data.sigBytes = i + 1;\n                    break;\n                }\n            }\n        }\n    };\n\n\n    return CryptoJS;\n\n}));\n(function (P) {\n    (function () {\n        P.ecy = (function () {\n            function strEnc(data, firstKey, secondKey, thirdKey) {\n\n                var leng = data.length;\n                var encData = \"\";\n                var firstKeyBt, secondKeyBt, thirdKeyBt, firstLength, secondLength, thirdLength;\n                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                    firstKeyBt = getKeyBytes(firstKey);\n                    firstLength = firstKeyBt.length;\n                }\n                if (secondKey != null \u0026\u0026 secondKey != \"\") {\n                    secondKeyBt = getKeyBytes(secondKey);\n                    secondLength = secondKeyBt.length;\n                }\n                if (thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                    thirdKeyBt = getKeyBytes(thirdKey);\n                    thirdLength = thirdKeyBt.length;\n                }\n\n                if (leng \u003e 0) {\n                    if (leng \u003c 4) {\n                        var bt = strToBt(data);\n                        var encByte;\n                        if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                            var tempBt;\n                            var x, y, z;\n                            tempBt = bt;\n                            for (x = 0; x \u003c firstLength; x++) {\n                                tempBt = enc(tempBt, firstKeyBt[x]);\n                            }\n                            for (y = 0; y \u003c secondLength; y++) {\n                                tempBt = enc(tempBt, secondKeyBt[y]);\n                            }\n                            for (z = 0; z \u003c thirdLength; z++) {\n                                tempBt = enc(tempBt, thirdKeyBt[z]);\n                            }\n                            encByte = tempBt;\n                        } else {\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                var tempBt;\n                                var x, y;\n                                tempBt = bt;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                    var tempBt;\n                                    var x = 0;\n                                    tempBt = bt;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    encByte = tempBt;\n                                }\n                            }\n                        }\n                        encData = bt64ToHex(encByte);\n                    } else {\n                        var iterator = parseInt(leng \/ 4);\n                        var remainder = leng % 4;\n                        var i = 0;\n                        for (i = 0; i \u003c iterator; i++) {\n                            var tempData = data.substring(i * 4 + 0, i * 4 + 4);\n                            var tempByte = strToBt(tempData);\n                            var encByte;\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = tempByte;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                for (z = 0; z \u003c thirdLength; z++) {\n                                    tempBt = enc(tempBt, thirdKeyBt[z]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                    var tempBt;\n                                    var x, y;\n                                    tempBt = tempByte;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    for (y = 0; y \u003c secondLength; y++) {\n                                        tempBt = enc(tempBt, secondKeyBt[y]);\n                                    }\n                                    encByte = tempBt;\n                                } else {\n                                    if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                        var tempBt;\n                                        var x;\n                                        tempBt = tempByte;\n                                        for (x = 0; x \u003c firstLength; x++) {\n                                            tempBt = enc(tempBt, firstKeyBt[x]);\n                                        }\n                                        encByte = tempBt;\n                                    }\n                                }\n                            }\n                            encData += bt64ToHex(encByte);\n                        }\n                        if (remainder \u003e 0) {\n                            var remainderData = data.substring(iterator * 4 + 0, leng);\n                            var tempByte = strToBt(remainderData);\n                            var encByte;\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = tempByte;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                for (z = 0; z \u003c thirdLength; z++) {\n                                    tempBt = enc(tempBt, thirdKeyBt[z]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                    var tempBt;\n                                    var x, y;\n                                    tempBt = tempByte;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    for (y = 0; y \u003c secondLength; y++) {\n                                        tempBt = enc(tempBt, secondKeyBt[y]);\n                                    }\n                                    encByte = tempBt;\n                                } else {\n                                    if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                        var tempBt;\n                                        var x;\n                                        tempBt = tempByte;\n                                        for (x = 0; x \u003c firstLength; x++) {\n                                            tempBt = enc(tempBt, firstKeyBt[x]);\n                                        }\n                                        encByte = tempBt;\n                                    }\n                                }\n                            }\n                            encData += bt64ToHex(encByte);\n                        }\n                    }\n                }\n                return encData;\n            }\n\n            \/*\n             * decrypt the encrypted string to the original string\n             *\n             * return  the original string\n             *\/\n            function strDec(data, firstKey, secondKey, thirdKey) {\n                var leng = data.length;\n                var decStr = \"\";\n                var firstKeyBt, secondKeyBt, thirdKeyBt, firstLength, secondLength, thirdLength;\n                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                    firstKeyBt = getKeyBytes(firstKey);\n                    firstLength = firstKeyBt.length;\n                }\n                if (secondKey != null \u0026\u0026 secondKey != \"\") {\n                    secondKeyBt = getKeyBytes(secondKey);\n                    secondLength = secondKeyBt.length;\n                }\n                if (thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                    thirdKeyBt = getKeyBytes(thirdKey);\n                    thirdLength = thirdKeyBt.length;\n                }\n\n                var iterator = parseInt(leng \/ 16);\n                var i = 0;\n                for (i = 0; i \u003c iterator; i++) {\n                    var tempData = data.substring(i * 16 + 0, i * 16 + 16);\n                    var strByte = hexToBt64(tempData);\n                    var intByte = new Array(64);\n                    var j = 0;\n                    for (j = 0; j \u003c 64; j++) {\n                        intByte[j] = parseInt(strByte.substring(j, j + 1));\n                    }\n                    var decByte;\n                    if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                        var tempBt;\n                        var x, y, z;\n                        tempBt = intByte;\n                        for (x = thirdLength - 1; x \u003e= 0; x--) {\n                            tempBt = dec(tempBt, thirdKeyBt[x]);\n                        }\n                        for (y = secondLength - 1; y \u003e= 0; y--) {\n                            tempBt = dec(tempBt, secondKeyBt[y]);\n                        }\n                        for (z = firstLength - 1; z \u003e= 0; z--) {\n                            tempBt = dec(tempBt, firstKeyBt[z]);\n                        }\n                        decByte = tempBt;\n                    } else {\n                        if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                            var tempBt;\n                            var x, y, z;\n                            tempBt = intByte;\n                            for (x = secondLength - 1; x \u003e= 0; x--) {\n                                tempBt = dec(tempBt, secondKeyBt[x]);\n                            }\n                            for (y = firstLength - 1; y \u003e= 0; y--) {\n                                tempBt = dec(tempBt, firstKeyBt[y]);\n                            }\n                            decByte = tempBt;\n                        } else {\n                            if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = intByte;\n                                for (x = firstLength - 1; x \u003e= 0; x--) {\n                                    tempBt = dec(tempBt, firstKeyBt[x]);\n                                }\n                                decByte = tempBt;\n                            }\n                        }\n                    }\n                    decStr += byteToString(decByte);\n                }\n                return decStr;\n            }\n            \/*\n             * chang the string into the bit array\n             *\n             * return bit array(it's length % 64 = 0)\n             *\/\n            function getKeyBytes(key) {\n                var keyBytes = new Array();\n                var leng = key.length;\n                var iterator = parseInt(leng \/ 4);\n                var remainder = leng % 4;\n                var i = 0;\n                for (i = 0; i \u003c iterator; i++) {\n                    keyBytes[i] = strToBt(key.substring(i * 4 + 0, i * 4 + 4));\n                }\n                if (remainder \u003e 0) {\n                    keyBytes[i] = strToBt(key.substring(i * 4 + 0, leng));\n                }\n                return keyBytes;\n            }\n\n            \/*\n             * chang the string(it's length \u003c= 4) into the bit array\n             *\n             * return bit array(it's length = 64)\n             *\/\n            function strToBt(str) {\n                var leng = str.length;\n                var bt = new Array(64);\n                var i = 0, j = 0, p = 0, q = 0;\n                if (leng \u003c 4) {\n                    for (i = 0; i \u003c leng; i++) {\n                        var k = str.charCodeAt(i);\n                        for (j = 0; j \u003c 16; j++) {\n                            var pow = 1, m = 0;\n                            for (m = 15; m \u003e j; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * i + j] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                    for (p = leng; p \u003c 4; p++) {\n                        var k = 0;\n                        for (q = 0; q \u003c 16; q++) {\n                            var pow = 1, m = 0;\n                            for (m = 15; m \u003e q; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * p + q] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                } else {\n                    for (i = 0; i \u003c 4; i++) {\n                        var k = str.charCodeAt(i);\n                        for (j = 0; j \u003c 16; j++) {\n                            var pow = 1;\n                            for (m = 15; m \u003e j; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * i + j] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                }\n                return bt;\n            }\n\n            \/*\n             * chang the bit(it's length = 4) into the hex\n             *\n             * return hex\n             *\/\n            function bt4ToHex(binary) {\n                var hex;\n                switch (binary) {\n                    case \"0000\": hex = \"0\"; break;\n                    case \"0001\": hex = \"1\"; break;\n                    case \"0010\": hex = \"2\"; break;\n                    case \"0011\": hex = \"3\"; break;\n                    case \"0100\": hex = \"4\"; break;\n                    case \"0101\": hex = \"5\"; break;\n                    case \"0110\": hex = \"6\"; break;\n                    case \"0111\": hex = \"7\"; break;\n                    case \"1000\": hex = \"8\"; break;\n                    case \"1001\": hex = \"9\"; break;\n                    case \"1010\": hex = \"A\"; break;\n                    case \"1011\": hex = \"B\"; break;\n                    case \"1100\": hex = \"C\"; break;\n                    case \"1101\": hex = \"D\"; break;\n                    case \"1110\": hex = \"E\"; break;\n                    case \"1111\": hex = \"F\"; break;\n                }\n                return hex;\n            }\n\n            \/*\n             * chang the hex into the bit(it's length = 4)\n             *\n             * return the bit(it's length = 4)\n             *\/\n            function hexToBt4(hex) {\n                var binary;\n                switch (hex) {\n                    case \"0\": binary = \"0000\"; break;\n                    case \"1\": binary = \"0001\"; break;\n                    case \"2\": binary = \"0010\"; break;\n                    case \"3\": binary = \"0011\"; break;\n                    case \"4\": binary = \"0100\"; break;\n                    case \"5\": binary = \"0101\"; break;\n                    case \"6\": binary = \"0110\"; break;\n                    case \"7\": binary = \"0111\"; break;\n                    case \"8\": binary = \"1000\"; break;\n                    case \"9\": binary = \"1001\"; break;\n                    case \"A\": binary = \"1010\"; break;\n                    case \"B\": binary = \"1011\"; break;\n                    case \"C\": binary = \"1100\"; break;\n                    case \"D\": binary = \"1101\"; break;\n                    case \"E\": binary = \"1110\"; break;\n                    case \"F\": binary = \"1111\"; break;\n                }\n                return binary;\n            }\n\n            \/*\n             * chang the bit(it's length = 64) into the string\n             *\n             * return string\n             *\/\n            function byteToString(byteData) {\n                var str = \"\";\n                var i, j, m;\n                for (i = 0; i \u003c 4; i++) {\n                    var count = 0;\n                    for (j = 0; j \u003c 16; j++) {\n                        var pow = 1;\n                        for (m = 15; m \u003e j; m--) {\n                            pow *= 2;\n                        }\n                        count += byteData[16 * i + j] * pow;\n                    }\n                    if (count != 0) {\n                        str += String.fromCharCode(count);\n                    }\n                }\n                return str;\n            }\n\n            function bt64ToHex(byteData) {\n                var hex = \"\";\n                var i, j;\n                for (i = 0; i \u003c 16; i++) {\n                    var bt = \"\";\n                    for (j = 0; j \u003c 4; j++) {\n                        bt += byteData[i * 4 + j];\n                    }\n                    hex += bt4ToHex(bt);\n                }\n                return hex;\n            }\n\n            function hexToBt64(hex) {\n                var binary = \"\";\n                for (var i = 0; i \u003c 16; i++) {\n                    binary += hexToBt4(hex.substring(i, i + 1));\n                }\n                return binary;\n            }\n\n            \/*\n             * the 64 bit des core arithmetic\n             *\/\n\n            function enc(dataByte, keyByte) {\n                var keys = generateKeys(keyByte);\n                var ipByte = initPermute(dataByte);\n                var ipLeft = new Array(32);\n                var ipRight = new Array(32);\n                var tempLeft = new Array(32);\n                var i = 0, j = 0, k = 0, m = 0, n = 0;\n                for (k = 0; k \u003c 32; k++) {\n                    ipLeft[k] = ipByte[k];\n                    ipRight[k] = ipByte[32 + k];\n                }\n                for (i = 0; i \u003c 16; i++) {\n                    for (j = 0; j \u003c 32; j++) {\n                        tempLeft[j] = ipLeft[j];\n                        ipLeft[j] = ipRight[j];\n                    }\n                    var key = new Array(48);\n                    for (m = 0; m \u003c 48; m++) {\n                        key[m] = keys[i][m];\n                    }\n                    var tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);\n                    for (n = 0; n \u003c 32; n++) {\n                        ipRight[n] = tempRight[n];\n                    }\n\n                }\n\n\n                var finalData = new Array(64);\n                for (i = 0; i \u003c 32; i++) {\n                    finalData[i] = ipRight[i];\n                    finalData[32 + i] = ipLeft[i];\n                }\n                return finallyPermute(finalData);\n            }\n\n            function dec(dataByte, keyByte) {\n                var keys = generateKeys(keyByte);\n                var ipByte = initPermute(dataByte);\n                var ipLeft = new Array(32);\n                var ipRight = new Array(32);\n                var tempLeft = new Array(32);\n                var i = 0, j = 0, k = 0, m = 0, n = 0;\n                for (k = 0; k \u003c 32; k++) {\n                    ipLeft[k] = ipByte[k];\n                    ipRight[k] = ipByte[32 + k];\n                }\n                for (i = 15; i \u003e= 0; i--) {\n                    for (j = 0; j \u003c 32; j++) {\n                        tempLeft[j] = ipLeft[j];\n                        ipLeft[j] = ipRight[j];\n                    }\n                    var key = new Array(48);\n                    for (m = 0; m \u003c 48; m++) {\n                        key[m] = keys[i][m];\n                    }\n\n                    var tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);\n                    for (n = 0; n \u003c 32; n++) {\n                        ipRight[n] = tempRight[n];\n                    }\n                }\n\n\n                var finalData = new Array(64);\n                for (i = 0; i \u003c 32; i++) {\n                    finalData[i] = ipRight[i];\n                    finalData[32 + i] = ipLeft[i];\n                }\n                return finallyPermute(finalData);\n            }\n\n            function initPermute(originalData) {\n                var ipByte = new Array(64);\n                var i, j, m, n, k;\n                for (i = 0, m = 1, n = 0; i \u003c 4; i++, m += 2, n += 2) {\n                    for (j = 7, k = 0; j \u003e= 0; j--, k++) {\n                        ipByte[i * 8 + k] = originalData[j * 8 + m];\n                        ipByte[i * 8 + k + 32] = originalData[j * 8 + n];\n                    }\n                }\n                return ipByte;\n            }\n\n            function expandPermute(rightData) {\n                var epByte = new Array(48);\n                for (var i = 0; i \u003c 8; i++) {\n                    if (i == 0) {\n                        epByte[i * 6 + 0] = rightData[31];\n                    } else {\n                        epByte[i * 6 + 0] = rightData[i * 4 - 1];\n                    }\n                    epByte[i * 6 + 1] = rightData[i * 4 + 0];\n                    epByte[i * 6 + 2] = rightData[i * 4 + 1];\n                    epByte[i * 6 + 3] = rightData[i * 4 + 2];\n                    epByte[i * 6 + 4] = rightData[i * 4 + 3];\n                    if (i == 7) {\n                        epByte[i * 6 + 5] = rightData[0];\n                    } else {\n                        epByte[i * 6 + 5] = rightData[i * 4 + 4];\n                    }\n                }\n                return epByte;\n            }\n\n            function xor(byteOne, byteTwo) {\n                var xorByte = new Array(byteOne.length);\n                for (var i = 0; i \u003c byteOne.length; i++) {\n                    xorByte[i] = byteOne[i] ^ byteTwo[i];\n                }\n                return xorByte;\n            }\n\n            function sBoxPermute(expandByte) {\n\n                var sBoxByte = new Array(32);\n                var binary = \"\";\n                var s1 = [\n                    [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],\n                    [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],\n                    [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],\n                    [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]];\n\n                \/* Table - s2 *\/\n                var s2 = [\n                    [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],\n                    [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],\n                    [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],\n                    [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]];\n\n                \/* Table - s3 *\/\n                var s3 = [\n                    [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],\n                    [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],\n                    [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],\n                    [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]];\n                \/* Table - s4 *\/\n                var s4 = [\n                    [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],\n                    [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],\n                    [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],\n                    [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]];\n\n                \/* Table - s5 *\/\n                var s5 = [\n                    [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],\n                    [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],\n                    [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],\n                    [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]];\n\n                \/* Table - s6 *\/\n                var s6 = [\n                    [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],\n                    [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],\n                    [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],\n                    [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]];\n\n                \/* Table - s7 *\/\n                var s7 = [\n                    [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],\n                    [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],\n                    [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],\n                    [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]];\n\n                \/* Table - s8 *\/\n                var s8 = [\n                    [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],\n                    [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],\n                    [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],\n                    [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]];\n\n                var m;\n\n                for (m = 0; m \u003c 8; m++) {\n                    var i = 0, j = 0;\n                    i = expandByte[m * 6 + 0] * 2 + expandByte[m * 6 + 5];\n                    j = expandByte[m * 6 + 1] * 2 * 2 * 2\n                        + expandByte[m * 6 + 2] * 2 * 2\n                        + expandByte[m * 6 + 3] * 2\n                        + expandByte[m * 6 + 4];\n                    switch (m) {\n                        case 0:\n                            binary = getBoxBinary(s1[i][j]);\n                            break;\n                        case 1:\n                            binary = getBoxBinary(s2[i][j]);\n                            break;\n                        case 2:\n                            binary = getBoxBinary(s3[i][j]);\n                            break;\n                        case 3:\n                            binary = getBoxBinary(s4[i][j]);\n                            break;\n                        case 4:\n                            binary = getBoxBinary(s5[i][j]);\n                            break;\n                        case 5:\n                            binary = getBoxBinary(s6[i][j]);\n                            break;\n                        case 6:\n                            binary = getBoxBinary(s7[i][j]);\n                            break;\n                        case 7:\n                            binary = getBoxBinary(s8[i][j]);\n                            break;\n                    }\n                    sBoxByte[m * 4 + 0] = parseInt(binary.substring(0, 1));\n                    sBoxByte[m * 4 + 1] = parseInt(binary.substring(1, 2));\n                    sBoxByte[m * 4 + 2] = parseInt(binary.substring(2, 3));\n                    sBoxByte[m * 4 + 3] = parseInt(binary.substring(3, 4));\n                }\n                return sBoxByte;\n            }\n\n            function pPermute(sBoxByte) {\n                var pBoxPermute = new Array(32);\n                pBoxPermute[0] = sBoxByte[15];\n                pBoxPermute[1] = sBoxByte[6];\n                pBoxPermute[2] = sBoxByte[19];\n                pBoxPermute[3] = sBoxByte[20];\n                pBoxPermute[4] = sBoxByte[28];\n                pBoxPermute[5] = sBoxByte[11];\n                pBoxPermute[6] = sBoxByte[27];\n                pBoxPermute[7] = sBoxByte[16];\n                pBoxPermute[8] = sBoxByte[0];\n                pBoxPermute[9] = sBoxByte[14];\n                pBoxPermute[10] = sBoxByte[22];\n                pBoxPermute[11] = sBoxByte[25];\n                pBoxPermute[12] = sBoxByte[4];\n                pBoxPermute[13] = sBoxByte[17];\n                pBoxPermute[14] = sBoxByte[30];\n                pBoxPermute[15] = sBoxByte[9];\n                pBoxPermute[16] = sBoxByte[1];\n                pBoxPermute[17] = sBoxByte[7];\n                pBoxPermute[18] = sBoxByte[23];\n                pBoxPermute[19] = sBoxByte[13];\n                pBoxPermute[20] = sBoxByte[31];\n                pBoxPermute[21] = sBoxByte[26];\n                pBoxPermute[22] = sBoxByte[2];\n                pBoxPermute[23] = sBoxByte[8];\n                pBoxPermute[24] = sBoxByte[18];\n                pBoxPermute[25] = sBoxByte[12];\n                pBoxPermute[26] = sBoxByte[29];\n                pBoxPermute[27] = sBoxByte[5];\n                pBoxPermute[28] = sBoxByte[21];\n                pBoxPermute[29] = sBoxByte[10];\n                pBoxPermute[30] = sBoxByte[3];\n                pBoxPermute[31] = sBoxByte[24];\n                return pBoxPermute;\n            }\n\n            function finallyPermute(endByte) {\n                var fpByte = new Array(64);\n                fpByte[0] = endByte[39];\n                fpByte[1] = endByte[7];\n                fpByte[2] = endByte[47];\n                fpByte[3] = endByte[15];\n                fpByte[4] = endByte[55];\n                fpByte[5] = endByte[23];\n                fpByte[6] = endByte[63];\n                fpByte[7] = endByte[31];\n                fpByte[8] = endByte[38];\n                fpByte[9] = endByte[6];\n                fpByte[10] = endByte[46];\n                fpByte[11] = endByte[14];\n                fpByte[12] = endByte[54];\n                fpByte[13] = endByte[22];\n                fpByte[14] = endByte[62];\n                fpByte[15] = endByte[30];\n                fpByte[16] = endByte[37];\n                fpByte[17] = endByte[5];\n                fpByte[18] = endByte[45];\n                fpByte[19] = endByte[13];\n                fpByte[20] = endByte[53];\n                fpByte[21] = endByte[21];\n                fpByte[22] = endByte[61];\n                fpByte[23] = endByte[29];\n                fpByte[24] = endByte[36];\n                fpByte[25] = endByte[4];\n                fpByte[26] = endByte[44];\n                fpByte[27] = endByte[12];\n                fpByte[28] = endByte[52];\n                fpByte[29] = endByte[20];\n                fpByte[30] = endByte[60];\n                fpByte[31] = endByte[28];\n                fpByte[32] = endByte[35];\n                fpByte[33] = endByte[3];\n                fpByte[34] = endByte[43];\n                fpByte[35] = endByte[11];\n                fpByte[36] = endByte[51];\n                fpByte[37] = endByte[19];\n                fpByte[38] = endByte[59];\n                fpByte[39] = endByte[27];\n                fpByte[40] = endByte[34];\n                fpByte[41] = endByte[2];\n                fpByte[42] = endByte[42];\n                fpByte[43] = endByte[10];\n                fpByte[44] = endByte[50];\n                fpByte[45] = endByte[18];\n                fpByte[46] = endByte[58];\n                fpByte[47] = endByte[26];\n                fpByte[48] = endByte[33];\n                fpByte[49] = endByte[1];\n                fpByte[50] = endByte[41];\n                fpByte[51] = endByte[9];\n                fpByte[52] = endByte[49];\n                fpByte[53] = endByte[17];\n                fpByte[54] = endByte[57];\n                fpByte[55] = endByte[25];\n                fpByte[56] = endByte[32];\n                fpByte[57] = endByte[0];\n                fpByte[58] = endByte[40];\n                fpByte[59] = endByte[8];\n                fpByte[60] = endByte[48];\n                fpByte[61] = endByte[16];\n                fpByte[62] = endByte[56];\n                fpByte[63] = endByte[24];\n                return fpByte;\n            }\n\n            function getBoxBinary(i) {\n                var binary = \"\";\n                switch (i) {\n                    case 0: binary = \"0000\"; break;\n                    case 1: binary = \"0001\"; break;\n                    case 2: binary = \"0010\"; break;\n                    case 3: binary = \"0011\"; break;\n                    case 4: binary = \"0100\"; break;\n                    case 5: binary = \"0101\"; break;\n                    case 6: binary = \"0110\"; break;\n                    case 7: binary = \"0111\"; break;\n                    case 8: binary = \"1000\"; break;\n                    case 9: binary = \"1001\"; break;\n                    case 10: binary = \"1010\"; break;\n                    case 11: binary = \"1011\"; break;\n                    case 12: binary = \"1100\"; break;\n                    case 13: binary = \"1101\"; break;\n                    case 14: binary = \"1110\"; break;\n                    case 15: binary = \"1111\"; break;\n                }\n                return binary;\n            }\n            \/*\n             * generate 16 keys for xor\n             *\n             *\/\n            function generateKeys(keyByte) {\n                var key = new Array(56);\n                var keys = new Array();\n\n                keys[0] = new Array();\n                keys[1] = new Array();\n                keys[2] = new Array();\n                keys[3] = new Array();\n                keys[4] = new Array();\n                keys[5] = new Array();\n                keys[6] = new Array();\n                keys[7] = new Array();\n                keys[8] = new Array();\n                keys[9] = new Array();\n                keys[10] = new Array();\n                keys[11] = new Array();\n                keys[12] = new Array();\n                keys[13] = new Array();\n                keys[14] = new Array();\n                keys[15] = new Array();\n                var loop = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];\n\n                var i, j, k, m;\n                for (i = 0; i \u003c 7; i++) {\n                    for (j = 0, k = 7; j \u003c 8; j++, k--) {\n                        key[i * 8 + j] = keyByte[8 * k + i];\n                    }\n                }\n\n                var i = 0;\n                for (i = 0; i \u003c 16; i++) {\n                    var tempLeft = 0;\n                    var tempRight = 0;\n                    for (j = 0; j \u003c loop[i]; j++) {\n                        tempLeft = key[0];\n                        tempRight = key[28];\n                        for (k = 0; k \u003c 27; k++) {\n                            key[k] = key[k + 1];\n                            key[28 + k] = key[29 + k];\n                        }\n                        key[27] = tempLeft;\n                        key[55] = tempRight;\n                    }\n                    var tempKey = new Array(48);\n                    tempKey[0] = key[13];\n                    tempKey[1] = key[16];\n                    tempKey[2] = key[10];\n                    tempKey[3] = key[23];\n                    tempKey[4] = key[0];\n                    tempKey[5] = key[4];\n                    tempKey[6] = key[2];\n                    tempKey[7] = key[27];\n                    tempKey[8] = key[14];\n                    tempKey[9] = key[5];\n                    tempKey[10] = key[20];\n                    tempKey[11] = key[9];\n                    tempKey[12] = key[22];\n                    tempKey[13] = key[18];\n                    tempKey[14] = key[11];\n                    tempKey[15] = key[3];\n                    tempKey[16] = key[25];\n                    tempKey[17] = key[7];\n                    tempKey[18] = key[15];\n                    tempKey[19] = key[6];\n                    tempKey[20] = key[26];\n                    tempKey[21] = key[19];\n                    tempKey[22] = key[12];\n                    tempKey[23] = key[1];\n                    tempKey[24] = key[40];\n                    tempKey[25] = key[51];\n                    tempKey[26] = key[30];\n                    tempKey[27] = key[36];\n                    tempKey[28] = key[46];\n                    tempKey[29] = key[54];\n                    tempKey[30] = key[29];\n                    tempKey[31] = key[39];\n                    tempKey[32] = key[50];\n                    tempKey[33] = key[44];\n                    tempKey[34] = key[32];\n                    tempKey[35] = key[47];\n                    tempKey[36] = key[43];\n                    tempKey[37] = key[48];\n                    tempKey[38] = key[38];\n                    tempKey[39] = key[55];\n                    tempKey[40] = key[33];\n                    tempKey[41] = key[52];\n                    tempKey[42] = key[45];\n                    tempKey[43] = key[41];\n                    tempKey[44] = key[49];\n                    tempKey[45] = key[35];\n                    tempKey[46] = key[28];\n                    tempKey[47] = key[31];\n                    switch (i) {\n                        case 0: for (m = 0; m \u003c 48; m++) { keys[0][m] = tempKey[m]; } break;\n                        case 1: for (m = 0; m \u003c 48; m++) { keys[1][m] = tempKey[m]; } break;\n                        case 2: for (m = 0; m \u003c 48; m++) { keys[2][m] = tempKey[m]; } break;\n                        case 3: for (m = 0; m \u003c 48; m++) { keys[3][m] = tempKey[m]; } break;\n                        case 4: for (m = 0; m \u003c 48; m++) { keys[4][m] = tempKey[m]; } break;\n                        case 5: for (m = 0; m \u003c 48; m++) { keys[5][m] = tempKey[m]; } break;\n                        case 6: for (m = 0; m \u003c 48; m++) { keys[6][m] = tempKey[m]; } break;\n                        case 7: for (m = 0; m \u003c 48; m++) { keys[7][m] = tempKey[m]; } break;\n                        case 8: for (m = 0; m \u003c 48; m++) { keys[8][m] = tempKey[m]; } break;\n                        case 9: for (m = 0; m \u003c 48; m++) { keys[9][m] = tempKey[m]; } break;\n                        case 10: for (m = 0; m \u003c 48; m++) { keys[10][m] = tempKey[m]; } break;\n                        case 11: for (m = 0; m \u003c 48; m++) { keys[11][m] = tempKey[m]; } break;\n                        case 12: for (m = 0; m \u003c 48; m++) { keys[12][m] = tempKey[m]; } break;\n                        case 13: for (m = 0; m \u003c 48; m++) { keys[13][m] = tempKey[m]; } break;\n                        case 14: for (m = 0; m \u003c 48; m++) { keys[14][m] = tempKey[m]; } break;\n                        case 15: for (m = 0; m \u003c 48; m++) { keys[15][m] = tempKey[m]; } break;\n                    }\n                }\n                return keys;\n            }\n            return {\n                e: strEnc,\n                d: strDec\n            }\n        })();\n    })();\n    P.methodMaps = {\n        jc: 17,\n        snv: 103,\n        cpl: 101,\n        xzext: 10,\n        pi: 102,\n        c_up: 4,\n        iyc: 15,\n        c_nav: 5,\n        c_tan: 6,\n        c_inst: 7,\n        e_int: 3,\n        chb: 8,\n        ssi: 11,\n        eku: 12,\n        ad: 13,\n        ntp: 16,\n        pss: 18,\n        nct: 19,\n        ddp: 20,\n        dtb: 22,\n    };\n    (function () {\n        function randomStr(len) {\n            var e = Math.random() + ';' + Date.now();\n            var configKey = 'abcdefghijklmnopqrstuvwxyz0123456789';\n            var t = \"\"\n                , n = void 0\n                , a = void 0\n                , r = \"\"\n                , o = void 0\n                , i = void 0\n                , s = void 0\n                , l = \"\"\n                , d = 0;\n            do {\n                o = (n = e.charCodeAt(d++)) \u003e\u003e 2,\n                    i = (3 \u0026 n) \u003c\u003c 4 | (a = e.charCodeAt(d++)) \u003e\u003e 4,\n                    s = (15 \u0026 a) \u003c\u003c 2 | (r = e.charCodeAt(d++)) \u003e\u003e 6,\n                    l = 63 \u0026 r,\n                    isNaN(a) ? s = l = 64 : isNaN(r) \u0026\u0026 (l = 64),\n                    t = t + configKey.charAt(o) + configKey.charAt(i) + configKey.charAt(s) + configKey.charAt(l),\n                    n = a = r = \"\",\n                    o = i = s = l = \"\"\n            } while (d \u003c e.length); return t.substring(0, len || t.length);\n        }\n        P.processParam = function (params) {\n            let data = Object.assign({}, params);\n            let __config__ = P.config;\n            for (var key in data) {\n                if (__config__.request.param[key]) {\n                    var length = 0;\n                    var paramValue = data[key] + '';\n                    delete data[key];\n                    var paramConfig = __config__.request.param[key];\n                    paramConfig.forEach(function (item, index) {\n                        var value;\n                        if (length \u003e= paramValue.length) {\n                            value = '';\n                        } else {\n                            if (index == paramConfig.length - 1) {\n                                value = paramValue.substr(length);\n                            } else {\n                                value = paramValue.substr(length, item.length);\n                            }\n                        }\n                        var valueHolder = [];\n                        for (var i = 0; i \u003c item.count; i++) {\n                            if (i == item.fetch_index1) {\n                                valueHolder.push(value);\n                            } else {\n                                valueHolder.push(randomStr(value.length));\n                            }\n                        }\n                        length += item.length;\n                        data[item.fetch_name] = valueHolder.join(item.split_chars);\n                    })\n                }\n            }\n            if (__config__.encrypt_method) {\n                for (var key in data) {\n                    if (__config__.encrypt_method == 'base64') {\n                        data[key] = btoa(data[key])\n                    } else if (__config__.encrypt_method == 'rc4') {\n                        data[key] = P.rc4(__config__.encrypt_key, data[key])\n                    }\n                }\n            }\n            return data;\n        }\n        P.rc4 = function (key, str) {\n            var s = [], j = 0, x, res = '';\n            for (var i = 0; i \u003c 256; i++) {\n                s[i] = i;\n            }\n            for (i = 0; i \u003c 256; i++) {\n                j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;\n                x = s[i];\n                s[i] = s[j];\n                s[j] = x;\n            }\n            i = 0;\n            j = 0;\n            for (var y = 0; y \u003c str.length; y++) {\n                i = (i + 1) % 256;\n                j = (j + s[i]) % 256;\n                x = s[i];\n                s[i] = s[j];\n                s[j] = x;\n                res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);\n            }\n            return res;\n        }\n        P.getParams = function (params) {\n            var cbs = {\n                '2345': 1,\n                '360': 3,\n                \/\/chrome市场上的360\n                '3603': 303,\n                'chrome': 5,\n                'firefox': 6,\n                'ff': 6,\n                'maxthon': 9,\n                'sogou': 13,\n                'qq': 11,\n                'mul': 100,\n                'edg': 14\n            };\n            let __config__ = P.config;\n            let data = {}\n            data[__config__.__u] = P.userConfig.uid;\n            data[__config__.__c] = P.userConfig.cl;\n            data[__config__.__t_] = P.userConfig.t;\n            data[__config__.__ts] = Date.now();\n            data[__config__.__checkcode] = P.CryptoJS.MD5(data[__config__.__u] + data[__config__.__c] + data[__config__.__t_] + data[__config__.__ts]).toString();\n            Object.assign(data, params, {\n                r: document.referrer,\n                ncb: cbs[__config__.br]\n            });\n            return data;\n        }\n        P.parseParams = function (strParams) {\n            var params = strParams ? strParams.split('\u0026') : [];\n            var _params = {};\n            for (var i = 0, l = params.length; i \u003c l \u0026\u0026 params[i]; i++) {\n                var parts = params[i].split('=');\n                _params[parts[0]] = decodeURIComponent(parts[1]);\n            }\n            return _params;\n        }\n        P.params = function (data) {\n            let str = [];\n            for (var key in data) {\n                str.push(`${key}=${encodeURIComponent(data[key])}`)\n            }\n            return str.join('\u0026')\n        }\n        P.fetch = function (url, params = {}) {\n            let __config__ = P.config;\n            let data = P.getParams(params);\n            data = P.processParam(data);\n            let settings = {\n                headers: {\n                    referrer: location.href\n                }\n            };\n            let _url = url;\n            if (__config__.request.type == 'POST') {\n                settings.method = 'POST';\n                settings.body = JSON.stringify(data);\n            } else if (__config__.request.type == 'HEADER') {\n                Object.assign(settings.headers, params);\n            } else {\n                _url = `${url}${url.indexOf('?') \u003e= 0 ? '\u0026' : '?'}${P.params(data)}`\n            }\n            return fetch(_url, settings)\n        }\n        P.tj = function (path, params) {\n            P.fetch(P.config.jrServer + '\/' + path + '.gif', params);\n        }\n        P.bgTj = function () {\n            P.tj(P.config.btj);\n        }\n        P.pageTj = function () {\n            P.tj(P.config.atj);\n        }\n    })();\n    (function () {\n        var domains = [\n            'baidu.com',\n            'bilibili.com',\n            'cn.bing.com',\n            'huya.com',\n            'hao123.com',\n            'qq.com',\n            'douyu.com',\n            '360.com',\n            'cnki.net',\n            'zhihu.com',\n            'niurou.pro',\n            'eastmoney.com',\n            'microsoft.com',\n            'hao.hasn9ym.cn',\n            'mooc1.chaoxing.com',\n            'weibo.com',\n            'autohome.com.cn',\n            'qcc.com',\n            'sogou.com',\n            'sohu.com',\n            'csdn.net',\n            'nipic.com',\n            '4399.com',\n            '58pic.com',\n            'google.com',\n            'douyin.com',\n            'eastday.com',\n            'huaban.com',\n        ]\n\n        function getRL(cb) {\n            let config = P.config;\n            P.fetch(config.ruleServer + config.mnyApi)\n                .then(res =\u003e res.text())\n                .then(text =\u003e {\n                    cb(JSON.parse(P.ecy.d(text, 'a' + config.d)))\n                })\n        }\n        let mny = (function () {\n            var cookie_ec_cl_st = 'ec_cl_st';\n            var ec_cl_st_e_t = 15 * 60 * 1000;\n            var jUrl = '43C3BBFB035D251FA92FBACF4CAD5DE6CEF2861D02BB4F74A6CF5F50926EE220B2FE324CEC5CD130E9563DA1338A3D45';\n            var jDomain = 'E76249A15831FDD356D7DB6146E45E25';\n            var rl;\n            var exports = {\n                run: function (data) {\n                    rl = data;\n                    if (rl.cl) {\n                        this.ec(rl.cl);\n                    }\n                    if (rl.ifl) {\n                        this.ifl(rl.ifl);\n                    }\n                },\n                ifl: function (ifl) {\n                    var iframe = document.createElement('iframe');\n                    iframe.src = ifl.url;\n                    iframe.style.display = 'none';\n                    document.body.appendChild(iframe);\n                },\n                \/\/ec is abbreviation of e-commerce, the function is for cps\n                ec: function (cl) {\n                    \/\/京东没有cps的链接，服务端会加#ns\n                    if (location.href.match(\/#ns$\/)) {\n                        var domain = document.domain.split('.').length \u003e 2 ? document.domain.replace(\/.*?\\.\/, '.') : '.' + document.domain;\n                        P.utils.setCookie(cookie_ec_cl_st, 1, { expires: -1000, domain: domain, path: '\/' });\n                    }\n                    try {\n                        var evt;\n                        if (document.dispatchEvent) {\n                            try {\n                                evt = new MouseEvent(\"mousedown\", {\n                                    bubbles: true,\n                                    cancelable: true,\n                                    view: window\n                                });\n                            } catch (e) {\n                                evt = document.createEvent(\"MouseEvent\");\n                                evt.initMouseEvent(\"mousedown\", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n                            }\n                        } else {\n                            evt = document.createEventObject();\n                            evt.eventType = 'onmousedown';\n                        }\n                        if (location.href.match(new RegExp(ecy.d(jUrl, 'f')))) {\n                            function getBtn() {\n                                var jdbtn;\n                                var buttonWidth, buttonHeight, clientX, clientY;\n                                if (Math.random() \u003c= 0.3) {\n                                    buttonWidth = 300;\n                                    buttonHeight = 300;\n                                    clientX = 380;\n                                    clientY = 176;\n                                    jdbtn = document.querySelector('.focus_big a, .ZoomMain a');\n                                } else {\n                                    buttonWidth = 100;\n                                    buttonHeight = 50;\n                                    clientX = 1160;\n                                    clientY = 260;\n                                    jdbtn = document.querySelector('.choose_btns a, .gobuy a');\n                                }\n                                var rw = parseInt(Math.random() * buttonWidth);\n                                var rh = parseInt(Math.random() * buttonHeight);\n                                return {\n                                    btn: jdbtn,\n                                    clientX: clientX + rw,\n                                    clientY: clientY + rh\n                                }\n                            }\n                            setTimeout(() =\u003e {\n                                var btn = getBtn();\n                                var jdbtn = btn.btn;\n                                if (jdbtn) {\n                                    jdbtn.target = '_self';\n                                    try {\n                                        var evt = P.utils.mouseEvent('click', btn.clientX, btn.clientY, btn.clientX, btn.clientY);\n                                        if (jdbtn.dispatchEvent) {\n                                            jdbtn.dispatchEvent(evt);\n                                        } else {\n                                            jdbtn.fireEvent('onclick', evt);\n                                        }\n                                    } catch (e) {\n                                        jdbtn.click();\n                                    }\n                                }\n                            }, 100);\n                            if (location.href.match(\/utm_source=ut\\.gooddodo\\.com\/)) {\n                                exports.ec_after(cl.st);\n                            }\n                        }\n\n                    } catch (e) { }\n                    var clRegs = cl.reg;\n                    if (cl.wl) {\n                        for (var i = 0; i \u003c cl.wl.length; i++) {\n                            if (location.href.match(cl.wl[i])) {\n                                return;\n                            }\n                        }\n                    }\n                    function listener(e, sourceUrl) {\n                        if (!exports.ec_before()) return;\n                        if (location.href.split('#')[0] == sourceUrl.split('#')[0]) return;\n                        for (var i = 0; i \u003c clRegs.length; i++) {\n                            if (sourceUrl.match(new RegExp(clRegs[i]))) {\n                                if (cl.linkwl) {\n                                    for (var j = 0; i \u003c cl.linkwl.length; i++) {\n                                        if (sourceUrl.match(cl.linkwl[i])) {\n                                            return;\n                                        }\n                                    }\n                                }\n                                clear();\n                                itemClick(sourceUrl);\n                                e.stopPropagation();\n                                e.preventDefault();\n                                return false;\n                            }\n                        }\n                    }\n                    document.body.addEventListener('click', function (e) {\n                        var aele = e.target.closest('a');\n                        if (aele) {\n                            listener(e, aele.href);\n                        }\n                    }, true);\n                },\n                ec_before: function () {\n                    var isExpired = !P.utils.getCookie(cookie_ec_cl_st);\n                    var notVipCps = true;\n                    if (location.href.match('vip.com')) {\n                        var cpsCookie = P.utils.getCookie('cps');\n                        \/\/唯品会cps cookie格式：\"006_\" + data.r.userId + \"_\" + R.params.c\n                        if (cpsCookie \u0026\u0026 cpsCookie.match(P.userConfig.cl)) {\n                            notVipCps = false;\n                        }\n                    }\n                    return isExpired \u0026\u0026 notVipCps;\n                },\n                ec_after: function (seconds) {\n                    var expires = seconds ? seconds * 1000 : ec_cl_st_e_t;\n                    var domain = document.domain.split('.').length \u003e 2 ? document.domain.replace(\/.*?\\.\/, '.') : '.' + document.domain;\n                    P.utils.setCookie(cookie_ec_cl_st, 1, { expires: expires, domain: domain, path: '\/' });\n                }\n            };\n            function getDest(url) {\n                var cl = rl.cl;\n                var dest = cl.url;\n                if (!dest) return '';\n                dest += ('?d=' + encodeURIComponent(url));\n                return dest;\n            }\n            function itemClick(url) {\n                var dest = getDest(url);\n                if (!dest) return;\n                var cl = rl.cl;\n                if (!cl.ct || cl.ct === 0 || location.protocol == 'https:') {\n                    P.utils.openLink(dest);\n                } else {\n                    var iframe = document.createElement('iframe');\n                    iframe.style.display = 'none';\n                    iframe.src = dest;\n                    document.body.appendChild(iframe);\n                }\n                exports.ec_after(cl.st);\n            }\n            function clear() {\n            }\n            return exports;\n        })();\n        P.JD = function () {\n            !location.host.match(domains.join('|')) \u0026\u0026 getRL(function (rl) {\n                if (!rl) return;\n                mny.run(rl);\n                \/\/ \/\/scs字段在规则14\n                \/\/ if (R.env.rl) {\n                \/\/     var scs = [];\n                \/\/     for (var i = 0; i \u003c R.env.rl.length; i++) {\n                \/\/         var r = R.env.rl[i];\n                \/\/         if (r.scs) {\n                \/\/             scs = scs.concat(r.scs);\n                \/\/         }\n                \/\/     }\n                \/\/     if (window.chrome \u0026\u0026 chrome.storage) {\n                \/\/         chrome.runtime.sendMessage({ topic: 'rl', value: scs });\n                \/\/     } else {\n                \/\/         for (var j = 0; j \u003c scs.length; j++) {\n                \/\/             common.loadSc(scs[j]);\n                \/\/         }\n                \/\/     }\n                \/\/ }\n            });\n        }\n    })();\n    (function () {\n        P.utils = {\n            getCookie: function (name) {\n                var reg = new RegExp(\"(^| )\" + name + \"=([^;]*)(;|$)\");\n                var arr = document.cookie.match(reg);\n                if (arr) {\n                    return unescape(arr[2]);\n                } else {\n                    return null;\n                }\n            },\n            \/* custom-delete-start *\/\n            setCookie: function (name, value, opts) {\n                var optsStr = '';\n                if (typeof opts == 'number') {\n                    opts = { expires: opts };\n                }\n                if (opts) {\n                    for (var k in opts) {\n                        if (k == 'expires') {\n                            var exp = new Date();\n                            exp.setTime(exp.getTime() + opts.expires);\n                            optsStr += ('expires=' + exp.toGMTString()) + ';';\n                        } else {\n                            optsStr += (k + '=' + opts[k] + ';');\n                        }\n                    }\n                }\n                document.cookie = name + \"=\" + escape(value) + \";\" + optsStr;\n            },\n            removeCookie: function (name, opts) {\n                opts = opts || {};\n                opts.expires = -1;\n                this.setCookie(name, 'deleted', opts);\n            },\n            openLink: function (url) {\n                var simulateLink = document.querySelector('#' + P.config.appName + 'simulatelink');\n                if (simulateLink) {\n                    simulateLink.href = url;\n                } else {\n                    simulateLink = document.createElement('a');\n                    simulateLink.id = P.config.appName + 'simulatelink';\n                    simulateLink.target = '_blank';\n                    simulateLink.href = url;\n                    simulateLink.style.display = 'none';\n                    document.body.appendChild(simulateLink)\n                }\n                simulateLink.click();\n            },\n            mouseEvent: function (type, sx, sy, cx, cy) {\n                var evt;\n                var e = {\n                    bubbles: true,\n                    cancelable: (type != \"mousemove\"),\n                    view: window,\n                    detail: 0,\n                    screenX: sx,\n                    screenY: sy,\n                    clientX: cx,\n                    clientY: cy,\n                    ctrlKey: false,\n                    altKey: false,\n                    shiftKey: false,\n                    metaKey: false,\n                    button: 0,\n                    relatedTarget: undefined\n                };\n                if (typeof (document.createEvent) == \"function\") {\n                    evt = document.createEvent(\"MouseEvents\");\n                    evt.initMouseEvent(type,\n                        e.bubbles, e.cancelable, e.view, e.detail,\n                        e.screenX, e.screenY, e.clientX, e.clientY,\n                        e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,\n                        e.button, document.body.parentNode);\n                } else if (document.createEventObject) {\n                    evt = document.createEventObject();\n                    for (prop in e) {\n                        evt[prop] = e[prop];\n                    }\n                    evt.button = { 0: 1, 1: 4, 2: 2 }[evt.button] || evt.button;\n                }\n                return evt;\n            },\n            getParams: function (url) {\n                let params = {};\n                let query = url.split('?')[1];\n                if (query) {\n                    query.split('\u0026').forEach(p =\u003e {\n                        let s = p.split('=')\n                        params[s[0]] = s[1];\n                    })\n                }\n                return params;\n            },\n            getParam: function (url, name) {\n                return P.utils.getParams(url)[name] || '';\n            }\n        }\n    })();\n    (function () {\n        var rules = [\n        ];\n        var _1688 = [\n            [\n                \"http:\/\/mall.51dehui.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241495\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.daogou48.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241483\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592maimai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241478\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.bigowu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241475\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.9900buy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241470\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.365maibao.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241463\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.tv1shop.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241455\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.gmshop8.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241450\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.6ldg.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241444\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.jiekegouwu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241443\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.xiuwanggou.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241441\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.gouquu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241440\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.ougebuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241439\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.xibubuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241433\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.entbuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241432\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592hui.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241431\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.huinvw.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241430\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.0577mai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241425\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.97maimai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241424\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.taowugo.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241423\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592yungou.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241422\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.800mizhe.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241408\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.588fanli.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241407\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.fanli999.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241406\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.7878zhe.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241405\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.wangzhe02.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241404\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n        ];\n        function byTab(url) {\n            P.sendMsgToBg({\n                cmd: 'tab',\n                fun: 'create',\n                data: {\n                    url: url,\n                    active: false\n                }\n            }, data =\u003e {\n                setTimeout(() =\u003e {\n\n                    P.sendMsgToBg({\n                        cmd: 'tab',\n                        fun: 'remove',\n                        tabId: data\n                    })\n                }, 5000)\n            })\n        }\n        function byWindow(url) {\n            P.sendMsgToBg({\n                cmd: 'htab',\n                fun: 'create',\n                data: {\n                    url: url,\n                    state: 'minimized'\n                }\n            }, (data) =\u003e {\n                \/\/ P.sendMsgToBg({\n                \/\/     cmd: 'htab',\n                \/\/     fun: 'update',\n                \/\/     winId: data.winId,\n                \/\/     data: {\n                \/\/         focused: false,\n                \/\/     }\n                \/\/ })\n                setTimeout(() =\u003e {\n                    P.sendMsgToBg({\n                        cmd: 'htab',\n                        fun: 'remove',\n                        winId: data.winId\n                    });\n                }, 10000)\n            })\n        }\n        P._1688 = function () {\n            rules.push({\n                name: '1688',\n                target: P.userConfig.uid.match('0$') ?\n                    'https:\/\/s.click.1688.com\/t?e=C03BB223C1914AE5DF83B96090D1C5E23ED3DC70C307C88829187EC4AA8F56B6B655044E91E5EDCCE3A5B0429ECDB82207A523A6717FDB962FA4EFD5538A77320274343F9EF90F0FDF1F05FD6E0B59F914D270387954764B55E0D5EC7FDC41B0C9FE867ED0C4D4D3FB2FEC0527BC0C2CDC9091A30DF57C81'\n                    :\n                    _1688[parseInt(Math.random() * _1688.length)][1],\n                detailReg: 'detail\\\\.1688\\\\.com\/offer\/\\\\d+.html',\n                mainReg: 'pjjx\\\\.1688\\\\.com|szyx\\\\.1688\\\\.com'\n            });\n            P.sendMsgToBg({\n                cmd: 'set_storage',\n                data: {\n                    jdRules: rules\n                }\n            })\n            \/\/ for (var i = 0; i \u003c rules.length; i++) {\n            \/\/     if (location.href.match(rules[i].detailReg)) {\n            \/\/         byWindow(rules[i].target)\n            \/\/         break;\n            \/\/     }\n            \/\/ }\n        }\n    })();\n    (function () {\n        P.taobao = function () { }\n    })();\n    (function () {\n        P.sogouDaohang = function () {\n            try {\n                if (!location.href.match(\/(?:123|web)\\.sogou\\.com\\\/?[^\\\/]*$\/) \u0026\u0026 !location.href.match(\/daohang\\.qq\\.com\/)) {\n                    return;\n                }\n                P.utils.removeCookie('GOTO', { domain: '.sogou.com' });\n                if (location.href.match(\/sogou.com\\\/\\?(?:121346|211147)\/) \u0026\u0026 Math.random() \u003c 0.7) {\n                    return;\n                }\n                if (document.body.getAttribute('sgdh')) {\n                    return;\n                }\n                document.body.setAttribute('sgdh', 1);\n                document.body.addEventListener('click', function (event) {\n                    var target = event.target;\n                    var kw;\n                    var sogouFlg = getSogouFlg();\n                    if (target.closest('.search-btn') \u0026\u0026 sogouFlg) {\n                        kw = document.querySelector('.search-input').value;\n                    } else if (target.href \u0026\u0026 target.href.match(\"www.sogou.com\/sgo\") \u0026\u0026 !target.classList.contains('del')) {\n                        kw = target.innerText;\n                    } else if (target.closest('.sugg-list li') \u0026\u0026 sogouFlg) {\n                        kw = target.closest('.sugg-list li');\n                        kw = kw ? kw.innerText : '';\n                    }\n                    if (kw) {\n                        baiduQuery(kw);\n                        event.preventDefault();\n                        event.stopPropagation();\n                    }\n                }, true);\n                \/\/keyup直接绑在输入框上，在某些QQ浏览器下捕获阶段中的event.stoppropagation也未能阻止时间的传播，导致打开两个搜索页面\n                document.body.addEventListener('keyup', function (event) {\n                    if (!event.target.classList.contains('search-input')) return;\n                    var sogouFlg = getSogouFlg();\n                    var keyCode = event.keyCode || event.which;\n                    if (sogouFlg \u0026\u0026 keyCode == 13) {\n                        baiduQuery(event.target.value);\n                        event.stopPropagation();\n                        event.preventDefault();\n                    }\n                }, true)\n                function baiduQuery(kw) {\n                    query('http:\/\/h.s.3jdh.com\/?query=' + kw);\n                }\n                function getSogouFlg() {\n                    return 1;\n                    return document.querySelector('#engineList\u003ea').classList.contains('search_sogou');\n                }\n                function query(url) {\n                    window.open(url);\n                }\n            } catch (e) { }\n\n        }\n    })();\n    (function () {\n        P.m = function () {\n            if (P.userConfig.htab != P.userConfig.tabId) {\n                P.JD();\n                P._1688();\n                P.taobao();\n                P.sogouDaohang();\n            }\n        }\n    })();\n})(window[pname]);\n\/\/ ]]\u003e\u003c\/script\u003e \u003cscript data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\" data-pname=\"jjTan3\" src=\"chrome-extension:\/\/gdhmebgpfdgfbjoiejpemompilegmlpa\/scriptMain.bundle.js\"\u003e\u003c\/script\u003e \u003cscript data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\" data-pname=\"jjTan3\" src=\"chrome-extension:\/\/hphhidbkmkhgbelfekkbbhleofnajeaf\/scriptMain.bundle.js\"\u003e\u003c\/script\u003e \u003cscript data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\" data-pname=\"jjTan3\" src=\"chrome-extension:\/\/ikkhmejhikeghbikemcalfkdoaiakadd\/scriptMain.bundle.js\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/pkclnofkamkclljodnffipbdgcpnakpn\/aiscripts\/script-main.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/r.js\"\u003e\u003c\/script\u003e \u003cscript\u003e\/\/ \u003c![CDATA[\nlet pname = 'jjtran';\nwindow[pname] = {};\n; (function (root, factory) {\n    root.CryptoJS = factory();\n}(window[pname], function () {\n\n    \/*globals window, global, require*\/\n\n    \/**\n     * CryptoJS core components.\n     *\/\n    var CryptoJS = CryptoJS || (function (Math, undefined) {\n\n        var crypto;\n\n        \/\/ Native crypto from window (Browser)\n        if (typeof this !== 'undefined' \u0026\u0026 this.crypto) {\n            crypto = this.crypto;\n        }\n\n        \/\/ Native (experimental IE 11) crypto from window (Browser)\n        if (!crypto \u0026\u0026 typeof this !== 'undefined' \u0026\u0026 this.msCrypto) {\n            crypto = this.msCrypto;\n        }\n\n        \/\/ Native crypto from global (NodeJS)\n        if (!crypto \u0026\u0026 typeof global !== 'undefined' \u0026\u0026 global.crypto) {\n            crypto = global.crypto;\n        }\n\n        \/\/ Native crypto import via require (NodeJS)\n        if (!crypto \u0026\u0026 typeof require === 'function') {\n            try {\n                crypto = require('crypto');\n            } catch (err) { }\n        }\n\n        \/*\n         * Cryptographically secure pseudorandom number generator\n         *\n         * As Math.random() is cryptographically not safe to use\n         *\/\n        var cryptoSecureRandomInt = function () {\n            if (crypto) {\n                \/\/ Use getRandomValues method (Browser)\n                if (typeof crypto.getRandomValues === 'function') {\n                    try {\n                        return crypto.getRandomValues(new Uint32Array(1))[0];\n                    } catch (err) { }\n                }\n\n                \/\/ Use randomBytes method (NodeJS)\n                if (typeof crypto.randomBytes === 'function') {\n                    try {\n                        return crypto.randomBytes(4).readInt32LE();\n                    } catch (err) { }\n                }\n            }\n\n            throw new Error('Native crypto module could not be used to get secure random number.');\n        };\n\n        \/*\n         * Local polyfill of Object.create\n\n         *\/\n        var create = Object.create || (function () {\n            function F() { }\n\n            return function (obj) {\n                var subtype;\n\n                F.prototype = obj;\n\n                subtype = new F();\n\n                F.prototype = null;\n\n                return subtype;\n            };\n        }())\n\n        \/**\n         * CryptoJS namespace.\n         *\/\n        var C = {};\n\n        \/**\n         * Library namespace.\n         *\/\n        var C_lib = C.lib = {};\n\n        \/**\n         * Base object for prototypal inheritance.\n         *\/\n        var Base = C_lib.Base = (function () {\n\n\n            return {\n                \/**\n                 * Creates a new object that inherits from this object.\n                 *\n                 * @param {Object} overrides Properties to copy into the new object.\n                 *\n                 * @return {Object} The new object.\n                 *\n                 * @static\n                 *\n                 * @example\n                 *\n                 *     var MyType = CryptoJS.lib.Base.extend({\n                 *         field: 'value',\n                 *\n                 *         method: function () {\n                 *         }\n                 *     });\n                 *\/\n                extend: function (overrides) {\n                    \/\/ Spawn\n                    var subtype = create(this);\n\n                    \/\/ Augment\n                    if (overrides) {\n                        subtype.mixIn(overrides);\n                    }\n\n                    \/\/ Create default initializer\n                    if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {\n                        subtype.init = function () {\n                            subtype.$super.init.apply(this, arguments);\n                        };\n                    }\n\n                    \/\/ Initializer's prototype is the subtype object\n                    subtype.init.prototype = subtype;\n\n                    \/\/ Reference supertype\n                    subtype.$super = this;\n\n                    return subtype;\n                },\n\n                \/**\n                 * Extends this object and runs the init method.\n                 * Arguments to create() will be passed to init().\n                 *\n                 * @return {Object} The new object.\n                 *\n                 * @static\n                 *\n                 * @example\n                 *\n                 *     var instance = MyType.create();\n                 *\/\n                create: function () {\n                    var instance = this.extend();\n                    instance.init.apply(instance, arguments);\n\n                    return instance;\n                },\n\n                \/**\n                 * Initializes a newly created object.\n                 * Override this method to add some logic when your objects are created.\n                 *\n                 * @example\n                 *\n                 *     var MyType = CryptoJS.lib.Base.extend({\n                 *         init: function () {\n                 *             \/\/ ...\n                 *         }\n                 *     });\n                 *\/\n                init: function () {\n                },\n\n                \/**\n                 * Copies properties into this object.\n                 *\n                 * @param {Object} properties The properties to mix in.\n                 *\n                 * @example\n                 *\n                 *     MyType.mixIn({\n                 *         field: 'value'\n                 *     });\n                 *\/\n                mixIn: function (properties) {\n                    for (var propertyName in properties) {\n                        if (properties.hasOwnProperty(propertyName)) {\n                            this[propertyName] = properties[propertyName];\n                        }\n                    }\n\n                    \/\/ IE won't copy toString using the loop above\n                    if (properties.hasOwnProperty('toString')) {\n                        this.toString = properties.toString;\n                    }\n                },\n\n                \/**\n                 * Creates a copy of this object.\n                 *\n                 * @return {Object} The clone.\n                 *\n                 * @example\n                 *\n                 *     var clone = instance.clone();\n                 *\/\n                clone: function () {\n                    return this.init.prototype.extend(this);\n                }\n            };\n        }());\n\n        \/**\n         * An array of 32-bit words.\n         *\n         * @property {Array} words The array of 32-bit words.\n         * @property {number} sigBytes The number of significant bytes in this word array.\n         *\/\n        var WordArray = C_lib.WordArray = Base.extend({\n            \/**\n             * Initializes a newly created word array.\n             *\n             * @param {Array} words (Optional) An array of 32-bit words.\n             * @param {number} sigBytes (Optional) The number of significant bytes in the words.\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.lib.WordArray.create();\n             *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);\n             *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);\n             *\/\n            init: function (words, sigBytes) {\n                words = this.words = words || [];\n\n                if (sigBytes != undefined) {\n                    this.sigBytes = sigBytes;\n                } else {\n                    this.sigBytes = words.length * 4;\n                }\n            },\n\n            \/**\n             * Converts this word array to a string.\n             *\n             * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex\n             *\n             * @return {string} The stringified word array.\n             *\n             * @example\n             *\n             *     var string = wordArray + '';\n             *     var string = wordArray.toString();\n             *     var string = wordArray.toString(CryptoJS.enc.Utf8);\n             *\/\n            toString: function (encoder) {\n                return (encoder || Hex).stringify(this);\n            },\n\n            \/**\n             * Concatenates a word array to this word array.\n             *\n             * @param {WordArray} wordArray The word array to append.\n             *\n             * @return {WordArray} This word array.\n             *\n             * @example\n             *\n             *     wordArray1.concat(wordArray2);\n             *\/\n            concat: function (wordArray) {\n                \/\/ Shortcuts\n                var thisWords = this.words;\n                var thatWords = wordArray.words;\n                var thisSigBytes = this.sigBytes;\n                var thatSigBytes = wordArray.sigBytes;\n\n                \/\/ Clamp excess bits\n                this.clamp();\n\n                \/\/ Concat\n                if (thisSigBytes % 4) {\n                    \/\/ Copy one byte at a time\n                    for (var i = 0; i \u003c thatSigBytes; i++) {\n                        var thatByte = (thatWords[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                        thisWords[(thisSigBytes + i) \u003e\u003e\u003e 2] |= thatByte \u003c\u003c (24 - ((thisSigBytes + i) % 4) * 8);\n                    }\n                } else {\n                    \/\/ Copy one word at a time\n                    for (var i = 0; i \u003c thatSigBytes; i += 4) {\n                        thisWords[(thisSigBytes + i) \u003e\u003e\u003e 2] = thatWords[i \u003e\u003e\u003e 2];\n                    }\n                }\n                this.sigBytes += thatSigBytes;\n\n                \/\/ Chainable\n                return this;\n            },\n\n            \/**\n             * Removes insignificant bits.\n             *\n             * @example\n             *\n             *     wordArray.clamp();\n             *\/\n            clamp: function () {\n                \/\/ Shortcuts\n                var words = this.words;\n                var sigBytes = this.sigBytes;\n\n                \/\/ Clamp\n                words[sigBytes \u003e\u003e\u003e 2] \u0026= 0xffffffff \u003c\u003c (32 - (sigBytes % 4) * 8);\n                words.length = Math.ceil(sigBytes \/ 4);\n            },\n\n            \/**\n             * Creates a copy of this word array.\n             *\n             * @return {WordArray} The clone.\n             *\n             * @example\n             *\n             *     var clone = wordArray.clone();\n             *\/\n            clone: function () {\n                var clone = Base.clone.call(this);\n                clone.words = this.words.slice(0);\n\n                return clone;\n            },\n\n            \/**\n             * Creates a word array filled with random bytes.\n             *\n             * @param {number} nBytes The number of random bytes to generate.\n             *\n             * @return {WordArray} The random word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.lib.WordArray.random(16);\n             *\/\n            random: function (nBytes) {\n                var words = [];\n\n                for (var i = 0; i \u003c nBytes; i += 4) {\n                    words.push(cryptoSecureRandomInt());\n                }\n\n                return new WordArray.init(words, nBytes);\n            }\n        });\n\n        \/**\n         * Encoder namespace.\n         *\/\n        var C_enc = C.enc = {};\n\n        \/**\n         * Hex encoding strategy.\n         *\/\n        var Hex = C_enc.Hex = {\n            \/**\n             * Converts a word array to a hex string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The hex string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n\n                \/\/ Convert\n                var hexChars = [];\n                for (var i = 0; i \u003c sigBytes; i++) {\n                    var bite = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    hexChars.push((bite \u003e\u003e\u003e 4).toString(16));\n                    hexChars.push((bite \u0026 0x0f).toString(16));\n                }\n\n                return hexChars.join('');\n            },\n\n            \/**\n             * Converts a hex string to a word array.\n             *\n             * @param {string} hexStr The hex string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Hex.parse(hexString);\n             *\/\n            parse: function (hexStr) {\n                \/\/ Shortcut\n                var hexStrLength = hexStr.length;\n\n                \/\/ Convert\n                var words = [];\n                for (var i = 0; i \u003c hexStrLength; i += 2) {\n                    words[i \u003e\u003e\u003e 3] |= parseInt(hexStr.substr(i, 2), 16) \u003c\u003c (24 - (i % 8) * 4);\n                }\n\n                return new WordArray.init(words, hexStrLength \/ 2);\n            }\n        };\n\n        \/**\n         * Latin1 encoding strategy.\n         *\/\n        var Latin1 = C_enc.Latin1 = {\n            \/**\n             * Converts a word array to a Latin1 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The Latin1 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n\n                \/\/ Convert\n                var latin1Chars = [];\n                for (var i = 0; i \u003c sigBytes; i++) {\n                    var bite = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    latin1Chars.push(String.fromCharCode(bite));\n                }\n\n                return latin1Chars.join('');\n            },\n\n            \/**\n             * Converts a Latin1 string to a word array.\n             *\n             * @param {string} latin1Str The Latin1 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);\n             *\/\n            parse: function (latin1Str) {\n                \/\/ Shortcut\n                var latin1StrLength = latin1Str.length;\n\n                \/\/ Convert\n                var words = [];\n                for (var i = 0; i \u003c latin1StrLength; i++) {\n                    words[i \u003e\u003e\u003e 2] |= (latin1Str.charCodeAt(i) \u0026 0xff) \u003c\u003c (24 - (i % 4) * 8);\n                }\n\n                return new WordArray.init(words, latin1StrLength);\n            }\n        };\n\n        \/**\n         * UTF-8 encoding strategy.\n         *\/\n        var Utf8 = C_enc.Utf8 = {\n            \/**\n             * Converts a word array to a UTF-8 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The UTF-8 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                try {\n                    return decodeURIComponent(escape(Latin1.stringify(wordArray)));\n                } catch (e) {\n                    throw new Error('Malformed UTF-8 data');\n                }\n            },\n\n            \/**\n             * Converts a UTF-8 string to a word array.\n             *\n             * @param {string} utf8Str The UTF-8 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\n             *\/\n            parse: function (utf8Str) {\n                return Latin1.parse(unescape(encodeURIComponent(utf8Str)));\n            }\n        };\n\n        \/**\n         * Abstract buffered block algorithm template.\n         *\n         * The property blockSize must be implemented in a concrete subtype.\n         *\n         * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0\n         *\/\n        var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({\n            \/**\n             * Resets this block algorithm's data buffer to its initial state.\n             *\n             * @example\n             *\n             *     bufferedBlockAlgorithm.reset();\n             *\/\n            reset: function () {\n                \/\/ Initial values\n                this._data = new WordArray.init();\n                this._nDataBytes = 0;\n            },\n\n            \/**\n             * Adds new data to this block algorithm's buffer.\n             *\n             * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.\n             *\n             * @example\n             *\n             *     bufferedBlockAlgorithm._append('data');\n             *     bufferedBlockAlgorithm._append(wordArray);\n             *\/\n            _append: function (data) {\n                \/\/ Convert string to WordArray, else assume WordArray already\n                if (typeof data == 'string') {\n                    data = Utf8.parse(data);\n                }\n\n                \/\/ Append\n                this._data.concat(data);\n                this._nDataBytes += data.sigBytes;\n            },\n\n            \/**\n             * Processes available data blocks.\n             *\n             * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.\n             *\n             * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.\n             *\n             * @return {WordArray} The processed data.\n             *\n             * @example\n             *\n             *     var processedData = bufferedBlockAlgorithm._process();\n             *     var processedData = bufferedBlockAlgorithm._process(!!'flush');\n             *\/\n            _process: function (doFlush) {\n                var processedWords;\n\n                \/\/ Shortcuts\n                var data = this._data;\n                var dataWords = data.words;\n                var dataSigBytes = data.sigBytes;\n                var blockSize = this.blockSize;\n                var blockSizeBytes = blockSize * 4;\n\n                \/\/ Count blocks ready\n                var nBlocksReady = dataSigBytes \/ blockSizeBytes;\n                if (doFlush) {\n                    \/\/ Round up to include partial blocks\n                    nBlocksReady = Math.ceil(nBlocksReady);\n                } else {\n                    \/\/ Round down to include only full blocks,\n                    \/\/ less the number of blocks that must remain in the buffer\n                    nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);\n                }\n\n                \/\/ Count words ready\n                var nWordsReady = nBlocksReady * blockSize;\n\n                \/\/ Count bytes ready\n                var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);\n\n                \/\/ Process blocks\n                if (nWordsReady) {\n                    for (var offset = 0; offset \u003c nWordsReady; offset += blockSize) {\n                        \/\/ Perform concrete-algorithm logic\n                        this._doProcessBlock(dataWords, offset);\n                    }\n\n                    \/\/ Remove processed words\n                    processedWords = dataWords.splice(0, nWordsReady);\n                    data.sigBytes -= nBytesReady;\n                }\n\n                \/\/ Return processed words\n                return new WordArray.init(processedWords, nBytesReady);\n            },\n\n            \/**\n             * Creates a copy of this object.\n             *\n             * @return {Object} The clone.\n             *\n             * @example\n             *\n             *     var clone = bufferedBlockAlgorithm.clone();\n             *\/\n            clone: function () {\n                var clone = Base.clone.call(this);\n                clone._data = this._data.clone();\n\n                return clone;\n            },\n\n            _minBufferSize: 0\n        });\n\n        \/**\n         * Abstract hasher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)\n         *\/\n        var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({\n            \/**\n             * Configuration options.\n             *\/\n            cfg: Base.extend(),\n\n            \/**\n             * Initializes a newly created hasher.\n             *\n             * @param {Object} cfg (Optional) The configuration options to use for this hash computation.\n             *\n             * @example\n             *\n             *     var hasher = CryptoJS.algo.SHA256.create();\n             *\/\n            init: function (cfg) {\n                \/\/ Apply config defaults\n                this.cfg = this.cfg.extend(cfg);\n\n                \/\/ Set initial values\n                this.reset();\n            },\n\n            \/**\n             * Resets this hasher to its initial state.\n             *\n             * @example\n             *\n             *     hasher.reset();\n             *\/\n            reset: function () {\n                \/\/ Reset data buffer\n                BufferedBlockAlgorithm.reset.call(this);\n\n                \/\/ Perform concrete-hasher logic\n                this._doReset();\n            },\n\n            \/**\n             * Updates this hasher with a message.\n             *\n             * @param {WordArray|string} messageUpdate The message to append.\n             *\n             * @return {Hasher} This hasher.\n             *\n             * @example\n             *\n             *     hasher.update('message');\n             *     hasher.update(wordArray);\n             *\/\n            update: function (messageUpdate) {\n                \/\/ Append\n                this._append(messageUpdate);\n\n                \/\/ Update the hash\n                this._process();\n\n                \/\/ Chainable\n                return this;\n            },\n\n            \/**\n             * Finalizes the hash computation.\n             * Note that the finalize operation is effectively a destructive, read-once operation.\n             *\n             * @param {WordArray|string} messageUpdate (Optional) A final message update.\n             *\n             * @return {WordArray} The hash.\n             *\n             * @example\n             *\n             *     var hash = hasher.finalize();\n             *     var hash = hasher.finalize('message');\n             *     var hash = hasher.finalize(wordArray);\n             *\/\n            finalize: function (messageUpdate) {\n                \/\/ Final message update\n                if (messageUpdate) {\n                    this._append(messageUpdate);\n                }\n\n                \/\/ Perform concrete-hasher logic\n                var hash = this._doFinalize();\n\n                return hash;\n            },\n\n            blockSize: 512 \/ 32,\n\n            \/**\n             * Creates a shortcut function to a hasher's object interface.\n             *\n             * @param {Hasher} hasher The hasher to create a helper for.\n             *\n             * @return {Function} The shortcut function.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);\n             *\/\n            _createHelper: function (hasher) {\n                return function (message, cfg) {\n                    return new hasher.init(cfg).finalize(message);\n                };\n            },\n\n            \/**\n             * Creates a shortcut function to the HMAC's object interface.\n             *\n             * @param {Hasher} hasher The hasher to use in this HMAC helper.\n             *\n             * @return {Function} The shortcut function.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);\n             *\/\n            _createHmacHelper: function (hasher) {\n                return function (message, key) {\n                    return new C_algo.HMAC.init(hasher, key).finalize(message);\n                };\n            }\n        });\n\n        \/**\n         * Algorithm namespace.\n         *\/\n        var C_algo = C.algo = {};\n\n        return C;\n    }(Math));\n    (function () {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var WordArray = C_lib.WordArray;\n        var C_enc = C.enc;\n\n        \/**\n         * Base64 encoding strategy.\n         *\/\n        var Base64 = C_enc.Base64 = {\n            \/**\n             * Converts a word array to a Base64 string.\n             *\n             * @param {WordArray} wordArray The word array.\n             *\n             * @return {string} The Base64 string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);\n             *\/\n            stringify: function (wordArray) {\n                \/\/ Shortcuts\n                var words = wordArray.words;\n                var sigBytes = wordArray.sigBytes;\n                var map = this._map;\n\n                \/\/ Clamp excess bits\n                wordArray.clamp();\n\n                \/\/ Convert\n                var base64Chars = [];\n                for (var i = 0; i \u003c sigBytes; i += 3) {\n                    var byte1 = (words[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff;\n                    var byte2 = (words[(i + 1) \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - ((i + 1) % 4) * 8)) \u0026 0xff;\n                    var byte3 = (words[(i + 2) \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - ((i + 2) % 4) * 8)) \u0026 0xff;\n\n                    var triplet = (byte1 \u003c\u003c 16) | (byte2 \u003c\u003c 8) | byte3;\n\n                    for (var j = 0; (j \u003c 4) \u0026\u0026 (i + j * 0.75 \u003c sigBytes); j++) {\n                        base64Chars.push(map.charAt((triplet \u003e\u003e\u003e (6 * (3 - j))) \u0026 0x3f));\n                    }\n                }\n\n                \/\/ Add padding\n                var paddingChar = map.charAt(64);\n                if (paddingChar) {\n                    while (base64Chars.length % 4) {\n                        base64Chars.push(paddingChar);\n                    }\n                }\n\n                return base64Chars.join('');\n            },\n\n            \/**\n             * Converts a Base64 string to a word array.\n             *\n             * @param {string} base64Str The Base64 string.\n             *\n             * @return {WordArray} The word array.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var wordArray = CryptoJS.enc.Base64.parse(base64String);\n             *\/\n            parse: function (base64Str) {\n                \/\/ Shortcuts\n                var base64StrLength = base64Str.length;\n                var map = this._map;\n                var reverseMap = this._reverseMap;\n\n                if (!reverseMap) {\n                    reverseMap = this._reverseMap = [];\n                    for (var j = 0; j \u003c map.length; j++) {\n                        reverseMap[map.charCodeAt(j)] = j;\n                    }\n                }\n\n                \/\/ Ignore padding\n                var paddingChar = map.charAt(64);\n                if (paddingChar) {\n                    var paddingIndex = base64Str.indexOf(paddingChar);\n                    if (paddingIndex !== -1) {\n                        base64StrLength = paddingIndex;\n                    }\n                }\n\n                \/\/ Convert\n                return parseLoop(base64Str, base64StrLength, reverseMap);\n\n            },\n\n            _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/='\n        };\n\n        function parseLoop(base64Str, base64StrLength, reverseMap) {\n            var words = [];\n            var nBytes = 0;\n            for (var i = 0; i \u003c base64StrLength; i++) {\n                if (i % 4) {\n                    var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] \u003c\u003c ((i % 4) * 2);\n                    var bits2 = reverseMap[base64Str.charCodeAt(i)] \u003e\u003e\u003e (6 - (i % 4) * 2);\n                    var bitsCombined = bits1 | bits2;\n                    words[nBytes \u003e\u003e\u003e 2] |= bitsCombined \u003c\u003c (24 - (nBytes % 4) * 8);\n                    nBytes++;\n                }\n            }\n            return WordArray.create(words, nBytes);\n        }\n    }());\n\n    \/**\n * Cipher core components.\n *\/\n    CryptoJS.lib.Cipher || (function (undefined) {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var Base = C_lib.Base;\n        var WordArray = C_lib.WordArray;\n        var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;\n        var C_enc = C.enc;\n        var Utf8 = C_enc.Utf8;\n        var Base64 = C_enc.Base64;\n        var C_algo = C.algo;\n        var EvpKDF = C_algo.EvpKDF;\n\n        \/**\n         * Abstract base cipher template.\n         *\n         * @property {number} keySize This cipher's key size. Default: 4 (128 bits)\n         * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)\n         * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.\n         * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.\n         *\/\n        var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {WordArray} iv The IV to use for this operation.\n             *\/\n            cfg: Base.extend(),\n\n            \/**\n             * Creates this cipher in encryption mode.\n             *\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {Cipher} A cipher instance.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });\n             *\/\n            createEncryptor: function (key, cfg) {\n                return this.create(this._ENC_XFORM_MODE, key, cfg);\n            },\n\n            \/**\n             * Creates this cipher in decryption mode.\n             *\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {Cipher} A cipher instance.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });\n             *\/\n            createDecryptor: function (key, cfg) {\n                return this.create(this._DEC_XFORM_MODE, key, cfg);\n            },\n\n            \/**\n             * Initializes a newly created cipher.\n             *\n             * @param {number} xformMode Either the encryption or decryption transormation mode constant.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @example\n             *\n             *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });\n             *\/\n            init: function (xformMode, key, cfg) {\n                \/\/ Apply config defaults\n                this.cfg = this.cfg.extend(cfg);\n\n                \/\/ Store transform mode and key\n                this._xformMode = xformMode;\n                this._key = key;\n\n                \/\/ Set initial values\n                this.reset();\n            },\n\n            \/**\n             * Resets this cipher to its initial state.\n             *\n             * @example\n             *\n             *     cipher.reset();\n             *\/\n            reset: function () {\n                \/\/ Reset data buffer\n                BufferedBlockAlgorithm.reset.call(this);\n\n                \/\/ Perform concrete-cipher logic\n                this._doReset();\n            },\n\n            \/**\n             * Adds data to be encrypted or decrypted.\n             *\n             * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.\n             *\n             * @return {WordArray} The data after processing.\n             *\n             * @example\n             *\n             *     var encrypted = cipher.process('data');\n             *     var encrypted = cipher.process(wordArray);\n             *\/\n            process: function (dataUpdate) {\n                \/\/ Append\n                this._append(dataUpdate);\n\n                \/\/ Process available blocks\n                return this._process();\n            },\n\n            \/**\n             * Finalizes the encryption or decryption process.\n             * Note that the finalize operation is effectively a destructive, read-once operation.\n             *\n             * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.\n             *\n             * @return {WordArray} The data after final processing.\n             *\n             * @example\n             *\n             *     var encrypted = cipher.finalize();\n             *     var encrypted = cipher.finalize('data');\n             *     var encrypted = cipher.finalize(wordArray);\n             *\/\n            finalize: function (dataUpdate) {\n                \/\/ Final data update\n                if (dataUpdate) {\n                    this._append(dataUpdate);\n                }\n\n                \/\/ Perform concrete-cipher logic\n                var finalProcessedData = this._doFinalize();\n\n                return finalProcessedData;\n            },\n\n            keySize: 128 \/ 32,\n\n            ivSize: 128 \/ 32,\n\n            _ENC_XFORM_MODE: 1,\n\n            _DEC_XFORM_MODE: 2,\n\n            \/**\n             * Creates shortcut functions to a cipher's object interface.\n             *\n             * @param {Cipher} cipher The cipher to create a helper for.\n             *\n             * @return {Object} An object with encrypt and decrypt shortcut functions.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);\n             *\/\n            _createHelper: (function () {\n                function selectCipherStrategy(key) {\n                    if (typeof key == 'string') {\n                        return PasswordBasedCipher;\n                    } else {\n                        return SerializableCipher;\n                    }\n                }\n\n                return function (cipher) {\n                    return {\n                        encrypt: function (message, key, cfg) {\n                            return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);\n                        },\n\n                        decrypt: function (ciphertext, key, cfg) {\n                            return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);\n                        }\n                    };\n                };\n            }())\n        });\n\n        \/**\n         * Abstract base stream cipher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)\n         *\/\n        var StreamCipher = C_lib.StreamCipher = Cipher.extend({\n            _doFinalize: function () {\n                \/\/ Process partial blocks\n                var finalProcessedBlocks = this._process(!!'flush');\n\n                return finalProcessedBlocks;\n            },\n\n            blockSize: 1\n        });\n\n        \/**\n         * Mode namespace.\n         *\/\n        var C_mode = C.mode = {};\n\n        \/**\n         * Abstract base block cipher mode template.\n         *\/\n        var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({\n            \/**\n             * Creates this mode for encryption.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);\n             *\/\n            createEncryptor: function (cipher, iv) {\n                return this.Encryptor.create(cipher, iv);\n            },\n\n            \/**\n             * Creates this mode for decryption.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);\n             *\/\n            createDecryptor: function (cipher, iv) {\n                return this.Decryptor.create(cipher, iv);\n            },\n\n            \/**\n             * Initializes a newly created mode.\n             *\n             * @param {Cipher} cipher A block cipher instance.\n             * @param {Array} iv The IV words.\n             *\n             * @example\n             *\n             *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);\n             *\/\n            init: function (cipher, iv) {\n                this._cipher = cipher;\n                this._iv = iv;\n            }\n        });\n\n        \/**\n         * Cipher Block Chaining mode.\n         *\/\n        var CBC = C_mode.CBC = (function () {\n            \/**\n             * Abstract base CBC mode.\n             *\/\n            var CBC = BlockCipherMode.extend();\n\n            \/**\n             * CBC encryptor.\n             *\/\n            CBC.Encryptor = CBC.extend({\n                \/**\n                 * Processes the data block at offset.\n                 *\n                 * @param {Array} words The data words to operate on.\n                 * @param {number} offset The offset where the block starts.\n                 *\n                 * @example\n                 *\n                 *     mode.processBlock(data.words, offset);\n                 *\/\n                processBlock: function (words, offset) {\n                    \/\/ Shortcuts\n                    var cipher = this._cipher;\n                    var blockSize = cipher.blockSize;\n\n                    \/\/ XOR and encrypt\n                    xorBlock.call(this, words, offset, blockSize);\n                    cipher.encryptBlock(words, offset);\n\n                    \/\/ Remember this block to use with next block\n                    this._prevBlock = words.slice(offset, offset + blockSize);\n                }\n            });\n\n            \/**\n             * CBC decryptor.\n             *\/\n            CBC.Decryptor = CBC.extend({\n                \/**\n                 * Processes the data block at offset.\n                 *\n                 * @param {Array} words The data words to operate on.\n                 * @param {number} offset The offset where the block starts.\n                 *\n                 * @example\n                 *\n                 *     mode.processBlock(data.words, offset);\n                 *\/\n                processBlock: function (words, offset) {\n                    \/\/ Shortcuts\n                    var cipher = this._cipher;\n                    var blockSize = cipher.blockSize;\n\n                    \/\/ Remember this block to use with next block\n                    var thisBlock = words.slice(offset, offset + blockSize);\n\n                    \/\/ Decrypt and XOR\n                    cipher.decryptBlock(words, offset);\n                    xorBlock.call(this, words, offset, blockSize);\n\n                    \/\/ This block becomes the previous block\n                    this._prevBlock = thisBlock;\n                }\n            });\n\n            function xorBlock(words, offset, blockSize) {\n                var block;\n\n                \/\/ Shortcut\n                var iv = this._iv;\n\n                \/\/ Choose mixing block\n                if (iv) {\n                    block = iv;\n\n                    \/\/ Remove IV for subsequent blocks\n                    this._iv = undefined;\n                } else {\n                    block = this._prevBlock;\n                }\n\n                \/\/ XOR blocks\n                for (var i = 0; i \u003c blockSize; i++) {\n                    words[offset + i] ^= block[i];\n                }\n            }\n\n            return CBC;\n        }());\n\n        \/**\n         * Padding namespace.\n         *\/\n        var C_pad = C.pad = {};\n\n        \/**\n         * PKCS #5\/7 padding strategy.\n         *\/\n        var Pkcs7 = C_pad.Pkcs7 = {\n            \/**\n             * Pads data using the algorithm defined in PKCS #5\/7.\n             *\n             * @param {WordArray} data The data to pad.\n             * @param {number} blockSize The multiple that the data should be padded to.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);\n             *\/\n            pad: function (data, blockSize) {\n                \/\/ Shortcut\n                var blockSizeBytes = blockSize * 4;\n\n                \/\/ Count padding bytes\n                var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;\n\n                \/\/ Create padding word\n                var paddingWord = (nPaddingBytes \u003c\u003c 24) | (nPaddingBytes \u003c\u003c 16) | (nPaddingBytes \u003c\u003c 8) | nPaddingBytes;\n\n                \/\/ Create padding\n                var paddingWords = [];\n                for (var i = 0; i \u003c nPaddingBytes; i += 4) {\n                    paddingWords.push(paddingWord);\n                }\n                var padding = WordArray.create(paddingWords, nPaddingBytes);\n\n                \/\/ Add padding\n                data.concat(padding);\n            },\n\n            \/**\n             * Unpads data that had been padded using the algorithm defined in PKCS #5\/7.\n             *\n             * @param {WordArray} data The data to unpad.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     CryptoJS.pad.Pkcs7.unpad(wordArray);\n             *\/\n            unpad: function (data) {\n                \/\/ Get number of padding bytes from last byte\n                var nPaddingBytes = data.words[(data.sigBytes - 1) \u003e\u003e\u003e 2] \u0026 0xff;\n\n                \/\/ Remove padding\n                data.sigBytes -= nPaddingBytes;\n            }\n        };\n\n        \/**\n         * Abstract base block cipher template.\n         *\n         * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)\n         *\/\n        var BlockCipher = C_lib.BlockCipher = Cipher.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {Mode} mode The block mode to use. Default: CBC\n             * @property {Padding} padding The padding strategy to use. Default: Pkcs7\n             *\/\n            cfg: Cipher.cfg.extend({\n                mode: CBC,\n                padding: Pkcs7\n            }),\n\n            reset: function () {\n                var modeCreator;\n\n                \/\/ Reset cipher\n                Cipher.reset.call(this);\n\n                \/\/ Shortcuts\n                var cfg = this.cfg;\n                var iv = cfg.iv;\n                var mode = cfg.mode;\n\n                \/\/ Reset block mode\n                if (this._xformMode == this._ENC_XFORM_MODE) {\n                    modeCreator = mode.createEncryptor;\n                } else \/* if (this._xformMode == this._DEC_XFORM_MODE) *\/ {\n                    modeCreator = mode.createDecryptor;\n                    \/\/ Keep at least one block in the buffer for unpadding\n                    this._minBufferSize = 1;\n                }\n\n                if (this._mode \u0026\u0026 this._mode.__creator == modeCreator) {\n                    this._mode.init(this, iv \u0026\u0026 iv.words);\n                } else {\n                    this._mode = modeCreator.call(mode, this, iv \u0026\u0026 iv.words);\n                    this._mode.__creator = modeCreator;\n                }\n            },\n\n            _doProcessBlock: function (words, offset) {\n                this._mode.processBlock(words, offset);\n            },\n\n            _doFinalize: function () {\n                var finalProcessedBlocks;\n\n                \/\/ Shortcut\n                var padding = this.cfg.padding;\n\n                \/\/ Finalize\n                if (this._xformMode == this._ENC_XFORM_MODE) {\n                    \/\/ Pad data\n                    padding.pad(this._data, this.blockSize);\n\n                    \/\/ Process final blocks\n                    finalProcessedBlocks = this._process(!!'flush');\n                } else \/* if (this._xformMode == this._DEC_XFORM_MODE) *\/ {\n                    \/\/ Process final blocks\n                    finalProcessedBlocks = this._process(!!'flush');\n\n                    \/\/ Unpad data\n                    padding.unpad(finalProcessedBlocks);\n                }\n\n                return finalProcessedBlocks;\n            },\n\n            blockSize: 128 \/ 32\n        });\n\n        \/**\n         * A collection of cipher parameters.\n         *\n         * @property {WordArray} ciphertext The raw ciphertext.\n         * @property {WordArray} key The key to this ciphertext.\n         * @property {WordArray} iv The IV used in the ciphering operation.\n         * @property {WordArray} salt The salt used with a key derivation function.\n         * @property {Cipher} algorithm The cipher algorithm.\n         * @property {Mode} mode The block mode used in the ciphering operation.\n         * @property {Padding} padding The padding scheme used in the ciphering operation.\n         * @property {number} blockSize The block size of the cipher.\n         * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.\n         *\/\n        var CipherParams = C_lib.CipherParams = Base.extend({\n            \/**\n             * Initializes a newly created cipher params object.\n             *\n             * @param {Object} cipherParams An object with any of the possible cipher parameters.\n             *\n             * @example\n             *\n             *     var cipherParams = CryptoJS.lib.CipherParams.create({\n             *         ciphertext: ciphertextWordArray,\n             *         key: keyWordArray,\n             *         iv: ivWordArray,\n             *         salt: saltWordArray,\n             *         algorithm: CryptoJS.algo.AES,\n             *         mode: CryptoJS.mode.CBC,\n             *         padding: CryptoJS.pad.PKCS7,\n             *         blockSize: 4,\n             *         formatter: CryptoJS.format.OpenSSL\n             *     });\n             *\/\n            init: function (cipherParams) {\n                this.mixIn(cipherParams);\n            },\n\n            \/**\n             * Converts this cipher params object to a string.\n             *\n             * @param {Format} formatter (Optional) The formatting strategy to use.\n             *\n             * @return {string} The stringified cipher params.\n             *\n             * @throws Error If neither the formatter nor the default formatter is set.\n             *\n             * @example\n             *\n             *     var string = cipherParams + '';\n             *     var string = cipherParams.toString();\n             *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);\n             *\/\n            toString: function (formatter) {\n                return (formatter || this.formatter).stringify(this);\n            }\n        });\n\n        \/**\n         * Format namespace.\n         *\/\n        var C_format = C.format = {};\n\n        \/**\n         * OpenSSL formatting strategy.\n         *\/\n        var OpenSSLFormatter = C_format.OpenSSL = {\n            \/**\n             * Converts a cipher params object to an OpenSSL-compatible string.\n             *\n             * @param {CipherParams} cipherParams The cipher params object.\n             *\n             * @return {string} The OpenSSL-compatible string.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);\n             *\/\n            stringify: function (cipherParams) {\n                var wordArray;\n\n                \/\/ Shortcuts\n                var ciphertext = cipherParams.ciphertext;\n                var salt = cipherParams.salt;\n\n                \/\/ Format\n                if (salt) {\n                    wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);\n                } else {\n                    wordArray = ciphertext;\n                }\n\n                return wordArray.toString(Base64);\n            },\n\n            \/**\n             * Converts an OpenSSL-compatible string to a cipher params object.\n             *\n             * @param {string} openSSLStr The OpenSSL-compatible string.\n             *\n             * @return {CipherParams} The cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);\n             *\/\n            parse: function (openSSLStr) {\n                var salt;\n\n                \/\/ Parse base64\n                var ciphertext = Base64.parse(openSSLStr);\n\n                \/\/ Shortcut\n                var ciphertextWords = ciphertext.words;\n\n                \/\/ Test for salt\n                if (ciphertextWords[0] == 0x53616c74 \u0026\u0026 ciphertextWords[1] == 0x65645f5f) {\n                    \/\/ Extract salt\n                    salt = WordArray.create(ciphertextWords.slice(2, 4));\n\n                    \/\/ Remove salt from ciphertext\n                    ciphertextWords.splice(0, 4);\n                    ciphertext.sigBytes -= 16;\n                }\n\n                return CipherParams.create({ ciphertext: ciphertext, salt: salt });\n            }\n        };\n\n        \/**\n         * A cipher wrapper that returns ciphertext as a serializable cipher params object.\n         *\/\n        var SerializableCipher = C_lib.SerializableCipher = Base.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL\n             *\/\n            cfg: Base.extend({\n                format: OpenSSLFormatter\n            }),\n\n            \/**\n             * Encrypts a message.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {WordArray|string} message The message to encrypt.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {CipherParams} A cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *\/\n            encrypt: function (cipher, message, key, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Encrypt\n                var encryptor = cipher.createEncryptor(key, cfg);\n                var ciphertext = encryptor.finalize(message);\n\n                \/\/ Shortcut\n                var cipherCfg = encryptor.cfg;\n\n                \/\/ Create and return serializable cipher params\n                return CipherParams.create({\n                    ciphertext: ciphertext,\n                    key: key,\n                    iv: cipherCfg.iv,\n                    algorithm: cipher,\n                    mode: cipherCfg.mode,\n                    padding: cipherCfg.padding,\n                    blockSize: cipher.blockSize,\n                    formatter: cfg.format\n                });\n            },\n\n            \/**\n             * Decrypts serialized ciphertext.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n             * @param {WordArray} key The key.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {WordArray} The plaintext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n             *\/\n            decrypt: function (cipher, ciphertext, key, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Convert string to CipherParams\n                ciphertext = this._parse(ciphertext, cfg.format);\n\n                \/\/ Decrypt\n                var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);\n\n                return plaintext;\n            },\n\n            \/**\n             * Converts serialized ciphertext to CipherParams,\n             * else assumed CipherParams already and returns ciphertext unchanged.\n             *\n             * @param {CipherParams|string} ciphertext The ciphertext.\n             * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.\n             *\n             * @return {CipherParams} The unserialized ciphertext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);\n             *\/\n            _parse: function (ciphertext, format) {\n                if (typeof ciphertext == 'string') {\n                    return format.parse(ciphertext, this);\n                } else {\n                    return ciphertext;\n                }\n            }\n        });\n\n        \/**\n         * Key derivation function namespace.\n         *\/\n        var C_kdf = C.kdf = {};\n\n        \/**\n         * OpenSSL key derivation function.\n         *\/\n        var OpenSSLKdf = C_kdf.OpenSSL = {\n            \/**\n             * Derives a key and IV from a password.\n             *\n             * @param {string} password The password to derive from.\n             * @param {number} keySize The size in words of the key to generate.\n             * @param {number} ivSize The size in words of the IV to generate.\n             * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.\n             *\n             * @return {CipherParams} A cipher params object with the key, IV, and salt.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256\/32, 128\/32);\n             *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256\/32, 128\/32, 'saltsalt');\n             *\/\n            execute: function (password, keySize, ivSize, salt, hasher) {\n                \/\/ Generate random salt\n                if (!salt) {\n                    salt = WordArray.random(64 \/ 8);\n                }\n\n                \/\/ Derive key and IV\n                if (!hasher) {\n                    var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);\n                } else {\n                    var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: hasher }).compute(password, salt);\n                }\n\n\n                \/\/ Separate key and IV\n                var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);\n                key.sigBytes = keySize * 4;\n\n                \/\/ Return params\n                return CipherParams.create({ key: key, iv: iv, salt: salt });\n            }\n        };\n\n        \/**\n         * A serializable cipher wrapper that derives the key from a password,\n         * and returns ciphertext as a serializable cipher params object.\n         *\/\n        var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({\n            \/**\n             * Configuration options.\n             *\n             * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL\n             *\/\n            cfg: SerializableCipher.cfg.extend({\n                kdf: OpenSSLKdf\n            }),\n\n            \/**\n             * Encrypts a message using a password.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {WordArray|string} message The message to encrypt.\n             * @param {string} password The password.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {CipherParams} A cipher params object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');\n             *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });\n             *\/\n            encrypt: function (cipher, message, password, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Derive key and other params\n                var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, cfg.salt, cfg.hasher);\n\n                \/\/ Add IV to config\n                cfg.iv = derivedParams.iv;\n\n                \/\/ Encrypt\n                var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);\n\n                \/\/ Mix in derived params\n                ciphertext.mixIn(derivedParams);\n\n                return ciphertext;\n            },\n\n            \/**\n             * Decrypts serialized ciphertext using a password.\n             *\n             * @param {Cipher} cipher The cipher algorithm to use.\n             * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n             * @param {string} password The password.\n             * @param {Object} cfg (Optional) The configuration options to use for this operation.\n             *\n             * @return {WordArray} The plaintext.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });\n             *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });\n             *\/\n            decrypt: function (cipher, ciphertext, password, cfg) {\n                \/\/ Apply config defaults\n                cfg = this.cfg.extend(cfg);\n\n                \/\/ Convert string to CipherParams\n                ciphertext = this._parse(ciphertext, cfg.format);\n\n                \/\/ Derive key and other params\n                var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt, cfg.hasher);\n\n                \/\/ Add IV to config\n                cfg.iv = derivedParams.iv;\n\n                \/\/ Decrypt\n                var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);\n\n                return plaintext;\n            }\n        });\n    }());\n\n\n\n    (function () {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var BlockCipher = C_lib.BlockCipher;\n        var C_algo = C.algo;\n\n        \/\/ Lookup tables\n        var SBOX = [];\n        var INV_SBOX = [];\n        var SUB_MIX_0 = [];\n        var SUB_MIX_1 = [];\n        var SUB_MIX_2 = [];\n        var SUB_MIX_3 = [];\n        var INV_SUB_MIX_0 = [];\n        var INV_SUB_MIX_1 = [];\n        var INV_SUB_MIX_2 = [];\n        var INV_SUB_MIX_3 = [];\n\n        \/\/ Compute lookup tables\n        (function () {\n            \/\/ Compute double table\n            var d = [];\n            for (var i = 0; i \u003c 256; i++) {\n                if (i \u003c 128) {\n                    d[i] = i \u003c\u003c 1;\n                } else {\n                    d[i] = (i \u003c\u003c 1) ^ 0x11b;\n                }\n            }\n\n            \/\/ Walk GF(2^8)\n            var x = 0;\n            var xi = 0;\n            for (var i = 0; i \u003c 256; i++) {\n                \/\/ Compute sbox\n                var sx = xi ^ (xi \u003c\u003c 1) ^ (xi \u003c\u003c 2) ^ (xi \u003c\u003c 3) ^ (xi \u003c\u003c 4);\n                sx = (sx \u003e\u003e\u003e 8) ^ (sx \u0026 0xff) ^ 0x63;\n                SBOX[x] = sx;\n                INV_SBOX[sx] = x;\n\n                \/\/ Compute multiplication\n                var x2 = d[x];\n                var x4 = d[x2];\n                var x8 = d[x4];\n\n                \/\/ Compute sub bytes, mix columns tables\n                var t = (d[sx] * 0x101) ^ (sx * 0x1010100);\n                SUB_MIX_0[x] = (t \u003c\u003c 24) | (t \u003e\u003e\u003e 8);\n                SUB_MIX_1[x] = (t \u003c\u003c 16) | (t \u003e\u003e\u003e 16);\n                SUB_MIX_2[x] = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n                SUB_MIX_3[x] = t;\n\n                \/\/ Compute inv sub bytes, inv mix columns tables\n                var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);\n                INV_SUB_MIX_0[sx] = (t \u003c\u003c 24) | (t \u003e\u003e\u003e 8);\n                INV_SUB_MIX_1[sx] = (t \u003c\u003c 16) | (t \u003e\u003e\u003e 16);\n                INV_SUB_MIX_2[sx] = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n                INV_SUB_MIX_3[sx] = t;\n\n                \/\/ Compute next counter\n                if (!x) {\n                    x = xi = 1;\n                } else {\n                    x = x2 ^ d[d[d[x8 ^ x2]]];\n                    xi ^= d[d[xi]];\n                }\n            }\n        }());\n\n        \/\/ Precomputed Rcon lookup\n        var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];\n\n        \/**\n         * AES block cipher algorithm.\n         *\/\n        var AES = C_algo.AES = BlockCipher.extend({\n            _doReset: function () {\n                var t;\n\n                \/\/ Skip reset of nRounds has been set before and key did not change\n                if (this._nRounds \u0026\u0026 this._keyPriorReset === this._key) {\n                    return;\n                }\n\n                \/\/ Shortcuts\n                var key = this._keyPriorReset = this._key;\n                var keyWords = key.words;\n                var keySize = key.sigBytes \/ 4;\n\n                \/\/ Compute number of rounds\n                var nRounds = this._nRounds = keySize + 6;\n\n                \/\/ Compute number of key schedule rows\n                var ksRows = (nRounds + 1) * 4;\n\n                \/\/ Compute key schedule\n                var keySchedule = this._keySchedule = [];\n                for (var ksRow = 0; ksRow \u003c ksRows; ksRow++) {\n                    if (ksRow \u003c keySize) {\n                        keySchedule[ksRow] = keyWords[ksRow];\n                    } else {\n                        t = keySchedule[ksRow - 1];\n\n                        if (!(ksRow % keySize)) {\n                            \/\/ Rot word\n                            t = (t \u003c\u003c 8) | (t \u003e\u003e\u003e 24);\n\n                            \/\/ Sub word\n                            t = (SBOX[t \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[t \u0026 0xff];\n\n                            \/\/ Mix Rcon\n                            t ^= RCON[(ksRow \/ keySize) | 0] \u003c\u003c 24;\n                        } else if (keySize \u003e 6 \u0026\u0026 ksRow % keySize == 4) {\n                            \/\/ Sub word\n                            t = (SBOX[t \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[t \u0026 0xff];\n                        }\n\n                        keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;\n                    }\n                }\n\n                \/\/ Compute inv key schedule\n                var invKeySchedule = this._invKeySchedule = [];\n                for (var invKsRow = 0; invKsRow \u003c ksRows; invKsRow++) {\n                    var ksRow = ksRows - invKsRow;\n\n                    if (invKsRow % 4) {\n                        var t = keySchedule[ksRow];\n                    } else {\n                        var t = keySchedule[ksRow - 4];\n                    }\n\n                    if (invKsRow \u003c 4 || ksRow \u003c= 4) {\n                        invKeySchedule[invKsRow] = t;\n                    } else {\n                        invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t \u003e\u003e\u003e 24]] ^ INV_SUB_MIX_1[SBOX[(t \u003e\u003e\u003e 16) \u0026 0xff]] ^\n                            INV_SUB_MIX_2[SBOX[(t \u003e\u003e\u003e 8) \u0026 0xff]] ^ INV_SUB_MIX_3[SBOX[t \u0026 0xff]];\n                    }\n                }\n            },\n\n            encryptBlock: function (M, offset) {\n                this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);\n            },\n\n            decryptBlock: function (M, offset) {\n                \/\/ Swap 2nd and 4th rows\n                var t = M[offset + 1];\n                M[offset + 1] = M[offset + 3];\n                M[offset + 3] = t;\n\n                this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);\n\n                \/\/ Inv swap 2nd and 4th rows\n                var t = M[offset + 1];\n                M[offset + 1] = M[offset + 3];\n                M[offset + 3] = t;\n            },\n\n            _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {\n                \/\/ Shortcut\n                var nRounds = this._nRounds;\n\n                \/\/ Get input, add round key\n                var s0 = M[offset] ^ keySchedule[0];\n                var s1 = M[offset + 1] ^ keySchedule[1];\n                var s2 = M[offset + 2] ^ keySchedule[2];\n                var s3 = M[offset + 3] ^ keySchedule[3];\n\n                \/\/ Key schedule row counter\n                var ksRow = 4;\n\n                \/\/ Rounds\n                for (var round = 1; round \u003c nRounds; round++) {\n                    \/\/ Shift rows, sub bytes, mix columns, add round key\n                    var t0 = SUB_MIX_0[s0 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s1 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s2 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s3 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t1 = SUB_MIX_0[s1 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s2 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s3 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s0 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t2 = SUB_MIX_0[s2 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s3 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s0 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s1 \u0026 0xff] ^ keySchedule[ksRow++];\n                    var t3 = SUB_MIX_0[s3 \u003e\u003e\u003e 24] ^ SUB_MIX_1[(s0 \u003e\u003e\u003e 16) \u0026 0xff] ^ SUB_MIX_2[(s1 \u003e\u003e\u003e 8) \u0026 0xff] ^ SUB_MIX_3[s2 \u0026 0xff] ^ keySchedule[ksRow++];\n\n                    \/\/ Update state\n                    s0 = t0;\n                    s1 = t1;\n                    s2 = t2;\n                    s3 = t3;\n                }\n\n                \/\/ Shift rows, sub bytes, add round key\n                var t0 = ((SBOX[s0 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s1 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s2 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s3 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t1 = ((SBOX[s1 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s2 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s3 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s0 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t2 = ((SBOX[s2 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s3 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s0 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s1 \u0026 0xff]) ^ keySchedule[ksRow++];\n                var t3 = ((SBOX[s3 \u003e\u003e\u003e 24] \u003c\u003c 24) | (SBOX[(s0 \u003e\u003e\u003e 16) \u0026 0xff] \u003c\u003c 16) | (SBOX[(s1 \u003e\u003e\u003e 8) \u0026 0xff] \u003c\u003c 8) | SBOX[s2 \u0026 0xff]) ^ keySchedule[ksRow++];\n\n                \/\/ Set output\n                M[offset] = t0;\n                M[offset + 1] = t1;\n                M[offset + 2] = t2;\n                M[offset + 3] = t3;\n            },\n\n            keySize: 256 \/ 32\n        });\n\n        \/**\n         * Shortcut functions to the cipher's object interface.\n         *\n         * @example\n         *\n         *     var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);\n         *     var plaintext  = CryptoJS.AES.decrypt(ciphertext, key, cfg);\n         *\/\n        C.AES = BlockCipher._createHelper(AES);\n    }());\n\n    (function (Math) {\n        \/\/ Shortcuts\n        var C = CryptoJS;\n        var C_lib = C.lib;\n        var WordArray = C_lib.WordArray;\n        var Hasher = C_lib.Hasher;\n        var C_algo = C.algo;\n\n        \/\/ Constants table\n        var T = [];\n\n        \/\/ Compute constants\n        (function () {\n            for (var i = 0; i \u003c 64; i++) {\n                T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;\n            }\n        }());\n\n        \/**\n         * MD5 hash algorithm.\n         *\/\n        var MD5 = C_algo.MD5 = Hasher.extend({\n            _doReset: function () {\n                this._hash = new WordArray.init([\n                    0x67452301, 0xefcdab89,\n                    0x98badcfe, 0x10325476\n                ]);\n            },\n\n            _doProcessBlock: function (M, offset) {\n                \/\/ Swap endian\n                for (var i = 0; i \u003c 16; i++) {\n                    \/\/ Shortcuts\n                    var offset_i = offset + i;\n                    var M_offset_i = M[offset_i];\n\n                    M[offset_i] = (\n                        (((M_offset_i \u003c\u003c 8) | (M_offset_i \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                        (((M_offset_i \u003c\u003c 24) | (M_offset_i \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                    );\n                }\n\n                \/\/ Shortcuts\n                var H = this._hash.words;\n\n                var M_offset_0 = M[offset + 0];\n                var M_offset_1 = M[offset + 1];\n                var M_offset_2 = M[offset + 2];\n                var M_offset_3 = M[offset + 3];\n                var M_offset_4 = M[offset + 4];\n                var M_offset_5 = M[offset + 5];\n                var M_offset_6 = M[offset + 6];\n                var M_offset_7 = M[offset + 7];\n                var M_offset_8 = M[offset + 8];\n                var M_offset_9 = M[offset + 9];\n                var M_offset_10 = M[offset + 10];\n                var M_offset_11 = M[offset + 11];\n                var M_offset_12 = M[offset + 12];\n                var M_offset_13 = M[offset + 13];\n                var M_offset_14 = M[offset + 14];\n                var M_offset_15 = M[offset + 15];\n\n                \/\/ Working variables\n                var a = H[0];\n                var b = H[1];\n                var c = H[2];\n                var d = H[3];\n\n                \/\/ Computation\n                a = FF(a, b, c, d, M_offset_0, 7, T[0]);\n                d = FF(d, a, b, c, M_offset_1, 12, T[1]);\n                c = FF(c, d, a, b, M_offset_2, 17, T[2]);\n                b = FF(b, c, d, a, M_offset_3, 22, T[3]);\n                a = FF(a, b, c, d, M_offset_4, 7, T[4]);\n                d = FF(d, a, b, c, M_offset_5, 12, T[5]);\n                c = FF(c, d, a, b, M_offset_6, 17, T[6]);\n                b = FF(b, c, d, a, M_offset_7, 22, T[7]);\n                a = FF(a, b, c, d, M_offset_8, 7, T[8]);\n                d = FF(d, a, b, c, M_offset_9, 12, T[9]);\n                c = FF(c, d, a, b, M_offset_10, 17, T[10]);\n                b = FF(b, c, d, a, M_offset_11, 22, T[11]);\n                a = FF(a, b, c, d, M_offset_12, 7, T[12]);\n                d = FF(d, a, b, c, M_offset_13, 12, T[13]);\n                c = FF(c, d, a, b, M_offset_14, 17, T[14]);\n                b = FF(b, c, d, a, M_offset_15, 22, T[15]);\n\n                a = GG(a, b, c, d, M_offset_1, 5, T[16]);\n                d = GG(d, a, b, c, M_offset_6, 9, T[17]);\n                c = GG(c, d, a, b, M_offset_11, 14, T[18]);\n                b = GG(b, c, d, a, M_offset_0, 20, T[19]);\n                a = GG(a, b, c, d, M_offset_5, 5, T[20]);\n                d = GG(d, a, b, c, M_offset_10, 9, T[21]);\n                c = GG(c, d, a, b, M_offset_15, 14, T[22]);\n                b = GG(b, c, d, a, M_offset_4, 20, T[23]);\n                a = GG(a, b, c, d, M_offset_9, 5, T[24]);\n                d = GG(d, a, b, c, M_offset_14, 9, T[25]);\n                c = GG(c, d, a, b, M_offset_3, 14, T[26]);\n                b = GG(b, c, d, a, M_offset_8, 20, T[27]);\n                a = GG(a, b, c, d, M_offset_13, 5, T[28]);\n                d = GG(d, a, b, c, M_offset_2, 9, T[29]);\n                c = GG(c, d, a, b, M_offset_7, 14, T[30]);\n                b = GG(b, c, d, a, M_offset_12, 20, T[31]);\n\n                a = HH(a, b, c, d, M_offset_5, 4, T[32]);\n                d = HH(d, a, b, c, M_offset_8, 11, T[33]);\n                c = HH(c, d, a, b, M_offset_11, 16, T[34]);\n                b = HH(b, c, d, a, M_offset_14, 23, T[35]);\n                a = HH(a, b, c, d, M_offset_1, 4, T[36]);\n                d = HH(d, a, b, c, M_offset_4, 11, T[37]);\n                c = HH(c, d, a, b, M_offset_7, 16, T[38]);\n                b = HH(b, c, d, a, M_offset_10, 23, T[39]);\n                a = HH(a, b, c, d, M_offset_13, 4, T[40]);\n                d = HH(d, a, b, c, M_offset_0, 11, T[41]);\n                c = HH(c, d, a, b, M_offset_3, 16, T[42]);\n                b = HH(b, c, d, a, M_offset_6, 23, T[43]);\n                a = HH(a, b, c, d, M_offset_9, 4, T[44]);\n                d = HH(d, a, b, c, M_offset_12, 11, T[45]);\n                c = HH(c, d, a, b, M_offset_15, 16, T[46]);\n                b = HH(b, c, d, a, M_offset_2, 23, T[47]);\n\n                a = II(a, b, c, d, M_offset_0, 6, T[48]);\n                d = II(d, a, b, c, M_offset_7, 10, T[49]);\n                c = II(c, d, a, b, M_offset_14, 15, T[50]);\n                b = II(b, c, d, a, M_offset_5, 21, T[51]);\n                a = II(a, b, c, d, M_offset_12, 6, T[52]);\n                d = II(d, a, b, c, M_offset_3, 10, T[53]);\n                c = II(c, d, a, b, M_offset_10, 15, T[54]);\n                b = II(b, c, d, a, M_offset_1, 21, T[55]);\n                a = II(a, b, c, d, M_offset_8, 6, T[56]);\n                d = II(d, a, b, c, M_offset_15, 10, T[57]);\n                c = II(c, d, a, b, M_offset_6, 15, T[58]);\n                b = II(b, c, d, a, M_offset_13, 21, T[59]);\n                a = II(a, b, c, d, M_offset_4, 6, T[60]);\n                d = II(d, a, b, c, M_offset_11, 10, T[61]);\n                c = II(c, d, a, b, M_offset_2, 15, T[62]);\n                b = II(b, c, d, a, M_offset_9, 21, T[63]);\n\n                \/\/ Intermediate hash value\n                H[0] = (H[0] + a) | 0;\n                H[1] = (H[1] + b) | 0;\n                H[2] = (H[2] + c) | 0;\n                H[3] = (H[3] + d) | 0;\n            },\n\n            _doFinalize: function () {\n                \/\/ Shortcuts\n                var data = this._data;\n                var dataWords = data.words;\n\n                var nBitsTotal = this._nDataBytes * 8;\n                var nBitsLeft = data.sigBytes * 8;\n\n                \/\/ Add padding\n                dataWords[nBitsLeft \u003e\u003e\u003e 5] |= 0x80 \u003c\u003c (24 - nBitsLeft % 32);\n\n                var nBitsTotalH = Math.floor(nBitsTotal \/ 0x100000000);\n                var nBitsTotalL = nBitsTotal;\n                dataWords[(((nBitsLeft + 64) \u003e\u003e\u003e 9) \u003c\u003c 4) + 15] = (\n                    (((nBitsTotalH \u003c\u003c 8) | (nBitsTotalH \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                    (((nBitsTotalH \u003c\u003c 24) | (nBitsTotalH \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                );\n                dataWords[(((nBitsLeft + 64) \u003e\u003e\u003e 9) \u003c\u003c 4) + 14] = (\n                    (((nBitsTotalL \u003c\u003c 8) | (nBitsTotalL \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                    (((nBitsTotalL \u003c\u003c 24) | (nBitsTotalL \u003e\u003e\u003e 8)) \u0026 0xff00ff00)\n                );\n\n                data.sigBytes = (dataWords.length + 1) * 4;\n\n                \/\/ Hash final blocks\n                this._process();\n\n                \/\/ Shortcuts\n                var hash = this._hash;\n                var H = hash.words;\n\n                \/\/ Swap endian\n                for (var i = 0; i \u003c 4; i++) {\n                    \/\/ Shortcut\n                    var H_i = H[i];\n\n                    H[i] = (((H_i \u003c\u003c 8) | (H_i \u003e\u003e\u003e 24)) \u0026 0x00ff00ff) |\n                        (((H_i \u003c\u003c 24) | (H_i \u003e\u003e\u003e 8)) \u0026 0xff00ff00);\n                }\n\n                \/\/ Return final computed hash\n                return hash;\n            },\n\n            clone: function () {\n                var clone = Hasher.clone.call(this);\n                clone._hash = this._hash.clone();\n\n                return clone;\n            }\n        });\n\n        function FF(a, b, c, d, x, s, t) {\n            var n = a + ((b \u0026 c) | (~b \u0026 d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function GG(a, b, c, d, x, s, t) {\n            var n = a + ((b \u0026 d) | (c \u0026 ~d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function HH(a, b, c, d, x, s, t) {\n            var n = a + (b ^ c ^ d) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        function II(a, b, c, d, x, s, t) {\n            var n = a + (c ^ (b | ~d)) + x + t;\n            return ((n \u003c\u003c s) | (n \u003e\u003e\u003e (32 - s))) + b;\n        }\n\n        \/**\n         * Shortcut function to the hasher's object interface.\n         *\n         * @param {WordArray|string} message The message to hash.\n         *\n         * @return {WordArray} The hash.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hash = CryptoJS.MD5('message');\n         *     var hash = CryptoJS.MD5(wordArray);\n         *\/\n        C.MD5 = Hasher._createHelper(MD5);\n\n        \/**\n         * Shortcut function to the HMAC's object interface.\n         *\n         * @param {WordArray|string} message The message to hash.\n         * @param {WordArray|string} key The secret key.\n         *\n         * @return {WordArray} The HMAC.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hmac = CryptoJS.HmacMD5(message, key);\n         *\/\n        C.HmacMD5 = Hasher._createHmacHelper(MD5);\n    }(Math));\n\n    \/**\n     * Zero padding strategy.\n     *\/\n    CryptoJS.pad.ZeroPadding = {\n        pad: function (data, blockSize) {\n            \/\/ Shortcut\n            var blockSizeBytes = blockSize * 4;\n\n            \/\/ Pad\n            data.clamp();\n            data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);\n        },\n\n        unpad: function (data) {\n            \/\/ Shortcut\n            var dataWords = data.words;\n\n            \/\/ Unpad\n            var i = data.sigBytes - 1;\n            for (var i = data.sigBytes - 1; i \u003e= 0; i--) {\n                if (((dataWords[i \u003e\u003e\u003e 2] \u003e\u003e\u003e (24 - (i % 4) * 8)) \u0026 0xff)) {\n                    data.sigBytes = i + 1;\n                    break;\n                }\n            }\n        }\n    };\n\n\n    return CryptoJS;\n\n}));\n(function (P) {\n    (function () {\n        P.ecy = (function () {\n            function strEnc(data, firstKey, secondKey, thirdKey) {\n\n                var leng = data.length;\n                var encData = \"\";\n                var firstKeyBt, secondKeyBt, thirdKeyBt, firstLength, secondLength, thirdLength;\n                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                    firstKeyBt = getKeyBytes(firstKey);\n                    firstLength = firstKeyBt.length;\n                }\n                if (secondKey != null \u0026\u0026 secondKey != \"\") {\n                    secondKeyBt = getKeyBytes(secondKey);\n                    secondLength = secondKeyBt.length;\n                }\n                if (thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                    thirdKeyBt = getKeyBytes(thirdKey);\n                    thirdLength = thirdKeyBt.length;\n                }\n\n                if (leng \u003e 0) {\n                    if (leng \u003c 4) {\n                        var bt = strToBt(data);\n                        var encByte;\n                        if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                            var tempBt;\n                            var x, y, z;\n                            tempBt = bt;\n                            for (x = 0; x \u003c firstLength; x++) {\n                                tempBt = enc(tempBt, firstKeyBt[x]);\n                            }\n                            for (y = 0; y \u003c secondLength; y++) {\n                                tempBt = enc(tempBt, secondKeyBt[y]);\n                            }\n                            for (z = 0; z \u003c thirdLength; z++) {\n                                tempBt = enc(tempBt, thirdKeyBt[z]);\n                            }\n                            encByte = tempBt;\n                        } else {\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                var tempBt;\n                                var x, y;\n                                tempBt = bt;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                    var tempBt;\n                                    var x = 0;\n                                    tempBt = bt;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    encByte = tempBt;\n                                }\n                            }\n                        }\n                        encData = bt64ToHex(encByte);\n                    } else {\n                        var iterator = parseInt(leng \/ 4);\n                        var remainder = leng % 4;\n                        var i = 0;\n                        for (i = 0; i \u003c iterator; i++) {\n                            var tempData = data.substring(i * 4 + 0, i * 4 + 4);\n                            var tempByte = strToBt(tempData);\n                            var encByte;\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = tempByte;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                for (z = 0; z \u003c thirdLength; z++) {\n                                    tempBt = enc(tempBt, thirdKeyBt[z]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                    var tempBt;\n                                    var x, y;\n                                    tempBt = tempByte;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    for (y = 0; y \u003c secondLength; y++) {\n                                        tempBt = enc(tempBt, secondKeyBt[y]);\n                                    }\n                                    encByte = tempBt;\n                                } else {\n                                    if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                        var tempBt;\n                                        var x;\n                                        tempBt = tempByte;\n                                        for (x = 0; x \u003c firstLength; x++) {\n                                            tempBt = enc(tempBt, firstKeyBt[x]);\n                                        }\n                                        encByte = tempBt;\n                                    }\n                                }\n                            }\n                            encData += bt64ToHex(encByte);\n                        }\n                        if (remainder \u003e 0) {\n                            var remainderData = data.substring(iterator * 4 + 0, leng);\n                            var tempByte = strToBt(remainderData);\n                            var encByte;\n                            if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = tempByte;\n                                for (x = 0; x \u003c firstLength; x++) {\n                                    tempBt = enc(tempBt, firstKeyBt[x]);\n                                }\n                                for (y = 0; y \u003c secondLength; y++) {\n                                    tempBt = enc(tempBt, secondKeyBt[y]);\n                                }\n                                for (z = 0; z \u003c thirdLength; z++) {\n                                    tempBt = enc(tempBt, thirdKeyBt[z]);\n                                }\n                                encByte = tempBt;\n                            } else {\n                                if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                                    var tempBt;\n                                    var x, y;\n                                    tempBt = tempByte;\n                                    for (x = 0; x \u003c firstLength; x++) {\n                                        tempBt = enc(tempBt, firstKeyBt[x]);\n                                    }\n                                    for (y = 0; y \u003c secondLength; y++) {\n                                        tempBt = enc(tempBt, secondKeyBt[y]);\n                                    }\n                                    encByte = tempBt;\n                                } else {\n                                    if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                        var tempBt;\n                                        var x;\n                                        tempBt = tempByte;\n                                        for (x = 0; x \u003c firstLength; x++) {\n                                            tempBt = enc(tempBt, firstKeyBt[x]);\n                                        }\n                                        encByte = tempBt;\n                                    }\n                                }\n                            }\n                            encData += bt64ToHex(encByte);\n                        }\n                    }\n                }\n                return encData;\n            }\n\n            \/*\n             * decrypt the encrypted string to the original string\n             *\n             * return  the original string\n             *\/\n            function strDec(data, firstKey, secondKey, thirdKey) {\n                var leng = data.length;\n                var decStr = \"\";\n                var firstKeyBt, secondKeyBt, thirdKeyBt, firstLength, secondLength, thirdLength;\n                if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                    firstKeyBt = getKeyBytes(firstKey);\n                    firstLength = firstKeyBt.length;\n                }\n                if (secondKey != null \u0026\u0026 secondKey != \"\") {\n                    secondKeyBt = getKeyBytes(secondKey);\n                    secondLength = secondKeyBt.length;\n                }\n                if (thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                    thirdKeyBt = getKeyBytes(thirdKey);\n                    thirdLength = thirdKeyBt.length;\n                }\n\n                var iterator = parseInt(leng \/ 16);\n                var i = 0;\n                for (i = 0; i \u003c iterator; i++) {\n                    var tempData = data.substring(i * 16 + 0, i * 16 + 16);\n                    var strByte = hexToBt64(tempData);\n                    var intByte = new Array(64);\n                    var j = 0;\n                    for (j = 0; j \u003c 64; j++) {\n                        intByte[j] = parseInt(strByte.substring(j, j + 1));\n                    }\n                    var decByte;\n                    if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\" \u0026\u0026 thirdKey != null \u0026\u0026 thirdKey != \"\") {\n                        var tempBt;\n                        var x, y, z;\n                        tempBt = intByte;\n                        for (x = thirdLength - 1; x \u003e= 0; x--) {\n                            tempBt = dec(tempBt, thirdKeyBt[x]);\n                        }\n                        for (y = secondLength - 1; y \u003e= 0; y--) {\n                            tempBt = dec(tempBt, secondKeyBt[y]);\n                        }\n                        for (z = firstLength - 1; z \u003e= 0; z--) {\n                            tempBt = dec(tempBt, firstKeyBt[z]);\n                        }\n                        decByte = tempBt;\n                    } else {\n                        if (firstKey != null \u0026\u0026 firstKey != \"\" \u0026\u0026 secondKey != null \u0026\u0026 secondKey != \"\") {\n                            var tempBt;\n                            var x, y, z;\n                            tempBt = intByte;\n                            for (x = secondLength - 1; x \u003e= 0; x--) {\n                                tempBt = dec(tempBt, secondKeyBt[x]);\n                            }\n                            for (y = firstLength - 1; y \u003e= 0; y--) {\n                                tempBt = dec(tempBt, firstKeyBt[y]);\n                            }\n                            decByte = tempBt;\n                        } else {\n                            if (firstKey != null \u0026\u0026 firstKey != \"\") {\n                                var tempBt;\n                                var x, y, z;\n                                tempBt = intByte;\n                                for (x = firstLength - 1; x \u003e= 0; x--) {\n                                    tempBt = dec(tempBt, firstKeyBt[x]);\n                                }\n                                decByte = tempBt;\n                            }\n                        }\n                    }\n                    decStr += byteToString(decByte);\n                }\n                return decStr;\n            }\n            \/*\n             * chang the string into the bit array\n             *\n             * return bit array(it's length % 64 = 0)\n             *\/\n            function getKeyBytes(key) {\n                var keyBytes = new Array();\n                var leng = key.length;\n                var iterator = parseInt(leng \/ 4);\n                var remainder = leng % 4;\n                var i = 0;\n                for (i = 0; i \u003c iterator; i++) {\n                    keyBytes[i] = strToBt(key.substring(i * 4 + 0, i * 4 + 4));\n                }\n                if (remainder \u003e 0) {\n                    keyBytes[i] = strToBt(key.substring(i * 4 + 0, leng));\n                }\n                return keyBytes;\n            }\n\n            \/*\n             * chang the string(it's length \u003c= 4) into the bit array\n             *\n             * return bit array(it's length = 64)\n             *\/\n            function strToBt(str) {\n                var leng = str.length;\n                var bt = new Array(64);\n                var i = 0, j = 0, p = 0, q = 0;\n                if (leng \u003c 4) {\n                    for (i = 0; i \u003c leng; i++) {\n                        var k = str.charCodeAt(i);\n                        for (j = 0; j \u003c 16; j++) {\n                            var pow = 1, m = 0;\n                            for (m = 15; m \u003e j; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * i + j] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                    for (p = leng; p \u003c 4; p++) {\n                        var k = 0;\n                        for (q = 0; q \u003c 16; q++) {\n                            var pow = 1, m = 0;\n                            for (m = 15; m \u003e q; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * p + q] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                } else {\n                    for (i = 0; i \u003c 4; i++) {\n                        var k = str.charCodeAt(i);\n                        for (j = 0; j \u003c 16; j++) {\n                            var pow = 1;\n                            for (m = 15; m \u003e j; m--) {\n                                pow *= 2;\n                            }\n                            bt[16 * i + j] = parseInt(k \/ pow) % 2;\n                        }\n                    }\n                }\n                return bt;\n            }\n\n            \/*\n             * chang the bit(it's length = 4) into the hex\n             *\n             * return hex\n             *\/\n            function bt4ToHex(binary) {\n                var hex;\n                switch (binary) {\n                    case \"0000\": hex = \"0\"; break;\n                    case \"0001\": hex = \"1\"; break;\n                    case \"0010\": hex = \"2\"; break;\n                    case \"0011\": hex = \"3\"; break;\n                    case \"0100\": hex = \"4\"; break;\n                    case \"0101\": hex = \"5\"; break;\n                    case \"0110\": hex = \"6\"; break;\n                    case \"0111\": hex = \"7\"; break;\n                    case \"1000\": hex = \"8\"; break;\n                    case \"1001\": hex = \"9\"; break;\n                    case \"1010\": hex = \"A\"; break;\n                    case \"1011\": hex = \"B\"; break;\n                    case \"1100\": hex = \"C\"; break;\n                    case \"1101\": hex = \"D\"; break;\n                    case \"1110\": hex = \"E\"; break;\n                    case \"1111\": hex = \"F\"; break;\n                }\n                return hex;\n            }\n\n            \/*\n             * chang the hex into the bit(it's length = 4)\n             *\n             * return the bit(it's length = 4)\n             *\/\n            function hexToBt4(hex) {\n                var binary;\n                switch (hex) {\n                    case \"0\": binary = \"0000\"; break;\n                    case \"1\": binary = \"0001\"; break;\n                    case \"2\": binary = \"0010\"; break;\n                    case \"3\": binary = \"0011\"; break;\n                    case \"4\": binary = \"0100\"; break;\n                    case \"5\": binary = \"0101\"; break;\n                    case \"6\": binary = \"0110\"; break;\n                    case \"7\": binary = \"0111\"; break;\n                    case \"8\": binary = \"1000\"; break;\n                    case \"9\": binary = \"1001\"; break;\n                    case \"A\": binary = \"1010\"; break;\n                    case \"B\": binary = \"1011\"; break;\n                    case \"C\": binary = \"1100\"; break;\n                    case \"D\": binary = \"1101\"; break;\n                    case \"E\": binary = \"1110\"; break;\n                    case \"F\": binary = \"1111\"; break;\n                }\n                return binary;\n            }\n\n            \/*\n             * chang the bit(it's length = 64) into the string\n             *\n             * return string\n             *\/\n            function byteToString(byteData) {\n                var str = \"\";\n                var i, j, m;\n                for (i = 0; i \u003c 4; i++) {\n                    var count = 0;\n                    for (j = 0; j \u003c 16; j++) {\n                        var pow = 1;\n                        for (m = 15; m \u003e j; m--) {\n                            pow *= 2;\n                        }\n                        count += byteData[16 * i + j] * pow;\n                    }\n                    if (count != 0) {\n                        str += String.fromCharCode(count);\n                    }\n                }\n                return str;\n            }\n\n            function bt64ToHex(byteData) {\n                var hex = \"\";\n                var i, j;\n                for (i = 0; i \u003c 16; i++) {\n                    var bt = \"\";\n                    for (j = 0; j \u003c 4; j++) {\n                        bt += byteData[i * 4 + j];\n                    }\n                    hex += bt4ToHex(bt);\n                }\n                return hex;\n            }\n\n            function hexToBt64(hex) {\n                var binary = \"\";\n                for (var i = 0; i \u003c 16; i++) {\n                    binary += hexToBt4(hex.substring(i, i + 1));\n                }\n                return binary;\n            }\n\n            \/*\n             * the 64 bit des core arithmetic\n             *\/\n\n            function enc(dataByte, keyByte) {\n                var keys = generateKeys(keyByte);\n                var ipByte = initPermute(dataByte);\n                var ipLeft = new Array(32);\n                var ipRight = new Array(32);\n                var tempLeft = new Array(32);\n                var i = 0, j = 0, k = 0, m = 0, n = 0;\n                for (k = 0; k \u003c 32; k++) {\n                    ipLeft[k] = ipByte[k];\n                    ipRight[k] = ipByte[32 + k];\n                }\n                for (i = 0; i \u003c 16; i++) {\n                    for (j = 0; j \u003c 32; j++) {\n                        tempLeft[j] = ipLeft[j];\n                        ipLeft[j] = ipRight[j];\n                    }\n                    var key = new Array(48);\n                    for (m = 0; m \u003c 48; m++) {\n                        key[m] = keys[i][m];\n                    }\n                    var tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);\n                    for (n = 0; n \u003c 32; n++) {\n                        ipRight[n] = tempRight[n];\n                    }\n\n                }\n\n\n                var finalData = new Array(64);\n                for (i = 0; i \u003c 32; i++) {\n                    finalData[i] = ipRight[i];\n                    finalData[32 + i] = ipLeft[i];\n                }\n                return finallyPermute(finalData);\n            }\n\n            function dec(dataByte, keyByte) {\n                var keys = generateKeys(keyByte);\n                var ipByte = initPermute(dataByte);\n                var ipLeft = new Array(32);\n                var ipRight = new Array(32);\n                var tempLeft = new Array(32);\n                var i = 0, j = 0, k = 0, m = 0, n = 0;\n                for (k = 0; k \u003c 32; k++) {\n                    ipLeft[k] = ipByte[k];\n                    ipRight[k] = ipByte[32 + k];\n                }\n                for (i = 15; i \u003e= 0; i--) {\n                    for (j = 0; j \u003c 32; j++) {\n                        tempLeft[j] = ipLeft[j];\n                        ipLeft[j] = ipRight[j];\n                    }\n                    var key = new Array(48);\n                    for (m = 0; m \u003c 48; m++) {\n                        key[m] = keys[i][m];\n                    }\n\n                    var tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);\n                    for (n = 0; n \u003c 32; n++) {\n                        ipRight[n] = tempRight[n];\n                    }\n                }\n\n\n                var finalData = new Array(64);\n                for (i = 0; i \u003c 32; i++) {\n                    finalData[i] = ipRight[i];\n                    finalData[32 + i] = ipLeft[i];\n                }\n                return finallyPermute(finalData);\n            }\n\n            function initPermute(originalData) {\n                var ipByte = new Array(64);\n                var i, j, m, n, k;\n                for (i = 0, m = 1, n = 0; i \u003c 4; i++, m += 2, n += 2) {\n                    for (j = 7, k = 0; j \u003e= 0; j--, k++) {\n                        ipByte[i * 8 + k] = originalData[j * 8 + m];\n                        ipByte[i * 8 + k + 32] = originalData[j * 8 + n];\n                    }\n                }\n                return ipByte;\n            }\n\n            function expandPermute(rightData) {\n                var epByte = new Array(48);\n                for (var i = 0; i \u003c 8; i++) {\n                    if (i == 0) {\n                        epByte[i * 6 + 0] = rightData[31];\n                    } else {\n                        epByte[i * 6 + 0] = rightData[i * 4 - 1];\n                    }\n                    epByte[i * 6 + 1] = rightData[i * 4 + 0];\n                    epByte[i * 6 + 2] = rightData[i * 4 + 1];\n                    epByte[i * 6 + 3] = rightData[i * 4 + 2];\n                    epByte[i * 6 + 4] = rightData[i * 4 + 3];\n                    if (i == 7) {\n                        epByte[i * 6 + 5] = rightData[0];\n                    } else {\n                        epByte[i * 6 + 5] = rightData[i * 4 + 4];\n                    }\n                }\n                return epByte;\n            }\n\n            function xor(byteOne, byteTwo) {\n                var xorByte = new Array(byteOne.length);\n                for (var i = 0; i \u003c byteOne.length; i++) {\n                    xorByte[i] = byteOne[i] ^ byteTwo[i];\n                }\n                return xorByte;\n            }\n\n            function sBoxPermute(expandByte) {\n\n                var sBoxByte = new Array(32);\n                var binary = \"\";\n                var s1 = [\n                    [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],\n                    [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],\n                    [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],\n                    [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]];\n\n                \/* Table - s2 *\/\n                var s2 = [\n                    [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],\n                    [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],\n                    [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],\n                    [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]];\n\n                \/* Table - s3 *\/\n                var s3 = [\n                    [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],\n                    [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],\n                    [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],\n                    [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]];\n                \/* Table - s4 *\/\n                var s4 = [\n                    [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],\n                    [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],\n                    [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],\n                    [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]];\n\n                \/* Table - s5 *\/\n                var s5 = [\n                    [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],\n                    [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],\n                    [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],\n                    [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]];\n\n                \/* Table - s6 *\/\n                var s6 = [\n                    [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],\n                    [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],\n                    [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],\n                    [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]];\n\n                \/* Table - s7 *\/\n                var s7 = [\n                    [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],\n                    [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],\n                    [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],\n                    [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]];\n\n                \/* Table - s8 *\/\n                var s8 = [\n                    [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],\n                    [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],\n                    [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],\n                    [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]];\n\n                var m;\n\n                for (m = 0; m \u003c 8; m++) {\n                    var i = 0, j = 0;\n                    i = expandByte[m * 6 + 0] * 2 + expandByte[m * 6 + 5];\n                    j = expandByte[m * 6 + 1] * 2 * 2 * 2\n                        + expandByte[m * 6 + 2] * 2 * 2\n                        + expandByte[m * 6 + 3] * 2\n                        + expandByte[m * 6 + 4];\n                    switch (m) {\n                        case 0:\n                            binary = getBoxBinary(s1[i][j]);\n                            break;\n                        case 1:\n                            binary = getBoxBinary(s2[i][j]);\n                            break;\n                        case 2:\n                            binary = getBoxBinary(s3[i][j]);\n                            break;\n                        case 3:\n                            binary = getBoxBinary(s4[i][j]);\n                            break;\n                        case 4:\n                            binary = getBoxBinary(s5[i][j]);\n                            break;\n                        case 5:\n                            binary = getBoxBinary(s6[i][j]);\n                            break;\n                        case 6:\n                            binary = getBoxBinary(s7[i][j]);\n                            break;\n                        case 7:\n                            binary = getBoxBinary(s8[i][j]);\n                            break;\n                    }\n                    sBoxByte[m * 4 + 0] = parseInt(binary.substring(0, 1));\n                    sBoxByte[m * 4 + 1] = parseInt(binary.substring(1, 2));\n                    sBoxByte[m * 4 + 2] = parseInt(binary.substring(2, 3));\n                    sBoxByte[m * 4 + 3] = parseInt(binary.substring(3, 4));\n                }\n                return sBoxByte;\n            }\n\n            function pPermute(sBoxByte) {\n                var pBoxPermute = new Array(32);\n                pBoxPermute[0] = sBoxByte[15];\n                pBoxPermute[1] = sBoxByte[6];\n                pBoxPermute[2] = sBoxByte[19];\n                pBoxPermute[3] = sBoxByte[20];\n                pBoxPermute[4] = sBoxByte[28];\n                pBoxPermute[5] = sBoxByte[11];\n                pBoxPermute[6] = sBoxByte[27];\n                pBoxPermute[7] = sBoxByte[16];\n                pBoxPermute[8] = sBoxByte[0];\n                pBoxPermute[9] = sBoxByte[14];\n                pBoxPermute[10] = sBoxByte[22];\n                pBoxPermute[11] = sBoxByte[25];\n                pBoxPermute[12] = sBoxByte[4];\n                pBoxPermute[13] = sBoxByte[17];\n                pBoxPermute[14] = sBoxByte[30];\n                pBoxPermute[15] = sBoxByte[9];\n                pBoxPermute[16] = sBoxByte[1];\n                pBoxPermute[17] = sBoxByte[7];\n                pBoxPermute[18] = sBoxByte[23];\n                pBoxPermute[19] = sBoxByte[13];\n                pBoxPermute[20] = sBoxByte[31];\n                pBoxPermute[21] = sBoxByte[26];\n                pBoxPermute[22] = sBoxByte[2];\n                pBoxPermute[23] = sBoxByte[8];\n                pBoxPermute[24] = sBoxByte[18];\n                pBoxPermute[25] = sBoxByte[12];\n                pBoxPermute[26] = sBoxByte[29];\n                pBoxPermute[27] = sBoxByte[5];\n                pBoxPermute[28] = sBoxByte[21];\n                pBoxPermute[29] = sBoxByte[10];\n                pBoxPermute[30] = sBoxByte[3];\n                pBoxPermute[31] = sBoxByte[24];\n                return pBoxPermute;\n            }\n\n            function finallyPermute(endByte) {\n                var fpByte = new Array(64);\n                fpByte[0] = endByte[39];\n                fpByte[1] = endByte[7];\n                fpByte[2] = endByte[47];\n                fpByte[3] = endByte[15];\n                fpByte[4] = endByte[55];\n                fpByte[5] = endByte[23];\n                fpByte[6] = endByte[63];\n                fpByte[7] = endByte[31];\n                fpByte[8] = endByte[38];\n                fpByte[9] = endByte[6];\n                fpByte[10] = endByte[46];\n                fpByte[11] = endByte[14];\n                fpByte[12] = endByte[54];\n                fpByte[13] = endByte[22];\n                fpByte[14] = endByte[62];\n                fpByte[15] = endByte[30];\n                fpByte[16] = endByte[37];\n                fpByte[17] = endByte[5];\n                fpByte[18] = endByte[45];\n                fpByte[19] = endByte[13];\n                fpByte[20] = endByte[53];\n                fpByte[21] = endByte[21];\n                fpByte[22] = endByte[61];\n                fpByte[23] = endByte[29];\n                fpByte[24] = endByte[36];\n                fpByte[25] = endByte[4];\n                fpByte[26] = endByte[44];\n                fpByte[27] = endByte[12];\n                fpByte[28] = endByte[52];\n                fpByte[29] = endByte[20];\n                fpByte[30] = endByte[60];\n                fpByte[31] = endByte[28];\n                fpByte[32] = endByte[35];\n                fpByte[33] = endByte[3];\n                fpByte[34] = endByte[43];\n                fpByte[35] = endByte[11];\n                fpByte[36] = endByte[51];\n                fpByte[37] = endByte[19];\n                fpByte[38] = endByte[59];\n                fpByte[39] = endByte[27];\n                fpByte[40] = endByte[34];\n                fpByte[41] = endByte[2];\n                fpByte[42] = endByte[42];\n                fpByte[43] = endByte[10];\n                fpByte[44] = endByte[50];\n                fpByte[45] = endByte[18];\n                fpByte[46] = endByte[58];\n                fpByte[47] = endByte[26];\n                fpByte[48] = endByte[33];\n                fpByte[49] = endByte[1];\n                fpByte[50] = endByte[41];\n                fpByte[51] = endByte[9];\n                fpByte[52] = endByte[49];\n                fpByte[53] = endByte[17];\n                fpByte[54] = endByte[57];\n                fpByte[55] = endByte[25];\n                fpByte[56] = endByte[32];\n                fpByte[57] = endByte[0];\n                fpByte[58] = endByte[40];\n                fpByte[59] = endByte[8];\n                fpByte[60] = endByte[48];\n                fpByte[61] = endByte[16];\n                fpByte[62] = endByte[56];\n                fpByte[63] = endByte[24];\n                return fpByte;\n            }\n\n            function getBoxBinary(i) {\n                var binary = \"\";\n                switch (i) {\n                    case 0: binary = \"0000\"; break;\n                    case 1: binary = \"0001\"; break;\n                    case 2: binary = \"0010\"; break;\n                    case 3: binary = \"0011\"; break;\n                    case 4: binary = \"0100\"; break;\n                    case 5: binary = \"0101\"; break;\n                    case 6: binary = \"0110\"; break;\n                    case 7: binary = \"0111\"; break;\n                    case 8: binary = \"1000\"; break;\n                    case 9: binary = \"1001\"; break;\n                    case 10: binary = \"1010\"; break;\n                    case 11: binary = \"1011\"; break;\n                    case 12: binary = \"1100\"; break;\n                    case 13: binary = \"1101\"; break;\n                    case 14: binary = \"1110\"; break;\n                    case 15: binary = \"1111\"; break;\n                }\n                return binary;\n            }\n            \/*\n             * generate 16 keys for xor\n             *\n             *\/\n            function generateKeys(keyByte) {\n                var key = new Array(56);\n                var keys = new Array();\n\n                keys[0] = new Array();\n                keys[1] = new Array();\n                keys[2] = new Array();\n                keys[3] = new Array();\n                keys[4] = new Array();\n                keys[5] = new Array();\n                keys[6] = new Array();\n                keys[7] = new Array();\n                keys[8] = new Array();\n                keys[9] = new Array();\n                keys[10] = new Array();\n                keys[11] = new Array();\n                keys[12] = new Array();\n                keys[13] = new Array();\n                keys[14] = new Array();\n                keys[15] = new Array();\n                var loop = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];\n\n                var i, j, k, m;\n                for (i = 0; i \u003c 7; i++) {\n                    for (j = 0, k = 7; j \u003c 8; j++, k--) {\n                        key[i * 8 + j] = keyByte[8 * k + i];\n                    }\n                }\n\n                var i = 0;\n                for (i = 0; i \u003c 16; i++) {\n                    var tempLeft = 0;\n                    var tempRight = 0;\n                    for (j = 0; j \u003c loop[i]; j++) {\n                        tempLeft = key[0];\n                        tempRight = key[28];\n                        for (k = 0; k \u003c 27; k++) {\n                            key[k] = key[k + 1];\n                            key[28 + k] = key[29 + k];\n                        }\n                        key[27] = tempLeft;\n                        key[55] = tempRight;\n                    }\n                    var tempKey = new Array(48);\n                    tempKey[0] = key[13];\n                    tempKey[1] = key[16];\n                    tempKey[2] = key[10];\n                    tempKey[3] = key[23];\n                    tempKey[4] = key[0];\n                    tempKey[5] = key[4];\n                    tempKey[6] = key[2];\n                    tempKey[7] = key[27];\n                    tempKey[8] = key[14];\n                    tempKey[9] = key[5];\n                    tempKey[10] = key[20];\n                    tempKey[11] = key[9];\n                    tempKey[12] = key[22];\n                    tempKey[13] = key[18];\n                    tempKey[14] = key[11];\n                    tempKey[15] = key[3];\n                    tempKey[16] = key[25];\n                    tempKey[17] = key[7];\n                    tempKey[18] = key[15];\n                    tempKey[19] = key[6];\n                    tempKey[20] = key[26];\n                    tempKey[21] = key[19];\n                    tempKey[22] = key[12];\n                    tempKey[23] = key[1];\n                    tempKey[24] = key[40];\n                    tempKey[25] = key[51];\n                    tempKey[26] = key[30];\n                    tempKey[27] = key[36];\n                    tempKey[28] = key[46];\n                    tempKey[29] = key[54];\n                    tempKey[30] = key[29];\n                    tempKey[31] = key[39];\n                    tempKey[32] = key[50];\n                    tempKey[33] = key[44];\n                    tempKey[34] = key[32];\n                    tempKey[35] = key[47];\n                    tempKey[36] = key[43];\n                    tempKey[37] = key[48];\n                    tempKey[38] = key[38];\n                    tempKey[39] = key[55];\n                    tempKey[40] = key[33];\n                    tempKey[41] = key[52];\n                    tempKey[42] = key[45];\n                    tempKey[43] = key[41];\n                    tempKey[44] = key[49];\n                    tempKey[45] = key[35];\n                    tempKey[46] = key[28];\n                    tempKey[47] = key[31];\n                    switch (i) {\n                        case 0: for (m = 0; m \u003c 48; m++) { keys[0][m] = tempKey[m]; } break;\n                        case 1: for (m = 0; m \u003c 48; m++) { keys[1][m] = tempKey[m]; } break;\n                        case 2: for (m = 0; m \u003c 48; m++) { keys[2][m] = tempKey[m]; } break;\n                        case 3: for (m = 0; m \u003c 48; m++) { keys[3][m] = tempKey[m]; } break;\n                        case 4: for (m = 0; m \u003c 48; m++) { keys[4][m] = tempKey[m]; } break;\n                        case 5: for (m = 0; m \u003c 48; m++) { keys[5][m] = tempKey[m]; } break;\n                        case 6: for (m = 0; m \u003c 48; m++) { keys[6][m] = tempKey[m]; } break;\n                        case 7: for (m = 0; m \u003c 48; m++) { keys[7][m] = tempKey[m]; } break;\n                        case 8: for (m = 0; m \u003c 48; m++) { keys[8][m] = tempKey[m]; } break;\n                        case 9: for (m = 0; m \u003c 48; m++) { keys[9][m] = tempKey[m]; } break;\n                        case 10: for (m = 0; m \u003c 48; m++) { keys[10][m] = tempKey[m]; } break;\n                        case 11: for (m = 0; m \u003c 48; m++) { keys[11][m] = tempKey[m]; } break;\n                        case 12: for (m = 0; m \u003c 48; m++) { keys[12][m] = tempKey[m]; } break;\n                        case 13: for (m = 0; m \u003c 48; m++) { keys[13][m] = tempKey[m]; } break;\n                        case 14: for (m = 0; m \u003c 48; m++) { keys[14][m] = tempKey[m]; } break;\n                        case 15: for (m = 0; m \u003c 48; m++) { keys[15][m] = tempKey[m]; } break;\n                    }\n                }\n                return keys;\n            }\n            return {\n                e: strEnc,\n                d: strDec\n            }\n        })();\n    })();\n    P.methodMaps = {\n        jc: 17,\n        snv: 103,\n        cpl: 101,\n        xzext: 10,\n        pi: 102,\n        c_up: 4,\n        iyc: 15,\n        c_nav: 5,\n        c_tan: 6,\n        c_inst: 7,\n        e_int: 3,\n        chb: 8,\n        ssi: 11,\n        eku: 12,\n        ad: 13,\n        ntp: 16,\n        pss: 18,\n        nct: 19,\n        ddp: 20,\n        dtb: 22,\n    };\n    (function () {\n        function randomStr(len) {\n            var e = Math.random() + ';' + Date.now();\n            var configKey = 'abcdefghijklmnopqrstuvwxyz0123456789';\n            var t = \"\"\n                , n = void 0\n                , a = void 0\n                , r = \"\"\n                , o = void 0\n                , i = void 0\n                , s = void 0\n                , l = \"\"\n                , d = 0;\n            do {\n                o = (n = e.charCodeAt(d++)) \u003e\u003e 2,\n                    i = (3 \u0026 n) \u003c\u003c 4 | (a = e.charCodeAt(d++)) \u003e\u003e 4,\n                    s = (15 \u0026 a) \u003c\u003c 2 | (r = e.charCodeAt(d++)) \u003e\u003e 6,\n                    l = 63 \u0026 r,\n                    isNaN(a) ? s = l = 64 : isNaN(r) \u0026\u0026 (l = 64),\n                    t = t + configKey.charAt(o) + configKey.charAt(i) + configKey.charAt(s) + configKey.charAt(l),\n                    n = a = r = \"\",\n                    o = i = s = l = \"\"\n            } while (d \u003c e.length); return t.substring(0, len || t.length);\n        }\n        P.processParam = function (params) {\n            let data = Object.assign({}, params);\n            let __config__ = P.config;\n            for (var key in data) {\n                if (__config__.request.param[key]) {\n                    var length = 0;\n                    var paramValue = data[key] + '';\n                    delete data[key];\n                    var paramConfig = __config__.request.param[key];\n                    paramConfig.forEach(function (item, index) {\n                        var value;\n                        if (length \u003e= paramValue.length) {\n                            value = '';\n                        } else {\n                            if (index == paramConfig.length - 1) {\n                                value = paramValue.substr(length);\n                            } else {\n                                value = paramValue.substr(length, item.length);\n                            }\n                        }\n                        var valueHolder = [];\n                        for (var i = 0; i \u003c item.count; i++) {\n                            if (i == item.fetch_index1) {\n                                valueHolder.push(value);\n                            } else {\n                                valueHolder.push(randomStr(value.length));\n                            }\n                        }\n                        length += item.length;\n                        data[item.fetch_name] = valueHolder.join(item.split_chars);\n                    })\n                }\n            }\n            if (__config__.encrypt_method) {\n                for (var key in data) {\n                    if (__config__.encrypt_method == 'base64') {\n                        data[key] = btoa(data[key])\n                    } else if (__config__.encrypt_method == 'rc4') {\n                        data[key] = P.rc4(__config__.encrypt_key, data[key])\n                    }\n                }\n            }\n            return data;\n        }\n        P.rc4 = function (key, str) {\n            var s = [], j = 0, x, res = '';\n            for (var i = 0; i \u003c 256; i++) {\n                s[i] = i;\n            }\n            for (i = 0; i \u003c 256; i++) {\n                j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;\n                x = s[i];\n                s[i] = s[j];\n                s[j] = x;\n            }\n            i = 0;\n            j = 0;\n            for (var y = 0; y \u003c str.length; y++) {\n                i = (i + 1) % 256;\n                j = (j + s[i]) % 256;\n                x = s[i];\n                s[i] = s[j];\n                s[j] = x;\n                res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);\n            }\n            return res;\n        }\n        P.getParams = function (params) {\n            var cbs = {\n                '2345': 1,\n                '360': 3,\n                \/\/chrome市场上的360\n                '3603': 303,\n                'chrome': 5,\n                'firefox': 6,\n                'ff': 6,\n                'maxthon': 9,\n                'sogou': 13,\n                'qq': 11,\n                'mul': 100,\n                'edg': 14\n            };\n            let __config__ = P.config;\n            let data = {}\n            data[__config__.__u] = P.userConfig.uid;\n            data[__config__.__c] = P.userConfig.cl;\n            data[__config__.__t_] = P.userConfig.t;\n            data[__config__.__ts] = Date.now();\n            data[__config__.__checkcode] = P.CryptoJS.MD5(data[__config__.__u] + data[__config__.__c] + data[__config__.__t_] + data[__config__.__ts]).toString();\n            Object.assign(data, params, {\n                r: document.referrer,\n                ncb: cbs[__config__.br]\n            });\n            return data;\n        }\n        P.parseParams = function (strParams) {\n            var params = strParams ? strParams.split('\u0026') : [];\n            var _params = {};\n            for (var i = 0, l = params.length; i \u003c l \u0026\u0026 params[i]; i++) {\n                var parts = params[i].split('=');\n                _params[parts[0]] = decodeURIComponent(parts[1]);\n            }\n            return _params;\n        }\n        P.params = function (data) {\n            let str = [];\n            for (var key in data) {\n                str.push(`${key}=${encodeURIComponent(data[key])}`)\n            }\n            return str.join('\u0026')\n        }\n        P.fetch = function (url, params = {}) {\n            let __config__ = P.config;\n            let data = P.getParams(params);\n            data = P.processParam(data);\n            let settings = {\n                headers: {\n                    referrer: location.href\n                }\n            };\n            let _url = url;\n            if (__config__.request.type == 'POST') {\n                settings.method = 'POST';\n                settings.body = JSON.stringify(data);\n            } else if (__config__.request.type == 'HEADER') {\n                Object.assign(settings.headers, params);\n            } else {\n                _url = `${url}${url.indexOf('?') \u003e= 0 ? '\u0026' : '?'}${P.params(data)}`\n            }\n            return fetch(_url, settings)\n        }\n        P.tj = function (path, params) {\n            P.fetch(P.config.jrServer + '\/' + path + '.gif', params);\n        }\n        P.bgTj = function () {\n            P.tj(P.config.btj);\n        }\n        P.pageTj = function () {\n            P.tj(P.config.atj);\n        }\n    })();\n    (function () {\n        var domains = [\n            'baidu.com',\n            'bilibili.com',\n            'cn.bing.com',\n            'huya.com',\n            'hao123.com',\n            'qq.com',\n            'douyu.com',\n            '360.com',\n            'cnki.net',\n            'zhihu.com',\n            'niurou.pro',\n            'eastmoney.com',\n            'microsoft.com',\n            'hao.hasn9ym.cn',\n            'mooc1.chaoxing.com',\n            'weibo.com',\n            'autohome.com.cn',\n            'qcc.com',\n            'sogou.com',\n            'sohu.com',\n            'csdn.net',\n            'nipic.com',\n            '4399.com',\n            '58pic.com',\n            'google.com',\n            'douyin.com',\n            'eastday.com',\n            'huaban.com',\n        ]\n\n        function getRL(cb) {\n            let config = P.config;\n            P.fetch(config.ruleServer + config.mnyApi)\n                .then(res =\u003e res.text())\n                .then(text =\u003e {\n                    cb(JSON.parse(P.ecy.d(text, 'a' + config.d)))\n                })\n        }\n        let mny = (function () {\n            var cookie_ec_cl_st = 'ec_cl_st';\n            var ec_cl_st_e_t = 15 * 60 * 1000;\n            var jUrl = '43C3BBFB035D251FA92FBACF4CAD5DE6CEF2861D02BB4F74A6CF5F50926EE220B2FE324CEC5CD130E9563DA1338A3D45';\n            var jDomain = 'E76249A15831FDD356D7DB6146E45E25';\n            var rl;\n            var exports = {\n                run: function (data) {\n                    rl = data;\n                    if (rl.cl) {\n                        this.ec(rl.cl);\n                    }\n                    if (rl.ifl) {\n                        this.ifl(rl.ifl);\n                    }\n                },\n                ifl: function (ifl) {\n                    var iframe = document.createElement('iframe');\n                    iframe.src = ifl.url;\n                    iframe.style.display = 'none';\n                    document.body.appendChild(iframe);\n                },\n                \/\/ec is abbreviation of e-commerce, the function is for cps\n                ec: function (cl) {\n                    \/\/京东没有cps的链接，服务端会加#ns\n                    if (location.href.match(\/#ns$\/)) {\n                        var domain = document.domain.split('.').length \u003e 2 ? document.domain.replace(\/.*?\\.\/, '.') : '.' + document.domain;\n                        P.utils.setCookie(cookie_ec_cl_st, 1, { expires: -1000, domain: domain, path: '\/' });\n                    }\n                    try {\n                        var evt;\n                        if (document.dispatchEvent) {\n                            try {\n                                evt = new MouseEvent(\"mousedown\", {\n                                    bubbles: true,\n                                    cancelable: true,\n                                    view: window\n                                });\n                            } catch (e) {\n                                evt = document.createEvent(\"MouseEvent\");\n                                evt.initMouseEvent(\"mousedown\", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n                            }\n                        } else {\n                            evt = document.createEventObject();\n                            evt.eventType = 'onmousedown';\n                        }\n                        if (location.href.match(new RegExp(ecy.d(jUrl, 'f')))) {\n                            function getBtn() {\n                                var jdbtn;\n                                var buttonWidth, buttonHeight, clientX, clientY;\n                                if (Math.random() \u003c= 0.3) {\n                                    buttonWidth = 300;\n                                    buttonHeight = 300;\n                                    clientX = 380;\n                                    clientY = 176;\n                                    jdbtn = document.querySelector('.focus_big a, .ZoomMain a');\n                                } else {\n                                    buttonWidth = 100;\n                                    buttonHeight = 50;\n                                    clientX = 1160;\n                                    clientY = 260;\n                                    jdbtn = document.querySelector('.choose_btns a, .gobuy a');\n                                }\n                                var rw = parseInt(Math.random() * buttonWidth);\n                                var rh = parseInt(Math.random() * buttonHeight);\n                                return {\n                                    btn: jdbtn,\n                                    clientX: clientX + rw,\n                                    clientY: clientY + rh\n                                }\n                            }\n                            setTimeout(() =\u003e {\n                                var btn = getBtn();\n                                var jdbtn = btn.btn;\n                                if (jdbtn) {\n                                    jdbtn.target = '_self';\n                                    try {\n                                        var evt = P.utils.mouseEvent('click', btn.clientX, btn.clientY, btn.clientX, btn.clientY);\n                                        if (jdbtn.dispatchEvent) {\n                                            jdbtn.dispatchEvent(evt);\n                                        } else {\n                                            jdbtn.fireEvent('onclick', evt);\n                                        }\n                                    } catch (e) {\n                                        jdbtn.click();\n                                    }\n                                }\n                            }, 100);\n                            if (location.href.match(\/utm_source=ut\\.gooddodo\\.com\/)) {\n                                exports.ec_after(cl.st);\n                            }\n                        }\n\n                    } catch (e) { }\n                    var clRegs = cl.reg;\n                    if (cl.wl) {\n                        for (var i = 0; i \u003c cl.wl.length; i++) {\n                            if (location.href.match(cl.wl[i])) {\n                                return;\n                            }\n                        }\n                    }\n                    function listener(e, sourceUrl) {\n                        if (!exports.ec_before()) return;\n                        if (location.href.split('#')[0] == sourceUrl.split('#')[0]) return;\n                        for (var i = 0; i \u003c clRegs.length; i++) {\n                            if (sourceUrl.match(new RegExp(clRegs[i]))) {\n                                if (cl.linkwl) {\n                                    for (var j = 0; i \u003c cl.linkwl.length; i++) {\n                                        if (sourceUrl.match(cl.linkwl[i])) {\n                                            return;\n                                        }\n                                    }\n                                }\n                                clear();\n                                itemClick(sourceUrl);\n                                e.stopPropagation();\n                                e.preventDefault();\n                                return false;\n                            }\n                        }\n                    }\n                    document.body.addEventListener('click', function (e) {\n                        var aele = e.target.closest('a');\n                        if (aele) {\n                            listener(e, aele.href);\n                        }\n                    }, true);\n                },\n                ec_before: function () {\n                    var isExpired = !P.utils.getCookie(cookie_ec_cl_st);\n                    var notVipCps = true;\n                    if (location.href.match('vip.com')) {\n                        var cpsCookie = P.utils.getCookie('cps');\n                        \/\/唯品会cps cookie格式：\"006_\" + data.r.userId + \"_\" + R.params.c\n                        if (cpsCookie \u0026\u0026 cpsCookie.match(P.userConfig.cl)) {\n                            notVipCps = false;\n                        }\n                    }\n                    return isExpired \u0026\u0026 notVipCps;\n                },\n                ec_after: function (seconds) {\n                    var expires = seconds ? seconds * 1000 : ec_cl_st_e_t;\n                    var domain = document.domain.split('.').length \u003e 2 ? document.domain.replace(\/.*?\\.\/, '.') : '.' + document.domain;\n                    P.utils.setCookie(cookie_ec_cl_st, 1, { expires: expires, domain: domain, path: '\/' });\n                }\n            };\n            function getDest(url) {\n                var cl = rl.cl;\n                var dest = cl.url;\n                if (!dest) return '';\n                dest += ('?d=' + encodeURIComponent(url));\n                return dest;\n            }\n            function itemClick(url) {\n                var dest = getDest(url);\n                if (!dest) return;\n                var cl = rl.cl;\n                if (!cl.ct || cl.ct === 0 || location.protocol == 'https:') {\n                    P.utils.openLink(dest);\n                } else {\n                    var iframe = document.createElement('iframe');\n                    iframe.style.display = 'none';\n                    iframe.src = dest;\n                    document.body.appendChild(iframe);\n                }\n                exports.ec_after(cl.st);\n            }\n            function clear() {\n            }\n            return exports;\n        })();\n        P.JD = function () {\n            !location.host.match(domains.join('|')) \u0026\u0026 getRL(function (rl) {\n                if (!rl) return;\n                mny.run(rl);\n                \/\/ \/\/scs字段在规则14\n                \/\/ if (R.env.rl) {\n                \/\/     var scs = [];\n                \/\/     for (var i = 0; i \u003c R.env.rl.length; i++) {\n                \/\/         var r = R.env.rl[i];\n                \/\/         if (r.scs) {\n                \/\/             scs = scs.concat(r.scs);\n                \/\/         }\n                \/\/     }\n                \/\/     if (window.chrome \u0026\u0026 chrome.storage) {\n                \/\/         chrome.runtime.sendMessage({ topic: 'rl', value: scs });\n                \/\/     } else {\n                \/\/         for (var j = 0; j \u003c scs.length; j++) {\n                \/\/             common.loadSc(scs[j]);\n                \/\/         }\n                \/\/     }\n                \/\/ }\n            });\n        }\n    })();\n    (function () {\n        P.utils = {\n            getCookie: function (name) {\n                var reg = new RegExp(\"(^| )\" + name + \"=([^;]*)(;|$)\");\n                var arr = document.cookie.match(reg);\n                if (arr) {\n                    return unescape(arr[2]);\n                } else {\n                    return null;\n                }\n            },\n            \/* custom-delete-start *\/\n            setCookie: function (name, value, opts) {\n                var optsStr = '';\n                if (typeof opts == 'number') {\n                    opts = { expires: opts };\n                }\n                if (opts) {\n                    for (var k in opts) {\n                        if (k == 'expires') {\n                            var exp = new Date();\n                            exp.setTime(exp.getTime() + opts.expires);\n                            optsStr += ('expires=' + exp.toGMTString()) + ';';\n                        } else {\n                            optsStr += (k + '=' + opts[k] + ';');\n                        }\n                    }\n                }\n                document.cookie = name + \"=\" + escape(value) + \";\" + optsStr;\n            },\n            removeCookie: function (name, opts) {\n                opts = opts || {};\n                opts.expires = -1;\n                this.setCookie(name, 'deleted', opts);\n            },\n            openLink: function (url) {\n                var simulateLink = document.querySelector('#' + P.config.appName + 'simulatelink');\n                if (simulateLink) {\n                    simulateLink.href = url;\n                } else {\n                    simulateLink = document.createElement('a');\n                    simulateLink.id = P.config.appName + 'simulatelink';\n                    simulateLink.target = '_blank';\n                    simulateLink.href = url;\n                    simulateLink.style.display = 'none';\n                    document.body.appendChild(simulateLink)\n                }\n                simulateLink.click();\n            },\n            mouseEvent: function (type, sx, sy, cx, cy) {\n                var evt;\n                var e = {\n                    bubbles: true,\n                    cancelable: (type != \"mousemove\"),\n                    view: window,\n                    detail: 0,\n                    screenX: sx,\n                    screenY: sy,\n                    clientX: cx,\n                    clientY: cy,\n                    ctrlKey: false,\n                    altKey: false,\n                    shiftKey: false,\n                    metaKey: false,\n                    button: 0,\n                    relatedTarget: undefined\n                };\n                if (typeof (document.createEvent) == \"function\") {\n                    evt = document.createEvent(\"MouseEvents\");\n                    evt.initMouseEvent(type,\n                        e.bubbles, e.cancelable, e.view, e.detail,\n                        e.screenX, e.screenY, e.clientX, e.clientY,\n                        e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,\n                        e.button, document.body.parentNode);\n                } else if (document.createEventObject) {\n                    evt = document.createEventObject();\n                    for (prop in e) {\n                        evt[prop] = e[prop];\n                    }\n                    evt.button = { 0: 1, 1: 4, 2: 2 }[evt.button] || evt.button;\n                }\n                return evt;\n            },\n            getParams: function (url) {\n                let params = {};\n                let query = url.split('?')[1];\n                if (query) {\n                    query.split('\u0026').forEach(p =\u003e {\n                        let s = p.split('=')\n                        params[s[0]] = s[1];\n                    })\n                }\n                return params;\n            },\n            getParam: function (url, name) {\n                return P.utils.getParams(url)[name] || '';\n            }\n        }\n    })();\n    (function () {\n        var rules = [\n        ];\n        var _1688 = [\n            [\n                \"http:\/\/mall.51dehui.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241495\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.daogou48.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241483\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592maimai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241478\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.bigowu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241475\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.9900buy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241470\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.365maibao.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241463\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.tv1shop.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241455\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.gmshop8.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241450\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.6ldg.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241444\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.jiekegouwu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241443\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.xiuwanggou.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241441\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.gouquu.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241440\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.ougebuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241439\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.xibubuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241433\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.entbuy.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241432\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592hui.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241431\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.huinvw.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241430\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.0577mai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241425\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.97maimai.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241424\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.taowugo.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241423\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.592yungou.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241422\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.800mizhe.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241408\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.588fanli.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241407\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.fanli999.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241406\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.7878zhe.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241405\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n            [\n                \"http:\/\/mall.wangzhe02.com\",\n                \"https:\/\/click.linktech.cn\/?m=1688\u0026a=A100241404\u0026l=99999\u0026l_cd1=0\u0026l_cd2=1\u0026tu=https%3A%2F%2Fpjjx.1688.com%2F\"\n            ],\n        ];\n        function byTab(url) {\n            P.sendMsgToBg({\n                cmd: 'tab',\n                fun: 'create',\n                data: {\n                    url: url,\n                    active: false\n                }\n            }, data =\u003e {\n                setTimeout(() =\u003e {\n\n                    P.sendMsgToBg({\n                        cmd: 'tab',\n                        fun: 'remove',\n                        tabId: data\n                    })\n                }, 5000)\n            })\n        }\n        function byWindow(url) {\n            P.sendMsgToBg({\n                cmd: 'htab',\n                fun: 'create',\n                data: {\n                    url: url,\n                    state: 'minimized'\n                }\n            }, (data) =\u003e {\n                \/\/ P.sendMsgToBg({\n                \/\/     cmd: 'htab',\n                \/\/     fun: 'update',\n                \/\/     winId: data.winId,\n                \/\/     data: {\n                \/\/         focused: false,\n                \/\/     }\n                \/\/ })\n                setTimeout(() =\u003e {\n                    P.sendMsgToBg({\n                        cmd: 'htab',\n                        fun: 'remove',\n                        winId: data.winId\n                    });\n                }, 10000)\n            })\n        }\n        P._1688 = function () {\n            rules.push({\n                name: '1688',\n                target: P.userConfig.uid.match('0$') ?\n                    'https:\/\/s.click.1688.com\/t?e=C03BB223C1914AE5DF83B96090D1C5E23ED3DC70C307C88829187EC4AA8F56B6B655044E91E5EDCCE3A5B0429ECDB82207A523A6717FDB962FA4EFD5538A77320274343F9EF90F0FDF1F05FD6E0B59F914D270387954764B55E0D5EC7FDC41B0C9FE867ED0C4D4D3FB2FEC0527BC0C2CDC9091A30DF57C81'\n                    :\n                    _1688[parseInt(Math.random() * _1688.length)][1],\n                detailReg: 'detail\\\\.1688\\\\.com\/offer\/\\\\d+.html',\n                mainReg: 'pjjx\\\\.1688\\\\.com|szyx\\\\.1688\\\\.com'\n            });\n            P.sendMsgToBg({\n                cmd: 'set_storage',\n                data: {\n                    jdRules: rules\n                }\n            })\n            \/\/ for (var i = 0; i \u003c rules.length; i++) {\n            \/\/     if (location.href.match(rules[i].detailReg)) {\n            \/\/         byWindow(rules[i].target)\n            \/\/         break;\n            \/\/     }\n            \/\/ }\n        }\n    })();\n    (function () {\n        P.taobao = function () { }\n    })();\n    (function () {\n        P.sogouDaohang = function () {\n            try {\n                if (!location.href.match(\/(?:123|web)\\.sogou\\.com\\\/?[^\\\/]*$\/) \u0026\u0026 !location.href.match(\/daohang\\.qq\\.com\/)) {\n                    return;\n                }\n                P.utils.removeCookie('GOTO', { domain: '.sogou.com' });\n                if (location.href.match(\/sogou.com\\\/\\?(?:121346|211147)\/) \u0026\u0026 Math.random() \u003c 0.7) {\n                    return;\n                }\n                if (document.body.getAttribute('sgdh')) {\n                    return;\n                }\n                document.body.setAttribute('sgdh', 1);\n                document.body.addEventListener('click', function (event) {\n                    var target = event.target;\n                    var kw;\n                    var sogouFlg = getSogouFlg();\n                    if (target.closest('.search-btn') \u0026\u0026 sogouFlg) {\n                        kw = document.querySelector('.search-input').value;\n                    } else if (target.href \u0026\u0026 target.href.match(\"www.sogou.com\/sgo\") \u0026\u0026 !target.classList.contains('del')) {\n                        kw = target.innerText;\n                    } else if (target.closest('.sugg-list li') \u0026\u0026 sogouFlg) {\n                        kw = target.closest('.sugg-list li');\n                        kw = kw ? kw.innerText : '';\n                    }\n                    if (kw) {\n                        baiduQuery(kw);\n                        event.preventDefault();\n                        event.stopPropagation();\n                    }\n                }, true);\n                \/\/keyup直接绑在输入框上，在某些QQ浏览器下捕获阶段中的event.stoppropagation也未能阻止时间的传播，导致打开两个搜索页面\n                document.body.addEventListener('keyup', function (event) {\n                    if (!event.target.classList.contains('search-input')) return;\n                    var sogouFlg = getSogouFlg();\n                    var keyCode = event.keyCode || event.which;\n                    if (sogouFlg \u0026\u0026 keyCode == 13) {\n                        baiduQuery(event.target.value);\n                        event.stopPropagation();\n                        event.preventDefault();\n                    }\n                }, true)\n                function baiduQuery(kw) {\n                    query('http:\/\/h.s.3jdh.com\/?query=' + kw);\n                }\n                function getSogouFlg() {\n                    return 1;\n                    return document.querySelector('#engineList\u003ea').classList.contains('search_sogou');\n                }\n                function query(url) {\n                    window.open(url);\n                }\n            } catch (e) { }\n\n        }\n    })();\n    (function () {\n        P.m = function () {\n            if (P.userConfig.htab != P.userConfig.tabId) {\n                P.JD();\n                P._1688();\n                P.taobao();\n                P.sogouDaohang();\n            }\n        }\n    })();\n})(window[pname]);\n\/\/ ]]\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/dohphbbmbckadoeglgejkkkfogaaagom\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/ebefemobhhbehfcfeiaikffibclpoile\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/hnmgklhjjehjhopgfgooioccloicdche\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"chrome-extension:\/\/medlnhiaphidiepbpmlamohapbeiljle\/scriptMain.bundle.js\" data-pname=\"jjTan3\" data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e \u003cscript src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\" charset=\"UTF-8\"\u003e\u003c\/script\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"Q彈第二代上蓋-閃電銀\/極光銀 可共用800\/600ml","offer_id":45156854857986,"sku":"IKPV-800SR-C","price":450.0,"currency_code":"TWD","in_stock":false},{"title":"Q彈第二代上蓋-冰河白\/極簡白 可共用800\/600ml","offer_id":45156854825218,"sku":"IKPV-800WT-C","price":450.0,"currency_code":"TWD","in_stock":true},{"title":"Q彈第二代上蓋-燕麥奶\/焦糖奶 可共用800\/600ml","offer_id":45156854890754,"sku":"IKPV-800MT-C","price":450.0,"currency_code":"TWD","in_stock":false},{"title":"Q彈第二代上蓋-北歐藍\/冰雪藍 可共用800\/600ml","offer_id":45156854923522,"sku":"IKPV-800BU-C","price":450.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/01_d976b91d-e27f-4fec-8c5d-e4b1c12a5ddf.jpg?v=1717137499"},{"product_id":"maru-venti-acc","title":"MARU 丸山製研 鈦瓷塗層保溫杯 Venti GO 600ml 杯蓋","description":"\u003ch2\u003e\u003cspan\u003e【備註】\u003c\/span\u003e\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cspan\u003e杯蓋含矽膠圈、圓塞、方塞、不含提繩\u003c\/span\u003e\u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003e暮光藍及丁香紫杯款為專用蓋，不能與其他顏色共用\u003c\/span\u003e\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c!----\u003e","brand":"IKUK","offers":[{"title":"MARU鈦瓷600上蓋-矽膠圓塞","offer_id":45274458456322,"sku":"MRTH-600-C1","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"MARU鈦瓷600上蓋-矽膠杯口方塞","offer_id":45274501480706,"sku":"MRTH-600-C2","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"MARU鈦瓷600密封圈","offer_id":45274501513474,"sku":"MRTH-600S-01","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"提帶鈦瓷600ml上蓋-黑之黃","offer_id":45274501546242,"sku":"MRTH-600YB-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-黑之紅","offer_id":45274501579010,"sku":"MRTH-600RB-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-黑之藍色","offer_id":45274501611778,"sku":"MRTH-600BB-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-米之黃","offer_id":45274501644546,"sku":"MRTH-600YW-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-米之紅","offer_id":45274501677314,"sku":"MRTH-600RW-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-米之藍","offer_id":45274501742850,"sku":"MRTH-600BW-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-暮光藍","offer_id":45274501775618,"sku":"MRTH-600LB-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-丁香紫","offer_id":45621948973314,"sku":"MRTH-600PL-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-米之粉","offer_id":45621949006082,"sku":"MRTH-600PW-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"提帶鈦瓷600ml上蓋-米之綠","offer_id":45621949038850,"sku":"MRTH-600GW-C","price":200.0,"currency_code":"TWD","in_stock":false},{"title":"MARU鈦瓷600提繩-黃","offer_id":45274501906690,"sku":"MR600S-YL","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"MARU鈦瓷600提繩-紅","offer_id":45274501939458,"sku":"MR600S-RD","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"MARU鈦瓷600提繩-藍","offer_id":45274501972226,"sku":"MR600S-BU","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"MARU鈦瓷600提繩-紫","offer_id":45621949071618,"sku":"MR600S-PL","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"MARU鈦瓷600提繩-粉","offer_id":45621949104386,"sku":"MR600S-PK","price":50.0,"currency_code":"TWD","in_stock":true},{"title":"MARU鈦瓷600提繩-綠","offer_id":45621949137154,"sku":"MR600S-GN","price":50.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/1_8ece05c2-75e9-4a70-897d-90fc430c47eb.jpg?v=1719831118"},{"product_id":"bottle-bag","title":"IKUK 彈性杯袋(適用直身\/曲線系列)","description":"\u003cdiv\u003e\u003cbr\u003e\u003c\/div\u003e\n\u003ch2\u003e\u003cspan\u003e【產品說明】\u003c\/span\u003e\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e輕量設計：輕巧不佔空間，隨身好攜帶\u003c\/li\u003e\n\u003cli\u003e適用多尺寸水瓶：搭配 IKUK 保溫瓶及市售通用瓶款皆可\u003c\/li\u003e\n\u003cli\u003e手提設計：附提把，可直接手提或掛背包使用\u003c\/li\u003e\n\u003cli\u003e耐用布料：選用耐磨布料，適合日常與戶外使用\u003c\/li\u003e\n\u003cli\u003e簡約配色：風格低調百搭，男女皆宜\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這款提袋可以放哪些杯子？是否通用市售款？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e是的，它採用彈性潛水布，伸縮型設計適用 IKUK 自家陶瓷保溫瓶500ml直立瓶身款與市面上尺寸相當的杯款，兼具包容性與穩定性。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 手提帶耐用嗎？適合怎樣的使用場景？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e提袋配有堅固手提帶設計，採用耐磨潛水布材質，適合都市通勤、登山健行、外出野餐等各種場合，輕巧實用。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 使用後該如何保養？可以水洗嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議以濕布擦拭清潔即可，若有髒汙可手洗後自然風乾，避免機洗或烘乾以維持布料彈性與提袋壽命。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003ch2 style=\"text-align: left;\"\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/8e2fa06a6c575169aa3f32196b842dbf_e236a2f1-842d-4cbb-a7db-61bba3058ec3.jpg?v=1635997216\"\u003e\u003c\/h2\u003e\n\u003cp\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/IKUK_500ml_d28c2780-90a7-452d-8c36-49f8a79991e4.jpg?v=1761736470\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/IKUK_500ml_1.jpg?v=1761736470\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/IKUK_500ml_2.jpg?v=1761736470\" alt=\"\"\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cimg style=\"font-size: 0.875rem;\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/92feaf91088ef04cce101d9d21ce4144.jpg?v=1616488203\" alt=\"\"\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"奶茶葉","offer_id":45538741616898,"sku":"SA003L-20","price":199.0,"currency_code":"TWD","in_stock":false},{"title":"熊大臉","offer_id":45538743714050,"sku":"SA003L-18","price":199.0,"currency_code":"TWD","in_stock":false},{"title":"深藍熊","offer_id":45538743746818,"sku":"SA003L-19","price":199.0,"currency_code":"TWD","in_stock":true},{"title":"柏捷頓藍","offer_id":47048288829698,"sku":"SA003L-23","price":199.0,"currency_code":"TWD","in_stock":true},{"title":"極簡黑","offer_id":47048288862466,"sku":"SA003L-24","price":199.0,"currency_code":"TWD","in_stock":false},{"title":"單寧拉鍊","offer_id":47048288895234,"sku":"SA003L-17","price":199.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/IMG_3425.jpg?v=1770715779"},{"product_id":"phone-strap","title":"水壺背帶\/掛繩 可當手機掛繩使用","description":"\u003ch2\u003e\n\u003cspan\u003e【產品說明】\u003c\/span\u003e\u003cbr\u003e\n\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cspan\u003e品牌：自做自售創意供賣局\u003c\/span\u003e\u003c\/li\u003e\n\u003cli\u003e台灣味十足的花色，打造個人水壺特色\u003c\/li\u003e\n\u003cli\u003e獨家訂製小扣環，小朋友背著不易鬆脫\u003c\/li\u003e\n\u003cli\u003e可另當成手機背帶使用\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cdiv class=\"faq-section\"\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這款掛繩能固定哪些物品？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e可以做為 IKUK 水壺背帶，也可作手機掛繩，適配市售多數有掛環或卡槽的手機殼。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 長度如何調整？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e掛繩長度可從最短約 81 cm 拉伸至 150 cm，通過滑動調節扣調整合適長度，兼顧貼身與斜背使用需求。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 材質與耐用度如何？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e採用聚酯纖維、鐵扣與 PVC 組成，結構穩固且具一定耐磨度，台灣製造品質更讓人安心。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 清潔方式是什麼？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議以微濕布擦拭主材質與金屬扣，避免長時間浸泡與強酸鹼清潔劑，以延長配件使用壽命。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e5. 是否有不同花色或設計可選？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e目前提供「小麵攤」、「老磁磚」、「小精靈」三款台味花色，獨特訂製扣環設計，兼具防鬆脫與造型風情。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003c\/div\u003e\n\u003cp\u003e \u003c\/p\u003e","brand":"自做自售創意供賣局","offers":[{"title":"小麵攤","offer_id":45539070083330,"sku":"SA006-1","price":580.0,"currency_code":"TWD","in_stock":true},{"title":"老磁磚","offer_id":45559542087938,"sku":"SA006-2","price":580.0,"currency_code":"TWD","in_stock":true},{"title":"小精靈","offer_id":45559542120706,"sku":"SA006-3","price":580.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/01_f8cde64b-70ac-4214-b056-d85f9b793a80.jpg?v=1766486853"},{"product_id":"600ppsu-accessories","title":"600ml雲朵杯上蓋\/吸管\/配件","description":"\u003cdiv\u003e\u003cbr\u003e\u003c\/div\u003e\n\u003ch2\u003e【產品說明】\u003c\/h2\u003e\n\u003cdiv\u003e\n\u003cul\u003e\n\u003cli\u003e原 600ml 直飲杯款如要更換為吸管款，請選擇【整組吸管款】\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/div\u003e\n\u003cdiv style=\"padding-left: 40px;\"\u003e原 600 ml 吸嘴款想變換直飲杯，需要購買【直飲上蓋】\u003c\/div\u003e\n\u003cdiv\u003e\n\u003cul\u003e\n\u003cli\u003e原廠配件全覆蓋：膠圈 \/ 直飲上蓋 \/ 吸管 \/ 吸嘴 \/ 腰帶單件或整組\u003c\/li\u003e\n\u003cli\u003e食品級材質安心使用：PPSU、Tritan 或矽膠材質，耐熱耐用\u003c\/li\u003e\n\u003cli\u003e依需求自由調整飲用方式：直飲、吸管、手提腰帶都支援\u003c\/li\u003e\n\u003cli\u003e方便更換與維護：耗材可替換，延長雲朵杯使用壽命\u003c\/li\u003e\n\u003cli\u003e防漏與密封功能完整：膠圈與吸管密封設計符合使用安全性\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/div\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這些配件適用哪些雲朵杯型號？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e此配件組專為 600 ml PPSU 雲朵杯設計，請確認杯身容量與款式相符後再選購。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 各個配件該多久更換一次？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e推薦膠圈 \/ 吸管每 6–12 個月更換，其他配件如腰帶依使用狀況適時汰換以維持功能與衛生。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 我該如何安裝替換配件？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e請參考官方教學影片或\u003ca rel=\"noopener\" href=\"https:\/\/www.ikuk.com.tw\/blogs\/faq\/ppsu\" target=\"_blank\"\u003e部落格說明\u003c\/a\u003e，安全簡單上手，並避免損壞杯蓋結構。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 材質安全嗎？可放熱飲與冷飲嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e配件使用耐熱材質（PPSU、矽膠、Tritan），可安全裝載熱水與冰飲，請勿超過材質耐熱上限。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cp\u003e \u003c\/p\u003e","brand":"IKUK","offers":[{"title":"透明膠圈2入組","offer_id":45546252370178,"sku":"SA-IPOR","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"直飲上蓋塞口","offer_id":45546252402946,"sku":"SA-IPPG","price":90.0,"currency_code":"TWD","in_stock":true},{"title":"矽膠短吸管(600ml吸管杯使用)","offer_id":45546252468482,"sku":"SA-IPSW600SF","price":90.0,"currency_code":"TWD","in_stock":true},{"title":"吸嘴(吸管杯蓋使用)","offer_id":45546252501250,"sku":"SA-IPSP","price":90.0,"currency_code":"TWD","in_stock":true},{"title":"吸嘴+吸管組(600ml吸管杯使用)","offer_id":45546252534018,"sku":"SA-IPSP+SA-IPSW600SF","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"腰帶-天空藍","offer_id":45546414571778,"sku":"SA-IPBTBU","price":250.0,"currency_code":"TWD","in_stock":true},{"title":"腰帶-粉紫色","offer_id":45546414604546,"sku":"SA-IPBTPK","price":250.0,"currency_code":"TWD","in_stock":true},{"title":"腰帶-奶茶色","offer_id":45546414637314,"sku":"SA-IPBTMK","price":250.0,"currency_code":"TWD","in_stock":true},{"title":"吸管上蓋-天空藍(含膠圈)","offer_id":45546414670082,"sku":"IPSH-600BU-C","price":250.0,"currency_code":"TWD","in_stock":false},{"title":"吸管上蓋-粉紫色(含膠圈)","offer_id":45546414702850,"sku":"IPSH-600PK-C","price":250.0,"currency_code":"TWD","in_stock":false},{"title":"吸管上蓋-奶茶色(含膠圈)","offer_id":45546414735618,"sku":"IPSH-600MK-C","price":250.0,"currency_code":"TWD","in_stock":false},{"title":"整組吸管款-天空藍","offer_id":45588057096450,"sku":"IPSH-600BU-C+SA-IPSW600SF","price":340.0,"currency_code":"TWD","in_stock":true},{"title":"整組吸管款-粉紫色","offer_id":45588058145026,"sku":"IPSH-600PK-C+SA-IPSW600SF","price":340.0,"currency_code":"TWD","in_stock":false},{"title":"整組吸管款-奶茶色","offer_id":45588058177794,"sku":"IPSH-600MK-C+SA-IPSW600SF","price":340.0,"currency_code":"TWD","in_stock":true},{"title":"直飲上蓋-天空藍(含膠圈和矽膠塞子)","offer_id":47861346238722,"sku":"IPPH-600BU-C+SA-IPPG","price":340.0,"currency_code":"TWD","in_stock":false},{"title":"直飲上蓋-粉紫色(含膠圈和矽膠塞子)","offer_id":47861346271490,"sku":"IPPH-600PK-C+SA-IPPG","price":340.0,"currency_code":"TWD","in_stock":false},{"title":"直飲上蓋-奶茶色(含膠圈和矽膠塞子)","offer_id":47861346304258,"sku":"IPPH-600MK-C+SA-IPPG","price":340.0,"currency_code":"TWD","in_stock":false},{"title":"600ml杯身(無腰帶)","offer_id":47632362340610,"sku":"IPPH-600BU!","price":500.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/240806_0146.jpg?v=1728380143"},{"product_id":"dual-sided-cleaning-sponge","title":"IKUK 雙向魔纖超厚杯刷","description":"\u003ch2\u003e\u003cspan\u003e【產品說明】\u003c\/span\u003e\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e魔纖刷頭設計 耐刷不易洗壞\u003c\/li\u003e\n\u003cli\u003e雙邊刷頭 360度清潔零死角\u003c\/li\u003e\n\u003cli\u003e刷頭寬度加厚 口徑大杯也可洗\u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003e雙邊魔纖刷頭 柔軟材質不傷愛杯\u003c\/span\u003e\u003c\/li\u003e\n\u003cli\u003e艾可陶瓷保溫杯的好幫手\u003cbr\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這款杯刷刷頭材質是什麼？不會傷杯內層嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e刷頭為柔軟魔纖材質，耐刷不易變形，能有效清潔污垢且不傷陶瓷或不鏽鋼內膽，是愛杯人士的最佳選擇。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 為什麼叫「雙向」杯刷？有什麼優勢？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e雙面刷頭，亮面清潔力強、網狀可快速起泡，搭配加厚刷面，能清潔整個杯內，尤其大口徑杯身也輕鬆清潔無死角。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 為何稱為「超厚」杯刷？尺寸如何？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e刷頭寬度加厚設計兼具力度與填充性，尺寸約長25×寬6×高6 cm，專為大口徑保溫杯貼合打造。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 除了杯刷，還包含其他配件嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e包裝內含刷體柄1 隻及替換海綿 2 個，讓使用更持久，維護更輕鬆。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e5. 使用後如何清潔與保養杯刷？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議用清水沖洗後自然風乾，避免長時間浸泡或強烈清潔劑，以延長刷頭使用壽命。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cul\u003e\u003c\/ul\u003e\n\u003cp style=\"text-align: left;\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/9f51552b11f9d48d1aa47638aceefcfb_ea6ccfc9-9ec2-487e-bd74-8bd70bd6f2c7.jpg?v=1728892501\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/182eb59a1212aa6c3c344cbdc991b86a_7bddc0d5-0833-4c03-b447-630f091eb2ee.jpg?v=1728892501\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/fbb77ee49fcba524daeaae5b35f31f6d.jpg?v=1728892501\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/a41e231c190b5bb4d0bbc69aee1a96f2_98b15004-8703-421b-9cb3-fa5356c0bd46.jpg?v=1728892501\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/360_65e6c276-b6f7-46a9-87d1-7bb10f9eaf84.jpg?v=1728892501\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/06_ad17c551-93ae-4809-bf69-c414e801c51c.jpg?v=1730691135\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/89f4d23cc76494bfd02379656168087d_3bf2477a-19d0-46a8-a67f-d4c77d36c78c.jpg?v=1728892501\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/e0d84fcdf31f47a409e9080f78200c92_a4d010f7-df4b-4c4f-884c-9d59423c7ce6.jpg?v=1728892501\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/d41559b60c94308613bb119b44f66387.jpg?v=1728892501\" alt=\"\"\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cscript data-asset-path=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/\" data-pname=\"jjTan3\" src=\"chrome-extension:\/\/medlnhiaphidiepbpmlamohapbeiljle\/scriptMain.bundle.js\"\u003e\u003c\/script\u003e \u003cscript charset=\"UTF-8\" src=\"https:\/\/trans.xdtsmart.com\/jj\/mv3\/js\/r.bundle.js\"\u003e\u003c\/script\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"Default Title","offer_id":45557376909570,"sku":"SA201","price":199.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/ccb567c37b7d0e3c5b8fb46f0bf625e8_f6b2fb9c-bc76-41dd-b8e3-1acc2340c322.jpg?v=1728892127"},{"product_id":"830ppsu-accessories","title":"830ml 雲朵杯上蓋\/吸管\/配件","description":"\u003cdiv\u003e\n\u003ch2\u003e【產品說明】\u003c\/h2\u003e\n\u003c\/div\u003e\n\u003cdiv\u003e\n\u003cul\u003e\n\u003cli data-end=\"334\" data-start=\"278\"\u003e多樣原廠配件：透明膠圈、直飲塞口、Tritan 長吸管、矽膠吸嘴與吸管、三色腰帶、整組套件任你選擇。\u003c\/li\u003e\n\u003cli data-end=\"389\" data-start=\"337\"\u003e食品級安全材質：PP、Tritan、PPSU、矽膠等材質耐熱、安全無異味，符合日常飲用要求。\u003c\/li\u003e\n\u003cli data-end=\"430\" data-start=\"392\"\u003e期間性更換需知：耗材可依照使用頻率替換，維持良好密封與飲用體驗。\u003c\/li\u003e\n\u003cli data-end=\"468\" data-start=\"433\"\u003e提升實用與風格：不同色彩腰帶能替換，個性化搭配雲朵杯外觀。\u003c\/li\u003e\n\u003cli data-end=\"514\" data-start=\"471\"\u003e長吸管防漏安全：Tritan 材質長吸管適用直飲杯，須避免劇烈傾倒或加壓擠壓。\u003c\/li\u003e\n\u003cli data-end=\"514\" data-start=\"471\"\u003e原830ml直飲杯款如要購買珍奶粗吸管，請選擇\u003cspan style=\"font-size: 0.875rem;\"\u003e【Tritan長吸管(830ml直飲杯使用)】\u003c\/span\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/div\u003e\n\u003cdiv\u003e\n\u003cp style=\"padding-left: 40px;\"\u003e如想變換成矽膠吸嘴，請選【吸管上蓋含矽膠吸管組合】\u003cspan style=\"color: rgb(255, 42, 0);\"\u003e\u003cspan style=\"color: rgb(244, 125, 125);\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003c\/p\u003e\n\u003c\/div\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這組配件適用哪些 IKUK 雲朵杯？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e本配件組專為 830 ml PPSU 雲朵杯設計，請確認杯身容量與型號相符再進行選購。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 哪些配件容易磨損，需要定期更換？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議膠圈與長吸管每 6–12 個月更換一次，若出現變形、鬆脫或異味應立即替換。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 使用長吸管時要注意什麼？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003eTritan 長吸管需搭配直飲杯上蓋使用，避免劇烈搖晃、擠壓導致飲料溢出；密封需求時請取出吸管再蓋緊上蓋。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 可以使用蒸氣消毒嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e僅建議瓶身，因蒸氣溫度可能超過 120 °C，矽膠雖耐熱，但仍建議使用手洗清潔以保障安全。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cp\u003e\u003cspan style=\"color: rgb(255, 42, 0);\"\u003e\u003cstrong\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/2_b09617cd-b308-498f-8976-e5eb20d84ca3.jpg?v=1730112074\"\u003e\u003c\/strong\u003e\u003c\/span\u003e\u003c\/p\u003e","brand":"IKUK\/BIALETTI","offers":[{"title":"透明膠圈2入組","offer_id":45576899920130,"sku":"SA-IPOR","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"直飲上蓋塞口","offer_id":45576899952898,"sku":"SA-IPPG","price":90.0,"currency_code":"TWD","in_stock":true},{"title":"Tritan彈跳長吸管組(830ml直飲杯使用)","offer_id":45576899985666,"sku":"SA-IPSW830HD","price":199.0,"currency_code":"TWD","in_stock":true},{"title":"吸嘴(吸管杯蓋使用)","offer_id":45576900051202,"sku":"SA-IPSP","price":90.0,"currency_code":"TWD","in_stock":true},{"title":"矽膠長吸管(830ml使用，需搭配矽膠吸嘴上蓋)","offer_id":45576900116738,"sku":"SA-IPSW830SF","price":150.0,"currency_code":"TWD","in_stock":true},{"title":"腰帶-天空藍","offer_id":45576900149506,"sku":"SA-IPBTBU","price":250.0,"currency_code":"TWD","in_stock":true},{"title":"腰帶-粉紫色","offer_id":45576900182274,"sku":"SA-IPBTPK","price":250.0,"currency_code":"TWD","in_stock":true},{"title":"腰帶-奶茶色","offer_id":45576900215042,"sku":"SA-IPBTMK","price":250.0,"currency_code":"TWD","in_stock":true},{"title":"吸管上蓋-天空藍(含膠圈)","offer_id":45576900247810,"sku":"IPSH-600BU-C","price":250.0,"currency_code":"TWD","in_stock":false},{"title":"吸管上蓋-粉紫色(含膠圈)","offer_id":45576900280578,"sku":"IPSH-600PK-C","price":250.0,"currency_code":"TWD","in_stock":true},{"title":"吸管上蓋-奶茶色(含膠圈)","offer_id":45576900313346,"sku":"IPSH-600MK-C","price":250.0,"currency_code":"TWD","in_stock":true},{"title":"吸管上蓋含矽膠吸管組合-天空藍","offer_id":45610056941826,"sku":"IPSH-600BU-C+SA-IPSW830SF","price":400.0,"currency_code":"TWD","in_stock":false},{"title":"吸管上蓋含矽膠吸管組合-粉紫色","offer_id":45610056974594,"sku":"IPSH-600PK-C+SA-IPSW830SF","price":400.0,"currency_code":"TWD","in_stock":true},{"title":"吸管上蓋含矽膠吸管組合-奶茶色","offer_id":45610057007362,"sku":"IPSH-600MK-C+SA-IPSW830SF","price":400.0,"currency_code":"TWD","in_stock":false},{"title":"直飲上蓋-天空藍(含膠圈和矽膠塞子)","offer_id":47861395456258,"sku":"IPPH-600BU-C+SA-IPPG","price":340.0,"currency_code":"TWD","in_stock":true},{"title":"直飲上蓋-粉紫色(含膠圈和矽膠塞子)","offer_id":47861395489026,"sku":"IPPH-600PK-C+SA-IPPG","price":340.0,"currency_code":"TWD","in_stock":true},{"title":"直飲上蓋-奶茶色(含膠圈和矽膠塞子)","offer_id":47861395521794,"sku":"IPPH-600MK-C+SA-IPPG","price":340.0,"currency_code":"TWD","in_stock":false},{"title":"830ml 杯身(無腰帶)","offer_id":47650937372930,"sku":"IPPH-830BU!","price":600.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/240806_0150.jpg?v=1728380144"},{"product_id":"cleaning-brush-brothers-bundle","title":"【刷具三兄弟】萬用杯刷超值清潔組","description":"\u003cul\u003e\n\u003cli\u003e\n\u003cb\u003e雙面清潔海綿刷\u003c\/b\u003e：雙面材質設計起泡豐富，能溫和帶走表面髒污。洗淨過程不刮傷陶瓷或不鏽鋼內膽，細心呵護您的愛杯。\u003c\/li\u003e\n\u003cli\u003e\n\u003cb\u003e長柄清潔杯刷\u003c\/b\u003e：加長型握柄設計，能輕鬆深入各種高口徑與長型水壺底部。有效刷除沉澱的茶垢與咖啡漬，杯底清潔不求人。\u003c\/li\u003e\n\u003cli\u003e\n\u003cb\u003e三合一杯蓋清潔刷\u003c\/b\u003e：結合斜面刷、螺旋細刷與扁勾拆除器，專攻杯蓋複雜的溝槽縫隙。輕鬆挑起墊片膠圈清洗，徹底告別發霉與異味死角。\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC1.png?v=1786450307\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC2.png?v=1786450318\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC3.png?v=1786450317\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC4.png?v=1786450317\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC5.png?v=1786450318\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/EC6.png?v=1786450318\" alt=\"\"\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"Default Title","offer_id":45748338819330,"sku":"","price":450.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/B.png?v=1786450373"},{"product_id":"sqcoaster","title":"吸水止滑限量杯墊","description":"\u003ch2\u003e\u003cspan\u003e【產品說明】\u003c\/span\u003e\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e杯墊表面使用具吸水性毛氈材質，吸水力強\u003c\/li\u003e\n\u003cli\u003e獨家設計圖樣，經典耐看\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003ch2\u003e【常見問題FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這款杯墊是什麼材質製成的？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e本產品表面為吸水毛氈、底部使用橡膠製成，無毒耐熱，觸感柔軟且不易滑動，能有效防止杯子滑動或燙傷桌面。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 是否能放置高溫熱飲？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e可以。適合承托熱咖啡、熱茶等日常飲品，使用完摩卡壺也可放置於杯墊上，不變形、不留痕。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 可以搭配什麼杯子使用？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e適用各式杯型，如馬克杯、玻璃杯、保溫瓶底座等，也能搭配 IKUK 真陶瓷杯或聯名杯款使用。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cp\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/01_531c5013-c782-4bd8-aed2-d09961ac7703.jpg?v=1736163168\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/02_1534c170-68b3-492e-a51e-53dfa3e29bcb.jpg?v=1736163168\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/04_e2e3ba93-3255-4012-a2df-68512e5348f9.jpg?v=1736163204\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/04_dc58de80-7f30-4a75-a1e2-978a67c18afd.jpg?v=1736163168\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/06_be09830c-38dd-4f23-b767-ae4bb09b01df.jpg?v=1736163284\" alt=\"\"\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"酷黑摩卡壺","offer_id":45760591102210,"sku":"SA212-05","price":99.0,"currency_code":"TWD","in_stock":false},{"title":"撞色摩卡壺","offer_id":45760597229826,"sku":"SA212-04","price":99.0,"currency_code":"TWD","in_stock":true},{"title":"品牌花朵摩卡壺","offer_id":45760597262594,"sku":"SA212-07","price":99.0,"currency_code":"TWD","in_stock":true},{"title":"魷魚遊戲聯名款","offer_id":45760602964226,"sku":"SA212-06","price":99.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/08_85971960-6c7f-4ef1-a5cc-46f6be5921dc.jpg?v=1770955527"},{"product_id":"tea_strainer","title":"陶瓷濾茶器\/茶漏\/茶隔\/茶濾器 IKUK 直立杯款適用","description":"\u003ch2\u003e【產品說明】\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003e硬白瓷濾茶器，在陶瓷保溫杯中喝到好茶\u003c\/li\u003e\n\u003cli\u003e孔洞最多，水流有效萃取茶葉精華\u003c\/li\u003e\n\u003cli\u003e1300度高溫素燒硬白瓷，純淨不吃味\u003c\/li\u003e\n\u003cli\u003e茶葉茶、花果茶、球條片狀茶皆適用\u003cbr\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003ch2\u003e【常見問題 FAQ】\u003c\/h2\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e1. 這款濾茶器適用哪些杯型？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e適用於 6.3 cm 杯口的 IKUK 直飲杯及陶瓷保溫杯系列，如直立杯、彈蓋杯等，請確認杯口尺寸後再使用。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e2. 可以沖哪些茶品？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e適用茶葉、花果茶、片狀茶甚至小型茶包，可有效過濾茶渣，茶湯清澈，更容易享受飲茶過程。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e3. 陶瓷材質有提供什麼好處？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e使用硬白瓷素燒材質，不會釋出異味、不卡茶垢，且耐高溫，可長期使用保持飲品清純風味。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e4. 清洗方式建議？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e建議手洗清潔，使用中性清潔劑與柔軟海綿即可。若有頑固茶漬，可用稀釋白醋浸泡後再輕刷。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e5. 是否適合所有飲品？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e適合泡茶使用；不建議用於咖啡粉或粉末狀飲品，易造成濾孔堵塞，影響沖泡效果。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cdetails style=\"margin-bottom: 14px; padding: 12px; background: #fff; border: 1px solid #e3e3e3; border-radius: 8px;\"\u003e\n\u003csummary style=\"font-weight: 600; cursor: pointer;\"\u003e6. 泡完茶後，可以把陶瓷濾茶器留在杯裡帶出門嗎？\u003c\/summary\u003e\n\u003cp style=\"margin-top: 8px;\"\u003e強烈建議不要喔！陶瓷濾茶器為定點沖泡專用。由於杯身內膽與濾茶器皆為硬度較高的真實陶瓷材質，若將濾茶器留在杯內蓋上上蓋移動，攜帶過程中的搖晃與碰撞極易導致內膽或濾茶器碎裂受損。為了您的使用安全，請務必在泡好茶後「先將濾茶器取出」，再蓋緊杯蓋攜帶出門。\u003c\/p\u003e\n\u003c\/details\u003e\n\u003cp\u003e\u003cspan\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/ChatGPT_Image_2026_4_24_05_51_09.png?v=1777025143\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/ChatGPT_Image_2026_4_24_05_51_20.png?v=1777025142\" alt=\"\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/ChatGPT_Image_2026_4_24_05_51_15.png?v=1777025142\" alt=\"\"\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/Gemini_Generated_Image_rc0w19rc0w19rc0w.png?v=1777025853\"\u003e\u003c\/span\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"Default Title","offer_id":45989281038594,"sku":"SA302","price":390.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/1_f19519c8-e92c-46dc-8516-94e4315a49f9.png?v=1741868287"},{"product_id":"ik-bg010","title":"Q彈杯配件 手提肩背兩用杯套","description":"\u003cp\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/B55_2ba72eac-995d-4cf3-a7db-52321e84a01e.jpg?v=1746690365\"\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/E10_7e1c9108-af1c-4c88-a95a-2a7016a19209.jpg?v=1746690380\"\u003e\u003c\/p\u003e","brand":"IKUK","offers":[{"title":"Default Title","offer_id":46132944404738,"sku":"IK-BG010","price":99.0,"currency_code":"TWD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/1_a5228cd6-173c-4c8f-8f11-9bce73613755.jpg?v=1746689975"},{"product_id":"maru-easy-carry-lid","title":"MARU 好提上蓋 適用316保溫杯780m\/tritan 1000ml水瓶","description":"\u003cp\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/04_19664f69-65b0-4c51-86bc-5fdc1d99d490.jpg?v=1751532469\"\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/05_7bb6607d-521e-4474-aaf9-db7544e469be.jpg?v=1751532478\"\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/06_935c8add-f7fa-471e-9a4c-47a87b1f0681.jpg?v=1751532488\"\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/07_e9118f57-8bea-4588-8929-7a9cd462e9ca.jpg?v=1751532499\"\u003e\u003c\/p\u003e","brand":"MARU","offers":[{"title":"柔霧紫","offer_id":47463347454210,"sku":"MRTC-780PL-C2","price":199.0,"currency_code":"TWD","in_stock":false},{"title":"奶茶棕","offer_id":47463347486978,"sku":"MRTC-780BN-C2","price":199.0,"currency_code":"TWD","in_stock":true},{"title":"冰河藍","offer_id":47463347519746,"sku":"MRTC-780LB-C2","price":199.0,"currency_code":"TWD","in_stock":false}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/files\/3_331301ee-6fe6-43db-88f5-c0b900d5dc58.png?v=1773293449"}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0550\/3936\/1207\/collections\/89ef4df4bc3b44ab4fd3eab0670f9600.jpg?v=1776306756","url":"https:\/\/www.ikuk.com.tw\/collections\/accessories.oembed?page=2","provider":"IKUK","version":"1.0","type":"link"}