From 0ffdbb8728f883523a45d3a7ad3a94c3fe78117c Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Sun, 5 Jan 2014 21:30:09 +0400 Subject: [PATCH] added initial web-version --- css/app.css | 1162 + img/Logo_1x.png | Bin 0 -> 1550 bytes img/Logo_2x.png | Bin 0 -> 2857 bytes img/bg_full.png | Bin 0 -> 587517 bytes img/bg_tile.png | Bin 0 -> 287451 bytes img/icons/Arrow_1x.png | Bin 0 -> 167 bytes img/icons/Arrow_2x.png | Bin 0 -> 229 bytes img/icons/Attach_1x.png | Bin 0 -> 515 bytes img/icons/Attach_2x.png | Bin 0 -> 892 bytes img/icons/Attach_pressed_1x.png | Bin 0 -> 527 bytes img/icons/Attach_pressed_2x.png | Bin 0 -> 904 bytes img/icons/CheckIn_Recent.png | Bin 0 -> 518 bytes img/icons/Checks1_1x.png | Bin 0 -> 362 bytes img/icons/Checks1_2x.png | Bin 0 -> 535 bytes img/icons/Checks2_1x.png | Bin 0 -> 469 bytes img/icons/Checks2_2x.png | Bin 0 -> 713 bytes img/icons/CloseHover_1x.png | Bin 0 -> 789 bytes img/icons/CloseHover_2x.png | Bin 0 -> 1496 bytes img/icons/Close_1x.png | Bin 0 -> 783 bytes img/icons/Close_2x.png | Bin 0 -> 1515 bytes img/icons/DialogListGroupChatIcon@2x.png | Bin 0 -> 3258 bytes ...DialogListGroupChatIcon_Highlighted@2x.png | Bin 0 -> 529 bytes img/icons/DocBlue_1x.png | Bin 0 -> 476 bytes img/icons/DocBlue_2x.png | Bin 0 -> 875 bytes img/icons/DocGrey_1x.png | Bin 0 -> 474 bytes img/icons/DocGrey_2x.png | Bin 0 -> 898 bytes img/icons/Location_Active.png | Bin 0 -> 574 bytes img/icons/Logo_1x.png | Bin 0 -> 1550 bytes img/icons/Logo_2x.png | Bin 0 -> 2857 bytes img/icons/NoResults.png | Bin 0 -> 4655 bytes img/icons/Search_1x.png | Bin 0 -> 431 bytes img/icons/Search_2x.png | Bin 0 -> 706 bytes img/icons/Smile_1x.png | Bin 0 -> 773 bytes img/icons/Smile_2x.png | Bin 0 -> 1384 bytes img/icons/Smile_pressed_1x.png | Bin 0 -> 712 bytes img/icons/Smile_pressed_2x.png | Bin 0 -> 1377 bytes img/icons/VideoIcon.png | Bin 0 -> 321 bytes img/icons/icon128.png | Bin 0 -> 35542 bytes img/icons/icon16.png | Bin 0 -> 4262 bytes .../DialogListAvatarSystem@2x.png | Bin 0 -> 5587 bytes img/placeholders/GroupAvatar1@2x.png | Bin 0 -> 1834 bytes img/placeholders/GroupAvatar2@2x.png | Bin 0 -> 1781 bytes img/placeholders/GroupAvatar3@2x.png | Bin 0 -> 1718 bytes img/placeholders/GroupAvatar4@2x.png | Bin 0 -> 1680 bytes img/placeholders/UserAvatar1@2x.png | Bin 0 -> 1551 bytes img/placeholders/UserAvatar2@2x.png | Bin 0 -> 1569 bytes img/placeholders/UserAvatar3@2x.png | Bin 0 -> 1427 bytes img/placeholders/UserAvatar4@2x.png | Bin 0 -> 1477 bytes img/placeholders/UserAvatar5@2x.png | Bin 0 -> 1398 bytes img/placeholders/UserAvatar6@2x.png | Bin 0 -> 1523 bytes img/placeholders/UserAvatar7@2x.png | Bin 0 -> 1477 bytes img/placeholders/UserAvatar8@2x.png | Bin 0 -> 1426 bytes index.html | 45 + js/app.js | 55 + js/background.js | 18 + js/controllers.js | 507 + js/directives.js | 512 + js/filters.js | 126 + js/lib/aes_worker.js | 21 + js/lib/config.js | 14 + js/lib/mtproto.js | 2612 ++ js/lib/pq_worker.js | 12 + js/lib/sha1_worker.js | 14 + js/services.js | 1439 ++ js/util.js | 55 + manifest.json | 18 + partials/chat_modal.html | 41 + partials/dialog.html | 73 + partials/head.html | 17 + partials/im.html | 118 + partials/login.html | 28 + partials/message.html | 91 + partials/photo_modal.html | 11 + partials/user_modal.html | 25 + partials/video_modal.html | 11 + partials/welcome.html | 5 + vendor/README.md | 81 + vendor/angular/angular-animate.js | 1294 + vendor/angular/angular-animate.min.js | 22 + vendor/angular/angular-animate.min.js.map | 8 + vendor/angular/angular-cookies.js | 202 + vendor/angular/angular-cookies.min.js | 8 + vendor/angular/angular-cookies.min.js.map | 8 + vendor/angular/angular-csp.css | 24 + vendor/angular/angular-loader.js | 410 + vendor/angular/angular-loader.min.js | 9 + vendor/angular/angular-loader.min.js.map | 8 + vendor/angular/angular-resource.js | 546 + vendor/angular/angular-resource.min.js | 12 + vendor/angular/angular-resource.min.js.map | 8 + vendor/angular/angular-route.js | 891 + vendor/angular/angular-route.min.js | 14 + vendor/angular/angular-route.min.js.map | 8 + vendor/angular/angular-sanitize.js | 615 + vendor/angular/angular-sanitize.min.js | 14 + vendor/angular/angular-sanitize.min.js.map | 8 + vendor/angular/angular-touch.js | 563 + vendor/angular/angular-touch.min.js | 13 + vendor/angular/angular-touch.min.js.map | 8 + vendor/angular/angular.js | 20282 ++++++++++++++++ vendor/angular/angular.min.js | 201 + vendor/angular/angular.min.js.map | 8 + vendor/angular/errors.json | 1 + vendor/angular/i18n/angular-locale_af-na.js | 99 + vendor/angular/i18n/angular-locale_af-za.js | 99 + vendor/angular/i18n/angular-locale_af.js | 99 + vendor/angular/i18n/angular-locale_am-et.js | 99 + vendor/angular/i18n/angular-locale_am.js | 99 + vendor/angular/i18n/angular-locale_ar-001.js | 99 + vendor/angular/i18n/angular-locale_ar-ae.js | 99 + vendor/angular/i18n/angular-locale_ar-bh.js | 99 + vendor/angular/i18n/angular-locale_ar-dz.js | 99 + vendor/angular/i18n/angular-locale_ar-eg.js | 99 + vendor/angular/i18n/angular-locale_ar-iq.js | 99 + vendor/angular/i18n/angular-locale_ar-jo.js | 99 + vendor/angular/i18n/angular-locale_ar-kw.js | 99 + vendor/angular/i18n/angular-locale_ar-lb.js | 99 + vendor/angular/i18n/angular-locale_ar-ly.js | 99 + vendor/angular/i18n/angular-locale_ar-ma.js | 99 + vendor/angular/i18n/angular-locale_ar-om.js | 99 + vendor/angular/i18n/angular-locale_ar-qa.js | 99 + vendor/angular/i18n/angular-locale_ar-sa.js | 99 + vendor/angular/i18n/angular-locale_ar-sd.js | 99 + vendor/angular/i18n/angular-locale_ar-sy.js | 99 + vendor/angular/i18n/angular-locale_ar-tn.js | 99 + vendor/angular/i18n/angular-locale_ar-ye.js | 99 + vendor/angular/i18n/angular-locale_ar.js | 99 + vendor/angular/i18n/angular-locale_bg-bg.js | 99 + vendor/angular/i18n/angular-locale_bg.js | 99 + vendor/angular/i18n/angular-locale_bn-bd.js | 99 + vendor/angular/i18n/angular-locale_bn-in.js | 99 + vendor/angular/i18n/angular-locale_bn.js | 99 + vendor/angular/i18n/angular-locale_ca-ad.js | 99 + vendor/angular/i18n/angular-locale_ca-es.js | 99 + vendor/angular/i18n/angular-locale_ca.js | 99 + vendor/angular/i18n/angular-locale_cs-cz.js | 99 + vendor/angular/i18n/angular-locale_cs.js | 99 + vendor/angular/i18n/angular-locale_da-dk.js | 99 + vendor/angular/i18n/angular-locale_da.js | 99 + vendor/angular/i18n/angular-locale_de-at.js | 99 + vendor/angular/i18n/angular-locale_de-be.js | 99 + vendor/angular/i18n/angular-locale_de-ch.js | 99 + vendor/angular/i18n/angular-locale_de-de.js | 99 + vendor/angular/i18n/angular-locale_de-li.js | 99 + vendor/angular/i18n/angular-locale_de-lu.js | 99 + vendor/angular/i18n/angular-locale_de.js | 99 + vendor/angular/i18n/angular-locale_el-cy.js | 99 + vendor/angular/i18n/angular-locale_el-gr.js | 99 + vendor/angular/i18n/angular-locale_el.js | 99 + vendor/angular/i18n/angular-locale_en-as.js | 99 + vendor/angular/i18n/angular-locale_en-au.js | 99 + vendor/angular/i18n/angular-locale_en-bb.js | 99 + vendor/angular/i18n/angular-locale_en-be.js | 99 + vendor/angular/i18n/angular-locale_en-bm.js | 99 + vendor/angular/i18n/angular-locale_en-bw.js | 99 + vendor/angular/i18n/angular-locale_en-bz.js | 99 + vendor/angular/i18n/angular-locale_en-ca.js | 99 + .../angular/i18n/angular-locale_en-dsrt-us.js | 99 + vendor/angular/i18n/angular-locale_en-dsrt.js | 99 + vendor/angular/i18n/angular-locale_en-fm.js | 99 + vendor/angular/i18n/angular-locale_en-gb.js | 99 + vendor/angular/i18n/angular-locale_en-gu.js | 99 + vendor/angular/i18n/angular-locale_en-gy.js | 99 + vendor/angular/i18n/angular-locale_en-hk.js | 99 + vendor/angular/i18n/angular-locale_en-ie.js | 99 + vendor/angular/i18n/angular-locale_en-in.js | 99 + vendor/angular/i18n/angular-locale_en-iso.js | 99 + vendor/angular/i18n/angular-locale_en-jm.js | 99 + vendor/angular/i18n/angular-locale_en-mh.js | 99 + vendor/angular/i18n/angular-locale_en-mp.js | 99 + vendor/angular/i18n/angular-locale_en-mt.js | 99 + vendor/angular/i18n/angular-locale_en-mu.js | 99 + vendor/angular/i18n/angular-locale_en-na.js | 99 + vendor/angular/i18n/angular-locale_en-nz.js | 99 + vendor/angular/i18n/angular-locale_en-ph.js | 99 + vendor/angular/i18n/angular-locale_en-pk.js | 99 + vendor/angular/i18n/angular-locale_en-pr.js | 99 + vendor/angular/i18n/angular-locale_en-pw.js | 99 + vendor/angular/i18n/angular-locale_en-sg.js | 99 + vendor/angular/i18n/angular-locale_en-tc.js | 99 + vendor/angular/i18n/angular-locale_en-tt.js | 99 + vendor/angular/i18n/angular-locale_en-um.js | 99 + vendor/angular/i18n/angular-locale_en-us.js | 99 + vendor/angular/i18n/angular-locale_en-vg.js | 99 + vendor/angular/i18n/angular-locale_en-vi.js | 99 + vendor/angular/i18n/angular-locale_en-za.js | 99 + vendor/angular/i18n/angular-locale_en-zw.js | 99 + vendor/angular/i18n/angular-locale_en.js | 99 + vendor/angular/i18n/angular-locale_es-419.js | 99 + vendor/angular/i18n/angular-locale_es-ar.js | 99 + vendor/angular/i18n/angular-locale_es-bo.js | 99 + vendor/angular/i18n/angular-locale_es-cl.js | 99 + vendor/angular/i18n/angular-locale_es-co.js | 99 + vendor/angular/i18n/angular-locale_es-cr.js | 99 + vendor/angular/i18n/angular-locale_es-do.js | 99 + vendor/angular/i18n/angular-locale_es-ea.js | 99 + vendor/angular/i18n/angular-locale_es-ec.js | 99 + vendor/angular/i18n/angular-locale_es-es.js | 99 + vendor/angular/i18n/angular-locale_es-gq.js | 99 + vendor/angular/i18n/angular-locale_es-gt.js | 99 + vendor/angular/i18n/angular-locale_es-hn.js | 99 + vendor/angular/i18n/angular-locale_es-ic.js | 99 + vendor/angular/i18n/angular-locale_es-mx.js | 99 + vendor/angular/i18n/angular-locale_es-ni.js | 99 + vendor/angular/i18n/angular-locale_es-pa.js | 99 + vendor/angular/i18n/angular-locale_es-pe.js | 99 + vendor/angular/i18n/angular-locale_es-pr.js | 99 + vendor/angular/i18n/angular-locale_es-py.js | 99 + vendor/angular/i18n/angular-locale_es-sv.js | 99 + vendor/angular/i18n/angular-locale_es-us.js | 99 + vendor/angular/i18n/angular-locale_es-uy.js | 99 + vendor/angular/i18n/angular-locale_es-ve.js | 99 + vendor/angular/i18n/angular-locale_es.js | 99 + vendor/angular/i18n/angular-locale_et-ee.js | 99 + vendor/angular/i18n/angular-locale_et.js | 99 + vendor/angular/i18n/angular-locale_eu-es.js | 99 + vendor/angular/i18n/angular-locale_eu.js | 99 + vendor/angular/i18n/angular-locale_fa-af.js | 99 + vendor/angular/i18n/angular-locale_fa-ir.js | 99 + vendor/angular/i18n/angular-locale_fa.js | 99 + vendor/angular/i18n/angular-locale_fi-fi.js | 99 + vendor/angular/i18n/angular-locale_fi.js | 99 + vendor/angular/i18n/angular-locale_fil-ph.js | 99 + vendor/angular/i18n/angular-locale_fil.js | 99 + vendor/angular/i18n/angular-locale_fr-be.js | 99 + vendor/angular/i18n/angular-locale_fr-bf.js | 99 + vendor/angular/i18n/angular-locale_fr-bi.js | 99 + vendor/angular/i18n/angular-locale_fr-bj.js | 99 + vendor/angular/i18n/angular-locale_fr-bl.js | 99 + vendor/angular/i18n/angular-locale_fr-ca.js | 99 + vendor/angular/i18n/angular-locale_fr-cd.js | 99 + vendor/angular/i18n/angular-locale_fr-cf.js | 99 + vendor/angular/i18n/angular-locale_fr-cg.js | 99 + vendor/angular/i18n/angular-locale_fr-ch.js | 99 + vendor/angular/i18n/angular-locale_fr-ci.js | 99 + vendor/angular/i18n/angular-locale_fr-cm.js | 99 + vendor/angular/i18n/angular-locale_fr-dj.js | 99 + vendor/angular/i18n/angular-locale_fr-fr.js | 99 + vendor/angular/i18n/angular-locale_fr-ga.js | 99 + vendor/angular/i18n/angular-locale_fr-gf.js | 99 + vendor/angular/i18n/angular-locale_fr-gn.js | 99 + vendor/angular/i18n/angular-locale_fr-gp.js | 99 + vendor/angular/i18n/angular-locale_fr-gq.js | 99 + vendor/angular/i18n/angular-locale_fr-km.js | 99 + vendor/angular/i18n/angular-locale_fr-lu.js | 99 + vendor/angular/i18n/angular-locale_fr-mc.js | 99 + vendor/angular/i18n/angular-locale_fr-mf.js | 99 + vendor/angular/i18n/angular-locale_fr-mg.js | 99 + vendor/angular/i18n/angular-locale_fr-ml.js | 99 + vendor/angular/i18n/angular-locale_fr-mq.js | 99 + vendor/angular/i18n/angular-locale_fr-ne.js | 99 + vendor/angular/i18n/angular-locale_fr-re.js | 99 + vendor/angular/i18n/angular-locale_fr-yt.js | 99 + vendor/angular/i18n/angular-locale_fr.js | 99 + vendor/angular/i18n/angular-locale_gl-es.js | 99 + vendor/angular/i18n/angular-locale_gl.js | 99 + vendor/angular/i18n/angular-locale_gsw-ch.js | 99 + vendor/angular/i18n/angular-locale_gsw.js | 99 + vendor/angular/i18n/angular-locale_gu-in.js | 99 + vendor/angular/i18n/angular-locale_gu.js | 99 + vendor/angular/i18n/angular-locale_he-il.js | 99 + vendor/angular/i18n/angular-locale_he.js | 99 + vendor/angular/i18n/angular-locale_hi-in.js | 99 + vendor/angular/i18n/angular-locale_hi.js | 99 + vendor/angular/i18n/angular-locale_hr-hr.js | 99 + vendor/angular/i18n/angular-locale_hr.js | 99 + vendor/angular/i18n/angular-locale_hu-hu.js | 99 + vendor/angular/i18n/angular-locale_hu.js | 99 + vendor/angular/i18n/angular-locale_id-id.js | 99 + vendor/angular/i18n/angular-locale_id.js | 99 + vendor/angular/i18n/angular-locale_in.js | 99 + vendor/angular/i18n/angular-locale_is-is.js | 99 + vendor/angular/i18n/angular-locale_is.js | 99 + vendor/angular/i18n/angular-locale_it-it.js | 99 + vendor/angular/i18n/angular-locale_it-sm.js | 99 + vendor/angular/i18n/angular-locale_it.js | 99 + vendor/angular/i18n/angular-locale_iw.js | 99 + vendor/angular/i18n/angular-locale_ja-jp.js | 99 + vendor/angular/i18n/angular-locale_ja.js | 99 + vendor/angular/i18n/angular-locale_kn-in.js | 99 + vendor/angular/i18n/angular-locale_kn.js | 99 + vendor/angular/i18n/angular-locale_ko-kr.js | 99 + vendor/angular/i18n/angular-locale_ko.js | 99 + vendor/angular/i18n/angular-locale_ln-cd.js | 99 + vendor/angular/i18n/angular-locale_ln.js | 99 + vendor/angular/i18n/angular-locale_lt-lt.js | 99 + vendor/angular/i18n/angular-locale_lt.js | 99 + vendor/angular/i18n/angular-locale_lv-lv.js | 99 + vendor/angular/i18n/angular-locale_lv.js | 99 + vendor/angular/i18n/angular-locale_ml-in.js | 99 + vendor/angular/i18n/angular-locale_ml.js | 99 + vendor/angular/i18n/angular-locale_mr-in.js | 99 + vendor/angular/i18n/angular-locale_mr.js | 99 + vendor/angular/i18n/angular-locale_ms-my.js | 99 + vendor/angular/i18n/angular-locale_ms.js | 99 + vendor/angular/i18n/angular-locale_mt-mt.js | 99 + vendor/angular/i18n/angular-locale_mt.js | 99 + vendor/angular/i18n/angular-locale_nl-cw.js | 99 + vendor/angular/i18n/angular-locale_nl-nl.js | 99 + vendor/angular/i18n/angular-locale_nl-sx.js | 99 + vendor/angular/i18n/angular-locale_nl.js | 99 + vendor/angular/i18n/angular-locale_no.js | 99 + vendor/angular/i18n/angular-locale_or-in.js | 99 + vendor/angular/i18n/angular-locale_or.js | 99 + vendor/angular/i18n/angular-locale_pl-pl.js | 99 + vendor/angular/i18n/angular-locale_pl.js | 99 + vendor/angular/i18n/angular-locale_pt-br.js | 99 + vendor/angular/i18n/angular-locale_pt-pt.js | 99 + vendor/angular/i18n/angular-locale_pt.js | 99 + vendor/angular/i18n/angular-locale_ro-ro.js | 99 + vendor/angular/i18n/angular-locale_ro.js | 99 + vendor/angular/i18n/angular-locale_ru-ru.js | 99 + vendor/angular/i18n/angular-locale_ru.js | 99 + vendor/angular/i18n/angular-locale_sk-sk.js | 99 + vendor/angular/i18n/angular-locale_sk.js | 99 + vendor/angular/i18n/angular-locale_sl-si.js | 99 + vendor/angular/i18n/angular-locale_sl.js | 99 + vendor/angular/i18n/angular-locale_sq-al.js | 99 + vendor/angular/i18n/angular-locale_sq.js | 99 + .../angular/i18n/angular-locale_sr-cyrl-rs.js | 99 + .../angular/i18n/angular-locale_sr-latn-rs.js | 99 + vendor/angular/i18n/angular-locale_sr.js | 99 + vendor/angular/i18n/angular-locale_sv-se.js | 99 + vendor/angular/i18n/angular-locale_sv.js | 99 + vendor/angular/i18n/angular-locale_sw-tz.js | 99 + vendor/angular/i18n/angular-locale_sw.js | 99 + vendor/angular/i18n/angular-locale_ta-in.js | 99 + vendor/angular/i18n/angular-locale_ta.js | 99 + vendor/angular/i18n/angular-locale_te-in.js | 99 + vendor/angular/i18n/angular-locale_te.js | 99 + vendor/angular/i18n/angular-locale_th-th.js | 99 + vendor/angular/i18n/angular-locale_th.js | 99 + vendor/angular/i18n/angular-locale_tl.js | 99 + vendor/angular/i18n/angular-locale_tr-tr.js | 99 + vendor/angular/i18n/angular-locale_tr.js | 99 + vendor/angular/i18n/angular-locale_uk-ua.js | 99 + vendor/angular/i18n/angular-locale_uk.js | 99 + vendor/angular/i18n/angular-locale_ur-pk.js | 99 + vendor/angular/i18n/angular-locale_ur.js | 99 + vendor/angular/i18n/angular-locale_vi-vn.js | 99 + vendor/angular/i18n/angular-locale_vi.js | 99 + vendor/angular/i18n/angular-locale_zh-cn.js | 99 + .../angular/i18n/angular-locale_zh-hans-cn.js | 99 + vendor/angular/i18n/angular-locale_zh-hk.js | 99 + vendor/angular/i18n/angular-locale_zh-tw.js | 99 + vendor/angular/i18n/angular-locale_zh.js | 99 + vendor/angular/i18n/angular-locale_zu-za.js | 99 + vendor/angular/i18n/angular-locale_zu.js | 99 + vendor/angular/version.json | 1 + vendor/angular/version.txt | 1 + vendor/bootstrap/css/bootstrap.css | 7098 ++++++ .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20290 bytes .../fonts/glyphicons-halflings-regular.svg | 229 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41236 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23292 bytes vendor/bootstrap/js/bootstrap.js | 2002 ++ vendor/cryptoJS/THIRDPARTY_LICENSE | 7 + vendor/cryptoJS/crypto.js | 2042 ++ vendor/gemoji/THIRDPARTY_LICENSE | 14 + vendor/gemoji/images/0023-20e3.png | Bin 0 -> 3742 bytes vendor/gemoji/images/0023-fe0f-20e3.png | Bin 0 -> 3742 bytes vendor/gemoji/images/0030-20e3.png | Bin 0 -> 3611 bytes vendor/gemoji/images/0030-fe0f-20e3.png | Bin 0 -> 3611 bytes vendor/gemoji/images/0031-20e3.png | Bin 0 -> 2825 bytes vendor/gemoji/images/0031-fe0f-20e3.png | Bin 0 -> 2825 bytes vendor/gemoji/images/0032-20e3.png | Bin 0 -> 3518 bytes vendor/gemoji/images/0032-fe0f-20e3.png | Bin 0 -> 3518 bytes vendor/gemoji/images/0033-20e3.png | Bin 0 -> 3758 bytes vendor/gemoji/images/0033-fe0f-20e3.png | Bin 0 -> 3758 bytes vendor/gemoji/images/0034-20e3.png | Bin 0 -> 3176 bytes vendor/gemoji/images/0034-fe0f-20e3.png | Bin 0 -> 3176 bytes vendor/gemoji/images/0035-20e3.png | Bin 0 -> 3593 bytes vendor/gemoji/images/0035-fe0f-20e3.png | Bin 0 -> 3593 bytes vendor/gemoji/images/0036-20e3.png | Bin 0 -> 3791 bytes vendor/gemoji/images/0036-fe0f-20e3.png | Bin 0 -> 3791 bytes vendor/gemoji/images/0037-20e3.png | Bin 0 -> 3055 bytes vendor/gemoji/images/0037-fe0f-20e3.png | Bin 0 -> 3055 bytes vendor/gemoji/images/0038-20e3.png | Bin 0 -> 3844 bytes vendor/gemoji/images/0038-fe0f-20e3.png | Bin 0 -> 3844 bytes vendor/gemoji/images/0039-20e3.png | Bin 0 -> 3776 bytes vendor/gemoji/images/0039-fe0f-20e3.png | Bin 0 -> 3776 bytes vendor/gemoji/images/00a9.png | Bin 0 -> 1600 bytes vendor/gemoji/images/00ae.png | Bin 0 -> 1634 bytes vendor/gemoji/images/1f004-fe0f.png | Bin 0 -> 3309 bytes vendor/gemoji/images/1f004.png | Bin 0 -> 3309 bytes vendor/gemoji/images/1f0cf.png | Bin 0 -> 3877 bytes vendor/gemoji/images/1f170.png | Bin 0 -> 3175 bytes vendor/gemoji/images/1f171.png | Bin 0 -> 3025 bytes vendor/gemoji/images/1f17e.png | Bin 0 -> 3498 bytes vendor/gemoji/images/1f17f-fe0f.png | Bin 0 -> 3083 bytes vendor/gemoji/images/1f17f.png | Bin 0 -> 3083 bytes vendor/gemoji/images/1f18e.png | Bin 0 -> 3859 bytes vendor/gemoji/images/1f191.png | Bin 0 -> 3493 bytes vendor/gemoji/images/1f192.png | Bin 0 -> 4182 bytes vendor/gemoji/images/1f193.png | Bin 0 -> 3605 bytes vendor/gemoji/images/1f194.png | Bin 0 -> 3905 bytes vendor/gemoji/images/1f195.png | Bin 0 -> 3927 bytes vendor/gemoji/images/1f196.png | Bin 0 -> 4201 bytes vendor/gemoji/images/1f197.png | Bin 0 -> 4158 bytes vendor/gemoji/images/1f198.png | Bin 0 -> 4262 bytes vendor/gemoji/images/1f199.png | Bin 0 -> 3721 bytes vendor/gemoji/images/1f19a.png | Bin 0 -> 3424 bytes vendor/gemoji/images/1f1e8-1f1f3.png | Bin 0 -> 3634 bytes vendor/gemoji/images/1f1e9-1f1ea.png | Bin 0 -> 2640 bytes vendor/gemoji/images/1f1ea-1f1f8.png | Bin 0 -> 4302 bytes vendor/gemoji/images/1f1eb-1f1f7.png | Bin 0 -> 3398 bytes vendor/gemoji/images/1f1ec-1f1e7.png | Bin 0 -> 5894 bytes vendor/gemoji/images/1f1ee-1f1f9.png | Bin 0 -> 3495 bytes vendor/gemoji/images/1f1ef-1f1f5.png | Bin 0 -> 2827 bytes vendor/gemoji/images/1f1f0-1f1f7.png | Bin 0 -> 5105 bytes vendor/gemoji/images/1f1f7-1f1fa.png | Bin 0 -> 3920 bytes vendor/gemoji/images/1f1fa-1f1f8.png | Bin 0 -> 6285 bytes vendor/gemoji/images/1f201.png | Bin 0 -> 2854 bytes vendor/gemoji/images/1f202.png | Bin 0 -> 3556 bytes vendor/gemoji/images/1f21a-fe0f.png | Bin 0 -> 3942 bytes vendor/gemoji/images/1f21a.png | Bin 0 -> 3942 bytes vendor/gemoji/images/1f22f-fe0f.png | Bin 0 -> 4103 bytes vendor/gemoji/images/1f22f.png | Bin 0 -> 4103 bytes vendor/gemoji/images/1f232.png | Bin 0 -> 5175 bytes vendor/gemoji/images/1f233.png | Bin 0 -> 4180 bytes vendor/gemoji/images/1f234.png | Bin 0 -> 3890 bytes vendor/gemoji/images/1f235.png | Bin 0 -> 4419 bytes vendor/gemoji/images/1f236.png | Bin 0 -> 3198 bytes vendor/gemoji/images/1f237.png | Bin 0 -> 3011 bytes vendor/gemoji/images/1f238.png | Bin 0 -> 3048 bytes vendor/gemoji/images/1f239.png | Bin 0 -> 4533 bytes vendor/gemoji/images/1f23a.png | Bin 0 -> 3411 bytes vendor/gemoji/images/1f250.png | Bin 0 -> 3095 bytes vendor/gemoji/images/1f251.png | Bin 0 -> 4729 bytes vendor/gemoji/images/1f300.png | Bin 0 -> 4986 bytes vendor/gemoji/images/1f301.png | Bin 0 -> 4623 bytes vendor/gemoji/images/1f302.png | Bin 0 -> 3964 bytes vendor/gemoji/images/1f303.png | Bin 0 -> 4963 bytes vendor/gemoji/images/1f304.png | Bin 0 -> 6594 bytes vendor/gemoji/images/1f305.png | Bin 0 -> 3914 bytes vendor/gemoji/images/1f306.png | Bin 0 -> 3841 bytes vendor/gemoji/images/1f307.png | Bin 0 -> 4312 bytes vendor/gemoji/images/1f308.png | Bin 0 -> 5314 bytes vendor/gemoji/images/1f309.png | Bin 0 -> 5137 bytes vendor/gemoji/images/1f30a.png | Bin 0 -> 5777 bytes vendor/gemoji/images/1f30b.png | Bin 0 -> 6167 bytes vendor/gemoji/images/1f30c.png | Bin 0 -> 5878 bytes vendor/gemoji/images/1f30d.png | Bin 0 -> 7164 bytes vendor/gemoji/images/1f30e.png | Bin 0 -> 7039 bytes vendor/gemoji/images/1f30f.png | Bin 0 -> 7303 bytes vendor/gemoji/images/1f310.png | Bin 0 -> 5837 bytes vendor/gemoji/images/1f311.png | Bin 0 -> 5371 bytes vendor/gemoji/images/1f312.png | Bin 0 -> 6198 bytes vendor/gemoji/images/1f313.png | Bin 0 -> 5967 bytes vendor/gemoji/images/1f314.png | Bin 0 -> 6455 bytes vendor/gemoji/images/1f315.png | Bin 0 -> 6458 bytes vendor/gemoji/images/1f316.png | Bin 0 -> 6510 bytes vendor/gemoji/images/1f317.png | Bin 0 -> 6176 bytes vendor/gemoji/images/1f318.png | Bin 0 -> 5885 bytes vendor/gemoji/images/1f319.png | Bin 0 -> 3541 bytes vendor/gemoji/images/1f31a.png | Bin 0 -> 6750 bytes vendor/gemoji/images/1f31b.png | Bin 0 -> 4280 bytes vendor/gemoji/images/1f31c.png | Bin 0 -> 4328 bytes vendor/gemoji/images/1f31d.png | Bin 0 -> 7224 bytes vendor/gemoji/images/1f31e.png | Bin 0 -> 7958 bytes vendor/gemoji/images/1f31f.png | Bin 0 -> 4068 bytes vendor/gemoji/images/1f320.png | Bin 0 -> 4366 bytes vendor/gemoji/images/1f330.png | Bin 0 -> 5875 bytes vendor/gemoji/images/1f331.png | Bin 0 -> 2260 bytes vendor/gemoji/images/1f332.png | Bin 0 -> 4924 bytes vendor/gemoji/images/1f333.png | Bin 0 -> 7374 bytes vendor/gemoji/images/1f334.png | Bin 0 -> 3664 bytes vendor/gemoji/images/1f335.png | Bin 0 -> 4509 bytes vendor/gemoji/images/1f337.png | Bin 0 -> 6065 bytes vendor/gemoji/images/1f338.png | Bin 0 -> 7174 bytes vendor/gemoji/images/1f339.png | Bin 0 -> 4202 bytes vendor/gemoji/images/1f33a.png | Bin 0 -> 8352 bytes vendor/gemoji/images/1f33b.png | Bin 0 -> 6567 bytes vendor/gemoji/images/1f33c.png | Bin 0 -> 4232 bytes vendor/gemoji/images/1f33d.png | Bin 0 -> 6694 bytes vendor/gemoji/images/1f33e.png | Bin 0 -> 4758 bytes vendor/gemoji/images/1f33f.png | Bin 0 -> 5889 bytes vendor/gemoji/images/1f340.png | Bin 0 -> 5995 bytes vendor/gemoji/images/1f341.png | Bin 0 -> 4450 bytes vendor/gemoji/images/1f342.png | Bin 0 -> 4890 bytes vendor/gemoji/images/1f343.png | Bin 0 -> 5649 bytes vendor/gemoji/images/1f344.png | Bin 0 -> 4887 bytes vendor/gemoji/images/1f345.png | Bin 0 -> 5748 bytes vendor/gemoji/images/1f346.png | Bin 0 -> 4800 bytes vendor/gemoji/images/1f347.png | Bin 0 -> 5423 bytes vendor/gemoji/images/1f348.png | Bin 0 -> 8233 bytes vendor/gemoji/images/1f349.png | Bin 0 -> 5501 bytes vendor/gemoji/images/1f34a.png | Bin 0 -> 6645 bytes vendor/gemoji/images/1f34b.png | Bin 0 -> 6055 bytes vendor/gemoji/images/1f34c.png | Bin 0 -> 3915 bytes vendor/gemoji/images/1f34d.png | Bin 0 -> 5634 bytes vendor/gemoji/images/1f34e.png | Bin 0 -> 5630 bytes vendor/gemoji/images/1f34f.png | Bin 0 -> 6205 bytes vendor/gemoji/images/1f350.png | Bin 0 -> 6936 bytes vendor/gemoji/images/1f351.png | Bin 0 -> 5920 bytes vendor/gemoji/images/1f352.png | Bin 0 -> 5604 bytes vendor/gemoji/images/1f353.png | Bin 0 -> 5477 bytes vendor/gemoji/images/1f354.png | Bin 0 -> 5706 bytes vendor/gemoji/images/1f355.png | Bin 0 -> 5273 bytes vendor/gemoji/images/1f356.png | Bin 0 -> 5534 bytes vendor/gemoji/images/1f357.png | Bin 0 -> 4200 bytes vendor/gemoji/images/1f358.png | Bin 0 -> 7787 bytes vendor/gemoji/images/1f359.png | Bin 0 -> 5408 bytes vendor/gemoji/images/1f35a.png | Bin 0 -> 4743 bytes vendor/gemoji/images/1f35b.png | Bin 0 -> 5336 bytes vendor/gemoji/images/1f35c.png | Bin 0 -> 6574 bytes vendor/gemoji/images/1f35d.png | Bin 0 -> 6955 bytes vendor/gemoji/images/1f35e.png | Bin 0 -> 6214 bytes vendor/gemoji/images/1f35f.png | Bin 0 -> 6405 bytes vendor/gemoji/images/1f360.png | Bin 0 -> 5684 bytes vendor/gemoji/images/1f361.png | Bin 0 -> 4449 bytes vendor/gemoji/images/1f362.png | Bin 0 -> 5543 bytes vendor/gemoji/images/1f363.png | Bin 0 -> 5257 bytes vendor/gemoji/images/1f364.png | Bin 0 -> 7550 bytes vendor/gemoji/images/1f365.png | Bin 0 -> 5818 bytes vendor/gemoji/images/1f366.png | Bin 0 -> 4603 bytes vendor/gemoji/images/1f367.png | Bin 0 -> 5908 bytes vendor/gemoji/images/1f368.png | Bin 0 -> 5469 bytes vendor/gemoji/images/1f369.png | Bin 0 -> 5209 bytes vendor/gemoji/images/1f36a.png | Bin 0 -> 8149 bytes vendor/gemoji/images/1f36b.png | Bin 0 -> 5249 bytes vendor/gemoji/images/1f36c.png | Bin 0 -> 4502 bytes vendor/gemoji/images/1f36d.png | Bin 0 -> 5771 bytes vendor/gemoji/images/1f36e.png | Bin 0 -> 5810 bytes vendor/gemoji/images/1f36f.png | Bin 0 -> 5830 bytes vendor/gemoji/images/1f370.png | Bin 0 -> 6129 bytes vendor/gemoji/images/1f371.png | Bin 0 -> 5732 bytes vendor/gemoji/images/1f372.png | Bin 0 -> 5612 bytes vendor/gemoji/images/1f373.png | Bin 0 -> 5211 bytes vendor/gemoji/images/1f374.png | Bin 0 -> 3608 bytes vendor/gemoji/images/1f375.png | Bin 0 -> 5954 bytes vendor/gemoji/images/1f376.png | Bin 0 -> 5073 bytes vendor/gemoji/images/1f377.png | Bin 0 -> 3151 bytes vendor/gemoji/images/1f378.png | Bin 0 -> 2949 bytes vendor/gemoji/images/1f379.png | Bin 0 -> 4189 bytes vendor/gemoji/images/1f37a.png | Bin 0 -> 6097 bytes vendor/gemoji/images/1f37b.png | Bin 0 -> 6591 bytes vendor/gemoji/images/1f37c.png | Bin 0 -> 4461 bytes vendor/gemoji/images/1f380.png | Bin 0 -> 5581 bytes vendor/gemoji/images/1f381.png | Bin 0 -> 6712 bytes vendor/gemoji/images/1f382.png | Bin 0 -> 5404 bytes vendor/gemoji/images/1f383.png | Bin 0 -> 5633 bytes vendor/gemoji/images/1f384.png | Bin 0 -> 4721 bytes vendor/gemoji/images/1f385.png | Bin 0 -> 6271 bytes vendor/gemoji/images/1f386.png | Bin 0 -> 6269 bytes vendor/gemoji/images/1f387.png | Bin 0 -> 5696 bytes vendor/gemoji/images/1f388.png | Bin 0 -> 2417 bytes vendor/gemoji/images/1f389.png | Bin 0 -> 5945 bytes vendor/gemoji/images/1f38a.png | Bin 0 -> 5521 bytes vendor/gemoji/images/1f38b.png | Bin 0 -> 4409 bytes vendor/gemoji/images/1f38c.png | Bin 0 -> 4036 bytes vendor/gemoji/images/1f38d.png | Bin 0 -> 4672 bytes vendor/gemoji/images/1f38e.png | Bin 0 -> 7138 bytes vendor/gemoji/images/1f38f.png | Bin 0 -> 6124 bytes vendor/gemoji/images/1f390.png | Bin 0 -> 3487 bytes vendor/gemoji/images/1f391.png | Bin 0 -> 6261 bytes vendor/gemoji/images/1f392.png | Bin 0 -> 5741 bytes vendor/gemoji/images/1f393.png | Bin 0 -> 4165 bytes vendor/gemoji/images/1f3a0.png | Bin 0 -> 5893 bytes vendor/gemoji/images/1f3a1.png | Bin 0 -> 6213 bytes vendor/gemoji/images/1f3a2.png | Bin 0 -> 5148 bytes vendor/gemoji/images/1f3a3.png | Bin 0 -> 4470 bytes vendor/gemoji/images/1f3a4.png | Bin 0 -> 3741 bytes vendor/gemoji/images/1f3a5.png | Bin 0 -> 4081 bytes vendor/gemoji/images/1f3a6.png | Bin 0 -> 3573 bytes vendor/gemoji/images/1f3a7.png | Bin 0 -> 1910 bytes vendor/gemoji/images/1f3a8.png | Bin 0 -> 6744 bytes vendor/gemoji/images/1f3a9.png | Bin 0 -> 3009 bytes vendor/gemoji/images/1f3aa.png | Bin 0 -> 4683 bytes vendor/gemoji/images/1f3ab.png | Bin 0 -> 3091 bytes vendor/gemoji/images/1f3ac.png | Bin 0 -> 4192 bytes vendor/gemoji/images/1f3ad.png | Bin 0 -> 6287 bytes vendor/gemoji/images/1f3ae.png | Bin 0 -> 4957 bytes vendor/gemoji/images/1f3af.png | Bin 0 -> 5462 bytes vendor/gemoji/images/1f3b0.png | Bin 0 -> 4605 bytes vendor/gemoji/images/1f3b1.png | Bin 0 -> 4141 bytes vendor/gemoji/images/1f3b2.png | Bin 0 -> 2957 bytes vendor/gemoji/images/1f3b3.png | Bin 0 -> 4184 bytes vendor/gemoji/images/1f3b4.png | Bin 0 -> 3434 bytes vendor/gemoji/images/1f3b5.png | Bin 0 -> 3188 bytes vendor/gemoji/images/1f3b6.png | Bin 0 -> 1614 bytes vendor/gemoji/images/1f3b7.png | Bin 0 -> 4252 bytes vendor/gemoji/images/1f3b8.png | Bin 0 -> 4382 bytes vendor/gemoji/images/1f3b9.png | Bin 0 -> 1944 bytes vendor/gemoji/images/1f3ba.png | Bin 0 -> 4453 bytes vendor/gemoji/images/1f3bb.png | Bin 0 -> 5020 bytes vendor/gemoji/images/1f3bc.png | Bin 0 -> 1576 bytes vendor/gemoji/images/1f3bd.png | Bin 0 -> 5701 bytes vendor/gemoji/images/1f3be.png | Bin 0 -> 5976 bytes vendor/gemoji/images/1f3bf.png | Bin 0 -> 4247 bytes vendor/gemoji/images/1f3c0.png | Bin 0 -> 6386 bytes vendor/gemoji/images/1f3c1.png | Bin 0 -> 1675 bytes vendor/gemoji/images/1f3c2.png | Bin 0 -> 5356 bytes vendor/gemoji/images/1f3c3.png | Bin 0 -> 3214 bytes vendor/gemoji/images/1f3c4.png | Bin 0 -> 6259 bytes vendor/gemoji/images/1f3c6.png | Bin 0 -> 5520 bytes vendor/gemoji/images/1f3c7.png | Bin 0 -> 5905 bytes vendor/gemoji/images/1f3c8.png | Bin 0 -> 6712 bytes vendor/gemoji/images/1f3c9.png | Bin 0 -> 7781 bytes vendor/gemoji/images/1f3ca.png | Bin 0 -> 4378 bytes vendor/gemoji/images/1f3e0.png | Bin 0 -> 3510 bytes vendor/gemoji/images/1f3e1.png | Bin 0 -> 8536 bytes vendor/gemoji/images/1f3e2.png | Bin 0 -> 5171 bytes vendor/gemoji/images/1f3e3.png | Bin 0 -> 5136 bytes vendor/gemoji/images/1f3e4.png | Bin 0 -> 4816 bytes vendor/gemoji/images/1f3e5.png | Bin 0 -> 4887 bytes vendor/gemoji/images/1f3e6.png | Bin 0 -> 5583 bytes vendor/gemoji/images/1f3e7.png | Bin 0 -> 4072 bytes vendor/gemoji/images/1f3e8.png | Bin 0 -> 5123 bytes vendor/gemoji/images/1f3e9.png | Bin 0 -> 5941 bytes vendor/gemoji/images/1f3ea.png | Bin 0 -> 4073 bytes vendor/gemoji/images/1f3eb.png | Bin 0 -> 5446 bytes vendor/gemoji/images/1f3ec.png | Bin 0 -> 5159 bytes vendor/gemoji/images/1f3ed.png | Bin 0 -> 5558 bytes vendor/gemoji/images/1f3ee.png | Bin 0 -> 4064 bytes vendor/gemoji/images/1f3ef.png | Bin 0 -> 4939 bytes vendor/gemoji/images/1f3f0.png | Bin 0 -> 5427 bytes vendor/gemoji/images/1f400.png | Bin 0 -> 5441 bytes vendor/gemoji/images/1f401.png | Bin 0 -> 4087 bytes vendor/gemoji/images/1f402.png | Bin 0 -> 6079 bytes vendor/gemoji/images/1f403.png | Bin 0 -> 4774 bytes vendor/gemoji/images/1f404.png | Bin 0 -> 5303 bytes vendor/gemoji/images/1f405.png | Bin 0 -> 5744 bytes vendor/gemoji/images/1f406.png | Bin 0 -> 5384 bytes vendor/gemoji/images/1f407.png | Bin 0 -> 4517 bytes vendor/gemoji/images/1f408.png | Bin 0 -> 5723 bytes vendor/gemoji/images/1f409.png | Bin 0 -> 7828 bytes vendor/gemoji/images/1f40a.png | Bin 0 -> 6125 bytes vendor/gemoji/images/1f40b.png | Bin 0 -> 6032 bytes vendor/gemoji/images/1f40c.png | Bin 0 -> 6657 bytes vendor/gemoji/images/1f40d.png | Bin 0 -> 4069 bytes vendor/gemoji/images/1f40e.png | Bin 0 -> 4735 bytes vendor/gemoji/images/1f40f.png | Bin 0 -> 6531 bytes vendor/gemoji/images/1f410.png | Bin 0 -> 4889 bytes vendor/gemoji/images/1f411.png | Bin 0 -> 4732 bytes vendor/gemoji/images/1f412.png | Bin 0 -> 4973 bytes vendor/gemoji/images/1f413.png | Bin 0 -> 6168 bytes vendor/gemoji/images/1f414.png | Bin 0 -> 3988 bytes vendor/gemoji/images/1f415.png | Bin 0 -> 5931 bytes vendor/gemoji/images/1f416.png | Bin 0 -> 4797 bytes vendor/gemoji/images/1f417.png | Bin 0 -> 4840 bytes vendor/gemoji/images/1f418.png | Bin 0 -> 5086 bytes vendor/gemoji/images/1f419.png | Bin 0 -> 5779 bytes vendor/gemoji/images/1f41a.png | Bin 0 -> 5115 bytes vendor/gemoji/images/1f41b.png | Bin 0 -> 5945 bytes vendor/gemoji/images/1f41c.png | Bin 0 -> 2851 bytes vendor/gemoji/images/1f41d.png | Bin 0 -> 5851 bytes vendor/gemoji/images/1f41e.png | Bin 0 -> 5255 bytes vendor/gemoji/images/1f41f.png | Bin 0 -> 4743 bytes vendor/gemoji/images/1f420.png | Bin 0 -> 5846 bytes vendor/gemoji/images/1f421.png | Bin 0 -> 3751 bytes vendor/gemoji/images/1f422.png | Bin 0 -> 5336 bytes vendor/gemoji/images/1f423.png | Bin 0 -> 5928 bytes vendor/gemoji/images/1f424.png | Bin 0 -> 3961 bytes vendor/gemoji/images/1f425.png | Bin 0 -> 5646 bytes vendor/gemoji/images/1f426.png | Bin 0 -> 4878 bytes vendor/gemoji/images/1f427.png | Bin 0 -> 4746 bytes vendor/gemoji/images/1f428.png | Bin 0 -> 5687 bytes vendor/gemoji/images/1f429.png | Bin 0 -> 6852 bytes vendor/gemoji/images/1f42a.png | Bin 0 -> 5139 bytes vendor/gemoji/images/1f42b.png | Bin 0 -> 4485 bytes vendor/gemoji/images/1f42c.png | Bin 0 -> 4343 bytes vendor/gemoji/images/1f42d.png | Bin 0 -> 6625 bytes vendor/gemoji/images/1f42e.png | Bin 0 -> 5745 bytes vendor/gemoji/images/1f42f.png | Bin 0 -> 6051 bytes vendor/gemoji/images/1f430.png | Bin 0 -> 5677 bytes vendor/gemoji/images/1f431.png | Bin 0 -> 5987 bytes vendor/gemoji/images/1f432.png | Bin 0 -> 6737 bytes vendor/gemoji/images/1f433.png | Bin 0 -> 4940 bytes vendor/gemoji/images/1f434.png | Bin 0 -> 4582 bytes vendor/gemoji/images/1f435.png | Bin 0 -> 5348 bytes vendor/gemoji/images/1f436.png | Bin 0 -> 5945 bytes vendor/gemoji/images/1f437.png | Bin 0 -> 5996 bytes vendor/gemoji/images/1f438.png | Bin 0 -> 4823 bytes vendor/gemoji/images/1f439.png | Bin 0 -> 7371 bytes vendor/gemoji/images/1f43a.png | Bin 0 -> 4845 bytes vendor/gemoji/images/1f43b.png | Bin 0 -> 5561 bytes vendor/gemoji/images/1f43c.png | Bin 0 -> 4814 bytes vendor/gemoji/images/1f43d.png | Bin 0 -> 4761 bytes vendor/gemoji/images/1f43e.png | Bin 0 -> 2471 bytes vendor/gemoji/images/1f440.png | Bin 0 -> 4398 bytes vendor/gemoji/images/1f442.png | Bin 0 -> 4335 bytes vendor/gemoji/images/1f443.png | Bin 0 -> 3703 bytes vendor/gemoji/images/1f444.png | Bin 0 -> 3738 bytes vendor/gemoji/images/1f445.png | Bin 0 -> 3662 bytes vendor/gemoji/images/1f446.png | Bin 0 -> 3207 bytes vendor/gemoji/images/1f447.png | Bin 0 -> 3225 bytes vendor/gemoji/images/1f448.png | Bin 0 -> 3113 bytes vendor/gemoji/images/1f449.png | Bin 0 -> 3122 bytes vendor/gemoji/images/1f44a.png | Bin 0 -> 4873 bytes vendor/gemoji/images/1f44b.png | Bin 0 -> 5048 bytes vendor/gemoji/images/1f44c.png | Bin 0 -> 4696 bytes vendor/gemoji/images/1f44d.png | Bin 0 -> 5135 bytes vendor/gemoji/images/1f44e.png | Bin 0 -> 5129 bytes vendor/gemoji/images/1f44f.png | Bin 0 -> 7110 bytes vendor/gemoji/images/1f450.png | Bin 0 -> 4951 bytes vendor/gemoji/images/1f451.png | Bin 0 -> 5655 bytes vendor/gemoji/images/1f452.png | Bin 0 -> 8101 bytes vendor/gemoji/images/1f453.png | Bin 0 -> 4929 bytes vendor/gemoji/images/1f454.png | Bin 0 -> 6116 bytes vendor/gemoji/images/1f455.png | Bin 0 -> 4676 bytes vendor/gemoji/images/1f456.png | Bin 0 -> 3470 bytes vendor/gemoji/images/1f457.png | Bin 0 -> 3631 bytes vendor/gemoji/images/1f458.png | Bin 0 -> 4938 bytes vendor/gemoji/images/1f459.png | Bin 0 -> 3890 bytes vendor/gemoji/images/1f45a.png | Bin 0 -> 4075 bytes vendor/gemoji/images/1f45b.png | Bin 0 -> 5033 bytes vendor/gemoji/images/1f45c.png | Bin 0 -> 5449 bytes vendor/gemoji/images/1f45d.png | Bin 0 -> 4691 bytes vendor/gemoji/images/1f45e.png | Bin 0 -> 4749 bytes vendor/gemoji/images/1f45f.png | Bin 0 -> 4799 bytes vendor/gemoji/images/1f460.png | Bin 0 -> 4557 bytes vendor/gemoji/images/1f461.png | Bin 0 -> 4061 bytes vendor/gemoji/images/1f462.png | Bin 0 -> 3327 bytes vendor/gemoji/images/1f463.png | Bin 0 -> 1604 bytes vendor/gemoji/images/1f464.png | Bin 0 -> 2007 bytes vendor/gemoji/images/1f465.png | Bin 0 -> 3021 bytes vendor/gemoji/images/1f466.png | Bin 0 -> 5946 bytes vendor/gemoji/images/1f467.png | Bin 0 -> 6314 bytes vendor/gemoji/images/1f468.png | Bin 0 -> 6023 bytes vendor/gemoji/images/1f469.png | Bin 0 -> 6895 bytes vendor/gemoji/images/1f46a.png | Bin 0 -> 7211 bytes vendor/gemoji/images/1f46b.png | Bin 0 -> 7615 bytes vendor/gemoji/images/1f46c.png | Bin 0 -> 6994 bytes vendor/gemoji/images/1f46d.png | Bin 0 -> 7633 bytes vendor/gemoji/images/1f46e.png | Bin 0 -> 7141 bytes vendor/gemoji/images/1f46f.png | Bin 0 -> 7918 bytes vendor/gemoji/images/1f470.png | Bin 0 -> 8515 bytes vendor/gemoji/images/1f471.png | Bin 0 -> 6622 bytes vendor/gemoji/images/1f472.png | Bin 0 -> 5324 bytes vendor/gemoji/images/1f473.png | Bin 0 -> 6528 bytes vendor/gemoji/images/1f474.png | Bin 0 -> 6733 bytes vendor/gemoji/images/1f475.png | Bin 0 -> 5977 bytes vendor/gemoji/images/1f476.png | Bin 0 -> 5921 bytes vendor/gemoji/images/1f477.png | Bin 0 -> 6193 bytes vendor/gemoji/images/1f478.png | Bin 0 -> 7920 bytes vendor/gemoji/images/1f479.png | Bin 0 -> 7147 bytes vendor/gemoji/images/1f47a.png | Bin 0 -> 5159 bytes vendor/gemoji/images/1f47b.png | Bin 0 -> 4513 bytes vendor/gemoji/images/1f47c.png | Bin 0 -> 6672 bytes vendor/gemoji/images/1f47d.png | Bin 0 -> 5478 bytes vendor/gemoji/images/1f47e.png | Bin 0 -> 4353 bytes vendor/gemoji/images/1f47f.png | Bin 0 -> 6652 bytes vendor/gemoji/images/1f480.png | Bin 0 -> 2428 bytes vendor/gemoji/images/1f481.png | Bin 0 -> 6605 bytes vendor/gemoji/images/1f482.png | Bin 0 -> 3587 bytes vendor/gemoji/images/1f483.png | Bin 0 -> 3737 bytes vendor/gemoji/images/1f484.png | Bin 0 -> 3384 bytes vendor/gemoji/images/1f485.png | Bin 0 -> 5814 bytes vendor/gemoji/images/1f486.png | Bin 0 -> 6036 bytes vendor/gemoji/images/1f487.png | Bin 0 -> 7100 bytes vendor/gemoji/images/1f488.png | Bin 0 -> 4252 bytes vendor/gemoji/images/1f489.png | Bin 0 -> 3078 bytes vendor/gemoji/images/1f48a.png | Bin 0 -> 5022 bytes vendor/gemoji/images/1f48b.png | Bin 0 -> 6295 bytes vendor/gemoji/images/1f48c.png | Bin 0 -> 2467 bytes vendor/gemoji/images/1f48d.png | Bin 0 -> 5232 bytes vendor/gemoji/images/1f48e.png | Bin 0 -> 4855 bytes vendor/gemoji/images/1f48f.png | Bin 0 -> 7219 bytes vendor/gemoji/images/1f490.png | Bin 0 -> 6915 bytes vendor/gemoji/images/1f491.png | Bin 0 -> 7370 bytes vendor/gemoji/images/1f492.png | Bin 0 -> 5847 bytes vendor/gemoji/images/1f493.png | Bin 0 -> 4052 bytes vendor/gemoji/images/1f494.png | Bin 0 -> 4118 bytes vendor/gemoji/images/1f495.png | Bin 0 -> 3565 bytes vendor/gemoji/images/1f496.png | Bin 0 -> 8002 bytes vendor/gemoji/images/1f497.png | Bin 0 -> 6269 bytes vendor/gemoji/images/1f498.png | Bin 0 -> 5413 bytes vendor/gemoji/images/1f499.png | Bin 0 -> 4094 bytes vendor/gemoji/images/1f49a.png | Bin 0 -> 4432 bytes vendor/gemoji/images/1f49b.png | Bin 0 -> 4414 bytes vendor/gemoji/images/1f49c.png | Bin 0 -> 4295 bytes vendor/gemoji/images/1f49d.png | Bin 0 -> 6013 bytes vendor/gemoji/images/1f49e.png | Bin 0 -> 5472 bytes vendor/gemoji/images/1f49f.png | Bin 0 -> 3534 bytes vendor/gemoji/images/1f4a0.png | Bin 0 -> 5698 bytes vendor/gemoji/images/1f4a1.png | Bin 0 -> 4490 bytes vendor/gemoji/images/1f4a2.png | Bin 0 -> 3079 bytes vendor/gemoji/images/1f4a3.png | Bin 0 -> 5208 bytes vendor/gemoji/images/1f4a4.png | Bin 0 -> 2027 bytes vendor/gemoji/images/1f4a5.png | Bin 0 -> 3781 bytes vendor/gemoji/images/1f4a6.png | Bin 0 -> 4782 bytes vendor/gemoji/images/1f4a7.png | Bin 0 -> 3278 bytes vendor/gemoji/images/1f4a8.png | Bin 0 -> 5448 bytes vendor/gemoji/images/1f4a9.png | Bin 0 -> 4754 bytes vendor/gemoji/images/1f4aa.png | Bin 0 -> 4672 bytes vendor/gemoji/images/1f4ab.png | Bin 0 -> 3044 bytes vendor/gemoji/images/1f4ac.png | Bin 0 -> 2130 bytes vendor/gemoji/images/1f4ad.png | Bin 0 -> 2582 bytes vendor/gemoji/images/1f4ae.png | Bin 0 -> 4391 bytes vendor/gemoji/images/1f4af.png | Bin 0 -> 3302 bytes vendor/gemoji/images/1f4b0.png | Bin 0 -> 5500 bytes vendor/gemoji/images/1f4b1.png | Bin 0 -> 1981 bytes vendor/gemoji/images/1f4b2.png | Bin 0 -> 1416 bytes vendor/gemoji/images/1f4b3.png | Bin 0 -> 2648 bytes vendor/gemoji/images/1f4b4.png | Bin 0 -> 4989 bytes vendor/gemoji/images/1f4b5.png | Bin 0 -> 4622 bytes vendor/gemoji/images/1f4b6.png | Bin 0 -> 3942 bytes vendor/gemoji/images/1f4b7.png | Bin 0 -> 4235 bytes vendor/gemoji/images/1f4b8.png | Bin 0 -> 7586 bytes vendor/gemoji/images/1f4b9.png | Bin 0 -> 4331 bytes vendor/gemoji/images/1f4ba.png | Bin 0 -> 6059 bytes vendor/gemoji/images/1f4bb.png | Bin 0 -> 1705 bytes vendor/gemoji/images/1f4bc.png | Bin 0 -> 2698 bytes vendor/gemoji/images/1f4bd.png | Bin 0 -> 5594 bytes vendor/gemoji/images/1f4be.png | Bin 0 -> 3215 bytes vendor/gemoji/images/1f4bf.png | Bin 0 -> 6718 bytes vendor/gemoji/images/1f4c0.png | Bin 0 -> 6993 bytes vendor/gemoji/images/1f4c1.png | Bin 0 -> 4013 bytes vendor/gemoji/images/1f4c2.png | Bin 0 -> 4292 bytes vendor/gemoji/images/1f4c3.png | Bin 0 -> 3729 bytes vendor/gemoji/images/1f4c4.png | Bin 0 -> 2183 bytes vendor/gemoji/images/1f4c5.png | Bin 0 -> 2977 bytes vendor/gemoji/images/1f4c6.png | Bin 0 -> 2920 bytes vendor/gemoji/images/1f4c7.png | Bin 0 -> 3749 bytes vendor/gemoji/images/1f4c8.png | Bin 0 -> 2939 bytes vendor/gemoji/images/1f4c9.png | Bin 0 -> 2910 bytes vendor/gemoji/images/1f4ca.png | Bin 0 -> 2460 bytes vendor/gemoji/images/1f4cb.png | Bin 0 -> 4663 bytes vendor/gemoji/images/1f4cc.png | Bin 0 -> 3793 bytes vendor/gemoji/images/1f4cd.png | Bin 0 -> 1936 bytes vendor/gemoji/images/1f4ce.png | Bin 0 -> 2558 bytes vendor/gemoji/images/1f4cf.png | Bin 0 -> 3832 bytes vendor/gemoji/images/1f4d0.png | Bin 0 -> 2706 bytes vendor/gemoji/images/1f4d1.png | Bin 0 -> 3162 bytes vendor/gemoji/images/1f4d2.png | Bin 0 -> 5921 bytes vendor/gemoji/images/1f4d3.png | Bin 0 -> 6036 bytes vendor/gemoji/images/1f4d4.png | Bin 0 -> 5329 bytes vendor/gemoji/images/1f4d5.png | Bin 0 -> 4847 bytes vendor/gemoji/images/1f4d6.png | Bin 0 -> 6050 bytes vendor/gemoji/images/1f4d7.png | Bin 0 -> 5090 bytes vendor/gemoji/images/1f4d8.png | Bin 0 -> 5092 bytes vendor/gemoji/images/1f4d9.png | Bin 0 -> 5085 bytes vendor/gemoji/images/1f4da.png | Bin 0 -> 6539 bytes vendor/gemoji/images/1f4db.png | Bin 0 -> 3985 bytes vendor/gemoji/images/1f4dc.png | Bin 0 -> 6749 bytes vendor/gemoji/images/1f4dd.png | Bin 0 -> 4945 bytes vendor/gemoji/images/1f4de.png | Bin 0 -> 2001 bytes vendor/gemoji/images/1f4df.png | Bin 0 -> 4022 bytes vendor/gemoji/images/1f4e0.png | Bin 0 -> 4650 bytes vendor/gemoji/images/1f4e1.png | Bin 0 -> 4867 bytes vendor/gemoji/images/1f4e2.png | Bin 0 -> 6001 bytes vendor/gemoji/images/1f4e3.png | Bin 0 -> 4821 bytes vendor/gemoji/images/1f4e4.png | Bin 0 -> 3683 bytes vendor/gemoji/images/1f4e5.png | Bin 0 -> 3700 bytes vendor/gemoji/images/1f4e6.png | Bin 0 -> 8449 bytes vendor/gemoji/images/1f4e7.png | Bin 0 -> 2128 bytes vendor/gemoji/images/1f4e8.png | Bin 0 -> 2206 bytes vendor/gemoji/images/1f4e9.png | Bin 0 -> 2697 bytes vendor/gemoji/images/1f4ea.png | Bin 0 -> 4360 bytes vendor/gemoji/images/1f4eb.png | Bin 0 -> 4196 bytes vendor/gemoji/images/1f4ec.png | Bin 0 -> 4581 bytes vendor/gemoji/images/1f4ed.png | Bin 0 -> 3101 bytes vendor/gemoji/images/1f4ee.png | Bin 0 -> 3388 bytes vendor/gemoji/images/1f4ef.png | Bin 0 -> 4819 bytes vendor/gemoji/images/1f4f0.png | Bin 0 -> 5198 bytes vendor/gemoji/images/1f4f1.png | Bin 0 -> 3499 bytes vendor/gemoji/images/1f4f2.png | Bin 0 -> 4037 bytes vendor/gemoji/images/1f4f3.png | Bin 0 -> 3906 bytes vendor/gemoji/images/1f4f4.png | Bin 0 -> 3521 bytes vendor/gemoji/images/1f4f5.png | Bin 0 -> 5083 bytes vendor/gemoji/images/1f4f6.png | Bin 0 -> 3231 bytes vendor/gemoji/images/1f4f7.png | Bin 0 -> 4661 bytes vendor/gemoji/images/1f4f9.png | Bin 0 -> 5090 bytes vendor/gemoji/images/1f4fa.png | Bin 0 -> 5242 bytes vendor/gemoji/images/1f4fb.png | Bin 0 -> 6150 bytes vendor/gemoji/images/1f4fc.png | Bin 0 -> 3145 bytes vendor/gemoji/images/1f500.png | Bin 0 -> 4313 bytes vendor/gemoji/images/1f501.png | Bin 0 -> 4009 bytes vendor/gemoji/images/1f502.png | Bin 0 -> 4287 bytes vendor/gemoji/images/1f503.png | Bin 0 -> 1399 bytes vendor/gemoji/images/1f504.png | Bin 0 -> 4823 bytes vendor/gemoji/images/1f505.png | Bin 0 -> 2498 bytes vendor/gemoji/images/1f506.png | Bin 0 -> 4060 bytes vendor/gemoji/images/1f507.png | Bin 0 -> 6635 bytes vendor/gemoji/images/1f508.png | Bin 0 -> 5309 bytes vendor/gemoji/images/1f509.png | Bin 0 -> 5024 bytes vendor/gemoji/images/1f50a.png | Bin 0 -> 7814 bytes vendor/gemoji/images/1f50b.png | Bin 0 -> 3812 bytes vendor/gemoji/images/1f50c.png | Bin 0 -> 2819 bytes vendor/gemoji/images/1f50d.png | Bin 0 -> 3040 bytes vendor/gemoji/images/1f50e.png | Bin 0 -> 3629 bytes vendor/gemoji/images/1f50f.png | Bin 0 -> 4967 bytes vendor/gemoji/images/1f510.png | Bin 0 -> 5701 bytes vendor/gemoji/images/1f511.png | Bin 0 -> 3452 bytes vendor/gemoji/images/1f512.png | Bin 0 -> 3676 bytes vendor/gemoji/images/1f513.png | Bin 0 -> 3551 bytes vendor/gemoji/images/1f514.png | Bin 0 -> 4859 bytes vendor/gemoji/images/1f515.png | Bin 0 -> 5944 bytes vendor/gemoji/images/1f516.png | Bin 0 -> 4696 bytes vendor/gemoji/images/1f517.png | Bin 0 -> 2652 bytes vendor/gemoji/images/1f518.png | Bin 0 -> 2198 bytes vendor/gemoji/images/1f519.png | Bin 0 -> 5434 bytes vendor/gemoji/images/1f51a.png | Bin 0 -> 1475 bytes vendor/gemoji/images/1f51b.png | Bin 0 -> 1806 bytes vendor/gemoji/images/1f51c.png | Bin 0 -> 1911 bytes vendor/gemoji/images/1f51d.png | Bin 0 -> 3785 bytes vendor/gemoji/images/1f51e.png | Bin 0 -> 5722 bytes vendor/gemoji/images/1f51f.png | Bin 0 -> 4095 bytes vendor/gemoji/images/1f520.png | Bin 0 -> 5136 bytes vendor/gemoji/images/1f521.png | Bin 0 -> 4471 bytes vendor/gemoji/images/1f522.png | Bin 0 -> 4751 bytes vendor/gemoji/images/1f523.png | Bin 0 -> 5434 bytes vendor/gemoji/images/1f524.png | Bin 0 -> 4247 bytes vendor/gemoji/images/1f525.png | Bin 0 -> 3886 bytes vendor/gemoji/images/1f526.png | Bin 0 -> 5024 bytes vendor/gemoji/images/1f527.png | Bin 0 -> 2775 bytes vendor/gemoji/images/1f528.png | Bin 0 -> 3812 bytes vendor/gemoji/images/1f529.png | Bin 0 -> 2169 bytes vendor/gemoji/images/1f52a.png | Bin 0 -> 2506 bytes vendor/gemoji/images/1f52b.png | Bin 0 -> 3161 bytes vendor/gemoji/images/1f52c.png | Bin 0 -> 4141 bytes vendor/gemoji/images/1f52d.png | Bin 0 -> 3322 bytes vendor/gemoji/images/1f52e.png | Bin 0 -> 6236 bytes vendor/gemoji/images/1f52f.png | Bin 0 -> 4859 bytes vendor/gemoji/images/1f530.png | Bin 0 -> 2761 bytes vendor/gemoji/images/1f531.png | Bin 0 -> 4833 bytes vendor/gemoji/images/1f532.png | Bin 0 -> 3599 bytes vendor/gemoji/images/1f533.png | Bin 0 -> 4113 bytes vendor/gemoji/images/1f534.png | Bin 0 -> 3946 bytes vendor/gemoji/images/1f535.png | Bin 0 -> 4637 bytes vendor/gemoji/images/1f536.png | Bin 0 -> 3899 bytes vendor/gemoji/images/1f537.png | Bin 0 -> 3790 bytes vendor/gemoji/images/1f538.png | Bin 0 -> 1944 bytes vendor/gemoji/images/1f539.png | Bin 0 -> 1898 bytes vendor/gemoji/images/1f53a.png | Bin 0 -> 2054 bytes vendor/gemoji/images/1f53b.png | Bin 0 -> 2157 bytes vendor/gemoji/images/1f53c.png | Bin 0 -> 3198 bytes vendor/gemoji/images/1f53d.png | Bin 0 -> 2934 bytes vendor/gemoji/images/1f550.png | Bin 0 -> 2641 bytes vendor/gemoji/images/1f551.png | Bin 0 -> 2651 bytes vendor/gemoji/images/1f552.png | Bin 0 -> 2544 bytes vendor/gemoji/images/1f553.png | Bin 0 -> 2684 bytes vendor/gemoji/images/1f554.png | Bin 0 -> 2664 bytes vendor/gemoji/images/1f555.png | Bin 0 -> 2630 bytes vendor/gemoji/images/1f556.png | Bin 0 -> 2667 bytes vendor/gemoji/images/1f557.png | Bin 0 -> 2661 bytes vendor/gemoji/images/1f558.png | Bin 0 -> 2543 bytes vendor/gemoji/images/1f559.png | Bin 0 -> 2639 bytes vendor/gemoji/images/1f55a.png | Bin 0 -> 2633 bytes vendor/gemoji/images/1f55b.png | Bin 0 -> 2556 bytes vendor/gemoji/images/1f55c.png | Bin 0 -> 2842 bytes vendor/gemoji/images/1f55d.png | Bin 0 -> 2853 bytes vendor/gemoji/images/1f55e.png | Bin 0 -> 2739 bytes vendor/gemoji/images/1f55f.png | Bin 0 -> 2847 bytes vendor/gemoji/images/1f560.png | Bin 0 -> 2832 bytes vendor/gemoji/images/1f561.png | Bin 0 -> 2730 bytes vendor/gemoji/images/1f562.png | Bin 0 -> 2820 bytes vendor/gemoji/images/1f563.png | Bin 0 -> 2847 bytes vendor/gemoji/images/1f564.png | Bin 0 -> 2746 bytes vendor/gemoji/images/1f565.png | Bin 0 -> 2864 bytes vendor/gemoji/images/1f566.png | Bin 0 -> 2854 bytes vendor/gemoji/images/1f567.png | Bin 0 -> 2797 bytes vendor/gemoji/images/1f5fb.png | Bin 0 -> 5004 bytes vendor/gemoji/images/1f5fc.png | Bin 0 -> 4802 bytes vendor/gemoji/images/1f5fd.png | Bin 0 -> 6075 bytes vendor/gemoji/images/1f5fe.png | Bin 0 -> 4085 bytes vendor/gemoji/images/1f5ff.png | Bin 0 -> 2166 bytes vendor/gemoji/images/1f600.png | Bin 0 -> 8098 bytes vendor/gemoji/images/1f601.png | Bin 0 -> 5721 bytes vendor/gemoji/images/1f602.png | Bin 0 -> 6339 bytes vendor/gemoji/images/1f603.png | Bin 0 -> 5794 bytes vendor/gemoji/images/1f604.png | Bin 0 -> 5890 bytes vendor/gemoji/images/1f605.png | Bin 0 -> 6519 bytes vendor/gemoji/images/1f606.png | Bin 0 -> 6347 bytes vendor/gemoji/images/1f607.png | Bin 0 -> 7000 bytes vendor/gemoji/images/1f608.png | Bin 0 -> 7189 bytes vendor/gemoji/images/1f609.png | Bin 0 -> 5253 bytes vendor/gemoji/images/1f60a.png | Bin 0 -> 5284 bytes vendor/gemoji/images/1f60b.png | Bin 0 -> 5886 bytes vendor/gemoji/images/1f60c.png | Bin 0 -> 5440 bytes vendor/gemoji/images/1f60d.png | Bin 0 -> 5758 bytes vendor/gemoji/images/1f60e.png | Bin 0 -> 5749 bytes vendor/gemoji/images/1f60f.png | Bin 0 -> 5307 bytes vendor/gemoji/images/1f610.png | Bin 0 -> 4843 bytes vendor/gemoji/images/1f611.png | Bin 0 -> 6669 bytes vendor/gemoji/images/1f612.png | Bin 0 -> 5315 bytes vendor/gemoji/images/1f613.png | Bin 0 -> 5576 bytes vendor/gemoji/images/1f614.png | Bin 0 -> 5119 bytes vendor/gemoji/images/1f615.png | Bin 0 -> 7306 bytes vendor/gemoji/images/1f616.png | Bin 0 -> 5881 bytes vendor/gemoji/images/1f617.png | Bin 0 -> 7431 bytes vendor/gemoji/images/1f618.png | Bin 0 -> 5767 bytes vendor/gemoji/images/1f619.png | Bin 0 -> 7619 bytes vendor/gemoji/images/1f61a.png | Bin 0 -> 5563 bytes vendor/gemoji/images/1f61b.png | Bin 0 -> 7825 bytes vendor/gemoji/images/1f61c.png | Bin 0 -> 6007 bytes vendor/gemoji/images/1f61d.png | Bin 0 -> 5785 bytes vendor/gemoji/images/1f61e.png | Bin 0 -> 4764 bytes vendor/gemoji/images/1f61f.png | Bin 0 -> 8022 bytes vendor/gemoji/images/1f620.png | Bin 0 -> 5088 bytes vendor/gemoji/images/1f621.png | Bin 0 -> 5410 bytes vendor/gemoji/images/1f622.png | Bin 0 -> 5699 bytes vendor/gemoji/images/1f623.png | Bin 0 -> 5540 bytes vendor/gemoji/images/1f624.png | Bin 0 -> 6164 bytes vendor/gemoji/images/1f625.png | Bin 0 -> 5648 bytes vendor/gemoji/images/1f626.png | Bin 0 -> 7361 bytes vendor/gemoji/images/1f627.png | Bin 0 -> 7902 bytes vendor/gemoji/images/1f628.png | Bin 0 -> 5600 bytes vendor/gemoji/images/1f629.png | Bin 0 -> 6279 bytes vendor/gemoji/images/1f62a.png | Bin 0 -> 5837 bytes vendor/gemoji/images/1f62b.png | Bin 0 -> 6178 bytes vendor/gemoji/images/1f62c.png | Bin 0 -> 7928 bytes vendor/gemoji/images/1f62d.png | Bin 0 -> 5730 bytes vendor/gemoji/images/1f62e.png | Bin 0 -> 7121 bytes vendor/gemoji/images/1f62f.png | Bin 0 -> 7760 bytes vendor/gemoji/images/1f630.png | Bin 0 -> 5972 bytes vendor/gemoji/images/1f631.png | Bin 0 -> 6503 bytes vendor/gemoji/images/1f632.png | Bin 0 -> 6043 bytes vendor/gemoji/images/1f633.png | Bin 0 -> 5866 bytes vendor/gemoji/images/1f634.png | Bin 0 -> 8084 bytes vendor/gemoji/images/1f635.png | Bin 0 -> 6278 bytes vendor/gemoji/images/1f636.png | Bin 0 -> 4732 bytes vendor/gemoji/images/1f637.png | Bin 0 -> 5235 bytes vendor/gemoji/images/1f638.png | Bin 0 -> 6117 bytes vendor/gemoji/images/1f639.png | Bin 0 -> 7190 bytes vendor/gemoji/images/1f63a.png | Bin 0 -> 6083 bytes vendor/gemoji/images/1f63b.png | Bin 0 -> 6176 bytes vendor/gemoji/images/1f63c.png | Bin 0 -> 6062 bytes vendor/gemoji/images/1f63d.png | Bin 0 -> 6801 bytes vendor/gemoji/images/1f63e.png | Bin 0 -> 4918 bytes vendor/gemoji/images/1f63f.png | Bin 0 -> 6682 bytes vendor/gemoji/images/1f640.png | Bin 0 -> 6844 bytes vendor/gemoji/images/1f645.png | Bin 0 -> 7034 bytes vendor/gemoji/images/1f646.png | Bin 0 -> 7527 bytes vendor/gemoji/images/1f647.png | Bin 0 -> 5143 bytes vendor/gemoji/images/1f648.png | Bin 0 -> 6828 bytes vendor/gemoji/images/1f649.png | Bin 0 -> 6550 bytes vendor/gemoji/images/1f64a.png | Bin 0 -> 5977 bytes vendor/gemoji/images/1f64b.png | Bin 0 -> 6177 bytes vendor/gemoji/images/1f64c.png | Bin 0 -> 5375 bytes vendor/gemoji/images/1f64d.png | Bin 0 -> 4826 bytes vendor/gemoji/images/1f64e.png | Bin 0 -> 5428 bytes vendor/gemoji/images/1f64f.png | Bin 0 -> 6203 bytes vendor/gemoji/images/1f680.png | Bin 0 -> 5388 bytes vendor/gemoji/images/1f681.png | Bin 0 -> 4100 bytes vendor/gemoji/images/1f682.png | Bin 0 -> 5159 bytes vendor/gemoji/images/1f683.png | Bin 0 -> 3648 bytes vendor/gemoji/images/1f684.png | Bin 0 -> 3842 bytes vendor/gemoji/images/1f685.png | Bin 0 -> 4992 bytes vendor/gemoji/images/1f686.png | Bin 0 -> 4817 bytes vendor/gemoji/images/1f687.png | Bin 0 -> 3423 bytes vendor/gemoji/images/1f688.png | Bin 0 -> 3792 bytes vendor/gemoji/images/1f689.png | Bin 0 -> 4836 bytes vendor/gemoji/images/1f68a.png | Bin 0 -> 4869 bytes vendor/gemoji/images/1f68b.png | Bin 0 -> 2904 bytes vendor/gemoji/images/1f68c.png | Bin 0 -> 4065 bytes vendor/gemoji/images/1f68d.png | Bin 0 -> 5305 bytes vendor/gemoji/images/1f68e.png | Bin 0 -> 4431 bytes vendor/gemoji/images/1f68f.png | Bin 0 -> 1715 bytes vendor/gemoji/images/1f690.png | Bin 0 -> 3113 bytes vendor/gemoji/images/1f691.png | Bin 0 -> 3708 bytes vendor/gemoji/images/1f692.png | Bin 0 -> 4862 bytes vendor/gemoji/images/1f693.png | Bin 0 -> 3349 bytes vendor/gemoji/images/1f694.png | Bin 0 -> 5683 bytes vendor/gemoji/images/1f695.png | Bin 0 -> 3744 bytes vendor/gemoji/images/1f696.png | Bin 0 -> 6287 bytes vendor/gemoji/images/1f697.png | Bin 0 -> 4278 bytes vendor/gemoji/images/1f698.png | Bin 0 -> 7469 bytes vendor/gemoji/images/1f699.png | Bin 0 -> 4081 bytes vendor/gemoji/images/1f69a.png | Bin 0 -> 3721 bytes vendor/gemoji/images/1f69b.png | Bin 0 -> 2938 bytes vendor/gemoji/images/1f69c.png | Bin 0 -> 5671 bytes vendor/gemoji/images/1f69d.png | Bin 0 -> 4311 bytes vendor/gemoji/images/1f69e.png | Bin 0 -> 7448 bytes vendor/gemoji/images/1f69f.png | Bin 0 -> 3937 bytes vendor/gemoji/images/1f6a0.png | Bin 0 -> 4405 bytes vendor/gemoji/images/1f6a1.png | Bin 0 -> 3489 bytes vendor/gemoji/images/1f6a2.png | Bin 0 -> 4233 bytes vendor/gemoji/images/1f6a3.png | Bin 0 -> 5433 bytes vendor/gemoji/images/1f6a4.png | Bin 0 -> 3512 bytes vendor/gemoji/images/1f6a5.png | Bin 0 -> 3603 bytes vendor/gemoji/images/1f6a6.png | Bin 0 -> 3422 bytes vendor/gemoji/images/1f6a7.png | Bin 0 -> 3700 bytes vendor/gemoji/images/1f6a8.png | Bin 0 -> 6620 bytes vendor/gemoji/images/1f6a9.png | Bin 0 -> 1399 bytes vendor/gemoji/images/1f6aa.png | Bin 0 -> 3310 bytes vendor/gemoji/images/1f6ab.png | Bin 0 -> 3288 bytes vendor/gemoji/images/1f6ac.png | Bin 0 -> 2875 bytes vendor/gemoji/images/1f6ad.png | Bin 0 -> 4228 bytes vendor/gemoji/images/1f6ae.png | Bin 0 -> 4091 bytes vendor/gemoji/images/1f6af.png | Bin 0 -> 5277 bytes vendor/gemoji/images/1f6b0.png | Bin 0 -> 3934 bytes vendor/gemoji/images/1f6b1.png | Bin 0 -> 5202 bytes vendor/gemoji/images/1f6b2.png | Bin 0 -> 4722 bytes vendor/gemoji/images/1f6b3.png | Bin 0 -> 5661 bytes vendor/gemoji/images/1f6b4.png | Bin 0 -> 6484 bytes vendor/gemoji/images/1f6b5.png | Bin 0 -> 9511 bytes vendor/gemoji/images/1f6b6.png | Bin 0 -> 2519 bytes vendor/gemoji/images/1f6b7.png | Bin 0 -> 5487 bytes vendor/gemoji/images/1f6b8.png | Bin 0 -> 3460 bytes vendor/gemoji/images/1f6b9.png | Bin 0 -> 3368 bytes vendor/gemoji/images/1f6ba.png | Bin 0 -> 3908 bytes vendor/gemoji/images/1f6bb.png | Bin 0 -> 4162 bytes vendor/gemoji/images/1f6bc.png | Bin 0 -> 2967 bytes vendor/gemoji/images/1f6bd.png | Bin 0 -> 1733 bytes vendor/gemoji/images/1f6be.png | Bin 0 -> 4088 bytes vendor/gemoji/images/1f6bf.png | Bin 0 -> 7583 bytes vendor/gemoji/images/1f6c0.png | Bin 0 -> 3210 bytes vendor/gemoji/images/1f6c1.png | Bin 0 -> 2784 bytes vendor/gemoji/images/1f6c2.png | Bin 0 -> 4018 bytes vendor/gemoji/images/1f6c3.png | Bin 0 -> 3899 bytes vendor/gemoji/images/1f6c4.png | Bin 0 -> 3502 bytes vendor/gemoji/images/1f6c5.png | Bin 0 -> 4025 bytes vendor/gemoji/images/203c-fe0f.png | Bin 0 -> 1387 bytes vendor/gemoji/images/203c.png | Bin 0 -> 1387 bytes vendor/gemoji/images/2049-fe0f.png | Bin 0 -> 2875 bytes vendor/gemoji/images/2049.png | Bin 0 -> 2875 bytes vendor/gemoji/images/2122.png | Bin 0 -> 870 bytes vendor/gemoji/images/2139-fe0f.png | Bin 0 -> 3670 bytes vendor/gemoji/images/2139.png | Bin 0 -> 3670 bytes vendor/gemoji/images/2194-fe0f.png | Bin 0 -> 3413 bytes vendor/gemoji/images/2194.png | Bin 0 -> 3413 bytes vendor/gemoji/images/2195-fe0f.png | Bin 0 -> 3544 bytes vendor/gemoji/images/2195.png | Bin 0 -> 3544 bytes vendor/gemoji/images/2196-fe0f.png | Bin 0 -> 3240 bytes vendor/gemoji/images/2196.png | Bin 0 -> 3240 bytes vendor/gemoji/images/2197-fe0f.png | Bin 0 -> 3249 bytes vendor/gemoji/images/2197.png | Bin 0 -> 3249 bytes vendor/gemoji/images/2198-fe0f.png | Bin 0 -> 3351 bytes vendor/gemoji/images/2198.png | Bin 0 -> 3351 bytes vendor/gemoji/images/2199-fe0f.png | Bin 0 -> 3360 bytes vendor/gemoji/images/2199.png | Bin 0 -> 3360 bytes vendor/gemoji/images/21a9-fe0f.png | Bin 0 -> 3775 bytes vendor/gemoji/images/21a9.png | Bin 0 -> 3775 bytes vendor/gemoji/images/21aa-fe0f.png | Bin 0 -> 3712 bytes vendor/gemoji/images/21aa.png | Bin 0 -> 3712 bytes vendor/gemoji/images/231a-fe0f.png | Bin 0 -> 5189 bytes vendor/gemoji/images/231a.png | Bin 0 -> 5189 bytes vendor/gemoji/images/231b-fe0f.png | Bin 0 -> 4492 bytes vendor/gemoji/images/231b.png | Bin 0 -> 4492 bytes vendor/gemoji/images/23e9.png | Bin 0 -> 3124 bytes vendor/gemoji/images/23ea.png | Bin 0 -> 3068 bytes vendor/gemoji/images/23eb.png | Bin 0 -> 3613 bytes vendor/gemoji/images/23ec.png | Bin 0 -> 3179 bytes vendor/gemoji/images/23f0.png | Bin 0 -> 7062 bytes vendor/gemoji/images/23f3.png | Bin 0 -> 6765 bytes vendor/gemoji/images/24c2-fe0f.png | Bin 0 -> 4737 bytes vendor/gemoji/images/24c2.png | Bin 0 -> 4737 bytes vendor/gemoji/images/25aa-fe0f.png | Bin 0 -> 3061 bytes vendor/gemoji/images/25aa.png | Bin 0 -> 3061 bytes vendor/gemoji/images/25ab-fe0f.png | Bin 0 -> 3068 bytes vendor/gemoji/images/25ab.png | Bin 0 -> 3068 bytes vendor/gemoji/images/25b6-fe0f.png | Bin 0 -> 3201 bytes vendor/gemoji/images/25b6.png | Bin 0 -> 3201 bytes vendor/gemoji/images/25c0-fe0f.png | Bin 0 -> 3202 bytes vendor/gemoji/images/25c0.png | Bin 0 -> 3202 bytes vendor/gemoji/images/25fb-fe0f.png | Bin 0 -> 4192 bytes vendor/gemoji/images/25fb.png | Bin 0 -> 4192 bytes vendor/gemoji/images/25fc-fe0f.png | Bin 0 -> 4035 bytes vendor/gemoji/images/25fc.png | Bin 0 -> 4035 bytes vendor/gemoji/images/25fd-fe0f.png | Bin 0 -> 3598 bytes vendor/gemoji/images/25fd.png | Bin 0 -> 3598 bytes vendor/gemoji/images/25fe-fe0f.png | Bin 0 -> 3495 bytes vendor/gemoji/images/25fe.png | Bin 0 -> 3495 bytes vendor/gemoji/images/2600-fe0f.png | Bin 0 -> 3802 bytes vendor/gemoji/images/2600.png | Bin 0 -> 3802 bytes vendor/gemoji/images/2601-fe0f.png | Bin 0 -> 3860 bytes vendor/gemoji/images/2601.png | Bin 0 -> 3860 bytes vendor/gemoji/images/260e-fe0f.png | Bin 0 -> 5495 bytes vendor/gemoji/images/260e.png | Bin 0 -> 5495 bytes vendor/gemoji/images/2611-fe0f.png | Bin 0 -> 1829 bytes vendor/gemoji/images/2611.png | Bin 0 -> 1829 bytes vendor/gemoji/images/2614-fe0f.png | Bin 0 -> 4745 bytes vendor/gemoji/images/2614.png | Bin 0 -> 4745 bytes vendor/gemoji/images/2615-fe0f.png | Bin 0 -> 4306 bytes vendor/gemoji/images/2615.png | Bin 0 -> 4306 bytes vendor/gemoji/images/261d-fe0f.png | Bin 0 -> 3431 bytes vendor/gemoji/images/261d.png | Bin 0 -> 3431 bytes vendor/gemoji/images/263a-fe0f.png | Bin 0 -> 5455 bytes vendor/gemoji/images/263a.png | Bin 0 -> 5455 bytes vendor/gemoji/images/2648-fe0f.png | Bin 0 -> 4359 bytes vendor/gemoji/images/2648.png | Bin 0 -> 4359 bytes vendor/gemoji/images/2649-fe0f.png | Bin 0 -> 4733 bytes vendor/gemoji/images/2649.png | Bin 0 -> 4733 bytes vendor/gemoji/images/264a-fe0f.png | Bin 0 -> 4296 bytes vendor/gemoji/images/264a.png | Bin 0 -> 4296 bytes vendor/gemoji/images/264b-fe0f.png | Bin 0 -> 5384 bytes vendor/gemoji/images/264b.png | Bin 0 -> 5384 bytes vendor/gemoji/images/264c-fe0f.png | Bin 0 -> 4913 bytes vendor/gemoji/images/264c.png | Bin 0 -> 4913 bytes vendor/gemoji/images/264d-fe0f.png | Bin 0 -> 4869 bytes vendor/gemoji/images/264d.png | Bin 0 -> 4869 bytes vendor/gemoji/images/264e-fe0f.png | Bin 0 -> 4229 bytes vendor/gemoji/images/264e.png | Bin 0 -> 4229 bytes vendor/gemoji/images/264f-fe0f.png | Bin 0 -> 4566 bytes vendor/gemoji/images/264f.png | Bin 0 -> 4566 bytes vendor/gemoji/images/2650-fe0f.png | Bin 0 -> 4505 bytes vendor/gemoji/images/2650.png | Bin 0 -> 4505 bytes vendor/gemoji/images/2651-fe0f.png | Bin 0 -> 4670 bytes vendor/gemoji/images/2651.png | Bin 0 -> 4670 bytes vendor/gemoji/images/2652-fe0f.png | Bin 0 -> 5096 bytes vendor/gemoji/images/2652.png | Bin 0 -> 5096 bytes vendor/gemoji/images/2653-fe0f.png | Bin 0 -> 4458 bytes vendor/gemoji/images/2653.png | Bin 0 -> 4458 bytes vendor/gemoji/images/2660-fe0f.png | Bin 0 -> 1719 bytes vendor/gemoji/images/2660.png | Bin 0 -> 1719 bytes vendor/gemoji/images/2663-fe0f.png | Bin 0 -> 1685 bytes vendor/gemoji/images/2663.png | Bin 0 -> 1685 bytes vendor/gemoji/images/2665-fe0f.png | Bin 0 -> 2925 bytes vendor/gemoji/images/2665.png | Bin 0 -> 2925 bytes vendor/gemoji/images/2666-fe0f.png | Bin 0 -> 2785 bytes vendor/gemoji/images/2666.png | Bin 0 -> 2785 bytes vendor/gemoji/images/2668-fe0f.png | Bin 0 -> 3538 bytes vendor/gemoji/images/2668.png | Bin 0 -> 3538 bytes vendor/gemoji/images/267b-fe0f.png | Bin 0 -> 3704 bytes vendor/gemoji/images/267b.png | Bin 0 -> 3704 bytes vendor/gemoji/images/267f-fe0f.png | Bin 0 -> 4224 bytes vendor/gemoji/images/267f.png | Bin 0 -> 4224 bytes vendor/gemoji/images/2693-fe0f.png | Bin 0 -> 4479 bytes vendor/gemoji/images/2693.png | Bin 0 -> 4479 bytes vendor/gemoji/images/26a0-fe0f.png | Bin 0 -> 3177 bytes vendor/gemoji/images/26a0.png | Bin 0 -> 3177 bytes vendor/gemoji/images/26a1-fe0f.png | Bin 0 -> 2233 bytes vendor/gemoji/images/26a1.png | Bin 0 -> 2233 bytes vendor/gemoji/images/26aa-fe0f.png | Bin 0 -> 2506 bytes vendor/gemoji/images/26aa.png | Bin 0 -> 2506 bytes vendor/gemoji/images/26ab-fe0f.png | Bin 0 -> 2369 bytes vendor/gemoji/images/26ab.png | Bin 0 -> 2369 bytes vendor/gemoji/images/26bd-fe0f.png | Bin 0 -> 4878 bytes vendor/gemoji/images/26bd.png | Bin 0 -> 4878 bytes vendor/gemoji/images/26be-fe0f.png | Bin 0 -> 6032 bytes vendor/gemoji/images/26be.png | Bin 0 -> 6032 bytes vendor/gemoji/images/26c4-fe0f.png | Bin 0 -> 4658 bytes vendor/gemoji/images/26c4.png | Bin 0 -> 4658 bytes vendor/gemoji/images/26c5-fe0f.png | Bin 0 -> 5181 bytes vendor/gemoji/images/26c5.png | Bin 0 -> 5181 bytes vendor/gemoji/images/26ce.png | Bin 0 -> 4434 bytes vendor/gemoji/images/26d4-fe0f.png | Bin 0 -> 3514 bytes vendor/gemoji/images/26d4.png | Bin 0 -> 3514 bytes vendor/gemoji/images/26ea-fe0f.png | Bin 0 -> 4653 bytes vendor/gemoji/images/26ea.png | Bin 0 -> 4653 bytes vendor/gemoji/images/26f2-fe0f.png | Bin 0 -> 5087 bytes vendor/gemoji/images/26f2.png | Bin 0 -> 5087 bytes vendor/gemoji/images/26f3-fe0f.png | Bin 0 -> 3548 bytes vendor/gemoji/images/26f3.png | Bin 0 -> 3548 bytes vendor/gemoji/images/26f5-fe0f.png | Bin 0 -> 3833 bytes vendor/gemoji/images/26f5.png | Bin 0 -> 3833 bytes vendor/gemoji/images/26fa-fe0f.png | Bin 0 -> 4482 bytes vendor/gemoji/images/26fa.png | Bin 0 -> 4482 bytes vendor/gemoji/images/26fd-fe0f.png | Bin 0 -> 4296 bytes vendor/gemoji/images/26fd.png | Bin 0 -> 4296 bytes vendor/gemoji/images/2702-fe0f.png | Bin 0 -> 3900 bytes vendor/gemoji/images/2702.png | Bin 0 -> 3900 bytes vendor/gemoji/images/2705.png | Bin 0 -> 3445 bytes vendor/gemoji/images/2708-fe0f.png | Bin 0 -> 4740 bytes vendor/gemoji/images/2708.png | Bin 0 -> 4740 bytes vendor/gemoji/images/2709-fe0f.png | Bin 0 -> 1655 bytes vendor/gemoji/images/2709.png | Bin 0 -> 1655 bytes vendor/gemoji/images/270a.png | Bin 0 -> 5880 bytes vendor/gemoji/images/270b.png | Bin 0 -> 4161 bytes vendor/gemoji/images/270c-fe0f.png | Bin 0 -> 4669 bytes vendor/gemoji/images/270c.png | Bin 0 -> 4669 bytes vendor/gemoji/images/270f-fe0f.png | Bin 0 -> 4450 bytes vendor/gemoji/images/270f.png | Bin 0 -> 4450 bytes vendor/gemoji/images/2712-fe0f.png | Bin 0 -> 2352 bytes vendor/gemoji/images/2712.png | Bin 0 -> 2352 bytes vendor/gemoji/images/2714-fe0f.png | Bin 0 -> 1103 bytes vendor/gemoji/images/2714.png | Bin 0 -> 1103 bytes vendor/gemoji/images/2716-fe0f.png | Bin 0 -> 591 bytes vendor/gemoji/images/2716.png | Bin 0 -> 591 bytes vendor/gemoji/images/2728.png | Bin 0 -> 2212 bytes vendor/gemoji/images/2733-fe0f.png | Bin 0 -> 4012 bytes vendor/gemoji/images/2733.png | Bin 0 -> 4012 bytes vendor/gemoji/images/2734-fe0f.png | Bin 0 -> 3312 bytes vendor/gemoji/images/2734.png | Bin 0 -> 3312 bytes vendor/gemoji/images/2744-fe0f.png | Bin 0 -> 5637 bytes vendor/gemoji/images/2744.png | Bin 0 -> 5637 bytes vendor/gemoji/images/2747-fe0f.png | Bin 0 -> 8904 bytes vendor/gemoji/images/2747.png | Bin 0 -> 8904 bytes vendor/gemoji/images/274c.png | Bin 0 -> 2118 bytes vendor/gemoji/images/274e.png | Bin 0 -> 3853 bytes vendor/gemoji/images/2753.png | Bin 0 -> 1740 bytes vendor/gemoji/images/2754.png | Bin 0 -> 1078 bytes vendor/gemoji/images/2755.png | Bin 0 -> 1142 bytes vendor/gemoji/images/2757-fe0f.png | Bin 0 -> 1315 bytes vendor/gemoji/images/2757.png | Bin 0 -> 1315 bytes vendor/gemoji/images/2764-fe0f.png | Bin 0 -> 3302 bytes vendor/gemoji/images/2764.png | Bin 0 -> 3302 bytes vendor/gemoji/images/2795.png | Bin 0 -> 315 bytes vendor/gemoji/images/2796.png | Bin 0 -> 197 bytes vendor/gemoji/images/2797.png | Bin 0 -> 340 bytes vendor/gemoji/images/27a1-fe0f.png | Bin 0 -> 3034 bytes vendor/gemoji/images/27a1.png | Bin 0 -> 3034 bytes vendor/gemoji/images/27b0.png | Bin 0 -> 1264 bytes vendor/gemoji/images/27bf.png | Bin 0 -> 3417 bytes vendor/gemoji/images/2934-fe0f.png | Bin 0 -> 3520 bytes vendor/gemoji/images/2934.png | Bin 0 -> 3520 bytes vendor/gemoji/images/2935-fe0f.png | Bin 0 -> 3521 bytes vendor/gemoji/images/2935.png | Bin 0 -> 3521 bytes vendor/gemoji/images/2b05-fe0f.png | Bin 0 -> 3053 bytes vendor/gemoji/images/2b05.png | Bin 0 -> 3053 bytes vendor/gemoji/images/2b06-fe0f.png | Bin 0 -> 3093 bytes vendor/gemoji/images/2b06.png | Bin 0 -> 3093 bytes vendor/gemoji/images/2b07-fe0f.png | Bin 0 -> 3024 bytes vendor/gemoji/images/2b07.png | Bin 0 -> 3024 bytes vendor/gemoji/images/2b1b-fe0f.png | Bin 0 -> 1332 bytes vendor/gemoji/images/2b1b.png | Bin 0 -> 1332 bytes vendor/gemoji/images/2b1c-fe0f.png | Bin 0 -> 1411 bytes vendor/gemoji/images/2b1c.png | Bin 0 -> 1411 bytes vendor/gemoji/images/2b50-fe0f.png | Bin 0 -> 3628 bytes vendor/gemoji/images/2b50.png | Bin 0 -> 3628 bytes vendor/gemoji/images/2b55-fe0f.png | Bin 0 -> 2542 bytes vendor/gemoji/images/2b55.png | Bin 0 -> 2542 bytes vendor/gemoji/images/3030.png | Bin 0 -> 872 bytes vendor/gemoji/images/303d-fe0f.png | Bin 0 -> 2685 bytes vendor/gemoji/images/303d.png | Bin 0 -> 2685 bytes vendor/gemoji/images/3297-fe0f.png | Bin 0 -> 4883 bytes vendor/gemoji/images/3297.png | Bin 0 -> 4883 bytes vendor/gemoji/images/3299-fe0f.png | Bin 0 -> 5364 bytes vendor/gemoji/images/3299.png | Bin 0 -> 5364 bytes .../jquery.emojiarea/jquery.emojiarea-orig.js | 458 + vendor/jquery.emojiarea/jquery.emojiarea.js | 475 + vendor/jquery.nanoscroller/nanoscroller.css | 55 + vendor/jquery.nanoscroller/nanoscroller.js | 899 + vendor/jquery/jquery.min.js | 6 + vendor/jsbn/THIRDPARTY_LICENSE | 40 + vendor/jsbn/jsbn_combined.js | 1348 + vendor/ui-bootstrap/THIRDPARTY_LICENSE | 22 + .../ui-bootstrap/ui-bootstrap-custom-0.7.0.js | 332 + .../ui-bootstrap-custom-0.7.0.min.js | 1 + .../ui-bootstrap-custom-tpls-0.7.0.js | 344 + .../ui-bootstrap-custom-tpls-0.7.0.min.js | 1 + vendor/zlib/THIRDPARTY_LICENSE | 28 + vendor/zlib/gunzip.min.js | 27 + vendor/zlib/gzip.min.js | 32 + 1326 files changed, 72013 insertions(+) create mode 100644 css/app.css create mode 100755 img/Logo_1x.png create mode 100755 img/Logo_2x.png create mode 100644 img/bg_full.png create mode 100644 img/bg_tile.png create mode 100755 img/icons/Arrow_1x.png create mode 100755 img/icons/Arrow_2x.png create mode 100755 img/icons/Attach_1x.png create mode 100755 img/icons/Attach_2x.png create mode 100755 img/icons/Attach_pressed_1x.png create mode 100755 img/icons/Attach_pressed_2x.png create mode 100755 img/icons/CheckIn_Recent.png create mode 100755 img/icons/Checks1_1x.png create mode 100644 img/icons/Checks1_2x.png create mode 100755 img/icons/Checks2_1x.png create mode 100644 img/icons/Checks2_2x.png create mode 100755 img/icons/CloseHover_1x.png create mode 100755 img/icons/CloseHover_2x.png create mode 100755 img/icons/Close_1x.png create mode 100755 img/icons/Close_2x.png create mode 100644 img/icons/DialogListGroupChatIcon@2x.png create mode 100644 img/icons/DialogListGroupChatIcon_Highlighted@2x.png create mode 100755 img/icons/DocBlue_1x.png create mode 100755 img/icons/DocBlue_2x.png create mode 100755 img/icons/DocGrey_1x.png create mode 100755 img/icons/DocGrey_2x.png create mode 100755 img/icons/Location_Active.png create mode 100755 img/icons/Logo_1x.png create mode 100755 img/icons/Logo_2x.png create mode 100755 img/icons/NoResults.png create mode 100755 img/icons/Search_1x.png create mode 100755 img/icons/Search_2x.png create mode 100755 img/icons/Smile_1x.png create mode 100755 img/icons/Smile_2x.png create mode 100755 img/icons/Smile_pressed_1x.png create mode 100755 img/icons/Smile_pressed_2x.png create mode 100755 img/icons/VideoIcon.png create mode 100644 img/icons/icon128.png create mode 100644 img/icons/icon16.png create mode 100644 img/placeholders/DialogListAvatarSystem@2x.png create mode 100755 img/placeholders/GroupAvatar1@2x.png create mode 100755 img/placeholders/GroupAvatar2@2x.png create mode 100755 img/placeholders/GroupAvatar3@2x.png create mode 100755 img/placeholders/GroupAvatar4@2x.png create mode 100755 img/placeholders/UserAvatar1@2x.png create mode 100755 img/placeholders/UserAvatar2@2x.png create mode 100755 img/placeholders/UserAvatar3@2x.png create mode 100755 img/placeholders/UserAvatar4@2x.png create mode 100755 img/placeholders/UserAvatar5@2x.png create mode 100755 img/placeholders/UserAvatar6@2x.png create mode 100755 img/placeholders/UserAvatar7@2x.png create mode 100755 img/placeholders/UserAvatar8@2x.png create mode 100644 index.html create mode 100644 js/app.js create mode 100644 js/background.js create mode 100644 js/controllers.js create mode 100644 js/directives.js create mode 100644 js/filters.js create mode 100644 js/lib/aes_worker.js create mode 100644 js/lib/config.js create mode 100644 js/lib/mtproto.js create mode 100644 js/lib/pq_worker.js create mode 100644 js/lib/sha1_worker.js create mode 100644 js/services.js create mode 100644 js/util.js create mode 100644 manifest.json create mode 100644 partials/chat_modal.html create mode 100644 partials/dialog.html create mode 100644 partials/head.html create mode 100644 partials/im.html create mode 100644 partials/login.html create mode 100644 partials/message.html create mode 100644 partials/photo_modal.html create mode 100644 partials/user_modal.html create mode 100644 partials/video_modal.html create mode 100644 partials/welcome.html create mode 100644 vendor/README.md create mode 100644 vendor/angular/angular-animate.js create mode 100644 vendor/angular/angular-animate.min.js create mode 100644 vendor/angular/angular-animate.min.js.map create mode 100644 vendor/angular/angular-cookies.js create mode 100644 vendor/angular/angular-cookies.min.js create mode 100644 vendor/angular/angular-cookies.min.js.map create mode 100644 vendor/angular/angular-csp.css create mode 100644 vendor/angular/angular-loader.js create mode 100644 vendor/angular/angular-loader.min.js create mode 100644 vendor/angular/angular-loader.min.js.map create mode 100644 vendor/angular/angular-resource.js create mode 100644 vendor/angular/angular-resource.min.js create mode 100644 vendor/angular/angular-resource.min.js.map create mode 100644 vendor/angular/angular-route.js create mode 100644 vendor/angular/angular-route.min.js create mode 100644 vendor/angular/angular-route.min.js.map create mode 100644 vendor/angular/angular-sanitize.js create mode 100644 vendor/angular/angular-sanitize.min.js create mode 100644 vendor/angular/angular-sanitize.min.js.map create mode 100644 vendor/angular/angular-touch.js create mode 100644 vendor/angular/angular-touch.min.js create mode 100644 vendor/angular/angular-touch.min.js.map create mode 100644 vendor/angular/angular.js create mode 100644 vendor/angular/angular.min.js create mode 100644 vendor/angular/angular.min.js.map create mode 100644 vendor/angular/errors.json create mode 100644 vendor/angular/i18n/angular-locale_af-na.js create mode 100644 vendor/angular/i18n/angular-locale_af-za.js create mode 100644 vendor/angular/i18n/angular-locale_af.js create mode 100644 vendor/angular/i18n/angular-locale_am-et.js create mode 100644 vendor/angular/i18n/angular-locale_am.js create mode 100644 vendor/angular/i18n/angular-locale_ar-001.js create mode 100644 vendor/angular/i18n/angular-locale_ar-ae.js create mode 100644 vendor/angular/i18n/angular-locale_ar-bh.js create mode 100644 vendor/angular/i18n/angular-locale_ar-dz.js create mode 100644 vendor/angular/i18n/angular-locale_ar-eg.js create mode 100644 vendor/angular/i18n/angular-locale_ar-iq.js create mode 100644 vendor/angular/i18n/angular-locale_ar-jo.js create mode 100644 vendor/angular/i18n/angular-locale_ar-kw.js create mode 100644 vendor/angular/i18n/angular-locale_ar-lb.js create mode 100644 vendor/angular/i18n/angular-locale_ar-ly.js create mode 100644 vendor/angular/i18n/angular-locale_ar-ma.js create mode 100644 vendor/angular/i18n/angular-locale_ar-om.js create mode 100644 vendor/angular/i18n/angular-locale_ar-qa.js create mode 100644 vendor/angular/i18n/angular-locale_ar-sa.js create mode 100644 vendor/angular/i18n/angular-locale_ar-sd.js create mode 100644 vendor/angular/i18n/angular-locale_ar-sy.js create mode 100644 vendor/angular/i18n/angular-locale_ar-tn.js create mode 100644 vendor/angular/i18n/angular-locale_ar-ye.js create mode 100644 vendor/angular/i18n/angular-locale_ar.js create mode 100644 vendor/angular/i18n/angular-locale_bg-bg.js create mode 100644 vendor/angular/i18n/angular-locale_bg.js create mode 100644 vendor/angular/i18n/angular-locale_bn-bd.js create mode 100644 vendor/angular/i18n/angular-locale_bn-in.js create mode 100644 vendor/angular/i18n/angular-locale_bn.js create mode 100644 vendor/angular/i18n/angular-locale_ca-ad.js create mode 100644 vendor/angular/i18n/angular-locale_ca-es.js create mode 100644 vendor/angular/i18n/angular-locale_ca.js create mode 100644 vendor/angular/i18n/angular-locale_cs-cz.js create mode 100644 vendor/angular/i18n/angular-locale_cs.js create mode 100644 vendor/angular/i18n/angular-locale_da-dk.js create mode 100644 vendor/angular/i18n/angular-locale_da.js create mode 100644 vendor/angular/i18n/angular-locale_de-at.js create mode 100644 vendor/angular/i18n/angular-locale_de-be.js create mode 100644 vendor/angular/i18n/angular-locale_de-ch.js create mode 100644 vendor/angular/i18n/angular-locale_de-de.js create mode 100644 vendor/angular/i18n/angular-locale_de-li.js create mode 100644 vendor/angular/i18n/angular-locale_de-lu.js create mode 100644 vendor/angular/i18n/angular-locale_de.js create mode 100644 vendor/angular/i18n/angular-locale_el-cy.js create mode 100644 vendor/angular/i18n/angular-locale_el-gr.js create mode 100644 vendor/angular/i18n/angular-locale_el.js create mode 100644 vendor/angular/i18n/angular-locale_en-as.js create mode 100644 vendor/angular/i18n/angular-locale_en-au.js create mode 100644 vendor/angular/i18n/angular-locale_en-bb.js create mode 100644 vendor/angular/i18n/angular-locale_en-be.js create mode 100644 vendor/angular/i18n/angular-locale_en-bm.js create mode 100644 vendor/angular/i18n/angular-locale_en-bw.js create mode 100644 vendor/angular/i18n/angular-locale_en-bz.js create mode 100644 vendor/angular/i18n/angular-locale_en-ca.js create mode 100644 vendor/angular/i18n/angular-locale_en-dsrt-us.js create mode 100644 vendor/angular/i18n/angular-locale_en-dsrt.js create mode 100644 vendor/angular/i18n/angular-locale_en-fm.js create mode 100644 vendor/angular/i18n/angular-locale_en-gb.js create mode 100644 vendor/angular/i18n/angular-locale_en-gu.js create mode 100644 vendor/angular/i18n/angular-locale_en-gy.js create mode 100644 vendor/angular/i18n/angular-locale_en-hk.js create mode 100644 vendor/angular/i18n/angular-locale_en-ie.js create mode 100644 vendor/angular/i18n/angular-locale_en-in.js create mode 100644 vendor/angular/i18n/angular-locale_en-iso.js create mode 100644 vendor/angular/i18n/angular-locale_en-jm.js create mode 100644 vendor/angular/i18n/angular-locale_en-mh.js create mode 100644 vendor/angular/i18n/angular-locale_en-mp.js create mode 100644 vendor/angular/i18n/angular-locale_en-mt.js create mode 100644 vendor/angular/i18n/angular-locale_en-mu.js create mode 100644 vendor/angular/i18n/angular-locale_en-na.js create mode 100644 vendor/angular/i18n/angular-locale_en-nz.js create mode 100644 vendor/angular/i18n/angular-locale_en-ph.js create mode 100644 vendor/angular/i18n/angular-locale_en-pk.js create mode 100644 vendor/angular/i18n/angular-locale_en-pr.js create mode 100644 vendor/angular/i18n/angular-locale_en-pw.js create mode 100644 vendor/angular/i18n/angular-locale_en-sg.js create mode 100644 vendor/angular/i18n/angular-locale_en-tc.js create mode 100644 vendor/angular/i18n/angular-locale_en-tt.js create mode 100644 vendor/angular/i18n/angular-locale_en-um.js create mode 100644 vendor/angular/i18n/angular-locale_en-us.js create mode 100644 vendor/angular/i18n/angular-locale_en-vg.js create mode 100644 vendor/angular/i18n/angular-locale_en-vi.js create mode 100644 vendor/angular/i18n/angular-locale_en-za.js create mode 100644 vendor/angular/i18n/angular-locale_en-zw.js create mode 100644 vendor/angular/i18n/angular-locale_en.js create mode 100644 vendor/angular/i18n/angular-locale_es-419.js create mode 100644 vendor/angular/i18n/angular-locale_es-ar.js create mode 100644 vendor/angular/i18n/angular-locale_es-bo.js create mode 100644 vendor/angular/i18n/angular-locale_es-cl.js create mode 100644 vendor/angular/i18n/angular-locale_es-co.js create mode 100644 vendor/angular/i18n/angular-locale_es-cr.js create mode 100644 vendor/angular/i18n/angular-locale_es-do.js create mode 100644 vendor/angular/i18n/angular-locale_es-ea.js create mode 100644 vendor/angular/i18n/angular-locale_es-ec.js create mode 100644 vendor/angular/i18n/angular-locale_es-es.js create mode 100644 vendor/angular/i18n/angular-locale_es-gq.js create mode 100644 vendor/angular/i18n/angular-locale_es-gt.js create mode 100644 vendor/angular/i18n/angular-locale_es-hn.js create mode 100644 vendor/angular/i18n/angular-locale_es-ic.js create mode 100644 vendor/angular/i18n/angular-locale_es-mx.js create mode 100644 vendor/angular/i18n/angular-locale_es-ni.js create mode 100644 vendor/angular/i18n/angular-locale_es-pa.js create mode 100644 vendor/angular/i18n/angular-locale_es-pe.js create mode 100644 vendor/angular/i18n/angular-locale_es-pr.js create mode 100644 vendor/angular/i18n/angular-locale_es-py.js create mode 100644 vendor/angular/i18n/angular-locale_es-sv.js create mode 100644 vendor/angular/i18n/angular-locale_es-us.js create mode 100644 vendor/angular/i18n/angular-locale_es-uy.js create mode 100644 vendor/angular/i18n/angular-locale_es-ve.js create mode 100644 vendor/angular/i18n/angular-locale_es.js create mode 100644 vendor/angular/i18n/angular-locale_et-ee.js create mode 100644 vendor/angular/i18n/angular-locale_et.js create mode 100644 vendor/angular/i18n/angular-locale_eu-es.js create mode 100644 vendor/angular/i18n/angular-locale_eu.js create mode 100644 vendor/angular/i18n/angular-locale_fa-af.js create mode 100644 vendor/angular/i18n/angular-locale_fa-ir.js create mode 100644 vendor/angular/i18n/angular-locale_fa.js create mode 100644 vendor/angular/i18n/angular-locale_fi-fi.js create mode 100644 vendor/angular/i18n/angular-locale_fi.js create mode 100644 vendor/angular/i18n/angular-locale_fil-ph.js create mode 100644 vendor/angular/i18n/angular-locale_fil.js create mode 100644 vendor/angular/i18n/angular-locale_fr-be.js create mode 100644 vendor/angular/i18n/angular-locale_fr-bf.js create mode 100644 vendor/angular/i18n/angular-locale_fr-bi.js create mode 100644 vendor/angular/i18n/angular-locale_fr-bj.js create mode 100644 vendor/angular/i18n/angular-locale_fr-bl.js create mode 100644 vendor/angular/i18n/angular-locale_fr-ca.js create mode 100644 vendor/angular/i18n/angular-locale_fr-cd.js create mode 100644 vendor/angular/i18n/angular-locale_fr-cf.js create mode 100644 vendor/angular/i18n/angular-locale_fr-cg.js create mode 100644 vendor/angular/i18n/angular-locale_fr-ch.js create mode 100644 vendor/angular/i18n/angular-locale_fr-ci.js create mode 100644 vendor/angular/i18n/angular-locale_fr-cm.js create mode 100644 vendor/angular/i18n/angular-locale_fr-dj.js create mode 100644 vendor/angular/i18n/angular-locale_fr-fr.js create mode 100644 vendor/angular/i18n/angular-locale_fr-ga.js create mode 100644 vendor/angular/i18n/angular-locale_fr-gf.js create mode 100644 vendor/angular/i18n/angular-locale_fr-gn.js create mode 100644 vendor/angular/i18n/angular-locale_fr-gp.js create mode 100644 vendor/angular/i18n/angular-locale_fr-gq.js create mode 100644 vendor/angular/i18n/angular-locale_fr-km.js create mode 100644 vendor/angular/i18n/angular-locale_fr-lu.js create mode 100644 vendor/angular/i18n/angular-locale_fr-mc.js create mode 100644 vendor/angular/i18n/angular-locale_fr-mf.js create mode 100644 vendor/angular/i18n/angular-locale_fr-mg.js create mode 100644 vendor/angular/i18n/angular-locale_fr-ml.js create mode 100644 vendor/angular/i18n/angular-locale_fr-mq.js create mode 100644 vendor/angular/i18n/angular-locale_fr-ne.js create mode 100644 vendor/angular/i18n/angular-locale_fr-re.js create mode 100644 vendor/angular/i18n/angular-locale_fr-yt.js create mode 100644 vendor/angular/i18n/angular-locale_fr.js create mode 100644 vendor/angular/i18n/angular-locale_gl-es.js create mode 100644 vendor/angular/i18n/angular-locale_gl.js create mode 100644 vendor/angular/i18n/angular-locale_gsw-ch.js create mode 100644 vendor/angular/i18n/angular-locale_gsw.js create mode 100644 vendor/angular/i18n/angular-locale_gu-in.js create mode 100644 vendor/angular/i18n/angular-locale_gu.js create mode 100644 vendor/angular/i18n/angular-locale_he-il.js create mode 100644 vendor/angular/i18n/angular-locale_he.js create mode 100644 vendor/angular/i18n/angular-locale_hi-in.js create mode 100644 vendor/angular/i18n/angular-locale_hi.js create mode 100644 vendor/angular/i18n/angular-locale_hr-hr.js create mode 100644 vendor/angular/i18n/angular-locale_hr.js create mode 100644 vendor/angular/i18n/angular-locale_hu-hu.js create mode 100644 vendor/angular/i18n/angular-locale_hu.js create mode 100644 vendor/angular/i18n/angular-locale_id-id.js create mode 100644 vendor/angular/i18n/angular-locale_id.js create mode 100644 vendor/angular/i18n/angular-locale_in.js create mode 100644 vendor/angular/i18n/angular-locale_is-is.js create mode 100644 vendor/angular/i18n/angular-locale_is.js create mode 100644 vendor/angular/i18n/angular-locale_it-it.js create mode 100644 vendor/angular/i18n/angular-locale_it-sm.js create mode 100644 vendor/angular/i18n/angular-locale_it.js create mode 100644 vendor/angular/i18n/angular-locale_iw.js create mode 100644 vendor/angular/i18n/angular-locale_ja-jp.js create mode 100644 vendor/angular/i18n/angular-locale_ja.js create mode 100644 vendor/angular/i18n/angular-locale_kn-in.js create mode 100644 vendor/angular/i18n/angular-locale_kn.js create mode 100644 vendor/angular/i18n/angular-locale_ko-kr.js create mode 100644 vendor/angular/i18n/angular-locale_ko.js create mode 100644 vendor/angular/i18n/angular-locale_ln-cd.js create mode 100644 vendor/angular/i18n/angular-locale_ln.js create mode 100644 vendor/angular/i18n/angular-locale_lt-lt.js create mode 100644 vendor/angular/i18n/angular-locale_lt.js create mode 100644 vendor/angular/i18n/angular-locale_lv-lv.js create mode 100644 vendor/angular/i18n/angular-locale_lv.js create mode 100644 vendor/angular/i18n/angular-locale_ml-in.js create mode 100644 vendor/angular/i18n/angular-locale_ml.js create mode 100644 vendor/angular/i18n/angular-locale_mr-in.js create mode 100644 vendor/angular/i18n/angular-locale_mr.js create mode 100644 vendor/angular/i18n/angular-locale_ms-my.js create mode 100644 vendor/angular/i18n/angular-locale_ms.js create mode 100644 vendor/angular/i18n/angular-locale_mt-mt.js create mode 100644 vendor/angular/i18n/angular-locale_mt.js create mode 100644 vendor/angular/i18n/angular-locale_nl-cw.js create mode 100644 vendor/angular/i18n/angular-locale_nl-nl.js create mode 100644 vendor/angular/i18n/angular-locale_nl-sx.js create mode 100644 vendor/angular/i18n/angular-locale_nl.js create mode 100644 vendor/angular/i18n/angular-locale_no.js create mode 100644 vendor/angular/i18n/angular-locale_or-in.js create mode 100644 vendor/angular/i18n/angular-locale_or.js create mode 100644 vendor/angular/i18n/angular-locale_pl-pl.js create mode 100644 vendor/angular/i18n/angular-locale_pl.js create mode 100644 vendor/angular/i18n/angular-locale_pt-br.js create mode 100644 vendor/angular/i18n/angular-locale_pt-pt.js create mode 100644 vendor/angular/i18n/angular-locale_pt.js create mode 100644 vendor/angular/i18n/angular-locale_ro-ro.js create mode 100644 vendor/angular/i18n/angular-locale_ro.js create mode 100644 vendor/angular/i18n/angular-locale_ru-ru.js create mode 100644 vendor/angular/i18n/angular-locale_ru.js create mode 100644 vendor/angular/i18n/angular-locale_sk-sk.js create mode 100644 vendor/angular/i18n/angular-locale_sk.js create mode 100644 vendor/angular/i18n/angular-locale_sl-si.js create mode 100644 vendor/angular/i18n/angular-locale_sl.js create mode 100644 vendor/angular/i18n/angular-locale_sq-al.js create mode 100644 vendor/angular/i18n/angular-locale_sq.js create mode 100644 vendor/angular/i18n/angular-locale_sr-cyrl-rs.js create mode 100644 vendor/angular/i18n/angular-locale_sr-latn-rs.js create mode 100644 vendor/angular/i18n/angular-locale_sr.js create mode 100644 vendor/angular/i18n/angular-locale_sv-se.js create mode 100644 vendor/angular/i18n/angular-locale_sv.js create mode 100644 vendor/angular/i18n/angular-locale_sw-tz.js create mode 100644 vendor/angular/i18n/angular-locale_sw.js create mode 100644 vendor/angular/i18n/angular-locale_ta-in.js create mode 100644 vendor/angular/i18n/angular-locale_ta.js create mode 100644 vendor/angular/i18n/angular-locale_te-in.js create mode 100644 vendor/angular/i18n/angular-locale_te.js create mode 100644 vendor/angular/i18n/angular-locale_th-th.js create mode 100644 vendor/angular/i18n/angular-locale_th.js create mode 100644 vendor/angular/i18n/angular-locale_tl.js create mode 100644 vendor/angular/i18n/angular-locale_tr-tr.js create mode 100644 vendor/angular/i18n/angular-locale_tr.js create mode 100644 vendor/angular/i18n/angular-locale_uk-ua.js create mode 100644 vendor/angular/i18n/angular-locale_uk.js create mode 100644 vendor/angular/i18n/angular-locale_ur-pk.js create mode 100644 vendor/angular/i18n/angular-locale_ur.js create mode 100644 vendor/angular/i18n/angular-locale_vi-vn.js create mode 100644 vendor/angular/i18n/angular-locale_vi.js create mode 100644 vendor/angular/i18n/angular-locale_zh-cn.js create mode 100644 vendor/angular/i18n/angular-locale_zh-hans-cn.js create mode 100644 vendor/angular/i18n/angular-locale_zh-hk.js create mode 100644 vendor/angular/i18n/angular-locale_zh-tw.js create mode 100644 vendor/angular/i18n/angular-locale_zh.js create mode 100644 vendor/angular/i18n/angular-locale_zu-za.js create mode 100644 vendor/angular/i18n/angular-locale_zu.js create mode 100644 vendor/angular/version.json create mode 100644 vendor/angular/version.txt create mode 100644 vendor/bootstrap/css/bootstrap.css create mode 100644 vendor/bootstrap/fonts/glyphicons-halflings-regular.eot create mode 100644 vendor/bootstrap/fonts/glyphicons-halflings-regular.svg create mode 100644 vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf create mode 100644 vendor/bootstrap/fonts/glyphicons-halflings-regular.woff create mode 100644 vendor/bootstrap/js/bootstrap.js create mode 100644 vendor/cryptoJS/THIRDPARTY_LICENSE create mode 100644 vendor/cryptoJS/crypto.js create mode 100644 vendor/gemoji/THIRDPARTY_LICENSE create mode 100755 vendor/gemoji/images/0023-20e3.png create mode 100755 vendor/gemoji/images/0023-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0030-20e3.png create mode 100755 vendor/gemoji/images/0030-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0031-20e3.png create mode 100755 vendor/gemoji/images/0031-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0032-20e3.png create mode 100755 vendor/gemoji/images/0032-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0033-20e3.png create mode 100755 vendor/gemoji/images/0033-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0034-20e3.png create mode 100755 vendor/gemoji/images/0034-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0035-20e3.png create mode 100755 vendor/gemoji/images/0035-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0036-20e3.png create mode 100755 vendor/gemoji/images/0036-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0037-20e3.png create mode 100755 vendor/gemoji/images/0037-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0038-20e3.png create mode 100755 vendor/gemoji/images/0038-fe0f-20e3.png create mode 100755 vendor/gemoji/images/0039-20e3.png create mode 100755 vendor/gemoji/images/0039-fe0f-20e3.png create mode 100755 vendor/gemoji/images/00a9.png create mode 100755 vendor/gemoji/images/00ae.png create mode 100755 vendor/gemoji/images/1f004-fe0f.png create mode 100755 vendor/gemoji/images/1f004.png create mode 100755 vendor/gemoji/images/1f0cf.png create mode 100755 vendor/gemoji/images/1f170.png create mode 100755 vendor/gemoji/images/1f171.png create mode 100755 vendor/gemoji/images/1f17e.png create mode 100755 vendor/gemoji/images/1f17f-fe0f.png create mode 100755 vendor/gemoji/images/1f17f.png create mode 100755 vendor/gemoji/images/1f18e.png create mode 100755 vendor/gemoji/images/1f191.png create mode 100755 vendor/gemoji/images/1f192.png create mode 100755 vendor/gemoji/images/1f193.png create mode 100755 vendor/gemoji/images/1f194.png create mode 100755 vendor/gemoji/images/1f195.png create mode 100755 vendor/gemoji/images/1f196.png create mode 100755 vendor/gemoji/images/1f197.png create mode 100755 vendor/gemoji/images/1f198.png create mode 100755 vendor/gemoji/images/1f199.png create mode 100755 vendor/gemoji/images/1f19a.png create mode 100755 vendor/gemoji/images/1f1e8-1f1f3.png create mode 100755 vendor/gemoji/images/1f1e9-1f1ea.png create mode 100755 vendor/gemoji/images/1f1ea-1f1f8.png create mode 100755 vendor/gemoji/images/1f1eb-1f1f7.png create mode 100755 vendor/gemoji/images/1f1ec-1f1e7.png create mode 100755 vendor/gemoji/images/1f1ee-1f1f9.png create mode 100755 vendor/gemoji/images/1f1ef-1f1f5.png create mode 100755 vendor/gemoji/images/1f1f0-1f1f7.png create mode 100755 vendor/gemoji/images/1f1f7-1f1fa.png create mode 100755 vendor/gemoji/images/1f1fa-1f1f8.png create mode 100755 vendor/gemoji/images/1f201.png create mode 100755 vendor/gemoji/images/1f202.png create mode 100755 vendor/gemoji/images/1f21a-fe0f.png create mode 100755 vendor/gemoji/images/1f21a.png create mode 100755 vendor/gemoji/images/1f22f-fe0f.png create mode 100755 vendor/gemoji/images/1f22f.png create mode 100755 vendor/gemoji/images/1f232.png create mode 100755 vendor/gemoji/images/1f233.png create mode 100755 vendor/gemoji/images/1f234.png create mode 100755 vendor/gemoji/images/1f235.png create mode 100755 vendor/gemoji/images/1f236.png create mode 100755 vendor/gemoji/images/1f237.png create mode 100755 vendor/gemoji/images/1f238.png create mode 100755 vendor/gemoji/images/1f239.png create mode 100755 vendor/gemoji/images/1f23a.png create mode 100755 vendor/gemoji/images/1f250.png create mode 100755 vendor/gemoji/images/1f251.png create mode 100755 vendor/gemoji/images/1f300.png create mode 100755 vendor/gemoji/images/1f301.png create mode 100755 vendor/gemoji/images/1f302.png create mode 100755 vendor/gemoji/images/1f303.png create mode 100755 vendor/gemoji/images/1f304.png create mode 100755 vendor/gemoji/images/1f305.png create mode 100755 vendor/gemoji/images/1f306.png create mode 100755 vendor/gemoji/images/1f307.png create mode 100755 vendor/gemoji/images/1f308.png create mode 100755 vendor/gemoji/images/1f309.png create mode 100755 vendor/gemoji/images/1f30a.png create mode 100755 vendor/gemoji/images/1f30b.png create mode 100755 vendor/gemoji/images/1f30c.png create mode 100755 vendor/gemoji/images/1f30d.png create mode 100755 vendor/gemoji/images/1f30e.png create mode 100755 vendor/gemoji/images/1f30f.png create mode 100755 vendor/gemoji/images/1f310.png create mode 100755 vendor/gemoji/images/1f311.png create mode 100755 vendor/gemoji/images/1f312.png create mode 100755 vendor/gemoji/images/1f313.png create mode 100755 vendor/gemoji/images/1f314.png create mode 100755 vendor/gemoji/images/1f315.png create mode 100755 vendor/gemoji/images/1f316.png create mode 100755 vendor/gemoji/images/1f317.png create mode 100755 vendor/gemoji/images/1f318.png create mode 100755 vendor/gemoji/images/1f319.png create mode 100755 vendor/gemoji/images/1f31a.png create mode 100755 vendor/gemoji/images/1f31b.png create mode 100755 vendor/gemoji/images/1f31c.png create mode 100755 vendor/gemoji/images/1f31d.png create mode 100755 vendor/gemoji/images/1f31e.png create mode 100755 vendor/gemoji/images/1f31f.png create mode 100755 vendor/gemoji/images/1f320.png create mode 100755 vendor/gemoji/images/1f330.png create mode 100755 vendor/gemoji/images/1f331.png create mode 100755 vendor/gemoji/images/1f332.png create mode 100755 vendor/gemoji/images/1f333.png create mode 100755 vendor/gemoji/images/1f334.png create mode 100755 vendor/gemoji/images/1f335.png create mode 100755 vendor/gemoji/images/1f337.png create mode 100755 vendor/gemoji/images/1f338.png create mode 100755 vendor/gemoji/images/1f339.png create mode 100755 vendor/gemoji/images/1f33a.png create mode 100755 vendor/gemoji/images/1f33b.png create mode 100755 vendor/gemoji/images/1f33c.png create mode 100755 vendor/gemoji/images/1f33d.png create mode 100755 vendor/gemoji/images/1f33e.png create mode 100755 vendor/gemoji/images/1f33f.png create mode 100755 vendor/gemoji/images/1f340.png create mode 100755 vendor/gemoji/images/1f341.png create mode 100755 vendor/gemoji/images/1f342.png create mode 100755 vendor/gemoji/images/1f343.png create mode 100755 vendor/gemoji/images/1f344.png create mode 100755 vendor/gemoji/images/1f345.png create mode 100755 vendor/gemoji/images/1f346.png create mode 100755 vendor/gemoji/images/1f347.png create mode 100755 vendor/gemoji/images/1f348.png create mode 100755 vendor/gemoji/images/1f349.png create mode 100755 vendor/gemoji/images/1f34a.png create mode 100755 vendor/gemoji/images/1f34b.png create mode 100755 vendor/gemoji/images/1f34c.png create mode 100755 vendor/gemoji/images/1f34d.png create mode 100755 vendor/gemoji/images/1f34e.png create mode 100755 vendor/gemoji/images/1f34f.png create mode 100755 vendor/gemoji/images/1f350.png create mode 100755 vendor/gemoji/images/1f351.png create mode 100755 vendor/gemoji/images/1f352.png create mode 100755 vendor/gemoji/images/1f353.png create mode 100755 vendor/gemoji/images/1f354.png create mode 100755 vendor/gemoji/images/1f355.png create mode 100755 vendor/gemoji/images/1f356.png create mode 100755 vendor/gemoji/images/1f357.png create mode 100755 vendor/gemoji/images/1f358.png create mode 100755 vendor/gemoji/images/1f359.png create mode 100755 vendor/gemoji/images/1f35a.png create mode 100755 vendor/gemoji/images/1f35b.png create mode 100755 vendor/gemoji/images/1f35c.png create mode 100755 vendor/gemoji/images/1f35d.png create mode 100755 vendor/gemoji/images/1f35e.png create mode 100755 vendor/gemoji/images/1f35f.png create mode 100755 vendor/gemoji/images/1f360.png create mode 100755 vendor/gemoji/images/1f361.png create mode 100755 vendor/gemoji/images/1f362.png create mode 100755 vendor/gemoji/images/1f363.png create mode 100755 vendor/gemoji/images/1f364.png create mode 100755 vendor/gemoji/images/1f365.png create mode 100755 vendor/gemoji/images/1f366.png create mode 100755 vendor/gemoji/images/1f367.png create mode 100755 vendor/gemoji/images/1f368.png create mode 100755 vendor/gemoji/images/1f369.png create mode 100755 vendor/gemoji/images/1f36a.png create mode 100755 vendor/gemoji/images/1f36b.png create mode 100755 vendor/gemoji/images/1f36c.png create mode 100755 vendor/gemoji/images/1f36d.png create mode 100755 vendor/gemoji/images/1f36e.png create mode 100755 vendor/gemoji/images/1f36f.png create mode 100755 vendor/gemoji/images/1f370.png create mode 100755 vendor/gemoji/images/1f371.png create mode 100755 vendor/gemoji/images/1f372.png create mode 100755 vendor/gemoji/images/1f373.png create mode 100755 vendor/gemoji/images/1f374.png create mode 100755 vendor/gemoji/images/1f375.png create mode 100755 vendor/gemoji/images/1f376.png create mode 100755 vendor/gemoji/images/1f377.png create mode 100755 vendor/gemoji/images/1f378.png create mode 100755 vendor/gemoji/images/1f379.png create mode 100755 vendor/gemoji/images/1f37a.png create mode 100755 vendor/gemoji/images/1f37b.png create mode 100755 vendor/gemoji/images/1f37c.png create mode 100755 vendor/gemoji/images/1f380.png create mode 100755 vendor/gemoji/images/1f381.png create mode 100755 vendor/gemoji/images/1f382.png create mode 100755 vendor/gemoji/images/1f383.png create mode 100755 vendor/gemoji/images/1f384.png create mode 100755 vendor/gemoji/images/1f385.png create mode 100755 vendor/gemoji/images/1f386.png create mode 100755 vendor/gemoji/images/1f387.png create mode 100755 vendor/gemoji/images/1f388.png create mode 100755 vendor/gemoji/images/1f389.png create mode 100755 vendor/gemoji/images/1f38a.png create mode 100755 vendor/gemoji/images/1f38b.png create mode 100755 vendor/gemoji/images/1f38c.png create mode 100755 vendor/gemoji/images/1f38d.png create mode 100755 vendor/gemoji/images/1f38e.png create mode 100755 vendor/gemoji/images/1f38f.png create mode 100755 vendor/gemoji/images/1f390.png create mode 100755 vendor/gemoji/images/1f391.png create mode 100755 vendor/gemoji/images/1f392.png create mode 100755 vendor/gemoji/images/1f393.png create mode 100755 vendor/gemoji/images/1f3a0.png create mode 100755 vendor/gemoji/images/1f3a1.png create mode 100755 vendor/gemoji/images/1f3a2.png create mode 100755 vendor/gemoji/images/1f3a3.png create mode 100755 vendor/gemoji/images/1f3a4.png create mode 100755 vendor/gemoji/images/1f3a5.png create mode 100755 vendor/gemoji/images/1f3a6.png create mode 100755 vendor/gemoji/images/1f3a7.png create mode 100755 vendor/gemoji/images/1f3a8.png create mode 100755 vendor/gemoji/images/1f3a9.png create mode 100755 vendor/gemoji/images/1f3aa.png create mode 100755 vendor/gemoji/images/1f3ab.png create mode 100755 vendor/gemoji/images/1f3ac.png create mode 100755 vendor/gemoji/images/1f3ad.png create mode 100755 vendor/gemoji/images/1f3ae.png create mode 100755 vendor/gemoji/images/1f3af.png create mode 100755 vendor/gemoji/images/1f3b0.png create mode 100755 vendor/gemoji/images/1f3b1.png create mode 100755 vendor/gemoji/images/1f3b2.png create mode 100755 vendor/gemoji/images/1f3b3.png create mode 100755 vendor/gemoji/images/1f3b4.png create mode 100755 vendor/gemoji/images/1f3b5.png create mode 100755 vendor/gemoji/images/1f3b6.png create mode 100755 vendor/gemoji/images/1f3b7.png create mode 100755 vendor/gemoji/images/1f3b8.png create mode 100755 vendor/gemoji/images/1f3b9.png create mode 100755 vendor/gemoji/images/1f3ba.png create mode 100755 vendor/gemoji/images/1f3bb.png create mode 100755 vendor/gemoji/images/1f3bc.png create mode 100755 vendor/gemoji/images/1f3bd.png create mode 100755 vendor/gemoji/images/1f3be.png create mode 100755 vendor/gemoji/images/1f3bf.png create mode 100755 vendor/gemoji/images/1f3c0.png create mode 100755 vendor/gemoji/images/1f3c1.png create mode 100755 vendor/gemoji/images/1f3c2.png create mode 100755 vendor/gemoji/images/1f3c3.png create mode 100755 vendor/gemoji/images/1f3c4.png create mode 100755 vendor/gemoji/images/1f3c6.png create mode 100755 vendor/gemoji/images/1f3c7.png create mode 100755 vendor/gemoji/images/1f3c8.png create mode 100755 vendor/gemoji/images/1f3c9.png create mode 100755 vendor/gemoji/images/1f3ca.png create mode 100755 vendor/gemoji/images/1f3e0.png create mode 100755 vendor/gemoji/images/1f3e1.png create mode 100755 vendor/gemoji/images/1f3e2.png create mode 100755 vendor/gemoji/images/1f3e3.png create mode 100755 vendor/gemoji/images/1f3e4.png create mode 100755 vendor/gemoji/images/1f3e5.png create mode 100755 vendor/gemoji/images/1f3e6.png create mode 100755 vendor/gemoji/images/1f3e7.png create mode 100755 vendor/gemoji/images/1f3e8.png create mode 100755 vendor/gemoji/images/1f3e9.png create mode 100755 vendor/gemoji/images/1f3ea.png create mode 100755 vendor/gemoji/images/1f3eb.png create mode 100755 vendor/gemoji/images/1f3ec.png create mode 100755 vendor/gemoji/images/1f3ed.png create mode 100755 vendor/gemoji/images/1f3ee.png create mode 100755 vendor/gemoji/images/1f3ef.png create mode 100755 vendor/gemoji/images/1f3f0.png create mode 100755 vendor/gemoji/images/1f400.png create mode 100755 vendor/gemoji/images/1f401.png create mode 100755 vendor/gemoji/images/1f402.png create mode 100755 vendor/gemoji/images/1f403.png create mode 100755 vendor/gemoji/images/1f404.png create mode 100755 vendor/gemoji/images/1f405.png create mode 100755 vendor/gemoji/images/1f406.png create mode 100755 vendor/gemoji/images/1f407.png create mode 100755 vendor/gemoji/images/1f408.png create mode 100755 vendor/gemoji/images/1f409.png create mode 100755 vendor/gemoji/images/1f40a.png create mode 100755 vendor/gemoji/images/1f40b.png create mode 100755 vendor/gemoji/images/1f40c.png create mode 100755 vendor/gemoji/images/1f40d.png create mode 100755 vendor/gemoji/images/1f40e.png create mode 100755 vendor/gemoji/images/1f40f.png create mode 100755 vendor/gemoji/images/1f410.png create mode 100755 vendor/gemoji/images/1f411.png create mode 100755 vendor/gemoji/images/1f412.png create mode 100755 vendor/gemoji/images/1f413.png create mode 100755 vendor/gemoji/images/1f414.png create mode 100755 vendor/gemoji/images/1f415.png create mode 100755 vendor/gemoji/images/1f416.png create mode 100755 vendor/gemoji/images/1f417.png create mode 100755 vendor/gemoji/images/1f418.png create mode 100755 vendor/gemoji/images/1f419.png create mode 100755 vendor/gemoji/images/1f41a.png create mode 100755 vendor/gemoji/images/1f41b.png create mode 100755 vendor/gemoji/images/1f41c.png create mode 100755 vendor/gemoji/images/1f41d.png create mode 100755 vendor/gemoji/images/1f41e.png create mode 100755 vendor/gemoji/images/1f41f.png create mode 100755 vendor/gemoji/images/1f420.png create mode 100755 vendor/gemoji/images/1f421.png create mode 100755 vendor/gemoji/images/1f422.png create mode 100755 vendor/gemoji/images/1f423.png create mode 100755 vendor/gemoji/images/1f424.png create mode 100755 vendor/gemoji/images/1f425.png create mode 100755 vendor/gemoji/images/1f426.png create mode 100755 vendor/gemoji/images/1f427.png create mode 100755 vendor/gemoji/images/1f428.png create mode 100755 vendor/gemoji/images/1f429.png create mode 100755 vendor/gemoji/images/1f42a.png create mode 100755 vendor/gemoji/images/1f42b.png create mode 100755 vendor/gemoji/images/1f42c.png create mode 100755 vendor/gemoji/images/1f42d.png create mode 100755 vendor/gemoji/images/1f42e.png create mode 100755 vendor/gemoji/images/1f42f.png create mode 100755 vendor/gemoji/images/1f430.png create mode 100755 vendor/gemoji/images/1f431.png create mode 100755 vendor/gemoji/images/1f432.png create mode 100755 vendor/gemoji/images/1f433.png create mode 100755 vendor/gemoji/images/1f434.png create mode 100755 vendor/gemoji/images/1f435.png create mode 100755 vendor/gemoji/images/1f436.png create mode 100755 vendor/gemoji/images/1f437.png create mode 100755 vendor/gemoji/images/1f438.png create mode 100755 vendor/gemoji/images/1f439.png create mode 100755 vendor/gemoji/images/1f43a.png create mode 100755 vendor/gemoji/images/1f43b.png create mode 100755 vendor/gemoji/images/1f43c.png create mode 100755 vendor/gemoji/images/1f43d.png create mode 100755 vendor/gemoji/images/1f43e.png create mode 100755 vendor/gemoji/images/1f440.png create mode 100755 vendor/gemoji/images/1f442.png create mode 100755 vendor/gemoji/images/1f443.png create mode 100755 vendor/gemoji/images/1f444.png create mode 100755 vendor/gemoji/images/1f445.png create mode 100755 vendor/gemoji/images/1f446.png create mode 100755 vendor/gemoji/images/1f447.png create mode 100755 vendor/gemoji/images/1f448.png create mode 100755 vendor/gemoji/images/1f449.png create mode 100755 vendor/gemoji/images/1f44a.png create mode 100755 vendor/gemoji/images/1f44b.png create mode 100755 vendor/gemoji/images/1f44c.png create mode 100755 vendor/gemoji/images/1f44d.png create mode 100755 vendor/gemoji/images/1f44e.png create mode 100755 vendor/gemoji/images/1f44f.png create mode 100755 vendor/gemoji/images/1f450.png create mode 100755 vendor/gemoji/images/1f451.png create mode 100755 vendor/gemoji/images/1f452.png create mode 100755 vendor/gemoji/images/1f453.png create mode 100755 vendor/gemoji/images/1f454.png create mode 100755 vendor/gemoji/images/1f455.png create mode 100755 vendor/gemoji/images/1f456.png create mode 100755 vendor/gemoji/images/1f457.png create mode 100755 vendor/gemoji/images/1f458.png create mode 100755 vendor/gemoji/images/1f459.png create mode 100755 vendor/gemoji/images/1f45a.png create mode 100755 vendor/gemoji/images/1f45b.png create mode 100755 vendor/gemoji/images/1f45c.png create mode 100755 vendor/gemoji/images/1f45d.png create mode 100755 vendor/gemoji/images/1f45e.png create mode 100755 vendor/gemoji/images/1f45f.png create mode 100755 vendor/gemoji/images/1f460.png create mode 100755 vendor/gemoji/images/1f461.png create mode 100755 vendor/gemoji/images/1f462.png create mode 100755 vendor/gemoji/images/1f463.png create mode 100755 vendor/gemoji/images/1f464.png create mode 100755 vendor/gemoji/images/1f465.png create mode 100755 vendor/gemoji/images/1f466.png create mode 100755 vendor/gemoji/images/1f467.png create mode 100755 vendor/gemoji/images/1f468.png create mode 100755 vendor/gemoji/images/1f469.png create mode 100755 vendor/gemoji/images/1f46a.png create mode 100755 vendor/gemoji/images/1f46b.png create mode 100755 vendor/gemoji/images/1f46c.png create mode 100755 vendor/gemoji/images/1f46d.png create mode 100755 vendor/gemoji/images/1f46e.png create mode 100755 vendor/gemoji/images/1f46f.png create mode 100755 vendor/gemoji/images/1f470.png create mode 100755 vendor/gemoji/images/1f471.png create mode 100755 vendor/gemoji/images/1f472.png create mode 100755 vendor/gemoji/images/1f473.png create mode 100755 vendor/gemoji/images/1f474.png create mode 100755 vendor/gemoji/images/1f475.png create mode 100755 vendor/gemoji/images/1f476.png create mode 100755 vendor/gemoji/images/1f477.png create mode 100755 vendor/gemoji/images/1f478.png create mode 100755 vendor/gemoji/images/1f479.png create mode 100755 vendor/gemoji/images/1f47a.png create mode 100755 vendor/gemoji/images/1f47b.png create mode 100755 vendor/gemoji/images/1f47c.png create mode 100755 vendor/gemoji/images/1f47d.png create mode 100755 vendor/gemoji/images/1f47e.png create mode 100755 vendor/gemoji/images/1f47f.png create mode 100755 vendor/gemoji/images/1f480.png create mode 100755 vendor/gemoji/images/1f481.png create mode 100755 vendor/gemoji/images/1f482.png create mode 100755 vendor/gemoji/images/1f483.png create mode 100755 vendor/gemoji/images/1f484.png create mode 100755 vendor/gemoji/images/1f485.png create mode 100755 vendor/gemoji/images/1f486.png create mode 100755 vendor/gemoji/images/1f487.png create mode 100755 vendor/gemoji/images/1f488.png create mode 100755 vendor/gemoji/images/1f489.png create mode 100755 vendor/gemoji/images/1f48a.png create mode 100755 vendor/gemoji/images/1f48b.png create mode 100755 vendor/gemoji/images/1f48c.png create mode 100755 vendor/gemoji/images/1f48d.png create mode 100755 vendor/gemoji/images/1f48e.png create mode 100755 vendor/gemoji/images/1f48f.png create mode 100755 vendor/gemoji/images/1f490.png create mode 100755 vendor/gemoji/images/1f491.png create mode 100755 vendor/gemoji/images/1f492.png create mode 100755 vendor/gemoji/images/1f493.png create mode 100755 vendor/gemoji/images/1f494.png create mode 100755 vendor/gemoji/images/1f495.png create mode 100755 vendor/gemoji/images/1f496.png create mode 100755 vendor/gemoji/images/1f497.png create mode 100755 vendor/gemoji/images/1f498.png create mode 100755 vendor/gemoji/images/1f499.png create mode 100755 vendor/gemoji/images/1f49a.png create mode 100755 vendor/gemoji/images/1f49b.png create mode 100755 vendor/gemoji/images/1f49c.png create mode 100755 vendor/gemoji/images/1f49d.png create mode 100755 vendor/gemoji/images/1f49e.png create mode 100755 vendor/gemoji/images/1f49f.png create mode 100755 vendor/gemoji/images/1f4a0.png create mode 100755 vendor/gemoji/images/1f4a1.png create mode 100755 vendor/gemoji/images/1f4a2.png create mode 100755 vendor/gemoji/images/1f4a3.png create mode 100755 vendor/gemoji/images/1f4a4.png create mode 100755 vendor/gemoji/images/1f4a5.png create mode 100755 vendor/gemoji/images/1f4a6.png create mode 100755 vendor/gemoji/images/1f4a7.png create mode 100755 vendor/gemoji/images/1f4a8.png create mode 100755 vendor/gemoji/images/1f4a9.png create mode 100755 vendor/gemoji/images/1f4aa.png create mode 100755 vendor/gemoji/images/1f4ab.png create mode 100755 vendor/gemoji/images/1f4ac.png create mode 100755 vendor/gemoji/images/1f4ad.png create mode 100755 vendor/gemoji/images/1f4ae.png create mode 100755 vendor/gemoji/images/1f4af.png create mode 100755 vendor/gemoji/images/1f4b0.png create mode 100755 vendor/gemoji/images/1f4b1.png create mode 100755 vendor/gemoji/images/1f4b2.png create mode 100755 vendor/gemoji/images/1f4b3.png create mode 100755 vendor/gemoji/images/1f4b4.png create mode 100755 vendor/gemoji/images/1f4b5.png create mode 100755 vendor/gemoji/images/1f4b6.png create mode 100755 vendor/gemoji/images/1f4b7.png create mode 100755 vendor/gemoji/images/1f4b8.png create mode 100755 vendor/gemoji/images/1f4b9.png create mode 100755 vendor/gemoji/images/1f4ba.png create mode 100755 vendor/gemoji/images/1f4bb.png create mode 100755 vendor/gemoji/images/1f4bc.png create mode 100755 vendor/gemoji/images/1f4bd.png create mode 100755 vendor/gemoji/images/1f4be.png create mode 100755 vendor/gemoji/images/1f4bf.png create mode 100755 vendor/gemoji/images/1f4c0.png create mode 100755 vendor/gemoji/images/1f4c1.png create mode 100755 vendor/gemoji/images/1f4c2.png create mode 100755 vendor/gemoji/images/1f4c3.png create mode 100755 vendor/gemoji/images/1f4c4.png create mode 100755 vendor/gemoji/images/1f4c5.png create mode 100755 vendor/gemoji/images/1f4c6.png create mode 100755 vendor/gemoji/images/1f4c7.png create mode 100755 vendor/gemoji/images/1f4c8.png create mode 100755 vendor/gemoji/images/1f4c9.png create mode 100755 vendor/gemoji/images/1f4ca.png create mode 100755 vendor/gemoji/images/1f4cb.png create mode 100755 vendor/gemoji/images/1f4cc.png create mode 100755 vendor/gemoji/images/1f4cd.png create mode 100755 vendor/gemoji/images/1f4ce.png create mode 100755 vendor/gemoji/images/1f4cf.png create mode 100755 vendor/gemoji/images/1f4d0.png create mode 100755 vendor/gemoji/images/1f4d1.png create mode 100755 vendor/gemoji/images/1f4d2.png create mode 100755 vendor/gemoji/images/1f4d3.png create mode 100755 vendor/gemoji/images/1f4d4.png create mode 100755 vendor/gemoji/images/1f4d5.png create mode 100755 vendor/gemoji/images/1f4d6.png create mode 100755 vendor/gemoji/images/1f4d7.png create mode 100755 vendor/gemoji/images/1f4d8.png create mode 100755 vendor/gemoji/images/1f4d9.png create mode 100755 vendor/gemoji/images/1f4da.png create mode 100755 vendor/gemoji/images/1f4db.png create mode 100755 vendor/gemoji/images/1f4dc.png create mode 100755 vendor/gemoji/images/1f4dd.png create mode 100755 vendor/gemoji/images/1f4de.png create mode 100755 vendor/gemoji/images/1f4df.png create mode 100755 vendor/gemoji/images/1f4e0.png create mode 100755 vendor/gemoji/images/1f4e1.png create mode 100755 vendor/gemoji/images/1f4e2.png create mode 100755 vendor/gemoji/images/1f4e3.png create mode 100755 vendor/gemoji/images/1f4e4.png create mode 100755 vendor/gemoji/images/1f4e5.png create mode 100755 vendor/gemoji/images/1f4e6.png create mode 100755 vendor/gemoji/images/1f4e7.png create mode 100755 vendor/gemoji/images/1f4e8.png create mode 100755 vendor/gemoji/images/1f4e9.png create mode 100755 vendor/gemoji/images/1f4ea.png create mode 100755 vendor/gemoji/images/1f4eb.png create mode 100755 vendor/gemoji/images/1f4ec.png create mode 100755 vendor/gemoji/images/1f4ed.png create mode 100755 vendor/gemoji/images/1f4ee.png create mode 100755 vendor/gemoji/images/1f4ef.png create mode 100755 vendor/gemoji/images/1f4f0.png create mode 100755 vendor/gemoji/images/1f4f1.png create mode 100755 vendor/gemoji/images/1f4f2.png create mode 100755 vendor/gemoji/images/1f4f3.png create mode 100755 vendor/gemoji/images/1f4f4.png create mode 100755 vendor/gemoji/images/1f4f5.png create mode 100755 vendor/gemoji/images/1f4f6.png create mode 100755 vendor/gemoji/images/1f4f7.png create mode 100755 vendor/gemoji/images/1f4f9.png create mode 100755 vendor/gemoji/images/1f4fa.png create mode 100755 vendor/gemoji/images/1f4fb.png create mode 100755 vendor/gemoji/images/1f4fc.png create mode 100755 vendor/gemoji/images/1f500.png create mode 100755 vendor/gemoji/images/1f501.png create mode 100755 vendor/gemoji/images/1f502.png create mode 100755 vendor/gemoji/images/1f503.png create mode 100755 vendor/gemoji/images/1f504.png create mode 100755 vendor/gemoji/images/1f505.png create mode 100755 vendor/gemoji/images/1f506.png create mode 100755 vendor/gemoji/images/1f507.png create mode 100755 vendor/gemoji/images/1f508.png create mode 100755 vendor/gemoji/images/1f509.png create mode 100755 vendor/gemoji/images/1f50a.png create mode 100755 vendor/gemoji/images/1f50b.png create mode 100755 vendor/gemoji/images/1f50c.png create mode 100755 vendor/gemoji/images/1f50d.png create mode 100755 vendor/gemoji/images/1f50e.png create mode 100755 vendor/gemoji/images/1f50f.png create mode 100755 vendor/gemoji/images/1f510.png create mode 100755 vendor/gemoji/images/1f511.png create mode 100755 vendor/gemoji/images/1f512.png create mode 100755 vendor/gemoji/images/1f513.png create mode 100755 vendor/gemoji/images/1f514.png create mode 100755 vendor/gemoji/images/1f515.png create mode 100755 vendor/gemoji/images/1f516.png create mode 100755 vendor/gemoji/images/1f517.png create mode 100755 vendor/gemoji/images/1f518.png create mode 100755 vendor/gemoji/images/1f519.png create mode 100755 vendor/gemoji/images/1f51a.png create mode 100755 vendor/gemoji/images/1f51b.png create mode 100755 vendor/gemoji/images/1f51c.png create mode 100755 vendor/gemoji/images/1f51d.png create mode 100755 vendor/gemoji/images/1f51e.png create mode 100755 vendor/gemoji/images/1f51f.png create mode 100755 vendor/gemoji/images/1f520.png create mode 100755 vendor/gemoji/images/1f521.png create mode 100755 vendor/gemoji/images/1f522.png create mode 100755 vendor/gemoji/images/1f523.png create mode 100755 vendor/gemoji/images/1f524.png create mode 100755 vendor/gemoji/images/1f525.png create mode 100755 vendor/gemoji/images/1f526.png create mode 100755 vendor/gemoji/images/1f527.png create mode 100755 vendor/gemoji/images/1f528.png create mode 100755 vendor/gemoji/images/1f529.png create mode 100755 vendor/gemoji/images/1f52a.png create mode 100755 vendor/gemoji/images/1f52b.png create mode 100755 vendor/gemoji/images/1f52c.png create mode 100755 vendor/gemoji/images/1f52d.png create mode 100755 vendor/gemoji/images/1f52e.png create mode 100755 vendor/gemoji/images/1f52f.png create mode 100755 vendor/gemoji/images/1f530.png create mode 100755 vendor/gemoji/images/1f531.png create mode 100755 vendor/gemoji/images/1f532.png create mode 100755 vendor/gemoji/images/1f533.png create mode 100755 vendor/gemoji/images/1f534.png create mode 100755 vendor/gemoji/images/1f535.png create mode 100755 vendor/gemoji/images/1f536.png create mode 100755 vendor/gemoji/images/1f537.png create mode 100755 vendor/gemoji/images/1f538.png create mode 100755 vendor/gemoji/images/1f539.png create mode 100755 vendor/gemoji/images/1f53a.png create mode 100755 vendor/gemoji/images/1f53b.png create mode 100755 vendor/gemoji/images/1f53c.png create mode 100755 vendor/gemoji/images/1f53d.png create mode 100755 vendor/gemoji/images/1f550.png create mode 100755 vendor/gemoji/images/1f551.png create mode 100755 vendor/gemoji/images/1f552.png create mode 100755 vendor/gemoji/images/1f553.png create mode 100755 vendor/gemoji/images/1f554.png create mode 100755 vendor/gemoji/images/1f555.png create mode 100755 vendor/gemoji/images/1f556.png create mode 100755 vendor/gemoji/images/1f557.png create mode 100755 vendor/gemoji/images/1f558.png create mode 100755 vendor/gemoji/images/1f559.png create mode 100755 vendor/gemoji/images/1f55a.png create mode 100755 vendor/gemoji/images/1f55b.png create mode 100755 vendor/gemoji/images/1f55c.png create mode 100755 vendor/gemoji/images/1f55d.png create mode 100755 vendor/gemoji/images/1f55e.png create mode 100755 vendor/gemoji/images/1f55f.png create mode 100755 vendor/gemoji/images/1f560.png create mode 100755 vendor/gemoji/images/1f561.png create mode 100755 vendor/gemoji/images/1f562.png create mode 100755 vendor/gemoji/images/1f563.png create mode 100755 vendor/gemoji/images/1f564.png create mode 100755 vendor/gemoji/images/1f565.png create mode 100755 vendor/gemoji/images/1f566.png create mode 100755 vendor/gemoji/images/1f567.png create mode 100755 vendor/gemoji/images/1f5fb.png create mode 100755 vendor/gemoji/images/1f5fc.png create mode 100755 vendor/gemoji/images/1f5fd.png create mode 100755 vendor/gemoji/images/1f5fe.png create mode 100755 vendor/gemoji/images/1f5ff.png create mode 100755 vendor/gemoji/images/1f600.png create mode 100755 vendor/gemoji/images/1f601.png create mode 100755 vendor/gemoji/images/1f602.png create mode 100755 vendor/gemoji/images/1f603.png create mode 100755 vendor/gemoji/images/1f604.png create mode 100755 vendor/gemoji/images/1f605.png create mode 100755 vendor/gemoji/images/1f606.png create mode 100755 vendor/gemoji/images/1f607.png create mode 100755 vendor/gemoji/images/1f608.png create mode 100755 vendor/gemoji/images/1f609.png create mode 100755 vendor/gemoji/images/1f60a.png create mode 100755 vendor/gemoji/images/1f60b.png create mode 100755 vendor/gemoji/images/1f60c.png create mode 100755 vendor/gemoji/images/1f60d.png create mode 100755 vendor/gemoji/images/1f60e.png create mode 100755 vendor/gemoji/images/1f60f.png create mode 100755 vendor/gemoji/images/1f610.png create mode 100755 vendor/gemoji/images/1f611.png create mode 100755 vendor/gemoji/images/1f612.png create mode 100755 vendor/gemoji/images/1f613.png create mode 100755 vendor/gemoji/images/1f614.png create mode 100755 vendor/gemoji/images/1f615.png create mode 100755 vendor/gemoji/images/1f616.png create mode 100755 vendor/gemoji/images/1f617.png create mode 100755 vendor/gemoji/images/1f618.png create mode 100755 vendor/gemoji/images/1f619.png create mode 100755 vendor/gemoji/images/1f61a.png create mode 100755 vendor/gemoji/images/1f61b.png create mode 100755 vendor/gemoji/images/1f61c.png create mode 100755 vendor/gemoji/images/1f61d.png create mode 100755 vendor/gemoji/images/1f61e.png create mode 100755 vendor/gemoji/images/1f61f.png create mode 100755 vendor/gemoji/images/1f620.png create mode 100755 vendor/gemoji/images/1f621.png create mode 100755 vendor/gemoji/images/1f622.png create mode 100755 vendor/gemoji/images/1f623.png create mode 100755 vendor/gemoji/images/1f624.png create mode 100755 vendor/gemoji/images/1f625.png create mode 100755 vendor/gemoji/images/1f626.png create mode 100755 vendor/gemoji/images/1f627.png create mode 100755 vendor/gemoji/images/1f628.png create mode 100755 vendor/gemoji/images/1f629.png create mode 100755 vendor/gemoji/images/1f62a.png create mode 100755 vendor/gemoji/images/1f62b.png create mode 100755 vendor/gemoji/images/1f62c.png create mode 100755 vendor/gemoji/images/1f62d.png create mode 100755 vendor/gemoji/images/1f62e.png create mode 100755 vendor/gemoji/images/1f62f.png create mode 100755 vendor/gemoji/images/1f630.png create mode 100755 vendor/gemoji/images/1f631.png create mode 100755 vendor/gemoji/images/1f632.png create mode 100755 vendor/gemoji/images/1f633.png create mode 100755 vendor/gemoji/images/1f634.png create mode 100755 vendor/gemoji/images/1f635.png create mode 100755 vendor/gemoji/images/1f636.png create mode 100755 vendor/gemoji/images/1f637.png create mode 100755 vendor/gemoji/images/1f638.png create mode 100755 vendor/gemoji/images/1f639.png create mode 100755 vendor/gemoji/images/1f63a.png create mode 100755 vendor/gemoji/images/1f63b.png create mode 100755 vendor/gemoji/images/1f63c.png create mode 100755 vendor/gemoji/images/1f63d.png create mode 100755 vendor/gemoji/images/1f63e.png create mode 100755 vendor/gemoji/images/1f63f.png create mode 100755 vendor/gemoji/images/1f640.png create mode 100755 vendor/gemoji/images/1f645.png create mode 100755 vendor/gemoji/images/1f646.png create mode 100755 vendor/gemoji/images/1f647.png create mode 100755 vendor/gemoji/images/1f648.png create mode 100755 vendor/gemoji/images/1f649.png create mode 100755 vendor/gemoji/images/1f64a.png create mode 100755 vendor/gemoji/images/1f64b.png create mode 100755 vendor/gemoji/images/1f64c.png create mode 100755 vendor/gemoji/images/1f64d.png create mode 100755 vendor/gemoji/images/1f64e.png create mode 100755 vendor/gemoji/images/1f64f.png create mode 100755 vendor/gemoji/images/1f680.png create mode 100755 vendor/gemoji/images/1f681.png create mode 100755 vendor/gemoji/images/1f682.png create mode 100755 vendor/gemoji/images/1f683.png create mode 100755 vendor/gemoji/images/1f684.png create mode 100755 vendor/gemoji/images/1f685.png create mode 100755 vendor/gemoji/images/1f686.png create mode 100755 vendor/gemoji/images/1f687.png create mode 100755 vendor/gemoji/images/1f688.png create mode 100755 vendor/gemoji/images/1f689.png create mode 100755 vendor/gemoji/images/1f68a.png create mode 100755 vendor/gemoji/images/1f68b.png create mode 100755 vendor/gemoji/images/1f68c.png create mode 100755 vendor/gemoji/images/1f68d.png create mode 100755 vendor/gemoji/images/1f68e.png create mode 100755 vendor/gemoji/images/1f68f.png create mode 100755 vendor/gemoji/images/1f690.png create mode 100755 vendor/gemoji/images/1f691.png create mode 100755 vendor/gemoji/images/1f692.png create mode 100755 vendor/gemoji/images/1f693.png create mode 100755 vendor/gemoji/images/1f694.png create mode 100755 vendor/gemoji/images/1f695.png create mode 100755 vendor/gemoji/images/1f696.png create mode 100755 vendor/gemoji/images/1f697.png create mode 100755 vendor/gemoji/images/1f698.png create mode 100755 vendor/gemoji/images/1f699.png create mode 100755 vendor/gemoji/images/1f69a.png create mode 100755 vendor/gemoji/images/1f69b.png create mode 100755 vendor/gemoji/images/1f69c.png create mode 100755 vendor/gemoji/images/1f69d.png create mode 100755 vendor/gemoji/images/1f69e.png create mode 100755 vendor/gemoji/images/1f69f.png create mode 100755 vendor/gemoji/images/1f6a0.png create mode 100755 vendor/gemoji/images/1f6a1.png create mode 100755 vendor/gemoji/images/1f6a2.png create mode 100755 vendor/gemoji/images/1f6a3.png create mode 100755 vendor/gemoji/images/1f6a4.png create mode 100755 vendor/gemoji/images/1f6a5.png create mode 100755 vendor/gemoji/images/1f6a6.png create mode 100755 vendor/gemoji/images/1f6a7.png create mode 100755 vendor/gemoji/images/1f6a8.png create mode 100755 vendor/gemoji/images/1f6a9.png create mode 100755 vendor/gemoji/images/1f6aa.png create mode 100755 vendor/gemoji/images/1f6ab.png create mode 100755 vendor/gemoji/images/1f6ac.png create mode 100755 vendor/gemoji/images/1f6ad.png create mode 100755 vendor/gemoji/images/1f6ae.png create mode 100755 vendor/gemoji/images/1f6af.png create mode 100755 vendor/gemoji/images/1f6b0.png create mode 100755 vendor/gemoji/images/1f6b1.png create mode 100755 vendor/gemoji/images/1f6b2.png create mode 100755 vendor/gemoji/images/1f6b3.png create mode 100755 vendor/gemoji/images/1f6b4.png create mode 100755 vendor/gemoji/images/1f6b5.png create mode 100755 vendor/gemoji/images/1f6b6.png create mode 100755 vendor/gemoji/images/1f6b7.png create mode 100755 vendor/gemoji/images/1f6b8.png create mode 100755 vendor/gemoji/images/1f6b9.png create mode 100755 vendor/gemoji/images/1f6ba.png create mode 100755 vendor/gemoji/images/1f6bb.png create mode 100755 vendor/gemoji/images/1f6bc.png create mode 100755 vendor/gemoji/images/1f6bd.png create mode 100755 vendor/gemoji/images/1f6be.png create mode 100755 vendor/gemoji/images/1f6bf.png create mode 100755 vendor/gemoji/images/1f6c0.png create mode 100755 vendor/gemoji/images/1f6c1.png create mode 100755 vendor/gemoji/images/1f6c2.png create mode 100755 vendor/gemoji/images/1f6c3.png create mode 100755 vendor/gemoji/images/1f6c4.png create mode 100755 vendor/gemoji/images/1f6c5.png create mode 100755 vendor/gemoji/images/203c-fe0f.png create mode 100755 vendor/gemoji/images/203c.png create mode 100755 vendor/gemoji/images/2049-fe0f.png create mode 100755 vendor/gemoji/images/2049.png create mode 100755 vendor/gemoji/images/2122.png create mode 100755 vendor/gemoji/images/2139-fe0f.png create mode 100755 vendor/gemoji/images/2139.png create mode 100755 vendor/gemoji/images/2194-fe0f.png create mode 100755 vendor/gemoji/images/2194.png create mode 100755 vendor/gemoji/images/2195-fe0f.png create mode 100755 vendor/gemoji/images/2195.png create mode 100755 vendor/gemoji/images/2196-fe0f.png create mode 100755 vendor/gemoji/images/2196.png create mode 100755 vendor/gemoji/images/2197-fe0f.png create mode 100755 vendor/gemoji/images/2197.png create mode 100755 vendor/gemoji/images/2198-fe0f.png create mode 100755 vendor/gemoji/images/2198.png create mode 100755 vendor/gemoji/images/2199-fe0f.png create mode 100755 vendor/gemoji/images/2199.png create mode 100755 vendor/gemoji/images/21a9-fe0f.png create mode 100755 vendor/gemoji/images/21a9.png create mode 100755 vendor/gemoji/images/21aa-fe0f.png create mode 100755 vendor/gemoji/images/21aa.png create mode 100755 vendor/gemoji/images/231a-fe0f.png create mode 100755 vendor/gemoji/images/231a.png create mode 100755 vendor/gemoji/images/231b-fe0f.png create mode 100755 vendor/gemoji/images/231b.png create mode 100755 vendor/gemoji/images/23e9.png create mode 100755 vendor/gemoji/images/23ea.png create mode 100755 vendor/gemoji/images/23eb.png create mode 100755 vendor/gemoji/images/23ec.png create mode 100755 vendor/gemoji/images/23f0.png create mode 100755 vendor/gemoji/images/23f3.png create mode 100755 vendor/gemoji/images/24c2-fe0f.png create mode 100755 vendor/gemoji/images/24c2.png create mode 100755 vendor/gemoji/images/25aa-fe0f.png create mode 100755 vendor/gemoji/images/25aa.png create mode 100755 vendor/gemoji/images/25ab-fe0f.png create mode 100755 vendor/gemoji/images/25ab.png create mode 100755 vendor/gemoji/images/25b6-fe0f.png create mode 100755 vendor/gemoji/images/25b6.png create mode 100755 vendor/gemoji/images/25c0-fe0f.png create mode 100755 vendor/gemoji/images/25c0.png create mode 100755 vendor/gemoji/images/25fb-fe0f.png create mode 100755 vendor/gemoji/images/25fb.png create mode 100755 vendor/gemoji/images/25fc-fe0f.png create mode 100755 vendor/gemoji/images/25fc.png create mode 100755 vendor/gemoji/images/25fd-fe0f.png create mode 100755 vendor/gemoji/images/25fd.png create mode 100755 vendor/gemoji/images/25fe-fe0f.png create mode 100755 vendor/gemoji/images/25fe.png create mode 100755 vendor/gemoji/images/2600-fe0f.png create mode 100755 vendor/gemoji/images/2600.png create mode 100755 vendor/gemoji/images/2601-fe0f.png create mode 100755 vendor/gemoji/images/2601.png create mode 100755 vendor/gemoji/images/260e-fe0f.png create mode 100755 vendor/gemoji/images/260e.png create mode 100755 vendor/gemoji/images/2611-fe0f.png create mode 100755 vendor/gemoji/images/2611.png create mode 100755 vendor/gemoji/images/2614-fe0f.png create mode 100755 vendor/gemoji/images/2614.png create mode 100755 vendor/gemoji/images/2615-fe0f.png create mode 100755 vendor/gemoji/images/2615.png create mode 100755 vendor/gemoji/images/261d-fe0f.png create mode 100755 vendor/gemoji/images/261d.png create mode 100755 vendor/gemoji/images/263a-fe0f.png create mode 100755 vendor/gemoji/images/263a.png create mode 100755 vendor/gemoji/images/2648-fe0f.png create mode 100755 vendor/gemoji/images/2648.png create mode 100755 vendor/gemoji/images/2649-fe0f.png create mode 100755 vendor/gemoji/images/2649.png create mode 100755 vendor/gemoji/images/264a-fe0f.png create mode 100755 vendor/gemoji/images/264a.png create mode 100755 vendor/gemoji/images/264b-fe0f.png create mode 100755 vendor/gemoji/images/264b.png create mode 100755 vendor/gemoji/images/264c-fe0f.png create mode 100755 vendor/gemoji/images/264c.png create mode 100755 vendor/gemoji/images/264d-fe0f.png create mode 100755 vendor/gemoji/images/264d.png create mode 100755 vendor/gemoji/images/264e-fe0f.png create mode 100755 vendor/gemoji/images/264e.png create mode 100755 vendor/gemoji/images/264f-fe0f.png create mode 100755 vendor/gemoji/images/264f.png create mode 100755 vendor/gemoji/images/2650-fe0f.png create mode 100755 vendor/gemoji/images/2650.png create mode 100755 vendor/gemoji/images/2651-fe0f.png create mode 100755 vendor/gemoji/images/2651.png create mode 100755 vendor/gemoji/images/2652-fe0f.png create mode 100755 vendor/gemoji/images/2652.png create mode 100755 vendor/gemoji/images/2653-fe0f.png create mode 100755 vendor/gemoji/images/2653.png create mode 100755 vendor/gemoji/images/2660-fe0f.png create mode 100755 vendor/gemoji/images/2660.png create mode 100755 vendor/gemoji/images/2663-fe0f.png create mode 100755 vendor/gemoji/images/2663.png create mode 100755 vendor/gemoji/images/2665-fe0f.png create mode 100755 vendor/gemoji/images/2665.png create mode 100755 vendor/gemoji/images/2666-fe0f.png create mode 100755 vendor/gemoji/images/2666.png create mode 100755 vendor/gemoji/images/2668-fe0f.png create mode 100755 vendor/gemoji/images/2668.png create mode 100755 vendor/gemoji/images/267b-fe0f.png create mode 100755 vendor/gemoji/images/267b.png create mode 100755 vendor/gemoji/images/267f-fe0f.png create mode 100755 vendor/gemoji/images/267f.png create mode 100755 vendor/gemoji/images/2693-fe0f.png create mode 100755 vendor/gemoji/images/2693.png create mode 100755 vendor/gemoji/images/26a0-fe0f.png create mode 100755 vendor/gemoji/images/26a0.png create mode 100755 vendor/gemoji/images/26a1-fe0f.png create mode 100755 vendor/gemoji/images/26a1.png create mode 100755 vendor/gemoji/images/26aa-fe0f.png create mode 100755 vendor/gemoji/images/26aa.png create mode 100755 vendor/gemoji/images/26ab-fe0f.png create mode 100755 vendor/gemoji/images/26ab.png create mode 100755 vendor/gemoji/images/26bd-fe0f.png create mode 100755 vendor/gemoji/images/26bd.png create mode 100755 vendor/gemoji/images/26be-fe0f.png create mode 100755 vendor/gemoji/images/26be.png create mode 100755 vendor/gemoji/images/26c4-fe0f.png create mode 100755 vendor/gemoji/images/26c4.png create mode 100755 vendor/gemoji/images/26c5-fe0f.png create mode 100755 vendor/gemoji/images/26c5.png create mode 100755 vendor/gemoji/images/26ce.png create mode 100755 vendor/gemoji/images/26d4-fe0f.png create mode 100755 vendor/gemoji/images/26d4.png create mode 100755 vendor/gemoji/images/26ea-fe0f.png create mode 100755 vendor/gemoji/images/26ea.png create mode 100755 vendor/gemoji/images/26f2-fe0f.png create mode 100755 vendor/gemoji/images/26f2.png create mode 100755 vendor/gemoji/images/26f3-fe0f.png create mode 100755 vendor/gemoji/images/26f3.png create mode 100755 vendor/gemoji/images/26f5-fe0f.png create mode 100755 vendor/gemoji/images/26f5.png create mode 100755 vendor/gemoji/images/26fa-fe0f.png create mode 100755 vendor/gemoji/images/26fa.png create mode 100755 vendor/gemoji/images/26fd-fe0f.png create mode 100755 vendor/gemoji/images/26fd.png create mode 100755 vendor/gemoji/images/2702-fe0f.png create mode 100755 vendor/gemoji/images/2702.png create mode 100755 vendor/gemoji/images/2705.png create mode 100755 vendor/gemoji/images/2708-fe0f.png create mode 100755 vendor/gemoji/images/2708.png create mode 100755 vendor/gemoji/images/2709-fe0f.png create mode 100755 vendor/gemoji/images/2709.png create mode 100755 vendor/gemoji/images/270a.png create mode 100755 vendor/gemoji/images/270b.png create mode 100755 vendor/gemoji/images/270c-fe0f.png create mode 100755 vendor/gemoji/images/270c.png create mode 100755 vendor/gemoji/images/270f-fe0f.png create mode 100755 vendor/gemoji/images/270f.png create mode 100755 vendor/gemoji/images/2712-fe0f.png create mode 100755 vendor/gemoji/images/2712.png create mode 100755 vendor/gemoji/images/2714-fe0f.png create mode 100755 vendor/gemoji/images/2714.png create mode 100755 vendor/gemoji/images/2716-fe0f.png create mode 100755 vendor/gemoji/images/2716.png create mode 100755 vendor/gemoji/images/2728.png create mode 100755 vendor/gemoji/images/2733-fe0f.png create mode 100755 vendor/gemoji/images/2733.png create mode 100755 vendor/gemoji/images/2734-fe0f.png create mode 100755 vendor/gemoji/images/2734.png create mode 100755 vendor/gemoji/images/2744-fe0f.png create mode 100755 vendor/gemoji/images/2744.png create mode 100755 vendor/gemoji/images/2747-fe0f.png create mode 100755 vendor/gemoji/images/2747.png create mode 100755 vendor/gemoji/images/274c.png create mode 100755 vendor/gemoji/images/274e.png create mode 100755 vendor/gemoji/images/2753.png create mode 100755 vendor/gemoji/images/2754.png create mode 100755 vendor/gemoji/images/2755.png create mode 100755 vendor/gemoji/images/2757-fe0f.png create mode 100755 vendor/gemoji/images/2757.png create mode 100755 vendor/gemoji/images/2764-fe0f.png create mode 100755 vendor/gemoji/images/2764.png create mode 100755 vendor/gemoji/images/2795.png create mode 100755 vendor/gemoji/images/2796.png create mode 100755 vendor/gemoji/images/2797.png create mode 100755 vendor/gemoji/images/27a1-fe0f.png create mode 100755 vendor/gemoji/images/27a1.png create mode 100755 vendor/gemoji/images/27b0.png create mode 100755 vendor/gemoji/images/27bf.png create mode 100755 vendor/gemoji/images/2934-fe0f.png create mode 100755 vendor/gemoji/images/2934.png create mode 100755 vendor/gemoji/images/2935-fe0f.png create mode 100755 vendor/gemoji/images/2935.png create mode 100755 vendor/gemoji/images/2b05-fe0f.png create mode 100755 vendor/gemoji/images/2b05.png create mode 100755 vendor/gemoji/images/2b06-fe0f.png create mode 100755 vendor/gemoji/images/2b06.png create mode 100755 vendor/gemoji/images/2b07-fe0f.png create mode 100755 vendor/gemoji/images/2b07.png create mode 100755 vendor/gemoji/images/2b1b-fe0f.png create mode 100755 vendor/gemoji/images/2b1b.png create mode 100755 vendor/gemoji/images/2b1c-fe0f.png create mode 100755 vendor/gemoji/images/2b1c.png create mode 100755 vendor/gemoji/images/2b50-fe0f.png create mode 100755 vendor/gemoji/images/2b50.png create mode 100755 vendor/gemoji/images/2b55-fe0f.png create mode 100755 vendor/gemoji/images/2b55.png create mode 100755 vendor/gemoji/images/3030.png create mode 100755 vendor/gemoji/images/303d-fe0f.png create mode 100755 vendor/gemoji/images/303d.png create mode 100755 vendor/gemoji/images/3297-fe0f.png create mode 100755 vendor/gemoji/images/3297.png create mode 100755 vendor/gemoji/images/3299-fe0f.png create mode 100755 vendor/gemoji/images/3299.png create mode 100644 vendor/jquery.emojiarea/jquery.emojiarea-orig.js create mode 100644 vendor/jquery.emojiarea/jquery.emojiarea.js create mode 100644 vendor/jquery.nanoscroller/nanoscroller.css create mode 100644 vendor/jquery.nanoscroller/nanoscroller.js create mode 100644 vendor/jquery/jquery.min.js create mode 100644 vendor/jsbn/THIRDPARTY_LICENSE create mode 100644 vendor/jsbn/jsbn_combined.js create mode 100644 vendor/ui-bootstrap/THIRDPARTY_LICENSE create mode 100644 vendor/ui-bootstrap/ui-bootstrap-custom-0.7.0.js create mode 100644 vendor/ui-bootstrap/ui-bootstrap-custom-0.7.0.min.js create mode 100644 vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.7.0.js create mode 100644 vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.7.0.min.js create mode 100644 vendor/zlib/THIRDPARTY_LICENSE create mode 100644 vendor/zlib/gunzip.min.js create mode 100644 vendor/zlib/gzip.min.js diff --git a/css/app.css b/css/app.css new file mode 100644 index 00000000..c16bef1b --- /dev/null +++ b/css/app.css @@ -0,0 +1,1162 @@ +/* app css stylesheet */ + +html { + background: #dee4e9 url(../img/bg_tile.png?1) 0 0 repeat; + /*background: #dee4e9 url(../img/bg_full.png) 0 0 no-repeat;*/ + /*background-size: cover;*/ + /*background-size: contain;*/ + /*background-size: 248px 382px;*/ +} +body { + background: none; + + /*font: 12px/18px "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;*/ + /*font: 12px/18px Arial, "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, Verdana, sans-serif;*/ + font: 12px/18px "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, Verdana, sans-serif; + -webkit-font-smoothing: antialiased; +} +a { + color: #3a6d99; +} +a:hover { + color: #3a6d99; +} +a:hover { + cursor: pointer; +} +.form-control { + border: 1px solid #d9dbde; + border-radius: 2px; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} + +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.form-control:-moz-placeholder { + color: #9aa2ab; +} +.form-control::-moz-placeholder { + color: #9aa2ab; +} +.form-control:-ms-input-placeholder { + color: #9aa2ab; +} +.form-control::-webkit-input-placeholder { + color: #9aa2ab; +} + + +.btn-tg { + color: #ffffff; + background-color: #6AC065; + /*58b152*/ + border-color: #6AC065; +} + +.btn-tg:hover, +.btn-tg:focus, +.btn-tg:active, +.btn-tg.active, +.open .dropdown-toggle.btn-tg { + color: #ffffff; + background-color: #61b75b; + border-color: #61b75b; +} + +.btn-tg:active, +.btn-tg.active, +.open .dropdown-toggle.btn-tg { + background: #5aaf54; + background-image: none; +} + +.btn-tg.disabled, +.btn-tg[disabled], +fieldset[disabled] .btn-tg, +.btn-tg.disabled:hover, +.btn-tg[disabled]:hover, +fieldset[disabled] .btn-tg:hover, +.btn-tg.disabled:focus, +.btn-tg[disabled]:focus, +fieldset[disabled] .btn-tg:focus, +.btn-tg.disabled:active, +.btn-tg[disabled]:active, +fieldset[disabled] .btn-tg:active, +.btn-tg.disabled.active, +.btn-tg[disabled].active, +fieldset[disabled] .btn-tg.active { + background-color: #999; + border-color: #999; +} + +.font-light { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Light", Helvetica, Arial , Verdana, sans-serif; + font-weight: 300; +} + +.tg_page_head .container { + display: block; + width: auto; + padding: 0; +} +.tg_page_head .navbar-inverse { + /*-webkit-app-region: drag;*/ + background: #497495; + border: 0; + + -webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.11); + -moz-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.11); + box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.11); + + margin: 0; +} +.tg_page_head .navbar > .container .navbar-brand { + padding: 9px; + opacity: 0.9; + margin-left: 0; + -webkit-transition: opacity swing .9s; +} + +.tg_page_head .navbar > .container .navbar-brand-alpha { + color: #FFFFFF; + font-size: 12px; + padding-left: 5px; +} + +.tg_head_logo { + background: url(../img/Logo_2x.png) 0 0 no-repeat; + background-size: 110px 31px; + display: inline-block; + width: 110px; + height: 31px; +} + +.tg_page_head .navbar > .container .navbar-brand:hover { + opacity: 1; +} + +.tg_page_head .navbar-inverse .navbar-nav > li > a { + color: #b9cfe3; + font-size: 13px; +} +.tg_page_head .navbar-inverse .navbar-nav > li > a:hover { + color: #FFF; +} + +.tg_progress { + height: 12px; + margin: 0; + padding: 0; + background: rgba(255,255,255, 0.4); + border: 5px solid rgba(0,0,0, 0.5); + border-radius: 3px; +} +.tg_progress .progress-bar { + height: 2px; + line-height: 2px; + background: rgba(255,255,255, 0.9); + border-radius: 2px; + overflow: hidden; +} + +.modal-content { + border-radius: 4px; + -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); +} +.modal_close_wrap { + cursor: pointer; + position: fixed; + top: 0; + right: 0; + width: 50%; + height: 100%; +} +.modal_close { + background: url(../img/icons/CloseHover_2x.png) 0 0 no-repeat; + background-size: 33px 33px; + width: 33px; + height: 33px; + float: right; + margin: 60px 10px 0 0; + opacity: 0.5; + + -webkit-transition : .2s; + -moz-transition : .2s; + -o-transition : .2s; + transition : .2s; +} +.modal_close_wrap:hover .modal_close { + opacity: 1; +} + +.modal-header { + padding: 12px 0 4px 3px; + border-bottom: 2px solid #E1E1E1; + margin: 0 18px; +} +.modal-title { + font-weight: bold; + font-size: 17px; + line-height: 1.4; +} + +.modal-close-link { + font-size: 12px; + line-height: 1.4; + float: right; + padding: 0 2px 0; + margin: 6px 2px 0 0; +} +.modal-close-link:hover { + text-decoration: none; +} + + +.img_fullsize_with_progress_wrap { + position: relative; + /*margin: 0 auto 20px;*/ + margin: 0 auto; +} +.img_fullsize_progress_overlay { + position: absolute; + width: 100%; + height: 100%; +} +.img_fullsize_progress_wrap { + background: rgba(0,0,0, .1); + position: relative; +} +.img_fullsize_progress { + position: absolute; + bottom: 15px; + left: 50%; + width: 190px; + margin-left: -95px; +} + + +/* Welcome */ +.jumbotron { + background: none; +} + +/* Login page */ +.login_form_wrap { + max-width: 310px; + padding: 25px; + background: #FFF; + margin: 200px auto 0; + border-radius: 3px; + overflow: hidden; + + -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); +} +.login_form_head { + color: #222222; + margin-top: 0; + text-align: center; +} +.login_form_lead { + color: #959595; + text-align: center; + margin: 15px 0 30px; + font-size: 13px; +} + + +/* IM page start */ + + + +.im_page_wrap { + background: #FFF; + max-width: 1000px; + margin: 0 auto; + + -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); + margin-bottom: 40px; + + border-radius: 0 0 3px 3px; + overflow: hidden; +} + +.im_dialogs_col_wrap { + float: left; + width: 310px; + border-right: 2px solid #E9EBED; + padding-bottom: 10px; +} + +.im_history_col_wrap { + float: left; + width: 690px; +} + + +/* Dialogs list */ + +.im_dialogs_col .nano > .pane { + background : rgba(0,0,0,.0); + width : 12px; + right: -7px; + -webkit-transition : .2s; + -moz-transition : .2s; + -o-transition : .2s; + transition : .2s; + -moz-border-radius : 0; + -webkit-border-radius : 0; + border-radius : 0; +} +.im_dialogs_col .nano > .pane > .slider { + background: #A5B1B9; + margin: 0 5px; + -moz-border-radius : 0; + -webkit-border-radius : 0; + border-radius : 0; +} + +.im_dialogs_search { + padding: 14px 12px; + /*border-right: 2px solid #E9EBED;*/ +} +.im_dialogs_search_field { + font-size: 12px; + line-height: normal; + background: #F2F2F2 url(../img/icons/Search_2x.png) 7px 9px no-repeat; + background-size: 15px 14px; + border: 1px solid #F2F2F2; + border-radius: 3px; + padding: 6px 6px 6px 30px; + margin-bottom: 0; + margin: 0; +} +.im_dialogs_search_field:focus, +.im_dialogs_search_field:active { + background-color: #FFF; +} + + + +.im_dialogs_wrap { + overflow: visible; + overflow-x: visible !important; + overflow-y: visible; +} +.im_dialogs_scrollable_wrap { + /*border-right: 2px solid #E9EBED;*/ + padding: 0 12px; + outline: none ! important; + overflow-x: visible; +} +.im_dialogs_scrollable_wrap .nav-stacked > li + li { + margin-top: 0; + margin-left: 0; +} + +.im_dialogs_scrollable_wrap a.im_dialog { + color: #000; + padding: 8px 9px; + border-radius: 0; + border-bottom: 1px solid #FFF; +} +.im_dialogs_scrollable_wrap li:last-child a.im_dialog { + border-bottom: 1px solid #FFF; +} + +.im_dialogs_scrollable_wrap a.im_dialog:hover, +.im_dialogs_scrollable_wrap .active a.im_dialog { + margin-top: -1px; + overflow: hidden; +} +.im_dialogs_scrollable_wrap a.im_dialog:hover { + background: #f2f6fa; + border-top: 1px solid #f2f6fa; + border-bottom-color: #f2f6fa; +} +.im_dialogs_scrollable_wrap .active a.im_dialog { + border-radius: 2px; + background-color: #5785A5; + border-top: 1px solid #5785A5; + border-bottom-color: #5785A5; +} +.im_dialogs_scrollable_wrap .active a.im_dialog:hover { + background-color: #5785A5; +} +.im_dialogs_scrollable_wrap li:first-child a.im_dialog, +.im_dialogs_scrollable_wrap .active + li > a.im_dialog { + margin-top: 0; + border-top: 0; +} + +.im_dialogs_scrollable_wrap a.im_dialog .icon, +.im_dialogs_scrollable_wrap a.im_dialog .glyphicon { + display: none; +} + +.im_dialog_message_wrap { + overflow: hidden; + word-wrap: break-word; +} +.im_dialog_chat_from_wrap, +.im_dialog_message_media, +.im_dialog_message_service { + color: #3a6d99; +} +.im_dialog_message_text { + color: #808080; +} +a.im_dialog:hover .im_dialog_message_text { + color: #698192; +} +.active a.im_dialog .im_dialog_chat_from_wrap, +.active a.im_dialog .im_dialog_message_media, +.active a.im_dialog .im_dialog_message_service, +.active a.im_dialog .im_dialog_message_text { + color: #FFF; +} +.im_dialog_photo { + width: 40px; + height: 40px; + border-radius: 2px; + overflow: hidden; + margin: 0 10px 0 0; + +} +.im_dialog_peer { + font-weight: bold; + margin-top: 2px; + margin-bottom: 2px; +} + +.im_dialog_badge { + background: #75BB72; + border-radius: 2px; + font-size: 10px; + padding: 3px 4px; + margin-top: 4px; +} +.active .im_dialog_badge { + color: #428bca; + background-color: #fff; +} +.im_dialog_date { + font-size: 0.8em; + visibility: hidden; +} + +.im_dialog_service { + font-style: italic; + color: #999; +} +.im_dialog_message, +.im_dialog_peer { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.icon-group { + display: inline-block; + width: 18px; + height: 12px; + margin-top: 3px; + line-height: 14px; + vertical-align: text-top; + background: url(../img/icons/DialogListGroupChatIcon@2x.png) 0 0 no-repeat; + background-size: 18px 12px; +} +.active .icon-group { + background-image: url(../img/icons/DialogListGroupChatIcon_Highlighted@2x.png); +} + +/* IM history */ +.im_history_col { + padding: 0 8px 0 15px; +} + +.im_history_col .nano > .pane { + /*background : rgba(0,0,0,.0);*/ + background: #E9EBED; + width : 9px; + top: 10px; + /*margin-top: 10px;*/ + /*bottom: */ + -webkit-transition : .2s; + -moz-transition : .2s; + -o-transition : .2s; + transition : .2s; + -moz-border-radius : 2px; + -webkit-border-radius : 2px; + border-radius : 2px; +} +.im_history_col .nano > .pane > .slider { + background: #B3BFC7; + margin: 0; + -moz-border-radius : 2px; + -webkit-border-radius : 2px; + border-radius : 2px; +} + +.im_history_panel_wrap { + position: relative; + -webkit-box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.12); + -moz-box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.12); + box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.12); + margin-right: 15px; +} +.im_history_panel { + padding: 10px 4px 0; +} +.im_history_panel_title h4 { + color: #333333; + margin-bottom: 7px; + font-size: 17px; +} +.im_history_panel_title h4 small { + color: #999; + font-size: 13px; + margin-left: 5px; +} +.im_history_panel_info_link { + /*color: #999;*/ + font-size: 13px; + font-weight: normal; + padding-top: 5px; + line-height: 1; +} +.im_history_panel_info_link:hover { + text-decoration: none; +} + + +.im_history_wrap { + overflow: hidden; + /*overflow-y: scroll;*/ +} +.im_history_scrollable_wrap { + outline: none ! important; + -webkit-user-select: text; +} + +.im_history_to_bottom { + position: relative; +} +.im_history_to_bottom .im_history_scrollable { + position: absolute; + bottom: 0; + width: 100%; +} +.im_history { + padding: 20px 0 0 3px; + /*max-width: 555px;*/ + max-width: 500px; + margin: 0 auto; +} + +.im_history_typing_wrap { + margin-top: 13px; + height: 18px; + line-height: 18px; + width: 100%; + margin-bottom: 13px; + overflow: hidden; +} +.im_history_typing { + font-size: 11px; + color: #999; + max-width: 495px; + margin: 0 auto; + + padding: 0 40px 0 47px; +} + +/*.im_history_typing { + -webkit-transition:all swing .2s; + -moz-transition:all swing .2s; + -ms-transition:all swing .2s; + -o-transition:all swing .2s; + transition:all swing .2s; +} +.im_history_typing.ng-enter { + opacity: 0; +} +.im_history_typing.ng-enter.ng-enter-active { + opacity: 1; +} +.im_history_typing.ng-leave { + opacity: 1; +} +.im_history_typing.ng-leave.ng-leave-active { + opacity: 0; +} + + +.im_history_message_wrap { + -webkit-transition:all swing .2s; + -moz-transition:all swing .2s; + -ms-transition:all swing .2s; + -o-transition:all swing .2s; + transition:all swing .2s; +} +.im_history_message_wrap.ng-enter { + position: relative; + bottom: -100px; + overflow: hidden; + opacity: 0; +} +.im_history_message_wrap.ng-enter.ng-enter-active { + bottom: 0; + opacity: 1; +} +.im_history_message_wrap.ng-leave { + opacity: 1; +} +.im_history_message_wrap.ng-leave.ng-leave-active { + opacity: 0; +}*/ + + + +.im_message_author { + color: #3a6d99; + font-weight: bold; +} + +.im_message_from_photo, +.im_message_contact_photo { + width: 34px; + height: 34px; + + border-radius: 2px; + overflow: hidden; +} +a.im_message_from_photo, +a.im_message_contact_photo { + margin: 1px 12px 0 0; +} +.im_message_contact_name { + color: #3C6E97; + font-weight: bold; +} +a.im_message_photo_thumb, +a.im_message_video_thumb { + display: block; + margin-top: 5px; + overflow: hidden; + border-radius: 2px; +} +img.im_message_photo_thumb, +img.im_message_video_thumb { + overflow: hidden; + border-radius: 2px; +} + +div.im_message_video_thumb { + position: relative; +} +.im_message_video_duration_wrap { + background: rgba(0, 0, 0, 0.5); + color: #FFF; + position: absolute; + margin-top: -15px; + height: 15px; + padding: 0 3px; + font-size: 11px; + line-height: 15px; + + border-radius: 0 0 2px 2px; + overflow: hidden; +} +.im_message_video_duration { + +} + +.im_message_geopoint { + border-radius: 2px; + margin-top: 5px; + overflow: hidden; + display: block; + position: relative; + width: 200px; + height: 100px; +} +.icon-geo-point { + position: absolute; + display: inline-block; + top: 50%; + left: 50%; + margin-left: -5px; + margin-top: -7px; + width: 10px; + height: 14px; + + background: url(../img/icons/Location_Active.png) 0 0 no-repeat; + background-size: 10px 14px; +} + + + +.im_message_document { + margin-top: 3px; + border-radius: 3px; + display: inline-block; + line-height: 0; +} +.icon-document { + display: inline-block; + width: 38px; + height: 38px; + vertical-align: text-top; + background: #F2F2F2 url(../img/icons/DocGrey_2x.png) 8px 10px no-repeat; + background-size: 20px 20px; + border-radius: 3px; + margin-right: 0; +} +.im_message_document .icon-group { + background-image: url(../img/icons/DialogListGroupChatIcon_Highlighted@2x.png); +} +.im_message_document .im_message_document_name { + color: #999; + vertical-align: text-top; + display: inline-block; + line-height: 20px; + padding: 9px 5px 9px 0; + max-width: 200px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.im_message_document:hover, +.im_message_document:hover .icon-document { + background: #EBF0F5; + text-decoration: none; +} +.im_message_document:hover .icon-document { + background: #EBF0F5 url(../img/icons/DocBlue_2x.png) 8px 10px no-repeat; + background-size: 20px 20px; +} +.im_message_document:hover .im_message_document_name { + color: #698192; +} +.im_message_document_name strong { + color: #000; + padding-right: 3px; +} + + +.im_service_message_wrap { + text-align: center; +} +.im_service_message { + display: inline-block; + min-width: 10px; + padding: 4px 7px; + line-height: 1.4; + color: #999; + text-align: center; + border-radius: 10px; + margin: 5px 0; +} + +.im_service_message_photo_thumb { + display: block; + width: 100px; + margin: 0 auto; +} + + + +.im_content_message_wrap { + margin: 10px 0 5px; +} +.icon-message-status-unread { + background: #43A4DB; + border: 1px solid #FFF; + display: block; + width: 11px; + height: 11px; + border-radius: 5px; + overflow: hidden; + position: absolute; + margin-left: -27px; + margin-top: 14px; +} +.icon-message-status-tick { + /*display: inline-block;*/ + display: none; + width: 16px; + height: 10px; + background: url(../img/icons/Checks2_2x.png?1) 0 0 no-repeat; + background-size: 16px 10px; + top: 2px; + position: relative; +} +.icon-message-status-tick.message-status-unread-tick { + /*width: 13px;*/ + background: url(../img/icons/Checks1_2x.png?1) 0 0 no-repeat; + background-size: 16px 10px; +} +.im_message_date { + color: #adadad; + font-size: 0.9em; + /*font-size: 0.8em;*/ +} +div.im_message_author, +div.im_message_body { + border-radius: 2px; + display: block; + overflow: hidden; +} + +.im_message_text { + word-wrap: break-word; +} + +span.emoji { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + *vertical-align: auto; + *zoom: 1; + *display: inline; + height: 18px; + width: 18px; + background-size: 18px; + background-repeat: no-repeat; + text-indent: -9999px; +} + +.im_history_not_selected { + text-align: center; + color: #999; + font-size: 1.5em; + padding: 200px 50px 0; +} + +.im_send_form_wrap { + /*width: 581px;*/ + width: 526px; + margin: 0 auto; + padding: 10px 12px 22px 0; +} +.im_send_form { + /*width: 444px;*/ + width: 389px; + float: left; +} +.im_submit { + padding: 5px 12px; + font-size: 13px; + line-height: 17px; +} + +.im_send_dropbox_wrap { + background: #FFF; + display: none; + padding: 15px 10px; + margin: 1px; + border-radius: 4px; + overflow: hidden; + text-align: center; + color: #999; + position: absolute; +} +textarea.im_message_field { + font-size: 12px; + margin-bottom: 10px; + padding: 6px; + min-height: 50px; + height: 50px; + resize: none; +} +.im_attach { + cursor: pointer; + display: block; + overflow: hidden; + position: relative; + padding: 0 2px; + + width: 23px; + height: 23px; + margin-top: 4px; +} + +.icon-paperclip { + display: inline-block; + width: 19px; + height: 22px; + vertical-align: text-top; + background: url(../img/icons/Attach_2x.png) 0 0 no-repeat; + background-size: 19px 22px; +} +.im_attach:hover .icon-paperclip { + background-image: url(../img/icons/Attach_pressed_2x.png); +} + +.im_emoji_btn { + cursor: pointer; + padding: 0 2px; + + width: 23px; + height: 23px; + margin-top: 4px; + margin-left: 15px; +} +.icon-emoji { + display: inline-block; + width: 22px; + height: 22px; + vertical-align: text-top; + background: url(../img/icons/Smile_2x.png) 0 0 no-repeat; + background-size: 22px 22px; +} +.im_emoji_btn:hover .icon-emoji { + background-image: url(../img/icons/Smile_pressed_2x.png); +} + +.im_attach_input { + cursor: pointer; + font-size: 72px !important; + /*visibility: hidden;*/ + opacity: 0.01; + position: absolute; + z-index: 100; + margin: 0; + padding: 0; + + right: 0; +} + +.im_panel_peer_photo, +.im_panel_own_photo { + width: 50px; + height: 50px; + border-radius: 3px; + overflow: hidden; +} +div.im_panel_peer_photo { + cursor: pointer; + margin-left: 12px; + height: 55px; +} +div.im_panel_own_photo { + margin-right: 12px; +} + +.im_panel_peer_online { + background: #6DBF69; + border: 1px solid #FFF; + display: block; + width: 11px; + height: 11px; + border-radius: 5px; + overflow: hidden; + position: absolute; + margin-top: -7px; + margin-left: 43px; +} + + +.media_modal_wrap .modal-body { + padding: 19px 18px 17px; +} +a.img_fullsize { + display: block; + text-align: center; +} +img.img_fullsize { + margin: 0 auto; +} +.media_modal_info { + color: #777; + margin: 20px 0 0; +} +.media_modal_author { + font-weight: bold; +} + +.user_modal_window .modal-dialog { + padding-top: 150px; + max-width: 506px; +} +.user_modal_wrap .modal-body { + padding: 23px 25px 70px; +} +.user_modal_image_wrap { + width: 120px; + margin-right: 22px; +} +.user_modal_image { + width: 120px; + height: 120px; +} +.user_modal_header { + margin: 0 0 5px; +} +.user_modal_status { + color: #999; +} +.user_modal_send_btn { + padding-left: 0; + padding-right: 0; + font-size: 12px; + margin-top: 8px; +} + + +.chat_modal_window .modal-dialog { + max-width: 506px; +} +.chat_modal_wrap .modal-body { + padding: 23px 25px 15px; +} +.chat_modal_image_wrap { + width: 120px; + margin-right: 22px; +} +.chat_modal_image { + width: 120px; + height: 120px; +} +.chat_modal_header { + margin: 0 0 5px; +} +.chat_modal_members_count { + color: #999; +} +.chat_modal_invite_btn { + padding-left: 0; + padding-right: 0; + font-size: 12px; + margin-top: 8px; +} + +.chat_modal_members_header { + margin-top: 15px; +} + +.chat_modal_participant_wrap { + padding: 8px 7px; + border-top: 1px solid #E0E0E0; +} +.chat_modal_participant_name { + color: #3C6E97; + font-weight: bold; + margin: 4px 0 5px; +} +.chat_modal_participant_status { + color: #999; +} +.chat_modal_participant_photo { + width: 50px; + height: 50px; + margin-right: 10px; + overflow: hidden; +} + + + + + +/* Emoji area */ +.emoji-wysiwyg-editor:empty:before{ + content:attr(placeholder); + color: #9aa2ab; +} + +.emoji-wysiwyg-editor { + font-size: 12px; + margin-bottom: 10px; + padding: 6px; + min-height: 50px; + height: 50px; + resize: none; + overflow: auto; + + border: 1px solid #d9dbde; + border-radius: 2px; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} +.emoji-wysiwyg-editor img { + width: 20px; + height: 20px; + vertical-align: middle; + margin: -3px 0 0 0; +} +.emoji-menu { + position: absolute; + z-index: 999; + width: 180px; + padding: 5px 2px 5px 5px; + margin-left: -88px; + margin-top: -225px; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + background: rgba(0,0,0, 0.7); + overflow: hidden; +} +.emoji-menu .emoji-items-wrap { + position: relative; + height: 190px; +} +.emoji-menu .emoji-items { + padding-right: 8px; +} +.emoji-menu img { + width: 20px; + height: 20px; + vertical-align: middle; + border: 0 none; +} +.emoji-menu a { + margin: -1px 0 0 -1px; + /*border: 1px solid #f2f2f2;*/ + padding: 4px; + display: block; + float: left; + border-radius: 2px; +} +.emoji-menu a:hover { + background-color: rgba(0,0,0, 0.5); + /*background-color: #fffae7;*/ +} +.emoji-menu:after { + content: ' '; + display: block; + clear: left; +} +.emoji-menu a .label { + display: none; +} + + +.emoji-menu .nano > .pane { + background : rgba(255,255,255,.0); +} +.emoji-menu .nano > .pane > .slider { + background: rgba(255,255,255,0.4); + /*background: #A5B1B9;*/ + /*margin: 0 5px;*/ + /*-moz-border-radius : 0; + -webkit-border-radius : 0; + border-radius : 0;*/ +} \ No newline at end of file diff --git a/img/Logo_1x.png b/img/Logo_1x.png new file mode 100755 index 0000000000000000000000000000000000000000..f099252dbf8727981b381af55271d7609668cfb8 GIT binary patch literal 1550 zcmV+p2J!icP)`lH%4Mk~Esw^^q77)Lj!b z7((J2VeDbjQzp|M)+4gn=rn{ z0=4TUZUw_*V=yPrI&TkDucsW~?(21Jt6^LjOq+5&Yfy7n5VYkC`w5B}rjGP%_qkQ_QA(S~mfWF;4X zak*Gr!)OPXJZU1-Et~^O@0tx$t3&6{AME|ji!>p;zH3r&uT=R_tP#`XynUs)O0ktC zEtTUd;C}N~sJ$}+^CP#ow%N7s2bn}gR#GmOW4oNcqLLF+w!XT1?sRy0-AdT;*3o;UG0OU?n#R{e(fDp)-KHf0TF_IFE%NKK@Pm2DG+q;RDRMY&~> z!XoF9>w+wya6wuliK#6(uGhWLL}@z7c2j6IVI-#2(XXBmoWc7}kdV-c=VF|=3NLLO z=^IeiAh)#kgE`se6`F{PlGSQDN(2+HTP_L~vC<$GlP8vwCy5VDgwh3wOF6RJJT8JT zu_|zJ$3Te8I-Y@E=VOF9aYJ6(cyD_fb9*^xdNc}=X;Y*$`0e*U!^u;pWfiXLl~0(& zxR_)gll0AaSdKA@jMa9DpJ60WTkXh+J6fng_o3e*{_56|4DzXm?u8pe*A*O4BAcYr zr#U%EJKT>ru&JRFpuhNMWBKwVLP?B{8rO z+t?(@X_UODMq<@T$7VuF+iqp}u@HZ0`jtw@m5b&=V$FrkkDkMQ(6I3X+3tL?@H(T{ zhmVB}qI6p!v7lLHu_QuRpoOJ`%-C9!6Y*N-YlaS$j-R)8!7so5N!;X*s@B%)({4~6 z-DXxX8x(ykm+Uj<_}}ajyNZpi^=$-wANQ%$CFF^LhcW%xEq4`Lg`kwCTn%D(~(07P7d{X-4H`v3p{07*qoM6N<$g0^bq AQUCw| literal 0 HcmV?d00001 diff --git a/img/Logo_2x.png b/img/Logo_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..f93dd4ecc7c6aeae2c4747c993ccf89405c8d4b6 GIT binary patch literal 2857 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 Hu0mjfqrQ6p literal 0 HcmV?d00001 diff --git a/img/bg_full.png b/img/bg_full.png new file mode 100644 index 0000000000000000000000000000000000000000..30c0042917dffc6d264bf6d3e80586d0cf31999b GIT binary patch literal 587517 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%0AGhcb$Z6*Fz5wTaGG%+ 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 +x}i`7x-fp>_i& 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�L7$x-{!~^h@&ORHB|z`Dn7bqsyBOS31M5 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ȼMpPz$h`R12 z6-aU>wWHB=3W&ERpCJA;6v9)DCTybb2!m2#)_gHY3Y0e<{0yZ1&x2=y78(A2s<$6h zk9EpO65HhEkV7DZG+_-S<}OUYh~8D6}IWQJShvS{8~pk?0YxK@?fWiN@cHT%<5qFrd3r*W^6|Sw{j-D=(GnnIbObkK8Do zE+}(1w*#L7mt`4RHP-ez7U+|Rs7g{>-IBnzO=NMyL9+gU z_O)8KM1(+A*;y8*NWNR7=9k33H_gon7B0v|q-)2v4D3RXoMJ>fC*1GCqO4U|($EF* z-+Dc?5C{3DuGLFTw3!3~m;V}9&7kw|)R={%1BhOR3f`C8KO~#x#}+5I#_jW31YuW* zZd#-5hkYF{+xs#dwqPP;2*ol>CnF_`j7P@3ld#p29iYPhpS>?pZyeW|6{*d3dhYu_ z=YKl!qJ>vg04UnA9WU~hw$3+arqhXIOC$&s3RVC5h5I8KK;yydbi^Ivs|ytmU8+y! zT#LJV-aQh=`>^@m)SdM0~-HI00Q-<9o7!kupr!R_TNXD{f9QQ zmx2O+k9-798PSM-LTjvI`oJt`6+R@#{Ck<|0&JI#pq}#9(kFW7_-NUOb(;p6WV z+nk_C#j}p917F&{B z-Tz)%Od|2Rbe#G%Yadf%x5?l}2OFNjapK2wQO9Ms(JL)*b)wIZbaZ-{K;%9W&}~B8 zxR2q7=Q{N>A;Mo)&k>t2#MFtT#Bk^0IDC^bDi|?3@97x!Le*hwN=kobl8JzdKHgYnF&QPSp-|s{Iox*~q&*F5$fS zIBD^$RiSZiW_?ZD6F^$?J>sCI3f<|@0mgC}yr_RtkdDD|rU0pu#*y$EH{{#vBm)_yL4$wKs`A%qPQA)d&h9?xRPYta6c~0|dXO@Ll-PP|^^;P95AWsgcQzV(arxS-lp;zUi$X_5vUW zFJ{jjuY#FT*J6Q_WemQlE^DLqH>Oh1g2CdQmwC4q|byxTf7 zjH_q+#XGl?Xvp_vYb< z@vSfOM8y01t5dBu^=4Dr?#Wk>$P2hQOtVscn!X>UUEoO)jRjnR>rdsJ*=F>Q14wNG0xQ2?0xNDBNUcY^0>8?z3wfW;z7mdU88zB zfGtDN<?8eBqWA8!?wHUc_z(`ytgjdnWV^ z>jLO=(}+;46vw*1HI}~u3To4WuxK$e`kC^5Y|lvI)#%X1ecH2zNEv~?Q>z@Fc|p|Y zf%cR|{zS1UM6uTN*^_@8?`L4*gn<{6Y*{+#TJXP@EAG*mYP-?L68Ql*Swk|3zXwoa z9N)VpSXcn)bAFMV)Du0Z>+&JqPbOrDO^BfVSB;ZP9V@28`bIKwENDY3YCNRRFD_^# zHixvNW@W`2E!Hve5HacE-JU+U1_Y-g>_z5}Rtw;DL0Hb4FW#nAq~HOEglb0dv-#KI zBH5q=Rq#KTZ2tk>!q+}N<`FUBI)H|ga=3O;z4x_0%c@nEXQ^6lF_2|WCoo|WEM)jm z12#mi%yIBBUZ(Mzw35-e-K zKm`~{#(%>h#)S~FhkDlGV#YcoSh!&xoGEXDiEV5N+Qr4A2-7ik7!pTJ2X^qu@^V19 zBmR80Ks(iE`YCXXtPOW@rhN7NLk6$fS5@(Pu#z9@YU`m6D&vrsP+wFQK4(brr`0B zkffvV=ik@$6{_wduea??+M!q7tbTMHQ9)|?_jdQf_V7~=6t10^3MV>A=ShY?#uhhTxT3e`#5-cDt^smYVHF~5O@VNl>*Gvtd-{;(ANfwfXb;2JZg4K&8$*d@;|AscKi3iJwxwHXs?{|eFMRmX6 zG%z?3;Rz=It>nRH1I1vY5-MyZfD)09#NQBOWJ3-X5=N{+1bBLd7VmcSKb#`QJp+9? z5UGo3QzPgW&JDELvCmM@_f`0DI)0aQZt@kDM75oonFq1ILIQ=gn->+66w#pc`;*uw zPF9h79E;;M&fkzJ0_PREl0v6Z9`+agYDILE(}ZdQz2Kj(KPQTF1I=2^5^EB}>Zh0} z*j*4#Nz33im7Sm%RRvKo$G$BpP0Y|iQ_HvqKV|6Q423omzdV)OW9rh6xR=tV?AX$% z%kt=ez$;a`Xc6Ms+Qf+0O6@JfaNR`>wS2D0Ya6R#6kNf^(371ZCtxZ>x+z1}oUOt64_2|qWZ7a@`VPvY*2ToEGul1gg+izeyfq$zko`CD*u>idc! z1$)Oxu{IrLfluzcX!wL1iU8kwZ$LYzQD07cUc^41yC1Da5X3R?^F_MCM!6j||GR6K zVy>LOT?78L%g`yTDIDZj6V|HRS18(AG`R#rraE&&>81S#17~z;a@8`7+^Jk_=JpA3 zzj7>envYEBfpKU6&0vv!F=-fs^-A}>?24Ta>J6r1E6l9s!m zQ9yq?l?pJg!4w4+@lj7&1osX(yxC~E6M0>~@vh1~1lQJhY+>*HhVEgXRYS3ZZ-Qv8 z>0RL-qiFiy=NIoIb+N?kINGOSuTo=kcutqlcTV~VK#@qUkfhvFFUU4pr;`ofF)(|~ z1TxLf=!pguI$gPj(BPt&Z7EUTBZGHOyEKLHjj20SRHK6VJ8_uqfC=J98Cz!I*WTZ2 z_fgQqWM50&^k{B5UC2&gFP2m?5!h?2D;a<#{w=e-fz{9K;ClhOk11fUs@=k?5#!m9 zxfe1mM#t+~w8e(+HxB4C=}ujfRP{FI4^@BV;_aLCvsM{VPHhqUC~h2nbu5wzJ@toO zW}GzjD(BG?l@S?-P2bSy+8IwO_tAGS-$7K;1moX8=>@T~BvZ88z9Yi8kJ!7SgH@;! zK%h`*+KuBdl>U4dhgcfkS;#b9YFBsCPf*2m`1har>}IGBu7-YiExA#hRi9`o~c8;j;nF!s{2sYw{oQOppk)i5aoz0m`9eYUH~`JCHuebTm3`?Y)>fm;Zn^ zolK`Wo~{2Io)O{_E)@EPeq)S8X~mw7N2KP4!b?jZuCk_S^IDrv<-{U!JWb>h88O)I)x zdm+z4vG)Q6SrbV!7jhFoy)`%61Q06_6&j*qd+S z5X6!A6vN*aLu?8M5{^oJ8_gvE7YbCo4q6eg@vuF}YMSjxX%QA}u7>iXr|PrDlb}MF zNP=(!%StrBXulN>abd#IWKFEWJY_9_T4D{X75xKesrrQm-iF#$epoLW55kG}?0s1= z<4=fl<2eTuxsUOPU3$60TG%Ks6b&ATQ+Qj%^6=8l^y8%gDX!hB#Vh^@k+h z&^SU;g0>o@WAND_*i0vi&t^ni`=%h z2*s6_7G9PcB%kn8UjT-)nBTdq6c1cJ9H=6Dma<17Lfa95-=nUXs{Z zrfcY(TuqRr$Y$-tt|8YphTiL{uGGUSk9*0yDQ)6~)(!Lg?t!&4%__Ft3x0-A_;-HH z9*UaSlH@SU4O=6o<=3hCEB=k-2G0uLh|fAw_>+L?gjhzh3LcR zL>s4hynm@p!9*wYQQaQaEg<4eZTcFbz?`aPD`}4{DzqSm!?UO*c{LxtcV0EkwO%!B z?^ur>#AQPqa2eu@L)$3=GdvAir{GyovAn<5zQ@$D zy*@tspN~2372CSQy{^w(t61lB%c!b%0Q;pE)&=qjLzXEaqXQFILnhU|BhU{7OdL53W8U$DKA z7M~e4Q}b{5Gm~WoYR3dgxJMiQ%wl+rxgtz#?S1w99ubcW+20}9|2OPMa2}DEfqy44 z&L=HMnbIaAl#BZN-_LG%ojH@>uQ+8`iRtzOVj=Ds+N36ydiQRC{yOYA9GZAO6p9}9 zSUB;yi#1xSM&oaR*WY;I+$*7dx!iEyLP*?c3(E|kQ@t@en|HsKo(F5?R9-r0QS4ic z&@e%wbcz*@y(t>$HbPJpv`Q3Z*<$o6Sb)i(X4IOopGSr{*Q&^_PW4kHS-8BYH5F-p z$G{XH9=ymn738_OKgqS2on4Jm=oN(9A;{6Hq!exfFtLxtg7*gpJQCwPA3dd**paOJ zhOU0Tzhm`-01Qchk*{WjhoBYMxOlGi^|~&ywwGxtd$w40UM-vOPuq>Aq~cxon4$qi z6Ao>*v4;1@1YCJozx^U7k)-J=Dl`^>RBo?ijgPRYjsbs^Pnp`Og z5X#qJg@ab#$M7{K(96K2>JO8wIrqQut!ye9NnF#lTvy;=IX@R2q|ozsnoubc93cKA zz+Xt&xMW{!7_Zm72iJ5nrb@Jo?2aT$2BJF!mWwdjf{ z?Xt_RqW3A31+---dTpXKU>DF*#`i1MeX(y5BdFvYYjg({culPwBgp2bL~+kjEHnxo zjWnFa4krY-WZm-+TkI&qn@xpzlwC9Z*Q&By$)u7GYLte=hZ41KfR9!l&k- ztm5XPTP25ikx4Noum5QY!p?Yfctk(ym5{4U+Ic~%WLiQEn+t?xF(~#@9JEc86iD}l zaSEGFyR|>kOZZrio!SfPERSH*Y@~Ict8~P_z)eBIgmyg=VyD3l@rBdM{WdsME8>oI zfTU;!&r-clh;jerA{>gO2?-ng%wV%2;*l$kj{}9men%p z@8+7|rQD`jB}vtaat>=I_vMXEqd9%7Q&x3ZJyimZ=YV^K^TfnAf7;(7)02}dUlii~ z_b-*5{}M&Sq#HQJoqgArqsXs%r#9-Bih%H?=G)lc(Bc%+=j(JL_wG_0FuCeLYIvXRBd!w$3Q@xtNu)42pY1jnbP;f;E9R2YOPhJ9A4dUphOYK zw0d{$Tj62%7f6V;mI`gtHac#OZ!yV%M~~nGKCcsdo8K;8V)|r_+GKzmwPgak5u^(7 zX!IDAmIDza=w*SFPE@~A)n~_q3JDkxCOmt*Hmz__NFgx^!k=1lGH}H~0<`_Gt`Iwk zLSu?iRqX8${I*?{pXz3g$s5)f5HU&gZ}a3(m@ah!5}*003Zft!EF^&7KNj=+$2oe$ zODl4$Rcq$TKS@aZhWObiAG)d}zWwGi0s9C=3Jaj+n(KET3dM<4%~x#iHEPW#-o^9S z5t=N)5=GOY(%m@(Q1yz+X~#E#L%l47jgNowWXw_8W5Pp1GC`s>+a1`h{*4AVsa30i$5$*)Ma+;{;~tb}1W0T7QJ+UA(#C_@MZVi^vh5R@3jdy< zIk+LQhS%#R8m}6Xu;O&tS`OpkYn#x<;fwUi(XS4ob(@xz5Y`*Mr_tw(Lmkf?2Q8|i z@`0+|yG!oZ`@a#PY=onc>^aeh>oVZG2*!QFi%Rbkl2LF(jhj`In^n=flVtcJXA;Fp zKya`yv72vbMFmB7w3JyP4?jBufS9mjZ6J~Hii+(%7qba!)Qr}In6o1fF!_9zk!5}+yU`F&rAOi=f-3i~!aPnipd=IWVIzUb#U_o8!x zZzH&aq#Q9C&r>8}f(nXCM+obj>ph#!r?~iDxro83ciVMsr*QG8_mi{Y+l6N%p)lcE zq0$13Zj$y)uIl~Cm5Bi2!&hZ~)#m1iWfvG6pCw3;Lp20?86r4sp~nP3hXN!47}b6| zn$vEy3U*s3DN(dc1{ZvuKh4I^-1CTB;s#-jY_f*;*!(teFXu{1rd^A+h?a^#rus}o zaT&Y{Cc9FIG;uPP>#r}lhwxej_%`o^_YP}Kf+u1MxKLYhrtNhAL6T<%;^EmLHtlL} z5zPWOONShgm?3duO98~`g{%>qGPKD+BxLy7hpv}TmB>JXl}@zTun!7Xo1iugJDb4f zS{&XuUh~$)5(bdWuI17_n(lLpN8!gL?K6BIss}S$G!shv@LDrwTHdH`%ojN= z4J$v4F1sU7q3cKZ{?bZ~ZrP3S8p`s1kf?^qgPR>+Mq&z71fq)hDaabzOGUN{jaq8R zD7V-Q^}sODKK=A{~ML$Bddr52PMSsX>3qtwGV-mSHX0y2NPa6cmaK`Xl|28e- z$suIMCfPAeFbPHuDcjzCH|KN; zl|vk~S5<1Zb@OW7DMAbVBfJMxeSa3)hQ4W%h5x1u$5N(3vCbMrB!Q9~UbEs)7~X=1ciV&D zLm6UZn7p}0Fg|eo)q3dWBJ{Zw^7<^1;z%#En~G?b3W8z{3vwkMs(=4}aeW9^OQryY zdpV*xJm4FlURawS#BJAQ*?jmpd=q$pwy#+z=>+7hN)NnGe_`AVN#T}jn+PVB5f(eMR z?j=a#;OBm=C5aKewkocBAbxA@4ncP0P%Ol`1oX}Z)+R}G(5eL00{p1OO#ZyuaPVZY zmxn$5h1>=ExmPi6n#%+5An*1zIl@_^D5j9=lyq4Z!&j6%CL^%ocSnQ;lQ0x9Tne0i zYI3EOkJmtUaplTU&5nony-B>L9)IYPKCmQMr%va{29X2YELSW+8KKs&cf(Ms;fNvT zy{<-uWhKe<(eDiv{>NOV^FSmPbgz%eHV&nmCL}6lfk27_HrOfrZG)CkBM!16t?%N& zjCS@~4MWXmv(kdZo&=>fhM0(JF5;4@v;ix8on|&En%(3HLZPOnen_sS zR^-aKSu>psL~Q);!^erjKg0UPA!4nEXk*p3Y*PZ!vGr{{5yVZCXA!<-9#O7sBjAY< zKjq+FVhuuCh)&}c+S$M!Fdi*Fi;1~5NNnddQ92e~7>U=3E|JYRJ&DHeS*tPku>zH5 z-O8WbJ^U@%vLTnYE4YVy3Y0dqYkTIkjtlo-rFwiIXqTq6uZ!O6WPjUsioA!dGs`Tr z@EjSNp&M3~SA%y%CP^Oevj6^k#QTqR)}D%}O_Jp49!D!M`TVz}4;7cc+3o4VO1VYm zF^Jm*p}nS+BnJ@pDW3sJ88Xakz0pj;obAB}RnG@Muac;nwmExoIk(@#?$GZtB#>m@ z{&C2O!PZzA*xb_c@S1e3DX^I53s&<~#h%T`2ZZ*Qr?6*z(>EuibO{8hA?WTkr@qmO zhlJ^?Rf=d8MM*W`R?$LK;>;QUb)_!TD&%`;CltblA953=QePZ!%XStdg~i}{@Y2IT^; zii5|yJPxz~?Z)A>(E+16;g3vR7!r9JVlaFY&$+N4)>>SfIP3pDzeLn^F^h!=?4j@( zWExT^Cao5lrWg0M?9SS|JS$o$ZVnYL;%*^4)+@f+DY1gliK$G5yT~lyKN8 zNt|?=Y_H;T$e8^7?FE_b6XLFM7tIny{L|La?3{cERTq9ISGT={x*$3>KIzsQp_R}3 zh>5*v^ifoFxfzn5ui@FvqHy8vHLFbpzF}c$lZLsf`IFbAVq4%10U0pzy%FkrCRSdP z^_(4pUImx2Kk%l69DhT>&oKG`o_e7;YMP!%o$XPZmR-E$NZ?fV#4_8qGDy(WlVY2i)%M()l0+gc!hm%~L)yA8!twF#}YN<@(D z=ZeX9IC3rthqUE-!ZYSHtdrpj5!tQzEbQ#+y8dce2YRr283y^{?-6S${{GqT7C0`x zL#d+@_}LVHHM3pml#Lzkfo-5woSfO6&`GPuP9Ln1v(JC7A(FnU@^N|}?udfADMlON z`_>Nel4NS|%I}Yz@Ls5rxmi_=dP5S#*dA0%8Jj{i-?OG&DqrTddOT(^#F6IAZR!8W zT6B@8F=}7+2V1kw3sOn3I(^>uT8|bT{p}YCzD2&p?K6*663{V`mme=SqO$wPjOZ)c z+g&F}%kC}`-7KJ4xp0X#a*)eG;>r?3vUh4hfIt>+dwMo*9k|2S|KFdFWN%%L5S{vNO_l)& zPC9Xo!cLOjVz2gNLBe~xmyh?bOKnYD_@>rr%>gSAvZ*>46;>t>paAG0#;F{@6nQ~wiA9;P$Z!!f=&&Z- znA6rdxJY9H?{v~uGzPO9a<9He^3(1$_ADoGp?;11qqZbYMfpm$**2=AzFkP#v)L!w zJN1R?*WvAE!)_?C$#vk1QZ$O3+6snR70&u`8ri*Y+xj zv=e6|cXz72nI$~z@J}eq7yB#uJaVZnK})S;kB7|mK`1+x_>vVY2lSju-FOl1^>-`oLw#*G)19|ga@tFmZ)GE zr>xICN1|K>3E#!uxa@Dh^ZVBj`(ociq%!g944tN(0~J5tZNx+thfk(KjmD-!Ai>50 zKc(YzVZAkFVg}FWaHkAn$HJ4t`0;&R9@bV8JQ$+jGa0IHc;(%btSL&_2184*JvO|6 zBoN#=6Zou#WM#%Bs~}{PxNXdLSDh}{!$$>LosoI z1fBcuyemOeWIu!~`zH*SZ+&glmI#S(8a{e0^rUTgnRupfNqqJPb~kJpuCofH_Nu1F zSu_RLDM68$2{Bzk(K$oQ63-ok^{yQY*~GdB?~fv%N$jrFP&f;mvegZ|zvgY&a zEBY@ALayk9%3-7(348w}#Ve|WDZ-grt)=_t)ELugA)8VU_7!kI)@TO2$JGMJda2^s zYn_H9*G-o713{XnM4SlUtQOGNYLS1J43XO zLR0}49VDlkK5d*H^S;;{^s!!@79zq=d-n^kLa$VbKTT+zCSF*Fv%2`Pc(b8|knGXj zk#@1+5QXTTnnQJ@N0`-DSyl11@HhC~SkEhH2tuJf`F%{NfV$9(d*j)f6Jsi><)@y;d^A)#ADF3h~nZqX}Y zi@EP356hkprv#N((rbX-O;By(5T6$$-y+Yqcr+kL7mCV$uO2h0sZI-d! zPTo+GkV0b$2_|JO+WxEp&@>p2Q9^j;CN+!t#fxm+xRS?cx>_+?zX?Hji%r-jaL-; z51%uT8)0jRJgDdeINUFojgtgl++7wwua$?$5n{T^8T9Ta5FAVGe4& zB$5)x5Lugmde@>?9zqc99FhW{DQO~ve{EDF2`JOPbsvrCH=A+tFCmn7Y5;CRqPuGb zh22u84BJ-tM4s=d;o(gFq5dXn29|mB`AgBXgGEmwgn5@k0YvbXXmlWMuY9TShA;xV2bP;uc3=s!VbL9+5WM`tO_m{f8{(S~kp3w}UH#rvl^rEL8A5EM;>BMWy^ z^tSfwnw7NZO5F;@G9NON?f7Z!7)f}nd;#GL8o|RV%h+B-@HI<}i$}VDSd*sCZJuxB z?hL=vgb)u^iK!|ug4w*T4px=D9@zH!U+X3!0q^Vlt5CWm_JTV+@;RUvAB{;#KENblpY-8HEA%Lw*FU+IMx4_@3Q7 z6*q0VwQHgvpr`v{cdzXG<;5BHX!t%%C~|=62aP;y=eLEl+R#BUN&=oa zx+ohAoanQ~YvZ$fFJj2FdaKIYbKrKKJEj{wldF1faz)!GSlbLSWP6$eLGm6N_lEC(vm^es)5#jZvqKGsB}Byrk@0JY?AF1bKCjIigRrZ_HjvvLmS2pUp+ zOBlFDf*@v@CL5;3wcGYOH;zg|en0vH$m>8(5GyFIdS-!j%GWMEGh$+)C^^MsPa28} zd`4fYBF{EuDT?MutjMDr)^J@`aUGzAYYO-7j{Hb`7IbHXPE*TX+JhWIy&cJau5t~6 zIE9$Jv*oGc-9Ts&Pj`*X-`9f@EL^DC`+iuELlA<$QE}!};aP9yNNZ5I6hZs+?UtGJ zbCUf8_KuLP+eWXjVe9#Q{jHoP&0iNzh@NvG6xt5Jv-&%%9h1)3O1y@DFxhCLch;iA zL4xn6`#OSr(UClBD$iHU%%~Qd3QekMotH9sl|NYBeP5gMr`DzYJr&8J^|g~=u`Q%(=(lWxIz>3EqU1UPibSMSxo~n& z=6hoW))$u5pLun#fDB2&2~Hsh*+rRuOW3^WEKyHMq&IB1HJU?4$9QzrG27W$od`y6`AAtmYwkzS>xzugLZ~0l?_T*6Iepoiq zR%`#g2Y(p|9)<;gj$*CTKU2F0AsdBkOA3k3`Ta~T;Yv{DZzSu{36^+eiLC)()Oq4C ze+wSWzUr8EDVQ|TRtnw^+eF#(>S~CxGf0(EJ(xh9xXtS{%Zc#2LB6r2phA^rSHjr{ zd#}~7_?GA$+9u$pfP?b+B}7qc;n<{=5&fwJHLNY01T&8}8i;essLM<YHdjYW|1hC(bE^OsCiI*}CDiOIFzU{4-VWHuVm(5)tD2<3;yc zC4wWVb-M3q6?24xv1vsE%y=^?iJvC9O())OMXuA8w?$yE$BIIT=J+gYwTE)ae%V4m zXh19IR&m1N=@i+)=QhLdusv29e@~%2tG@5Aj8P()fS0|u?U#82BJSHhcsN>$wUvoI z58e*ELC;R!Rq(PXWU>&+I9rX*3rf|?v|}HoGgQp;PM@FczF{9q8*_gYLp26_%bT)|nR z))Y|)fy+_txl|oHSb`-7B_~}^2tdNq5ZxT%gXB!2bFHlHnVXm>{;tr(?imUM1Z(qP zw1A6gE+!GP`rA+exi3(X9_}GpqByLKz?>4pJ55A3nz-4N-OX(D624ERgmfryr`AU4 z&N5T(a;F7`1lc>kcbd;$A8R_4+sL$eS~?v$o9@|$gDA#L4Y8<^bCz(_bz%U-y$v*=e$9T+OK(d zi1IKFzAAb;U7rc2M$?4)8_}-8LR+BX$PER0jfa{FsQO-1=1oBuh|Nzs*2ude9Uv1O z1rKdeCFWEe+G?|EZ?cOD2gt-C;SZUhCMue>T6x_1cA9Xa>EM{_eL9haHD&&BGYX8# z^Z(lk$D%BzvCP4b^M0Wnu-WkFlKUzN5AI8#c2BMMI-K;Ju})1l4(k+2)Zf2fS^h*bk*R^Y*joy1uv>&cNHrO;#QZBYt`PSE6W)y<^@CbWLoJuJU z_H$NU)bpy$Jb8GNAAe@wiUQ-e2F6>*Da6mA;6PlRs}Z;8BIaDr8x~AXrzw9!QY8T& zg%p6Aj)m4fL@Q$q3O(eC|(fU5)v`*e>c6nng<`Q|Iq$ zraXo$d&zz=KEqOdqs-)Vc7p5$4uvmrfL!#A+D)SDFaT*<^ij6&FGVhCQL~+ZNqefi zXhQVTqz1nLfx#xLIAV>%R+B7A7QGsdI^}SAzDKOJj|s=5Lnf18*i4p$w(BmUrh>GT zXZdhh;1i>0Bp5P{1rW1Tg0+qNKMS7)A5Z+_0^1C1d1=6@*fOg`dSF5e;^EjrLVGZ>e~XOF<_qv7>jq$qGG)1sv+?;_}I6cJ9DZyGgEpT1og_Ec{nyI-3G zzvgQ#iT&(|Z5GeTPPD=r%8zvPPW5|i*IF&YLm1;7P;?B5@%br77Kz#lEkkxUevg|3 zIJ--20ekPGkaNn3ZoB)$Q4Mw`)ipORlW6`>pga=7hh2&xz5A1p&-?S33qD0r}c5ueOYcFG}!)Q*Z2 zk+QeA>|ne%Ck}JwFyGyMJSyvcP%LhPD@glV_GnqC^iPNr-?2_oAwom@_#8U1_RA+gjf-nO0IECu(^q9wOGY+0 z{C{SHbGw$IA=yAi-li#PS&c@h?tbIlr^B}*gn15xnA!%J9nen~4tJmi5g|Cj(-G3T zxWCiVq1tYNI4_BAqpif#hH}47Nl#iYsM~6TF`r)=%v^+o>kXH58y8* zY~iNEPxnr)7`tdoCDX*E4tedi+;KlpY!dKc_ejpfYli@eYd=V=5>??^)O&?Tg~sl_ zHj9ag%0cR~T_pC|Hj(%;inrV!CL*U!Lxnh9b;>}1_27|QMTFp|U!;ldYAw3hp* z@gbgIl~y{tp9=^M?TTo{kjJdurrsun;E_OfU0f5^jxsWBkvC#f60%4%2a0v;sx>t{ zB|7^tV-mn||7N4Z1o=T!*0~hP8WNCd`pFziXj&!GPjx$(P&7hnFLJ4H8DNwzW`1!9 zz9BdVKB$!7T5#Aq+fSScTi%4P zkP!nm>~)$iFRGL8hb56MwQ=$v7Df{_eNJ88Hn}vaLMIpp)!W5W5~##t5BJL~F50dj zVj)EH>DwN{`RZAzrAQ{G`V86Q&_p7TXLcp`4y-sL=XI$(hauoYGiP{yUa@43%)9aM zV4E$BWS(2RTaJ>$440Zbxq32QUp*H&l8A=M0|Jo@P1HhmR~wN&2(ntJc;_{bgNo*8 z{Vt{T%ipW}!Vcl7pEE;z!uWgU0x2W`+#p=GH}>y|;V$ z5T08wkq(j%Yo!-i67lWpvQ^ut4OkZA|89a9MKEm~+{yF68l2~q7BfD!NPpvnJF-?o zY;tHPlHoA#R1RZk`w?r}Jb`T;hn)fuph!`?ZenFaD$)iN&}TN&7HQ^UVQ<|iqesMI z(@Q7AiZFCo*6QN%6baV8Wb4&k*31N0`q#PY`V=SgbEtq%GGX^a<}6&P*#(N;M_Y(m zy`wT|6w3cLNui>Uy&g2EPNyDA#{2m1W1)*WY$2KZ5K;GFG?U4(`p*TOfb3$G9inNk zykuYYSMhSlCkWiPVqr}HFGj0!$~={8mi0kr1fb$G$4d4m0($LDzJzxPPS~? zkss;(b;*zHBLuxRdY$TESX4g8`#&8eKJ9m+f<=NQiDIp-;anvbpx&JzUPT^tkP6)g zGMr#jS%HWHTQNk9^GOd0o3<4`NVj*uuKZ{ae$iLmAy^axGKW0u&jO5EO>awxuk1{2N$mrZbe(Bagh;git zOhQ^}G;nXJ%V$RJZZG;5I8DhRE0xjNLcO0U!TMEYh6a+kX@LzV0wy<3t@U!{7nwZ4 z{wmvDB<5!}4oA_WVS#)uLD+@O$F@xZ6UgCU{-gy6CUmNsDi*(*MZ?}U_yK(J7WZta zLY|o75`wnlv@V7NhLuGdD-#&RK~IgGwM~_tww8b{qN2kZ#lVDkmX)G8#twcTi-l?K zsU@dQN2K$J)>sm>sOys;{d3kG62ugl%2odci2%7RifEDE;6_nPmlQ#_K73+gHS9@f z!vS?J%i?ABiNzGQ3w@DnmE)a^-K6c;A1gX_Oflp6iESt+0YCII@Z(jFt*Z9eJJFl0 z9mmO?j|h(yyr4mlH|J!XrO6r-u`GM3WXlQ@TIkJYQG*aDxfN7KcxQLS??F|`#p)uJ z1?80t1Y9Of@=mZ$etMDwK|=|L5R$CL333a<0l{tFWGx>4tUh=UU&ga=I~n=+*Jcm8 zE!cwO`<~aaV!{D#sN7=y%+^ECRkh#aGJi&nVe6Pa+G?GWH^HyKWzW-|9SHiIWIS;_ z(XC-7erE_qD@}5+CP4JIbqQ`vedW{~-Xo{bS}`2wRBaOA5cIJgu}=Twe$vTHaC)Es zj%3R8tN1kvSBmmJ5>3-%Lsh?mz@{F6;3=Y5nNniHsq{lM?9~ZWa3f8B>{a*U_Erf; zi^Ob?%z#VCjlV4-$*{*p_ScEiYK}t7!~SV{qN$Kp!Co!Z=4TgCZyITf;qPi{UG;29 zRw_J-H9xCodkwj_pUrFBeM98Tf#6F$Um3^hQim|~KE)Pw@>x+&GQ16Oi5#|0L~UD% z7neZl?*!|NU}1q7qNfyLRJ)T?P$pK-SKDUn&)QLe@12TDk^=FR6aiNdn1N6rsAJPX z^wP|0-^tZ;TqM{J&j+Zcs8t8*E|F}GapU3d@yrmQw<<6tS-7*-kPRACDhw(Uck9?v zlNJ>Ugr+PGDomexu$Z+DT^V)=;&V;7OcDag<5X+1R596B3H|YFL*U(LLP}%2j;x}AN z+P-a@hMyAa$(hWg2tu-tJ;~NS4X<5n#{zMg(?vrH8SuMMNMu1IQ%nPKYGKXCttE*q zUZpHhD2|d(!aV~|uxVsckRro<7X4EVoRG=?oD>Do&GK6&_P;8@a{DTx2Ot(EPS&Y< zbyaDlyOJ^ODA4#*^{f^TQ}Ij8MyFTe^RY_E$n49N^p%kyf?&S*z$j||POP3Vq0iku z9l0zf0M(A|jFD#LdHai26kCI;@q`42!AfNtcrbu4HLI^mvf|F%hz@6G!h=)=drC3!enYSp5yQSXpAj<52LluC&xwQo; zsSoHC9&157{|>6~s%a=tfmu~e_P)df8EfF@`(b0Jcpo$6*1U78#{}8*Fh$F6-AX0j zs|l?L+-c>srMwa1L}RgoBK1L%?N*W2Yu6SsvoXZ~wN z4ino#JyAEC_*{&5yk&$QBz|V&P~6MLEkUoks|=($DNNB@X%AvD9EfbKw2!paS}N)a z<9WEPi28fAMJ?EOAcr{V{URjyFixhH>e0B-Jx;ZIN;QlVt&PeikshF^f7A)ne*i$x zuFhR99aB7dlUaq#@k-r1<{6axeCzNKgGd83-b*%Xr=$5M9=D4IS{9Csy;I}ovV2qT9v5K4@GMq* z1{NeyEqN1Z)bBxcA9kkJI^8Qq3f{f2zW#i84K59X=v2Bo6xak;uk7O7Oo0x2V;&Ga`0x;ME(!BRzLzMF_55Ym;7FrCW@+lZxSu$43OJ& z=09HD2#VqbG0=PDwx$k43K)tB@{N5{Z+qTlF#(#FvynNh=<|!e7i;h*LDQE+L;*5*X^$@H`P&3l6uk>9~k-V5ZXw_;aZi8`p9PjLTsL!mzs;o#AsPe&m*bn7r8#;hL+y z)%$v2L7|00r)U)p`k7Xrqf%+ex=<3{#yYntwodtW$M{u+$`K$ry9JVK)w7|oo3`Pk z4Nb!V!576g`miq$s_5Z*Eh^yU7AG-8&SQTAEhH92(6iI&S^R#l$ApgZYzsQwV=?j7& z$zBuA@{l`h#HGRfM3GOV6ZDNbJAebq!u1Le=OGCe7s3!+m#P{ry-$BY6XpAbn*)s) zkj#^r<~RJwS8I8^H4z{8^D!&MS_(-aJ@XeX9RGPIt!8x}iIFd$tfV0Q5V z5=2kP(6xeodU>pxvyCL8xM+7$_;)+-3F<7b7A>V7@@UnFZ(>w5&7=h}pK$u_P_jt0w$FKJP+H+j6RomT6nFoDOCHVeJ!a7%1L$KR z0@HY`X|vR^19(a_+C+l|)pA=}a%rp9G{LqJDi^0U0}ZmfI0bswm4ncgeCX5R>-y`>9orj=_rrm>1<2#V6 zl7hH`BohFj)XJz~Wv}C6Hz@q-Gr%i%b*UYJ@Ap&qqga|o)4?x^yM&;P-%#9p`_-YFi?Jo+awZc^lxD_9e}q-6_-4hoTA2%-+ZUJIF= z-eJbuQ!arK#D&QE-B%LG=#m_Z@-7o;RD^coy;vodOlX&bNE^9Eds<@j_)}!gIA!+v zm}IKIW~;{8Q^z2gCX~aj-nFI*AxUgUV6DXkaxhBA*~~S-pK3WY#RPsgRMcz=eNjni$I^afY3ALLcJMK41*mtTw zbX~?y$k&PO0g1;P#jUpp(C_5xd60u%4>SsG4r|0JEt`yD8&HwS5G)Z`MnmF_4k@JT z+$0rR3I|qqA7wXg16rM>PCw%FiHfq2Ny`Mu-A#7BmK&nJIFLCyp2_D1&#NI{vHYgG zeC-=%tJV8h;6-#wdwzKkv^iv=#|5sVdAxZYLYUVDTRr@9p$6OuQuPcRt5k1G#`Dc8 z#mANk(CsWilBi^@Rzc?DSgK~yv0`nbg2i}E$OhoB|H*%q4j1SI%w?h(&xNsUNYH`y zVDR8q?0qNbo)i%ImMG{!w5t{4dnN`edp;uT(RPv`!x9I3rr~s8LyjaV0!P*ZEx(#J zqONA0W7G1l%+bXfLPzZHP~?3w+4o`t)I*KEhEg7O`w9AX!uQCO$eZeE_z4xNk%`ObzNh>5 zzIN*XP(ZK0`+ANFYo+7Cg`$_c$N&+p%qK>y68LPqpQ_9|B-LJtn!@!dAMfADB(LNF zv1x?sgd_z?2uQYKzM8g&dL@NR^67FZKq{RwgRIDu`+6*t{1&0T(?hLOzcL#dK>}i) zp1CF^_D?LUo{&~$P7Q6_#kR*>iRIrv!}v3Xx(O#r28(bYnbn9S_+z3)?I7H@;R}Bt z{W3gXAba42q7Xec(P}zP;>jlnKMwegqL9P;uER^CD(T4~c1%7NRVk{t`x(LWmG*e9 zivBWH4D=D=qWF8^F6WZmqot*~Vld#|Tigvl0a^_@D=ZY8@eK1g-N@(AbP*w+a*Fp} zF$lCH;2!{8Y+`dho5unVg`Wtm7DTx`-6b}WGSFzDIz`O6TY|+F#zwU#X43{s)3{jg zsqWJ%Vb>Di+=ED33k5S{EO2m8e$ucB34~-VkSx1C7+Yn!G?V}?^mYA~UU=%wFIF&K zU4sv`zQWFProuReC#r%62D=ZOY7IG);#QUYaWL6nMv){=;)f}%YrLk3JfiT!Wb3ZwktNu;zkmKL_+Ifl zY~nK0MBV+89-;Z%p zK02Go4y(B50&7}na}*aECmzdMOXYyzchrf(HQ{knaotID&b11V>^NuED^rZiE%^Kt zR4PmqL4gQZPZ@1eBl*8`t0%5u)sDtmeW#qyB6vBht&iEkwaOOZP?chw*quGcbz8*F zP&tTn3Zm6gkEc;oiW)VTaN3#FvFThP@=D99nh>2sg5Z=F=AhW_%h>L-eZ2d-UZHTI z#K&-8Fb>v2Q%FhD=U8c`pVwkst2QJ!$dM?csO!~Bk#<~)nsG>DNV5KZ^;>)xyF@!s zxU^Uwc(yZFllNlo8Q%Y%V$oy*WNFD@hgCxO%)7iP78FMkVNr3Pku$W?`%USWPHb>; zoxHT)hOc35{F%>`KC=JDimzc#KhsygP?+Wm&wGR<%06?hlfj_Wkh;_M(asKMX)z&} z`z{F<`_I}3#iF>yo-t$8Rs%PF7Z#pP2N`c7CVQ%>MFVH{Wlx_}BA*0-Uu{HI^p$GH zq^&4oD`Coe7(%AHJ!^ihlCl-0D)PQlt5>*8;BVvFlTU0xvGT28+iDxD)#3q_v6zoP z=Q^;qC^;U(zi|kgnKcgPa*ry!A;w6s=oL62H^h7ox4AH*5aBCchzXx6jQEE{-s${B z?InPev#12pu^NiZZYha>5Xl9`Rkci1d+g z^f@!(RW9YLUraY$`8;w)kQ9`Sv@N2ST2N#fI!R@lwU9z6 zJ09>;E%%pb_nmmrZ*I9JUknGzt*m!qqD6EdSMG|)jZp4l(A zSzI=PyN%GV$j|kX7$%S#zD`TB;eRFCJ&PC9a&n`0WxCUik3}Z|wxli)w$&kp&AN%d z49_2D8rA~_p3DUKRJoI&Q?%CzY(7uS(L@V~-T|5c(5+GPZerl)UZ2uPmbdEYT0ftY zOBi$4w%M_%7wYv4i_S=IIP5Ozy*eE$9@43(g|k%B+$9H|ON0z5hS4_wjNGM zysR}<6#0Ac>?T)TPairUe2YDrO1DG@_?$W?)@7M!yv-F!rS_6)o*_0jibAoSt=v@+ z-1J)#HkN20`9fSq@?~DHSm(Wx#a}JM;wMe_I#FHGZNil5xmty^VN%2}<#yq|0=)uH z7&I0<6GVzeCwhPS6-34%mOU%~iT#5a8^q9C@cr(RV3}d(zNwWdFRyOw;2zA>Cgj+H zwS!1DuaiucLXYP!tdu~HK!-*8rG4+8VA+^dWlmLjMP~DI`?tPX#F@9gBQTMeUMELE z|7Rhp+~k)vjT-Y-FU2=atyU#TV3jqg#aSqwK!Oo72kRy!I{3)nRM@%M# zg+mpt_^jlc41oge5Ae>4+>Q1cX_T^xq3xq=zm4+>!j^CG!`_M2@3>5L7{PVlB@ny`Y3)Ccho`3yYd7SVc16v@3fRLrtpGtq;jhiKFAj|_cy zMfRlNrVz2(WKqLPwH3{_s;bLLvMa%H7F!napV5{{EF~*dVg%P zkxIRqZ;_~|0%zkG?>nn{NOhA`nzu+SNF;4r;Ytiu`YB#(wti^fx)L51$*cZ%@FmJZ z1W9fB*TgY#;WN_0<`-~7rnrDK;2r_tF`vVGUB&^#+H+Uz0sL&qY0)B4nimspPS1h_ zu7xM%CO`vel^{RynokEE?m3G~sfxv%9Te>8C<~H}1$p%4)WVDjkQcRmXtW$WA{13L zEi@D|vadRIgveuuh4)#9r|K6r)jqq}9dd@nq851y-BY$6=t%HPRynN(MDbCQl`7=1 zKD&oPPp%$jm)&S_C&wa}s^Gc}Ol9hixf~L$5a3e?i&Ka2T`PR#Go%~qH=DvfbzD?JrG2DM<+YDfv?|S0^>pz zHn6>ss>*pcrc>WWbl=wl53ZJlLa!DQ^!IZ9U@~S8?ULu_)sqjc9zfK_H!=@6CKcKq z;Ko-UOcJ46{Vpg=vtaNB2Z$(1D6!+tD% zM76SPIubV8>?o{_#pOp;*P7_AUiXW#s%M8#cHfS>)s!W(Wa53`yZcnS@fu!TgV zne#iHx?EX*>WhO3@N?`X2-R`IbQ6tStv<51zKlQ*74o2_)F|9LvsId)R<~(Iv>q>mRqXjh+WW5GwF;h6E*6L{rXw-@VY3tLKF`^Vr)^4#^G@|HX+IEkgEW!aOyuWLbg=8AxUr&oU+*h3%P~>zKX)qI zZU0|(&NzCftt->Cx>tg4`@wXu@CU?)b?9S4aLrqxej*YK`h<$dqM2LcO!Myk`_F!# zOtj_E4kuF&y>s3Uld48+)huaPeyzn;OVKOOc44D~1V!W|rEe(wV|#415uWQJ>0I0` z!6E@~(`745uFCSqMTjI2gh=tMy5Y^~-&01fQi-qGGIrU2A9Ke1|NZ^qCNJvyaEmyd zGprYkM++BfTLBx1*G9$pfU+TpqS))ArgVl&J_`bqP4&I2z$aU47PQVxDxNj?cb(XQ zo!2IIGI$hZa@i0K6Mqgr#e1O4n0&1sqqXLfJq5CRKcS^jo{JWnST{8?sRwVwx_anZ zi8_r)^fD1yrF_p>&md^$NZO5T2ciYJ=@RK5`8Qr)OrDW+ITha=@4c;=?f4dcRRM_4 zhGKg|FVBie?%fkC97>Qfz`;|MC-&lX1iNX)NADI%5FRvwN8zsHs0g6qUK+i69?RcT z0zekwcz?&_1Z~0PO4@=8O|H^4j=yE+&(g-}^TUDnMhi}C5=@Jr7W+`8X zyIM7FUNI4-XtNGFoO2JB>R%dt@v@)@My@=k{Aj#4nFRmnduEF0NE(Jjp$OBE&~cC! zq=v{~%QN}AQjm1G_l?@H6$h-}4xNeQZmLuRIA%;xl|O3Un`r&=YaFI&v%WD|2vs?^ z1WSi+@`ax^@OV+7DW!pRNso)xK@te-(TSCz#8Nk&TJ$R!M!CuMCp2y;#i{uilR8B4i50Z z@XtRufIz8T;Xo= zHzHCwHr4%n>j2O1@7I#g;#6Nji?#UK|J!`gbbB!*Sti@Ci^h#m$ym%fT zrd^wat_#tSQ-n%&1Av#H!%SS$1bErXL#mAAPUcu$KVx#6^o z6KRiog*8sr=;7K76?MZ@HZ&eG9?pD1G8Un4J*fSK;&+CwF*7e73lUqTXue&Y ziMJ-)0~x;+y$%FGRH-?WOPARmwm`haVQ}upg~ie3jYt&GI^aeJHQ&1m=iTyd?@B>9 zg}#wwHN#rW>H}+aNLG-z9!u(RIMLRqe0*Dh&uvHwgSK^`wEZt$&}uTp>)mHkL?O#k zRKte^8M;!<3KP)s27yFo`XMapo@30K;>%vljrzu5YCk@#)!;>G_kfZ8|2`eHWrq0>bLwW(j^>7c3a5=QsTG zIjoVYEl6_pzZ?OixN?ybss2)9;96TzwC*a!WVtHbw~VS+`oTT#k*SxHEA^rrx~r4x z3j!wF#JLxHt|6|6I@5D9jCO5i-$u_v{C5}m(x6e;8G#ssm^h!$v-foa1j}WYiz?zF zmPMIuayYR!!-JdVK*B=6LYd{o#kJL1wT4^EQSK3(DpV^8BvCBPe#^E@5{_~Ux~vNpJzW>3n2kc z4`vFwCePV4Z`LX%O9lTD{(e47=LDX`ZD8b=%3hx8-5>$LItFz^C?I7dQvcuIuf6eJ z+R!cU`D`X=->qdz@HR%TS@*C)_>%Z^?NquMVPC_05`$>z_H;VTB<>KhClK@SccLIK z{9D^6xXm~tu?9sZ0E+bPLic)d$>5Ebun@=ER0J@z1BX!kIt&c z_mnM2;XSR@f++Q-lh14l64y`oqr;3T{OC(oN;$N=VHm_CmSPrD2P;nV6Zad&4 zPRL$ZF4s&bnOLP&xo#h8xwl%Rln*BL8vUWC-rsa5oQ?A%HpEFWofglmjTFMx`vA%n zmLZytoA>NuHj7FAEv`-r$^3Y7f!Dd21p7Zd`CoU2w>m0+}Ob|M5=GMA$=jLZU>@5)q5>*%T*UeT-AG3 z_8kKQHL9L`H<6>}g-PvJhxbGl4I$T~fChT}qF1-b;*H_$3-q80v|dA)UbP{3DrwrG0gJnkYL zEClFPXkr`Ta?~M{NkR%auK3^QK0JZ=H(6PULwGpz;Vm_DN2UHOJe8oX@dD8nk%$

a>UPr45II6E#45HX*e?I1_Gb3$E3eSZnCzS>fhI5H( zalt?P*jC^nkqQ3_hi#>3C8uGAiVYQ-p`fA%CTlw{ii3Lr&kBeSh7!oXx>GuiVXKnGZQB!MfZrp$%hyy7T!@zi`5YX?@^`X1N+ zcixbBOE${Gs;yF2kz!Fw@6>Cuk7y0%~-DRK9ThGZ^fY-#6#Ixo^VA!wBE?p1d=1rB@rt(AEgGr-kxbYx! zwJ-bi36`1CVv~!0%=ME5geq5A_K7w}A5J&5bQuo}yr@)jz=LYUtIb2YeOnb79Yr#C1m;x#1_eI`5F%H=r7ek`iN>=oa&wGF z0K$F1CN1j`N(Z`=&6IPaJgq9((6qzZYMP?of32; z*Q-^dIy412jK>Ze8rfMJ(%S)3^nyKf!08$sw< zOg*_UED|e_$!Y)P?fqtFcYX|cLJY>e5~Tk8WTx%(UI3?1%?n3Y<@ntd5%Q<^S*{)#R9B6~HbjEnmjv$D$mHcK_gygvBOl_w+Zx|Tg+ zfid0QsW~QB3UA_P^D{&$ZQ=^S78MzO*DK)65RgQ2AT6%MT^^VOkT~$jh};NzlPOsn z6}w9UU=hCa=Vmp~!w{zxLlCW#mHw=I0kC$hfdZeMqO<8iVAVk;t)hNU(SUXu+Ceo( zncHao>URWjc{nUrOkD9S;H3yo;jM$ca~8CPH-yh|D%sRT6vf)2I51Oa24>i zwT1gEEvhyai7rX-_I-9F`z{KiK6%@^6-~weJ{H_x_^cK`kXW7?FFKvvvqbk&F=J9` zx=zmxiReOdFS#EC$=~KeGuauQITPWkoGiIQw*dQ*oskAUu!5)~CV@+d_Zm6C;7V$X z{$%jw)e|fUR3#5!JMgc)`Q*J|(?N@7xXEQBm13S7$$R8htXD00Hg$a-`h-`ohg++m z=ksmO{RBc(kFAc}`<>(=CqaF@SC&v9*_df%kA!2xvFrU%EnYG`a64@QBl+^)KQ-Th z2f>hhit2pO8LPvK!0)-|xOYgbRwl5j#OHkhA}=I~%T=4~9-@bqB;Z+)3#3KGInO0c zH0_|`8maexP9W7^%hOuK>0dw7T0xAW@MtB|QYftW40Ept-YlB^BEYZvPB>j*^rgez zD@_4gb(kJCVabY~g!CctsfvTLAVz3DmD@^NA@!GwiD^3?Y)poRxZu`~b}NS-F&!G_ zvuruU@XxQ6#vT_@im|Ax_}-c!9``oktnLc?QJhxLphCEW&)+c$(V?O!WPk$55v^{{ zOh!zP>QVu0Qyf77g*G3O7MRz6sX;v*T3~EnCMNb;w2sn6Zj!azv~A>Fqq9K$IaP&c zL4!$b_yN{s*nEwMm>03Xx6lhCsvxak3RHC}i#w)kF_ltr~i@ zxwzzkFF|f)Vpct6a+PT?GGck^okp!17029n-%>HS_;pRZwyMCkjT^3ywjo1e)vGCP zCei~8fG=X?iQq3bPOVN8=4S^(!1(LFVR8jN0!Ggd1qrm6a1ilOrpMbY4_l{GK5HJV zGn?X>1Q9v@ce%ENjI*>05Lw%~4@xRe+S*Rh&@C5%yW$QY?Kd10nW>kgXgBqd@A<#a zC8-Jjfp<3C+plEcrq<-s))M%3HZkYfUU>``%VNR$h$Duenj+uwksm%B?Rk)Y2R}^? zzl?|YjAE<8_p`}lB&$y2zdIPmy{w(kYk}spNc*m;UoMKwCVLMh4?(>XIe=1@FOXcx zlrruW^c8E`Fb!$dN4EDq94o4@=A3dSui5t^zayy~-WP^7P(Yeo56SLr7kR(ch6e!Sul8-hqEABTF z^)1b3)s54&vZmUY1hCCByjJxfULq4bsP%uXBkB`&*0Uj7h|fR@j8MMo%ec~ZDY<$& z_|ThFgStB4o}s|aOV4}C!XgB|?ry?hd>`De`CJm$K7^ymQ+8xk+dv2TZ~Fe89=k#k zOs;InwPlmZRe8D`QBU+{6FFyfInCT?uZ4nWo#|kZwS!fdIMbvXzptL~tYjjGY3*UJ z;W?V-qX|1Z7B1D+S}^pp?Kbhu`X>-9BNl%kNDT)zOhW+;Pr^gf2?DPKHw0*G+Blw@ z1uj-V)>tgF`fyc)tQR~ad;@~*vu{xHJiPEmqT;w(<=8Zrcl*`!(?G_>7)DDAQ*Spu zNnHxRDA(8Bhfci8Mbff!4bK$ufvqUz^BMn&ZNfs@&*UTZ z!x}&v`QtIMBxoU4l`YBQ|9yNHg=O_WtWPAGm;&^PEK8^Y#yj^dZq%Z%>Jl)OycnZDR8(U_ypeHH2(B#W28r{YA7IPcoQU8 z_V5rqvBAHT*oXjDUZLj8DX^Gf$!o}%rjXt$MH-l7VUvHZ6#0?Xg9JkvV-}68B38UF zkuW4gWQs!$%PSmsTEJO%lSBB7B!4$e zgdSOW2rK-sWw8>J(-y=A1+_aD@;0qgwvq?K-zV2wyto_!39 z2%7@-BkVa><=GxgR^>V)Ms8)msG>J)16Z|*z}&P;Avh2Dgx6{rUoZ6mzOtHi~W0Tsc)GPNcWo)J*s z{;Maq2$ki&4p(UF5_(X0j;}OHX6w*~V=7&zV$bHdzp^^f0vn$VHUjre>yw2UZWQjnfzVnwM{&VQ+H7#F^j`N& zft+1F-`@r`86CDYRodZ8t?k5n_#a5HVrAnTgVUyIB6+eV)a;{C>7g59T$i>JMe$O7 z@j_HFm%|6Gz-Gt5*6Gy7P-9aNt<-6W5W=tbOtK28+#%dKiIvi10MIRy=-qxcq1A%zpd65(HwTk*)=Uzz8Ot&n(k4S`# zIE(vcKB#!#MtVoG`e(6V>;ek5+6d`=NME#&6CyVd;a)vGvA#NO8Goqy{Udf4lSOb) z(c*)=L^pD04xww~m%>^5ASidnTE`%<*NP;F>q8O6ck#WrucaEta~jQ56YDMx&&(* zRVkSW;UEH&-A|`(Llh**KGoAcUo+%nqfqF>MHusIsFC^tL&MWw2Ek08)J*en#eie^=v}z z+#tRiSNPe$r5fT9+AP2z|I|V}M$1!vj}XC`WPQw;G$7H-olHAnVseG=?KAQ@WrENv z;?PG$|6-m$bpK0>HRmK4-alKJWgZj6pNzf_Y$bV);N-OpTi06?rD&aMOcq@=X`v#P zOWUyBGMBfc&nvIX-aL7x{fNLDVu5xu4$?nref38t)qg`r!dig%2lr80x3ag*dsf=J z)l~wwcE3~3V4NU#KD!6-YNEZkVC#jwgW`?*sXR@g-2fJtiCdC|R_m<(2NNtVAcft# zPDpLA_sE>I8gl1j8Dq)R=oW5$>3)x7q)hbK1dDBKuTxhaH<;>rU#}OyST&<%p~U5> z92S1>>yfk@6ya%=RBfJO*19cJ%PoE1hQ=WvvB=Uxd3Ho=>8B(W$pET$ zpi-?)Gm3v9^@tkvQW31L`essAHr2GPG?!MN3Lsh0~)e*~62zRA6;1K0+)SrY@H6jrxdi zb;q@1p0PkQ$*&8-YqjL^r$n+)qC73nIO+Pll1q0PgOMpBs6|T!*!8^%X^t5-H$ONL zovMiIhTE6LavF(&7}J6Ew`~1=y)Pcl)CpQKk+>B0w&esA1{@_$GYu6~RZYKj(#aa^ zlRPhY$n4?{xmNRtOg|-gBnd-zCi(m^xf+rNv;wUiXH%;9%qGOS9|;v*IvlQe-GwD* zn#4$Z$EhukACkZ#P7og3r>VRMk|QRD*<~#YshBrBw5(dj``XmOyxXB4$@;e?q| z{){5ZV%zcGp9Mc7+n_F}eNM~wM#BEAdMF2LUzKl0@vWMCo1PW_-eqHJWzSmxt?Ro5i@R>C$mwN;H~Yw^C`*I4NY*G9;{ z!qGVoM-uNpwmL}i_BYc}3mSxia(Yl;RMlZ`y+1#Q`qB$c5uD7t;9_zmlT34}n~yC{ z=Utp^Iz%*giZJ1xLSCU(q^D`5LM3NLIhV&dK;dY04HU`ej#X;D)807cYL$E*fIe-+ zyAjV$%)nK~VMvq>-9y}wcCV1$@ioL9v`L}wht?tfeyOB)kub>PXOzS+Y$fH7L~t!m zjwauoCQX5&lD+*?hCkWYbV5ZTRV9Dh*X+5au_v5 zoQ|N;TNyA_dnwQi!2r+6c(a(^LOOgqDq@9W9{=e+W(TNSVEd#+7* zS9-Kb)%Ozn$l{Po$COoHZLP&2xm@LQYg!hM2>@Ak*w9mrcXNT^Q8g~rvnbX31&Lh( zC5X9kp7?#eudR#ZUnkQylr*54vP@6y;{n>gjYDFhrFETF@6#_dyb~PwcHjVUaaX?L zXi_}d)`$<-h6u;5v8(Cf9M$JhR4mur4;oBCkq00R6iBsUmMf}n{2Y>)UdgPvP7I%V zA@J6H#Wp5K(o2ykzyZEinHNKKXnRDIO9=L6=8bk$oGe_fMNl)(V~Z1?(2zSMm`G-Y zp#MCRO%`iKP&j8ZB^^N6?@Kx&jA;^d=rciIur1nX6b%$&snc%I`G=mG^EvMm_G7Mm zFq1y1;vqTy&V}0l962hkLaxl$6GaA1kbCKZA-hrO0>!~ncqcCn3^YIzw?k0|Y|iYWU#!MY$Qn0xn^!uILSM5VD*VkD~N_w~LG zt);q@ppK1;pt@c=)t~WOaD!QcNc-Bcip9^Onm#1hH+A5T!jBWx3wA(plpm<@a;*m5 z)d|)m-`^jDpAuvPCV7X~t>^WYMb1U%~Hz(QmY5FXBLm8QD`=#E#j$WXnO1L9v=I}8M#i@LMPI@iQ-^_~q#u+bD2aj!Kd$Gb z9+OL`(8H#u*EQ9Oar!Ix<=tejXD0lbtJau`Ne=(L8TQ_KwTbOpPySk={2V{2=iRY_ zi`HY%bQ_*s7sR0(A^g;!Mo zDB6~Hc}rX8>oYUyB(^0I1PXi4%_ zhscz>Ns)^bfX`jqgKyc22hr>W47RORxPk{(#QH*TYENDGqwtGK+(Kd zNuy)$Q^Yf8!`cRt1I|N~6bUWHY1nf|(I+#ktxTQ$hWlf@oDNpeovf=^UA*o5-oXf2 zg=-QQ^CCp7z(399LBvBdB3T`MN=3*J!5)7HQB@j2_XhzIu||2JXyroh$?Sb_2um`Y zsyO4PMB5UFR&;Y#$|NK1Z<-d0Lbxz6@(4j_Gww#xj6=I^+R)nEMtyw{SSmRyLm54xU2j0=IEzK4)#P^Wo3n=!vbtpBE!jc*B$ z9P#6yYo#Rpvdp(^nC!q2E@K*80gfg{SKg!GbEtYhGPW6jZFo!^*?)Dk|nC~g1Q^w1XR(>N`tEK zwHFDG%e5FnBZwl=`h`K#Dnui2x9u=RgulzwESug{g&c-9870+!5;lW~yB1rXWxJQP zq%eU6;;T)BO>L0;TdrDV8oo&W6lnpVHd$7UCJkjFHZznUz~mK_j`MspVHCmDbn6g7 zf`Ek1TA^Zy+>V+C-;&5DW**(tg!{WlXi-$HRTnFD!5U=j^MZuVc2Ztl6=20>qDoeo z3&`I}`JH%WnoncOnL1gm8anq?Guwt69<;Pz!ZV?5&|JJJvov_1ev+%p(5*+tzO_!M zE#~Fc0m?SInuVjtF4VZ%^cmmHmgl9a*@;c^=00}D#RF$yhApb#)Bd<-akg(wf zE+|N-T0~j)>lSvc{$7Rx0414aiu6EAnA#kO{A<(a%)b9ID88 zy;{}pr#RFQIK@0#oXJTHg zt)NQ|2C>2raYnH~5iv-N>ZA2Hiv;49D)ML}>nRVfqEE{D_mQ_RKVJLn=fx@7{{A(& zSiD#<;iH5Z8$02oT_Mf~2M?FQegv1Ci+OT&a8)&fC=Nla%9&a|1DIvk|ui zcWD;`BitO!9IowwYNUE~3Y57nEI6bfGHZ%tZ7f7y_ zT-jlCNuuV0-3qbz9flc77xG4J^?_>1PN9By<~f- zRnNJ_LO3s`TLRRgECof&FVr>qmr*Ssg(xV#lzV9WKues`Bgux5w|8+#6%a#^Z9&x&%g~qIeE9BF?bCm9!q)&O5p?UlmNO;t5xCcr79w5{Hs(4 zDGntiOjw-X8mqrKfI>)eA@2wK9!M|VpS5S@CV5U;!p;S+kF{(qTNV>a)^Aj0dZ{*F zEGY8)Vp9I+nl=v7*V0RzvPdoi9(7m)@%P(-k992kx=$f^Pr&4GLG^rO*jxoDlB&P~ zt^IT|*;>qp;_zGdY0w%$07ODFwz0+nHFa)Ct`l@1jm&h-Ko?aF{mDSWr5;iiv|J4R z;lvk4NITK$s;Kgvk{?EXlXFi?ut?}sHD!vo&C0uvK;uwCwvU7kdje2yr;}nxws5bq zOb{6G8|V|)MGi$|MoT!Z#qQ8XN`qX%bAwGFJOuum2E%?w4fnh@e`EAIe z*^cZI<+}(mmB~RIV09#EFeF;J?l%jraVs0+^i!`FQ;P=LOJ(;y@u%jEO%!HXQ2VAw zBeeOnwK4cY4oEuwZlh+)_&qqlX@>nds2_gedEi;(g&1Djen33J^G0ASig8OPJn!O& z49e&Ftx5TIT!bu3o;9SzU>zAhFG-T9i|~sQEV}_jjrt8hroT=htTovpHv%=OLiLt# z;b2Ds1yo>+$1&%)buMO<*qmqsP;1Mn?^dRMN*z(O#k>eNmqxeHSXs=Tie8Bg#D-P4 zjI`b-xiWnv5ZW>AhJP;#;a#Dn(x_Q0?sFYUKmf&(DH61h<{!HIk@^k^E0T~ew5e2$ zo~q**?9i;)P^W!eFGaADPQ5$3p#Riq>(+OJJrI(J1t(>0TQB7575PELGf9e_gG}C+ zCFC3Zj6jr3Bo&%>_e@Zza!&!uG-!sIl!KvIhPEBMH@j-~R^@`zRiq!@;iJ(jOr7HX zLp|PtG74;HEK$)PNf_2%+HFnPilvKiem~d0u~xWOfsVJ^ZWP8n28fcl$Wkrw5r=Gi znm&KO8<8-%!6X}1le=y!u+_@)w~E>PjKnxnkR9~msoH$t_Y09*{OUSwv7nj}1!r-K z|I$`XoV@VwvcpEXk3u|t)CMBv*i8Bicz-346MrcotPFUcmev85ze|Ee*gxfcU9My*87Sc%w|S%$Krcd_thGc@ zti41`Gk;O*oL^s_sNW%YqHL>cyU>*OTjgJ2vUyF5BY9pjOwoj?*AII2yW?!9BE+1K z*D2*)y~I@Ig#hRjVOVJJRXij}`xXgS+?LyDTMl6lRV}M=DlBhQGef78^#2&7H4$LK zl?lJ%)KG{`a*4N=Bxq&f1Mg+mLZzlVc&p0U&x4eIR-%wQtIC`1^&!-dD52iZMDNXF zwg^%W=X`Fj(gOIyR^jIW8o{n)Vhx)aiMyeL){-jbA|F7ZP}T3@6WZc2bqoS?_2Dz4 zRU}$K8Rxm^x&Y}l#pLvf6}zn+Aafv)_QztMe0NMTX{M|w>AeE22#m`8Ch~g5;kwi| zp#6>n!8F3zXD^t_8UEB*fXf?k<&16S)>3u74+!I@ziYi#M(E+k(#U+!h@{<&V` zl8(TjLI5BDIYOLAv?_4CQ3?S&Lw)SEWGtg0_;}oW`2+nzwc$JmM_^de#p4SNw}zt`uCVAcjQ?c63L2J%a2p}3Jzu{(Z-}t z8#gyIPCFc|6^JY!2`H*Ek5&wQ@ZMWg4B4ncswx~4eu2D2_{YV70$)%|RpXm|dW+TZ3Ri5i0%jt8wL~%Qx6YX5p#`V@AmjgfhvI!Ql z#U%;80^N&#lO7hKxOJjq5{*qBx`wHr(}#z17wFfh9+Am3JfmX8D{gcmhPq&9{D6rj z;!uvy(^%6>e3s-eCSq010-1WMkBRq-ad;6WEnap*VoewcyHTFaa3BlfcdQqGYqjN6 z)J~AYGC0knnxawh*IZ$3N%amHRonCBXG(>Pj=f`Tc1|4Tuc`Y((^qFG@`H<*h$BXH zWFrdBm@2}v?>d~AZHWKJSzXCCmpU!7AQ**?Qz3G_w|)BW$E!Q*Y7B03IZORny5At9s}Twihi_xDFo%NGe~)=K^R{S)|Y9Nq5k z2LwOaZtnjZ0UB*0tQU~YF&){c0Nq^=`$R+%k)ZzlUW&?i*G2Rt7yj72Hlq75DWjH7 zw93f?q5k!{gn|@{AnEhoT&G-~M%zyxi=5X(uLNms6%ltNy7TL*QzmA?10rdKH2w=z z2ty>L@cXm}f79A9i6uPqJj-uB*M#4Fc-P zUx5Q;YXJ)CcJ5Yk)TW4_WsYG%HpaAheQhr zAzq&oZvA^`wG9Hq%i7s?kLy}2qc8x1;DfIsQDYVVVzB{<-?I`Lr2W6Nc^9InwB`2aqdH?IQ8|pjW@@vI3L5x|^)FlE8I6 zcIB_LF*LA4RB<-jQdpn5>OWc~w?h6NHs(HB6vo{#)tF=?gxeVWqg_GK;zLj<^2^Md z4cQQHI5RhG#Bb@2QPzz-2lH(c&7k}x5G?bm!~$5*<|oxjqe=^bI{ANp<}3s_;@v0Z zA{ipds(Ajb`Psyi@_wHw)p2vk8pM4Cakd$|7_6@dLo z*8DuLaNybyho>}4`n2_dq-wp9q?x9(>F;SDc`X`ouZw;yfUoq9{>FG5XyxPi>>hsD zn_r89|D;n#|20}qrJ|9wA<`xGRKD@S4(W3xzh;eFCo9ixw6dc-!)bY;rzco;$m1}> z#sH_`UM(r(PaH~KEwcsr%?OflkYN(lX`dcnZ++2;!}W7U_s=>x0X$5toSoF-O@N;Ba7fMkvKEBF!5B)sFC$9tumbPx zTazlRR}f(#R7mCTs^EYI+si<=ma8QDTHHNR2}F46M~3$kP)npeE!yX}}lq;kg^?{AoX%Jc1ageC+X`0h06QYc?QQy9rp9g}!SMNgP0n zh#Z*y0Tz!6zHT5jXIEt8_!(+pX_6D#vUhl^Ehl-TWo5|#4)036zW6kq+|y?&;hRae zSjv>5zt+GxJ&o3Yyhp0gt786tf0vGlDaD zq4Vljj_s$an#)AlS4YLOm?X}mQsH2ld)9AVr)EMpu#)q_|Nr>&Uus0Gfc3+{0 z?u*v>EWhh#y=YSXbKRw&xF(d4BGf760xjqhzG6>FuQ=Hwptz-BDmRWugML|D1t* z!_S7FW8&qDP!K%p@WKBfA#9Zdykub`Toil;aLkOym#ZM@dLs!L4xlWPsVe+QwR+pW zcV3j`b=r~>!09yW2Yg68k7pw!HhuQ2tRboBeQnhsM0#dZ7%$$Z^t zvWL$it)=2&mLm)pR~_6wh*35=((LaR_{7?X?I@GJD2BCQuZw51+-#U+XI4=^IDmJC zmZ&;!S(a>-A<3FYBl(t)B6ydP?GN5A9zB9J?`xqgiROXG=7|fR18D0~ZHoSU%@rLQ z@?ATK*v^GweE;5&K(3n2FqPa?+*`@mLJt};2lFkW|MNUSaG&g0*Lj~_^R#g!K zD8ht35gwlXe3?oM(QH(#YJC+MRhv9aflIV1m|5-z3llP((Wa(IHqDaz73;iHe?Ze0 zYCA_1dJ$wjrh8(rXUenetbq0#4+Rv2GPT?e2KKP$0bg}O+dodOY;1#le>;XDms=`^;3eeH2Y;ho`3YZEj}&7J8ve-5xOe}(nRHd*ej==*TZL?#Voj1b@qaXQ=^kimo98;Wf*z- z6h8w<12!Al9UJwfn(|^>i6qJ<>HNbY%P4~7R0vg6YinuSbX_=LLy|xhZ)xpZ%5T}# zSvn`#8eJ2pJUdM2&65B3XCa2!{r{+q1$`&gpt^U9joYpBfja~PWZWD0`Qb1_a5Oms zdES{;%{sCh+SM|(XRS{8x__yWEaSjo43mWeH$!grb~D+)hjL8e~olZ9k%}Sf2&`onYibQjsgjp()`*fa@a-HPY8$s;~-d50lj%1U&9S9;YLcf zi8wQ9Hk6@I+5cLn$If18;O;0f)GC8R{JCTPcBZ=QRHlJr;@Wb<-yzA_(CoM&QJj_N zoo^`;eH>(1Cpc8l+MKH~EFk^AKg%HM+S%vRQEyAII3=kn!BXjTca>_mX076yRRxO_ zNK5?JA3*qTv_&NdwS6L0^0VM`7h0g$p`J$KjVzGd^h*3d&@#0N`q!#^k^GQpRi$34xm%9;jg(1BDP5Cio79`D+3Xw^6tQOYWls=D5{l_c0h#f z0bDJ5YNE}l=ZM7&8}LADle$;RLo_sk_pd4+hQ0}RbHhpAqL3k&K`i_EmvJsJ=z@ax zl4L50i2F=$&k~eFcW`c__wzEoK)9be@xZkl2jY$&;EwFl+|QkH8_2sApn} z!wO_h1e%%pJ7y|7fcw`Jt#Z>&Z$eJmZTazG3UR*z#37KX=i%5wZnWiqgMAm}!q0*9 zUiX{86w+rq2hF{Lbw=Z9Bw1@B2n)Smf*v#s-gOWvOqk^FE(u+gA|3C5Be`KY}XC9Fv9h$L6l^DTLthz=XSPGUfFlz?yCK(=Sq zF3g0C{jRs2(~d{t0=)u>xSbb|;8vQPQJTU0TRdfp+@JmWoqoPcrkNj}U||Xmo015N zjqEEDb*(acp+UjM=1<*ZAw16dBx^%h8<2N#rS{hTjrI&SOO)dlg4mJUbk$__fqU^=!hVbt`CA5lxs@R7!98{*4Dk!CmYfMM0;YKqN&ZNqK0Rh8=CbG;u+K_s1-8 zoZCv??xF za;v=jww{d-5~>FX-mZrB?XAy0O)Y8O ze~uZ2X)BTUP{au98&kIAkG$a zD`-0Sg(%wm{`%vdXB(`z+w}A~=f^9VQ7zXs-;P<8p|EMx)nTzy%nlt47{eDV%mj_f zOqp{3nP%Ic+0dXy6L7>Dpo=q&xA!_SjTh^bzJW8T@iMSc9qEq5M&L$eIp-}tO@Kp2 zuKVNzRZ!F3xLCcSGaV7BB0q2XjL8s!1Sjd*{szjF6gK9m3JY3E=coHM9i+G#nF`F z_b2VaCep=n$u1(^sx})c{0vpo9SyVZ1*Ol^N(t^Q*ZZ>WtJ+l7e4Y=JV>sBlK;GTw z+r{W50x8wv`+YW#5@c&LtZQjU{)@?#-8UovKPy3DG8{N=K=<(-Yh8a9XRv2CSkErv4g^>G*~NDS4dmgxVC*fP(^WHmp@28qz2bK8+#ldSfq<(M*M8jxf;L0zzk+`?VN3*hiVYJ#T&u^vB<_L_~B zqeVdeK@juI#d@X>dT6&HcvmNe1F$igZ+QmUJUb(ZjCbaMUg8P;f!ClWYL!YdaPkt? zNB#SnS7kT^GLCW=p^~G2o3r&iObA(0iD{gIs?hJ{8yio8na&rI##(Jg&}v?;SoZ&I-2fsH9G*x67svQr*stD8QDw=t zS@WQ?aZ5Xx?PLt1^lKCE1HVgtr=ZQ93Laxd14!IGEWzIG>PQ2q`K*NSt!nsAVzVSZ z8)o*@?@AK&W*tzRYdbWSaGCvB-oM_O^p#CgK&ZH?6wUIJeO3cNNDI=KU!qX#V-C(B zwnejS#K%(3a}(J;8%TP0Fx}cVNEk}BT`?nDwxIfiVRoWtN{t^@Y@X(y2y!wlBf(=A z30o7+%nk}i(*6bLg~IsvJOtT}OJw3JOV6)fQ{{Gu!g_xIelPj^KvZAVbwHHPZ#y7( z)uEy>=(i#oC>AXYerU&aT|h=~FjHfve=Q`+K+&usJ=PAuz2Dfh)6u~ONr=aYiN-U@ zcF-jp4yFJtKAC;6u5*6fDth}>=A+oE)PyAlHm*)@%M0wEUNYH=?mN&34o$Q^!2DhK z<7t!g9g-~<_?1-fSEJ^EKeUZNq{`oT2j9END{CZH(7IC8NceE&C_l$q<93U3og!Rs zZg*u6Z`Ew8NH|p38CQp%oP8{Twv$aSLo%VNBtcAf))Ak7GSC;CzSgZaW3)4Z=3XC5 z5YxiMukvevo?)HheLqvP>($mB&d5L2T;jG0p<)ezJ1f)FOG%vjdpOr_$0@YxnrCOG z^+ zruFN`P>DK1l59#%Bp<|AZw)OYK*rrTDLPi9MnwZZIUKq;>^Dp@WYPnbQK|M3JRrcU zIZ|ouss-Qk%2XbJQ$NM|FbT=yTA={NOF7-5WOV31B?6_-n7HO!0e!r+AkZq1jWD|J zQk`}Z*j_4g>0x6db(#ocGvQhCb=dM)D{_)4|H^G4Dm30jYbuedG&_)B8J7hCLt0Kl zqSLAAbf)C=?Qr3^UYIC28KOYo`R}`tBqJA?*eY*H>RY0Jupbg*Sv-Uw}m*{CDDLmQEIP!kYHS9WpXa zW`2^jXvU#H12WL>V-#*bYL8{DUQQS`Qph^D-6k^B;MVu=L&6Ti{aiE;`xySisW=hX z#R2}&^OUuR*i4i!LPLebEfkU}FGR{mi&=Sg{%%E(`1vq-cLLAAz`q%)GUOaJaSUf2igs2#|57FyA|Ui^-R&@p)fwqhq% zHpYQ#;B`@ z)&A;Kq4-asS8L%SS!^?1#58bLBeWcVIMhuW_*8x;K-G#i9m=MKQv zisEiQSp^q$`v#ks5za%-0~|Mari4FKR`XfL#Ymq#g&C1QF)>pzxQ{B+P6g~9VNUB+ z3~(7u>}7^*`NvK zqn5|_O3agI>Xo;KxMhD2L5}}lz94E6Yya5$J9VLbOz*vww37|lvaxc1@Q}%9@q=U! zD4QgZc~WI1e^=KDV%6%Tl#%zDI4)*yMQs0E4?wN-pJJ!Ap_~ZNU4XnwS4>|Ox^vE zFn+e;kVuf&9<&mN!a0u;2pis_TLUI8b2wKN!f{)!sgq@2j}hppu1w?T-|r<~bAIE{ zORCe)(7?(vf8Zq{Lm_Spaw4_Oxxja(DH7F4+(*(vL3ID z6AfM|ku1R096MElBLYdS0(v5fCmAf%tZjM+H=WuUItA6J_aP45K6i_Po;(b^j#qEO zM_d*>nik5%<;9yVQ%x$o_t<3~)#ZZKOC5BH5}mZLR$YwP*>kYJFN-|D|JbWQC2^Z# zrEl{LBf_MF*o~5;*LAB#(F06tZI!Axf66SQ_t!iKH)5?xE2cQ(py_`$n+xfkLY$jq z6^;6SbDF9RmO&!Am3Fik|nW1~*^1IV_u7+$AZR&5r5{DUzw-IBHMkKACG5F!L||65 zCAZ6>Kt0MXmx_LVg5@Nw0)NF$TpuxF%s`n|I64w62B_^;HFWCcB3b)#GARIR%|bo4 z@`!i~t&UR3(^T12otL-@D)JeFPSeOAK`dN=Rgw7N^N=8(K1RTf2RkM(>Lygemj+X) z6L=pfv#b1rNFzue-jFFyNBUvoQNt=19TXFoLr`_mW{X|OT_o(+Dd&p!mz*#e`A7BJ zs09bUUl1c%=<~9Y!{khH+JTpmZ;|KE`dMo?D`8hA;{32)A@NWeK|9mL%6|g-=h|9l z)-LmkL{*j9J`I*3MpWOZRE6x#Oa%}f_XfwzcMdK59rpjcEGLZ1(#~tz^CzJ^(OBF7M2Jn?O5bn8L5yv4Zx+$D$~aUqWD-1O)5|*&&*xyNxLqs& zwu{bK;!^PK4w^cbOdOe-FQ9C+oR&-BWSMNgco}AD>r$wVLbkX1#5YRxm%5@0W385% zmpY*!>cEeQC`J|)Q|Fe!_L5glM{J5LxLN=wsX4{w@kz8t___ane~U5ftPG>KW0k5{ z6J!DH>6CzO&k|l{tXRm)!u`#ez*w^YuS*o#17^t-e`u;1@Lr^w{V z32!rXjb1Zxbw@ln8%1Yp78iYN=?jM$iXbI)J1t~3OrGk%^(a)nM7;cDjdAi;2Pnew zb4l>qa}%Pbu}j3UNnP8AtDrA5$h!c6!xQ^gCqrNDGErJf+;fUx-?lHMy91t^Nw=(- zpddM+3=(;HCc>R1WnP4YMvS&`P`KlCWhX7ldMQI~v+DY(Yz`fP;|)g>yncU}p$%zo z0Ns;~>SReikgMF1yUJtr=?RwC8&8>pv57EE9%4?9aCiL0AK1vG6w3QqB^_*XsJWA~ z+OmTbNfH7gve|N^jTGy5IG2pJnjU!+2>+>5`-08T6Tjg?P&DZZ;dS|B5Q&Sw&ygp! zR?k5Z{M-M1)Tp_$Xqx9Za93t^jS4p30v@fRx69-aHD*pE$t#IX5=#f8# ztzK5^h8!y*m{fi*qG^^0U1QLe)-HG*-d9I8vOd=@I1IFHv4Ie*4qlijB`r|${3Z6J zOaX58c_ljq9X%{r^bBj;Jo9RG4iJA!5$8-^M3mNSZ%_oq4ht4_@l3!&^%_%6azdOi zY^2{1t)tPy;trc1`oP6|QlAU0(REXSbZO@OZJ5!Q?0}pnVNoumL#aP{I@@R(EAp!HR z@jOt;r;5_qdp8eO+ViMn%GXS^uSC;M_GipnbnfDV7x`()l7+@*-|$$_2ou_%*!847>=%6)q9ep3JVaj1W;B! zrQ5*?Bp_I-J%&Y(76m<``UL6kkBpQ9LOpgnXvPe5p|6a1fNVB=9}sZG)haqE383%* zW|f#m?~bR-_luw_6`s3JTQPn}2&?i}3EH@W|B*~$hWqLl*2{)dru};E3#~u>x*>AS z7L{kk{m0Fu;#^BGMDpL7T7LexP$p#bO+Z%_YR zp$jVgIDatWzEU|An!aPoSovgDh~e*TBmZlbN3UAEpd(W^(h0&jasSs$LZx8EQ^&!F zmcWMBuF0jzH;3LJTz$g9}3ZQQ$dmyN7_S%CHIuXoiKyXrf7h}H z|D365`f^n##?85o$nm)*MzyUv_VN7_tU)Ia4<-q7w$)8T0B|}phAefOwMPQ|6L2{m2ccyOa zB=N2#G0tawg^+7<>_jxQ(FBoXcWPv1IwCH~RF-e6_`hqgwm`65iY)9QG$3)WGbaB=Qe99&)#5KQctgn=dgShpfw(1djZy`V@oT zudn%JT2QB>^SI@Y=;R6NW^0yqIEwmUZ@$G;oyOfw(gY4H4(E9&+Q#?4Sgkm<7x@T$ zKKqQIx9(~%R*w^`TICa%3}oqKpvBnxNK+ANwjzaJPcIS1PJ;F&{bkE^g7+nZBjOs< zhBX@}Sm_N#{mZb0GaACm)JmT3+su&90R9ebNZdnU&Ud(Mb7T=2-z9_QlnoGI0p&{6 z^N9#;g2--8^FBsbbaHd1M0q@uAkqqHi(?BmNdm{j4w0sn-(ITjbnS{?iL=|%mzrrZQ@Mw1=sDYL&>9PmDkJx$*s z@s&i%v1N}IN>Khj@v~JW&)~zpdOmo8{q(=S@W2^>v%umjMxp zkQD;`IBx{HC;%a885H%}L9|Sr1nsQMG~si>_%%kr-d!`tl1norH??;m_0NJf&;Zf< zajq4Wj-AM1Br?WdH>NowJhwS*ozk~o&j9I6W!gxnl2|3dAQKzwEz`KpiO zzA?E!i6q3CEM4DosYubf0r8t$yF7c-`{mTJp;pn}E+j2zbDJ7?u&f|5n{(Q*t|cf^ z>Z3AF)cv0?s@(QRr4}@~vnl85mrb~mLuoa@M{nVcl4DtuYo%cTg>+h&r(Oz$%38RY z#B9Xxd+#0_SQ4RAf5qo=quO&f7ftHoB9cN*X$ZHe3FNmwL>EZPF>DvNdM+|Yq`~ei z{OHVvlGpDPae!@sp&6z20R-8-cDOmesPbIBRW4ihSn4A*tw#h4s~RXkXnwW{Gt zGGLsOM z0Y29YB~@OnaMo(MYvD;&xl?!~dh^gJgD zL1jsN(A&D@_44Z#z*U{CFOap@?N)MaHX9=KP`u?cQwo@vLn~*%kilbDt2QP!JYX8u_c-{)1tFyr z26$N{c_Yc^sC! zxEsurJ31tVo^nIf?V*Zv>^9JP)(8B?%DVQnR}o@fHu zCtnEq;sIElWz77!F56Ki&}xe5@=p=>jFsu9zT{w^g_dK-X~v<#pqxVXzK2Pp+$m0k zX$6?3r$rO#%SAhrEb%w!SDnk$5t1hCpXSN;a!C%w|8$bhA4rn-Cg0NZDSR2M8*&~f zHkiufpb8)&(9&c)A5WYxTAdNSTamMwD!=WK>&@>VT8Rc{5l^z7xOal6!8W{gkZ021n3R)#7uXgA6px$d9A;7|m8&igbb)&Q?LmWaOH4h@p!v3BJ0#1hr>z}93sOPW zRx2Gxm&2o0EuHcgPJDi@*SLrTZ$#Q;KAVktw$f*pb~6nVnyAc-;@swZpMub}u2aD}M=tFi3Qo36@20#d3enk)MbKSZi%;DRs&Cnp+iGDIRL#8H~ z_e^$v3-J|&0K{xNPPFEO%J#*`#$`XTR;@5=t#*{T=x8^DMCqLEBIDRXrU&tzEdoV2 zo$88N@Yo$5X*&_{M8bmvVXa7#@SC!b#NYEWG1a=2$sM!MIE5f_`UhHVK#8ms@}%_x z@lEgL-dh36Agc-Fz3fRo*S~xQB%JO>48h)~Y|9be^Pnx)$j@LP!wdR_LNc*JtB(;s z+NL+E2lnSY>O|q^tdoV9F`v(lo&{@FVD~{RSPCkNV^`&#{-sT`7rCA>7xG~*i`hbH zf(%ij(iT&^On&Q|iXZftBCLpBijublZ?p?Pfo77-Mvw+=O_bemDB)n7`65~MNo`w5 zvM|UY_zw?cZ}T^_F+p(oGoKAA+jo9l8szo~QAz%h2FFgO5JenN;Qlk0gBtBRaevpA z=1_&67Kt_O7ZE31B}J2o7F9ZN`^~)hoZJJn`b=7crtk3g8$o+^hYpPM=A&Qvtl+}7 zdB1kd-pT1md8WzZX9DkeNl22oUwQwjyQY4zvqQwH=spO)NJO1Y6AOq^LjmtjNbUix z7hlj^yH3*Di{bzzcj%sQe3%Wt3h@>D8$|~8?2?*OE%$27y*vgc*oAt~-Ki56w=So+ zCYd6n)kkD+65D%N8wu52M~F~33dIXlbC0kIxNCl;K^-WSO+T0kvJtHz$chRBt)oo) z<%0&(Zrkf0OuXD++>3Sjr9!F?SqrLWkG32FTc?n?wUau^UTpfrxd=w2Cy^i}i;q3e zvkX;JX-!h+sg|Vk@86|*?oEe;8YhGTfBijxwKFPc1bePk6}(M$+7Y66<%znrbO2~X z1T%jO(snArHIw*UHGk}2|0Gw>it!>%(x54l8Hi}I_owYk#)hj z{HHIPfSS`hU3H+SKdJh2*k=?nj@tAt*&kLiwE5WU;&*{|f&GaN7JdcV`kk6RpIbnN zBG7lqJs;had-di7%hXS4*`nfdsd`wU#lfJgi2xoL+ZX+V&gah`Cx_r!Ym)scfO(Ee z@vB|JUy)vQ5ouVNR0EO*9NaRx+gB=UF?YsiHS%_<2bxvf{{mNpf~$bImm6+$Q>nj& zn4Vnl^Ij(t(T+qi1r$d{m<5V23(0nik2b$hi=~LBxtCBGB%~8j)w%y`bL%T`Kn?)Prr4=TBnw%;$hLgFQqkkW7k8 zbCf__eCNawwsM32FRfh0|9}zRioj#1~|4C;OoOl zg;i2@MUcohwbVvEe;z&cvkR?K6w~Adw3PyFq3XnfeYuC2N#&1Z_ov?=2pr}>V7IqW zy(+d-bn4GY)fRC44w8Wb4;%8ga^?_R(4Mo_&b836kvHk5m^c-i%+DO?5R?gl4SVW; zUker?sJ8R0JUi$tBf(2cxM0Rx-r#s(L~`7lZyI;6l0WHu(#ju8D_C=AuaC)MJ6Kf6 zP>mdvF5-xY0d~eX;@n66;BzU;f>xOFdw3Z4>xeN?k^4<1c2iyD-xkF(yO~@)TaTV~ zYoQyEM6Uj@M9x!j`Y<{|sqP4QR`7eV=l}a&hPD|E&a3m|3C?-&t`XN3^O8T0IA=pO zoCLl=wuD4`J-glo1h{&N5Ck~fxIdgC9D1~-f3(T#kPT;4LoFg#?Tsvsr1OS2C`YMRt?EX z!X<(uo>?qwU?bbCaBox=w?GUH9lTde1K$Jjv3r8GhPaU`XRy{uA`>CS=iF~qe3FY} z>+D}?Q37QF&liXd z)g~v^WN6J;CN1rT)?7HZJMVP5PR^Kf9aM~7!1$3!OalmmO$=ZIzrQSt3-_&f5Yk33 zdk+)ws}ii`QuMF>ECw=gvXf0p?>1pIzS=aBU?nnCe7Cc*VwGKiB)$%;MIYGwnMxwT)Uso=Zsdrh&!ePRi!(l+_j6@DStmo?Dp!{!No}=(h zKq1~MF}y5!_9`y`L`Ej+$}Oo8K|sW5f#|6ERzl#?^zLj}EmxO-SG{LWInHg<^7GQ9 zxRNdsVvlt!5TD4??Z21t2>h!>#kgnpMbKcU@k08cvUq5(=U8I2#xV5KTf z7VDa4EC@rHN;cta#XlQ%jF8}!>dSdqQi0glC+=ZDpkZG;*R zU%ZF9pwEPdY}}_uS8|PtiQ!PQg@ez8_k_>XDiI%>EsGwaRXJVf_tKSt^YpyPFCJ}< zi4ZCWd9`g3?rK@wHuRIol-jEQdQA{v{+iELDK|e&%XTLzIFM36 zdlUcyjpjvA6o_-HE)*=@qI28pBs%t+6lP_xLBm?XS+Z7rE&RPr493p@zlt58K2b$( zAao#+bzou@JXj^}8b|cfxQp+^XQE`po1n7!r9sws5JfTYBMw2T#*sj!A6isOfVcL? z!xK?IO#2vT3Y-!>yRJ7B9-T4}$<&{4{jh(FJK59V`JkNunGuUG zmk?n;mnlwS~4}{H%N;F-%O@a~;rW`Wr9Pv=!qkIV?Qd8=E^yyKqy?u7Eg7w?wK6`P9JD%qj5e4B9w}mu|17=-#B&RvD1azBnr1=Q z%DHI{Rd3_mZ1H2n`o0Hj94kJ_)ny6l#z@|J;}8e1r)T|oxTm|rRLGmyxpV<}LL%{_ z1)~)tK3X5bDJpc&?XO#r9JcY_1!~x)0dB2JO z(LMwSgp*$TT8YL;I$*znMJMp6RDeY$3b^?Qm%%DUz@vYES~aMBZlxF|HHfU`p$g&T zppw|l`)TaLB1Xbo-o*ij6o->p{>acY(iqO7teI~3JI3*v+{80`;iQ_)-%m`TCa=r$(fbU#TOPx zdJ7~gm-r2uOF9>!;1wlKO2M>5YD-ZpOhc8A$ zr|A6#<>)dMb6!1!49&segpHjmDn-u8fklzC^;RW$lM~JRp(T);#LH+3C>a+%*R0C; z6}CBb15vUedXt7|{bu!P76~Mt%ajeh7%mN>2;@c1fW(bID`Z`@4N)lUheX@q=lt$e z(KH@_7j8?m?93?H+9?q7!}~(ApJme`sz|=Uw}|NhpX)WQS~)osJMEtn)`eN9&{+3J zP>LkaULKvXsdMTm^~(%vd5|3uvNf$=`u$=enuccW#x0wuI|uzUqj$t_8Gw0@XHUUz zc+#3Ig~o4_Y(X3VXkcBXrE>FlewpPO#6Nf9m8FJxiVDX zjA9o?N$&oQCj2jm+YltYyFnInYak@z)BR?I zBGbysl1+EjT5?-lhE{d3u?;~50SN3ek)V0K<`-_#<s@j9U z37MLB_-yw)AWcU3Xa!B>%j8(u$QJL$Izm}gyr)C{a6!yntHvN=+(s>TUXd3!8Y?eF zfAA2@ugs|tF4|C-e6o>qe0Y$2sgboqBK8XF=1*#&d4-*^*f1pms5Brw0eA;$Pjg$fodnK7s^oT;T*ft!wUetI zgg@&*M3I0hktWYd%tc{69x9n^N0B_uE^a*5FGWvdVXb+)PEDXd2q!G}zUI zg9wLC5>K%<#Ga`m*D#+*XA5m8yiarkEGaBhlTf5+(lAW&vy_4&S07691N(m`L0(nP zIo}q!6UXM~d)qc}gOazIsxTDUxQjwo!k}OayWp2xNYy5`Ew3Uc>7L)TrE{5(D0+x2(Ix#Wdu0PnS8wKV}%^p=4 z+mJB0{1Ad)Z}DeB@{~k4yJ;}N6xUbk5|8z5T3cC`AKVi$l88jCD)OLJguN!yw}&;f z1j0w~+Ayf*cZSYI%SI=Ie_4(d7l!X73*i+pz*>ogSdF^DVTVLI5GX9CxKEu5c4EB~ z@u4)#^=mJl*cS26Mg}yf+q5rcjo~C9DmYJ)pna*DPG*6o9+!|S`S1IO@A**M&ucvR zTFfbtf<*6Yk-f$9M-h)dV9tsPTm7WmsQixzK&tDwO66? z-N1{80y}Q&6pJxh`i9ElRc+6Fb z)OI%pP3wFF5y`|Wk8!-y!K6Xatay*4N?VD)A841MU#E(w+?2=H_1g_`ut0-Gluq|` zY9`;R{TUKi6#R)!(zAsJ%QPmjLhq?nNVrqsQYP;}LC-+=tsTpC0UI7o#Iat!)M)}w zF3ZZmQw1N);$ETJTS%_WpnG1;LkyMYAu*M$I+_Jfh;7==qNICvr74vyjFEmko7NcyePpsv| zjXrzk@3p1|k?2twaKDj8*jthy`Mru- zt#pV&56!xf7%kJBc zn$#nP(wzdRWZkN!**2dP?+tOc%VGD^1(Lpz-?0uLa*c#97RPm(7&h&DI1=2%G&gwz z+HokUd!?Kv7ZlMGPUhhNptn=Y$M-+=}&!$&@1hHG=1`i1jjgYPJ{d{7l`Vnpp9gtZXors-4aJKh0S1tAZ(xeP4Mev+nwvMWgC0$ z%fl6$%A_E;(aOmw2jdP13=i`z35wD0+WICJq<=!IRjqa&Ss2nGX?Q6H+F}W0-kd`c zF%=p##rnl_Pt^)*OP9zFKku(juJ{?1Y;MjFSclM9O0|7$NX3*fx$6eh>C)$F!lC9Z z+bKc2%#XL~DJ_IVyZ_ps8)Lxe-f2Y32}xhFQ!I(+XsU?aH2g`QY(sg2o>d-@yiVhD zOKn8n_%H-zx{t@WPLhZ9nkVYw9H zR71>DO|pFJx4!<^Jr^glcTBMCp&>Ata;p#Ib{}qHswBHt4#t>vfbA5raC{CB^MpK^ zUcI~lzt%}}Ga~lR7Xk`eFJFt-9II`+F0?x|GEee*5ilFHIMQ^l3U^KpkX)6O4O+(q z)8XK1|r{1Wuf!~rkna|3n7Y;%8W~3c0E#&kp{ihhwn2aIV#pH{Dq~yh9Y+7zE`)|i zzZfLRLchB052)+7QzR{C3cISdNbKzXFI*(T!rA>r{mPkN+*Mc#Br1S z?E@uRIoXX#mJv@I)u1`nYI%#~s=qHd)V_H54pvaG0+Eq^#~ARvtP^Xq&8l3Jn1t&Z zMc87VJ$;W+LTBXpnrlVf*nu_9FAc3RBvR-`kT>e1gHNotgvaHG$b$rqMC)G1n^#Wa zHAN{W8WWi~E3%wZbz`5KD5cUuknk*Kvj3;56?_WMF46b_$n{LF42V)F;yM*wG1ksC=~ zpaFvSVg8tj%0++!cx;X4(>|yqd1rAPBfcZa!ofrrafK|e`DF&1)30&8QNB->{44T| zG#Mp_sC>!87|#R;Nk;L!Y7#VJsix0Bju2FkP>}436f=j`Cs*Uo|h;l@V>kWR&P9gq_gVDtNn{O=EgnPQkr2&i#c1rISKUU$9Ay#}aVllfL2<~) zUk*P{AG%BxGopG>@YQGnK~Ch*!)ZE4O5aX2|g5#XxSz_@9q&m*+1E3qH|aPlxV2y$i=+YR!+93ZvQ*) zqrl!IN8XT6azNk?_X-tQ&15Ih%JTLWCV5c(?<6E%$-&)+A3paDwYH@FV46X;rc70y zqsIrtK@p%kCq~kK@1Usmsz>t-MWP1|mx%jbFO9O^3~I`+6Gjrz(7h(>=>}5SaFd)&3l<=9*YzG>=^n-VsRTowqi8ZBZZ6j= zlFYkh#{wyT@FY44zHBz*aKm;B*p04{sS_HuZ~ND-(mX<+lR(0E?t%NyNj&XhPVpJE zr%!@);IdW`4kuI+n2b1gqi<>>&gSBF&cjozc{p*SZJYcTNH@4Rfb0Y{ARU|x!RG~n z;>Hf{jl$sjhM+jm!CUy>*J9F598Zc4eq;W|-(65?32NL0d1emr&rx8Q;6rmT9)szE?p9aRpMI{?2D3Q zi}=kcy#Djex{A}8B0ZCBnb+F=sC6nz_$kjF4z|xQmh>*yk~sYDYtHxs1QPM=578Ql zZQ`RT9GTeuAv{cF46`^&6J35Q_YYDF;iq5RA2L`O?pF6 z#l85#@Bi)#(ms*Hu*NN?naJD-?++SHx7_DJ{5MLlv;e|q2V(T-GpmiJF4F@s2wz*M z7&fR3h@)&}K5eZ%?jGS>khZqQ9Icw#PRz<@)#D32%2QQ9wPoPN90Yz1f`tmdZfYL7 z^Pp*R-`7NCXA1PxX_-|=Gj~((CJ{KA>XDISN2nL7!r1U#*}b&@sk160g$nxqvmnvB zKa6CgJ>3!i6CuHTL~q8N+ws*|RotagN_Bc=x^!H4PyNRw+JnHjUFrLfRN}w!xonKy zxI8$NepK`}RyU?)MT^$sEF@lG((2dhyl# zy@Gtsv?jvodQ|@wzgA!n^ zxJM-oCZdUF)9s+5NKj2=HNMDoD&?7x3&s0U{F-4Yne5nOWJ7deoOrL>4!Mehgg-){wuWCV_P(FI#tu~@h zV^R(NjQ4NF1j(%|6pFyRdexY2BCSAEGv(G5YB(RnK^5tyc}#-ZXQ_58}jNXgMlHFFOE^FoFB1V*19`w3`j#O*nwmbI} z_c3o+ESd1;JB~@k$&@8jcplKSB7ap|xp`C=g^B4TAt*s_O(WJn88trVdW!_hM^4<> z{6KeqlpBQyaqqsgASo3Owxy{8L;LGM_2twiA zg`lWct{W09EEN-rWt&qiy6hm$sSk!R^i?nu?$m|@2e0klvCmu-BGmvC8b6E4uvaXQ zSfC`ymWGkpF$v072j_|*ZcOt*ppAtjmxCQw?klfIL76w?l0gTl$g`{WJE!!jzR*eJ zFo(db+yj5tIEnj!b4u1{DaoErW!fignp{=TTd_RaL8zcHRjQ2)_NHj)r7vv^62}Z8 zQP@KZJArX>$B2zK_vK^8YnQaY|Y4==&Y$dTZ zGp_fBY9FlvvG@niDLbn=jU(Fp}2i+D_9_r_5CB@jgGlM2 zm%QYzSt z!fQ&_G5`Rz>#?>1kgd5B$NMpr=ZeY5nu%h%$A=MDcIfS->3ym-JOjKA5-dDVIh@b0 zxJkx@$7bR}q9eSHl+PK2Vw><=Lqlp-1{3I`XQU!nNfxcCsMQ1RkQ5dA^e8Z{Nfd0Hm>)KGMpH&@XR<@iZoC$Hdt-Xxr1k`SB#}&rW`}*aeX+DUnlJ^dcpTA~v84pNMDiT7(r9b24L#m~*ZBT;vd^gsfD^&_oP&jRTh$ptH3 zu&+#*_Ld?JF&FU;NMzgOOo~o%r{eU(kYylhNT^eC#b#{B-|O*V|KdG6YHZB{e{p=h zcs@IKM7f;_${XxO>u%6zHQ4Qlq{nvb^CLo|Bl|6Q9LhSXsv>!(>*W(HpV-8OkSLKA zuSj5Rm{j3lGd=`c0C&vly>e%8xS`rG->O}qu`ivV*;UA;ZH(&Y+~UjVocZPL5Vifl z*^w!XO`qHd*J-AQ#*_yFey{l7wFeV1d{(xZM*be;)6|WV%_+_alyEk?tHltXUH?BC z{;ouU9Z6QMX5A4U5DsXwg<99bRiYy65U(!Lu$?RDiZ7`V38smWuQ1f!kB7fMqgLL}0C0VvRkW z-JoA*`<_P7oD$A&e6}eEK=9sCtkpj)KX;zz!OkpxwuXXOOASd?h@0eG<#%l{xkRLT zQ1E=sW?REfG1?vfgqbX#M*Chn&BDjTGe=zd-(oRH(`d`@)IB%Oq)-+bA-rn`gZhzg zW;gfx2o}vu+i)0pINy}}^H zrjd3^yHXFqTuoSAc)xgt=C5eV#=Flk_N&YF(CQR6_mQ8SSxv-gwoLqGdpb?~&)-B! zbD4YMR7~D|Vicm)S`cm1`Eoq8JGSrf-;hiZF3e&38GQYVav`Ovy1N_VlOSU2y1v|dpF7#Tx$H?*0_>AmeB_{4Jb+xC5`^hBvreAX(SC{(kwvB&DzQq8IwTe zTaLZAP7@TW>$}(GA6argw42X6=cKT7)az?vE@&cJQ?nze@+ZN%;vsn@@UGRwHZ!{h z-MoXp$Z9AY31F^Td>qxoR1ZUA#C*R$YZ898iWkkYc#k<)sz+n_Rk0!mQ49+5` zD2H{ZWkmZ%;#ZZGkRzQbCKapy!`#MC>ufz6O%+Hs|2bfpS^WDx^_=<6;s+2R6JjNeoYp9%9X-4>zX?I@`aEOkO3CzpMR|=#;x{PFyOId(Giy_tz4?ZU>QdTV(I^;;vKAP+y8HN2kwbm$#E@8#GPb zIN$N^P>$|xzkjebIt^%kiK~q~A0v5>f(&(|@;}9EJ1M9jXS#8s?7zbk9pAU&Z5WgI zgLFmzdGkC=-u1d$g5`EFTYu)y2sGHKwTvvnTs1u(*rYkODKU$ZYpVLsb^V1kR;u<8N8d*hUaUGKUS3VXr%?Piv@K4)1419x zniZKX$>p_CDE5PxTUkPsQ6+l>Jvpw#l>;Fmxm=Ikr7zG2XgCVkn=ztk&Gq6D%X! zitb0oo9^6rg>6K3EFw%YL9c{5Ex6IzXSW-Dh#)Nebs=RU=>W;@kVep?L0UJAC?u~) zBELS5LA|bt-zV!m~YF&%O0Fo%vFT#zA&3!|~x5 zOB4&0aT$vjm_inx(n8$>UR^R}Q1-7CJ;l8kdsbN{$rt~r)6pUzet)^4w@$Fk24&!i zq~u4%3e^U^ZgKDle#HYC7}l1iyo z+zramIY-0YmU4S|{u>0?I{ZCaF{Xv`tiF3_vE-30@D5Sal6rx-MXyJuU5ZeBjXkqE zdOkKfE~@O$5%V-_B70U-{mx_K^wS%~dNm047yZuN@3mG1HOBmqU}IfcGImYkXH#XS z=ZC#x2s>64?*9rRsZFCvd##)=?C*S-GTUhj9z#hHLlIlotD3w|Af_lf$2v^*Jg|=O zGl-)$Q9E{zI_0CCD#EPba4s1=FxjP;%C72_4%SS>lh;afaC4h9_CY+<=o(`&+4c{T ztCc!lkn8$Rlf8)hKtEMlBHo*ZW;so|r8sh19fM!74(@exJ2lcpP?9XRp?b2A`=o_s z8NLOuN~f`65w=V3wOKYS%ywkC4t5EgNNm0M0rmk6gw`qeLt=eWhKUt?E`xiEBG<~Z z&*nP~++BM!demB=&NJmi2~jeZfG~2YA&FD>?(JS9QNV#f{Ut~)WKOG+H1OxGZ1eZJL7 z2-M&j&YonXOn#59r>XSQS}mN!p2Y7Y`e_&*unP9(psI*TTZ?$)wQC*EjuI^T<4&j5 zzy-P1)~anfwn{oP?LNSx;ZO>bu(eK2ZQJ}@nm9_aQV)v0vZv&rSpI}ukDr^sGCnC{W1_pA8kSdi@fKpXmtM27RC|}2e548}R9TEp74F4% z2sv-ms!G-M-z^C>gwa5TbT@&F%N3Ov`fb)LH@t5+W@OrLKrttfJ%t4-}jnhtJP!w+|+#2#bz|#pRj0*(xDXum$v9$vn2O1Ei zO3jm<9vIlHc|IuQPI;l_0j>u9*^nU5GDRLmx8*xo1%$>9C~BMZ&jAN5MKkk^oI7ce z6if(l$Tdx?hS}*$Y?fNRz;+YlER_~OnM;C*_iwsX@xG9$MDcAjgbSPs%4%!`xyaJT zepcF0ZE77DnQo2P??8LRhB~b9;^EP+8Pijvy-InTAf-)TF4>O9XSq&5a;ER2(TPv) zHE2Wi&-KsO{NndW%{uIl{+}r5j)^4NdO!Tsels@gMQ-;Z&GLy^9zLqa~Q z-bcCoXtH(WzklnM-{VF)Fxmyk|;ed$&Uh(B>}Gs zYT7XYdy3ZU>bF3A^V+;7xO@-?R2t+9({?x=h;_Aeiy1`+|y@s4=6^u7Ew{48kPuIyO}1e zRT(5JVn{r06UWbolb%JP9$Vr^_O+Nj^m7TZmJQIb80h1NOy^y`dDkkoDcWR*@9kRe176$YRHj(& zc+X#o=A+$Yyf15Y8(MF!TzbLoV@sC}DJ3uyg@FBrccaGmY zvw@-)Nfly9t^7-oQ*+U9iw^?|{Ca=y7b>XglFv}fC&Aj<)Wbwzr^@TJt5D*)iASE| z6HM{}l{>Liqh>1jYWq$Szb5brrhs568!;1~Gb9Iph@1(xMsX}9o8R`CGqu_oQ%d%h z0BQS)8(g)Orn;meZ8_;z6ve@3X~>l+n#ZUQ|Jyr`Zxiv1#;Khmg0BAzOtO4MH1rv9 z#$4Rl3g+j{wh~?1Z;mi$;$Eh= zw)m4_I?gHA5(f__VS#S<_wN?uMtsV0nd)7O$+f@Ytp;RI75*tKx~Q&OH+@or&v_`} zb4n`5`YF|*ddf#&MGoFS5>MlHiKd{u5Ge$SAkewC_H6)T_jie#MMY88@1J%5xf=C( z%#ZT-AYtPp)Ks{L5AY8jfp6?i$Q2GOddE{hWS zjKgznLMJA{1t)L@AH8BL6fT#7E>WayN^Xx!#4}5wZY0hK8fdxhYSCDG5-4K)ccu|$ z#-0t$g~zpa=Kas|HCOAcdpmYenSt`;t69hRTM$-PKmyzjhhQMCUOWlKHdz*IpJZyx zi)!(m+5&`lfsHy0a+XjPRP2$ew z_t@)N3lr} zgsnTE=@t%+{&)OYq?#1hNwbz=rs_z0+3& z_b0)+L&`3&uaI1AQ_oA`AWTKpv*{cvYMT)0$ik!sOsU)+PWqXq5!wM&7=NB>QFHo- ziGZj;|6MK_Jo8}KDfIJOG(LDJ_5pLHhraao1!_mT4HytA&0B3Mb}!>bVTgbR!8Fn> z_Yz**YfR6?ror*mw4ILbO2W0^NcjH!umJ+1W@=4Tso|@^BBD_3gORqh-ty7$@@p>{ z9FV~blboPZ2HSUJFk!cW0~~hvxvDC!%6YK=n4o3p z(Py|)oi}<*-dXd931}wVRC4Y#=Cw+`=Jd5DmO%QC#WxOW6ou-+C8Ox|p_q+?vT3Dl znx;weujLYlv;ckLKXBD2!8)&M&DA-))v305Rb8zJeDJVe*TJou5G(bI@=+OT;b&w) zvuW3C`5qMmjVYZZ2AH5UPd-*~(9D|MHW?zM=q#Xdv}b@E2Doj-v`Hhbjf%gTh$}u1 zwOMu!kmW`aFFubE@jUWE`XFzK5xE`taUO;dJ%KFXa~5oQdLE!%E93O0QPs2!*Ixn- z$%LQ3)B}awDiw+}YZj|KZ%g7z9_+?RLTeN)FTAD=4P5128IVKa1g+I@9QSI@VUPO= z@=_pkBL>oJef94IZ9pKPSWEM)+Cd0?}5(&3|e%g!#(cC0VI^qz5$u*6}wG}l*LQ4sgER#gCfg?bz(^q-m zxj47ep!CT|q7oTXcY}P05oxLTUm7>>KBt^%9Kk=%-l$C!?r3_e)svfe@0Gk~waO15 zxlHQu^^IpYn^$a=iG+f``tTPCf;KTl?_?BJ_gp(DEXpUybNHy(F_{$}2)QJ~*M9DU zx=!?zZAh8O)d2o;eXdV}b<5!&4xC%ua}uhV@29tYf12q1QQ=THt@wF`}YTJ!W zb}0ciP1E4@=A!9T=1)4o7`MHGy@=|~m0_y%eh`9*rW*^-+Q z;kLuRWUH@`Hgda78%{G-MvsuHX=EyrAVc9t5)qK!@tMiBOP<>qLOT%2yd&tFUxg-0 zjMxxS&eLs9C_5QCz~Pi6|J#H`KiB7ac!G5oWGoyCQXQ62Yw47@AUWp9YWg667FE2* z@44Y^k_YHS34*sy)a3d5+kNi6hX(P+$NBDRbAut=^wJnrz zZm%OPu1566`j-F+8eVaj9Np9+3V5w3<*?3OFw$<+YC@1GwViN-XI#)&(>tQBH(SrC zP!V6)y%_iD(TBPvj%?p1gMAYaNq1+THS^d@^XOh#QuSc!OV^2sJ@n9uJbOCrh6MGh zxH`EsPgEq(Y|;BB@LDCg@*=d_f6^}%PyKWTKi4P0ngU&!IBzjQL5Tjj9dE01jxB@# zgG~PeFAHAeiM<)05y=Gg#QH!AgbK+Fct|!KneN$LT-RbbN1JTShQ*LlPBhM@ksAPq zY~3eLP?q1l(6Z}-n5K~2>%7+S^%aKz@*71vMXXoG=7GYP>pai^;eq)Gb=h9y*7l+g zDBSJcxZ(EQlZn=cXT$b=vTZfAqD+K{VBSLr_fSIc%mQ)4=~|!6zp9rpv%TfM;~65k zGK(z_`ra3D-MH5gylDqj2U`8WL?iJds)LB<7o z)7k_Q4p4|xsx6Eqt#ZH%isTekOr1NLYnv!%(1uae#f{v%rfbzCdRPOJcy!tZo`y>Y z`G9oeg14ho`zg765al!@-k}u*Vs*v?1xXgrnp>6G{8cak^g4(m-Fte;HJ4g(HJT62=v zw6h-VQt-Jx*RM{nEzJ?fef>6DhHPgX=hv1T~UsFRXZ zzkk!@YRs_OracYO#lCP6jX@@7yWe4df@x?b&q`X?eTc#ciF3PbgOA>}2&w-}4}Pxc z_94I=@732>x(oS>*sHxnf(5P%T2Da@e1nZTV?Z9;hjhEY0>vWwff4^a|E$U@4|ld_ z7jtrsIGsgbGp`4jkMgCRzQuhAoi0)AM-s1mtTz55m6R z%_<;lsd|Oxcan&>XE0A_FVhbCYd-dzbYTdAHZ)Amjg}xX1%pM(`(_#V3=|oLuj?#I z7U_ynh-W9f^s0jQNzBB(nxMNdr125d{9LzQbinvov%nT-gqj0K7@B$Z>Uw&nfrD~M zVNG)v#$QD7L=}_u*Yj2DAf!_OwbaM-pT<9AUaGnjjkn5z@Gh zRiQ)ii1djdRmR!z-UT$18b+zx5{$&xH#&kZKjW?*^~dY-uU|Djvn zw6M8=0LSJ-`?XbR03I%#5V5;tsPJV>K1#7H@zRz`S%@)orW}=EkgSo=C);gDY8{n1 zb-GLz;Hvg9_=3s>`k@_;XqL^6B=J^-^H3e(eNnKn6Wf*|%b#voeQJ-~=e3f6T7}p2 z+pW%bKx@q21w{lCBp|6(u7b*Lr;vld>V^o8IZdRhRNrYE`CikKk4jKlw(L9V{OuvU ziL~#*Q(SNQSlxe5p|T*ID#xQG-_&A~jsXrSt{+kx>hlqqj3SaO`CQ}AdVf;wby~c} z-9_iZ3LVfy`rS9NIMgd9Sg1_86TW*+f=_wm@Np`JS4T+2?(Z}4QLnZu+pQ?av1l{3 zrEp{-8aNp|@KX1Is&7oR>^bGyDvXzQ=l#ht@f1hnpvRe)wu4nG*N&OvFf296`wErN zCUMY>D)X&eKt|6y?fH97geArJ@5aW*K?F^$EK8qWQFU7Jk-zp}2>l(mm{YU{_Y4TQ zkh#ksbuo4oY-7(kP1m$ia9ARac$k;jd&e7}s7dj0-9cIV%iyxW!%xvW{2dZ4_^Gay z3P7&bo%e@KHLgWQB9kEud+pD)J)zxc`&)|V;qR?8@d{^WsuS$gKU6L-@&LB!Uw~(Q z*8~e2iQa9f+EO=qXbK_iG!KLJHbou|2%3eWZKU^biD{+&YZXI1k` z<6tU*CuTrf@cr6B|4F!RJxKk|rgdj0YEvY8*Bl!0zfvp}?Vx_G*u)pxA{@r3`A=En z*-8C|AK%Bv-jj2dOqR;93X+(j&D9#mhxouYdMdVC(oWnYUw2G&@Ukmy9hulE zbnBpB*R=U$)5q_JQn@gdT%#aRDVVrhu&3;-+Izx@&BNLG=yTJ=#<54+pEk7YuXQ7M zn*%&3g?^r7t0^d(x9Zopvbwnu1)x zvv>hEsS9HA|7Y(@)En1%WJRsEyZ?Fr*Sz29#ETYQRRN%ATi)d@v1WSCbUJZti3EW{ zp$hLCYk#?}?|Pv9go_0IJ~4(NwxI0i7a5_2tZfWSEFRSgOUyEB=j&6pCy%`hjoJHx zLhPp6y#&VY2U>}~E2$w@(=DR7&q1x+PT_M7qb4z zcM4I&Oip&Im6+LuA-0If^8=HZe$D*v?}G22)=$~%$bsA)!9vo)K6`QduR^GxeMlel zQf)^ynrY9;#o6Wq#0ip2D`k7Bxalq-LEEUN3;s(2CQz;XlW6^X#4TdHMsXxnf<2OX zpglC@O{KMP3D?Ux@lmY5C6Iye{^&{%zYb`eb7-N@#kQvZTy>M*&FuLnpjSj+`l744 zGJfHZLV+n7Z=E9K_dCojRso4k8&kiw$4&#~mxm>q?V4cLeUSpF+Dx=d!nhLZx{HCq4R+PU0~-XkNJV*(p% z1BED`^Q?S08i@B?zJM#j-4iSw@S-Ob5+QoTwITv}jfyXzzfLD_=miJ3U0aLThz(6* z6Y@!th!E|~HxB-PjX;M$9n2CU*obH%h{-~kitB4fsNzYyY0%un^gS>-c>{MN=0H zw!vBHqU7Wr7oIT^XKPDJp*tLQKn@GjADL{4W%^nSIvU~ z{AhyJ|NhOUJ}Vg&@!b0jVW6EvTOYh17CwC;{h|}T_Z)Y&eb~1db??TUrJUGn|816G*12vQM6>oIjCjyA?5% zqRRc>u^#XTUt1t~{lz1i`Lqkev3hD0=B36735;Tno8`4^qXaf(sACffkr-7o0 zw!Qj;o=Re{Cy>z2=Yvr2y{w*mGOoh^D#;ZP!zItER^)1uXD-0m%=70uwn^iKdsGOH}o{2{8Eio5~a32BL+9 zh1dV;mRs6QiK;W#IwAH`J=H$fGzADqqfHBRw|GcGW4xBJ5qRN-iN9o{Q-z;vC-z)% zFi5NrDS&x3yF2N&QG}A})#1SOM-z<14^~r1&S-g)XNpwR{5t-)$gXOvV92vld5WUe z&-fd;Ishp`(VG{C6L`dD+%J9>bPO7?;i5Tsn*J(&)M{1pS>V3S6rk`E#vkJtlP*)7 z2X@#QEPzQaE!O^dV^~Z)CLM=n@EpbALMHo+!w3*$Ru#W8hD?rETa`{z(>}O^L&Yq% zPrT5}g%R%DR~M7s{YZeY#0pkBG~VT+lpvF8%TTOZL?>z0iAILgB=7v+D}t8T=%%rO z#U{E&BA&_Qj)d6ks+Pj%`W*=tDnW`I0wuk3f<>L7J`kccHMZZp99Kf+M;te@IUTA+Wm#SrQ;A}V8v?jgE0v=_>zD_mKaL*7?hHUJ8qzje zc`X%&=9xgvwd&wKmIEBb`y_NKn!4lKP1U^Jw8wsQa-~AHxH2`BpHgYQ(?lHibRK9m zek+k0JGX4oU$~_5te5nomGj)GE~VEAS$hdvLn5i>j~ zL1p@|zB|;2Gp)?hh=5p-=+}ga#%CVjb{|{SY@((~*9K3(II^Yc{l`jCh1r5^hX3f? z-{Z1-E}ngfw#Oc)Uhm&ur zrPZm_45s4ncZxq=iS!`JW}({03dG|XwFLde>n+#fvg-- z={u*N)A%-c{@2E^LFdcq1Z95F=iEKjor?4#VO^;_51xfg!v36t8hUhV9l$aGLHu&3 z)GPCP2Kqua@GcvA%qP%E)+sWTuRfe z!?>=6B0&uzI1pSSA)@c!-d95I7xE1@fbKYw=-uQy$D(BU#y5_mR#6Ln75 zGM!3zfDR5i@rg&7kdXC7fado~{D-uVKB{h65su~Y;i3diX zpm$w4$$*3$_M0&Ma}I~Y>%l7eZ(UMV*{`WG<^BwVDx@*&>=8;D)Y(Das3}?#P0z9j z8IXIs)Tum@-e*;ajmO>-+BVCjAonDrFRGB_xh**nxApalTi5-wHD4+bI`YpfThVT)ZRR$O`-Y{m{fB=<`_y<`_ zkX3opu$2-+(U&YRRtU3MAQEDsfm2l~F;nzFW=X|yQ%SVeO5!V;oQcaA$r3tUjgGq` zC_ZB1#p%8IUJpWXfBNJV2~cw8q$Clqrioq??NOYHugcIYyam1F)Iib%6SV5EKX8%U$tAStAmsa@j!AZqu)WlV$OR;>FON zs>-87KHS^iq9X*0o@%GS+kU3<|07wyHTg+LPCjY@YMemwSU%B9lS3Jh-f7FAu#Z;S zJJtd;5Dy$>(T_4d6W3MhCdsc1T)vQq!H_dXQ|3J;d7_y@8NkqB$85qZYMB^QgX`#27zs{sJ2=(GT{V;V0k!Q z+b@nANOJfoqEwws9g+`&uT|pszFuv(Xn0dJc@VX0f$0CK3U=HoVDe$gw-4IncHfqY z`k6Guxx5L}@M2q2Z7eKMW21CkU#+_Vk&`JiNvLL3M~#+Ey^PGpHMggHNX_tQW49h z5hDE9dck|b-d-$b;?w6(my_4-J+JF=%Wp190zl6&<@WDdq!g+P+mKUV^fy$Y=`4Fs z6bsZB-2Fu#GxETn8(P(Dzhx7ESO758s!7hSQzqpRYP%6rd$0CLl@+^dW3AsNh@k*%Zo2!xRtx;Opd{tycVZSP+$ZK>d_NYZKfE z4r|eL>Su<4gYUOsbLnO64j%Z)(5#uY~gCRE!$*Ad%9&VsuV!!9hya?RM zV^dT>x7+qx+U4p`YK0&Q4X5kH){ThCN*hZ^Jq)c zn~*C-9%2N=lI}lxVB-4kYpH15b5{nrXqjksyWyiGAZbzGcO%TU+CPBt0B4Cx3}0$q8bgDMWoU#BzPEiHY#<|hAMgZykZ9HOCPKf>blkqBkjYI zT%#h8;we6tN`m^#Ho}xe0X{FPuR}>AlMx*(NEA+IQE;W1GunE1N=xG`0x3BA{U&S= z;_$h~Se;cWI5_Z2?4N1n%H*ex6Jp&1LBLv_>rl-(JiC(9Y#UB7$C3!V=lX9%RdnD5 zab;JA!zF`t7Y-=43~_)dIUY7+skY&7iFcR978!D=Yb`P(w+&0K$kT*Zpzn?_79WK^ z%J3BVa(DDCocw*`9O|F>vX2wHiM6exoQmn~9g0+cki2er97Ik*i|I&IMfS?5H1viHrPf zWmubDKpRqU&+XKH@SBw=I{MM^#G+EG^Lhl@l@ZP8mrif5+lLu0XnChsx zY9c*%Ax_ITEE7q{tW}$-$?LazMx}11D2*Qun`rzy%VY?^{24_|al?%R4HDR)-YFS)ixZVd+bT|MEh*nkt`I*=eAz5?aNu^DV56NA zdPRG_n91EV(?lRS4cckDnnhS!^sYm}@dA4~aO55!*gMtLsWzPrRrygASti`2Gve-k zr&%Pz1x4+1>}xnHSn#E8v;&3sh(DaVPcy~~E9`wDEoGcJICrt%Ds=_;ZJIw1Pq4&z zcEgQYospPG@3-IrXmkNkn&Iq+HF#kylrZW?0!(RIKpFr^K(@a`#;PK`53~yZeJ%BU zq#Uh%L`zJ(595Sxe6!GGmfAgHzKKH;RSA3I;EyQJ%nojR{p)*4GVK^|C;mIRSc{Cw zo=sZ*_wSqb38>a_f7?>j!||H6c|qoHHkB3$=;5-Vh;+n{jT%x=!sZyhuFV@iD*{s> z!DgqeLImAxr0V3}kaBa7)i@V(@O=N&erl#Sq>cp(pRpcTY_$#J0rt?;BCp4c!HrN4 zK}oR`Gbysz1?D~w4xvmA(o^pRZJi%HM5l9%|&aKD@Q?ln?vy#eH1Irdb ztHOH{5QeJJ>5W5h;B;Jmm`h_>yC_nzN6;JvdjEZY^Vu*_ zKB{GwFmaF;L$-w!Be}*;BKbWPI3&Q!y2qX>CcVqTO=`Ipr6n~sl^aU}+yzC@Vyn1V zcT7~&-IchWnQjY5B@fA!NMp3YEM7+0J5iAD(m}!|NkThJ{NJWOcsXn|SIe7PCuO| z7c5dB28o(Vas+fU=>C{^nyDPG1Mlj%2q^xgP%WU1Dq4@;uq=JJCzekJF500(>1(+R z6%fW?y;hyLZ;l#PKqk7q0~H$%QUM?~;&cD^)rgkUk!KV;tyB9ap9fD!wzg;kQzd`< zV7*eyBnaK1C7fk1I944CsJa1}B9hYyr{Gu{!dkB9fvP^h>1r4-{+gNig?%aS4-os< zH=C3M_Ex1jK}@W0aH~~GXTjqPZd{fQWYoz#&^no(vxy`tv}UT(ZEH9P0aH??yi4`2 zh5F?|)F(k3&$-J+=<&Nm)VK{=ScYhEGEoJVjh}*~MwGTUK^g+<5zj<4hwhhDq*`c} zMKKzaAF+4M<_R5xF@7$^Rh#y0WMVjtxms(iJZ|3XlffSpXI)YFo1eBNp+w~ir}tMR zeiBWNa3;@GYx0y)IQD_aEu`V|jGhykP^F|DoR+(JW&+%@u+btabCaR8`6E9>-NH~@Mj7s^OwP6P2L?BKW>Eiwgd3r6{WMh^(&V?2@ z#ZLQ#4DH*LHdPgW2K$1#L24d*GALxJ`d4-nAOw;u)NoADA_kv*6X~jP>>h%)G%a>i ziT+yplQuus9NgrVUD#%mJtkUN7+|=RG_2mdZ0uUzxh{yss`hI=&6^W+_9J;vj#&h)3mXF}Zk_r2ztEA#xO&uHgi zW4u!EtxPa9k>QP5S)RX^VMy)7D>2y0`EERplGo`-D;c^>ua^Luz%cjqgo`SF+=oEb z5oNsxK7dWi;X#`IQXEi#6wsWs8PsEmHjxI`Vxsdp0H*?=8{NVSrpLApZ4<7B;UrutVCS>PkU;o~R6c&V^~pWJ3PffHrk!wGwT;H|ibs z=YWVQ3|l)j#?)j&{XW*vEA8GeZN#-`CTukNj?XPB0g-VgETgXl%GI@Ug2tWFbK~wJ5$2O zgt5_eSnFi_Ek#A9paTVLm#Z+P$l~V6z|?rMDAWJ4RtMDn;GS^8>r7M-`xzdRY;{wl zHXB`Q#-Vj#lTDXlJtV<0>j%@wIP}&j&ZmmWX?pnZW#X0XPpGlt$6|B?U%|#p&sji* zhEZu7{qGk#{1M#O#*HZQDDjlfi9;4e1QM-nL04JO5G@pw&zdCGvXBHac5Ju*QW<_x zQ4EpXfyhhJ)RWy2SXee+&cqioColra?Q&?GVX10b2;!v@Ev8G_76Gk$5e3EaD%!KP`97Q7NYCoubdtl$}l) z{nIHUAU5JzCW3}FNxmqSib>VF&v76z|2wR8Q}Uk|RnYsnB%z}e3h%q9pj%w(6k(1B zK#1`5_X#63WuD)3u)b8nr0d=UD^CjX;@)RD4|62Bnd&zoDc#lod*zGL2e3$DvUJ%n z6lFpB_4ZY-W$@|-6wCYu(Q>T8HPyI+`&gc-wMOf@O{2huX8}jLhZTALc)~2__H%R+ zTSchye4mGEKE5t|j%nXpdjHKepe)jE8Lz_eA`lqO!NZkGCjB!NOsQ@0s{KZo+|qO#y@e2OADBwCt8T)fBHgrzA`> zjsD-CIe*87t-n?B^|g|=q~A{Bb`dRUe^h*phEf@8m3Amaq_lr6|I2hygxloL=J6rT zFEeYa7@h7Zys>&?&_z(c}REL-BVXA$9C(L3_V6oN-yWeqYl9^b9f zu_p2RohFJ+z6qWOoj8oXeFgBye zFC|2@&@x4QL%MEFXn}l~x2DM)V14KL@#=lsv&~=iyFqyg_S`!cAEK2cdVJvLAWrnFUNo21bsy)mqs4Qks`s@fs5lQyasC}{ORF|RbojV( zD9SVs|NFNL0@>HD39~apF$Uc#q1Bw9_ldx+@RM?N^@!h#6)f9@x;!`Rzk-O@bJnzh z5!hq)ESv%rwYKR2Ui{aem&Rv(iv-JhzSvZy@)zO^SEg%f1{ov|b0!RFxFOFv1i27E zOnfm}e-onYy!hWiJ9SY>k|hHHLLRpJXH_>jE&Vqm5faIZlv8S`2CH1SU8pQ6`kHh> zZ&^25152+Hs-isg3ijLn&M5ywV;LMWyW`pL#9G<1<^jmi)!&6h8lo`i3GrZjuwV z8d4wgo_(1Fi=&`Xh8Uw8+NB8@K^2iX<1jv$YmZs_Y zXDF3?=S>gjbaHMjIr>Mc&zy;gdOgsv4{Am}ATn#+p3qp@~$NVt!D8cyFr8YCCl9g{e^dM|*x ztE77yh?yN3HX;Irb78XyYj?K8+vOljJ&@)zl`+}WB4Fy(0Qy2nmHrE=IcKYb-6 zOALKw6CwdZYZdxewt4Lvec~0p$Ym-8dRN$Bn})3*BR$Uy%2wNqSbo9A=-G-&T?7E= zro#O~g`yC)ArNgVi`&M7=@731sF`X@RqEk}wgI5)XH1zqW=#o_m_~xQmp=1MlTftW zi(;`eXmI-AVVk)`LM$y}F%$NC6*JJpFIp|NSA_^0iojbc)lmFklBALqHt7Qd>wCEl z+>KgIaj$I^8d)9H>K~x6S*k6|`>ivxtLnVpo7QE}H-dXMf=Ku$SC>;ISZ%Ak&wTXb zT@s8fe!Pbx1jJ+4vd{CBdtr}vtclAe8XVdy#u`b4Qgv47bYB(uWrG&G7wwo-BXO-L z+Zeyl1~iCf`@!v`EVm~PJ^9tc^KlBS;JtEirYx^c3a5&>wkPraOooWgBT-zE0y85> zu~FxaDXzPGa`3J&5r_l(nAX-nxVd9FKi}CVYogaA$R6`#TILx z9wshwa;uv4hhAjRtehUxu}XIC_od>3Lr|3i-|ObI|0c;GmTFa%wKcIBkU0KC;yYk@ z92BVv)n4-vtwjq71F>`}R4>V$?ek^i?PL2YQ+u9ko&rbd)vclAki_h=KYh+8X`epT)scbh22Zt#u(6XGibz{xcSeM0bV;nTzu3SKBc_T+-mF zc*9u&KCYrT=b|86ostLUs!sR0k-F&z+lp&|b#Q1Ex88&V6bVc^-xjZK)g}ulD^O-EHQw8Fm6Y`MZ{bk{Wn{J9u$yg@y8gn~I_JQ+bkA&R zK`%4)G;?SCl9(F-tvm#JBxmsXEXf;dh`3&R-{ifN6gxybYPxPKrkP21Ghutql<82h}Ev$)V|M7vlxmp*x=I?zQ0>Mb#Nt-6NQ85Sl^<#~{VtQAEy)AmQ) z8w#Xq!XoPE1?6#Y$p7nOED{#9_@U8=*!zEf7fh%vkxBKrBKct=q`XuVRkX`W#aFhw zk)xajt-PE!4T%RhxZ<|Z@_yqzb#%mP@R74b<`%2sA{6&6e zGtgMJ5xuG5K@6HH&-8{gKEwo*>UZDNX#e5<$p&7DPRtP@ON)630BBQSgj$q%J$W~R z-t|F>WM|hOa^)nW(T5DGxu|QY`cVPqFEY6~WhG??W|7}!4xXvsq3p-@B|mFIX^Dad zfmiAgw2IMrtDflk`mt@1@~K?p2SvUd8h z_X{neU5KU7i9-}Nrm`K-No|*H)QnsF3Z()^QaYOzY_q=xg4LNL5LwwLny5KmS@Sgxvl`=9AiYDM7@FJ}X{DeXW1Qc)4no*K^2g=)besj^9M zT)1a0qGRAQEXY|ES(WNyFU|cV3muPaqcRYkNVv!ZuM=cEtjS!taBZNS7zG4Hc)Z4O zp3KzG@R?W%-YeFg74NNYh3mc34yAx_GPt~8|A3>33E0`AI9OEA-84Y})XiPEfrl1QrB# zMc}M@0-VhR?oLxpHno}Q2yyoV+k-%LTAif5m1AaH2(yd2*U}Wr2zTiZNtIhCO33Y^ z_P-BFg8jYGHUxt8OxGCJ0Y>w`zmuSHj{9buj{Jr}1j>cLWdQ!9O%u5u$bd+nwFDp1 z+pAZ9b@h(J_3K;oqt$_7f=5y^xTIHXm>aNk(Z$u-r zm~*x>q3V)hZSZq~E3*>mp4k}|Gq_J|tGP7X15bAYypH&x8YgJ?_nnLAo zl`rz6Ei|79+#8`BLPCr8Zk)=e6{bm|6QMpl zdmst_sW)kd^yCU_0mu~GNRUu5u?DIZbw*4JZ;WS+u-A?F_D+vr zc^}A{vr0D0#=QPO*gbOS3Tr4SKoT2D87b1j(XAa5>sn4zcs z1@FO94zNR4K||mT{R0R1+N&zK8``yZd=#l3pttfiUhP?k4NRxj64OWnI89_|ZXN~- zUTFRGhs9>iuks-o726S{@qMjY>R@=I>U=n8or>e8cdoc_PwPhZ0uZAq zNUmehcovYF?&vdSJE<#p*pUpaZJjYMS9}fku2oa*sdtczlIY_}wj=M!3ITb(C7}$=fr2;_e<}(qHDaLsN&&t(?v*ME8%A@P+Intj|oD`j$lEGiDL8Zi)s&hv!ZSR&3&EWKhW6uU4&+ z#|}@(m~#Et*mnB6t9a5^W(?vr$vfYp32W+2Te9w(9qhlbcRU&M7LE_%(%`U5Cj^ zHnPHe+U<*BY|AdP=pu{gL?k57p8t-kl`2UyPiKA>3So7LjbF=cGFfq?iPjCtEy zi}#hz!cKivO=>1lTOX035R}&@l#yJSc28KfJi=qw3=wLx%?1iA98oDtN4T0syOQ>}mI$wP}Q3g}XRRdm4c2gG6# zNxeK>JM_GfxZ<-Kx%l{@ETWA_I)LniX=&5e z=zxfP-G%t<0VYL2P%Hypfk=80npH{v836=|78c@6y$3BIU~-F^D|sUjKPR~Iha|eD zA};TxOWyr5wP36jnW!x$U&*PeCf5@Se+T)LE77ani<&-5F_9Kdr%WUZeA}glvcI*ITQR)5Yj0|1^$uS%cHuY&P zjatBMwPTn7dmBKiL%b?aaK~r}uSlJ{U{M&dfpxv6^FkU9BP7UOL~Nf~QhMS(PqiiD z;i8 zTH2He3X6etnu|2NglKXZ}-Q|PrYq36PD4?l4?8laJPGxmu16-3IVnSR37^e zhHB%94-80M0#D*BSMNAco=4zE>ugrOPl9FBpMXZ~*})SKpN$@d(FSGj+CLsWv>@5} z2M=y~YY`?}hu40u(4UoT*tj?jPDyTyJ0;_OPy*L+SC>q)XIcuPx=AWyAOcLN`ooP? zH__BO@%=us$>C0?y^Ld(=`n!%UfbrQc7K2~q+lL`qE!n~5-aaH8o} zH|-W-m?F5D7{BL_L>(2)b&><9+<+fNTg5)9)!~D} z?XOR;*#1-fJrqLQmV7QqHn3}^8do^?P}oqHEK1Dr8lWv?O5(p2vCB_o<~A*0T#8Jg z>b0+lh`^xrDuf8an9D(g)Clc7DztTg0P-xMG6bx0$3Kl)J#QdDdbBzRH)1ZWB^-Vb zz$^6ND2x1QA1!r5D|%8g)S2j+-$7BErj6d41mFA&(({Ij;dS6jRCm(eF|8jSEGFtY zQSr=aC>1ol<>fjReI#*RTN$PzPmP++4|;h!!kYLzw9rb@;ZGg9^!DC|{Lcy($OK(=;GM{^2pi4#QS?VtJk(DC+&uXYHZ``?9mFn+)-|2*GA2 z2@v-4rbb^R#R>q;HfK_38tctQy(}e<0Z?T2eAvTM$jLp09EDJnvPt4je$Io$24Akk z%r|4ZDdhwZvc{%p4+fB988|jOq1Yl5@^zM~_mX7g(huJ-$$D1b_a{#W@F%{ z*lu69w&-t|;xtYjTBGYP5%6TV4TB|pwZ7TNq)}NMQ)JaiB7JQ3`XV4_7|9T?FkLV<%~jp@eORswKpe;RUy#1P+!HW}9O zcOr;9g%(wUCoXbm%Tmj~oANggBb8ARM+Ucr?mjbCND?ZxE!RwccD@Tp)Un~MLtw!v zQQ3PW|I``l{3Gkp*98wubId4Bh{embu7`|VO3~&kRDwlE_+m>X?}H#T+J_sp)>$0$ zQoS|7@@iPRavN1s7X6hfOr8P7O0v8k#lvEx93l5$nH zdzC+uh~;X9sOx8wh%cge5;}qS zs99nmdPq@A@P%9MUK!YC5pqoOB#t3cJ=a_tc|JagOI;(No=f3{h(@3btvllc8OI46 z%J~^OSLS=SsW)s3X39abK8KP8E3iUg}DLOZuAFGr0D z7BmgHsqYfsxqqDS;M_+va)_CcJdDs{ir^e0Y!I(!j#o8=G{pZ#JzgQ_v8rnhz1)&G z=jT002`Z)@U6c}l=PJQ~J|ZwBq*tYgQ@&5KBSmh8Zy)e%u3U_oi`- zkeevE_@`Z_O;&ZKXvXx5?R(h-F*)N_*fTnZ?0X5)VU@9)z##UT-_NNcOrVU6=3CMQ zR0T)?0y*|54yi=__rT4w%ps~N!>`oVB(Zx z{47-I)FW)$ki-RKR9oWt0pZNoL!sqNLXpTM>jcR@PK2SOg>wx1`8+u8NW!X={~C~1Wq<`rf7(? z^o?4nke*E&rjef#NrUABm1qk0+>POapnCJAyz!EDiuDKRL>2A zH8?Xy{>@e6#>l?TZMO<8M+k&?Xua=e@b0K)-)v86?cSd}6BTe7bm$Y2Iuld@QXYxw zzRjzfk}K1K6Gd^+E~~2I;2~#K?9IlyNuuVco@&@rN=jG&j5Xzc!-Z#K#QtM8Nv1B3 zbwzYfRqc)E70C3k6Us96Q(T1>u?;$4zqU$XXX`aDWXR%x3cm38P%su-{&?}B6(`28 ze!vP>P7quo<&V+CEb8_<+>>nIJ$Dxmt;#s~8XGiShmq-9Oq; z-Dok?Q6#b^i8{|d?S^UAm6$ctw3q`y)zNiTsn6WZmFxzL={aFNV0~IL+^J|M$?NDK zXiVl5W3-PBt)FA9zITdoMr9$d6jP6V;)JQkLkDc5Jl}@X@x|Trq#hBcg~IWB_nB9} zW8^5<3q@A&JQ}+vHsy`jjqjQ3ofu2wmEkVJzdaJ5!9BaO|nqG_8uVs&tK7^4zpV!D?-`BTrb5PZ%Zbu*HupSEtp8$k#F!v?b%QX0{4d^1C6+D@6!;vUF%S3g|`Q1|2 z!JqBEi#@J%t=*F)*;X4>Y>v8U!m8u_lR+w<>_r1FBi^M><`qxWbFpc*C2cc=C>yu8 zydpe8I2SEAl8x06eTpcD1ZTBblawjH|GYql_YOqSgdQ(lTb!Om8>j{OOlWL^h1$DCEtqhx|g?N{Pnde3pf2;9Kum zrj81ap5_a@)hAF^1c*pphL22&Mjw-lI#V!Yc)p_GF4OWzgo#+HrdymO*K8NB)#|I7 zB&J`bC^?(S1j<^WSW8OCx!Ti+**;axiz?B;Ug>D;D_pgXU$gQ-#+wM*hRwN{l?Nw* z?v1Y0t#H@cuG{0<0QE5R1;kWKZT*85^)AAbVqv?%FuK!8&_hAY5Uyt*3|=j5U<7M? zGeaAirdF4E9r;}pOh(M)m4dt{*6=w*VG(akf@ajY_asvd9|Vv7FBc|to(Dfx&8&JK zg6}(Brl$qo6yz$PT{X5|On`KwHXdlbC!b{ZVl)ZsxK(p!a65S}fyz=y$7N~`ZK}3U zQ(A4E7qhzL(FSAqU5JB7M0_Gzb?%1ohwj@W|F$tt2-p*MnmF$&BeF~E_oBq8g8z!}-3WjD+L?X5m zKzYxH5|CFi48>cVFDj1Ahw*h=lTJvmrV-|q7!~9Zju=3*NTeKw3RdRT?DqR4r8U)9wlPtWP=++2Y;ybBkMLk)xaSS2cJ-l&1ijI{eiEABG zHW>635}0>6xLLvUNmku-VQifUVV}4-@3s>{O^8F@d*DNY*VU;6#IgHhG7pz=puBP$ z-Nj%Bk~JsiFp6=?_cYGpr&W7nv3jKNoBDTA@RzFn z{vn^u2Fbw1dt?C$83e?s|NRl3>c6jL5UYKa^=b|WOBFN6`!!1`gmfgrtVx|r36{CY zlGtaM@>Aqf1&<^qL%Z#l-o5c=?-6US7?+3A02^sL=9`QVa72Hn<^2nyt)J`M z6|yt7u1eKo6`dan13!XXnU`my+A4<<^KM6p_>zjagP@(D$@&^SLNrC zKPbs6m3{yefHqaN6j6BYG;XeI#+_7k**@2MBy*(9^znQC5Zf9ls;`L`w^<_p6ZBIukC6m z15mTNhAAvL3(-Qlr$&yPq4e6D+}E0Og0yO=3@-*S&y@?GkH!za0VuM5D!I?*=$os$hL4NUSIUExvd z7SpYnPEOl;#aaeED0#smjRRB;!&74b%fP|9C-U~R=Bcx)-|S~%6?Ze%U5Qo5hGYDK zdKt<4>U+Z1kSVwL;KS?UKpeYLohmG6MbK%Q;%e#9w&ue|wheOqDcz{C`{C$1CThA)|UV8l(^?ZKD*QMgNhc~XZr`r^%qEx5L6WP*W(8lry-prS>!U4hjXJxTOueO zEQV5rGA|*e8$mg?ml@MwqEK2kPnK%$f*_6!@(6FiPtZL-OE&l&Khr9C^-{S7F;$kf zJ5}j}Ook5wC|)aV;anA;HShulvm{mdQ-c5Jny^5EsBDq(tO8&6o^BtA+sL4x?C92CE8BF06-p$S{o!>AT1M}*eA6w7G;tw&3h}^Z>7VmpT_HLpCeRWJ$5$d~yQ1 z`Q&1vxj0jZc#5R1R-3qT%)SXS^^G1SrLy zKj!p(d8I_NWj#o%q+m;FrHEGBCvRQ1Pin{Sh7J#wK8emSnEgzT-RC(ciE{js(*mT4 zwguZpRj6~Kn^26u==tb0;g}!dvrK!@21h%iR^Q5C?)#xacWXdK*;?Z z`;|sLSguydzy5jQeU{{FeG;tEsyazNFyGXb0FopwnlMSnA9ynU{WD`>Xm%&j7JSL~K2w2gv7)-} zO|t8uQa;>I6So}C0R`9|%(JuOj|hBL`d)p%*OuISn-fCIzaqgxV1#r4ZV3Ln+SH$& zKGB7P)`Z#aIcR~lU#aa!aR_gMr(S$vxBwMVO?{;1^MI}lq?wGl4uZ960F8ti2LkoY z(9&?CcpR*CuqNu3Vz44GDR8=p!+w!V*D>)b^6aguKO~H$P6!_h#5gqS$j#wi7pi|G zS%3TL8h@|{p%3?IO}_4hDQTQXSVw>9+nBxGXMp7vuJ7;FRr+>_7x-CAS{@(YWH=?y zvWpWVoGr57W{h=`Q>+A)_k-{7PrpKo5Qi*UMld=SqMj%|TOj;gwhI91k;M%(4Lx>@*di(WOxRvgp|IVQa=)0XJXG{kC*EXDv))<*##Ipi z%N1LRNJP+1@X015X{g%gvl+Qd`;&;T{h-b-jAO=>$NVkFB`1O-g9c4gGHcY^u-d8(|KQPn zY44X50C?(xwxVLkNV4#CxQ>V&Txvn%$I+7Vp_;B4vwraskB;(&Z{-mM$OYd$~D!+k&^3&8$usIpC~l@i9)wjF`b(5<`<~7`zvt@R_tx7NpdPJ!@g3W!Z0fK z9l|9x`)1QGc<_My&mJmu+y7@Y5S)6JV^0dz*dI4%q5$-%D5O2+qhumgm|sZmo{5#n zGGwA(m6jBL1rmmU>iX2`(0jE9=%e=~0XThnl7(LnsR^_?y+2OQM^L42Ce7BnyJ%xM zoy0Wrb9>H)jC`*1@1t>O?p1_YiyW^%8xgfUxDQ_(`M~G+JD;&b1U^-rH)800XuV?) zXRxLMbbp9!;@D*>~#xnP`l-B;N-d@rr+%`?i3V{u_q zVv~yNdAb$Qh?ey4%Mgd3L_%~Ltc+mYsakqsgzG3Qw{3Supp2%M;3nYY^_~73p!~!g zPS{wf&9kld=c5W8NS2|9oxSHBeiDC|K0~o`dadUrJVTK4g?4aMX2MG{CLW0x?Y&1_FJneP*YnCstrS@s)L`Cfds`lo9N6kwWKtm;zrdvswc(JbQ3$MqE-eI7%Z ze-<;6p7B1bzM>{);d9-dVEKUneRj2&hY-${!R%2N}F5I z-Qqw|NqaCobVIiV`%V#$O7+%W@#)%o0`I8gkVPH1v14(^M?XZqB8o4FN^3mBISsA6 zwZ?A~pEjQD6zUaD?bN(K?*&B%YfTO+_FAWFr|j1YrYd(or{DQmJUdIq%(&inq7m3C z;eNep0xBp8R$tH|-sI^^8l`Wgmh=@;b>-ixTXCP9KDme}i2IJV-q&|cUJm#?hn|JV z1SAYRP>Dz7fSbz`z27peG!`e5Rcx{N@lsDWvpCoVDohQnHwsc=0;9xGY z!#Y>c{lYzhoJb44XK^3Cr+@X#^aU?*o{)V69ud%PtZ}rtHX3K9E{Loc+Hj!Mg^OS8# zT3oZIjOO6a%&a} ze;ukze(HgKu3Ia!>+U5sVA(GgBv@E%mD&&NPLm<{VFBY$OKy)$-dKPH9F0Q`x+K_e zsCuvg;`d~U2m%;>?`AbPr-L_uH$d}J-@U~dwN_491lj3JPIuX$;TI4kkCW7g3!ZPTJ-l)clpMM#uDR&`FR3wSt;3 z|L=4VNZLQ!Ngh@GkmD=AfYXY90)k zaSueAXB|*2B3t=2EmS9#JpMcx6} ze2u}pk5$eKU!wTlDM7bk%T_j|AvGNn39)5K>9B4+ev<>R2{RI_t0Gx0H<6@(7xKFr z@uD(7f`*?jGMQxSzLwMxs#SIS9ndU%PM=7?u}!+^t2+c9n^rM+*($tq5Jqb?%Doq5 zc2;fLvWQ!V2r?9v{bk8jT>TR9XuB;D)#3+po=n}Bt?}@sSGoL z(`7LUI(xMa&7_K&p_nmUt5fI}N#$${`?C;1b_BA0zrrcjvbO>^w1(A*L0_8#Lz&QE zx)(wLJ_*(XHWU^{(_N<=jfw!t6SZO1&DKIUk{?vRQ6-oj6UWdoJyi(`9*wm znN$s#<}3OBAVXq2!^NzccH+|wr|?*E9TI`zn@9FwdY38GsjpU%?UD(>w0tqIoC0gJ zN(?Gl%4sutOrHY zTb{f1m4P%3*|}3e$~06gvavG$5$=SLys-{VywAp6E#Y%f8x5S9L_P6BfQ9!}Qu22| z-GAAC&zdlNt{!=>jH2|(VwKu)rkk+aYuk>I-VY@LyS|PxI_%D>2!GQxOsJ;hNaT5S z^dL6_U!to=i19z=YH6KS2ZS%NL`xHP6jdl$Do|ZRi(=8a#paN+Q)K8CD>4k z@KXmZs#go`R*0>4)`9IAqi4Jl0{$x#tVcuf($;IQ*7^yPfJHHSlr2|{wh%Sxf$T!v zh2Vs*Wjn6(oga7)w(0O+__f(6Hj+BF303$Gx2j}SB-}2kgwmi{GUe5I@ks>nIZ@U5 zYsia!hbeB>Hq)q~Z;Ro5607}nk2Oi1s}rq1D-JM$1oCh3!xYx-lhwokicZw^;$oNevZbX8xg7e zul`~<$JeUjFsVD0sJ8XmoPtxbpb@r>%Y}*u0e(ULUQ@vdkw72H*V#>b#6K zOWAb_$=kz@VmGpKQwEC+gRjxSTOreJoGw-UpTxby=7QB*No|B1zEll#U~aI}*M! z@=i0fqSYZGe_`KFjXnu-~#^pT8TVE z|IFJ)z=FB9uRjS^$mr{n#6*8)@?^RwrxUT^=3`UOXVqOlqZyT=Emz**mLo~Tlp)7f zy$fXZOBNZ4#?)HLnSe6E>Yoj!2nBw3suXSkuTQ9oj-r?NUbGHD!k;2pWo6p`4zwn6 zgM!%(z-agE$HWoY{_pn_ zz8A5N3jb^2Qg*E!BtJgm)74SV=9SQk-S{f) z%v2pcUh_Ga3`Bg8PH{h{OeoRH#M#gkEejTia?97#fNs9Z_0$9l8wuJS=e3vIc<$r| z9V3HXZR+8WI=89brqL$8@8%Mr!=~wU)O7m5h`@{BWEv#bEHXm#n#{_?odknMTZn<= zt_s3l`51{WlK;M!{Jtp`xaqE-)yemx%Dyr*{JGu>y^&G!m9EcYzNRF`_iGDWKNJf% zOy517hGYn;ZC2j%xu5}Os%~3*J9T0&f>;HzIR!aao`=j&5e7!QM!Z4c2DBPJb(jV& ziT0#}Qn?P4bd)*}?I$EzqKf{yp1G|GW&-7Zb@OU}2ZSGI@l>>Rq0ho;9bznIP`!J^f{sTpehiXp9e?VY9N?) z^CH2b2;U6}qnNF>$yXoTPzf#;716gwc_VmU5E-mmBfmpwS9P?!_=wTw;l`x3$c48< zH~B2nNx-B}9^Xsw^mEBxD>cEQ&ef6WN}mj>)YhJU=fsk0xK9?ao`J5U>dt3KJWF`7mgTh10BS&$zX?8uNUnr4{Cej@{+z(muu3VFl)Zb%$C;5;B%SJ{5KU>@ zP!ZVAi1WAn%^wjp#JAvgB0+d088TBc_(ts!rrf+pt|-?~mRE`Y#Zx)h2sj8}n`FK0 zOh>bE@Zq3bf$-knf7%~#(kWwd$DrRQV1NJ2ZW7m&YJV2^IA}2u{?9(Xm{VWoF}J%9 zr#@h?*EgnfbtEB3b!raD`n?RGA90`p0fy!r)-2Yp*}w_LUlL?S3-JfD&$hw~prj3Y&+csMWd zH>F6>ODkM_cqB6lkPMnY^nudf*lCSpYgJYtAiMr6+ zf85icWI&%`Be4`i(`=&q*#rxTG&}4*-)Z}AH>tGyh9F?mON#?UL2^g>ufw(in+5-B ziO(XdSV{c9f8SjA=#$^F+UbosulCT8&o$jutMW0E;qrbylunhE*R|+e9ji1=#Bx*1 z&<40h?>3!@J%qNPb7BB~NIz}2h&=Q?d%l@{?1R@Rk}M>m;70x=-8HYpazQlnaN<9h zrN8$20A~zI;%{>)pkh5GeKHp8D8A8^fbEi-Akj410nV#eojQJKf`u#|H#t5$L8vw{ zNbz^`TcTm6K+6Qe{NteGq)1j1DVbAJp!HnP#>p}p7?Ut~770?Oq_Td&2`T(fHlIL4 z%7t<7@(8J&Nu4^-W3l62no02zt-t>L*iUkd_eg~y&u&K2u8hSB;T_+-R<&oBPHCd? zx$aTuU@yvKrjFhx$=!5syiU@Bf5b8M6HtDdi7pR`@m=wDEikdC>R8O>J3fp=Wj0M9 zY9nUZq;80lt&Gi!W}O=y9?5gr$A~5Pefj+79p3)Ne}9R+rl0|y`z)_so_{rIVu^{w zKF-V)!Nq_7^#%Ah&cFT)xn*6fb=_C$_xh^$G=JpHrj`zN_iz# zEphv*rR7O2B+taYxBtFU>;dp^2?^!W$H(_MC5VD7c`mv1ZYUPtOObqiuUUD5n0d?F zF{Sb%&knX-s28L50cqQQfTg7>Dscbqs>g<Atqam6e{3@qA)>=UJ67PteNs!_S)q^D|Q* zR@StgL-{r66^0wUV@C^n2(N{+W>%IjeGeX%U_m7um6>QNb)grVDMDra>9|s3uo+nWJvUyQb^-WB(LOS;Woj7gp-5S z>>&4wZ3?XxC_vgu`vM4*aYLMBP5s}~`1mUN@ckfmM`?aLGq> z^OY}f=sHfEE=Ux1cSNt^HG{R!Y1dkWM2~ICJTibT-Xw9b_e*icDrX^SCn_XHzSnEU zq`&i_1uxcCYqtBu$TlO99W8d_G}@2}_VJdT4#v_;p&f`(_RrA{`$;Gqp5N}-_B#?R zE#Tk-yJ>jVSM%Z`4zls8TN-({VUP-Y;T?ux9`+7J3#th^FlO1}c4XCCMPt)kY!o*1ci>M4hPCf$JU*B#!eG2A~Om6`U!!hXg2i))zMkcK^r(3&hpB7G4Fat~5;i0jZKvOCxOauus+b zyALwvJ488x%|<=-EC5Ns0{>^VTCo*@_E%{{_7~0U5lA72fIlLrd3jr{QRL{~zTb`N@gU*JcMgEgoALYpp@L$Nrn~B?=c5fK z36vmV(0g+EV47{R7AQJxvig|L*ylQYf$D&cNqNNm;@XNDi9(V7P7Oa7t9R;TEu+%moDz|SPS;p5a;d=GkpDWQHEjA!VltH+#6(Yio+2mF0C9g-@kFpQ}MD)eW zQU?;;hlll~t5XRR`b>(mb+Ev|VGO=c{JoN-Kc*Tn-X!*NSstGz%+oArVx5y<*?>&; zjKfUtpAF{hu74BC?EGQ0Zg;=TgH$DFL*uwT0e|o-;&eojN*TD9wzgVM6T&^zWTkd4B%|?6!~-+%Ul5rV8%Vm#Zjp z?Ndvu%DnM_SP|7?5Gq*hSw9;=`dck1%pT@lrZlX@2J{Na36d-mT|Gyi%g_h&QoKh- z->NLe@!uha&*s3+mWLO#B#)Bh&voAm2LlPulq%`$bhcw!f)>R1%3_D-2=PNlKBMum zI)6XO2J_(~x99{h+o?Yt?3y^tQ5+w|20@(kgH$H@upW&d@9+4T&Hypg0!XM2W1KSY z#}EHjr=sPc*+;o8jwI^=9r#@5pG`RMkzCn?`IoLsj{Q%NyxH{jZ)^|77dXFWmsJ$i z_)u2l%3_NBiB34b>%F^sg2f3JMX74=6F9Ohl_?f+rd);i1|y*Y$~73H%A^~(35iy7 zlBCsat<9@hAhN&Hb6{}Hq$P*ZRg+Ty3Utao$aJmlC0r+l%PX1sAlIrKHT|^SdX~v> z!GHgjav`-Ora z-8uKwi+$3&U-><6>bHt&nhp*KoLfIM(Aw2ys9n~03g>e6~rML3P33ukb<9ReVd65&!pHd=8&!H}%6J+BrQQ*)Y#Vu9?g8cxu>JGO~w0Nuw2 zPGd!ax@km&&s-J=v1$K#hy9U0M1RN!61x-?NOIFHHFots?PSs!Em9!7`AFN(gp`qt znN5{Dnb3Xq+T{tBS7{8Vh=~jhw4BJi?X{()opUce;_P_k%V;LuFT4kLNwAEN4w(e> zw!_qm1_G-r5zO&@buAhhCgEWHYBf(6k<#@hv=q#w`4P`cv}$B((R91+^?L_>DQJAO zOgM3GFlm^oI3cQkaGN9hT7B#=Pf@L%IC$^Pg+XWfW9!2{NzAZ3oaaJ$K1D5BsS=)_$C`+BZ1&qsxd zc(rc0=YSfY;_qO1;d5PnwZ_YfCO6GitlL3$FM3@S(3UmlZ#pmTDIf8<-Y~%etPOsY z@TSV0Ng5aWv8#>vl1V~Q?Icz{e7~VqAnp!C_Q#+jHlY~QY*sa^&T;|*7gOWan4|m zJw*L0AU%p$HL5F9Wd)NdCR9bvq!nk9~k3#%!MzGp0Sg*ygPRBv7GUzrrA);X?{P6}U6(4~R zJ|t9hCsF&cdz!I7qWH4`noojt!=^%@B-(;e@L9Q+SXrP4VbwSjCe08pE*oh^K*hA7 z_}?u8|K|}Kmt&e(PXS2IcB*ph)*Yp&DS-2UGBaj~&spqp*b8d=_ z_6LJ6^S9g#v33-Q`V0)+@Ek<-e&CzMEw@)pw0P)3VZUEHGhb4x3U;&;hbS73%(bfgS@D!X3iCo?`9G^qcsHZpfp`Mh|Ga!$7Lm=^&CSQ^p;W8JCE7 zFV-MiZ`$H)Q{S)K>|vR)_>JaCRtwz$$kLdYsBk0 zPrlI|Na>gJ0vt{xtKQNBP)P7h$Dajoj|*1qxv@#j(k=nsN>?cWaX>dTjQ+*5vdYGnFWei7VvK&@2=wbwX9gz_)QvJCu8QL=xG=&FRmtNiKx%M-` z3l)hVTduR};P>KvW4L9lUZT>9zbwwtCJY{+9EiD(x;48FZ6|B~2&&^W;rs5-fv%N7 ziy4*a-zP2zht6U_7nJfZxmQ@Xhdwi&6*8ww9h#+%FofCikQSliaZ zfAx4n9X>B>2K&IN72ZRWL;4r)-={}PIZc*et%yvu$)CRZDwJfpX&VM|Wb{m|=8{<1 zf(4x-(<+V$mbN3nKfpyrb{%JaY}W2Wf{6E%vO4x^2_vKL&q@YB3>Nk0k_QbDK5(8e zjrD|f9FfWXK;&Y&bL;dTi8R+KxNe&|aLj~DlTwe(<@<;M*Mfd#6UD=y{6*~>wh$r8 zd$^#XHlK^500KFEB!h5eOEio7u;0`0(F1=d&$H=*6A+)gP|l{L;rEMGi6 z!9qZ#?MarsRi%o{PzE41zJsBMX6TCw4Mf?NZJve)D}tqa5w?NXz|l3L zLuXbl#_bbsqwtroXGMl1BChp+vc>GE@1i}ci;{rw*(EW< z0c=yq_ewl)Ke1;JZ~iQ*(RFSEjYK;8Qf*>C_xtg7zu_VQad9pLR*)wP<=iuRQe`kr0!$O6g4UyO?+4b{gpDyz*#4))nx zNV4E&!3Z}e2{?Z^xztRf`5ff)xkjS5US_1vUVPWF7Jh->y3`F4^Z8Rhn9o6lX zM4b(lJnn-D#iA{gKKWkYeTi>p6Fv|2CoQU|GbcWu*mp>x5R8zp|Cx(WXQ!4SZ6`b@ znPzjmZ%c9$-DE=ym0B$|UhbVt9&g7B(UB^NhBJ8keMS0BT?f(IL|dPfp?GlOZwB;; z8(3rbY>W9cD2|9MuT-@?5!HSkd`&2H=2ba)yB^6DCRFjP{(Y~Q3}a1W`^b}nOFnqdG$CnJ_1sj< zQ{_cMnrN+DX5sHSO|m4>a)Gpe8ks?|v8p#``!8l{TO|Wc?qIS;DWybsk@kI$e(pqD z`y#E#;(Ia-#V`r%`aHg2u93noGcnTD#6_l9R73hL=q#?jX#S8X)qQs{{ME5}cc z?RU@@+Ax646s<~mK((3_xvi0Te7_Nqad-p4EYQ-~dF_(OZOsYVuW!%x_H&agA2gXN zHA=OBZ@~p^=I=hhkb~8KF18AZ4&}l@)C7TOvPw5BvB$Mdxa{xa|NhQz-(zZ_g@7NU zPA30h(kRlR%K9R%W{}S_7ySBAoiwU<0k|ef1g!|-@vFTql z&Ws;rMa{8iZ)g-y=6O}_du@_`w)+t3vz zCRET2wN8Ss@yAyELHWOO!T%ox6OyL3&6BUyO10?<26F^Y9I!xk(e5aVX?Q=TXN5qw zolpo5?C-*+>hS(0$P?yIl(&LbTrDly_z-^u6w%O3AO%=^Wh3$zF~V`qv%~=a^bnWm zZqgG@8UROGZhdtWq(AZNGtk$M1atRoD zlvsTfyzg`2fCtKljo0mnev$))K&}gALsX*T26f4_)vS^2H<3W>%g0MvH*F-jTFin^ zU0m7FiYc;Vu^@-dHrL76Q)?Udd+sZ4)KyyRy?M@l5X47#QmmLGCjjFqIaehAeM!q< z-mk6y>SYiawb5|M4FIuV3%~#SN)_I*9(nk0WJu-OB-<)V64;en!YUt!8=l*8uxT=+ zCZnZ^sG^G{Nl8TR6;V?lfY3yuf2!_H98d`EX_O>cJK9WDJ8fmGb%Kn0jhcbko^F!J zha^{NH=R15h)Sig=%r3+DuOaAVt$$50ZRmRNmL)|l{ysG>KfbEK9RQTrBj55?qRA! zQ`k$=VGvJFjFD`VziDp)XK9+clc=9bIRH`5a~}|2N|dN{4%O4~zio36t;2m_%l8Dx zAqfXWnEVmJ$muv4#wWmGA${)ms7hBPl{Vy86xn`NDBgPs1BV@UlGIiq z_?@%9@hwPdARZ}+NA{4G?V$_LKH2iB^Isud?XaI=W^p1YzAYld0HTCZ|&6aU#)0iw*CIyci9Hc>m5S`8#+fPI+-1 zWOF7Cf@>a^8ok`t-6a5!yvf^2<{WhT7CG>J1Oyk~2R<9*q4Y&*YY zY;1(@RCN-$_g*EzBH1|~Eg&29$vn5P8t%PXnSmSU(=GHzrk3qDc=hDW_uLHdf3Xk0 z*|N`1wpL?dZWP&BnT9QIQ=Q$23x~B2Th))lKDW<%@Z9HfFO&{ZhfmFcHE{GISAy3l zaC9If`ut;Z5k{q;!-ewOWRT~!cHvDJf0}*_ET4#AAN)E{lq{FS5DVpBvs7bjfue8O z03aEIdqc8)|9Y>sp~f!y>M37jo8x22*P0cWk-)8bMYVZ|hcWiGm`F+FrxEla%c`fY z6SM-lPOO)#vh{j!7X2SoZwT^e`ON2~Bmf97{nx>{!q1~k2Q4JrOSBLXq)Y)GRV_`} zF)cQ~?z3i8tCrTtzpqu$`;jSRK?H>_l7yBN0=i6Cxwnx3fXx@sAGC^apIg1BHWg@W z8GJ^O{tz)%*keJ|=NX@~Q3;sca~H|dW+So!Ce4F2zbi^S_^0}p5sb6MV{8DTRW6a4 zhF?12iA0&nalZR?x0UGFp}x_!US)-x-dj9-AhiF>7uTH+J_!WxYz#TH-_?IcfLADD zx^6{@jYESWO#aH8YZsRgu=VIK`oHHLIrJQEL;K(TXjmp1&YMrJeThm`HGUslD}fjlIP|UCVF3LQ5ExF zDBq%q*QsRpbqgawq_QHvi1h8RkrbZ*t;Q58P^nqD&8;QrITt%GAT4NtGI4iuV8?ls zi;%Ea$grqy82QVNB~X+Ofl~m6LEs;G=3D08PaWe+Qtkd;x0isJwixA!ViZe-fx(01 z)NFoRA$x3(AQ4$<@zN+AU~%A_@Rp$T@7a*FcP1{n)XB1Q2;f_Xsv46c7G!5|&P-nn`*1cZ zw+fDYld=<0=Jz?Ov2ST_=Uk9w!QTE--s7Pp3n(R3=9kcUb1z|ogC~TxCCK)P(ik{| zk*4AO$z=3K(f4K)p%Ol+=y-C_;FDl|uG5evgk8lep7pccWncUT>Z{F>P-M$rVxc zLgJUb?|ATz-mLH{ZH0qs9LL?;iWn&IySwRaeG;r+gl0+Gu;k*w#@McmT=0aOh2%=0 zbOc(2C8p@Y(|8%@s08A*IF)U`_HRHBtD(bV`AM9$Dw&5DO3 z7t+ef`v8~*9h+E?mV|0lq8riU3F4!FW_3Fn*`6vXmdgT3h7h|)E!JIZ3R;O~t< z5}w2-t9n#o#TJU{zS&_!6y|_v<=(S8un0_R36h8AhG1=HJNQzQ4@tL8)z2zSqU76z zPR&rcYrCM&WlHKNiQ`EUM1`-p@L8A3l^}MA1O4ahlyfzffC9zhK#9qc=tM5|*0)MV z^r>hvReO~@vp$Ies*UO4SgT7UX@vKPL<=Z3lDpksZN9=LW%DeZGZEpgb=aohdlKDB ze-JrF^0jVjSu;CbYeUSZxYM5m>p{?E@0_LOd zKxp6HOr4JXTeTXuKFr6>Z<&r5A8iof183`t305W+8rkXKJRpZT6Ra`L)}t;YkZC?t zb0k+oH>c}@Fr}>vOoYKE2g$c3h}1h;WYn6XDCxZ9AjS9hS}b(lpk4gA4joQ|6ho~; z3)Hsj69npYB~oNziZIX8(Vx9E7Gh7}Pp7_~VtU+?hCscxT6biGik;l+G1BE!wn9Bc z3$?v*7#MKw?5V)IX+w+Y(!z*3Wyy>M3haVXO-2s2(tIKl%Uz$)h$yWT!a`x_ChZtd zmH}-+B+w%Tb5joe8$Zh1aVLAk57X2;#bQ` zsuQ&6$}#qdQx6#lH;5Do)T|7AomvUZNJQ|SspIn|X05wH3-`Us%5WMWXo5Guickrz zmT(z52Uu8?eOtCK3QaVO99f#J0z^m8NI6jr#fi)_?gLwU{M>CIb5em{J>!sOexW5) z2*H235dy0iFs~TEQmqt3PC=%}{`{G39kjSVB0QXaHvWqyREAb`T7XcTvS~z|HXuAQ z>i_S1P5(J+1wrB@AD$~r(lP#yWG1^nFDh;)=DE5j`0OAu)}B$Eh>7pE!0GO1PShCr z+~mrL{MVpHhCXH4;B=6l;b({fcd61R%VZ;-n(Fa8Rs2}e$Xc|Yb}vKR5%2%^N8UT8 zda>WZ!QA7kIrlXCxFi(Jl9(4GYp`x*sA*QJx2d{$7%%tGd+$_~`BrY(C&79Ed}-tC z-RyFmAo|{A6Z`zBHjQt55Ze>O-7Z=7l?^IZgVIe*?k%}5ez=EDH`|xW4gjf{YcQiq z_F7DAjdO-gXe|;XAe_crZ-TYLAZ~e@083x9U}55(7Ku7m!WdB={JH4ihe=6&e;~Hc zmAH)0i-2F();65;^Mbd58!F;_YGb1ZE|M_>vm&oPx_B>>Pz^0FphPGrWE8#AHkfGZ zi7Z4mpjwH@dsu?*b^YM)E8RC<;R3dcj*RyoOGL&J7#DG>ZWSjz^gE7S;%g}mCD$%v zzmw>lMJ3b3M`DlgC_YH((0hE7Qbw#(}PvHtHkbu z-HuQ8yKm;KFs(h)rCF>EV@bha{3)+a6j=YY8f(jE^=#qB5)JXyDC$KEzx)>@ShbOn zRrUDU7czYuC~Z4Tm>~Gz@Hq@A3XC4FP7ZL#RO~j;|jY5+E=U*!d03s+~w;Uh)eibA~ zban*xW=kh<5agf~1#t;Rtlo1KI{Y&qEOPq51k!7;pVcWs{Nd!Em!NCa_vd;iBO63ZweB10kM!TO=p)C%%u% zQMYr}2N2A~yx229=4a+4aj_RcP5*D#+mrFKjS;NpMH)-+ay@#9~Y1XDj^q>PApw|fy1(-ajA^0Q?rNDFoc1Q zjH@bvbLZfHW0Cnp?~qo}G7!8`KLWPH3)!m*F|f*?90c?5Dr z4>IyIHYB_T4>R>^L;{9tan0i6@c8rRy3b{;ZbMsVs#Kk3gAGrk(hE)#YJcSsE+*C` z*S{4gl@izA{dq$p2{9gV{6$3PCrd>rHk`RVGj7Jmer-@_d1ucW5=y?($o*(L5mI@k zu{wS==o*ya*fhafDhw@YH=+w>_xl|M``+)>TKzSPE!U49nP8C@)3m|p6$=4h1IhMY z{%&K3Z~SktRKdYw({@Z$l00~a#SrBo)W{Y^z+EG_HU2x>Eq6?K2nAPhYvE@dhgNAL zF)%HjEX%jh7jy53tvmn=bCevgaZ1)L0{gi0dhG-;y=BrzZCs(8iWd_Etfal;n zZWQ4#{*A5eR0;ih`eIX`1@f79X;J{M_a}{?Oy*(oWZzp z)WT9EN^&NS`{&ZmoCUbxQV6lyg-vAu|Vn`Jz%+fLa7eXT=s#^e425-f4YfeWHNCI$Z3a z=kZ#zKN}>!lJdB|R5afO!lWGTOjs3s41>jb8EW zHBjU-m<4M%vG?jUam+`jTq!;a^d6{tQ~tUOA|afKB+D{u99$w6cL!0a z{`Hn>1!EV8aP!$L1d#9LCX6gQH!L_BwxR{4lKlSQ0!T;Gs6+jBi(7i;X)Q=oGv5HKf^^aQRM;xePemB zl`OSahI3F)*PsxA7|>O0#KzhCfEHF>>YNwH9Zy+U>tCm zIGwNW2G8j;$NjRvDxNFY|3o~v<~i5vne{QDakUq9PW=6*k!G2PcM$FbS=r}Ox(6F+ zNUF&x9erYLJ(y$-)%R87aL#73=MJzEDPbYP{(pbJ!-4ssMDn>`=Qo8X&6qc1R9n}0 z0UO>-qh%(Wq&D9i|E^I;vN#YJ1ZrsXg1tJrtJvN@wBs2pYlnJAvUwLsh~n5@&On^B zV9A9N*J-WN!pUkCkwV!ZTORKw!Qw@!jD+vH3FL3@$4WBv< z_o!C%u6`xga;8goMDB(alE+_$Hqo0j&jQWm(EKtEA5ib5^3retnHMAboF&3%noij7 ztrK2c1G=C^Y0fvPc9-Wx7Oc};GCvagyd}a!+Qt72FO?+={r9;KDr?J?&8Hx@ivDv& zE(G7Y7LTS}Hft*%1%3^5gjz9;JRJSXVnqNK|Gjnia1tj;P|gj=STCF6uR0VG^~7s! z!gnDHvhm>Guh*2PxaM%Q&&5GI>dH+2oRkXF@bB1sHp2o0a>M!2=1G|!=4IHQFSP82 zQnq=Z6)85M>}k3(@oWeNZS$0}-pEU{8QXgy{npx52qY`lIgXz*LTKuo>V;*(>q@m8 zdZ*`sb{7Ib6Qs0f!T~@r)JOZI-8Rblv3UY}6vZVqad`(c!LDTIuXf#87qRyU$$ zVhKvmmU1yErjMroostoDNKDZP3?+t68>kIPFn~a$cQhQQU?Ze#yd2b{a<+fsF-?Dc zHQ}7`H=jh~WSTUQAw;k8taiS{xa2+NVgCFBbgS5M7kk)G1SPmj_g)q@@b!AlL$fTz z`{>xlm8B9$2?t_)#ZymZ2v+Z3x2w-KQ45lqwh2T@G%OUE3f=AeJdg--mk^8=1%sMv zwP=VSfkTyxGCA*|D7KmtjL7No?Gj=EX@a)Z4pEV9KsU`#&o1QnR%`qDmLTUdZnEKh zb@IL#u&A$>*gNh24(5BQ5WEpd#UQ&^o1EL1Sd8;#s`Ruj;yw0C0B@Nfxe5KAXAv#F zcAZIgwO4vWxs^0Fzj=FNeX%K`D(@QPU4~-4uicCLSpNFP zFZW*ZZ>yZdh0LnfuEn1ebo)*ZA#Nt8m+(y7@f6f2Y?3cRav#w>+3Z>7Q-U`FjFO!k z(j4HU?n&{I>R3_>h{^B{fNG(04P-@FHC%fbLZ7NrHFqlkOP~OvcS}nU8u3L-5LtJr z7CHEx&8B5=c!(S36s^N|An>4Y-$7p9^IYsiV~MTfQ&cDFqG3$?q7MgVukHp=g}?Rl zcB)l|`?NJ;#T^_3hDz_22hHf(l*wNm*h;k=D@dM{YlWL7C2<6pA7we4-O5jw8SetQ zLaF$Z_9TuvYb&(StHshYkEd{Be{W~?yF~mBup;MRD~(NJDGdzigOUcb&B3;@#sO!1MDaiWSWbAZ|RAJF$NO$~ML6 zu`C^*-KfmLq7)sLr!I-;yrdk(Fh0vg8J_20g3tffA_w^32Zh9@1_=il; zmKRDLc9@DVqm)r_=-QvN1zxD9H9u+}Q{4snzf-Lw5BFnc9ERovi_FU`f$2PpTuhk~Z z1CXZ|5voQb>EX{IVPG0kEU&!+M?vQ$JMj8$6w3974|SC0tfe{L!0|q@Htum@O%$3G z1-=)$e8KBOU=IW?Ix2DS;~it&BALQJgSdSXoI1@Aj_t$PaLNlv+t0Ka z8OMlR9XPY&P(z0q4ld=ai3EiZ+c9RAF?kJId*x@DNhpF9cz+>KD~2g)r~`RE!zO?L zYp!;Cdw)0#SjLPH4t~FWPdw%^I)Cnq77n^* z{|^6Qa2SpE_WTp|=MD#E)&)^Ubn)fd_I;mum{6mx@_kUGN87cP%t9lBda&XBP;tJ< zLU$>&%l>Mo@G`PQlCrhDSI$!>^X4c1-D6NJ36L>&;W9y!_B#hKo&i+Nam4paC-%;~ zabw4Jk!MdEum(=1*;_p{SQ_`CW7bo>22My2F>kG#)_#``B1j?;WMK~+#(yzki}R@G z{LKO0JHU#97_6t<1VkYo`H?0oEhz!v`utdMN^G}vx=~sHisAPAE(w8xi2;Hn?b7EF zoxCKl!ZVV+SKLZIoSH=0rLp5p)FJR9!2ceYlC$rq&LwPIYsH z@50X0EPE*ewbw2$m^#DU8S{Npi{6_deD)5h3C5tflnq@Cf5DTxHwl*OHO&w$1+(hi z;5gQ{Np~!djAMuAumjc1ehnEj7YU+s#dDTaD3bx-NNAf4`_(6fBX5sfu`G`9VsO=j zMDy>Elmbbtq97f?DfE(n7*Z1FNzq*?c?<04?i_$v=O-IZ)El%@LwWq!$70{-6ypvw zK2bkFmkM%dvNyTT`EQl!5T)|xNEFC*OMI}9`;DmPJHVRA#zw>`) z(@i;LIa7$??q$2vut5WfEDO<82#Ujo1znpU7H#taiA$D>Hd&bz$@|(~J7`kqG-)wZD#m$`{CuLEZNb&BKeAk3 zh#nQsp&ehqTK7;;V6Bt%(fgAmF?9eQWdF=LKi&b>KQ-x%99Bs-8<< z*;IV6awV-}O!GY3(kL-bn`Mm%dVmt4oUmM0H+i?XN(OH^`A3cVSD9pi-|0ATTbZsj zKpD_dC^)t8`CUYqh}mhV}68c(3?p3$Bn9?HYUcip1hQ zv6IvsP#(NL;Xc=DU$azIc?5wtKgyyLq2_mh_3s5*Hpx)}#H6M0q(EwEN^hS-jhxz%T z+$z4uVXjF+kOYC$G$MS*!4)?7noeJntQ0(9+|=SE`RV_8xD|IkmH)Tr{FqqKV^`e5s+Ym)3DDIja$`Ji>Hjo zFX?W~Z!v(j0sgitQ|SR@7p-bxnSY+~SegWZK^3w#T%u9a2#gP*J(XT~)6LrCha${Tc1fTW0!dOIm#Mb|&f-M^4Kyc2+*H)@bs(w2Lz)B;RxK zQ{)tZQ$DSQCML*9@*9LIUp)vUVYm!H(eVvcVsLwX8eV2-o1*8W>F`Tl@l;8Ak@hWj5au4&9YndjT6l)gN`3{nE4|x z%_Gc=-`Dg7G`a8hUq)QY6QoPHD)`Bzk@JT+Z1NOd52IL~f~5=%P^b?YFI z&K~S;71jU`hKwsunT=%1 z^oM%$_t%=gi?)Amz=@DsKh=wjh{5o4U&A7zjYlu?2pPLJm$P&VzOUbZu^c$8J9PO1 z1)#i!A+RjFGz^AuKw-Zq@?6XFj`NS@-CoN346b(Oo$(1VCz}YVei?+%HuyZ_`m4Z!fJsYw! zm&b ztX!nwV*fi3?02po)^c|@eXm=LlPT_JS&}Za()NXZ=V#0uEyZHj=2DZ*WOYH)+;0h%0+{%J3 zJY2(bcFmsyAImBy&$NrWL`#=grz$?%d*QhPb^C~b80vJDIe`?6MXFrhS3MVI39vev z+tx%jPzE!bjSV+BcQH}f>_=?Fl&-#1B>q+Kku4Vf1cuv^Zs`Jcjucqc554Kh` z-`Lgl3y9e?UsP`u%B-A>Zx}yd$9?q<5jmfW`NkY_l`lt7I!}?hs(i!wquNQvS-ePRscB;JEl`Qltc6fik|^TBvv{jQy8-ie0Y_TM*3;lPzCZ|m6AXv2(GNgF@Gt1~5dYo4i0 zhws2uD@ojfHT)hD!0Lz^e=Hn*%k^v4V#|mpRVz=G%>#N?Qt)%a(df$VSzJX==#a5 z!Q=*dzh~Xd`=#fd>h?VArj5)V6Tgq1(TuUhx6yB9|7Pvbd$VomL)Vd!X+dx&|DzR) z6*F6YU#A~#$jEoqod2!pDhVWYA*he@FC+5mNK>A)t@5L*0`?~CEwIAE{KQ<&Gebv2 zvg7~$?=xiCrGFdaj>(tfx@|Rij42v4dsbC^0PLe7$JZ9<7XULg^)RJo73 z5od{8Rypk4UMZ*(gtV_%_xaT~q~1pc>0yB__28rpMVoU{AQGJng1jxB>49Ts0U=ZQ zE?BCV+yTl=zPox1PCD2?sD%cJWN;z?LO{L00LMU~++U5>HHYy?cRF?_06?O*a#c;Fm>kfFJ-GLY`k)E|1gQ;_I`;)& z&FV%xB-se1T&9gSL>xx2v>E9JD~sq=+Xn46+%`$=>X`7M^coQntplOmf<{4m8V0n> zO7+?}#;sU)?P&8oPhu#Y_jn!||6+@C^|7b|YDC*DohN2%1_4r(3Ulq=pZm>FN(jO0 zMw-)bZv+qe>%S?#Zs3G0X@~~}=u`j=8k{y*t(KJbYV|Ju-+gG-Iw^3#dk@Z)z@lX- zWYtvhJk-sHp}*~hl8Jr{^_yr*V9#1a!JP}TBU8K$9&R00Q)u^ExC&t<8K_HQ!#x$6v@a0eNSJZEcn+pf4F7f)b)ahKp~cu08d zVbg;tyK($>_Y4!Mb$gkqbT->YZ%G-lY1p>(ia29z@w0W?1q&xi&b+7L*1l~AIRbtk zS)8yjCUI(=lZx5>j7urP4son&;rqPjtqpYW>5Q}d(1Dzg!5bImch8mW{g&UOWa*Byg?z`MLH6%N?a}7mq6C=|2Mc!1rP}RU zx60SeCAb0)t14LKFdG@Hb(%dd7lHR1@1ZPl!-lMurmAO?Hn0SzVR;wM2&29n&+#+~ zG!pz7k*wtyWEs#RKA~;UpPUY!cCo4P{5H{CnrILAgC>n$=O4yZyktd)xP_IE?iJUJ zWq$2S>$qrKi2j_`=i__I)zy2tWyNm=Y=;(?(?x}eWHoZzC{e~LZbbeip?!Ep)PdRk zrWPG0n#PPI%eFRPD|o(g)@wRI=<;i$;Fwl1h12Lhl~PLNgM}7b+XQyW$nWcdz+%{d zH>!GX+y(OYU_w63NuV-I?+=im09ryAX`R9nbck~7!{-C+0incwSKNI{f{cfIYj zKffIk$}N!F?G}kX;uhs#%q0Xs!oA8ul7xAMc}?9XO$wGQnTb`IAzo-2%d>3D6366= zP&OwYI7@?1>@!^mBsa>-lZsEu0E=S3!&o5jr9N9D0hlzmtr?iJ!7LjERbi)dNC;Ne zyAP9*RWo%Su^^lDZs!AMJj+uJ?$VHK!SB(f>DG8ZB*3x`Ijgs`ojKhvS@`Y$y6D0{ zn_hFCvIV0gCxLBz`r>WGw@|9De-S3I3 z+M6|R!ijkK9azl}SkR{|O@my9OKko-in+3h1R0;x4%J^i9tSf@C2g3dm5mcJ)u0dL z_mi+*d0AuFkP0`(i_tSnh-Lmpul8^OIk2*Hm)5Z_hhSwx9H`}l{gt~Q88x1k>35yF zw-dpdj zhRhlJi|WAHK5^__{c9^CF7Hk4)1h?eRk)MLVL#JoY1jCH{XRZCO*3mNfj;p4w+gTX zy=v7?EEUQHBmfpm@f<{B80KzOjU_>7xqU1oX;N`!DH*nG@_=nlsra~l!$qAyU*26{Fwx9>DH9ko}2!lwp*N|QTNV? zBg-7anP0ZyB|--6#1%W60ZO|Brbf4qAVvZ~ULt6U3Eiu=7Cy%|ZP@)#n+3vidA8L) z8b2yBTucgV&R?rlvgj+(g6bv6DxTcj^nE>NaMjTuyHWXoEX;b6-G{mLhh0c6bm4q? z$rjm3^rV7=*IZbi76jSG3G||hTJ=pL#@1UO1p#6>-f|sJHPc`(f#wa$GUytt7So8= z-aZIkiBGnKb$|8T)Zl5O(mPD9cS0toeyg@mi?q#r$cngYXlJKC9F(6O2zh@Kf;i6@ zqE`hw9}##UF+$m!!4>B4kiY|pCSpy&?ggs{A)p=3T9g7QQ{hC;0H|zgZW>RR^s;Nb z%(sH8-E{}x0zsC@H{{V7>kq!mdt$?!BE{vi}&B}HG`~Mcz|AlI?aiAI;9Ah6aziY5>+IR4)}O4GJYt+ zv0B^vt8zNw!EZo1Wzm-mvRt}2=+t1HNa88FmLT{a39ziZMWIaCxtt4L zj0FX!6nPOV%|2^2L8N*TC93;_fil)y-ef#~Pi@xOVx&NDybt zeaiFEta!*e>bwo+ut3z(^dA<5d|ziHS0?CcawoRY3O_)K8wmKtvZ-Nd!R8-=tgr74 z|8BP>{+^c*RwY107GBI4d{A4hbkbQlY^oM4;lCRVybzQce}j9+sk{_#NEw0%F(Q|y znlv(!)(#|1z{r0o%YR~iGO!XL-zX{y-5ZF|f&6!%OUk0;JZm{=0W+R!KuQvv z4r)BGXAiPVg1PfO)aBpTV^EoS5E+>;qxp5u3|AEJn>}>cYqo|pBpL2@&|vGJC|V+^ zWpV$~w2L-8>kO-hjT0^B<&0S&HgAlB2`>Vb!sg5pDQ#2=6}|0}N;RxZ0^pQ{2SKZ7 zkAZsN0$J8f_N?@X!|o$0)&BMi4HXDNptWSY+ugmA{(r-N%Df2wzSaY9y9AUd+4%fm zfuE_tZB^ux9}rvh@F3odRy0#i2S8=ey3{^`wJA zGRIS(H0k8=A-Xgji=VTlK6DJi$hA6hU>K6tqCAH{Zc&|m2+kF;-m(+reLe1?s3G`y znJ9gqVmLds-y|9^QJ}S#l0{F!MEUnjNuCHAq$6(p0#l_H(Y|8x3q&VN_=AhZef4ly z0#T)AQ>6wHWC7ot7lWH&okP^unr#qtiJ<68ZL9=2uzly86^Z-zE3tekRd){ouIc&F zGHP*OgWb8yu4iZX!LFtif7pmjZp35LlCmTdl?D7A-qoJy@`YzM<~KBqkl=UP{pGgi zp#*s*Y7FiYl6(aEQ)|L$%PFfR={!2__zrOXQbkW&mH086G^`b#Yt+12@VsO9x$3n^ zU{!3{l)cI&961+sGP5H4(U=<=ic?ydKOuy9@UA+GH7(Abq%vltczR^dzgaT=3*k1w2;zG*3809oHmcj z6|)39X#Z9hdY}iNM@sTd(}w$*V~l|8;X0!skS_zS|9; z$5GL}X-@pi5vdQtuBxSzX;5Q2Tld-nP-;TZj00H8Zq4v+v%5AkV1GS@<7zrtBloCL ztu_-UjU*h@cIO0XgO^JT<){C~J71r$*F4~SLbUt0SE>6Hadw>4-^C|2r=XkA`9zcVqUrqX|w z|JXr%%46j}W~IXb{Z*@!oQ~LHjgy}d;q^hs`xhC=nXvsGg#D!kfaTO0T=Th>Tr3^}j2Kz*-~4R3J6iMwGG5 zTdXC9IBSphD8{jyAZ@a|prk%^Ay`8x2;8N=Un`lj6d1fM;eNZTC%1u1mB`Vt4WCAf))5x)3m%TGPJXYS%8rWbS8KHe&Z!KjqHtc%R z@C9OfnmthF=*9sS{1Fjw4tvhx2b7$&qX$c!7~+aEcPe!;<89Cm5D!T#bKIje|M^Qb z3oS**1B&J3iMZ2h)%2$WUm=QWPn}9ow&kIFqFCo>7X7;1D|?A1dYUU5fyIf1%hCq| zEhRb^4-$HvBO6A^1Kg$&Mi*%RsgF$!W*Evu1OX%G?Y!vJIays0 z!5!uc%7vIKq7E;n$G4DjFvaO-Sbw{gR|uR|wAnCK@g$%tUX6-bzR90V*UGC5%!i;s zX;g-OjkWI2`ty6n^V-igj@2^hZFr_LcrYNnq$c?U zhz_D>^G3_HvjTjdlAUFRlK-WI!LAd9H7nKca4vZXL`x>C9Cqek)+?H|*`z_=>CxBN zlE0s69vW+Nfq#aLlj}}{tac+Z1{mA&Un({0##yQi27+HRkQMXYG|a)!4*!IYVLY%G zr|10QX(pY6yXAPI-AKM5;e$i_UwMCCo|}4JO&hG{w)a<0Fahf`e=tzsb&Z+C2KPt= z#yFQjso03xJovV>CUZYCzVcHijtOyvNZ?F1+0?k9bis|UDAaqcCR*^R+A`-JQdY(R zBx&S9DnM%&%QK@^v;i3oK>DqbRBPqYA%IFph+P(|bg%VlpMb0h$QB}Q(@c5BK+B9i zH(EwBk2w&cjS%@wMdLPE_~PLx$d;g?&L3o2KygKns-jB&t+-TkAxfARpX&Q%rT2g8 z;7f!)kT0`?$)k;+yE4lLkh4$| z&}KON3#!l;x~Lz&CtFt*+Pc{Rr6$G*tUs1j*pQ42zM@Nf&$e0Ie6KzmkBGOdj^}u~;z3!kUHz!TUO#{JpRDbHIduKK4-yzaNQ zJe>~E)eJyI+$p4a&Hx1LOLI^{jIUhgmmA)jiwpL5+_RN+KbEDO0V=n1s=wxsBzJ4G zWW-j85Le>o*_A+^2ZDit2N3s3AHe+LATHP)fUgi8AkWChGK7gGK{e?`aM`K?HO7V( z9B!XWvU@nNYb-6<`fI+7b-U)lkI%uxI7L$9CILz>!Jm0WvE+sT*h$HA3u(i<(?G_v zG?$7c3bcPx$#U{La!*X6#5#<|f0uhla)9v$0{05Y0?HGe-gln2vlHCk*ZcZ6(JPm< zXpZQGypAOKu^zqC=gsIskWk(tKEqQjjm6@zbKQHY9*RLom13^4pYJ*XT#8yDAz!O; z_O<1k99mkb1W{$N2w;tA7a}H-&gd&kgm~~jpUbUB`S0tSs{Ennh`FN(Dc5AnzgzBTQx> z7FkdR&(#~s-(^7~F#0Ak=fi_%Do|@>&MjmvNx}lhA43HkrB7;4k#{x(26seWEMSkV zm*}af8LEf@x|b>2cui^=_0f|~)YxPq`DZij_w~N6*(Y+^-7ML*?-KV^>g#si)YRka zbPwAWEjFZ{loW09AQ6A2X8?DJm8#+6{(LM#U49PL{6r}>)Ktr_=W*e4P#N02Khg9Q zd6e=*&&0Esu60wh`-Ty4*Pm?kd}vbgrqgK^-b;cv!vQn`C!@~&3$nIyfdt%}&D)cic>8tHT^ zl@OoYCN{7I{Y?!NK@>{{BpKfcGo^_Q$VCg?I!mxHmx~2WX3YchUL`rpSn_gQCRJJS zM#(3;vyt~)?+Zw$v>J;>SKpaVk)YL!#p_F)ys!6l&x;+XX_olp`SPt5DjKzj?8-h| z?$L0h%h3lfL?q{d(>sILW~yB1|AuqdQ)68ngOKOK`^t!t2T!;=P zFb!()lCoSx1G{!4wh#Bc+N{O$1YT!F8T_;`-k6-U1Lzxh)1!f(U%Kd>sGNVo(?!TZvAATRtKt$;d41VK{`CdHj zEVuz_)l8c2ec|~P?4pJSJiCZts3iaJT1h(gZ| zAee1mb%ry{X#rLv!Ihy9E9IVG&@UmR^WYo~cQIyNhf^7f@tMjFxHDU&yG|wr?guXs z2Zk8x_93%)f^e@#wAU)GWRnV&@ zbm371Rl5NSmp`l)Za@oBE7c(S^SR*5vA{A{WX6cot-eTepr^pA+U1l*eo%tJNQ%OH z+Ay$$#m8=7g7Rah^=brlSU|H&SSayc#8Khl*PVov;r$`#MxbcKaa-WMmwQg{r9VMF zn-AJzkBT}1mu>dYD>AyhvmN&ekYci%gA- zuU{KA+6LcAcuD6YP9|}L^K?aV>x7M0*AA~Gh4{=bJ?GLHjMGu2f(vdliE8B?IwI0gD@1*iwLVgqz*||o_8Vqp12=)*lQJwwBB9b6^?4ZQ4h4BKi z#^BitcPPCV|4PCQDV-(mVF#$!Ak*f;*ikx)pq?9Gv4@Am(9ul%eH{q;As&e}42`2` ztXc9vreEc<>F&IPDJAdsb^8klecbi?FJ7YE)TsXBbpV6+a_-N1%^Fi)$=>GmkSn2K0O=JG;NqX$ zFR&k=fhy0Wv1qO!6X#T`7H;{LvcTmR?h$^UM6!k;OL$`CRrF6o-sY&vU=4p!u|45^ zUP4nj8esM2)0Oxw|0{eAf|*X0PO%9ILUHG=Dwj~)ZKEXdTX?ITi&{yrvkCWvjTe&~ z1aM)sP*b&b`#q z;NR7n<75cspJMrPyz4niM=nW%S#*(!4qdC`QkKQViA{{e#Fh_lpk*ANdLtTa-~)c{ z>~BRPi6&J2tyG&rYDE$2UG&PScPJd;VhDF-+| zw5uZuhP=IXb(x$!OK@tYjHnhF1B0yL=Y?E;XQXJjM?5(#~fnAgKCOh6SxUN)`e0i{YIa} zsQK{+c25)mnoS4*=CTEOU*m-Xkx1{y zl50kIui}Bn1G~syjw>eunk|ET?4#T##ndABX0jkCztCP)>` zF`Blfu#TkhYxLNSwHxo@4{9hVDFFa1%92$j@UJ?mCY+B5P6k+;h?H%LrI^45mD~PX zupCtqMoYL!-+v0S>&YkDsrJAHK8%++ZIl00=49>|kvPi)0sQapii=~RinHt<)M%O3 zILnIABqmv@auu9(8zI@@vkIRW5V7KYPk!t>#G@OMl8Y?*Yekp8iGzDj^4sA5B| z9HOg5nFj;ti^g*2-yzaE7utkGDsf|`?9^jxd8K95Yok}PM#$sPj>|(sjWycPsi5P2 zL{z#e#`oi7EYZmfq+cXbAmQVZtYA84C{^RJVHA41dF5YXkR z_!;JbQ#{K3%z;)}LWS={fF=CjidvGCen=bD3_L%f&8MN(hN72$K1Nu46%$!rm_v! zUBWjLAxi|}#z_MjgZqjnc2ICnguri$E%8Y}x?Tn07sKj}c4`jKgXczPUDlviQ4aGm2VI$+RP7MsmiHfej|`3Dm`KT4f1W<7EGoXWEF3lqIuSvGy%~TtSq-s z5hNm6z9iy8H0x{4{ZfRMpSK(?U2AI*&Ey`RCrPr6Ec+bnb2+b}QTeT7fc+FQKeyNY4#8RR*)MJDJ_cp?wc?9 zRCN9XfWhy;phDO#7@32QlqwmoDwG62EEK$0Y!rB@UkXir(8arCITUK`iK1ds zhDZXDoT$~Xb9^k9(*#E)Nn6=&oQ|GwEV3nJP1%*YQw$*6j_(Et8a2I!dk2vbNZ%5H zqLPHWwhO|R3qrEF_$hAcgM|2Jy|4~UA|pnGun7upAy1yANMUnhu_!0s_51KYZ5&Jt zmx<_tQ>2dRql0>^a4BIaRq7 zmxyHH{yY%Cqh~V}x#f|sEanEzWJo+xhN;wb7SaTex`Ki9XTp zrqL-8K7UY&&O|hEfR)j~b}#tKsroen8;nImI~x`DgbKM%02^QYIkd36!dXW4M)_bv zqIty^3LX;4>>nbx0O3&S_LD9_fh&E`y%G(ua+EUI5ssr|#99c7{5?kQ9SwjDL8_{X zi<|z45z2J-J4u8Xh|i$}ga(WoK-kP01m%$|D5a`Bf+_@}*kjQpVF65f=^fPZ@y(-kdgQ@9E+DfIg1?&CMa;cR6%j9U;0(%A5dMX?D3|_AP zHnNzg*}BLP0IfQ#q3KB_$tYdZl7@g}j}#1Ycb|s@555l$f9O}m0LM@BmC{K~7x>Y) z+~=IT-*_3lBrA#_<6zzRJ!|J{d{Dv;i0vI)aw9 zD%~3o$`tT39l%sbFZ%mpb7S3tc#$+{Mm>75xoP44vh=kO!u#$ij&o8B za@(!4_C;u)RscwAaOvCY@v2i^?AxHrWZtSjy#o7dD=}g3MA-*`f>jKX)88q4>m$h%^Vqd@g{5Q$)fT@9SR{=B2(Hn&?$lGURs@V(H762B#yL0t zVpAkAEv!r7=6rVpNK^scx?r#oAfiUZZ&2LUMy-aikJ>QoAfq5<-`_pZvrN|@Q>oVq z=@60rMwQ3`Vj&R9vvF+gz{Pm~@AE^uF(tEt!7({in+;bBkSy5*obs7!1|cAJE=m*e z++S8G9fHW5DuK}I+X!Z?qfa&{iP-UZ4O-7PBHM5cl+5odvJhIlO!vsVttl$&O6=wYq&& zBYw9;y+F%YZN&JTo!{bn`iQpzm|~-dJ)2lAxCzUTB34B<&k^dP>veL!b@eDT_z~up!-aLY-g~Dg1 zs@^qCfa8f?JOmAqF&I=NzdsKPfu~6i7~+tyXdrq^Ww1ilB+KA?AWt>hPW-Po^`+94Qo`EVgT(1 zu4U4uYX{pS^ia}t)QURg!g!fqA>Jv2q7!|S4OKF!gpTie2%?8fy;>Gw=aSNh=*8gk zFYyi(({`B$?}PsE`zZ2)T};-kWqaafL2VzoO+41VD>NxZ+|Yvo{}y`s99Bxw$kVfo z76(z}z*0+4#39Y|b^84(>hVXoS!;GG3wr(tE-wy!6KB3OLNTQL9v9A)rWwU_tqPH& zlo#yoZZla@Jy%wp`14Y%6yCax`0ENHDW$$%y@m5R9X4 zYIpRaB3~(b;-iI#`>}(AhexEzg`YR|cfi%x9aPEACM_54KU4Q}plPNt!tTMHL;s#Z zI}j@(JZ&$=)6S_SO?vXP#sTIjQ&Bu5TPY1IO5AA{{_#<5Y1&8-44t3;;`d|1v#%_` zc&}hY?4IgiI)14d`)VUPO(GR=XEatHhJ0C+O*+qR;$AzO{e*}m_ceXiRCzZrlIOv6 zCtaecOEmE`xrn-Qt=T7db`F1lGodUyMW*%>k+{(#%d@Z-m2DneLGJa8BwRapl@rN5 z&b}~TaBe9$AYh9Z9mv%xsad5d^xT<$1o4SDXE*6E7ls&Q=^zALCat>5tSGMCumorg z4i+>?!avL##52)8okq`r-$e&uJFF8}VX=J6ZvXN+lKc3w`!I3k=1}wYsv$BC7!D!a z;$k70`qz4WG;5galEc3V*@jcmwYrs;i~!_*=f(*6ql}u9XEjpds7=y$q4k|&Z51|# z)v)0SEQyylOcicu2sDrZKui>$OM4U*G8BXC>R^T?%JvO6bHwM6*~s&01WFE%lJAg8 z)DhBGS-p0hDR=!wYV8OO#T zk+^9C&7cU$@E)3l1b5hT1+{=!^opo|c?W?~F}d$&v3I#gASl{yWoVEJ<5&tOd!u5Z z9i2ID!=1G`$g{Hnk1h=*zp5920PoVlRe_Cg5pty(9bL5lQpmLvmkiO>wDU7l^jYK_ z&h_lg4;_3cwHdi~vl$j?((UlC674v2!D|bXmqL-f@KNSICS5?+HvCSBHe2b`(>6^C zt86SdFBmy7fVz8`# zit)pIYOzSG+aHYFuym7!wGt5r-%sB0C5IY5s#Y#sndk4|>cmSN8G35hA;^+0-ebn) zE|dgKM!*_6?w0m>p(Ggh5r<1vW?M@A){1V#;N6RB0efp=*?k`xo4%36)y+r{zj02~ zs=l1qkCl@MVUS-?%E*U0kKnujqTf=htP2-SG$?-#R9B0&|qvqGMGwBweyqxTPkslAg^1d z?OuhJ)9{&vI+~2Apm4O%rHRD$9JC=nv^dAG-Ea9J8N6+%Osc_665TX21}-```$WXU zf&h)h-f6Un>UFOrFq4hAHwcodT!h$|xM0jHmIfJN)u1os<>!qUpD8rlEB6hX2}^e? zX)IuwC_migLiA-*YsOH94hVn3c;Y=Vuxqxhav1mwp94OFbT}5j)~C)V79?-$e>t^` zVtJ?QZm!D}4{yQX8ukBzn^vEUOOkT~#LMz@$eJ)WOV1q-k$aXuUj0Hag_6{_9@5`y zvAZ$;Ta0i>`CsM>_5#t^Deo#Qim!?Jmk2Vf-5f|9T@+N(hKXtFCfm^2gwjetCMhDHPYm^bPDes&!*HJ=5G23q@n!KFh7#@bq!O8 zVid6oN;yBV-bOz1IJQNWg^HS34ee`qk@u=Z_d|N0s00DUBIo>!;3D6HjF}zx5yah* z|HBNf>B7z8fk>E6jeITT6wpHZ_qr5jJTM$o!P+*FSKm~ z+9xkwHnl93PC^D;sqlX?^_IdoLX1?R>LS@?Jn+{j@gNH6Qa)Uq4Kwq8OCi;7R3ah3 z=BQU|2cSgt?$?_EZ*#xI5Zh@0TFf}7u&%J)i;30&)nuXevSi(74=BP-buE+F_jRYbV-Egn|3}VD`Fvfa$ zWj>-=hx{kEbr5^*HJFdMKJ?kRZ`3vCYjKM`7j5(_5l1%B;+WrvF<+~Sxs;>a-ZL2C z9Wpscn2g7TL*K05w%sm#KrYR`OFU+~z|ERFsd6)oRWMt*K_G}Zj(M;=K_gLU4_UJG zl9*sUSXFG!vler(-E?Y(y)WeKZ2>27N&K*|@?_Ac`jtS-&Q-9_w{C@@T#^XoL~QAoo0f)syA#85*CoGe9{gT7UkhOXHn;-}nu zsJ))DEIBEf?$iL7oE4zmZ6@VEXSIY151dv6$ynRqIp%pfIgZpf9Nu}IiDb??5i#Uh=bE$N z=(-P0BUzbSybR+fok|(8Bt37Xp=)m7#X0~-ui6ttS)+jKymKJaIR_V%(|<4D%F7 zh?pq4U1fmav+TJQ)o(Gc5HK^jP^JAjE)hFShQqF5lSq6aphCuM!NaG@JzySzR|7=z z6mqeZt_*cCMg8RI&2C4;r&GVMUOSq111ZxxLfPjoBw?56o|uQg!#3d2wZT7dAM|3$ zGptkW;cNsdr5wf}1*H96%9j>2^#@!A(nv%(Er;LN5}|b4Cdp>qh^1AYovb>3PRv0L z+gjAMF?V;Bx)JcSDp-7qw1V-h0y4F(!#+H!x=(awJ3*Q^4a!K_?CU4hF(!dLxx5UC z^P_EU(@8HCtd`?&?nk3Uj=6XXzhEm9wp#X1)7za-mq<_KyO0}e^(;Y%&JxMky;|sC zB0!I+?}E=0CjM@B;iE2V$COC>F>(!7j!7dJ(OTlGNE(49R&3Bi7FMfl1IE$XbqRlx z81J^CX5$6$;2kol-K@?IClT?K-NATr2bHLkk<`u&XGgmVhzSm8WbW6>HoW51v|Zqw znG?R;lq0==_ZnnEl%U@+cvq2mRaA5l?q^G0Rysf>F!NHLU?<;^U=DNkm;jocIE zZPm)Drx%zD2r($vE*(*8{`{~${x)lJ%Wl=Rw3p1KV~e^WY}eQ!&3h0C>H;D<60sB| zJn90aL^+U5m3jW7zSY)qCDNYHuEa)4Y`srHL(QC9t+|R=X$d6r-TPW=a8#&|+_^z$ zrar00&0>=gWHexvvS$YEw4~oB`3=hJX7?synU{YCWD_>)ksCedRBYH~Cz^%l>X=f9 zJe43QzdYrCVl_F=U~Y}G$YJU z@1a?5GImH=SIm9yNt^m7I``rif((G!ZzrW6pi!-sgQ&gKZYXYOitChWP_s*P^Z`l9 zbJ^6UL_paQNY0#DCt&f(=M<{B6%)E~z#+(zPMwab>iHk&?leFt>P9p1b9 zh=bK@E4u|J6iS8=Yo5*i>?5gNIstcY4}pjn{)$|{CDe$}EnOB|+bA2>wMcQ~+6Yoc z=G~q5L8$T;6G)^od~gl8#8Qi$a74oT+3$0+*(iPFGNdvm9j2ST#AQVGwFbfdhA1}X z8_wu+VvBrgAfVMm?iD5;tXhT-`=6p&hSW%>o^ZBMI%Ee22$gr%*0E^%o4kTfjh|c1 zM()@tHB#85L+8M@W1BI?c1biaXMokHUQ4e$tiBr-eA-Ip*mglRH|F2$5;L(WH5`Lf z$*rk+G6}y5T3bbK8RtG36q^dwaMeC1w5l44MZ$YMeE#Cs8`X-g4oVOr_)334szk3N zJ)|q=x)X^C2CSNe0^ao8-(GJW`TgKt;NLpy_X>2Lp}3A8vJWKj{_*lEgqPBQDCM3$DrBJN8bj;*$XS}S!Q5RYjs9efgls~wq!@e=iTwljkV_T7`$ zvx~x5S4N}i?xq&sYa6Uj?;czY2M+=%j2Tb>+pMU;GmHt4A^g4QAzjBk zu?@$TE|GyuxF=SM0%EyQu}X4{CJ;nf3mwt6T6q}wy$|T2J)tB65b@ANLtCUm=?Hz$ zjxyJKL2@%KGl)q!2B75c=pL{U1J}2K_2GSnO6)u6-m$W#bH^(abFY6B!lmLp^s4fF zLQHhSQe{vI-$QOC8Et}KuipyJfp8+BiJOM(X9~401JAK(TP??T{GKkB*|`x43a%1} z_n-(^(sk~6NKmA%FH#+!dLguS8$J*B_N>w_mH^bv?VViCZ6KHouyTq&meQdSb?Mn$ zH3P*=Nng|&K@GWWc@VU%=sDdQHJ7X<-Zl*hu!}tu2#bEBqLLPrpVMi0 z@2gR>a!(P$lIsXuNf#(J%@s|UuH%U^T zWsX>*^nQE{bK~y1?&1xG!mf!x`#=JlHW!aN=O&{z>eDohzK_Gl zye%|%E48o^P;*Rn=WJzpSx}ir=ZC@S%a2MFk{@T(e!usq35J`r)sT(0S3VZr&7zX- zyt#;_)HEA{-%bgY&eobsws=}Vtm;}gHeE=1q^q|qpOYs?cYw8$mw|o{|Nh-H+T~V- zR&KMeSU0sc8TjyCtZSCGP^+5d2P6ysT8Hbo=+G;yTWjn=Fcj0tr4v@%MCeknv(_YN z-$?1OECM2Gha-LHu%~HdfMtF~NDl=&2vnqEAZ0S^5WVF^6suh^!TS6-UjaSWZdMbH zz9!Q{B949T&kX0d34z{Z9{SO)jtOR--e9h)f~h-CKRrJRS>lkvu&8WjMxpbW@QSr$hvk{)@$oBV{)4uD31Pg7`Trt?WaAdDx(vW{vm zL7qZBrwJZ&Kq07sl%>hr`RDLFmJX})1JHBiUgkq`giiy`4$hNM_D&>t+6{`VTUN|` zi@i=#TgPVYvY_r?$KL_1#2q;V0Wv^t=QCT(vakPiS)~DcIjS?e9h9fMYa}3FtCbSw zFQak*xdQKuRgWvzmeF0ZtVog@I6E2-%Oz%9euMAuQld`hFnivLs28$%iCxGr$-5+c z32N20d5T_ArIG+?a!apueEW!w`QYVbL5FcW`Wu_{PNNTac2T*X)3kW%qohT>+ftdP z(X$dZ50UKY8<|S955d?`99FutOiu&|gK2*}^WkL~s=I??HVw5mP0(}!mkq%V%CtbU zFzz(5){JTk5;wKrV~1JvvV*$taM-legA$T^YzJk|0j5#r?x-4mUQ(2donOl7!~>Jp z5%I3%kdbG~?U{7w*npw378L!Ysc-&IpsE)iZmQtUjyyDGoUY=zAfb12P9J z3=S6Tb#Pc^%fp?1GJdHBpgwqeS?3lfMwXo{3GnFbTsGrgMCWke-ZD^7%`yg{T0TH& zJpas-O(U99Xb!Q4fjkur7^fLla>SM-33@}?7Ti(raPKz189eQ*ZmyHI55IR<4APC#HQIH$&P;YDf37_(Ny0s$ za^&>c&q)GNefs;o=2`HuEPq@ha&8Kznaw@31XoGm60>0{z3p1ftgHJ*U*ZG#>OwEV zpI!i7TAPW=yQn8;TVM9beQsObISpvcUG=b3i$sL`{LP6EW?pHXQ}&L4q>#gKaDfQA zHihq*ml|O4XTMA@hbW$sQOmqj_x9Udrq%Sh7`rf4&y{dKGJTfsR9B}?M(+SaK)k<6 z+jOP_tYkaDQZC*Y5IYIjGAWnEW!q=Jydt}zH`FTPod-fQ<{Hro1h2!GiFs=ug0fV* zzobl2b3YLbBXG4T{3upH4q})I=4`SD8I(k0( z>*pZoMf`rEgty&gs8iLMRggQF>|J^ry*5wG!ofN;Vx|yoI!w>lwL^o|Gzq1YJiiYo z#cILAmAUTWO89?Y!Bo-Szj zqcQtRJBrTwBXIkPpPhdtI5f zmEVK^HHy8Chm)12nDO~)G61&w3$4()sX>Fw3^Z@eqnqQR^#bG+vOI7%TrGT`TPyUOEmTmiFa$Xw8C05$r}_VyF7N1L7jmPjE~3~WXY z<~@!{`3fA4R{pmCbXq!hN1pxA1w>hdSBtQodezghq~}?$k4on5YAtdk=g6;^D+1O5 z=0U2Rww;z3Trt))#&dg2QPC7Tna)o;cbZ_5jRvVqdy%Zqq)ZQV#qxhhU z(2NLey2)hfdkKbi5Gg~Sz~Px{LpDDplosQR#@e9sEWO)add(%)1?Z>~`H(e42z_#p z;6K*^c1{i6NB>2RQJx+7eIMS%s|Qnu$3wc=@`IcpACjYMu7+J=4ZE^r1KqIn@!K5; ztQi3NboEh$v2N5L-X%vAsiQH+!DJqgG$-=+Z5WCXbRt^AUSPQ5&3Pj|sn7Hh*ql7&~@&W7+>fDi5; z4YbSRu45%WoPv7(9o9Vc42S!`{UEraejbpmXbqIQW+-Ai{NKlfpD96!B$>a9aOzMe zTA*2wh#?A^RcNqvk4(`B*oe$ANfIUF%fv~Qo72;B;TnhXOD-$XWmz4>?rw2dnv}y< zFr*|-^RbIfn=K#}h2td3WQ9yjSql}{dcL;`_d3$o)!zz-`9> z=vB(bj|JC(lqQ==CxqX0u`Jz4i9A_qLg3)N3_TRAm`&*_7jY9oRf&Ogq` znw%nb7K)H=l1=*`9=bgua;bR02ImB|S3#pt-}Nu?ZY%ZXL}2*e*NUhtP?tl%Mos>c z(~iQL_EM$|SrpP;n09WqN(GUtM$jM;#;)$Zr{GM3`LjbMCTl}^8>#|A+|Tzclo(`b z0E>O1&a%D62Ld;G#+-^#5dFqgE6q!o0MfS>zMR@n!DmP%4W-L=MM(SeEC3Av_xYjmao+IE`pqu z2;Xi6jPL7Ty+kKVcqNq*;~6xl{Zq_C`HdGP3y^&5sE)Il0D;K~+{E~>CjXBJSTpSP z`NPVr=pN<1hdnL#+oyWi`}}sW5Y2^H^jh??qyrwoz^f!YLW9VYKQK2Q&KICr2xtnG zX^Ax$*R=o)B&>tS37y0tcqk|VQHB8`&8JUh;ZxT{NjJQok2?ofNg_x!s4Z6ZL>DB+ zNE*KKAN?6Qj%~-lG!C%jEbXNO{7hQZ`2iMQMCyW(uyv^T;YH)oghY6cjZ_}iv{KsP zpR+{T;c*{UYwjNqDIha~OhQ?9%$`>C02I<_p>68dmQ$?+nH~@zW!5?I`3SCpNTzyA zfhdmb#x#{)sWL?}W1imy6?yHz!`&4@dT5ZLBv(^>7qL>YAZgSub?)cCYq#=|0~lPR zESpB5{V|y5NWh9f^=s9#t8n=s1Q72Nl>zZYEkYm>+pn-|ycZ%eE+ma``@s8_4BI3xQZ?yDaE0Fs2|DQ|qhrJ+{)hP8 z)kgSDqj&KGl60RacXLb*tkZOPz?ozBS#UnD)>6$GogtiZ)*>m0n*>-<(%_O&of+gw zM2??Yp1H@k=D{G@i;o#aPX!``;&bZ8uA_Um;ri$v|9oUDzahX{Ynh@{0_QoUxN{l` zT<}!c5!*`=?Pwc`l1>`~Xt4UC<&$?{_48%z=OPqqUp_ zuKAf(Q+NlB`afc95m;4Pf_wD7VuG@i$MMNYG#zgxaVK7md7cJ7C`!p9hctuP^Px<} zM|F6%j;?Fg#m(9L-W#^bBCwUU)Ry>G0>0fc;UgP}3KfNHi%tzm#Rss=)!HQe8PPK3 z?yJl@anROHfKTo705ele@U4pd>n_VK8+DowbFwWcoAAozGMlTyJ8Fo+iU@KlntkXf z0EO?&G!Q(~h^AV}!SpyaDM*99pbz+-aTfF9 zd~L9c#e&ufNn)br2iiMNwTtlw_(VU!lDogpjsYcgH(C$2miR{o4&nX^5lTcbimaE0 z)lI{DMk{|tTZ7wlv`AM;%LM@eQbgmbxWS+=4`lpzQ1Y9uRU{x-Y6~(BVw93r=$N^o zA^S}ZT1;8>Acb`o5cIC=LdHrIsg&06u5SW`!S;uySu;D$%Ih<(US(jGutplP-Hjez z_g+J^ZyMG%);FHrIGA(YhoK?(Tz2w#|A4ZZ4*`N12ixO?ZbvVKb_7}IB+KIlA9W7E z_!Rf-D!%>g6QUlsU z4~IYhW)|p9GPcBnHg%)jd53u=jK+u16`DKGDf+i7M_Mu0U<@eyb{H znXGMkmPh6i47M(DmYPvc%JaMK6<*6c46xufu~06Rmdflv?9|3>*P&Vn;t0U2@Oy^* zrN!?ExUy7)Sz(vvqv%_@#(n52-3~^CPLfim4+QVwOd9^rkU=Z4L8gP9r|Ky2QI=a3 zk7qbHocim=PneN!c3zjL_+5^Pl678QvQJ(RVEJI%@l%#WxW08q+57l)1R6#t+tOm1 zI5fIOlxeAF@sq}eivzFc5_a)XTCFQ* z0p$}xxJKV+{tm8wRYohBrc+{T7IFCGeS@dciTix^m;=U~7A)y-QPvq2Nzl0y;lidB z|4eT370jMfmIS8_ew{XLj0ib6Qt0jlviG^XzS|i{0S~- zZO|zt_p)uAO;N?_u*jr|efb%WNnQJ;F#!0$T8X6m`*H+6e42mF527 z!w0LG1t}OYvbazD|1Djmey^-It{n?Pcju02BDU(C%emsD1Q=|Hkd$XdaFmEOFQ4hi zaQeJKoY^NT@_b$Z82_v&By^!9eK!Q_r~73mODb92Pgyd`V!}fbb4&a#Al|9YCy>pY zW{y7(_j8-U+I@+;dr73P(Lf7+f_a?N&~1h?3@ z-tpD%L9c*_BAYLZd`}CFjUSy4nf{~Teek1V8y4&rnd-1*ZuD!78qth5;fuDXqX$>s7y@sQAR_`w6Y0{j~6!GfDG#2 zV>~|=#XGqAEx}c^sd9l&Ad_v^2gHKBi%fWd_wEieVL*I$=Ow6UsYBE3WXYn>hWQJA zh@o1SPT7T07H|Ns)B5V}S%1yDN)qidma?anI6}*PGrXr7<0RzrSOH(u>Xlxh+D2I> z@)Xj|#z}GKE|Njvfmj|pEQ|5c6>-aURfBpGuMtCcMc?205h=UKbHHJYJSFf zexJ}=610u-B6By7ngQ0NSeISam7AY4xh>NQf}=l_-CVp89{o{KlWn`Pjocj>Nz1%{ zV@zP`?9|KxDYtFNoxHZ+QHIg&_9xc}P8fdA3mfrLfH1K}U z9>nk75#L28EYSnShGdb4muO$L6r+2F1%~gZwxU*gj$Z?3KzvE>|FnUxzCgf)=A*sV0CZ_nzx3 zXlPYUUAK`2VcKrpMzp|y&gbbUhKOUj$d#i*}B0RPRpsh2tE^QmL91`SlNFXDu2>E~Qai5MXKT`UY>sYWt5e zj(*la%Q81`4s6$CSBIAgfXr+}Ax1-6wyJl6WVp-)<4VSYv=shd)CARaNCA=SKK;SvbfUh(R+-Ia?OE-y@*5d!c}3S*qWh z$_-@KtF4phk08d6C|DeLNDx{wum?i4T+Ao5YXOu6Z3ujkc>-`8r_Fb;^HoCu@? z3?0TD$EF<;D*PydVU|q&_4`XaE_e^@IJ;u}aXz2~g+q|toN6x2PBqw^QKqIL!d9JO z2#lGTQ^CAuFy!3mF9;c&x)EdwYa(A%TZCtm@}QiD29)4!;XRqWgIU3O4OS=gns1V9 zAW=r5V( z;mvz?fR#GqHO>5Hq73z**}E>>f7NYnS0GNx3eqVASR5M~7OA+2CxQEh@%sCB6{P-g z*jTq>mfbdkIhAwKX{HadB{n+nK)UXGIP?}F^M7Bv8-R7zb?UDsg1^?0=MMxn@!uGc z+N`hcY5BrZb|$=^h8!8;0_HQAjbjcWkm;4I>|0OX&TbGT8g!ydM?v5j%H`5jA^{u8 z=04H2DY|?>M=-Cc`ktId80OxKwc1EE0LWEwqwdc+5?eGd;Gjd`Y-3K;(x=KXmAQ+9 z67zT(ZJj;?IA2p2y5mA?z8|@%t$x0N0i4^t1yy}Sf=))XPVLsLq!v)#JA@6^)s1_^ zyj?^J^p{2=!8>w0nvc%A5!j5e%K^&ZS3!u+s<5vXIoJ$#1>v6`+dPI;Pptk}e7PioPI#&x?Y;vs$l{zuzk!Qj4-o-q(1Mpj}JWP2=^l z+OoenrzkHvIlZbF-!pv?WX1^IhUiSINS})!iJSnDlU%G*Y6ejvq!@Qov3plH?tIAX zuUQdc^qdb~XyCeG<6kvmSMmoXP}L+l^_%KiJm>J4c&7Lnp6w9C*l(1>6$iBOJ1y8P zx{wkgOQi{etW&gxh`gub!w1<8AC>d0gRIq#Oxsf|KqbPf9jaq_Fcr1$_?)<+iQ*!3 zK`RUBYW*GpaiI8kmc<$9-qgA_X$7E$NLowXOJA`%gj>eELZ`8VH(=tnb~z*SW4+bt zo9QneI|;C2)cfWEmibc21n%b*DU1=UgRpad{0DZjFk5)(?~SjtOw<#(vYIpw-EZwa ztnyruD$7iZ(0E{IF4aWaJo;CzXf{1Q0T;11et^r)$oMVC;s6BR=1kO z&2Fh26_gVG`&x7J!RP#I{5)h-B%(Ks$QBf02}6=_GB!n6mWKcgoUB-)1Uw+qQ?hq} zpF=Bqx+BVYw?jD-p6psVylr?>qbP#XN?_wbxw-y8Bs zf9l%8Ts0BN_)AV18-FAIFxFd|IZYZ)Kk_Un=Q{6u6^AXDIIlO-@k@2_ljqGS&w$@W zc^dl!Ju+W4!PKNlxX2mLH>}rKa5k)E6Yd`NHm>=JaXZHG_G%wDm!D+Hq*0#@`3dNWzj*K>8LjD@wm z0}3{y(?3dZL;4gZ=_qar{kc3IArgqg%E!yIw@`X zqGcwQ4J;8A+kRQ({nV{=Y^nYkHu^FzRfJKHg<88x;|&IzF9L$>K~V2c;l8zAr`hQi zQlpKRKk4wzw2P2Le}6sE-`>+#zhW5+Helx>V>n!aUJ-d%R!`qfkNJs1kK(pximzfl z1HW8T0CqDeG(B|?KFc~arvc2PO;Sr!0+Hp@?lV)wP0lz8@Xb^kV**g2IMLF_`_bM7 zdu9@}uG}kchM@t6mS4mCLS+Mc<1WI7gbfZ4_3-z_gn~U$eb8shVv@RII)cUvye1$& zJHTR*34(2=E3#VaVQ=L)iQr>`o{57_22E{0DS~$h_9Vf6_`G#j2UwWdxo?woQwyoG zEToeFr6zQYWWTdUXy(?thllC3K5_#Ra_Nwbu^TK=gXtv+oIs;6hfwOW1+g%5(jyt? z$3i;e)@;T0Bx|PbwYvCcK4vg&ur>8a2UBh3lrs3@+UI8A>#+v z4eQ5(h)f~%M|Nuhj!zVxdQrLY6uNC)?n7>QgI89c;?VVZ&IG5OIIzzL~Wd%l;s3(*Pnd!|Ky0p>B#mS)J zZ-+j}_r1;LmWk(B+&###TnI0&`gSv zI2d=wTs#nXZPdRqQF#We3-e~P&kW_*L=1Zq7tI(&mmeLZ?z%Uaf97f>t?Q8NKp=^X z{Lg^{Lv-O}Jj?R@IT1?NGkKRHFqHDn={h=iM@`p~Q|a~n&`dhbLdWAR&PpV&>wqL@ zXGtgEt|=1(w}`UPgXxkmMS`K8o{lhLRf=f8BEZ^&J%B0{=J zun@uXNKS=+TDKw-BEq`+`yN6SBt=E&uzx^+g|d{@hCh@%x(gMv{Z>nKU8Lf>yQIw0 zgF#j2Lk7AlNkE;RzEe0k=Y|_A@QR6XM$Q8!wCOz+Me%Sn=byXWs20Dw8DP@>VW*b1 zTVG&%f_M4{@b~bp(PfCma%tB5sLPbNr;`tv*S1NR61VxIQ5VCD{p!$&TNNE}f%cvHSWu12qk<$d5~SBwerV{HZiS?4T;_s%*w?A`wgNwIpy^CztTq zt{=lr&6LT zi)LVChPX2z;8@H3w{;|DPfhL*iJx|{It&Q6N6+UZns^*bI>K5 z&>ftr+(a7Lxujm^F#dxC)bydi;i6-~3+$1T!3x$A=phiVtwt*xp7X=luh}HA=Gf+n zK;c)VJ#-ZQHGlHW1)-bEN%5StRf4cV8rD4|9y7 zlEa4laYCE-V}l7t-6zab%x}>NigW(M!4e41$i|H4QmH}jtHb}P(g@6|#q{f98;oP) z*^}$k2Hl^FGGsm4=g9JnS7Y9OmjoDl-gs*5BlAG)XUHMB^3~&zrXVP~@{~V>z1TRl zyJI9BkuJbzyvfpkdssT+1_cNX))ha#okQ$(OvApD#7*z}>CIKQxbw-!UH9r>GkM zQEk{=KX%?RxKz&aA-*Zb2u;`3az1^?^GWVrN)n$-CoQ?q+aUD0KmRcps2_J!8Q<`L z*wk(d@?&>RF*5y&ULsR$Ab;D{4mwpzu+&L?ka|3AB z_xGCF_n#eqwr9Iva0EjMMzwFY=JKAR`dAXASKLyhDt^U$@^Uz|tsk3RB96sRfe7@L zvaAf=n_r5);LqmX+(p2*-&)gC>smC(MEb&Auul})W-j8ZS;VE216=;Dy*hz(5kEEr zM>h8kWcUn-6XDjPM2|U1yPK+FUB+yu%-O;CN@#{bf>&!ftt|4FDjm`pVR#P8{uI(FZ%Ck1ZuXS*R9qt6 zFAYlR5Xmbl0&}YOUp!-}h)jiW(XZKs)tz<|T5yCzkJ*y)vPg_qNHrb|rw0foDtI{37%(YD`oSw<@U_W+>i`SwAK8wZeBvS%v zqe0fQH^Z68EXKzBa@Ov>U}mi6-=UyLG~Yz%wxf1b8t(0bfQOVTQQAc^vaG7B^`7o` zmO5!{YFcUX8O9j_{&HCczsW=E@6dQ*Ev>B^v7GmOzWCEDVrG`c?8oi>fZv&TRh1=W z6i6LDFda9U(nq^aGOARUdzqWxy02%5#!Z{3(ZkWSi7c>uBU$?gOA?Klbl7am`%~*o zv$LtJiv;@5Me_G+O*HHC36U)Ek4(9-;W?L87LXf2`74M5=F=Pi1`xl@mytSWvB=^T zA#tjmlsH)MAL}%}_QLvQce0}HR+hy(B-&Gpa=2vFxgu9C>3o0koUj9cUv1mhWO z9_Jclk;l`+V#r-xF_UtjB*8drMQcs`>vqvG(P)zAr--A9)>5zPhVz5y%WyBKegL%- zk>Tf_)3K&iHltspbs2WPohle@y;n1}rrk@lmxRg@1e=Gs3USxJU#rod@FkLOtx{FP zS|9d$L180VTg`O*37=y+V@ROTd^LC3be3?>)5nb5l7>q~YV0G)yJtJ|5Uj2m_1@dJ95J1g54JUnU?F%4 z=@X^B#uvc+u#z905jwHJaT+B2gx36~OAJ*d!1TVjY9sPN$0=b6i^j?)l&{Qm*|<}7 zA&B~>(4%885nE@N9T5WMR=fPngAWn|ed{U6EM-1FiO{l5A7o{hgu~eO49s1K^M26< zp-^GomIn#ZoEgTx;NDb8M=Qv~u(+uvc#LX~W(`Z3DudrzUx^d|9Q+%{F1)gQfeL^# z#1Ho#C;jfAuq9+U5TO60*=S|wUYo#bGGzCQzMKq3=-D)rbXAP%lPs8YzQ~e^ zpv3%L^q8z84`d*lK-fhJpbMH$9}m=5%A(1)&d*FFZC_y%=a-mQ{L6T3HJ=@=JF=U5< zq5glgu*&a)jJ^}BD-Q-vJ|eN=q@%*?RPU9<$^s)17Z4!(ESV@)zIxw4O|HP1qE}YG z(bOf`6M-flQZZf%=s-{IU zLrCZx0BS@?($+T%2epu*lD_G)>vYtf33?(nMtFUQj|$bGP7Ob^;PNBwV%! z8Z{%wIzk~K{ImNBRlgIgD-MuaD-SU>7Mlc;@wFQ)t-?yg(3Aj+L<@&Lezq)&f0~Ph zPcBBbqSOsO02KJ~?>NxxphGZewc^KNg_a9#G`wi=2(N7n?^>m8YQ8o}GpE~4aa?^* zU;UbpK)cIa_CdmcsD+>VzHn;O(P>+EpC?B|A}XrQhcZjWEAdj^6eVQ(-@OI_wrP|U z?UGZdP(WI1HF!0d0wgqiMkkt!+xINgi;r>&l%i3zs2h@#GLvKm!QKphr}u~;5S*gx z|1^d=b#i}+5Z7IF@Ya(lO0X4kf~>IE15Zbv$FYP7hfzhDoJ5BR+KcUoE{_ziLBhuK zpl7Jk8@LymCP-R{4wc(`I$k-(Ok!`e&3`i6-rYM$R1jY|Tmfpu3nf`XGr%6oSQMdU z82hx!b7>WI?)TqvdU)iWU_Cjh!g{mB3e^GO^5s%t>|uHl-;0r0nsi2DgX9+V!EMXn zJ^!hgD`12{yb*y%zh>1n{<)!&xetP&NUlIMG(xYB6pv+UHRB=k&DNS2!qVacIynb; zZ9o*-R(kDt7IU-J31;O=e8-`_ilA+)xU3yD=Ws_pQY{MR)=u)GLlK||6GaqTpFDIg zaM0(Ll+-dVeSUCvfw#BW*6O+FPx2z&)>S|jMeJDo4{^|(yG8kVoOowuE@g|)Ds8?$ z{7++rCI6?iMZKaToX*yJYpB$C+xdWwp}>==N+AW?p)*KK_#X#@HdPbMZxQ1t69KjB zG<_cmJ4hP_8_;syH6RA6+I6WWrsHH9O7#{4h?E{%1Cd_bDM;F>(}BkOLpK0>&^TG? z3qE7q`zm!r!|mM0`TSAl!Fx3>h~5d-461VBSBVH}OA}-8Jk<9sNk$2QEm#~j*@SW~ z6q>Pso3>%X;18exyZ`=DiD=m1qM74~2nd1Qv`oYZH)rsvX#pZre-*v;61}&BvUj41 z)}M5l{P%k;x+Rz-`QECsd3JEaHSLCq)l|TqSv5@koC3&zW1=a7nJ!da!Zj#ommH2K zWosV7Ht8gYlp_p33@Ui?tZJ1YsOvl&+KKWhWF)`l&!0OwZc}l1-exN!MzF<^k@kcY zZ&kIbb}hvakf)3z_u0kIlxWsMiYOEXc(xf8*axk%J_YO#%lz!m89#&3VH=qUBYCq! z1~E$xOTXt)c`RW7a%IR1eF9a(tuylULqe1An9T5cuF;Ur0xEz_yQXCDPYucO#Co!+ zzEhriqxawaxHoj*gAElJa|qgyVsa1YpP=DciuLtW7=+AUxukSrYz6f;>lse@Ia9GpTDq zTzO%w#73rbxoi@WBa;dwjUn9wLA2WPHd!&sHU5t~5>ksz$KgS~qie4(ELRonSqvHZ{`TiyBvxgP@*) zO)Ay2=>@Uf5KVE2eo?{65TH~at8#~5C5f)-_8{3sVC%nnq^c2QLriJYAc8xm3+n)F zMA3l*Z>gF(ftI$XB&o6$l1$pH?odr+jb?3HQ^kVdic8FTX^U> zpMzrKci}T3iCHbmV1GlS;Qq4#0pX-z>eTXPUyM15~Kz+=}9j2%J73l zPp9|(&~Fm|%{Fil=Zfg#(TOaN=d<2@pSO6=`2D!=WnTV>JhDZPq_jAXR^ark`(D>F z+)>CL#qUFb?0zk$<(**NcZ29IX|&y89*co15>2$ldxeBLEPNfcrh~VWX`y4Ss63PQ z1IKdy%z6WUkP z2c%4UA(1sWzT@;*dKB5fbERg=$1+J~*eaCCFnosjaUU$X5{2lFYf<sOsT?#sr!ROmE(IAo=ZqR#i0of=-HFMunuG%>HX+YoQh#|0F?r!$ffhjI zx)@rhHClOn62WQMop@vfbL@wLUTWEqXVdZ7@Gx8~#H%nFM)A>lMXdV!^{u{af;1W# z+9Vqg1HF?XX1SyC?NZ~9U4hnSqE+{;Ry&=dh1tXeqYVmK(mYqX1m2bnMWDTX>-T9A zKpapg^5ccJB8;8dh@Bg*#osVZYH-OwP3YIh7Zdb4_$j`xcY<|tyw+W*nhv)!P+BOaA=Ys(>}R~(B)!FgoRFp@)?s4 zO?t&leEXw>LDUk6_J;|i&9;h=gzP|dFGz@(faiR{j)~gw0}%%g?)kQA^-z5)>YrMG zh+f$ykiQpKs%n#13oc{-yQo^e5wtd=M`@Yh=!c|<32mZHiamBLarz0FmL#fTvVn`@ zijgb?k|3;2d`?vE`f{QvRK}8dz*Nlwe^` z$?xz){S3K^KR**y_#8Ik=epiBJMDLAZTb?(9tkHtKAdYL17 z7pCW2(0;-nd|h;%>cHc05vg@n@VOgXdGMarGT9}FAc8~_f{}4Lys1_1Aclt&kU5p+ zqC@uw$U)jOMSst?p@M&3CsfeNo5AEP*8Ht3OK9o~*$uBr7Fyz;OSQu&*rFiP!Iosh zwPPF?*)Kkc2Nidhpy{Jv-=ZStkV-2;zu4=$R!U~rD@1uo^znVS*i|;nkXES2 zS}%AV6jDhL6defcX7GIMtYrJIk?FNELauh>0ov(#zDT--x+6sG$y5*4LnhXiXgkKJ z?y6WrQ|l}X`cOn@DpBM%&Z*dosVz!5XXM0lZ6P7eZ#;;C$AETxMbtApi3>%=e`vqu z#YM$|xl3@(IYrgYFZ6~<5R2_b5Za*3eu60QJHeVcV%2d<$fOopLeJD*iVRyviIrA} zl^RS^DLM+yhZdW)!j8QcPHlXNZVv(}78m|q5@uPf2g>EBm5 zLjt$iU7!lZ0li!n+*q4VG9vt4V-tnRzVkdMh}>?A$c2ffbBV$>DTAsIQV(xi$e%Bc z=Gy^&V?Q`19wmt2B~hdGx>8cL$Q`(35V+hZIX=_F%n0>PtwEe3nO@1>GB)1@zK>08 zEdozw`aN-?u@xWDvM6pg!D%`?A{dHBuoohJzTyOB7ri025VKtQJv-IxD)Is5AzXnf-REc@pjxAVzezgZvQL`sdc_AR)lG)jyL;B|dDxr!0$; z>|>r@d~}{@&r%0+Zdv4Rx8j3I-s18!G*vX{Jd^25-%n~jeOsBPT`PAmb+>bwSZ``3 z)!oi7#NOk8N%H!9uYV@NavBh}npoL%k5sW)GU&mKgNe!TQ#?+mY4U8}Yfkh!~cTAix#bGVVz{#*TsY&2BjVfC%{BJ_F8xkhNRw#oV~s z9HgaA!wK2}1Za`0l0^_SZI$2G`C)iM1WjF-7~SO>{d53|O^qB9gyCG zs4J#w*BiD`O}MyGMR%7BUY$sy#P75T;+2$W*y4MOAOwrQOqmqqjE5#-OW6vY8oOjP z-}p#)eyhGjpJ>&Xo>P|UxiUcW-_8bHh2@>sGbQ1KG zu7o9`Tjgq*|Ej-Y9PNhXFp5aBw!<)Y*riih<;A z&j-&_r`WJLaaf?W0y6Ts!32jAk~8Dvyjz9S53*?uA{ zPLYmWEY5ps@?vJrhuWSZry|Pb{QNgqB;q}poOO5zRbUyW9EU_QQE3a){%Qr$4t&y_ z@d^C7wSHD0++w+70M0+L5Nzk zfGUv*V5_m<$axY45>$XStH&*qfnyIsk_}l@2=?JM)>{$NEb>r|BUssn&ZGBOtGO(Q zqNw=OCk8I3CD5^Tl4`4tRyY0q0Uzp1pAWvCQ}9j_v{uCux0SR*;DCvTaX(}Dw|f)c?ChP!o>0$5!))&(KGH@ z+xZZCiXu~=$1KEfA&i4mE~xuPW7wuo0=7=>7vvpQN6{;#LjbwiNg62gKv#t{nB7|! zfYWV}uO^bK;ujP)DE6>67Ajd1Ki857a7JDs(X1Uhg3(ZT_CV%A<$I{W@1%$}xs9o0 zMMPyQ_1^5)alc@leewJMI`>sl`kckfp z(?ZllMYqeBNs{w>&i8tlb|9mFUFxKY1-UHU4_(wa zQKnA92s#pnkL6-7$j1vyI7DecufEmDn8}$<7-BO5LRQD{EFUIrI<~%~4S>b_`LUdR za9S$w=3C__{sUjaN-A#SiNI-IG_IT&=_)s7z1c9RtS(d;Hsk_HcdG`i@9Wt?*hb!4 zl?vET>Nsr&If95EBzj4;987AN!+{ZNyX&)N+rffl=fgTUTm(2K;`lv>rdfC6B-Uo`yAyuc-7Imx1 z;jWOhJ7X&RIf$j_nU3xZ3MnzDZzt`J^3#5yz?@-}UO#uP>ewJ=@jHWRJdl<8%kY2hcQsZcM;K>CcKf+kCN@~qYr;5u9C64F8ZYP_$3<2&Y z7A8Iy1Shecz}r~(l0n%NqisU0?MyD98?Z9xj`}$st3t%{PO8U`eDQL=kB_))a)?Rj z558n}-)$1?-1TRbAzMomEftcqq4DE}*h_t`eob`Bg~47hP9zV%{`WNWKio0_<6ujg z2A2j_p9j4P9orTaKT~^>HWZURoj{BajIQfK3pCFzM{e-zpksx5u~3U4Tenk_%QghE z(}Wl#GLn)7V4(vy$KIEZELe~r83}q+G%bpdq%BpCYd{*)$cyo^w#yu2nE!#7Vf?nB zyQovlMEf*$Bk}z2-*1tUDaFZRidsVO0Bc^SML$26T8M-!TRmQd%W9LDQ}>g_W!Lfb zObfN_b70$kv?)1`Xdxnn@0u2e^%f(1~0XG4O7Xs~~*f(09MweuB2r?uJ z)^YV|BzheFQiV8H4^^{aa87I*rvKl%>K9oh2v!`~x;!_WL@ zx#VU*^+F~1JR40GB}_{EQGdix^ncv%QFfup0f_k zZ!JGyXXFx-O_BB8sQ4}(KK8m1f=#SeCa@MdaxMa+U)t8k-Z9;sWA89kZ78B@`EiwQ zLH1M8dxPy!v=1?`K^?5C+a6A36ht>DnP{^}(j#B5s%E50?{*TVR0ndBGe+?7{r~g% z!J-d^puu9cKK2gk15Ox|$!RSbPWg)<%3P04m*k7-sXZhxD4szl8vHwb6#oS&<=6Y~ z{nH=ZrmVkPpvVNZAXoUAkCj!)09I7qr4XIS7L>#OpOcpA(^Zd|r zV#E%@lB$U%6J$*!f+*_Vwc3W*Bw*7>rI)G6ux)6NMYALALqS<&a}+vJ*tDv}^+vHq zmno~GN`s{hId4&-C2Ls{U<7RAJe^AlHz^g$ZpE^xhI`@r3PNvB-$?jhh)WMT)YadrV(F6 zadhF0ol#v-2BI-*nA4J{Q(^%1>H59fWF2GYoXwqwGo^ptjTFQ&nrEp2x);!6OZz4F z-KeJ3s?^Ev&4BXg8MUIMKb; z@zE(j1Mc5$!blnbVt(6(4{2hzVjI`ZZU_SR3kh?RN#R0dE=eZ&g!v)Vs*N;CM5`%h zmI+l^JG460WCCi1D#*keSxNQ_MUa^0D(Cf!6Rf5SndN?Fp9eDaZbdp}_H1g(gD2s* z*KU)4tU%bZOT)s&_oID*pTT`J4N1yWo7V@utS%HiIEVmOK&ZdtmYWD<>K@&RJ&0Y1XP6Xj^miO9v}FHDsS-ce z;|Ff4oXn1#%3JS0<9iN-;Azwy`ya`QQ>`Iz7EM=al=N95d15j{oua|I4=cI6(y(dUHV&Gp*j>YS9dKz{zvfyFEVAw_}#ncrCndd=nf|>&5XF+$#P_4u# zK?4d&g-yjh@?x@)PAl0OPopA7D;ot4kzHtLH6T-N#XyYJ|1+|G{Ii)(65!Cz)%FG| z%#~Jj4P3n>DuxiVR*Z4N8*Qcf{OOQ5BLTW+JF3%zC_f;Zfv-qw zs39#O^_X5ulRC=-H|=_))~T>*ll(O;z6&i*oSGBcnPc)R8;aXX44yNnOgW!E;lcg~ zR~bV&Ufl<5QkqCj)EW-FH06_vUD_amOKxo@@zKznZ?*-~;E(y!Ju&wW%6I5wr#(CA za`-R^5*M?^7rT{>m`Ob}bT61jN_W>H?pdp6F{gaAWg;Q9L&YPCUon>>Zq<4wYN%{7haxPs&9mCovJ>nynn2!F#}&dqhhdO!F!^=noGGpUb+3~6FV@n zX<NS4vW@SbdN zWknucUnq9cHlna{#4(-gzA)2r79JYoSUlP~NDd)5(yGHRS*^;b1Jj70w7OkDAuP6cesVsR4&6p^$d6Un6h&q{gG#|m*2YEn3Fgzm9Q zL%V-2tr&c!sZPv~309&(uIww;3`*JG8yTDLKk%PFD{>KROtg;tvux9eRZJ!Vm@{<8 zmJK235S7-I07!AZRUXWqx#(0xt}@X)YUYg52p1hb0|D5DN<`;OMraBbw=QbY1`)_s zMA-ZY1rbH&O!--L(6a%u7Q^X852JP__*+t)KS@tkeIEg98%nTP7SX+x$tLd9caNZZtctLPveX({1(B!=$!;5;wH%IxeFWz%8iM;10% z|Jwiiw`HPR`ro1JJJq&}QDAG$b5P@BpO;`UVXK;R=L%Y)t&Vk71RmJ_`!gkTCf;;Y zSnjpOGUZFQZMVl!nK~piCl_x+rGbS*JBSnmDME3{ zw#K=Mi%$Y=0SN`~b-({Wxd4LvpU>rwZ7Umy0Gf|tu~rVR?4M#dU`v^9#689P_Ajs} z$XDLsr1>Kgs#t?4!r5j`heXVhHcMXFp;#@>K2NQUEa%YB-9ZA!0kC8chK&iHeIly_?Z9|M`3J!;ozk&>cXM|NHk_ zP#0fNFv`TurWOw#Xs)fSXE|fLBP!zd9?K$==>@f!SW?hUR+Mm}8ZJaEcO)~C(2Q3& zE0!b)+EqsIWo4&7TkD88?~9VL%_~eMM_LUka$uP43l@CqMOhx3(2$-|ElWg4WGev* zi4~ye2xi9jv1QdghbSl$FD+#}u!d~vB5-B6`U<{3AcGV=L=_wLvyFRzzY{a;l)ZV5 z#TL?f+qK$A67eO3>_Xd4oB9feWgx}dq^A(y&tGe+<#Ljf^simkx-z6S?c)TK&SaQi zGb@~}w$qC|Ke>HsVuc3PPn`f}7lH$uQ%V#GZHXT5dRnrw-qzAm&Q3vk9f|xbI47=5 z71W<)x^D3aoLCecMrSaV4f$&-Y?*8lk#;#_KMSvH+#N6(403R{wK`EulkXAFY8@zP z!mx@AO%-`I@{vSBSkz76$<0-Cat|0kWB-frYcehl_2)UD08v^b#@Z>mB(%6_nw!r+ z2f)%D=>`J;%n9ID#?D^XB@!gzDR*Ho&h`vZyS8OQP5T^uZ$SNVK9b9(?bcViCKD`h zSL#i}50>pb1U!JhUz=dtQmA9QJ$#ucYC^A{!ktf06?ZNP8aNS~SW;)i$k}Ff7zzK_o6r2v+=BsZW-RCoGDlDbAf4V8f~i&-EUMt4(A-t0rPx z*qO(%Sb;N!(n#o-T(RE+G8GlQhTcwHIJdGZTF3{J4RAD<=|~rCcm_#O9awW(Ci{*#ygJ8*Hn(9C!%pt@uXeIw@yHptj)M4(yHt-_VtfYI_Xw0uNfaS*Gsu zhqa9|)t#c+v!YWF5kmm5q+m#Rx4%qy)>RP=69H#OguPRJJ7( zOHp|DLF33a++bx?O1t8MLIxoEt4fy?PrY87!z{4>E?WeGvJyLp4)E zeb*fxaPU!LXUM&|HRKbh%H306mqglrhTI>TmctqgWOteKDFR)Pbmltwudj-WaT(jmOlGSolZS8i&?Pf{lv=B`Ch`8UiE=j$E#qM> ziXsqQacHl|p&7VTaTP8^bFIuf`8;+=W5H0fN+C}R*a&!ywh={jTn>1&xnu%Ls@>L1 zrUP=elUQx#?+~PfNL_?h<8YWKD%4qr1#5@)Gg?JfAtB+*iu|Nxz_z?dPi*-!e^h=U zp8E3_TUxvDY~uEHNThF=V9B~jj_i_{k5usxvMEs>EK%}ovLR;Bi*|BBhkM7Bf;1rRo@P zI7v3z0Hh9_w&S1GvP#2R?bHz0jglPlKa+uI9V1wy_7qWLCkDg5JE>X;{G2qM{C>1_ zM8`?mKs2idVVi=kBHaUmHR7M|#&$=OpEZ>MluavWewk-Cx#y6$5ieQMdosC+xg6ZL z+tYqTUFejHW%_I*-7YI&RlxS1$>yQojAE!$E+Y~vCgEPXG@y^z1pbG5`@UR)6+`^^ zWY`P~B}Wnwf>s9v)zahoF2+T&$ra%$`G=6ynB+LA_Bm~I1X_-TCXrOyBwIYiX9ASg zDm3v_9*)*WHr|Qq>kLR*|NC{}{{8yq_kmA^Q^X_{7=)_9)+0;>>O>}>QBk4K`T(|! z_+CCF1@b#;P0oxjmV`h@W$hD_oZCUdDi~M)Oti=Mk;l=y`ai41plPJUM>rJ# z9W~37HJ8OA}`w82A(BMOIjo)pyYW90<+8G{hKk;-qbVRy@ibG!!#KZ-lOTM?FO$fUa zT%1-@4aeVf*+7B|;?|u?2<O`9-}tMX`pA}!5Q-~XWp3NFBxk||eNxpzSR=ksIS zEKsN%ggi;SBr%f*?t@WrG8$)Iu*yaj4%DGhgJWCVyNMMNCi#9by%qKBA^8i)$F^2K zC($9ZB+xiKnNBteS@N;A174FoI=i>|q|&XuBYXxVlAU@p2Gi}G=Vl1SHxK1CKQC3q zgSCpEY#rL`Sk)R^DBU|?nExdZ7Eb2s^Qjv_L^#2wYt2T}r%(&IsZQlO3c3S;F#6SP z7?hqiEqXy4Bvh=r=Am}ou~HS6g|TkW^tDkkyCo7umL238N}}iVHA^lCoA{G9%;DED z#4~mac=pZ2d-1h=ej6T%*UG6)C2w4~6N(MWJw#rsW0YiQL*ZEQiu$poon^sY!eZ(| z1(HSV`7kQQ7-m)^-3{!&G||BC`kz0mFeqUL$&*R;i(l4}L42hg#Il^cFJ`h%8?q;I z4`fh8CP*kS}|>We-HB@`(Thgk}VQFPne(#16^b@35mO4p~2EnouT; zgd1ZcxC3gC=rDvF6w;edWQyd7b{CPYem#mcP_2_vg7k1RYTrJd9+au2MxE!EAz2+K zF=^6&*Uj$%Me{l#X(DO1)>8be$ZgT_<#Jh!^mEAnYxMnd5Mv? z?%J2{TTLpwfn_|I$aQ^;1GEiTcin|e>8Sq3ymie362X4$Vxu586%t*_gS zOl$7QqR5%jpZVJ^SoJ)8edhobI-=8vn>@c0=@g;0z5d?vT$gx1Up`hoRWaBk6-+0w zfl+0Dk+7JK%owLGBp))eE251FTZ#oM)kkN=SU4oO_J_}w5(ni$SqTLAW-IE!pQ|iX zwS**12TRF@Mnc@}*Nc{pBmmIX61o2>5YG7;R5F))LV~*aJW`5a8!FP(LMnR~!R}^3 zveoxe=DAwvObgi=Poq;)TxlmfUUU@g8LAxj3Adv;X2ztUZO3ZIhMcD9&-NlVwK-U` zNFt5T$ONWoLqaLZNUF(;sNMSm2lqV=CK2sj1|LN`D9lhb*EV$-wJlwo-FtBffJ+k8 zjT0BC;Cmr-V;BJXMxU$K@Ne5qVur(5f~e36j@Wg0vDbh&V;^D#efZ(onR$4pVvyF7 zrRwLQOh6l`#DH|IfmIS8^ko>c%V@VP#{qJIOkrfINqjHA- z5jLEe4hO9km~&zpsq-ONTgy&HkX!Yfk^_;GUaMu0R1n#UlBks>5w#LQO%QbTu?QL< zan`%7G->rxWfa;PoAe=5L`3XlTI!Z%N-EBuG)*W20g~j=oSBvnxsJBWNIBYmr^bJLkSNG zG(*ZWbJR%0W-AoRH$r55B6ck#K<`;lxv0Bw+Ur@nZ&wEB&}J8FQ6K0g*HRsTf`BK+ zX=0Z%!5BoM|E+8A(wmnkc&bt;U+pGHub4I$Vrip#T1>u*e3mh9lC+U31dQpAlGB3G zM2c=)=l1zDwMy(8B1E_`&z`zyz4n~3CF#=MKa_=`Ls9U_*z)U>F>;^kp-NW%lU34q zz}r?PPzn>+Qz;6ONa&NMBnj=tPVd)JiRY%>V+PGFEele$nLywg#7d=|C^az11Ql{DNwAL>jxD1Rztza`Ogt(YU-7L-uv*twp+RuXc$( zU7t8s`)U{98|?k8?=XzSO{UUOa_G*jHuJ* zM{NQgy>K{Ion_Rj`ub`ZByzQ%Nfhykr)VqyQ%rOtm79%gn^ClJf1G;R?N`4t0*vaw z2*{jz!aY>+MVN#Zp^Ec?bXrF(FC)_Dc{+JdrHAg-@2?Jsn+d#H+n}q|1o?@Fuc_PP z{&zd~+mhdFlQ{hT%~q0qRyTas&p#Z^v=z@@_K0w^Or9eat&LNLnDlOB&qRsWh8VaA zxx_tQl;z6?`oSx7b5nsyBf?Y94q8C{Yjl?HOaAlcMmjgrGyma}TVrbI7=ERMML znJz;zZsMN#4W>&W1+h`SCkLK(l3SCRvGuvt`@nyT=d0`oGkXX9fyTZ?{-ATg zPo(PaYi<`}nbCAWi?KC^wT|-wMYK$vXJR^^icX-L!IRC8W%o@Z3dpRsm%=Hs2_LgS zv7azB#*|j)SPWofILlVr*KIW!8T_&MaFR55{f&t3Zhr>yC#1#1R#Odj8%<6#_3?_K z_Fz+>h?NATOvcXhbg#m&_hgCHmL}9);3e4vmi+youf?GI439LsC#_e~>X>I`I%B@` zfk$=8#da*rLHo7(=c7=i?s=%5n>VG&mmpxQxo=w0;eiNdnkBoOP246-%^0cM>}K#M zTV#7TT9StsuB4Mhk(n&C21Zf@>E$@24MDJ7uOt5~VzdCVJ&or=;n0LC-AD4hE%N6lo7GxBv4=uy*mC zAYV34zbn#8#7bL@I7~=#4-<;}iJkcO*(9OYNyQ~wok^$&>+oE#*oNm+0~5GREya0i{P%dmH5lv~9z6d`+vPj2j_bKr` zbR9MN{6vu%Bd^ldcFF&IuB08V10N=&%lEkpJ-9>%VpIYAA8zH%i3j*laD?tMX;Sw^ zL)pc$OEM9>P=QkHQSMdk2%vlP%&EwurGoHQ#w63YCkl`BpW z>Nrh3hchlNOvI)pqqf@D_gcu~RK(WAFzECL>|u zr#nHCu{Kd&WTVq!A$E>G;TNx%2Cy*H?Sjhndz$zK^(QSgKBqUcPum0RkKZ%+{X6%|I;ou#7l-v+F++bfZ zByD2iNwebqaEO22{GNo1WhD2Hpl#!m1Bg{X3X_qlyIsQXs(Ad3~@OiG^6nfzd>uX;p?Gf6Zba$t8)aYJ|=~kN&?Q6@&JG z2~Xnt1hEt8i&N1hn=Zw^;9!LoCA2n5gdPzaIh!#&=@GDf$rs79*&S4|S6wR8x})2M zCW^GjQnV-A69zqAdU67JTLmv#vmWwC?q^X<$iHYCFx8lO2wj|6kNZNrS^x97;`8p*f-U_=k}WGH57}A;K*E`!xzK0K0pJ;{=AveI7`rcJ;b*CP z*{P-d&o)eCLF?+;hmxzhG@$m+d`T1u2vi*stFg_=F27;mSk;LM#+5}est84QOvc(# zMgHegCJliyB2Z#8eta%&CdkJ3eL3OP-S|jhe<-co-7qP3-TT7N)h99&}(Z|9}D}iX6p~o~1!?6`N3yiQl#6 z1znIyBUFgz5W=T8NU|U@ZiX+vVX(l1|NK}S)Ych{n`Klz@rl}_m=%b4!JyK_^iZvi z@TfFRIsyj~{@x6!Z#hxHdz6U`2NwNev54BKT0#JIamtqQKfgAT!Bq9b&P|Z4l9L2v z{)>@GH;B{yXa3%7D3pnW3kQhFc$jD;Q5Lp(mqDrlyvQtA14+BpCdP0;b%q4I;Jy@; zwo$FOp{=!2-6BB#KxkZ~U@z#bCgx|M0&b@reSEwd`_CqOi!6KU?UiX!IdE1wE$l}H za6!bU(**3N`+x)uYYl}UJstb?Cc?Lu$9J31%+#vo(C^_|*U7M5`bDk9qoHuWIlYSg z94GHnCp<&+0NDO*8ZBlO!8Q}_Ux?l{%GHy&H*V2e7e&s~=&XQv46#xF|z@bBhfCJM-q4REZQWrTEJdxfpQeo<^2HEvcPJG6$-hIP?B zHv+p)M8Hy}o1`6BsRq|44&_V&+dUo=Mz))EL#2PTTW%x^5 zVZ#KuY2mfXS(Wzpa1X^-5JjzTwz^O@>LOg=(YWec5XwD43lOtIII)Z=}j$F zt2oU2kaXd9aXOJmpnEx92G&2;FAoi!7@QjLpgTl=*e-k#2-MO-yl(*YiVh&aH&1TC zw#vsOsrQG(@|^oJ)&aZreh!D=DX2=SYT`ipDcPb^p~hGIjnWN=y& z_R@HA-4nsJq?D3F>Nc=g$^es0We$7e_u*M_)E4v;pL460bc6I!!s6?hQVs6}>p-B% z^Gxk;4iu7d<~y zro=cyfWl$wIp-QJ}@eoV&Ns>HLR#W&Ji{$Tm z!+`OzER~R&C4baY&WMJv?EvbA`-%esLDbBTGnZZjYg5rT9Yj?x$FGLxe$RC!0W_r) zLy@O@96a0uaFB2>5iplJDQGR>QWJ2yCeghi8tb7qo{m5v9etz;j-&t3YVB z;A_kYX_9BNy;q%02A){7xWwEqD)F6L6lW#e^G9E#4Q_3$g=!e)*?ysQ zY#_icti{idEZO$=Ys1(oM&EQ@A?n@raYn4!EH1q4d93n1h_;p<$&h2 zT;2)R5oCsg7ffl_@V#F&Ehd&#EGZz6W9=T82{5)B9^t24ssubNxm# zqymI_vk-Z9bwcZxT9B8|k92fDQcVnyAZ}E0g2^EyC$xGKURilDcSwXF8#P2ex8gPP za7Q3}P?7w@`1;xgVyKr0EYaQy+g6 z*9|X&q73&6NHx7pXMC?1(>foX^`Yk)jGiI6(TWp;OwE>~b@kF`2|Y-qaB5p|>Hz95 z1*N|@ew*yzQU^kiWPul(IpuV!PNTUHJX_WL$^|uex2l(@ff7UlQJ~Fm5aOL+9SIOP zs5dH=ur%e^2$8ZW!EU5puELvsaA{9cA$pe-E3CQ5k%7lkgf>lwLzV>gvJARTJcx)| zZG#~)k`qa~=7RVM;_|(&co6K8QVsqGSKzC> z4rj2l_*9C$2&&6_9iT*=zBdwd)hM08w|`C3$U*`J84etzE4F|I`bNO~?hhiX>ejSk z>ePqM-T&N;s%>ir4!kJgJtRwMhtn**6$Ny=uc>w!%kAxN^0aE=+qK2_t64)s|no+$vc+9D)vhgmkLGqbc zb?jc`5oAKfpSE*wY=Pmx{m`lli9)R@0ju-kvcOtoeKPE-$u{LFhe4~oeGCj($!%U% z_ew|+EWXKI6V-ClEE5ylwH!G3zK=!F2eWBW^4uUMyWR5rvpUV6pjPY;d`bCcSkIjw zOuX$rcWUS@Ezs8yMh$|Orib;QJ8qSFrW$HKBn=q1Pa<6>a>q6s4Zw*i!8?-nYaLUzgV&$^+N#{EG8P}J z^Qsv`QWolESVh(~_kx{~fPD4|GZLm+o#0L93JYnW929EbpxstA!MvBm_eRjakCjxb zk6IQ!i26A-U(F})ktJFTf~rLCcdAUW{aMRrevzmzs`{yDG(7-m33f@Ew9X&Bl4Ow6 zZ68Z&`_(Ez(6s|c(gq^Yd*E^nHqFVAVSnCy0nU#F(YVufSvjjQe;xOT2|Hhne#5p@Ow+yh$bK}Y;h3Q74NaCu7a^E&=<&8 z&|A)3*5WchG;vdJnZz#2)7m%Is>S4u@fim3();4+nZn+Z&{guf2!x670IRJeo`Xh? zR%?k!dOWM*Pn}IJilOQ$NS{BHtmt%Ydtq|@41@*;l~Dxl&HM1-H67RX>ILFv9Z1Jn zk`-yPP*r#1Wr=_5pdT3dn*WaEs*>ai1+|%mU%E&86G8SzpD2B<+(8)=7VxDE8;P!# za`h4sy%&$1OWl#glaXO8XRwuLCXO_ z2gnrAiDl&V6{TN@vdn?nSiiah%sc7k~n~KsH zrh7KWVR0nHlcD~|MsyK$X52MME5(#V60g@rzVn}i8adXe0ENzGK&+uZ{G>lkAW>^#Q+`@ zrgzc_h~6GTJPqQ*bVwIGwrsM7?M78J&lIt#b)1&wtdKD%2Sn=?lTu8{*e1teu&FjO zK?lSovWu~yfLoz+NYuW;_0f^&kI2I3CqzbM5(JTvNuS4!h}*O!g#nXdG&o@=SFk>r z(P4^d$8_s>sBjvv$a(L~IC+fjjJ=4w^4#nLA$S$9pxCXPy+@9{8@&MgiF`~o!JZrB z(`hon$ytA&DNFlirg87zl9~`VpuOb)k*M^hQe$tTKb{JkeO?5a6MGwy` z(HTr!^1ddnH72+<3C6kHHgfM!5a2w(KR^3K7sU;Db>I%?{rv@(_*laFPOwg?R>2)f z>f~#)RnIsjW?E1Q0c4Qqw+^vWtDRKGyHgdHtT>%m^Y`I_QGhfDp?Rs+AFqASc+e^z zN+u*_vanE9a`4(Ja;3ze`c|Jev~7~p&YnRLT@qaCbRo%k;-r?fg!0^tzUY$~won4n zng^?=N{zeCvd5$^;)>8~0@*Ub?t-YUpjh+f8NqlK@3koMhmM7V!?Wb1?v`i<240St zC_e)QFi~VtW&gKYQRW3pv+O>OqsYee9^1Oh@+yf0s+2>vT=9(htGwb*mCCW{Z=iyVe+Q7scY<}orpXj$ zty!hJu!wDurjd<~)2gylqOz5rT`Q-g*+<|&$G`vgYok1zMSy;PLrlUE36i!P23uAD z3)Qs|!gkH}sPLrr6CSgLI0rSWYMIzUa*Kd=3=J{;9g}6)YElqui#>nsy~-Z33DUmu zE4yf5K@+H?35P_SMB3vOQD5OS;W^+L%=KXQiqLQffl?{S15r-7&&!1=;6dv(X?3(@|o)40%wMa1_mZwf^(6A>!s}#+nRo*f3z|qkHn5?~K|~ar9>|>-)%u`F z4W3rp$`oDOosZXGLdjIFk=#vL=a?oe`t2r!iEAwA`d;&w6e5DMK$>AOnj|yx+1;ec z=?HnI7CYaZrj$v_pZo})hR|%xGqF%K`|V;`P-$E)+Lu z`tKklCM1e`06Q?VD|05jf+9na*=rsVWlyqlbl?4fy=Yc%9YtFgGO-Ci-2NF|V=4BV zk}Dv3#&_;~7lw%B{7yOa^i6cD4WA_x)9Ci(ld4pE|0r+6vYb^LL)zR8+b&WZluyNHP(TPjWXpXN zTV_3q_hiop2hX<(X#xev|1lD^O;3NU#K0NP1BWohFIBfJyK#KMuOi`H6Q@|P8W##x zu?wW#o{%F6z=vsgm=b)4_I7%ugTx#gz$}3#%1cQ z4ZI+um#}rEX41yn#M;d>Q9Vc8L&EScw+Zd+F}^JmsY+yWz@3XXj7a~O1zQ$`k#p_N ztQ7&n*KP9rjbOd6r(dkNlU>5)^^=4q-f7;Cb{H7XCylssAqjY2^H~>*QvEt>MnW7; z>64!m))FScI!&(7-k;0DL7>M0TNmPO$(BduIPILP4ppjxox{}Bfxm1uqiQGg`gm28XL9K^sn=n+a8@YCQPH7?& zB%f7+6`Li;t>kwPkvCE`^Xd`@$EqZ6S^}x)l`xaz|51xMYgjhc;uNNjx)< zCK|v@^C$j0r*;&~2EBhH4e#rsgXf)8y<(E(bP_8iY>yZ*aOEB|gdoK2h5;8z3(x{2 zF>_r?UdfA@nk9F>42LNW5t4X2(Vp`Mgo_7d_3`hu=xYl0Y=u#mDL)E+J?l(~{%a>C zdF=Z%9uL|`)QHP(f83g7RSC3F-%wG5-{A*wj`0 zZxj>Y(B-+b;ae>#tRQLC=$(Axs!I$A>~?PGLlZ2ka*$a!oVu_FFU?{j8h6nGajJgH zKB;r>O6h&QuYV-TvbGaAb=0bX69E0#GS$|)?cqKUghidcs$>lNlPFE`GI7Ur;K=*I zq3%ui*tm$2aF}Vm{fudp?cS5nT2IB=>XAhHQ_d4RQ*2t*{yF*#`u=I%lMT9T_x=oQ zBlWLoKC8Fp?s+}b<=`KG9-Df%XPzo((Xw@%K6UDJ4m$}G%&Sr+D{1%D?{n&vA?Ean zD3C!UTzIdUS{=z99kf}}um%q#z>nGpOsZ;8m&KdOm^h`u9e&)#kv>1vR3YjI5+&LN z2yzSUEx&WD=Lfd;^}g<$DlkdNKUXAESB+SZY@F(D<@q3J8nwDkr5D811RQ>CYtkJx z4{2&nEz6rvfITkJN=8SSBo*V&eTJh^61jan^?sQ7HKypAI`-*I2HUYHVdk@C<}4a! zc%C*{m*@ANcqEFo-Y8e+`m-x8EDVV$CirhoA9hU+p-eUcNwWm`S?2~@mzuOcYaQ{u z@ZO34>>6tO{ns(5VS^%+-l!x8vA1bXF1tuoKzSdXU||7Ns%--Z+Ti7wbh*DUgsfaZ zPY2?hjgTr$DH<9y7)gF#&p7gur0RoI9?2lQulIHDV7OcsN!jK}-L*Uv?GF9dpBclDygkdGKKlLBO1GWh=e2`vQN;|j9Bq?w~6+Lbf;!o2yJjjvMNIN+fJvQ~hM1q5L((3f12!zU1 z7zJGKP>=#x;A>GQ>AKf2^bR~BasS8w{&LS^7YlK=jk@YYWEYsudwxMeb)_M5BDsgm+NrI0a?UkrRX)LGWDq)GebHjg;@jVs$;A`EV9HczVA0p zu&fn`EVWX_Q}7qi(!-+uUiaB6-iTJ4cq6h|+{pWFHy|3+jRo?jzZq+eBX5&#-6fx^ z)jP?W*if>u9SOR=jY+Cbg*Ii9B-8eajI64U;zTCS>&HOh|j>^opk*ArhlI9oz%XsIV4>A ze}U8;mzNXC(*9xON3rF7%`m>Xgwvexjl&`K!Olg56zD%P)&1(zsn8`stovTC*(ITN zk%}2x%MS4jt^qhl5GOHJhVvx7v1L}K2|Qa+*>zGMHZ}OIye?B8-$S}OuPyJCX8}Kx z-6tdz{qI0q%s#hyDBi0u!kKUTuTk}YTfW>BH<;d`)s_iv{Q1g4{5&CJf+VW#lX3dj zs;8>C5g^F|;k|9U@ZW=WqbF5Cz>I`R>~0jfI>9m@Dm&awwN}0+Rw&Spp-E*LBU2p{ zGJ)o0)KpNeE#E9Q0-!o-drYW%Bgv}UhLCXE-LHrKG8q>7%Wa=n_4gXpiKRvzZ5)K$ z=#1P5osa%G(coAY3P*|+s*S}zX^6?u-j2@V^k33S@O{0nd7)dQwCiY9|Gr)&xpIQm z^k+dC40#W?Z(~nP=&6B6x86u{)@c%v=~N+GKVDvghc8=1Fwss(X}Q(m&m;%t%c%?M z;n$?|g39WF4|HXUtijKxoWfLFsXM;|ty3UM-+g?i-BJI!KUcSRDR7DCv;k54N(8|J z5F>oK+f3);oWoGut`vp|s(vi;JyJc8O(uGJpYZ-lx@_Rngi)+jEFi{d>Zk-{6KGO}{BaNy(F{`veM zvSPhr*q)$&yIYACDn9rx2F*^VF>DF57u;7eG*EUXd7)Y?*#M6RUYqKt*u<$NVj@WB zLglzsu|jHuV8mD9(tp{<>Xq{D_fvXbuY8Fbx)kC}f=(=?8RvY$_7gOpSdjMzFckT5 zC<>=^EK9LeKSvz?+p4l96CmsyQr=L1_|Z8!BT4DuhGoGV55 zO+6)VTKFV_E;Bz!MBEd}jU;ooNy1w-8;^OICKNo}C%^YhR!U8BM4C1b&q>G}uV6FT8ar4sXRjax7d={b_# zQ2K;u94(Zt~ zna3Og94?Bw!hNdwa8ViH%~bG1>Te((qE#8Yh!X-olBNrd+2=FSk5JpSfBjCV#2i{ zF)$08l5wdMxchz0Be4?CMH#_HyIe@L19{ul%x9{I@B6mBua}8;a^PpSj@k7XJVwt? zN_N^j{U0Df{QF4W1Jmj7_}gsj;!AAM0TK5Sop~N@ZkXeO=bHwRw@XTxJ|DX zD9Au!_eLjE8`J(FbSl4~(%g8T5-LE{ zwQ>kJnG-bTjO^_k! zF-qXTyXj-9y&jXUG!-4KGz-&+WpTZSAbvd#=vbreUKie~439Y?fQaMZlu@c+EBawb zrl{r~{TvE1AXlbro@qDfRW7Uv+C=p^M5DYaBdq`Q{17+)WJ|6&@X@#~bXp$D2VY82 zN}V~&WHSBu)9*be`$TeuMY^QpeaC4ss;e)Gy{QX3fFUx9hl;6j^k3zAvfU;NCnzxSRNMlyXvg<#F>dJ1xH5-W(Ls$LlKo+WWc; zy&|861znmfayig|uJ2MprrI+$Mc4F+RjqnyNHl`dyC0sB)9FJIo<&j8g!4;Gny)WR zIu$wPfuH9(xz{H;puF5Li6L(m>f@MJ?9XLR!C`RhLy{-FKEMnhbRY27EXV$ul(i^D zx?)Ru$l}HJq?2``G5u5^z`n;kPib!6b|VceoWDrCUDWyc>H0Cja#5y_7sDGs(u4rN zLPC^}WfTJ9qWm3@&kByn7TP)-4m14yMj<&)cl7@>=>=TK!qLsL#G>FdoFruAXD!Nq zAkcUcGdX6u9MHP4X33!SBQ^x)sU{PDP!Qe80`ZvDU0jAz6UOGchDsAJ6+b^N_4n43zQ;%W{v; zJ9Ri(fGn{NsY({K|io-yU|qj#h<5^_Wfd+ z^YuvFheu)8-HhkObGMP0Ug&wjB(VUmDpRW-Xg#e+{~)^E{}hCK$1%R(eXH1UDsG}a z|Hx~k2YKe^8!VUl{R^s$8zX~L|9(}1CCSxxNUl@@;NxSZhLL`+$|mB}Gz>K2+MO!# zw&uU*Y(Z5)*_QewE@6)teQ)7%m1=3>DBEBJN9l<=8KeCNf{iH3x^Z%)EkL{XLiFrJ z&fkj$mT9F3ysgtX{k^qhN*0kSSeK$+O~esFiS0&6Z2$#vnw+Idgm;o;;lQqI)g+rI zx`5BZL_^=V3E_(IX%7(r4DKR<9VZb>kmI#5gwQ)of>JNn_K%C+$%(=Qp{C@avPM;0%x1(}TZ zh4{khGwFQ_QToc(y&>1850qFOyS* zMZw>1uY<%Y@UV8^b`w?u!S7!%d^Y3-pLdsMhK*xmxH7`L4DRWjq8PEinp0j5IXao} zbiDeoQQUP~iwSrCdvO@s@Ia-$UFI8=DFLuuvKU4o=LKsm zO0?o~&7_UDqDK&q=p#7Ak+U_Z$V#x=KHarW|A@HL6T=j)W;seRqL^-jB zg~RBB%+RIrs8yb%Q#8%mb*8U$;CP>W&6uCeHmIUa_>*(+Y{6psZ(jrhtpX4OezWLC zs!W6*)*7fk&~-{9Dh2eZ@;(ltW7M=#biUW-4HGOPN}GxS1-uPGq=d}Q9=KL&m|UvZ z^A*yxWdB*%7+az$GWFmTg~IoPB!-7(S+`S&_Rxd;rV(Q&{!70sXdeq2%TmUZiN;jb z5Hxhd+gN_98wda0X#$I6s#K4q(Ed}zW?M<}m8iKbDn)!ps~ZomxzY*3svZndIaNsA zkCMR&0qNL8%M-FI21Qh-bQ4I&L{1t9FT}$ODBSnP6Xg-&Vy?;lmca=`P>AIEhrDes z7E_HTR@9AI@qWi>RTv-cD||z;>ZldMgQZ^|UDGGozT&^z=LX*cRe5y-Pc%V5o$&Y~ z#ecjvxra3qJ**$o!F%b`RSQtY`!kW;g|b`sVbeMyiXg{+8UO?+WT64$X=3`I}k=eLxfYO zlPyTLTpK=*(_{z1^_!EvVuh5arj?^S64i$3OPQO?6TT}DX1-A^;bUi$JaE`6&6 zixYwxpmDftH2B*zpk(8Y4@9OSvXE5mE@~qc+N5Bb3UrGD13?GK3HVfgim%~B01Q9B z)Ct6Y1Eh4+{EDjvXiwE@v}~=sQ0XBFg4TzVwjmDdCXDY(f}7HCv#ld$^oIa%KD@tTE&2rAj)^GfAA{bsA61R~YDbCqOjr2D0=^{$Pk@+L8kg}N1^JcE!dl}Gib9i>Fd^0HdoaW`Ny@~G zlSvlOZD~n@QqyqAOp(kVZ)2i%Sx+DL%XlGH)d&Zs;BhNFt4395^JKdb6I5(EBw3hf!RB7EcVDRi zs;C}|y+Kr&CqmSeb{f->WDa9#6uYfOpUuVS9jqy|Wr}35)K;J+9zf@ixFX2O)J;Ny zEfRkOl;y&UXJ(dOtzQ$!>y>z`;r;=k{9KmG#Yohdy;USmY#9oj=tR)9mXaLIF0?nY zFmNLOO>Ph;B-3Dlf#31D+Sk9i^zf5}p$Ujhq6f*c9OON4=t-NRVxY!)nqwvGBGKMm zxf!DQ@Q^Eti?}FW_axebb+b{S$c64@A0jUh=)dbV@2Rz{pN$Hei$)z;kd#e+_XH4o zwcG7xxI|@rV&0!qj-u}S1Dqx4x-^r;l5moIh;4b@1kEY~1+JZX!P+VFEbu7f_4d8N z6k`@VUh&y8mmP_#13xP^yvAOKUo3w2mnK&W4!V>{OmL6y%!-mrl3a=ASM1c`h=8X~ zyaV47FE>cAI2Inp!KIA=?UA4o9<=~Z+5AphOq>{830TWA%E z(|S=0!F@cUI#f82`kTY1Lozr_pY9;CUR=*jLn^5Cl4rqhNSZ!*f#+qS{4<-HB%xp1 zu;wgq>1CBS-Ukt$4{NJie0Kq9vI!us%E6X!%fVX&BoTTxSSMLljt(LVhLl19a@Btx z84kJrd9~dj@4=x5wZD*dam8dFvMNS!7ipI^kZ~6?Dwb?WpwqTYs{EH&C&}6<(ki|f z#|XAAi*jl*PK1=P$G`d{Ozc#ijiWnhZ8jLRSu!SJNJ3-)a_L;$>6wsz&_=}(*K!?@ z#6*WFP!w6g;E$vulwD9{6_bM_%0Qgv0_pFI9?(~+st$gww?M63R507?dkH`K8C^h+ z`~@RyMDqIQf?`_+d~}NVhkJwWhjAw*?i7LZX_N`>5r0$3t~;(f##2iG49aC$G3nq$j@HT_RL+bFq9=+leN6t3tSAT%QsXJA|qw!s2 z8YLB27u*35aQk3rfD#TeR5N1xuwgPJNmk8P6uu5bVW~VTBwiR722zIaulroR{e^eGE$RhZmfW*(?o)}Di$sXXu-9~Jp zkOY>Ih^tkioY<_Jz|BE$z~j#IETG9|w_z1$lE`FR*^MUyMTf4Iwl7-*i<<-)^AbfH zb)`au_PPtD7Hm0C)Gc zX)piO1I?yui?S5e>cofp(A^nXbM#ehnD}Nz5i}F+DuOPc`!NP_&l_mKtkoS&D%o03 zuTlwZBb3VKM+@Bo$&bf(tB~DF?9H(yb7Erua z+tyMtf+X%I789f~P-%*je91P~DzZxe8q=U%2;?U(WZ0mo8Gr=-_pg!MnlU(oVtVAT zkiauAX4iG46#_6*(4G3@y&l`!I=AzkP zeUnDIQbM-ghIU8lhM^P6qO>YQu@x&NJWC|ax7tObr6xx03pHLJ#Q89(ScD|D)dLFW znH^NEqBwJC6OwDATvH^@Y^Ul}vn19<&=Xpe%d2#(IGL;VE?9H^K$4lNIzOIorReb! zx0VjF^a*?`N5xu`oO{Lwr>$)h*~Kj%Cs#T5?5W7oMz!#0d_F>q4?L$-)Z+UcdD0}~ zwFP1pOsxIY_e}<&JojdnoyZkTRK|tq^Sp3AxoGLZG+tcLbT$LM(P{QB!@ossmZ^Ey|aKATLrG#U4ReP%Y6Q zLu&!n2SgXjj);Yg!6#&M@^Zi#>kp>?ey=6DL3>!A_bvS6h>rF5%_h4j0ph1( zWtnu}ojO`Le&16NtVB49h}-}D`VKJ%#o4`EE>=9qnj83EI5So!4r!RJT99T4sPS+p zAAD_Eh$R8ByXRTtZWs&M&Q`y?^WL+p@rKil@ecLD8Dx&ol@*i~2N+B@Fy|DdonvTg zLu9$@N}Vi!VuE##g=A<8Hm0fQT6W#kXl;p@+lK|Z2L@WdlMT-;r?cmg=liWXr#3IR zhb1d;;T3^Dfc7eq0w7m7tj!_bX9<(%O|>N_r|cJFyXle-C3U~jWumH_ZpzZV=V7?Gg+G0kyMhg#e7ULin zI+A?h0&Ut_Yf$@5UlB2M<4KxS6B+UC6OAzYdrRs`5?2pDX-RLX=LQ`wn>Ip%kUBve zkc7tkk4x?mcx;_-1Lq2y2UjGlvTV)Ubnfu`osMy*+FlzYA)H3kX(!VqBbV%B86}vv zJ@i_wj)mOp!!$7n?3tRg193C1+TLEWarhZbog%SL!)HlEo2n6e6)0XWOw9KVhXeL8 zl4m5RE0v!aPzbD5+1E(2zL{igkYYWhU1;dz@E#vyj4o~ROp78R|C^8Msh7D~7%E-l z1LcGkI1yrH$2K(xE1kHGEX3}4Wg3gFX`Q=hk7XC2i)LpXhiwZX^FJQjwa5S zY*m^B!Gl#f6wKa_)~$5ooF?n-!}m}=1&`kA_8J0!!ygL@n+U-PyhKhXLu zrhw6hQrQqBrbzhl8Wx8>caW@G^64%?(jWPHrHUI<7fO8|PdWVA0#-j-<~U)pXGK5VrU}BTR;b3U=BFiC_gFw?J}C!-80%uevr0^#gPd%22$QGXotgG#jjHFiTD zg0x5?l|Mk#2No?wt}P7{6&#D%b~eGssIlb=91`E^OM9$Vd%+ zt#s6y7+0<1CV`-rLmRYG;lLA$RHYN9aB`;z08SkYXRJKb+eLFu);qCelvQ?`x z2xam7HZ(p)!NXfTI1P!z00I))V3DFpr0D?dR>{|1%SAal42@79a{@)qW641m^Tium zn*83&rhiS^gg${EpGSUU|s)&1|LiMKT z0S*BuV~hDRT2`L$b*dti;3_mKBx$L?m*>lYAILqFj*!(+)!B-j5(g+|!1KfVE2!e1 z6Y2O`%g{g;ap3Iffp13@ZWW%y&txhsbL}>Y4?!OG{p$d+qR?bCLCwAYv0}ncH;sP3 z)43r{f7yQCze=6ttaNV@pg3-aAO!ICyE`iNuxa+2iUOBCVFa|H>e2BXhO9g^0dAZ>-BboYL|4Bmw#iQ5|7y(aLNV&BoJ0BxiFv@)3q*U$D6(QHnd$$$Wp zESHIhu8K?=QY;o!^0|R>PZ7RPT^@%N$4hNZ?*2XQ+ee>dp;c(Ul@9GBFG=4ctMZ4U zSV^M7$b!_e(D?3xWzpVRL%Y9ILcaR+rBQpGND(xWnpTHKT(a(qC?Fr^JR(2yxI;Kq z8KaH*Dqi|5sh`Mr){1iqIHy-6MVwG?l$!;9)SYk#bEd#Lrav*K-AirrihPYF+vt2v zCD(|}A4@?U#kaL%+?6865=a$teIS4`nP8C+rj_%q5a>9NxBzV%S|x{q98$#!se19m4N21D?VQ3OY#d*a8*D}Jw79f{I-*9@9PzqM^>UW16u z*tbD5PN!E*uoqx}xqqmqxeQM279Za0NPiLt?bfEnIMb!i6R zMG^_W6YWl{mum*M8d#0dEo6DuoCGl#QbbiMNF~uqjm2Vxln>|Gp=3sfZ)l08h3B)c zNiV`8&-FvrYUZ5AmRYRvMZZU~TlPFvegP;IS~Nz!-W`dZ7yLZY-|k(g#ScAbnufZK}eps*RO}VqmB&E9EpSl)rY-B%!t)QCT)xVVhqf zbh*qokdh72p>0(=EAo82ub#1|aLe0LJUE$6UmTlh7u?m1T!%> z2ak-XuqM4fsg;ZIy~V&zNXok7+BiF!L}px&g)ogUlislQ2ockW2Nd2DlCqR9B0rzH zU%kg|BJ2aL!OV#{u@0dGoj)eWl3WRzQHC}jlT{svF)g=Ppwc)%Xtk%wbIt*_qE%qF z?eeSj>p&K#D+Og6F8dwGJF$mNg!h_D?55maYtLdc1xnepO`@QbmHl z3yWh(LXZwqnB*-bPFt;6KmZ7Zcio5s5o=gcS^WwGMm+h-kTe;gJu6L)!HtYyWBs$i z^UWvTKR0PckVJ)?E7t=Df_e2>OU>)#fI#~BOB65Sk7{xRr}INco_0I_cE=tRQGa@+ z$>b+mR<&ww`558ai_bnJ|43Z3h`aauFEJ;^{$8u@8xr}oqSxWs!Xzvyat?i-qKgwm3@GTrH%!9SnUF^0AC)JcWLhWpQ=uUd(*+#25QtKjim0 z*Zowgo|tiCtj*$7&kONE+F!|wA;Za8PdRQGkNA0RDm{u{N0XwRwa}{6hS4c@pTD49 zsT93Y-2Hb7DnT5fPlv-&&@3(b?T&jNBpUXfr&CgSo&`<3xvWv)A=xxtM$Y52-dD$@ zsDB@6cCr8JD4&3wi{FMs3uqx??N%LJXwkM%=^%HR+4a#i)89|LCV6h{H)$G=kYjTH z=l}k{FCdCP1&_Tt>YYcuubExq+qe~e9r$#aSZ$y!NH4NPDx`9!vO|D|L`Rxsi>SwK| z89H~MP{cn!KbJ(epA$zSUC)!>tgfj2xWBtA>hFYf<5#0PoHLIy;7 z6PUi!^_~Cpu;17FdX>w}d1droG^~t2MM5)^s~!J0oeo2wUgm#-Huc*or%)M3-o(7LZs%s-FQdyP!IQPWEGaKOznqC2DqOsauS0}#Z0r&sUm zeZ8*-UqsrIg;*!~WSDrqQ*J1OK%FS1tCiC=UYsr>2=1z~Luvz@*A-nLo-+U=nwJ>N z6ZsEFe6Vd8oKD^e*87@$GBqsJPR&*6s1kXCS;mz{o?uriWGCuDs4YTNf|wrKQU$+G zL}zH+0%u~SRN;Vy(Upv@t@KbB_S`sBSvO+ST&5 zgnAIjsk|QsjZ*bq6lMNP&9vjsaLXjk47WiQ>H7N(_X%3(UH&V--wD?Hy2+x%#>Zx& zP%V_Pfd;Ag?BoVXrukQ$SuP<_1AoeknK8WkapS^-NuG;!0>t51Rj5Fmdk^=$ulM!7e%WQQ5vUFQGu8gZ zC>CAc>`h$EqY(wFSkd@c;6I{Z#d*-ErIu(;UH3YhbtA8n8~|(eOs-T1ZK^~TNgI+m zpl-NXUB8W7+0SyCY#G#< z4jfx|Q?~F-Y!Ougs-8{JFsXy56itWUS=ReHH(+l6zwE7s{=WW&M9YvUi-q0p5KlJR zEBT!%?MJTvUf&nH8#jb)+MVtBdvJftiO*4-)gK@8F=FTq8z_`@K6)m*^sj1I)w-Zm8G{yUy$PkgYwIUptzK36xU{Mo^$-(0eW-O|X zdLW(#lQCHUac+1RNLVl?o9D$#CkrM*hdqi>UO=*s4MSp0m9(qcVh(&K&Ic27nB zMJm8T2NV8o54e&f5<|kb)-|_64e5XuzNvq}XaH z=+3_3jGt1`vn}6sTh%8Do+5YLdm!ER8mQmb^cRX*n)>R{OO|CXv7WH*{f;-``?_z2 zMOJPIH-iY+tFXE0HCe;U!9d#Qk9(f`*03Svh%MVvW_YP~_oEJDAyz95VWm*Tj$7yU~URLr>y4`(l71ml7^Py4&DQ83v^&bu{B#?@W%U? z=UbTq&={{Ri?%FZB7sSRB^}4xR+FpzWey&^4S|P6$PSzAeI%YfWU&54u&|Ai7n|Yv zQnZl61l6!-N-@D^vem@NqgO2ecB@PHoY|x>AT()Pbtr z5ABCvBA@Vx)?i>!3Qo0UjYYoTn(Epv8jYvdKb>IVv*Mt@M+WZ-s_g@`#pc{mh3X zoFH-t(P;qte?jwHu>|3Mh1qK-?Lu<5d`o`cyM1`sg*eumpB>PlAf(_*NzOKHg*BC} zrF|%p19^-)Q?4r(iK~Y13qQxEkAdL!I+6Cyq2JdfaRqA#;;BISO&d$l^3hNCS0q@O zie2I+pf_56%veQXbI)f569@EfF^N!4*e)~zEzmKmlCyFfeMzs`Y)B5g=y?ELz~-lV zd09N|AY-cxD{ zVq@R;U`^I}!F5Ol>EU2R>y7HqFvQjt+bbnnV)UJ7ZIMR-TrL$a#mu~vc4!&~mur#! z`13KRcN+FC_*YFv4FYV9?K2M)tWIM@e~Imo*r74D0XL6xfS#6F^7=-a}%}C2RkJB5aG_B`xzEG z6!SI22BNRV?Nn_pw}X2B3J#W3uOeKDO)UOMP4=;vbE7S3bUB+WP_h!%fN|a=4G@Ex zusNV?K#)Mdnzo1s*`qJo)ilx?oN5|~+@IlKr&i0(3+BTKSipPmg3oGh==h$EaoFCm zZ0ka01vwBLDoB(O0DxkF)c!H6PbNtAPm-7wd>!0tBwDmYDvDSLywXK|xvq=v-@{Hs z)E2kI71_QT*1Ao`+N2W#DG+7sN74w=0;(HrKRB#Xlx$c3_6s7);98MNa9}6K=ivn< zMUsOg3p~#?W8YZt7Bqgp9zn#jTMobQY-W)P64=S`d~U_g`bOcuo#Ig-*m2qeWAaeDr3!Jc z&m)j4vr*dzJcsg3G|EKuY+CGnjn%lR?c*L{`jb4EA-Td@GE|bjX01%tq6K)Y)fz{U zhkyV7K0b(o;TJ@6%ToNz>_B{l>fdZbq6ls_woA=0w$sn!cd7_!UC96n6VuFil#&Rb zdPRG>r$fVrU;7Ls%WaLoZ^vlimPz6xNsZs@4LTWu)%I~9;@p^L&k6Uxtfc+C(L`&V zNxU#}d@fcIci|0W z-FOV|AXt}z6?iUq6`NqU=OJx5|L`POkgR$~+%*hm*7sqc;?Tke2@ov-Drq}u6P0(y z_7LdToL<-#!-Jv*APB45?TaNwq=M~i5MgT zBd0ty2{`M1Gr?-JK6?b!@%0lc64`+Wko+%eMo7J#@QQ~03`qtiw3&-yeb8f*;eq}4 z9f6Ld_geT%Xa#kBrCL)P{sNjK2jXiCYv7O-xd7Q~bA9hL6Gu|twBuCUzBO%?cf!-c z{SozSQIN(x*-qaciBJZ%z_4E{#?A6uf^Ev)&I@M|B=38?RZH@&X|LH=)3|t8S2Ijq zD`(Y`rQCb9BvEtYos)G`)E0i#SV-u-LLoOit6KMj$@MU~T1xz%vAyZCzn{ILEpL|A zByq`0VZG4=_Z%-mJReYI@P#$cBEMx*^S{rfprG~jNw86-!o}a`;(vP#&1528y!%G> zp4M1!NUo6i7e43jmzv#|<$WfJY@t(bo|9oYZ(cFMrpXnwOJJ>Ii6ri~1;=S z*Tun(f`WwjVf|R^Fn^M^TdIR)g%kGN-)^ahXU{fKtp??L4RSjfyB0>wHh@8oK#=j<5YHwvU6 z!8&ygk)|^I0@z>)ar*B@4H4A+@^#niIpmbfdo2{!DivYhnOqzS(jwp}mF!}uM*klK zF+21733mw=_`taFIEZm*|NUCA;;gh?7O_o=?*r-}#Nb|n|NArQMm35G&$S5P z>*l3$99zB*pwZlSb@}jf3hM`lF@m$TEm15km4AbxD_636intgO%k?*`Q6%`Zz!)wh zSE%zdA3$e_o6d z3Jlg;UAMM-yxsCv`zJRCd6r$40e{vw|WoYX5^9c((;E4rGUlVD*( zA`r11P>ExA7VZmx)2j%JIv|qi=yY0b;uk)%dA{u~`k-Qe5?H~L$VOkOPDZ+m@|^cDtcgC;_30iOFz_tob2%0U z_d*p{6tg>`__KoqB1kv8aiLb2y zo=L!={z)dBmqK0UA9-)ucC`M9t@q*g{}uCZ?Q9UPOshmr7eoq)uFW67npYRPQ`f(axG`!jS|?xuA>K)hRT))W~%r@c>P zwClK!fT$fx5`twuI|+rwsFa6h9ldYyCKKugevVi}NsPib%OFqM^3nM7;zKjWv9qFG z_FmYVd>H}Tc^9XKADwJ@Z4;7PtZ3`86PpE~cU;fAgC>;!(DMSh3f8-|kWcYrCD=jxwn!5lveg+R)YbNc@fq`oZa zC}cXU*F-dbuxF%Gvh$(j*xDA@M^v;Q{)aupHk9(LaBt0fGcE3nEDb?ZrwLkKR}cMc zt+w$^!*4@FdD(CHeMO$pcHxykFDi~!5Nz@t*m>dA7|AxqBRLw7SL|` zES@EYo}Ex&+Hc3Z4LZ~p=qZXw^T@y2*JV4{e*uBDfkJ5)A{=+O11vd3O>O$`kWgU* z5V^v^FjUN_%8l%pbA(qW$gp8#x*(i5h$X?=XVqY&$==|QiBOL1gz9^cPrnWvreZGM zdPJ%~l>h2@@5#p^LZV~jGjL&Aw$>;+K>@|@L|vQ0IX79kCf)El$=B>uC3!w7?C$o@ z%fkBSMNF=G)gQtJSa4$Gv~s+)3OF&A-5*FWn-$#eQ8!7P0aioxzL-76JeVfUEPxb= zQhpWqR@e_XI5rGS!YwgfAwjof6deS3a!^(qws3JM8$!i>mY`E`CXlMHXFCOfFC>W! z5HPc!!OugxvFlwnD=SUPaxD}dbD{l=XM)7hs1BC&ue2Bdp&9?h=Pnd|w0mS+G@w9! zckgC4h%)2;yLR;a<}5!`%cE5z5((T#o{2_X7TGRAJ0#$}CD&6X2t+8faKig)S|Q#? zo}b=F7LrZJ_gQJ8?rzwRjmAH`##&L^V+edn8cKdJp0LQ)3DiT04iX!D&iq0AJE!g- zn??pR@MjZgWkPWzsTkwrNKs*jp+zS|i{kj4?yGB;tF#MZJYv^E_u!$lfN`u5t+c+c z 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 M)78&qol`;+0AK|&rT_o{ literal 0 HcmV?d00001 diff --git a/img/icons/Arrow_2x.png b/img/icons/Arrow_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..8f53434c481201b4b046fb96021c2788876820ee GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^GC<77!3HF4glkxU6id3JuOkD)`V;1?T`z%r$r9Iy zlHmNblJdl&R0hYC{G?O`&)mfH)S%SFl*+=BsWw1G<(@8%Ar-gwTr}isFyLUlaO=qH z0_D6nhprsnkKpnKoG@GhW|q<&<>;nNd;ai2viVLK}-eF3W5~`E8wgk*a7L_=peh9x0#*GiFh+_ z1X+H!AMcp8ZEGg3EvY2UaX*k6(xxa1&wtD&z%r5}EpdOsZ%(=clz2s#+yFX~?)gP% zL3#tQan5Dw6<7n%0VV3?Q95t<%;k<{R+CnwGY6{DvPdtvRGW-|o&b`PxZE#NuiysF z@3?~G2G9!S^2_g$3{42z05k+3ZgPdbNmgYrs6oR@>?j}^0E1qTv4(JIhNf6xNG?$U z9}3hXqd7|3skk-i8_zTKY{%BH7eJvU^oBO@;GPEI(qPw4CNl#1w;_Rk`zV<$(4QIs zX9dauG5~eT%qIf<4I)+9gq9GH!*!+N)`+t)Yit9MS0J%P9of)_FmB|lD#J(oRin2T zK?2KheMCT}{Iv(D#9@|6`q&xNrgg!y1Kb{)q`3yO>eFHY2|?Z1_bNd~0}irGu~#57 z1tiuGQ+|?KG}x%mbTtK}%jAYX;><0TaUawHzq)<|7y$V;kMJ6lMKb^Z002ovPDHLk FV1mbT*H{1m literal 0 HcmV?d00001 diff --git a/img/icons/Attach_2x.png b/img/icons/Attach_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..2f9a2ed91eba17f701518108150aeeedae1a185c GIT binary patch literal 892 zcmV-?1B3jDP)6wkPb)%;0lbN@=D(GfIB$tjmYS9 zE70;0&1hoCvi$aski_2Qc|M!KLhu+o0$+nK$p5b31$YWx8e^Oj1QS3V!7K1b@b3)D z+6w#tezAaH>#4!4N+tL&2aIGE`~q?ZEN+;3DJT~X1(Tp+k2y+wa~oTrl7qlf z2KDL*_1ECh6&QDoC04ay0MynIQ$teBji?p{J)w3C%3$2k$87M129MiRv)5+yR4@Tl zlVEdv>vB9!I_55D`k8w`#SH4^fa2gZs2?%kNq`mky$(E}o_j)3J76m5vPCces_am6 zZxcBFrMW86DA5IGlu)iQDN!uuR6qV5 zlh}ZL6S~hneU}UB#R2u-d;oRi3HHNLlz9&Ffzl|?p`0HhZz%OusDCSE-=$eVrh%d{ zmSQm0iWW!H&7K`lDSoce`4Zn+sp-4g#zq6?6TuQT$-5_%Q7T{ibQdu;bTr{b!X$~} zhCYiF!R|eaGG74C>OPBX1v`2`_3hD0Z66;HwRQ}$6ndtv8%9H+D41b!a1!cY+R^H0 z#&|16li*lIc`wY@tLN7Qr>k+)wnM$aq|FZ_v^wF~P}b(cW0T-EEM7F-#303J7rAZu z#41PLhEjpikJ8f@?2V~o?8H<{gBmz|E#$7X)36;1Z!_-_vK&NOYx3DzQLAe5-4kb1Q-Bti!CHS S+lQh60000+nGjJ_Q8EJ(3mb4`;KJG3Xeh>_RM5Kyz56~XsH6zs*tM_yW zj6o$SA?-+KqzM$09!RI0ApxVX2et)hgA(;>P&#jT!{v5mR*=S|0|(++ijUo1a{p}5 z0h$3MC2_f*+#>}yXg>Ee3H|{Zqg?*@$&=yH02TnX4v3pPN8co?%o$XxVHtK5kPLu9 zx5!vSxHLmkoM1?0paPy1s76L3l$NWwDd`LEBlRw4YuG+!p3;~HX#FQ_jS2WnbN7@p-D^Lge8fPw1#=TMpymx&IFaSJvkXrmi RJ!k*`002ovPDHLkV1h1}*5m*H literal 0 HcmV?d00001 diff --git a/img/icons/Attach_pressed_2x.png b/img/icons/Attach_pressed_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..0b814d22947c13439fafff83c2ab9414a2a25f77 GIT binary patch literal 904 zcmV;319$w1P)G30+SOMpTKm{b=_^d2suH>4af6^zq{`5(s81i`h_!wqBxO(;F+hl|hLL?9|#1djg{&#{XA##Z7$HzC;1%eTv z_7FA1EyOzpWyS(x2XQojufKj@jtyp1svtgDV5DKdj{uj91$K=pE!h48#0QA?7&j1i z5EnM@p2J-YkYgd{%!1`nf(lB9icW1D#E;>w>iQS zM!4-#%^X{hT~ROsR8wG|@Tq&k?X+d>l9r#T2UNnKE*2;bPLui;>zxExli$n01M0pb z6dgM(C2eCC^nj{b)ZCf^j(=&bN;OKffkjFv+nk&znX~pK)y0=q<^o%?C#AXC%2Q3A z*wUbdwhkOnC36W|cIA;0YSLEYunkeLGUy0pQ!{Zuty|Pf$@$C$7TjGlo@!3^8QYS1 zf=hERm}6%)=Scf46x<}RH03#K%0odl>YXifXgd7W#5GPK#M?JxYUUp4P_%(#dwK!W zK((pK=ekr4ahuNh+?d1$?5*HFyZ9~})Pn`;pY;H0&kO7?OH<}G$OlTJJcqKrjQm8Y zPeT7&D1Dda0tyWj&9NMl@vN{o8aI2eK;`(lM%PPyd!@#Ax#q?_))T=}w#c(5RHRh? z?BgyHG<3A!#lj+~;)FgIDS};lHf4SRysG^o zP!ud;d5{VHFK@9rnmOKz(IPlhQ{D>eb@Ke0L zisg&OP4rTXy2!QT6{{NfGn5L9zLaMF;oF!x$1Q+1}u-%P{d{ z{9Ri-T09weOf8kYBFQ|*40`W~Cz6QjvkriAjPz2K~STsumaU&3i05Lxn`Qt#`0mPe-1)0zk zB>?elAWp_%2nbjL@kSut0>nJn3@QcU`A}~V1H6Iwu-=6GJje#Q0&zP7>A(PLIRhgw zu$h7M4Ioy*qVOXS?}G-g4K(1f0XI-!2jVaU6sVy<{1izn6Nsl_QCk7>njaR4??4=l zW(WvO2jVGM)Z2p$Qp6&05Qy*N@Wx^+V$2|eB(O+)!4tqAu?aHaNH3tY!iK{jS6l}D z#*w-wU=de=rh2Rfox))=D29#!aT+x7febhg#6noqegj4SBp?pJlN~IHNSIqdF4_;o zcNxeBe}Ook2`QhE3nl@Jk{2+8)&ucYG7JHwwQBU-pG6@3U;~Lj*L+7e=n)V%kzmMN zXb!+yu=PPRD=}Uw##ciAg=W?-1Y#)yJ*zO`uq_LZLG{=YF%zB~z7mW0K4`(uK&(L^ zkOHlOVBiJROMgi<2oz31&_eDPw6uJUOEKgB|Nj}N0RRFF0G4%CK&<@Hv;Y7A07*qo IM6N<$f~_dUs{jB1 literal 0 HcmV?d00001 diff --git a/img/icons/Checks1_1x.png b/img/icons/Checks1_1x.png new file mode 100755 index 0000000000000000000000000000000000000000..35b72decb5a18c9c9621eba656dbef1d3a33d803 GIT binary patch literal 362 zcmV-w0hRuVP)P?VgAAvXsmtk-NK`sDdW-NxWLA?p`?k}ie zm+?7(38+a0NS_Dd$yns)1F;j7od`5+A0Z!sTxbu(qClJpG`s@IbuBB+b!KdMT8i4m2!_*wnxR^9~S8K)tsRNq!R$=aQ1};mHOXo2P+T6)JZYh;4zc z`%adDP(!VO)HWdg48-O@!=5sb2rv>hG)Mdb8g`R`3;+;d0EW+9l3kzA{{R3007*qo IM6N<$f~$*&HUIzs literal 0 HcmV?d00001 diff --git a/img/icons/Checks1_2x.png b/img/icons/Checks1_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..86c6f6a8a958670fa9f4b6071ffad991284e7343 GIT binary patch literal 535 zcmV+y0_gpTP)P12qtV zMoqhb0LhbX*FXiV$?JFGPHN#L+nW?(U=F&q@v|hq|841+Fc5?>ZTtcKYVGHeTsKex z)6kp6H3Kl8q76bU*W@a^a-4t=yulM3XPDm(D^RRyAreRP{f^EXn37|aRCP<5xk}rV zIZkZDOd-q2F>tME^{@&)P4kJSx7Qd9@$|L{1H%y4boF-%L#YrJ&52v+A^B&aUCgP0 zD=Dshs1?mG9nLw|TdZH|#WH0;#i>;DE|iHDNSU8dPY#dSwAp<6zyXXyx|`dw_D@Kj zF!c-drqMQ_2}V=&SrSJK?;kRD!euzq#wziGIlqy&vK~>AgOAyJxAQVDyU8eu65Twr$Aya3i-l(0)3THm*iLq1 zNMn(5uGeu)1GGNYH!ub}9UIb^qg+D0GL$JvM#SeW$7rEv&yYXG5Jvf91 zU5_DXK>@Q?JW{WV1A~fp;C(-ZOSpnp7|_9#+L^h?35{KbNBxL#2a7NYJu(XwGx+OP z{JPjgpQN0@yB`U?Ny)=1+Wx=y%nW^Ij`BGeiD_w=i0^I3mjD9*oCCfiJxdWZ00000 LNkvXXu0mjfsO-Pu literal 0 HcmV?d00001 diff --git a/img/icons/Checks2_2x.png b/img/icons/Checks2_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..233b82825d22948d1c48f6e8ca785ce0bdc72aa7 GIT binary patch literal 713 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 literal 0 HcmV?d00001 diff --git a/img/icons/Close_2x.png b/img/icons/Close_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..1a892be1dd5019f6fbbd5526872994c85ea9c46c GIT binary patch literal 1515 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 literal 0 HcmV?d00001 diff --git a/img/icons/DialogListGroupChatIcon_Highlighted@2x.png b/img/icons/DialogListGroupChatIcon_Highlighted@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4991d5bd80070a1ee3ede11194cb60820bb7612f GIT binary patch literal 529 zcmV+s0`C2ZP)_HkOfqg(!$cAYf-BSPBulU}510CWj&@29x!z z-iaJ{JCijgKKQ|HZf5T>ncF!br4$TOpa`DjmoC9Rm}2I$;RKaHLk8;wqHqp)$x5F^6uPzp2NFyb05$-Xmgm0;=%}9*o{#=8=9LGB$2OJR~Qp88_9i zyeOkTCN<|#S(A4FE<)~YhrWr7>Z}vPbyJhO91yR*9L7zj{Tz5C484IBVEJ+__q)lj zD=^!sAsZaY&ZHim12IMqsn{fCNNuzT&gAcO4^BXnh*Oo{@He-2F$@ae2DD{w<$ydG zRbC>Wu7t?Aoj)S_BXy3|)lBpZ)!hjl5&hFU*zydu`)ua>6!H$niufO@d-j TmEKmm00000NkvXXu0mjfsUq6a literal 0 HcmV?d00001 diff --git a/img/icons/DocBlue_1x.png b/img/icons/DocBlue_1x.png new file mode 100755 index 0000000000000000000000000000000000000000..6a85c564b82bdd96553bdcf93fbe45f844e7bc78 GIT binary patch literal 476 zcmV<20VDp2P)}`dcC@>CtCeJr+O`e;bKDF)n7{2)OdIIV+gdMXk1I98fiQ>Z9g3hA=mC0$j?fbO zg`OStJ(;jqI!_VJr?+2XdXh`9SA{*WgwOnfoDbu0+|MpXNLWR4%30tOXbY`yL1Us! zV8`JVFtKHQ2hBAijz)_WcEBP!-$JQ@1EQ(E!K8|{u?1E$`iWiwTVP|g ze{yJGW5P;n16FvcNZ3Yd$5J%g*nP10OkO4Wd+h)VR7e*r;<~1yv8j<%oNa8=s5uU1 zLsDV={i19L+x`Xi3&_KsM zgw53+`ahK1Ecvlld{S`@?4-(Yt~F=OSH@>|{<`{}tPOi)aXtv!4TZ`07GMA)mdX3d SU+_2p0000y55TAOCeeOk?AkhS|C$KVs+(XV*k3C5nRGlE+pxVHN`oKOs z7z8Ow>MP&lOC(vuM*swW@$P!PCjWE$Fm-^}x9{5HHS{OwDfSig9(srU_36v!i#EXB zR1Z1;2aqH5EMSNe^a4P8>7iL5Dubuq1K|?<-8)P){TG0Pkp?|zTMc~&{o@cZ{5xE? z%;Sv&X%>VVLbgGe8n5mB8lP>*{o%bcK(3YmTsz=e&wDL{9L9N`8}QG}1-LHcWmp^? zdin1y>P0hg1+UO^X$%~JY;iT)32!F@3UCQ}qGR5Dz`phj`HlSlIEM!-2A7kZvvu$n zPNKomQ?V6Jy;!pa7Y_*Dt7sSy?nJK7JlRRjYdni4q24x;aG3&EVMuN3*lJEk6!CF@ z0$eG;ark>&IE9pBLb-|q1h|YDKSACU3LJ+o+2WBF-I|3u3=rWe2A8wk%D4a!>ZR6b zPG5on1-M#(s~B7^40V(MNPCe=j`6@fFykFHE_v1g$HV`X+1ZouUTDcN3S5fig2HXA zZgapF!cfmbZnkWa)O&?jup%7Y{5hQXoNW4`;rHeCtp^3;{X%ftkO&w@vWCL-4!EtB zyI8C%SNiw>4`|TBb)-&J0dS&mMc6vwL_h@E2yi#D%0BlQCzDXqC+e%t2S>i@xbX{a zb5zp*Amzk0$dwb}5*Q`#Xmvjbo=XCZABE@j7>Q>TWnuHF1-QK<{F-r}u$=_>iLykh>WuBLqv15b zRQOJC3D*NNz8AD%8T)1CEi=4`VlJMD@jcsrUjpRUWWb(@2M(QMJ&X~qvjF~dNO1~T zDsb%_a2jCE&Pr0xsTLOpySa|cjB=pU`p)j)-j;ocyR>0+)6S@K+}u}oqX(dxg#VGP z_SxaQYDN&Kt`-dk(TXoK80ve^L1ejv=WP2ezyNFkcTaWKXA=Mb002ovPDHLkV1oS) BmLdQE literal 0 HcmV?d00001 diff --git a/img/icons/DocGrey_1x.png b/img/icons/DocGrey_1x.png new file mode 100755 index 0000000000000000000000000000000000000000..8835c3b49f89160f75b799ebd76428d36f0cf49d GIT binary patch literal 474 zcmV<00VV#4P);eysgnZS<2 z8(?C~`T<&KL>#RaE9`+qbiRjD0}Gf#Sv#7G^wQ%Q(1S@88)FNsVe~V-1h&AYYX9WW zz@~&%)&{KfQjxHY)Q+WSwy}p`@rArf^pDyB7O0RuSj2TrMQc+dskqqKrct*zn2$+? z_4kXiA#C>-*e@V+^eW}YLC58i&RaTHwAXzwKf=^N`l2oME3to`cJHri=*il!Cl=>}u)|oGjBf!30CO?QJt|<4 QhX4Qo07*qoM6N<$f@nO|EdT%j literal 0 HcmV?d00001 diff --git a/img/icons/DocGrey_2x.png b/img/icons/DocGrey_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..7bcc7642d20a3eda224343fde81d757c0e923afa GIT binary patch literal 898 zcmV-|1AY97P)EyAc1A3?WMYXd;C9b>Y zY3Kz{53-=4x@W*pIaAHZlJ$34aK)C=;A-h!F0-ybeQ5d}fQDU{h-XKt^UhmTmsEdH z{Ymu|U`q{hIx<`(?i&Wn_!`~%!k`U6nnwUyxJ1A$6)-F<#oiqH?Z*b30bI*gYkRz7 zDf%zSii=SI=|u^|TpMY*t3p=n#=VJ0f9?ikxQgBDg6rD09B-kNQ$YS44yeF&Wi8;W zWltPaJMMpiF=)j`gw0(Re20lL&T$s5;(QodOgD>07{Lqzq=6;4E8|=zSD}GCScu6J zwrHp%y#X06^}uQEUClW@T1+Ji%_~3GYZ?qUwLg32P(@3}!CO;BfF798j z9ag1v*~~M?O2lRz4ajgMz-8h-g_t_BTe0i~z=zWQS6qKa0V;4G5>A76z@hu!U>=z# zTloRgfXPdUAs<}hfZHnWui-t?1FxJD-GY^K(9Py=2Xgxf;Fik%8?vzGp|w{mM8Z`g zz!^|3ss}U|?{M>1;1Z$hG&n6h@{l}}uJr+CJTby)vTCis83j&$g!+*hoC?St*F324 z$tv3(AzWLJc3ivQqE2-#Sta0Ia4k#v7DR*zd}REY#3iegm%4)s%6|a{ Y0P47awlYa~O8@`>07*qoM6N<$g5{B$>;M1& literal 0 HcmV?d00001 diff --git a/img/icons/Location_Active.png b/img/icons/Location_Active.png new file mode 100755 index 0000000000000000000000000000000000000000..9878efba9ccc37dc5a4280ffa097c6d3b52e75e8 GIT binary patch literal 574 zcmV-E0>S->P)9UOoaP>~meBhUx7!MVYV)B)zeT{K&cnGEw_#`3N%P=IMdWw;2& zt;R*W%EL4w8}@;WA*l$C`BGF0fUImt=h3DJq#GRqQ7{U+K?-~-Vq>Us*v};=6aiH* z#?{H%mn(88A-KOnip3*^nXMeR&YyM@8Z*mqUZfg$QauDRY}X|98w>-QLR!i2OOq5g zm`-zZJJm^sm*88mNVi^ayci#M#Jc7~w{*)N-~sd~0>W%c=k?4L2MtHDBcxk%n>qt7 zX0PDTHrxeoR&&Z=l+|oQ>imT!%&xfM>xRP~IQxegy{IXwPBp$#9MFhXVOG@5!xC6) zz^uemTRUJ$OW@k$R+Ff%>Sp*Gs2NeR(y9*&!&cG;vlFnTS`db$949(OFJ@AgBwV(Y zbc``-jS2AbU&9I;RHbt>_Nw2*ZC-$R`e%R*w_xG1-*UWtSN#Yu0L}elc9<2bA^-pY M07*qoM6N<$f)}0ojsO4v literal 0 HcmV?d00001 diff --git a/img/icons/Logo_1x.png b/img/icons/Logo_1x.png new file mode 100755 index 0000000000000000000000000000000000000000..f099252dbf8727981b381af55271d7609668cfb8 GIT binary patch literal 1550 zcmV+p2J!icP)`lH%4Mk~Esw^^q77)Lj!b z7((J2VeDbjQzp|M)+4gn=rn{ z0=4TUZUw_*V=yPrI&TkDucsW~?(21Jt6^LjOq+5&Yfy7n5VYkC`w5B}rjGP%_qkQ_QA(S~mfWF;4X zak*Gr!)OPXJZU1-Et~^O@0tx$t3&6{AME|ji!>p;zH3r&uT=R_tP#`XynUs)O0ktC zEtTUd;C}N~sJ$}+^CP#ow%N7s2bn}gR#GmOW4oNcqLLF+w!XT1?sRy0-AdT;*3o;UG0OU?n#R{e(fDp)-KHf0TF_IFE%NKK@Pm2DG+q;RDRMY&~> z!XoF9>w+wya6wuliK#6(uGhWLL}@z7c2j6IVI-#2(XXBmoWc7}kdV-c=VF|=3NLLO z=^IeiAh)#kgE`se6`F{PlGSQDN(2+HTP_L~vC<$GlP8vwCy5VDgwh3wOF6RJJT8JT zu_|zJ$3Te8I-Y@E=VOF9aYJ6(cyD_fb9*^xdNc}=X;Y*$`0e*U!^u;pWfiXLl~0(& zxR_)gll0AaSdKA@jMa9DpJ60WTkXh+J6fng_o3e*{_56|4DzXm?u8pe*A*O4BAcYr zr#U%EJKT>ru&JRFpuhNMWBKwVLP?B{8rO z+t?(@X_UODMq<@T$7VuF+iqp}u@HZ0`jtw@m5b&=V$FrkkDkMQ(6I3X+3tL?@H(T{ zhmVB}qI6p!v7lLHu_QuRpoOJ`%-C9!6Y*N-YlaS$j-R)8!7so5N!;X*s@B%)({4~6 z-DXxX8x(ykm+Uj<_}}ajyNZpi^=$-wANQ%$CFF^LhcW%xEq4`Lg`kwCTn%D(~(07P7d{X-4H`v3p{07*qoM6N<$g0^bq AQUCw| literal 0 HcmV?d00001 diff --git a/img/icons/Logo_2x.png b/img/icons/Logo_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..f93dd4ecc7c6aeae2c4747c993ccf89405c8d4b6 GIT binary patch literal 2857 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 Hu0mjfqrQ6p literal 0 HcmV?d00001 diff --git a/img/icons/NoResults.png b/img/icons/NoResults.png new file mode 100755 index 0000000000000000000000000000000000000000..9b6747ecd5f0f15b97a12f469a8ace260c1a22a2 GIT binary patch literal 4655 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 Z3;>r&bJa?K&H(@b002ovPDHLkV1mK=v6lb< literal 0 HcmV?d00001 diff --git a/img/icons/Search_2x.png b/img/icons/Search_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..e920e66e4ecd13ea0375275038d172c2d4737774 GIT binary patch literal 706 zcmV;z0zLhSP)lSlXadT3`U?orYoE^- zOlRwILJYzls3o8-!_rq^78}^hi5P?)s10B&%e@AGQEcElYhorn1v-pZ6j};tjGxN^ zp9sAz6#jObyf}+puN$OsU=dh=vmaxVMNreg9N^(;%7YzXNd3idM1&V&>J1nMVJL%L zJ=8u>Bc_L77tj(vLN$ueHpBQ?c|=uE4}1i6!qvJJhE0N$WLZl}g0&Q#c`;Q@N9NYp ziZLa|nu9C934DrYzlOM8jGyoYAK9{UCf`e+8sbVZj#|z|+E!?Y<6>Nt1MweQ4e`4e z*W^GfZKE3ECo!%=mU|u4_Hr&DNuL_xBjb76!Pib1p+3?UkQ=C0apv9swLHVN1?oza z&M<5n+{zu#7)f#fhkj+hJ{F`&U)m-yXgrsaLpa`sUNI{fmq`lmxIwy#wI>;y1b3M& zU_{aI-}x9S(qup7$^eMt{}O|=1Zo%PGhV$oxK^vcq)nPO)F7o$9;Rsemq0HQFBx?_ zmE1C6DC4gW-?>xc-r0W;U2yU#)>1j`=Xzeri5KCh1h6)u`q^Vg=P7>T!aye+#jHF@ zv5|>%-@GXjr#qjdNn$3wzvIKAicH0NZ5V0U=kq@c;k-07*qoM6N<$f`LRe761SM literal 0 HcmV?d00001 diff --git a/img/icons/Smile_1x.png b/img/icons/Smile_1x.png new file mode 100755 index 0000000000000000000000000000000000000000..29c057a316d47634803cc0bd47c193a8820bc2c0 GIT binary patch literal 773 zcmV+g1N!`lP)lX#At3D+TM`ryaBxnFbNo%`N%UT^ZN>v&SwYuS*M31GAzS(`Bl7_p zI0w!t(>bskIpjcwyYksmj9d_yb()tQm%pd^7)sBL5%BZ6a zZH-@A&us>Np_duE)!}#@jxU?d=1l||)8RD4Ic3z*hPI*p=2(yEFsZ1Yr`2{l;4XMn zuh$o&(dca~|0g|KtyThoM_EVN?EGsf-w*s5tKgcWkK;ZVroX!4H28o(UZc@S63!`; zjy5d>9hNW00yaw}W?Jj2_WCnqHHQpY*e~D$OW-)pNg87LpYh0{2Cygh`t ztXbU*taT9%89>K<@C%uKBAiP`T}B&gM!vJbfo~6bDki~u{oPk!MO!{)>{61g$R;hH z&RKlW)s)kTcbKbbk);e@O-`T7G~4GgE%drf{|Ybwh&~8<;o%eH00000NkvXXu0mjf D><3<_ literal 0 HcmV?d00001 diff --git a/img/icons/Smile_2x.png b/img/icons/Smile_2x.png new file mode 100755 index 0000000000000000000000000000000000000000..f6103f12997d4d1f628d14795278d3e321accef6 GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/img/icons/VideoIcon.png b/img/icons/VideoIcon.png new file mode 100755 index 0000000000000000000000000000000000000000..ea9482b45ff9c6b41abacf4a121a910ea810b590 GIT binary patch literal 321 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

6MdmZc zOwKY?dF1>vs{U(U{;MFs<3<-0Ld=PYzE6AyclSL2YF8Lsc&p!ID*d>|{#Vca8+!_S U(cPo?)Bpeg07*qoM6N<$g7e5})&Kwi literal 0 HcmV?d00001 diff --git a/img/icons/icon16.png b/img/icons/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..249892e1d4cd770af0597af23582dc2f5be8fc35 GIT binary patch literal 4262 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 literal 0 HcmV?d00001 diff --git a/img/placeholders/GroupAvatar1@2x.png b/img/placeholders/GroupAvatar1@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..99a1762ba18620f772b0e6f2377ef48d11d0a243 GIT binary patch literal 1834 zcmV+_2i5qAP){ZTg$|91xmOq&rBpfrq%3j=5aPzcyO>5%f*R#Jem&4-!h&#Rr473 z=F`GULrFa#fj=9(ry_MTyt(_X_xf_wco2~_4g7)Ev;9Go{o8Wtv%o(n9Nt@4me+4N z7ob5XzrOEw6iM039^5xr5DPWCI&gcqGiZ;RdA+uV`{I7FYuOi+?~_9{ocs&#c>32&?~k!DKdutL2;*^zvTzNm4eDVM*d90x(=e z-Rw}+Lv2qeuTZzyzWFHobUVF=De$5oih}fimR^WT+cQszN!=81jo}$Y8M0=nlIF*p zt=QrhcHG7A6n5W&Rq`%J7pkn4jcqiam86$L+QFcV5KvX~$aK4lXvqN*La>;l!P>yN z14CqW#!XOb6iZCfi6n)k$$H$d6j7mlOBb)UAGqDMdPfQ?rDkG>MS1Y!2Oi1ZArCHZ zKEcu~U5?p6fXd#X<4;_l4B)_mkyf)Ys=FXS!o3s6Pu?sbf;A6kRr7c}8^xIl#Wv+( z54a@k&c_@9mgSp{Zy^fAZ6+WDb4b-M6$BA`4hsZWvzVJ%pA~Kt!Hce;IN1=T#3fX& z__8NKRVU%phMR#U(Nv(Cl%#@7;5h{ZSexlOT)T%PRTyd#rd5_D1pyXqQfD5tMU}2# z!dknpiC|^4+y+R2WWdg%dP@q``l+Id6Il_v*JMjVedoA7Sz8yUq{>}M@5Bu&ua~G^ z-=DPK^Km7-pzddq0$;Lc$*9okoqCq{+^splYn7++WG zQFfoUa~-{BPwPu%8coUlu=TS$AHVCqK|FIU=w)3=l~dH)JdQJ`)h3DBK!MVO-cLiE z0toExv%*U@ZyAUCTb+(stU2OlOsN@W7jCG?2^vB*xw0Y51`F*ey{wkMllQW%91E;8 zUW+-cu^T0b0^H~6^Li1-XMK5xIh4{Gv@c?7e=qX{&%4NFV+S7=kRmyfB*=rMh#3u7 zzpDJSmD-J}>vD2Ge<+D-ybEJOd7OJTnUA8J*+JF1gAo@gHEpP=euQ(@YvMnW^>Ek{ zhafyJzKYVTJS=^W)#`-sjM9D}Zxe`76o)x9pa90L%%gl-jyOw1(rM;`Bcmaosxh}8 zAiBwuOe9#A*JsW8$TcQ-2$}x$|2nLSZw$Ah>q3bQ=03_nfNl!~$!%T%K9gc{pRfv8Hp5@~F^P1rUXy zhcJXaNVg$qCloB^RrBrYCK*X!o|td@ZU-0Eh~{e`s;tp^7rIx2PMr@wu6P!h26|Ap zPI}|^e*Q%YqkjMk&>1%=1WTZHc@&Y=om|$eDhjEaan(xfy{<*u)StHYupZD@nQ7?J z{!+r@`|#ZUcwwK$^raNj?H+ahXpb6f&k4Y+V0y5YlqNC!&_AN$wLTPwz6Ddc^$#{6 z4p@(-Q}2vhTj||OYKPo3!Nedi*}m5f*5|16`*wP7C-a!(1VCPm36{&*;MXQ0d$gQ$ z2(hBEwVmEw>s{UXK!)&vAc9qjTa_Y|>*3#lrpdaYq(ErA zIF}Pv0z?o56r>a4`tzqnAFHKc zYQrTDWkAON*cfTO0k($2inEaBu=wDxI4ll}!{V?wEIv3a4vWL$usAFZiw_P9d;BH9 Y015#QcyQl2J^%m!07*qoM6N<$f*KKU#sB~S literal 0 HcmV?d00001 diff --git a/img/placeholders/GroupAvatar2@2x.png b/img/placeholders/GroupAvatar2@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..85619a500c21ed3928d2975b991fd069c1a512f6 GIT binary patch literal 1781 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 M07*qoM6N<$f-{RPDF6Tf literal 0 HcmV?d00001 diff --git a/img/placeholders/GroupAvatar4@2x.png b/img/placeholders/GroupAvatar4@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..b87915554c0f0df661895d7002a55115f088dccf GIT binary patch literal 1680 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 B+>ihO literal 0 HcmV?d00001 diff --git a/img/placeholders/UserAvatar2@2x.png b/img/placeholders/UserAvatar2@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..ac3cb9ec33b147b91e33e48e1b0b0b6023fcf0b7 GIT binary patch literal 1569 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 literal 0 HcmV?d00001 diff --git a/img/placeholders/UserAvatar4@2x.png b/img/placeholders/UserAvatar4@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..7e697fbe5fd77a068a036645f8b8ac6118e611ff GIT binary patch literal 1477 zcmV;$1v>hPP)nUVkn&VUiy>EZd9lsQbT9UX+(h zr;)e%a?23Uh6jT##A%c2uvmLA|Ks7{KwwpMy>h~hx0Nm5!BJe@c|R_u#y}H(8J1Oj zxxBY&NIhHq>$Qhh;bCE!G`sHJlr%3lek?YuAkGjRG5HNQs)dGy=$y?@E6s|!$0`gls!X;nO6G7k%L{6sNCm5^nHB3H=E{mnOjs2+tfxFd zNLY0Xtl(9|)GS$&_+e4c5EU$`jf!R^sDW48sQ-%U4OOKDSQ7Etr+TD*8)b4?P*{pA z^LJvXoeJUe@b_S-r-$&}`B$Q%2n$Q^bNAUaabfY)#b3KZu{BF#jN|(%dDE2;792U} zO4R80k5Iu1;_UAmC(R1Rl0)T&iIA{tFN)Hfv#OQm#r4|9t9Y;yMxA<{8~RZu9;~{R zf|j@jz7-*LzjUyqR$!54Jai?Rc3_ciK&67EwX|z?KpELl!D7yJo^wOey^~b1Mn<0> zmQFlFgqp=)b+CwMh|qV;#|CrNfqK6rA*?ATnz8;j8|kXJB^p@T-%c>u9F`uK&L$@L zr;xt;P}hEZn`K4$bLA3ci|~M^(T5f@G~YOEFakwW?-Ri~pIZ}CKd9W0uG7OA&~d?{ z2_ujva2~K@g7r|37cj7D2iC)3O9JIGb?pFQQD^}sV8nH5ha1+^(wps!ffVzWIX+ke zO}&^|4JJ3IlOc2N$y!!Mw%Anq_HAzQC+gfa`0uCV{bMd*nvIMeyKuu&WXUr2RW7!W zy=7Rv$8PBUDd$nZDywS$LpE&{__<+i{CNNVt0GB<5349E+il{=X*;YKVL_o5Yp;Bty1MZZZjkU4mkCd@E^MEa)U)Jeb#>=mE*ziUb<1@1}W(_;oStm%5|DAH!{{GmgoMx@f~5ols??U z7k))X|4-ea@)$5=Q_GlIyKjk5KWma;kFeIVqU?z#a5(VJD<>EY2h)+U!w#}-VMR%f z$$>VBzGoZX{^@Q?O_66K17mwd`xq81B?7-z4gpX{XGk!SHo=_D$3tU_ioW{3fxOuS z47Y`~t7uQr#!%Nz#>4mfDR0AqNy74m{q7x&z|O#{>wWcNKKfOo`wdvgPLVxOUsduo z1=a>>6Fk8A3~7M+0jxVWymP|3chvGw&xq2~sd+Xvr8g640J>g#tD`6NOar$6pQTg2 zx~}O3*3$NwFO>cIg5>-)um51#Uc_^IrEn5w#f|O1z(R0v>x3PbcOuQ;v3nptwGs~U zEMT;^$F=< fb+BmUUjYUH0ko?d{(sl|00000NkvXXu0mjfR7=sd literal 0 HcmV?d00001 diff --git a/img/placeholders/UserAvatar5@2x.png b/img/placeholders/UserAvatar5@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..de984d8b91ce9aea13edc8d472d777ba97a5f825 GIT binary patch literal 1398 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 ZFaRT_xM3AOqzeE5002ovPDHLkV1g*r-d_L! literal 0 HcmV?d00001 diff --git a/img/placeholders/UserAvatar7@2x.png b/img/placeholders/UserAvatar7@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..bf6e73f16d948071df94c135ebc90925f5fa48eb GIT binary patch literal 1477 zcmV;$1v>hPP)+jE+lGTJO1PYddrC=#o3YLPU5GYtEV)XtC>ZVDnI;%uki-$Sn%rcG%_~WK+gS>>nn6~TK zheKyz=-UFTZMBm{80O_GJ~&Tv7<;aLH1_DVtOo~w?nkd6^`ii2= zSpPYtXpUz=Cy#n_W(e;F>HxZsmUWj(x`=efc5G`yV1awSjMCX^zWfyn#XpPiCMj5Yfm93sN?ESlBa!1*;EM=(djq%iuj!%34iMSY{uvn8u`p)k~S2b2(w@ zoNZo>9P#-!xpL{qwvYJqfld#L$qLIcsrT7TU0Tg@Et7O9Wa#kdA28=~gYSg^(eiyoGX zoG>727Jb!Wggirt?(o2~iK`A1M_O2Wu1#5q-*;_^OElnVKTL)miKholha(sLTTq|w zS?0%sNh!q1JVMGAVFd(NwdW29Hs2_w-O}};Wg@|PKlXN=!A9kVwyC2jFWs6;1q&yz zwscN;z>WykT|HjHz^WfuoG}|AMjZ{z4TQB!fXvP(U~F5P32WE2yWJTBQk=F8j1HD< z=ttvWhsn*mp+lT|l9uQoTkPt%+n+l_n>kz>ipzwnqNgJJuHg2u2?n$b$hZLU}aVPe(X_}`O#s`lKdi!G5WNE zybO!-H_v%Da%qx8Tv*p}b{Qt9)_oIai>#n2E~E8lwJo@FR8kL%tY}Ub(eW(Ekvr&6 zG%GGEAXU_K4W;*A`f2L#x`-ESbquR+n#(YS)vA}Jz16;5umvUwzO3`+l+GTP*8-yR zd0I4W{|%Dh#b5xe1J9XsS0h{(7TB7<{AD?<(XAp7teln61!tgWyN1Hq^Y@|i{C>*Qu)rmK4O5@?uEu@^{LIO`a!liB$NRss^%JllJB92) zG_AIM0^SDFCeW`x#@^#I-ao?v8wN|>MovG~GxG9qjk1< fDOfo2p8x{@8xELgk6Sc=00000NkvXXu0mjfHnqm6 literal 0 HcmV?d00001 diff --git a/img/placeholders/UserAvatar8@2x.png b/img/placeholders/UserAvatar8@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..614b75ef12530dc3909057a41e19834106ee5e90 GIT binary patch literal 1426 zcmV;D1#S9?P)PC$BIPt;5`lyzVM$mLmV_l?NdyuWifFz6f^D;{@~SGTrm9~)95JTpnySHd ztd3O)O94Q9lVovr{A(jNnphLVHQ~xsc8jp$b(Cz9Q@+`5+dRpkjYcCt=G-};bhiSl zZCn4lU-0~lKg^;OnmM&*_fs&{;XC;7DL8}FTLE6HKUZZ|4jdNuc@|}t->0b??_u4^ zt**`t;oY(@EwZxeR2_n)5ANS^jDf%cM-#7O?k7n14<7x+x5e1dg*U@?yY(JCJW~74 z2$lg{g@*;NQRV1vxGw87NX3R#@B)G(s&OL`8&*Q{0xtsy^o^*nz+07Rp%6;Wb5UVc zMNJ&R5%dkivkPKa;O4Q%L_9NW6>@2+Mo?JW9$?ji!sc6CG{VL{5)11;npLW4Ex z0T#CHW5MdB{@V(wS*q3pENpE?gEj7I8P3zueJ6)vn~lf>%?)w;Q#Lz&fy$AGFnJAi7W+jk9U9ouZp{u`E=G4MFV5{SsLSz8i1f!MG zll(Yf%Qfv!cIS&zI)nA!87CYtwY}{4{U5S8g9fm6MIpDd8sVj|>Z%6+nnfA0(VZd? ztOU!Ft(f7O=G44=((FuF;7YS32TWJU=)GsyseHh}k%33ErsvOHYrp*9aA#}SCnzAr z#^6t(8IEDitTW1Lr^14<2091gz-w?xmq)YER80kB*33R#(LRO+o|12pUN!+>M`w^= zLIZbZ&z)0N4Qj_7WcVBroEFye&>8IpDBaZUPtNiAl*6#VB}MBfk2B?F1pG{yZN`)F z^nRxQWT)f-Sdg6tOCS5FlIs-kHjp-fejTi5XzxY|dcenBKG g2}{E2UH%nd0L_}063LVE5dZ)H07*qoM6N<$f*p&cjQ{`u literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 00000000..1a806b4c --- /dev/null +++ b/index.html @@ -0,0 +1,45 @@ + + + + + + Webogram + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/js/app.js b/js/app.js new file mode 100644 index 00000000..828de512 --- /dev/null +++ b/js/app.js @@ -0,0 +1,55 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +'use strict'; + +// window._testMode = 1; + + +// Declare app level module which depends on filters, and services +angular.module('myApp', [ + 'ngRoute', + 'ngAnimate', + 'ngSanitize', + 'ui.bootstrap', + 'myApp.filters', + 'myApp.services', + 'mtproto.services', + 'myApp.directives', + 'myApp.controllers' +]). +config(['$locationProvider', '$routeProvider', '$compileProvider', function($locationProvider, $routeProvider, $compileProvider) { + + var icons = {}, reverseIcons = {}, i, j, hex, name, dataItem, + ranges = [[0x1f600, 0x1f637], [0x270a, 0x270c], [0x1f446, 0x1f450]]; + + for (j in ranges) { + for (i = ranges[j][0]; i <= ranges[j][1]; i++) { + hex = i.toString(16); + if (dataItem = Config.Emoji[hex]) { + name = dataItem[1][0]; + icons[':' + name + ':'] = hex + '.png'; + reverseIcons[name] = dataItem[0]; + } + } + } + + $.emojiarea.path = 'vendor/gemoji/images'; + $.emojiarea.icons = icons; + $.emojiarea.reverseIcons = reverseIcons; + + $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|blob|filesystem|chrome-extension):|data:image\//); + $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|file|mailto|blob|filesystem|chrome-extension):|data:image\//); + + + // $locationProvider.html5Mode(true); + $routeProvider.when('/', {templateUrl: 'partials/welcome.html', controller: 'AppWelcomeController'}); + $routeProvider.when('/login', {templateUrl: 'partials/login.html', controller: 'AppLoginController'}); + $routeProvider.when('/im', {templateUrl: 'partials/im.html', controller: 'AppIMController', reloadOnSearch: false}); + $routeProvider.otherwise({redirectTo: '/'}); + +}]); diff --git a/js/background.js b/js/background.js new file mode 100644 index 00000000..71f326cc --- /dev/null +++ b/js/background.js @@ -0,0 +1,18 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +chrome.app.runtime.onLaunched.addListener(function(launchData) { + chrome.app.window.create('../index.html', { + bounds: { + width: 1100, + height: 700 + }, + minWidth: 1100, + minHeight: 700, + frame: 'chrome' + }); +}); \ No newline at end of file diff --git a/js/controllers.js b/js/controllers.js new file mode 100644 index 00000000..15c8bcdd --- /dev/null +++ b/js/controllers.js @@ -0,0 +1,507 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +'use strict'; + +/* Controllers */ + +angular.module('myApp.controllers', []) + + .controller('AppWelcomeController', function($scope, $location, MtpApiManager) { + MtpApiManager.getUserID().then(function (id) { + if (id) { + $location.path('/im'); + } else { + $location.path('/login'); + } + }); + }) + + .controller('AppLoginController', function ($scope, $location, MtpApiManager) { + var dcID = 1; + + $scope.credentials = {}; + + function saveAuth (result) { + MtpApiManager.setUserAuth(dcID, { + expires: result.expires, + id: result.user.id + }); + + $location.path('/im'); + }; + + $scope.sendCode = function () { + MtpApiManager.invokeApi('auth.sendCode', { + phone_number: $scope.credentials.phone_number, + sms_type: 0, + api_id: 2496, + api_hash: '8da85b0d5bfe62527e5b244c209159c3' + }, {dcID: dcID}).then(function (sentCode) { + + $scope.credentials.phone_code_hash = sentCode.phone_code_hash; + $scope.credentials.phone_occupied = sentCode.phone_registered; + $scope.error = {}; + + }, function (error) { + dLog('sendCode', error); + if (error.code == 303) { + var newDcID = error.type.match(/^(PHONE_MIGRATE_|NETWORK_MIGRATE_)(\d+)/)[2]; + if (newDcID != dcID) { + dcID = newDcID; + $scope.sendCode(); + return; + } + } + switch (error.type) { + case 'PHONE_NUMBER_INVALID': + $scope.error = {field: 'phone'}; + break; + } + }); + } + + $scope.logIn = function (forceSignUp) { + var method = 'auth.signIn', params = { + phone_number: $scope.credentials.phone_number, + phone_code_hash: $scope.credentials.phone_code_hash, + phone_code: $scope.credentials.phone_code + }; + if (forceSignUp) { + method = 'auth.signUp'; + angular.extend(params, { + first_name: $scope.credentials.first_name, + last_name: $scope.credentials.last_name + }); + } + + MtpApiManager.invokeApi(method, params, {dcID: dcID}).then(saveAuth, function (error) { + if (error.code == 400 && error.type == 'PHONE_NUMBER_UNOCCUPIED') { + return $scope.logIn(true); + } else if (error.code == 400 && error.type == 'PHONE_NUMBER_UNOCCUPIED') { + return $scope.logIn(false); + } + + switch (error.type) { + case 'FIRSTNAME_INVALID': + $scope.error = {field: 'first_name'}; + break; + case 'LASTNAME_INVALID': + $scope.error = {field: 'last_name'}; + break; + case 'PHONE_CODE_INVALID': + $scope.error = {field: 'phone_code'}; + break; + } + }); + + }; + }) + + .controller('AppIMController', function ($scope, $location, $routeParams, MtpApiManager) { + + $scope.$on('$routeUpdate', updateCurDialog); + + $scope.isLoggedIn = true; + $scope.logOut = function () { + MtpApiManager.logOut().then(function () { + $location.path('/login'); + }); + } + + updateCurDialog(); + + + function updateCurDialog() { + $scope.curDialog = { + peer: $routeParams.p || false + }; + } + }) + + .controller('AppImDialogsController', function ($scope, $location, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager) { + + $scope.dialogs = []; + + var offset = 0, + hasMore = false, + limit = 20; + + + MtpApiManager.invokeApi('account.updateStatus', {offline: false}); + $scope.$on('dialogs_need_more', function () { + showMoreDialogs(); + }); + + $scope.$on('dialog_unread', function (e, dialog) { + angular.forEach($scope.dialogs, function(curDialog) { + if (curDialog.peerID == dialog.peerID) { + curDialog.unreadCount = dialog.unread_count; + } + }); + }); + + $scope.$on('dialogs_update', function (e, dialog) { + var pos = false; + angular.forEach($scope.dialogs, function(curDialog, curPos) { + if (curDialog.peerID == dialog.peerID) { + pos = curPos; + } + }); + + var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count); + if (pos !== false) { + var prev = $scope.dialogs.splice(pos, 1); + wrappedDialog = angular.extend(prev[0], wrappedDialog); + offset++; + } + $scope.dialogs.unshift(wrappedDialog); + }); + + loadDialogs(); + + + + function loadDialogs (startLimit) { + offset = 0; + hasMore = false; + startLimit = startLimit || limit; + + AppMessagesManager.getDialogs(offset, startLimit).then(function (dialogsResult) { + offset += startLimit; + hasMore = offset < dialogsResult.count; + + $scope.dialogs = []; + angular.forEach(dialogsResult.dialogs, function (dialog) { + $scope.dialogs.push(AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count)); + }); + + $scope.$broadcast('ui_dialogs_change'); + }, function (error) { + if (error.code == 401) { + $location.path('/login'); + } + }); + } + + function showMoreDialogs () { + if (!hasMore || !offset) { + return; + } + + AppMessagesManager.getDialogs(offset, limit).then(function (dialogsResult) { + offset += limit; + hasMore = offset < dialogsResult.count; + + angular.forEach(dialogsResult.dialogs, function (dialog) { + $scope.dialogs.push(AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count)); + }); + + $scope.$broadcast('ui_dialogs_append'); + }); + } + + }) + + .controller('AppImHistoryController', function ($scope, $location, $timeout, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager) { + + $scope.$watch('curDialog.peer', applyDialogSelect); + + ApiUpdatesManager.attach(); + + $scope.history = []; + $scope.typing = {}; + + var peerID, offset, hasMore, maxID, limit = 20; + + function applyDialogSelect (newPeer) { + newPeer = newPeer || $scope.curDialog.peer || ''; + + peerID = AppPeersManager.getPeerID(newPeer); + + $scope.curDialog.peerID = peerID; + $scope.curDialog.inputPeer = AppPeersManager.getInputPeer(newPeer); + + if (peerID) { + loadHistory(peerID); + } else { + showEmptyHistory(); + } + } + + function showMoreHistory () { + if (!hasMore || !offset) { + return; + } + + console.trace('load history'); + AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID, limit).then(function (historyResult) { + offset += limit; + hasMore = offset < historyResult.count; + maxID = historyResult.history[historyResult.history.length - 1]; + + angular.forEach(historyResult.history, function (id) { + $scope.history.unshift(AppMessagesManager.wrapForHistory(id)); + }); + + $scope.$broadcast('ui_history_prepend'); + }, function () { + $scope.state = {error: true}; + }); + } + + function loadHistory () { + hasMore = false; + offset = 0; + maxID = 0; + + AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID, limit).then(function (historyResult) { + offset += limit; + hasMore = offset < historyResult.count; + maxID = historyResult.history[historyResult.history.length - 1]; + + $scope.history = []; + angular.forEach(historyResult.history, function (id) { + $scope.history.push(AppMessagesManager.wrapForHistory(id)); + }); + $scope.history.reverse(); + + $scope.historyPeer = { + id: peerID, + data: AppPeersManager.getPeer(peerID), + photo: AppPeersManager.getPeerPhoto(peerID, 'User', 'Group') + }; + + $scope.typing = {}; + + MtpApiManager.getUserID().then(function (id) { + $scope.ownPhoto = AppUsersManager.getUserPhoto(id, 'User'); + }); + + $scope.state = {loaded: true}; + + $scope.$broadcast('ui_history_change'); + + AppMessagesManager.readHistory($scope.curDialog.inputPeer); + }, function () { + $scope.state = {error: true}; + }); + } + + function showEmptyHistory () { + $scope.state = {notSelected: true}; + $scope.history = []; + } + + + + var typingTimeouts = {}; + + $scope.$on('history_append', function (e, addedMessage) { + if (addedMessage.peerID == $scope.curDialog.peerID) { + dLog('append', addedMessage); + // console.trace(); + $scope.history.push(AppMessagesManager.wrapForHistory(addedMessage.messageID)); + $scope.typing = {}; + $scope.$broadcast('ui_history_append'); + offset++ + } + }); + + $scope.$on('apiUpdate', function (e, update) { + // dLog('on apiUpdate inline', update); + switch (update._) { + case 'updateUserTyping': + if (update.user_id == $scope.curDialog.peerID) { + $scope.typing = {user: AppUsersManager.getUser(update.user_id)}; + + $timeout.cancel(typingTimeouts[update.user_id]); + + typingTimeouts[update.user_id] = $timeout(function () { + $scope.typing = {}; + }, 6000); + } + break; + + case 'updateChatUserTyping': + if (-update.chat_id == $scope.curDialog.peerID) { + $scope.typing = {user: AppUsersManager.getUser(update.user_id)}; + + $timeout.cancel(typingTimeouts[update.user_id]); + + typingTimeouts[update.user_id] = $timeout(function () { + $scope.typing = {}; + }, 6000); + } + break; + } + }); + + $scope.$on('history_need_more', function () { + showMoreHistory(); + }); + + }) + + .controller('AppImPanelController', function($scope) { + $scope.$on('user_update', angular.noop); + }) + + .controller('AppImSendController', function ($scope, MtpApiManager, AppPeersManager, AppMessagesManager, ApiUpdatesManager, MtpApiFileManager) { + + $scope.$watch('curDialog.peer', resetDraft); + $scope.$on('user_update', angular.noop); + + $scope.draftMessage = {text: ''}; + + var lastTyping = false; + $scope.$watch('draftMessage.text', function (newVal) { + AppMessagesManager.readHistory($scope.curDialog.inputPeer); + + var now = +new Date(); + if (newVal === undefined || !newVal.length || now - lastTyping < 6000) { + return; + } + lastTyping = now; + + MtpApiManager.invokeApi('messages.setTyping', { + peer: $scope.curDialog.inputPeer, + typing: true + }); + }); + + $scope.sendMessage = sendMessage; + + $scope.$watch('draftMessage.files', onFilesSelected); + + function sendMessage (e) { + cancelEvent(e); + + var text = $scope.draftMessage.text; + + if ($scope.draftMessage.sending || !text.length) { + return false; + } + + text = text.replace(/:\s*(.+?)\s*:/g, function (all, name) { + var utfChar = $.emojiarea.reverseIcons[name]; + if (utfChar !== undefined) { + return utfChar; + } + return all; + }); + + $scope.draftMessage.sending = true; + + MtpApiManager.invokeApi('messages.sendMessage', { + peer: $scope.curDialog.inputPeer, + message: text, + random_id: $scope.draftMessage.randomID + }).then(function (result) { + + if (ApiUpdatesManager.saveSeq(result.seq)) { + + MtpApiManager.getUserID().then(function (fromID) { + ApiUpdatesManager.saveUpdate({ + _: 'updateNewMessage', + message: { + _: 'message', + id: result.id, + from_id: fromID, + to_id: AppPeersManager.getOutputPeer($scope.curDialog.peerID), + out: true, + unread: true, + date: result.date, + message: text, + media: {_: 'messageMediaEmpty'} + }, + pts: result.pts + }); + }); + + } + + $scope.$broadcast('ui_message_send'); + + resetDraft(); + }, function () { + delete $scope.draftMessage.sending; + }); + + return cancelEvent(e); + } + + + function resetDraft () { + $scope.draftMessage = { + randomID: [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)], + text: '' + }; + } + + function onFilesSelected (newVal) { + if (!angular.isArray(newVal) || !newVal.length) { + return; + } + + for (var i = 0; i < newVal.length; i++) { + (function (file, randomID) { + MtpApiFileManager.uploadFile(file).then(function (inputFile) { + var inputMedia; + if (file.type == 'image/jpeg') { + inputMedia = {_: 'inputMediaUploadedPhoto', file: inputFile}; + } else { + inputMedia = {_: 'inputMediaUploadedDocument', file: inputFile, file_name: file.name, mime_type: file.type}; + } + MtpApiManager.invokeApi('messages.sendMedia', { + peer: $scope.curDialog.inputPeer, + media: inputMedia, + random_id: randomID + }).then(function (result) { + + if (ApiUpdatesManager.saveSeq(result.seq)) { + ApiUpdatesManager.saveUpdate({ + _: 'updateNewMessage', + message: result.message, + pts: result.pts + }); + } + + $scope.$broadcast('ui_message_send'); + }); + }, function (error) { + dLog('upload error', error); + }) + + })(newVal[i], [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]); + } + } + + }) + + .controller('PhotoModalController', function ($scope, AppPhotosManager) { + $scope.photo = AppPhotosManager.wrapForFull($scope.photoID); + }) + + .controller('VideoModalController', function ($scope, AppVideoManager) { + $scope.video = AppVideoManager.wrapForFull($scope.videoID); + }) + + .controller('UserModalController', function ($scope, $location, AppUsersManager) { + $scope.user = AppUsersManager.wrapForFull($scope.userID); + $scope.goToHistory = function () { + $scope.$close(); + $location.url('/im?p=' + $scope.user.peerString); + }; + }) + + .controller('ChatModalController', function ($scope, AppUsersManager, AppChatsManager, fullChat) { + $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, fullChat); + }) + + + diff --git a/js/directives.js b/js/directives.js new file mode 100644 index 00000000..482a445e --- /dev/null +++ b/js/directives.js @@ -0,0 +1,512 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +'use strict'; + +/* Directives */ + + +angular.module('myApp.directives', ['myApp.filters']) + .directive('myDialog', function() { + return { + restrict: 'AE', + scope: true, + translude: false, + templateUrl: 'partials/dialog.html' + }; + }) + + .directive('myMessage', function() { + return { + restrict: 'AE', + scope: true, + translude: false, + templateUrl: 'partials/message.html' + }; + }) + + .directive('myDialogsList', function($window, $timeout) { + + return { + link: link + }; + + function link (scope, element, attrs) { + var dialogsWrap = $('.im_dialogs_wrap')[0], + scrollableWrap = $('.im_dialogs_scrollable_wrap')[0], + // dialogsSearch = $('im_dialogs_search')[0], + moreNotified = false; + + onContentLoaded(function () { + $(dialogsWrap).nanoScroller({preventPageScrolling: true, tabIndex: -1}); + }); + + var updateScroller = function () { + onContentLoaded(function () { + $(dialogsWrap).nanoScroller(); + }); + } + + scope.$on('ui_dialogs_prepend', updateScroller); + + + scope.$on('ui_dialogs_append', function () { + onContentLoaded(function () { + updateScroller(); + moreNotified = false; + }); + }); + + scope.$on('ui_dialogs_change', function () { + onContentLoaded(function () { + updateScroller(); + moreNotified = false; + }); + }); + + $(scrollableWrap).on('scroll', function (e) { + if (!moreNotified && scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) { + scope.$emit('dialogs_need_more'); + moreNotified = true; + } + }); + + + function updateSizes () { + $(element).css({ + height: $($window).height() - 162 + }); + } + + $($window).on('resize', updateSizes); + + updateSizes(); + }; + + }) + + .directive('myHistory', function ($window, $timeout) { + + return { + link: link + }; + + function link (scope, element, attrs) { + var historyWrap = $('.im_history_wrap')[0], + scrollableWrap = $('.im_history_scrollable_wrap')[0], + scrollable = $('.im_history_scrollable')[0], + panelWrap = $('.im_history_panel_wrap', element)[0], + sendFormWrap = $('.im_send_form_wrap', element)[0], + moreNotified = false; + + onContentLoaded(function () { + $(historyWrap).nanoScroller({preventPageScrolling: true, scroll: 'bottom', tabIndex: -1}); + }); + + var updateScroller = function (delay) { + $timeout(function () { + $(historyWrap).nanoScroller(); + }, delay || 0); + } + + scope.$on('ui_history_append', function () { + var st = scrollableWrap.scrollTop; + $(scrollableWrap).addClass('im_history_to_bottom'); + if (atBottom) { + onContentLoaded(function () { + $(scrollableWrap).removeClass('im_history_to_bottom'); + updateSizes(); + $(historyWrap).nanoScroller({scrollBottom: 0}); + // scrollableWrap.scrollTop = st; + // $(scrollableWrap).animate({ + // scrollTop: scrollableWrap.scrollHeight - scrollableWrap.clientHeight + // }, 200); + updateScroller(); + }); + } + }); + + scope.$on('ui_history_change', function () { + $(scrollableWrap).addClass('im_history_to_bottom'); + $(scrollable).css({bottom: 0}); + onContentLoaded(function () { + $(scrollableWrap).removeClass('im_history_to_bottom'); + $(scrollable).css({bottom: ''}); + updateSizes(); + $(historyWrap).nanoScroller(); + $(historyWrap).nanoScroller({scrollBottom: 0}); + updateScroller(100); + moreNotified = false; + }); + }); + + + scope.$on('ui_history_prepend', function () { + var sh = scrollableWrap.scrollHeight, + st = scrollableWrap.scrollTop, + ch = scrollableWrap.clientHeight; + + $(scrollableWrap).addClass('im_history_to_bottom'); + $(scrollable).css({bottom: -(sh - st - ch)}); + + onContentLoaded(function () { + $(scrollableWrap).removeClass('im_history_to_bottom'); + $(scrollable).css({bottom: ''}); + $(historyWrap).nanoScroller(); + $(historyWrap).nanoScroller({scrollTop: st + scrollableWrap.scrollHeight - sh}); + + // updateScroller(); + updateScroller(50); + moreNotified = false; + }); + }); + + var atBottom = true; + $(scrollableWrap).on('scroll', function (e) { + atBottom = scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight; + + if (!moreNotified && scrollableWrap.scrollTop <= 300) { + moreNotified = true; + scope.$emit('history_need_more'); + } + }); + + function updateSizes () { + $(historyWrap).css({ + height: $($window).height() - panelWrap.offsetHeight - sendFormWrap.offsetHeight - 90 + }); + if (atBottom) { + onContentLoaded(function () { + $(historyWrap).nanoScroller({scroll: 'bottom'}); + }); + } + updateScroller(100); + } + + $($window).on('resize', updateSizes); + + onContentLoaded(updateSizes); + } + + }) + + .directive('mySendForm', function ($timeout) { + + return { + link: link, + scope: { + draftMessage: '=' + } + }; + + function link (scope, element, attrs) { + var messageField = $('textarea', element)[0], + fileSelect = $('input', element)[0], + dropbox = $('.im_send_dropbox_wrap', element)[0], + emojiButton = $('.im_emoji_btn', element)[0], + editorElement = messageField, + dragStarted, dragTimeout, + emojiArea = $(messageField).emojiarea({button: emojiButton}), + emojiMenu = $('.emoji-menu')[0], + richTextarea = $('.emoji-wysiwyg-editor', element)[0]; + + if (richTextarea) { + editorElement = richTextarea; + $(richTextarea).addClass('form-control'); + $(richTextarea).attr('placeholder', $(messageField).attr('placeholder')); + } + + // $(emojiMenu.firstChild).addClass('nano').nanoScroller({preventPageScrolling: true, tabIndex: -1}); + + + $(fileSelect).on('change', function () { + scope.$apply(function () { + scope.draftMessage.files = Array.prototype.slice.call(fileSelect.files); + }); + }); + + var sendOnEnter = true; + $(editorElement).on('keydown', function (e) { + if (e.keyCode != 13) { + return; + } + var submit = false; + if (sendOnEnter && !e.shiftKey) { + submit = true; + } else if (!sendOnEnter && (e.ctrlKey || e.metaKey)) { + submit = true; + } + + if (submit) { + $(element).trigger('submit'); + dLog('after submit'); + return cancelEvent(e); + } + }); + + if (richTextarea) { + scope.$watch('draftMessage.text', function (newVal) { + if (!newVal.length && !messageField.value.length) { + $timeout(function () { + $(richTextarea).html(''); + }, 0); + } + }); + } + + + $('body').on('dragenter dragleave dragover drop', onDragDropEvent); + + scope.$on('ui_history_change', focusField); + scope.$on('ui_message_send', focusField); + + scope.$on('$destroy', function cleanup() { + $('body').off('dragenter dragleave dragover drop', onDragDropEvent); + }); + + focusField(); + + function focusField () { + onContentLoaded(function () { + $(editorElement).focus(); + }); + } + + function onDragDropEvent(e) { + var dragStateChanged = false; + if (!dragStarted || dragStarted == 1) { + dragStarted = checkDragEvent(e) ? 2 : 1; + dragStateChanged = true; + } + if (dragStarted == 2) { + if (dragTimeout) { + setTimeout(function () { + clearTimeout(dragTimeout); + dragTimeout = false; + }, 0); + } + + if (e.type == 'dragenter' || e.type == 'dragover') { + if (dragStateChanged) { + $(dropbox) + .css({height: $(editorElement).height() + 12, width: $(editorElement).width() + 12}) + .show(); + } + } else { + if (e.type == 'drop') { + scope.$apply(function () { + scope.draftMessage.files = Array.prototype.slice.call(e.originalEvent.dataTransfer.files); + }); + } + dragTimeout = setTimeout(function () { + $(dropbox).hide(); + dragStarted = false; + dragTimeout = false; + }, 300); + } + } + + return cancelEvent(e); + }; + } + + }) + + .directive('myLoadThumb', function(MtpApiFileManager) { + + return { + link: link, + scope: { + thumb: '=' + } + }; + + function link (scope, element, attrs) { + + scope.$watch('thumb.location', function (newVal) { + if (!scope.thumb) dLog(222, scope); + if (!scope.thumb.location) { + element.attr('src', scope.thumb.placeholder || ''); + return; + } + + MtpApiFileManager.downloadSmallFile(scope.thumb.location, scope.thumb.size).then(function (url) { + element.attr('src', url); + }, function (e) { + dLog('Download image failed', e, scope.thumb.location); + element.attr('src', scope.thumb.placeholder || ''); + }); + }) + + } + + }) + + .directive('myLoadFullPhoto', function(MtpApiFileManager) { + + return { + link: link, + transclude: true, + template: + '', + scope: { + fullPhoto: '=', + thumbLocation: '=' + } + }; + + function link (scope, element, attrs) { + var imgElement = $('img', element), + fullLoaded = false; + + + if (!scope.fullPhoto.location) { + imgElement.attr('src', scope.fullPhoto.placeholder || ''); + return; + } + + MtpApiFileManager.getCachedFile(scope.thumbLocation).then(function (url) { + if (!fullLoaded) { + imgElement + .attr('src', url) + .addClass('thumb_blurred') + .addClass('thumb_blur_animation'); + } + }); + + var apiPromise; + if (scope.fullPhoto.size) { + var inputLocation = { + _: 'inputFileLocation', + volume_id: scope.fullPhoto.location.volume_id, + local_id: scope.fullPhoto.location.local_id, + secret: scope.fullPhoto.location.secret + }; + apiPromise = MtpApiFileManager.downloadFile(scope.fullPhoto.location.dc_id, inputLocation, scope.fullPhoto.size); + } else { + apiPromise = MtpApiFileManager.downloadSmallFile(scope.fullPhoto.location); + } + + scope.progress = {enabled: true, percent: 1}; + + apiPromise.then(function (url) { + fullLoaded = true; + scope.progress.enabled = false; + imgElement + .attr('src', url) + .removeClass('thumb_blurred'); + + }, function (e) { + dLog('Download image failed', e, scope.fullPhoto.location); + scope.progress.enabled = false; + imgElement + .attr('src', scope.fullPhoto.placeholder || '') + .removeClass('thumb_blurred'); + + }, function (progress) { + scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); + }); + } + + }) + + + .directive('myLoadVideo', function($sce, MtpApiFileManager) { + + return { + link: link, + transclude: true, + template: + '
\ +
\ +
\ +
\ +
\ + {{progress.percent}}% Complete (success)\ +
\ +
\ +
\ +
\ +
\ + \ +
\ +
\ + \ +
\ +
', + scope: { + video: '=' + } + }; + + function link (scope, element, attrs) { + + scope.progress = {enabled: true, percent: 1}; + scope.player = {}; + + var inputLocation = { + _: 'inputVideoFileLocation', + id: scope.video.id, + access_hash: scope.video.access_hash + }; + + MtpApiFileManager.downloadFile(scope.video.dc_id, inputLocation, scope.video.size).then(function (url) { + scope.progress.enabled = false; + // scope.progress = {enabled: true, percent: 50}; + scope.player.src = $sce.trustAsResourceUrl(url); + }, function (e) { + dLog('Download image failed', e, scope.fullPhoto.location); + scope.progress.enabled = false; + scope.player.src = ''; + }, function (progress) { + scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); + }); + } + + }) + + .directive('myMapPoint', function(ExternalResourcesManager) { + + return { + link: link, + scope: { + point: '=' + } + }; + + function link (scope, element, attrs) { + + var apiKey = 'AIzaSyC32ij28dCa0YzEV_HqbWfIwTZQql-RNS0'; + + var src = 'https://maps.googleapis.com/maps/api/staticmap?sensor=false¢er=' + scope.point['lat'] + ',' + scope.point['long'] + '&zoom=13&size=200x100&scale=2&key=' + apiKey; + + ExternalResourcesManager.downloadImage(src).then(function (url) { + element.append(''); + }); + + element.attr('href','https://maps.google.com/?q=' + scope.point['lat'] + ',' + scope.point['long']); + element.attr('target','_blank'); + } + + }) diff --git a/js/filters.js b/js/filters.js new file mode 100644 index 00000000..a2914d42 --- /dev/null +++ b/js/filters.js @@ -0,0 +1,126 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +'use strict'; + +/* Filters */ + +angular.module('myApp.filters', []) + + .filter('userName', [function() { + return function (user) { + if (!user || !user.first_name && !user.last_name) { + return 'DELETED'; + } + return user.first_name + ' ' + user.last_name; + } + }]) + + .filter('userFirstName', [function() { + return function (user) { + if (!user || !user.first_name && !user.last_name) { + return 'DELETED'; + } + return user.first_name || user.last_name; + } + }]) + + .filter('userStatus', ['$filter', function($filter) { + return function (user) { + if (!user || !user.status || user.status._ == 'userStatusEmpty') { + return 'offline'; + } + if (user.status._ == 'userStatusOnline') { + return 'online'; + } + + return 'last seen ' + $filter('relativeTime')(user.status.was_online); + } + }]) + + .filter('chatTitle', [function() { + return function (chat) { + if (!chat || !chat.title) { + return 'DELETED'; + } + return chat.title; + } + }]) + + .filter('dateOrTime', ['$filter', function($filter) { + return function (timestamp) { + var ticks = timestamp * 1000, + diff = Math.abs(+new Date() - ticks), + format = 'HH:mm'; + + if (diff > 518400000) { // 6 days + format = 'shortDate'; + } + else if (diff > 43200000) { // 12 hours + format = 'EEE'; + } + return $filter('date')(ticks, format); + } + }]) + + .filter('duration', [function() { + return function (duration) { + var secs = duration % 60, + mins = Math.floor((duration - secs) / 60.0); + + if (secs < 10) { + secs = '0' + secs; + } + + return mins + ':' + secs; + } + }]) + + .filter('phoneNumber', [function() { + return function (phoneRaw) { + if (phoneRaw.charAt(0) == '7') { + return '+' + phoneRaw.charAt(0) + ' (' + phoneRaw.substr(1, 3) + ') ' + phoneRaw.substr(4, 3) + '-' + phoneRaw.substr(7, 2) + '-' + phoneRaw.substr(9, 2); + } + return '+' + phoneRaw; + } + }]) + + .filter('formatSize', [function () { + return function (size) { + return Math.round(size / 1024) + 'Kb'; + } + }]) + + .filter('nl2br', [function () { + return function (text) { + return text.replace(/\n/g, '
'); + } + }]) + + .filter('richText', ['$filter', function ($filter) { + return function (text) { + return $filter('linky')(text, '_blank').replace(/\n| /g, '
'); + } + }]) + + .filter('relativeTime', ['$filter', function($filter) { + return function (timestamp) { + var ticks = timestamp * 1000, + diff = Math.abs(+new Date() - ticks); + + if (diff < 60000) { + return 'just now'; + } + if (diff < 3000000) { + return Math.ceil(diff / 60000) + ' minutes ago'; + } + if (diff < 10000000) { + return Math.ceil(diff / 3600000) + ' hours ago'; + } + return $filter('dateOrTime')(timestamp); + } + }]) \ No newline at end of file diff --git a/js/lib/aes_worker.js b/js/lib/aes_worker.js new file mode 100644 index 00000000..fe1ff83b --- /dev/null +++ b/js/lib/aes_worker.js @@ -0,0 +1,21 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +importScripts('mtproto.js', '../../vendor/jsbn/jsbn_combined.js', '../../vendor/cryptoJS/crypto.js'); + +onmessage = function (e) { + // console.log('AES worker in', e.data); + var taskID = e.data.taskID, + result; + + if (e.data.task == 'encrypt') { + result = aesEncrypt(e.data.bytes, e.data.keyBytes, e.data.ivBytes); + } else { + result = aesDecrypt(e.data.encryptedBytes, e.data.keyBytes, e.data.ivBytes); + } + postMessage({taskID: taskID, result: result}); +} \ No newline at end of file diff --git a/js/lib/config.js b/js/lib/config.js new file mode 100644 index 00000000..7f7ef7ad --- /dev/null +++ b/js/lib/config.js @@ -0,0 +1,14 @@ +Config = window.Config || {}; +Config.Schema = Config.Schema || {}; + + +Config.Schema.MTProto = {"constructors":[{"id":"481674261","predicate":"vector","params":[],"type":"Vector t"},{"id":"85337187","predicate":"resPQ","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"pq","type":"bytes"},{"name":"server_public_key_fingerprints","type":"Vector"}],"type":"ResPQ"},{"id":"-2083955988","predicate":"p_q_inner_data","params":[{"name":"pq","type":"bytes"},{"name":"p","type":"bytes"},{"name":"q","type":"bytes"},{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce","type":"int256"}],"type":"P_Q_inner_data"},{"id":"2043348061","predicate":"server_DH_params_fail","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce_hash","type":"int128"}],"type":"Server_DH_Params"},{"id":"-790100132","predicate":"server_DH_params_ok","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"encrypted_answer","type":"bytes"}],"type":"Server_DH_Params"},{"id":"-1249309254","predicate":"server_DH_inner_data","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"g","type":"int"},{"name":"dh_prime","type":"bytes"},{"name":"g_a","type":"bytes"},{"name":"server_time","type":"int"}],"type":"Server_DH_inner_data"},{"id":"1715713620","predicate":"client_DH_inner_data","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"retry_id","type":"long"},{"name":"g_b","type":"bytes"}],"type":"Client_DH_Inner_Data"},{"id":"1003222836","predicate":"dh_gen_ok","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce_hash1","type":"int128"}],"type":"Set_client_DH_params_answer"},{"id":"1188831161","predicate":"dh_gen_retry","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce_hash2","type":"int128"}],"type":"Set_client_DH_params_answer"},{"id":"-1499615742","predicate":"dh_gen_fail","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce_hash3","type":"int128"}],"type":"Set_client_DH_params_answer"},{"id":"-212046591","predicate":"rpc_result","params":[{"name":"req_msg_id","type":"long"},{"name":"result","type":"Object"}],"type":"RpcResult"},{"id":"558156313","predicate":"rpc_error","params":[{"name":"error_code","type":"int"},{"name":"error_message","type":"string"}],"type":"RpcError"},{"id":"1579864942","predicate":"rpc_answer_unknown","params":[],"type":"RpcDropAnswer"},{"id":"-847714938","predicate":"rpc_answer_dropped_running","params":[],"type":"RpcDropAnswer"},{"id":"-1539647305","predicate":"rpc_answer_dropped","params":[{"name":"msg_id","type":"long"},{"name":"seq_no","type":"int"},{"name":"bytes","type":"int"}],"type":"RpcDropAnswer"},{"id":"155834844","predicate":"future_salt","params":[{"name":"valid_since","type":"int"},{"name":"valid_until","type":"int"},{"name":"salt","type":"long"}],"type":"FutureSalt"},{"id":"-1370486635","predicate":"future_salts","params":[{"name":"req_msg_id","type":"long"},{"name":"now","type":"int"},{"name":"salts","type":"vector"}],"type":"FutureSalts"},{"id":"880243653","predicate":"pong","params":[{"name":"msg_id","type":"long"},{"name":"ping_id","type":"long"}],"type":"Pong"},{"id":"-501201412","predicate":"destroy_session_ok","params":[{"name":"session_id","type":"long"}],"type":"DestroySessionRes"},{"id":"1658015945","predicate":"destroy_session_none","params":[{"name":"session_id","type":"long"}],"type":"DestroySessionRes"},{"id":"-1631450872","predicate":"new_session_created","params":[{"name":"first_msg_id","type":"long"},{"name":"unique_id","type":"long"},{"name":"server_salt","type":"long"}],"type":"NewSession"},{"id":"1945237724","predicate":"msg_container","params":[{"name":"messages","type":"vector<%Message>"}],"type":"MessageContainer"},{"id":"1538843921","predicate":"message","params":[{"name":"msg_id","type":"long"},{"name":"seqno","type":"int"},{"name":"bytes","type":"int"},{"name":"body","type":"Object"}],"type":"Message"},{"id":"-530561358","predicate":"msg_copy","params":[{"name":"orig_message","type":"Message"}],"type":"MessageCopy"},{"id":"812830625","predicate":"gzip_packed","params":[{"name":"packed_data","type":"bytes"}],"type":"Object"},{"id":"1658238041","predicate":"msgs_ack","params":[{"name":"msg_ids","type":"Vector"}],"type":"MsgsAck"},{"id":"-1477445615","predicate":"bad_msg_notification","params":[{"name":"bad_msg_id","type":"long"},{"name":"bad_msg_seqno","type":"int"},{"name":"error_code","type":"int"}],"type":"BadMsgNotification"},{"id":"-307542917","predicate":"bad_server_salt","params":[{"name":"bad_msg_id","type":"long"},{"name":"bad_msg_seqno","type":"int"},{"name":"error_code","type":"int"},{"name":"new_server_salt","type":"long"}],"type":"BadMsgNotification"},{"id":"2105940488","predicate":"msg_resend_req","params":[{"name":"msg_ids","type":"Vector"}],"type":"MsgResendReq"},{"id":"-630588590","predicate":"msgs_state_req","params":[{"name":"msg_ids","type":"Vector"}],"type":"MsgsStateReq"},{"id":"81704317","predicate":"msgs_state_info","params":[{"name":"req_msg_id","type":"long"},{"name":"info","type":"bytes"}],"type":"MsgsStateInfo"},{"id":"-1933520591","predicate":"msgs_all_info","params":[{"name":"msg_ids","type":"Vector"},{"name":"info","type":"bytes"}],"type":"MsgsAllInfo"},{"id":"661470918","predicate":"msg_detailed_info","params":[{"name":"msg_id","type":"long"},{"name":"answer_msg_id","type":"long"},{"name":"bytes","type":"int"},{"name":"status","type":"int"}],"type":"MsgDetailedInfo"},{"id":"-2137147681","predicate":"msg_new_detailed_info","params":[{"name":"answer_msg_id","type":"long"},{"name":"bytes","type":"int"},{"name":"status","type":"int"}],"type":"MsgDetailedInfo"}],"methods":[{"id":"1615239032","method":"req_pq","params":[{"name":"nonce","type":"int128"}],"type":"ResPQ"},{"id":"-686627650","method":"req_DH_params","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"p","type":"bytes"},{"name":"q","type":"bytes"},{"name":"public_key_fingerprint","type":"long"},{"name":"encrypted_data","type":"bytes"}],"type":"Server_DH_Params"},{"id":"-184262881","method":"set_client_DH_params","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"encrypted_data","type":"bytes"}],"type":"Set_client_DH_params_answer"},{"id":"1491380032","method":"rpc_drop_answer","params":[{"name":"req_msg_id","type":"long"}],"type":"RpcDropAnswer"},{"id":"-1188971260","method":"get_future_salts","params":[{"name":"num","type":"int"}],"type":"FutureSalts"},{"id":"2059302892","method":"ping","params":[{"name":"ping_id","type":"long"}],"type":"Pong"},{"id":"-213746804","method":"ping_delay_disconnect","params":[{"name":"ping_id","type":"long"},{"name":"disconnect_delay","type":"int"}],"type":"Pong"},{"id":"-414113498","method":"destroy_session","params":[{"name":"session_id","type":"long"}],"type":"DestroySessionRes"},{"id":"-1835453025","method":"http_wait","params":[{"name":"max_delay","type":"int"},{"name":"wait_after","type":"int"},{"name":"max_wait","type":"int"}],"type":"HttpWait"}]}; + + + + +Config.Schema.API = {"constructors":[{"id":"-1132882121","predicate":"boolFalse","params":[],"type":"Bool"},{"id":"-1720552011","predicate":"boolTrue","params":[],"type":"Bool"},{"id":"481674261","predicate":"vector","params":[],"type":"Vector t"},{"id":"-994444869","predicate":"error","params":[{"name":"code","type":"int"},{"name":"text","type":"string"}],"type":"Error"},{"id":"1450380236","predicate":"null","params":[],"type":"Null"},{"id":"2134579434","predicate":"inputPeerEmpty","params":[],"type":"InputPeer"},{"id":"2107670217","predicate":"inputPeerSelf","params":[],"type":"InputPeer"},{"id":"270785512","predicate":"inputPeerContact","params":[{"name":"user_id","type":"int"}],"type":"InputPeer"},{"id":"-1690012891","predicate":"inputPeerForeign","params":[{"name":"user_id","type":"int"},{"name":"access_hash","type":"long"}],"type":"InputPeer"},{"id":"396093539","predicate":"inputPeerChat","params":[{"name":"chat_id","type":"int"}],"type":"InputPeer"},{"id":"-1182234929","predicate":"inputUserEmpty","params":[],"type":"InputUser"},{"id":"-138301121","predicate":"inputUserSelf","params":[],"type":"InputUser"},{"id":"-2031530139","predicate":"inputUserContact","params":[{"name":"user_id","type":"int"}],"type":"InputUser"},{"id":"1700689151","predicate":"inputUserForeign","params":[{"name":"user_id","type":"int"},{"name":"access_hash","type":"long"}],"type":"InputUser"},{"id":"-208488460","predicate":"inputPhoneContact","params":[{"name":"client_id","type":"long"},{"name":"phone","type":"string"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"}],"type":"InputContact"},{"id":"-181407105","predicate":"inputFile","params":[{"name":"id","type":"long"},{"name":"parts","type":"int"},{"name":"name","type":"string"},{"name":"md5_checksum","type":"string"}],"type":"InputFile"},{"id":"-1771768449","predicate":"inputMediaEmpty","params":[],"type":"InputMedia"},{"id":"767900285","predicate":"inputMediaUploadedPhoto","params":[{"name":"file","type":"InputFile"}],"type":"InputMedia"},{"id":"-1893027092","predicate":"inputMediaPhoto","params":[{"name":"id","type":"InputPhoto"}],"type":"InputMedia"},{"id":"-104578748","predicate":"inputMediaGeoPoint","params":[{"name":"geo_point","type":"InputGeoPoint"}],"type":"InputMedia"},{"id":"-1494984313","predicate":"inputMediaContact","params":[{"name":"phone_number","type":"string"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"}],"type":"InputMedia"},{"id":"1212668202","predicate":"inputMediaUploadedVideo","params":[{"name":"file","type":"InputFile"},{"name":"duration","type":"int"},{"name":"w","type":"int"},{"name":"h","type":"int"}],"type":"InputMedia"},{"id":"-433544891","predicate":"inputMediaUploadedThumbVideo","params":[{"name":"file","type":"InputFile"},{"name":"thumb","type":"InputFile"},{"name":"duration","type":"int"},{"name":"w","type":"int"},{"name":"h","type":"int"}],"type":"InputMedia"},{"id":"2130852582","predicate":"inputMediaVideo","params":[{"name":"id","type":"InputVideo"}],"type":"InputMedia"},{"id":"480546647","predicate":"inputChatPhotoEmpty","params":[],"type":"InputChatPhoto"},{"id":"-1809496270","predicate":"inputChatUploadedPhoto","params":[{"name":"file","type":"InputFile"},{"name":"crop","type":"InputPhotoCrop"}],"type":"InputChatPhoto"},{"id":"-1293828344","predicate":"inputChatPhoto","params":[{"name":"id","type":"InputPhoto"},{"name":"crop","type":"InputPhotoCrop"}],"type":"InputChatPhoto"},{"id":"-457104426","predicate":"inputGeoPointEmpty","params":[],"type":"InputGeoPoint"},{"id":"-206066487","predicate":"inputGeoPoint","params":[{"name":"lat","type":"double"},{"name":"long","type":"double"}],"type":"InputGeoPoint"},{"id":"483901197","predicate":"inputPhotoEmpty","params":[],"type":"InputPhoto"},{"id":"-74070332","predicate":"inputPhoto","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputPhoto"},{"id":"1426648181","predicate":"inputVideoEmpty","params":[],"type":"InputVideo"},{"id":"-296249774","predicate":"inputVideo","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputVideo"},{"id":"342061462","predicate":"inputFileLocation","params":[{"name":"volume_id","type":"long"},{"name":"local_id","type":"int"},{"name":"secret","type":"long"}],"type":"InputFileLocation"},{"id":"1023632620","predicate":"inputVideoFileLocation","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputFileLocation"},{"id":"-1377390588","predicate":"inputPhotoCropAuto","params":[],"type":"InputPhotoCrop"},{"id":"-644787419","predicate":"inputPhotoCrop","params":[{"name":"crop_left","type":"double"},{"name":"crop_top","type":"double"},{"name":"crop_width","type":"double"}],"type":"InputPhotoCrop"},{"id":"1996904104","predicate":"inputAppEvent","params":[{"name":"time","type":"double"},{"name":"type","type":"string"},{"name":"peer","type":"long"},{"name":"data","type":"string"}],"type":"InputAppEvent"},{"id":"-1649296275","predicate":"peerUser","params":[{"name":"user_id","type":"int"}],"type":"Peer"},{"id":"-1160714821","predicate":"peerChat","params":[{"name":"chat_id","type":"int"}],"type":"Peer"},{"id":"-1432995067","predicate":"storage.fileUnknown","params":[],"type":"storage.FileType"},{"id":"8322574","predicate":"storage.fileJpeg","params":[],"type":"storage.FileType"},{"id":"-891180321","predicate":"storage.fileGif","params":[],"type":"storage.FileType"},{"id":"172975040","predicate":"storage.filePng","params":[],"type":"storage.FileType"},{"id":"1384777335","predicate":"storage.fileMp3","params":[],"type":"storage.FileType"},{"id":"1258941372","predicate":"storage.fileMov","params":[],"type":"storage.FileType"},{"id":"1086091090","predicate":"storage.filePartial","params":[],"type":"storage.FileType"},{"id":"-1278304028","predicate":"storage.fileMp4","params":[],"type":"storage.FileType"},{"id":"276907596","predicate":"storage.fileWebp","params":[],"type":"storage.FileType"},{"id":"2086234950","predicate":"fileLocationUnavailable","params":[{"name":"volume_id","type":"long"},{"name":"local_id","type":"int"},{"name":"secret","type":"long"}],"type":"FileLocation"},{"id":"1406570614","predicate":"fileLocation","params":[{"name":"dc_id","type":"int"},{"name":"volume_id","type":"long"},{"name":"local_id","type":"int"},{"name":"secret","type":"long"}],"type":"FileLocation"},{"id":"537022650","predicate":"userEmpty","params":[{"name":"id","type":"int"}],"type":"User"},{"id":"1912944108","predicate":"userSelf","params":[{"name":"id","type":"int"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"},{"name":"phone","type":"string"},{"name":"photo","type":"UserProfilePhoto"},{"name":"status","type":"UserStatus"},{"name":"inactive","type":"Bool"}],"type":"User"},{"id":"-218397927","predicate":"userContact","params":[{"name":"id","type":"int"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"},{"name":"access_hash","type":"long"},{"name":"phone","type":"string"},{"name":"photo","type":"UserProfilePhoto"},{"name":"status","type":"UserStatus"}],"type":"User"},{"id":"585682608","predicate":"userRequest","params":[{"name":"id","type":"int"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"},{"name":"access_hash","type":"long"},{"name":"phone","type":"string"},{"name":"photo","type":"UserProfilePhoto"},{"name":"status","type":"UserStatus"}],"type":"User"},{"id":"1377093789","predicate":"userForeign","params":[{"name":"id","type":"int"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"},{"name":"access_hash","type":"long"},{"name":"photo","type":"UserProfilePhoto"},{"name":"status","type":"UserStatus"}],"type":"User"},{"id":"-1298475060","predicate":"userDeleted","params":[{"name":"id","type":"int"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"}],"type":"User"},{"id":"1326562017","predicate":"userProfilePhotoEmpty","params":[],"type":"UserProfilePhoto"},{"id":"-715532088","predicate":"userProfilePhoto","params":[{"name":"photo_id","type":"long"},{"name":"photo_small","type":"FileLocation"},{"name":"photo_big","type":"FileLocation"}],"type":"UserProfilePhoto"},{"id":"164646985","predicate":"userStatusEmpty","params":[],"type":"UserStatus"},{"id":"-306628279","predicate":"userStatusOnline","params":[{"name":"expires","type":"int"}],"type":"UserStatus"},{"id":"9203775","predicate":"userStatusOffline","params":[{"name":"was_online","type":"int"}],"type":"UserStatus"},{"id":"-1683826688","predicate":"chatEmpty","params":[{"name":"id","type":"int"}],"type":"Chat"},{"id":"1855757255","predicate":"chat","params":[{"name":"id","type":"int"},{"name":"title","type":"string"},{"name":"photo","type":"ChatPhoto"},{"name":"participants_count","type":"int"},{"name":"date","type":"int"},{"name":"left","type":"Bool"},{"name":"version","type":"int"}],"type":"Chat"},{"id":"-83047359","predicate":"chatForbidden","params":[{"name":"id","type":"int"},{"name":"title","type":"string"},{"name":"date","type":"int"}],"type":"Chat"},{"id":"1661886910","predicate":"chatFull","params":[{"name":"id","type":"int"},{"name":"participants","type":"ChatParticipants"},{"name":"chat_photo","type":"Photo"},{"name":"notify_settings","type":"PeerNotifySettings"}],"type":"ChatFull"},{"id":"-925415106","predicate":"chatParticipant","params":[{"name":"user_id","type":"int"},{"name":"inviter_id","type":"int"},{"name":"date","type":"int"}],"type":"ChatParticipant"},{"id":"265468810","predicate":"chatParticipantsForbidden","params":[{"name":"chat_id","type":"int"}],"type":"ChatParticipants"},{"id":"2017571861","predicate":"chatParticipants","params":[{"name":"chat_id","type":"int"},{"name":"admin_id","type":"int"},{"name":"participants","type":"Vector"},{"name":"version","type":"int"}],"type":"ChatParticipants"},{"id":"935395612","predicate":"chatPhotoEmpty","params":[],"type":"ChatPhoto"},{"id":"1632839530","predicate":"chatPhoto","params":[{"name":"photo_small","type":"FileLocation"},{"name":"photo_big","type":"FileLocation"}],"type":"ChatPhoto"},{"id":"-2082087340","predicate":"messageEmpty","params":[{"name":"id","type":"int"}],"type":"Message"},{"id":"585853626","predicate":"message","params":[{"name":"id","type":"int"},{"name":"from_id","type":"int"},{"name":"to_id","type":"Peer"},{"name":"out","type":"Bool"},{"name":"unread","type":"Bool"},{"name":"date","type":"int"},{"name":"message","type":"string"},{"name":"media","type":"MessageMedia"}],"type":"Message"},{"id":"99903492","predicate":"messageForwarded","params":[{"name":"id","type":"int"},{"name":"fwd_from_id","type":"int"},{"name":"fwd_date","type":"int"},{"name":"from_id","type":"int"},{"name":"to_id","type":"Peer"},{"name":"out","type":"Bool"},{"name":"unread","type":"Bool"},{"name":"date","type":"int"},{"name":"message","type":"string"},{"name":"media","type":"MessageMedia"}],"type":"Message"},{"id":"-1618124613","predicate":"messageService","params":[{"name":"id","type":"int"},{"name":"from_id","type":"int"},{"name":"to_id","type":"Peer"},{"name":"out","type":"Bool"},{"name":"unread","type":"Bool"},{"name":"date","type":"int"},{"name":"action","type":"MessageAction"}],"type":"Message"},{"id":"1038967584","predicate":"messageMediaEmpty","params":[],"type":"MessageMedia"},{"id":"-926655958","predicate":"messageMediaPhoto","params":[{"name":"photo","type":"Photo"}],"type":"MessageMedia"},{"id":"-1563278704","predicate":"messageMediaVideo","params":[{"name":"video","type":"Video"}],"type":"MessageMedia"},{"id":"1457575028","predicate":"messageMediaGeo","params":[{"name":"geo","type":"GeoPoint"}],"type":"MessageMedia"},{"id":"1585262393","predicate":"messageMediaContact","params":[{"name":"phone_number","type":"string"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"},{"name":"user_id","type":"int"}],"type":"MessageMedia"},{"id":"694364726","predicate":"messageMediaUnsupported","params":[{"name":"bytes","type":"bytes"}],"type":"MessageMedia"},{"id":"-1230047312","predicate":"messageActionEmpty","params":[],"type":"MessageAction"},{"id":"-1503425638","predicate":"messageActionChatCreate","params":[{"name":"title","type":"string"},{"name":"users","type":"Vector"}],"type":"MessageAction"},{"id":"-1247687078","predicate":"messageActionChatEditTitle","params":[{"name":"title","type":"string"}],"type":"MessageAction"},{"id":"2144015272","predicate":"messageActionChatEditPhoto","params":[{"name":"photo","type":"Photo"}],"type":"MessageAction"},{"id":"-1780220945","predicate":"messageActionChatDeletePhoto","params":[],"type":"MessageAction"},{"id":"1581055051","predicate":"messageActionChatAddUser","params":[{"name":"user_id","type":"int"}],"type":"MessageAction"},{"id":"-1297179892","predicate":"messageActionChatDeleteUser","params":[{"name":"user_id","type":"int"}],"type":"MessageAction"},{"id":"558533855","predicate":"dialog","params":[{"name":"peer","type":"Peer"},{"name":"top_message","type":"int"},{"name":"unread_count","type":"int"}],"type":"Dialog"},{"id":"590459437","predicate":"photoEmpty","params":[{"name":"id","type":"long"}],"type":"Photo"},{"id":"582313809","predicate":"photo","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"},{"name":"user_id","type":"int"},{"name":"date","type":"int"},{"name":"caption","type":"string"},{"name":"geo","type":"GeoPoint"},{"name":"sizes","type":"Vector"}],"type":"Photo"},{"id":"236446268","predicate":"photoSizeEmpty","params":[{"name":"type","type":"string"}],"type":"PhotoSize"},{"id":"2009052699","predicate":"photoSize","params":[{"name":"type","type":"string"},{"name":"location","type":"FileLocation"},{"name":"w","type":"int"},{"name":"h","type":"int"},{"name":"size","type":"int"}],"type":"PhotoSize"},{"id":"-374917894","predicate":"photoCachedSize","params":[{"name":"type","type":"string"},{"name":"location","type":"FileLocation"},{"name":"w","type":"int"},{"name":"h","type":"int"},{"name":"bytes","type":"bytes"}],"type":"PhotoSize"},{"id":"-1056548696","predicate":"videoEmpty","params":[{"name":"id","type":"long"}],"type":"Video"},{"id":"1510253727","predicate":"video","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"},{"name":"user_id","type":"int"},{"name":"date","type":"int"},{"name":"caption","type":"string"},{"name":"duration","type":"int"},{"name":"size","type":"int"},{"name":"thumb","type":"PhotoSize"},{"name":"dc_id","type":"int"},{"name":"w","type":"int"},{"name":"h","type":"int"}],"type":"Video"},{"id":"286776671","predicate":"geoPointEmpty","params":[],"type":"GeoPoint"},{"id":"541710092","predicate":"geoPoint","params":[{"name":"long","type":"double"},{"name":"lat","type":"double"}],"type":"GeoPoint"},{"id":"-486486981","predicate":"auth.checkedPhone","params":[{"name":"phone_registered","type":"Bool"},{"name":"phone_invited","type":"Bool"}],"type":"auth.CheckedPhone"},{"id":"571849917","predicate":"auth.sentCode","params":[{"name":"phone_registered","type":"Bool"},{"name":"phone_code_hash","type":"string"}],"type":"auth.SentCode"},{"id":"-155815004","predicate":"auth.authorization","params":[{"name":"expires","type":"int"},{"name":"user","type":"User"}],"type":"auth.Authorization"},{"id":"-543777747","predicate":"auth.exportedAuthorization","params":[{"name":"id","type":"int"},{"name":"bytes","type":"bytes"}],"type":"auth.ExportedAuthorization"},{"id":"-1195615476","predicate":"inputNotifyPeer","params":[{"name":"peer","type":"InputPeer"}],"type":"InputNotifyPeer"},{"id":"423314455","predicate":"inputNotifyUsers","params":[],"type":"InputNotifyPeer"},{"id":"1251338318","predicate":"inputNotifyChats","params":[],"type":"InputNotifyPeer"},{"id":"-1540769658","predicate":"inputNotifyAll","params":[],"type":"InputNotifyPeer"},{"id":"-265263912","predicate":"inputPeerNotifyEventsEmpty","params":[],"type":"InputPeerNotifyEvents"},{"id":"-395694988","predicate":"inputPeerNotifyEventsAll","params":[],"type":"InputPeerNotifyEvents"},{"id":"1185074840","predicate":"inputPeerNotifySettings","params":[{"name":"mute_until","type":"int"},{"name":"sound","type":"string"},{"name":"show_previews","type":"Bool"},{"name":"events_mask","type":"int"}],"type":"InputPeerNotifySettings"},{"id":"-1378534221","predicate":"peerNotifyEventsEmpty","params":[],"type":"PeerNotifyEvents"},{"id":"1830677896","predicate":"peerNotifyEventsAll","params":[],"type":"PeerNotifyEvents"},{"id":"1889961234","predicate":"peerNotifySettingsEmpty","params":[],"type":"PeerNotifySettings"},{"id":"-1923214866","predicate":"peerNotifySettings","params":[{"name":"mute_until","type":"int"},{"name":"sound","type":"string"},{"name":"show_previews","type":"Bool"},{"name":"events_mask","type":"int"}],"type":"PeerNotifySettings"},{"id":"-860866985","predicate":"wallPaper","params":[{"name":"id","type":"int"},{"name":"title","type":"string"},{"name":"sizes","type":"Vector"},{"name":"color","type":"int"}],"type":"WallPaper"},{"id":"1997575642","predicate":"userFull","params":[{"name":"user","type":"User"},{"name":"link","type":"contacts.Link"},{"name":"profile_photo","type":"Photo"},{"name":"notify_settings","type":"PeerNotifySettings"},{"name":"blocked","type":"Bool"},{"name":"real_first_name","type":"string"},{"name":"real_last_name","type":"string"}],"type":"UserFull"},{"id":"-116274796","predicate":"contact","params":[{"name":"user_id","type":"int"},{"name":"mutual","type":"Bool"}],"type":"Contact"},{"id":"-805141448","predicate":"importedContact","params":[{"name":"user_id","type":"int"},{"name":"client_id","type":"long"}],"type":"ImportedContact"},{"id":"1444661369","predicate":"contactBlocked","params":[{"name":"user_id","type":"int"},{"name":"date","type":"int"}],"type":"ContactBlocked"},{"id":"-360210539","predicate":"contactFound","params":[{"name":"user_id","type":"int"}],"type":"ContactFound"},{"id":"1038193057","predicate":"contactSuggested","params":[{"name":"user_id","type":"int"},{"name":"mutual_contacts","type":"int"}],"type":"ContactSuggested"},{"id":"-1434994573","predicate":"contactStatus","params":[{"name":"user_id","type":"int"},{"name":"expires","type":"int"}],"type":"ContactStatus"},{"id":"909233996","predicate":"chatLocated","params":[{"name":"chat_id","type":"int"},{"name":"distance","type":"int"}],"type":"ChatLocated"},{"id":"322183672","predicate":"contacts.foreignLinkUnknown","params":[],"type":"contacts.ForeignLink"},{"id":"-1484775609","predicate":"contacts.foreignLinkRequested","params":[{"name":"has_phone","type":"Bool"}],"type":"contacts.ForeignLink"},{"id":"468356321","predicate":"contacts.foreignLinkMutual","params":[],"type":"contacts.ForeignLink"},{"id":"-768992160","predicate":"contacts.myLinkEmpty","params":[],"type":"contacts.MyLink"},{"id":"1818882030","predicate":"contacts.myLinkRequested","params":[{"name":"contact","type":"Bool"}],"type":"contacts.MyLink"},{"id":"-1035932711","predicate":"contacts.myLinkContact","params":[],"type":"contacts.MyLink"},{"id":"-322001931","predicate":"contacts.link","params":[{"name":"my_link","type":"contacts.MyLink"},{"name":"foreign_link","type":"contacts.ForeignLink"},{"name":"user","type":"User"}],"type":"contacts.Link"},{"id":"1871416498","predicate":"contacts.contacts","params":[{"name":"contacts","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.Contacts"},{"id":"-1219778094","predicate":"contacts.contactsNotModified","params":[],"type":"contacts.Contacts"},{"id":"-775091636","predicate":"contacts.importedContacts","params":[{"name":"imported","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.ImportedContacts"},{"id":"471043349","predicate":"contacts.blocked","params":[{"name":"blocked","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.Blocked"},{"id":"-1878523231","predicate":"contacts.blockedSlice","params":[{"name":"count","type":"int"},{"name":"blocked","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.Blocked"},{"id":"90570766","predicate":"contacts.found","params":[{"name":"results","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.Found"},{"id":"1447681221","predicate":"contacts.suggested","params":[{"name":"results","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.Suggested"},{"id":"364538944","predicate":"messages.dialogs","params":[{"name":"dialogs","type":"Vector"},{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"messages.Dialogs"},{"id":"1910543603","predicate":"messages.dialogsSlice","params":[{"name":"count","type":"int"},{"name":"dialogs","type":"Vector"},{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"messages.Dialogs"},{"id":"-1938715001","predicate":"messages.messages","params":[{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"messages.Messages"},{"id":"189033187","predicate":"messages.messagesSlice","params":[{"name":"count","type":"int"},{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"messages.Messages"},{"id":"1062078024","predicate":"messages.messageEmpty","params":[],"type":"messages.Message"},{"id":"-7289833","predicate":"messages.message","params":[{"name":"message","type":"Message"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"messages.Message"},{"id":"-1768654661","predicate":"messages.statedMessages","params":[{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"},{"name":"pts","type":"int"},{"name":"seq","type":"int"}],"type":"messages.StatedMessages"},{"id":"-797251802","predicate":"messages.statedMessage","params":[{"name":"message","type":"Message"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"},{"name":"pts","type":"int"},{"name":"seq","type":"int"}],"type":"messages.StatedMessage"},{"id":"-772484260","predicate":"messages.sentMessage","params":[{"name":"id","type":"int"},{"name":"date","type":"int"},{"name":"pts","type":"int"},{"name":"seq","type":"int"}],"type":"messages.SentMessage"},{"id":"1089011754","predicate":"messages.chat","params":[{"name":"chat","type":"Chat"},{"name":"users","type":"Vector"}],"type":"messages.Chat"},{"id":"-2125411368","predicate":"messages.chats","params":[{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"messages.Chats"},{"id":"-438840932","predicate":"messages.chatFull","params":[{"name":"full_chat","type":"ChatFull"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"messages.ChatFull"},{"id":"-1210173710","predicate":"messages.affectedHistory","params":[{"name":"pts","type":"int"},{"name":"seq","type":"int"},{"name":"offset","type":"int"}],"type":"messages.AffectedHistory"},{"id":"1474492012","predicate":"inputMessagesFilterEmpty","params":[],"type":"MessagesFilter"},{"id":"-1777752804","predicate":"inputMessagesFilterPhotos","params":[],"type":"MessagesFilter"},{"id":"-1614803355","predicate":"inputMessagesFilterVideo","params":[],"type":"MessagesFilter"},{"id":"1458172132","predicate":"inputMessagesFilterPhotoVideo","params":[],"type":"MessagesFilter"},{"id":"20626867","predicate":"updateNewMessage","params":[{"name":"message","type":"Message"},{"name":"pts","type":"int"}],"type":"Update"},{"id":"1318109142","predicate":"updateMessageID","params":[{"name":"id","type":"int"},{"name":"random_id","type":"long"}],"type":"Update"},{"id":"-966484431","predicate":"updateReadMessages","params":[{"name":"messages","type":"Vector"},{"name":"pts","type":"int"}],"type":"Update"},{"id":"-1456734682","predicate":"updateDeleteMessages","params":[{"name":"messages","type":"Vector"},{"name":"pts","type":"int"}],"type":"Update"},{"id":"-782376883","predicate":"updateRestoreMessages","params":[{"name":"messages","type":"Vector"},{"name":"pts","type":"int"}],"type":"Update"},{"id":"1806337288","predicate":"updateUserTyping","params":[{"name":"user_id","type":"int"}],"type":"Update"},{"id":"1011273702","predicate":"updateChatUserTyping","params":[{"name":"chat_id","type":"int"},{"name":"user_id","type":"int"}],"type":"Update"},{"id":"125178264","predicate":"updateChatParticipants","params":[{"name":"participants","type":"ChatParticipants"}],"type":"Update"},{"id":"469489699","predicate":"updateUserStatus","params":[{"name":"user_id","type":"int"},{"name":"status","type":"UserStatus"}],"type":"Update"},{"id":"-635250259","predicate":"updateUserName","params":[{"name":"user_id","type":"int"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"}],"type":"Update"},{"id":"-1791935732","predicate":"updateUserPhoto","params":[{"name":"user_id","type":"int"},{"name":"date","type":"int"},{"name":"photo","type":"UserProfilePhoto"},{"name":"previous","type":"Bool"}],"type":"Update"},{"id":"628472761","predicate":"updateContactRegistered","params":[{"name":"user_id","type":"int"},{"name":"date","type":"int"}],"type":"Update"},{"id":"1369737882","predicate":"updateContactLink","params":[{"name":"user_id","type":"int"},{"name":"my_link","type":"contacts.MyLink"},{"name":"foreign_link","type":"contacts.ForeignLink"}],"type":"Update"},{"id":"1869154659","predicate":"updateActivation","params":[{"name":"user_id","type":"int"}],"type":"Update"},{"id":"-1895411046","predicate":"updateNewAuthorization","params":[{"name":"auth_key_id","type":"long"},{"name":"date","type":"int"},{"name":"device","type":"string"},{"name":"location","type":"string"}],"type":"Update"},{"id":"-1519637954","predicate":"updates.state","params":[{"name":"pts","type":"int"},{"name":"qts","type":"int"},{"name":"date","type":"int"},{"name":"seq","type":"int"},{"name":"unread_count","type":"int"}],"type":"updates.State"},{"id":"1567990072","predicate":"updates.differenceEmpty","params":[{"name":"date","type":"int"},{"name":"seq","type":"int"}],"type":"updates.Difference"},{"id":"16030880","predicate":"updates.difference","params":[{"name":"new_messages","type":"Vector"},{"name":"new_encrypted_messages","type":"Vector"},{"name":"other_updates","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"},{"name":"state","type":"updates.State"}],"type":"updates.Difference"},{"id":"-1459938943","predicate":"updates.differenceSlice","params":[{"name":"new_messages","type":"Vector"},{"name":"new_encrypted_messages","type":"Vector"},{"name":"other_updates","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"},{"name":"intermediate_state","type":"updates.State"}],"type":"updates.Difference"},{"id":"-484987010","predicate":"updatesTooLong","params":[],"type":"Updates"},{"id":"-738961532","predicate":"updateShortMessage","params":[{"name":"id","type":"int"},{"name":"from_id","type":"int"},{"name":"message","type":"string"},{"name":"pts","type":"int"},{"name":"date","type":"int"},{"name":"seq","type":"int"}],"type":"Updates"},{"id":"724548942","predicate":"updateShortChatMessage","params":[{"name":"id","type":"int"},{"name":"from_id","type":"int"},{"name":"chat_id","type":"int"},{"name":"message","type":"string"},{"name":"pts","type":"int"},{"name":"date","type":"int"},{"name":"seq","type":"int"}],"type":"Updates"},{"id":"2027216577","predicate":"updateShort","params":[{"name":"update","type":"Update"},{"name":"date","type":"int"}],"type":"Updates"},{"id":"1918567619","predicate":"updatesCombined","params":[{"name":"updates","type":"Vector"},{"name":"users","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"date","type":"int"},{"name":"seq_start","type":"int"},{"name":"seq","type":"int"}],"type":"Updates"},{"id":"1957577280","predicate":"updates","params":[{"name":"updates","type":"Vector"},{"name":"users","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"date","type":"int"},{"name":"seq","type":"int"}],"type":"Updates"},{"id":"-1916114267","predicate":"photos.photos","params":[{"name":"photos","type":"Vector"},{"name":"users","type":"Vector"}],"type":"photos.Photos"},{"id":"352657236","predicate":"photos.photosSlice","params":[{"name":"count","type":"int"},{"name":"photos","type":"Vector"},{"name":"users","type":"Vector"}],"type":"photos.Photos"},{"id":"539045032","predicate":"photos.photo","params":[{"name":"photo","type":"Photo"},{"name":"users","type":"Vector"}],"type":"photos.Photo"},{"id":"157948117","predicate":"upload.file","params":[{"name":"type","type":"storage.FileType"},{"name":"mtime","type":"int"},{"name":"bytes","type":"bytes"}],"type":"upload.File"},{"id":"784507964","predicate":"dcOption","params":[{"name":"id","type":"int"},{"name":"hostname","type":"string"},{"name":"ip_address","type":"string"},{"name":"port","type":"int"}],"type":"DcOption"},{"id":"590174469","predicate":"config","params":[{"name":"date","type":"int"},{"name":"test_mode","type":"Bool"},{"name":"this_dc","type":"int"},{"name":"dc_options","type":"Vector"},{"name":"chat_size_max","type":"int"}],"type":"Config"},{"id":"-1910892683","predicate":"nearestDc","params":[{"name":"country","type":"string"},{"name":"this_dc","type":"int"},{"name":"nearest_dc","type":"int"}],"type":"NearestDc"},{"id":"-1987579119","predicate":"help.appUpdate","params":[{"name":"id","type":"int"},{"name":"critical","type":"Bool"},{"name":"url","type":"string"},{"name":"text","type":"string"}],"type":"help.AppUpdate"},{"id":"-1000708810","predicate":"help.noAppUpdate","params":[],"type":"help.AppUpdate"},{"id":"415997816","predicate":"help.inviteText","params":[{"name":"message","type":"string"}],"type":"help.InviteText"},{"id":"1047852486","predicate":"messages.statedMessagesLinks","params":[{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"},{"name":"links","type":"Vector"},{"name":"pts","type":"int"},{"name":"seq","type":"int"}],"type":"messages.StatedMessages"},{"id":"-1448138623","predicate":"messages.statedMessageLink","params":[{"name":"message","type":"Message"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"},{"name":"links","type":"Vector"},{"name":"pts","type":"int"},{"name":"seq","type":"int"}],"type":"messages.StatedMessage"},{"id":"-371504577","predicate":"messages.sentMessageLink","params":[{"name":"id","type":"int"},{"name":"date","type":"int"},{"name":"pts","type":"int"},{"name":"seq","type":"int"},{"name":"links","type":"Vector"}],"type":"messages.SentMessage"},{"id":"1960072954","predicate":"inputGeoChat","params":[{"name":"chat_id","type":"int"},{"name":"access_hash","type":"long"}],"type":"InputGeoChat"},{"id":"1301143240","predicate":"inputNotifyGeoChatPeer","params":[{"name":"peer","type":"InputGeoChat"}],"type":"InputNotifyPeer"},{"id":"1978329690","predicate":"geoChat","params":[{"name":"id","type":"int"},{"name":"access_hash","type":"long"},{"name":"title","type":"string"},{"name":"address","type":"string"},{"name":"venue","type":"string"},{"name":"geo","type":"GeoPoint"},{"name":"photo","type":"ChatPhoto"},{"name":"participants_count","type":"int"},{"name":"date","type":"int"},{"name":"checked_in","type":"Bool"},{"name":"version","type":"int"}],"type":"Chat"},{"id":"1613830811","predicate":"geoChatMessageEmpty","params":[{"name":"chat_id","type":"int"},{"name":"id","type":"int"}],"type":"GeoChatMessage"},{"id":"1158019297","predicate":"geoChatMessage","params":[{"name":"chat_id","type":"int"},{"name":"id","type":"int"},{"name":"from_id","type":"int"},{"name":"date","type":"int"},{"name":"message","type":"string"},{"name":"media","type":"MessageMedia"}],"type":"GeoChatMessage"},{"id":"-749755826","predicate":"geoChatMessageService","params":[{"name":"chat_id","type":"int"},{"name":"id","type":"int"},{"name":"from_id","type":"int"},{"name":"date","type":"int"},{"name":"action","type":"MessageAction"}],"type":"GeoChatMessage"},{"id":"397498251","predicate":"geochats.statedMessage","params":[{"name":"message","type":"GeoChatMessage"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"},{"name":"seq","type":"int"}],"type":"geochats.StatedMessage"},{"id":"1224651367","predicate":"geochats.located","params":[{"name":"results","type":"Vector"},{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"geochats.Located"},{"id":"-783127119","predicate":"geochats.messages","params":[{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"geochats.Messages"},{"id":"-1135057944","predicate":"geochats.messagesSlice","params":[{"name":"count","type":"int"},{"name":"messages","type":"Vector"},{"name":"chats","type":"Vector"},{"name":"users","type":"Vector"}],"type":"geochats.Messages"},{"id":"1862504124","predicate":"messageActionGeoChatCreate","params":[{"name":"title","type":"string"},{"name":"address","type":"string"}],"type":"MessageAction"},{"id":"209540062","predicate":"messageActionGeoChatCheckin","params":[],"type":"MessageAction"},{"id":"1516823543","predicate":"updateNewGeoChatMessage","params":[{"name":"message","type":"GeoChatMessage"}],"type":"Update"},{"id":"1662091044","predicate":"wallPaperSolid","params":[{"name":"id","type":"int"},{"name":"title","type":"string"},{"name":"bg_color","type":"int"},{"name":"color","type":"int"}],"type":"WallPaper"},{"id":"314359194","predicate":"updateNewEncryptedMessage","params":[{"name":"message","type":"EncryptedMessage"},{"name":"qts","type":"int"}],"type":"Update"},{"id":"386986326","predicate":"updateEncryptedChatTyping","params":[{"name":"chat_id","type":"int"}],"type":"Update"},{"id":"-1264392051","predicate":"updateEncryption","params":[{"name":"chat","type":"EncryptedChat"},{"name":"date","type":"int"}],"type":"Update"},{"id":"956179895","predicate":"updateEncryptedMessagesRead","params":[{"name":"chat_id","type":"int"},{"name":"max_date","type":"int"},{"name":"date","type":"int"}],"type":"Update"},{"id":"-1417756512","predicate":"encryptedChatEmpty","params":[{"name":"id","type":"int"}],"type":"EncryptedChat"},{"id":"1006044124","predicate":"encryptedChatWaiting","params":[{"name":"id","type":"int"},{"name":"access_hash","type":"long"},{"name":"date","type":"int"},{"name":"admin_id","type":"int"},{"name":"participant_id","type":"int"}],"type":"EncryptedChat"},{"id":"-39213129","predicate":"encryptedChatRequested","params":[{"name":"id","type":"int"},{"name":"access_hash","type":"long"},{"name":"date","type":"int"},{"name":"admin_id","type":"int"},{"name":"participant_id","type":"int"},{"name":"g_a","type":"bytes"},{"name":"nonce","type":"bytes"}],"type":"EncryptedChat"},{"id":"1711395151","predicate":"encryptedChat","params":[{"name":"id","type":"int"},{"name":"access_hash","type":"long"},{"name":"date","type":"int"},{"name":"admin_id","type":"int"},{"name":"participant_id","type":"int"},{"name":"g_a_or_b","type":"bytes"},{"name":"nonce","type":"bytes"},{"name":"key_fingerprint","type":"long"}],"type":"EncryptedChat"},{"id":"332848423","predicate":"encryptedChatDiscarded","params":[{"name":"id","type":"int"}],"type":"EncryptedChat"},{"id":"-247351839","predicate":"inputEncryptedChat","params":[{"name":"chat_id","type":"int"},{"name":"access_hash","type":"long"}],"type":"InputEncryptedChat"},{"id":"-1038136962","predicate":"encryptedFileEmpty","params":[],"type":"EncryptedFile"},{"id":"1248893260","predicate":"encryptedFile","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"},{"name":"size","type":"int"},{"name":"dc_id","type":"int"},{"name":"key_fingerprint","type":"int"}],"type":"EncryptedFile"},{"id":"406307684","predicate":"inputEncryptedFileEmpty","params":[],"type":"InputEncryptedFile"},{"id":"1690108678","predicate":"inputEncryptedFileUploaded","params":[{"name":"id","type":"long"},{"name":"parts","type":"int"},{"name":"md5_checksum","type":"string"},{"name":"key_fingerprint","type":"int"}],"type":"InputEncryptedFile"},{"id":"1511503333","predicate":"inputEncryptedFile","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputEncryptedFile"},{"id":"-182231723","predicate":"inputEncryptedFileLocation","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputFileLocation"},{"id":"-317144808","predicate":"encryptedMessage","params":[{"name":"random_id","type":"long"},{"name":"chat_id","type":"int"},{"name":"date","type":"int"},{"name":"bytes","type":"bytes"},{"name":"file","type":"EncryptedFile"}],"type":"EncryptedMessage"},{"id":"594758406","predicate":"encryptedMessageService","params":[{"name":"random_id","type":"long"},{"name":"chat_id","type":"int"},{"name":"date","type":"int"},{"name":"bytes","type":"bytes"}],"type":"EncryptedMessage"},{"id":"-1717290801","predicate":"decryptedMessageLayer","params":[{"name":"layer","type":"int"},{"name":"message","type":"DecryptedMessage"}],"type":"DecryptedMessageLayer"},{"id":"528568095","predicate":"decryptedMessage","params":[{"name":"random_id","type":"long"},{"name":"random_bytes","type":"bytes"},{"name":"message","type":"string"},{"name":"media","type":"DecryptedMessageMedia"}],"type":"DecryptedMessage"},{"id":"-1438109059","predicate":"decryptedMessageService","params":[{"name":"random_id","type":"long"},{"name":"random_bytes","type":"bytes"},{"name":"action","type":"DecryptedMessageAction"}],"type":"DecryptedMessage"},{"id":"144661578","predicate":"decryptedMessageMediaEmpty","params":[],"type":"DecryptedMessageMedia"},{"id":"846826124","predicate":"decryptedMessageMediaPhoto","params":[{"name":"thumb","type":"bytes"},{"name":"thumb_w","type":"int"},{"name":"thumb_h","type":"int"},{"name":"w","type":"int"},{"name":"h","type":"int"},{"name":"size","type":"int"},{"name":"key","type":"bytes"},{"name":"iv","type":"bytes"}],"type":"DecryptedMessageMedia"},{"id":"1290694387","predicate":"decryptedMessageMediaVideo","params":[{"name":"thumb","type":"bytes"},{"name":"thumb_w","type":"int"},{"name":"thumb_h","type":"int"},{"name":"duration","type":"int"},{"name":"w","type":"int"},{"name":"h","type":"int"},{"name":"size","type":"int"},{"name":"key","type":"bytes"},{"name":"iv","type":"bytes"}],"type":"DecryptedMessageMedia"},{"id":"893913689","predicate":"decryptedMessageMediaGeoPoint","params":[{"name":"lat","type":"double"},{"name":"long","type":"double"}],"type":"DecryptedMessageMedia"},{"id":"1485441687","predicate":"decryptedMessageMediaContact","params":[{"name":"phone_number","type":"string"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"},{"name":"user_id","type":"int"}],"type":"DecryptedMessageMedia"},{"id":"-1586283796","predicate":"decryptedMessageActionSetMessageTTL","params":[{"name":"ttl_seconds","type":"int"}],"type":"DecryptedMessageAction"},{"id":"-1058912715","predicate":"messages.dhConfigNotModified","params":[{"name":"random","type":"bytes"}],"type":"messages.DhConfig"},{"id":"740433629","predicate":"messages.dhConfig","params":[{"name":"g","type":"int"},{"name":"p","type":"bytes"},{"name":"version","type":"int"},{"name":"random","type":"bytes"}],"type":"messages.DhConfig"},{"id":"1443858741","predicate":"messages.sentEncryptedMessage","params":[{"name":"date","type":"int"}],"type":"messages.SentEncryptedMessage"},{"id":"-1802240206","predicate":"messages.sentEncryptedFile","params":[{"name":"date","type":"int"},{"name":"file","type":"EncryptedFile"}],"type":"messages.SentEncryptedMessage"},{"id":"-95482955","predicate":"inputFileBig","params":[{"name":"id","type":"long"},{"name":"parts","type":"int"},{"name":"name","type":"string"}],"type":"InputFile"},{"id":"767652808","predicate":"inputEncryptedFileBigUploaded","params":[{"name":"id","type":"long"},{"name":"parts","type":"int"},{"name":"key_fingerprint","type":"int"}],"type":"InputEncryptedFile"},{"id":"974056226","predicate":"updateChatParticipantAdd","params":[{"name":"chat_id","type":"int"},{"name":"user_id","type":"int"},{"name":"inviter_id","type":"int"},{"name":"version","type":"int"}],"type":"Update"},{"id":"1851755554","predicate":"updateChatParticipantDelete","params":[{"name":"chat_id","type":"int"},{"name":"user_id","type":"int"},{"name":"version","type":"int"}],"type":"Update"},{"id":"-1906403213","predicate":"updateDcOptions","params":[{"name":"dc_options","type":"Vector"}],"type":"Update"},{"id":"1638323254","predicate":"inputMediaUploadedAudio","params":[{"name":"file","type":"InputFile"},{"name":"duration","type":"int"}],"type":"InputMedia"},{"id":"-1986820223","predicate":"inputMediaAudio","params":[{"name":"id","type":"InputAudio"}],"type":"InputMedia"},{"id":"887592125","predicate":"inputMediaUploadedDocument","params":[{"name":"file","type":"InputFile"},{"name":"file_name","type":"string"},{"name":"mime_type","type":"string"}],"type":"InputMedia"},{"id":"1044831837","predicate":"inputMediaUploadedThumbDocument","params":[{"name":"file","type":"InputFile"},{"name":"thumb","type":"InputFile"},{"name":"file_name","type":"string"},{"name":"mime_type","type":"string"}],"type":"InputMedia"},{"id":"-779818943","predicate":"inputMediaDocument","params":[{"name":"id","type":"InputDocument"}],"type":"InputMedia"},{"id":"802824708","predicate":"messageMediaDocument","params":[{"name":"document","type":"Document"}],"type":"MessageMedia"},{"id":"-961117440","predicate":"messageMediaAudio","params":[{"name":"audio","type":"Audio"}],"type":"MessageMedia"},{"id":"-648356732","predicate":"inputAudioEmpty","params":[],"type":"InputAudio"},{"id":"2010398975","predicate":"inputAudio","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputAudio"},{"id":"1928391342","predicate":"inputDocumentEmpty","params":[],"type":"InputDocument"},{"id":"410618194","predicate":"inputDocument","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputDocument"},{"id":"1960591437","predicate":"inputAudioFileLocation","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputFileLocation"},{"id":"1313188841","predicate":"inputDocumentFileLocation","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"}],"type":"InputFileLocation"},{"id":"-1332395189","predicate":"decryptedMessageMediaDocument","params":[{"name":"thumb","type":"bytes"},{"name":"thumb_w","type":"int"},{"name":"thumb_h","type":"int"},{"name":"file_name","type":"string"},{"name":"mime_type","type":"string"},{"name":"size","type":"int"},{"name":"key","type":"bytes"},{"name":"iv","type":"bytes"}],"type":"DecryptedMessageMedia"},{"id":"1619031439","predicate":"decryptedMessageMediaAudio","params":[{"name":"duration","type":"int"},{"name":"size","type":"int"},{"name":"key","type":"bytes"},{"name":"iv","type":"bytes"}],"type":"DecryptedMessageMedia"},{"id":"1483311320","predicate":"audioEmpty","params":[{"name":"id","type":"long"}],"type":"Audio"},{"id":"1114908135","predicate":"audio","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"},{"name":"user_id","type":"int"},{"name":"date","type":"int"},{"name":"duration","type":"int"},{"name":"size","type":"int"},{"name":"dc_id","type":"int"}],"type":"Audio"},{"id":"922273905","predicate":"documentEmpty","params":[{"name":"id","type":"long"}],"type":"Document"},{"id":"-1627626714","predicate":"document","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"},{"name":"user_id","type":"int"},{"name":"date","type":"int"},{"name":"file_name","type":"string"},{"name":"mime_type","type":"string"},{"name":"size","type":"int"},{"name":"thumb","type":"PhotoSize"},{"name":"dc_id","type":"int"}],"type":"Document"}],"methods":[{"id":"-878758099","method":"invokeAfterMsg","params":[{"name":"msg_id","type":"long"},{"name":"query","type":"!X"}],"type":"X"},{"id":"1036301552","method":"invokeAfterMsgs","params":[{"name":"msg_ids","type":"Vector"},{"name":"query","type":"!X"}],"type":"X"},{"id":"1401115413","method":"invokeWithLayer1","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"1877286395","method":"auth.checkPhone","params":[{"name":"phone_number","type":"string"}],"type":"auth.CheckedPhone"},{"id":"1988976461","method":"auth.sendCode","params":[{"name":"phone_number","type":"string"},{"name":"sms_type","type":"int"},{"name":"api_id","type":"int"},{"name":"api_hash","type":"string"},{"name":"lang_code","type":"string"}],"type":"auth.SentCode"},{"id":"63247716","method":"auth.sendCall","params":[{"name":"phone_number","type":"string"},{"name":"phone_code_hash","type":"string"}],"type":"Bool"},{"id":"453408308","method":"auth.signUp","params":[{"name":"phone_number","type":"string"},{"name":"phone_code_hash","type":"string"},{"name":"phone_code","type":"string"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"}],"type":"auth.Authorization"},{"id":"-1126886015","method":"auth.signIn","params":[{"name":"phone_number","type":"string"},{"name":"phone_code_hash","type":"string"},{"name":"phone_code","type":"string"}],"type":"auth.Authorization"},{"id":"1461180992","method":"auth.logOut","params":[],"type":"Bool"},{"id":"-1616179942","method":"auth.resetAuthorizations","params":[],"type":"Bool"},{"id":"1998331287","method":"auth.sendInvites","params":[{"name":"phone_numbers","type":"Vector"},{"name":"message","type":"string"}],"type":"Bool"},{"id":"-440401971","method":"auth.exportAuthorization","params":[{"name":"dc_id","type":"int"}],"type":"auth.ExportedAuthorization"},{"id":"-470837741","method":"auth.importAuthorization","params":[{"name":"id","type":"int"},{"name":"bytes","type":"bytes"}],"type":"auth.Authorization"},{"id":"1147957548","method":"account.registerDevice","params":[{"name":"token_type","type":"int"},{"name":"token","type":"string"},{"name":"device_model","type":"string"},{"name":"system_version","type":"string"},{"name":"app_version","type":"string"},{"name":"app_sandbox","type":"Bool"},{"name":"lang_code","type":"string"}],"type":"Bool"},{"id":"1707432768","method":"account.unregisterDevice","params":[{"name":"token_type","type":"int"},{"name":"token","type":"string"}],"type":"Bool"},{"id":"-2067899501","method":"account.updateNotifySettings","params":[{"name":"peer","type":"InputNotifyPeer"},{"name":"settings","type":"InputPeerNotifySettings"}],"type":"Bool"},{"id":"313765169","method":"account.getNotifySettings","params":[{"name":"peer","type":"InputNotifyPeer"}],"type":"PeerNotifySettings"},{"id":"-612493497","method":"account.resetNotifySettings","params":[],"type":"Bool"},{"id":"-259486360","method":"account.updateProfile","params":[{"name":"first_name","type":"string"},{"name":"last_name","type":"string"}],"type":"User"},{"id":"1713919532","method":"account.updateStatus","params":[{"name":"offline","type":"Bool"}],"type":"Bool"},{"id":"-1068696894","method":"account.getWallPapers","params":[],"type":"Vector"},{"id":"227648840","method":"users.getUsers","params":[{"name":"id","type":"Vector"}],"type":"Vector"},{"id":"-902781519","method":"users.getFullUser","params":[{"name":"id","type":"InputUser"}],"type":"UserFull"},{"id":"-995929106","method":"contacts.getStatuses","params":[],"type":"Vector"},{"id":"583445000","method":"contacts.getContacts","params":[{"name":"hash","type":"string"}],"type":"contacts.Contacts"},{"id":"-634342611","method":"contacts.importContacts","params":[{"name":"contacts","type":"Vector"},{"name":"replace","type":"Bool"}],"type":"contacts.ImportedContacts"},{"id":"301470424","method":"contacts.search","params":[{"name":"q","type":"string"},{"name":"limit","type":"int"}],"type":"contacts.Found"},{"id":"-847825880","method":"contacts.getSuggested","params":[{"name":"limit","type":"int"}],"type":"contacts.Suggested"},{"id":"-1902823612","method":"contacts.deleteContact","params":[{"name":"id","type":"InputUser"}],"type":"contacts.Link"},{"id":"1504393374","method":"contacts.deleteContacts","params":[{"name":"id","type":"Vector"}],"type":"Bool"},{"id":"858475004","method":"contacts.block","params":[{"name":"id","type":"InputUser"}],"type":"Bool"},{"id":"-448724803","method":"contacts.unblock","params":[{"name":"id","type":"InputUser"}],"type":"Bool"},{"id":"-176409329","method":"contacts.getBlocked","params":[{"name":"offset","type":"int"},{"name":"limit","type":"int"}],"type":"contacts.Blocked"},{"id":"1109588596","method":"messages.getMessages","params":[{"name":"id","type":"Vector"}],"type":"messages.Messages"},{"id":"-321970698","method":"messages.getDialogs","params":[{"name":"offset","type":"int"},{"name":"max_id","type":"int"},{"name":"limit","type":"int"}],"type":"messages.Dialogs"},{"id":"-1834885329","method":"messages.getHistory","params":[{"name":"peer","type":"InputPeer"},{"name":"offset","type":"int"},{"name":"max_id","type":"int"},{"name":"limit","type":"int"}],"type":"messages.Messages"},{"id":"132772523","method":"messages.search","params":[{"name":"peer","type":"InputPeer"},{"name":"q","type":"string"},{"name":"filter","type":"MessagesFilter"},{"name":"min_date","type":"int"},{"name":"max_date","type":"int"},{"name":"offset","type":"int"},{"name":"max_id","type":"int"},{"name":"limit","type":"int"}],"type":"messages.Messages"},{"id":"-1336990448","method":"messages.readHistory","params":[{"name":"peer","type":"InputPeer"},{"name":"max_id","type":"int"},{"name":"offset","type":"int"}],"type":"messages.AffectedHistory"},{"id":"-185009311","method":"messages.deleteHistory","params":[{"name":"peer","type":"InputPeer"},{"name":"offset","type":"int"}],"type":"messages.AffectedHistory"},{"id":"351460618","method":"messages.deleteMessages","params":[{"name":"id","type":"Vector"}],"type":"Vector"},{"id":"962567550","method":"messages.restoreMessages","params":[{"name":"id","type":"Vector"}],"type":"Vector"},{"id":"682347368","method":"messages.receivedMessages","params":[{"name":"max_id","type":"int"}],"type":"Vector"},{"id":"1905801705","method":"messages.setTyping","params":[{"name":"peer","type":"InputPeer"},{"name":"typing","type":"Bool"}],"type":"Bool"},{"id":"1289620139","method":"messages.sendMessage","params":[{"name":"peer","type":"InputPeer"},{"name":"message","type":"string"},{"name":"random_id","type":"long"}],"type":"messages.SentMessage"},{"id":"-1547149962","method":"messages.sendMedia","params":[{"name":"peer","type":"InputPeer"},{"name":"media","type":"InputMedia"},{"name":"random_id","type":"long"}],"type":"messages.StatedMessage"},{"id":"1363988751","method":"messages.forwardMessages","params":[{"name":"peer","type":"InputPeer"},{"name":"id","type":"Vector"}],"type":"messages.StatedMessages"},{"id":"1013621127","method":"messages.getChats","params":[{"name":"id","type":"Vector"}],"type":"messages.Chats"},{"id":"998448230","method":"messages.getFullChat","params":[{"name":"chat_id","type":"int"}],"type":"messages.ChatFull"},{"id":"-1262720843","method":"messages.editChatTitle","params":[{"name":"chat_id","type":"int"},{"name":"title","type":"string"}],"type":"messages.StatedMessage"},{"id":"-662601187","method":"messages.editChatPhoto","params":[{"name":"chat_id","type":"int"},{"name":"photo","type":"InputChatPhoto"}],"type":"messages.StatedMessage"},{"id":"787082910","method":"messages.addChatUser","params":[{"name":"chat_id","type":"int"},{"name":"user_id","type":"InputUser"},{"name":"fwd_limit","type":"int"}],"type":"messages.StatedMessage"},{"id":"-1010447069","method":"messages.deleteChatUser","params":[{"name":"chat_id","type":"int"},{"name":"user_id","type":"InputUser"}],"type":"messages.StatedMessage"},{"id":"1100847854","method":"messages.createChat","params":[{"name":"users","type":"Vector"},{"name":"title","type":"string"}],"type":"messages.StatedMessage"},{"id":"-304838614","method":"updates.getState","params":[],"type":"updates.State"},{"id":"168039573","method":"updates.getDifference","params":[{"name":"pts","type":"int"},{"name":"date","type":"int"},{"name":"qts","type":"int"}],"type":"updates.Difference"},{"id":"-285902432","method":"photos.updateProfilePhoto","params":[{"name":"id","type":"InputPhoto"},{"name":"crop","type":"InputPhotoCrop"}],"type":"UserProfilePhoto"},{"id":"-720397176","method":"photos.uploadProfilePhoto","params":[{"name":"file","type":"InputFile"},{"name":"caption","type":"string"},{"name":"geo_point","type":"InputGeoPoint"},{"name":"crop","type":"InputPhotoCrop"}],"type":"photos.Photo"},{"id":"-1291540959","method":"upload.saveFilePart","params":[{"name":"file_id","type":"long"},{"name":"file_part","type":"int"},{"name":"bytes","type":"bytes"}],"type":"Bool"},{"id":"-475607115","method":"upload.getFile","params":[{"name":"location","type":"InputFileLocation"},{"name":"offset","type":"int"},{"name":"limit","type":"int"}],"type":"upload.File"},{"id":"-990308245","method":"help.getConfig","params":[],"type":"Config"},{"id":"531836966","method":"help.getNearestDc","params":[],"type":"NearestDc"},{"id":"-938300290","method":"help.getAppUpdate","params":[{"name":"device_model","type":"string"},{"name":"system_version","type":"string"},{"name":"app_version","type":"string"},{"name":"lang_code","type":"string"}],"type":"help.AppUpdate"},{"id":"1862465352","method":"help.saveAppLog","params":[{"name":"events","type":"Vector"}],"type":"Bool"},{"id":"-1532407418","method":"help.getInviteText","params":[{"name":"lang_code","type":"string"}],"type":"help.InviteText"},{"id":"-1209117380","method":"photos.getUserPhotos","params":[{"name":"user_id","type":"InputUser"},{"name":"offset","type":"int"},{"name":"max_id","type":"int"},{"name":"limit","type":"int"}],"type":"photos.Photos"},{"id":"681431542","method":"invokeWithLayer2","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"66319602","method":"messages.forwardMessage","params":[{"name":"peer","type":"InputPeer"},{"name":"id","type":"int"},{"name":"random_id","type":"long"}],"type":"messages.StatedMessage"},{"id":"1102776690","method":"messages.sendBroadcast","params":[{"name":"contacts","type":"Vector"},{"name":"message","type":"string"},{"name":"media","type":"InputMedia"}],"type":"messages.StatedMessages"},{"id":"-1220062616","method":"invokeWithLayer3","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"2132356495","method":"geochats.getLocated","params":[{"name":"geo_point","type":"InputGeoPoint"},{"name":"radius","type":"int"},{"name":"limit","type":"int"}],"type":"geochats.Located"},{"id":"-515735953","method":"geochats.getRecents","params":[{"name":"offset","type":"int"},{"name":"limit","type":"int"}],"type":"geochats.Messages"},{"id":"1437853947","method":"geochats.checkin","params":[{"name":"peer","type":"InputGeoChat"}],"type":"geochats.StatedMessage"},{"id":"1730338159","method":"geochats.getFullChat","params":[{"name":"peer","type":"InputGeoChat"}],"type":"messages.ChatFull"},{"id":"1284383347","method":"geochats.editChatTitle","params":[{"name":"peer","type":"InputGeoChat"},{"name":"title","type":"string"},{"name":"address","type":"string"}],"type":"geochats.StatedMessage"},{"id":"903355029","method":"geochats.editChatPhoto","params":[{"name":"peer","type":"InputGeoChat"},{"name":"photo","type":"InputChatPhoto"}],"type":"geochats.StatedMessage"},{"id":"-808598451","method":"geochats.search","params":[{"name":"peer","type":"InputGeoChat"},{"name":"q","type":"string"},{"name":"filter","type":"MessagesFilter"},{"name":"min_date","type":"int"},{"name":"max_date","type":"int"},{"name":"offset","type":"int"},{"name":"max_id","type":"int"},{"name":"limit","type":"int"}],"type":"geochats.Messages"},{"id":"-1254131096","method":"geochats.getHistory","params":[{"name":"peer","type":"InputGeoChat"},{"name":"offset","type":"int"},{"name":"max_id","type":"int"},{"name":"limit","type":"int"}],"type":"geochats.Messages"},{"id":"146319145","method":"geochats.setTyping","params":[{"name":"peer","type":"InputGeoChat"},{"name":"typing","type":"Bool"}],"type":"Bool"},{"id":"102432836","method":"geochats.sendMessage","params":[{"name":"peer","type":"InputGeoChat"},{"name":"message","type":"string"},{"name":"random_id","type":"long"}],"type":"geochats.StatedMessage"},{"id":"-1192173825","method":"geochats.sendMedia","params":[{"name":"peer","type":"InputGeoChat"},{"name":"media","type":"InputMedia"},{"name":"random_id","type":"long"}],"type":"geochats.StatedMessage"},{"id":"235482646","method":"geochats.createGeoChat","params":[{"name":"title","type":"string"},{"name":"geo_point","type":"InputGeoPoint"},{"name":"address","type":"string"},{"name":"venue","type":"string"}],"type":"geochats.StatedMessage"},{"id":"-559885264","method":"invokeWithLayer4","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"1098536878","method":"invokeWithLayer5","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"979686733","method":"invokeWithLayer6","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"-1514252589","method":"invokeWithLayer7","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"651135312","method":"messages.getDhConfig","params":[{"name":"version","type":"int"},{"name":"random_length","type":"int"}],"type":"messages.DhConfig"},{"id":"-162681021","method":"messages.requestEncryption","params":[{"name":"user_id","type":"InputUser"},{"name":"random_id","type":"int"},{"name":"g_a","type":"bytes"}],"type":"EncryptedChat"},{"id":"1035731989","method":"messages.acceptEncryption","params":[{"name":"peer","type":"InputEncryptedChat"},{"name":"g_b","type":"bytes"},{"name":"key_fingerprint","type":"long"}],"type":"EncryptedChat"},{"id":"-304536635","method":"messages.discardEncryption","params":[{"name":"chat_id","type":"int"}],"type":"Bool"},{"id":"2031374829","method":"messages.setEncryptedTyping","params":[{"name":"peer","type":"InputEncryptedChat"},{"name":"typing","type":"Bool"}],"type":"Bool"},{"id":"2135648522","method":"messages.readEncryptedHistory","params":[{"name":"peer","type":"InputEncryptedChat"},{"name":"max_date","type":"int"}],"type":"Bool"},{"id":"-1451792525","method":"messages.sendEncrypted","params":[{"name":"peer","type":"InputEncryptedChat"},{"name":"random_id","type":"long"},{"name":"data","type":"bytes"}],"type":"messages.SentEncryptedMessage"},{"id":"-1701831834","method":"messages.sendEncryptedFile","params":[{"name":"peer","type":"InputEncryptedChat"},{"name":"random_id","type":"long"},{"name":"data","type":"bytes"},{"name":"file","type":"InputEncryptedFile"}],"type":"messages.SentEncryptedMessage"},{"id":"852769188","method":"messages.sendEncryptedService","params":[{"name":"peer","type":"InputEncryptedChat"},{"name":"random_id","type":"long"},{"name":"data","type":"bytes"}],"type":"messages.SentEncryptedMessage"},{"id":"1436924774","method":"messages.receivedQueue","params":[{"name":"max_qts","type":"int"}],"type":"Vector"},{"id":"-374613507","method":"invokeWithLayer8","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"-562337987","method":"upload.saveBigFilePart","params":[{"name":"file_id","type":"long"},{"name":"file_part","type":"int"},{"name":"file_total_parts","type":"int"},{"name":"bytes","type":"bytes"}],"type":"Bool"},{"id":"1769565673","method":"initConnection","params":[{"name":"api_id","type":"int"},{"name":"device_model","type":"string"},{"name":"system_version","type":"string"},{"name":"app_version","type":"string"},{"name":"lang_code","type":"string"},{"name":"query","type":"!X"}],"type":"X"},{"id":"1987140195","method":"invokeWithLayer9","params":[{"name":"query","type":"!X"}],"type":"X"},{"id":"962726977","method":"invokeWithLayer10","params":[{"name":"query","type":"!X"}],"type":"X"}]}; + +Config.Schema.API.layer = 10; + +Config.Emoji = {"00a9":["\u00A9",["copyright"]],"00ae":["\u00AE",["registered"]],"203c":["\u203C",["bangbang"]],"2049":["\u2049",["interrobang"]],"2122":["\u2122",["tm"]],"2139":["\u2139",["information_source"]],"2194":["\u2194",["left_right_arrow"]],"2195":["\u2195",["arrow_up_down"]],"2196":["\u2196",["arrow_upper_left"]],"2197":["\u2197",["arrow_upper_right"]],"2198":["\u2198",["arrow_lower_right"]],"2199":["\u2199",["arrow_lower_left"]],"21a9":["\u21A9",["leftwards_arrow_with_hook"]],"21aa":["\u21AA",["arrow_right_hook"]],"231a":["\u231A",["watch"]],"231b":["\u231B",["hourglass"]],"23e9":["\u23E9",["fast_forward"]],"23ea":["\u23EA",["rewind"]],"23eb":["\u23EB",["arrow_double_up"]],"23ec":["\u23EC",["arrow_double_down"]],"23f0":["\u23F0",["alarm_clock"]],"23f3":["\u23F3",["hourglass_flowing_sand"]],"24c2":["\u24C2",["m"]],"25aa":["\u25AA",["black_small_square"]],"25ab":["\u25AB",["white_small_square"]],"25b6":["\u25B6",["arrow_forward"]],"25c0":["\u25C0",["arrow_backward"]],"25fb":["\u25FB",["white_medium_square"]],"25fc":["\u25FC",["black_medium_square"]],"25fd":["\u25FD",["white_medium_small_square"]],"25fe":["\u25FE",["black_medium_small_square"]],"2600":["\u2600",["sunny"]],"2601":["\u2601",["cloud"]],"260e":["\u260E",["phone","telephone"]],"2611":["\u2611",["ballot_box_with_check"]],"2614":["\u2614",["umbrella"]],"2615":["\u2615",["coffee"]],"261d":["\u261D",["point_up"]],"263a":["\u263A",["relaxed"]],"2648":["\u2648",["aries"]],"2649":["\u2649",["taurus"]],"264a":["\u264A",["gemini"]],"264b":["\u264B",["cancer"]],"264c":["\u264C",["leo"]],"264d":["\u264D",["virgo"]],"264e":["\u264E",["libra"]],"264f":["\u264F",["scorpius"]],"2650":["\u2650",["sagittarius"]],"2651":["\u2651",["capricorn"]],"2652":["\u2652",["aquarius"]],"2653":["\u2653",["pisces"]],"2660":["\u2660",["spades"]],"2663":["\u2663",["clubs"]],"2665":["\u2665",["hearts"]],"2666":["\u2666",["diamonds"]],"2668":["\u2668",["hotsprings"]],"267b":["\u267B",["recycle"]],"267f":["\u267F",["wheelchair"]],"2693":["\u2693",["anchor"]],"26a0":["\u26A0",["warning"]],"26a1":["\u26A1",["zap"]],"26aa":["\u26AA",["white_circle"]],"26ab":["\u26AB",["black_circle"]],"26bd":["\u26BD",["soccer"]],"26be":["\u26BE",["baseball"]],"26c4":["\u26C4",["snowman"]],"26c5":["\u26C5",["partly_sunny"]],"26ce":["\u26CE",["ophiuchus"]],"26d4":["\u26D4",["no_entry"]],"26ea":["\u26EA",["church"]],"26f2":["\u26F2",["fountain"]],"26f3":["\u26F3",["golf"]],"26f5":["\u26F5",["boat","sailboat"]],"26fa":["\u26FA",["tent"]],"26fd":["\u26FD",["fuelpump"]],"2702":["\u2702",["scissors"]],"2705":["\u2705",["white_check_mark"]],"2708":["\u2708",["airplane"]],"2709":["\u2709",["email","envelope"]],"270a":["\u270A",["fist"]],"270b":["\u270B",["hand","raised_hand"]],"270c":["\u270C",["v"]],"270f":["\u270F",["pencil2"]],"2712":["\u2712",["black_nib"]],"2714":["\u2714",["heavy_check_mark"]],"2716":["\u2716",["heavy_multiplication_x"]],"2728":["\u2728",["sparkles"]],"2733":["\u2733",["eight_spoked_asterisk"]],"2734":["\u2734",["eight_pointed_black_star"]],"2744":["\u2744",["snowflake"]],"2747":["\u2747",["sparkle"]],"274c":["\u274C",["x"]],"274e":["\u274E",["negative_squared_cross_mark"]],"2753":["\u2753",["question"]],"2754":["\u2754",["grey_question"]],"2755":["\u2755",["grey_exclamation"]],"2757":["\u2757",["exclamation","heavy_exclamation_mark"]],"2764":["\u2764",["heart"],"<3"],"2795":["\u2795",["heavy_plus_sign"]],"2796":["\u2796",["heavy_minus_sign"]],"2797":["\u2797",["heavy_division_sign"]],"27a1":["\u27A1",["arrow_right"]],"27b0":["\u27B0",["curly_loop"]],"27bf":["\u27BF",["loop"]],"2934":["\u2934",["arrow_heading_up"]],"2935":["\u2935",["arrow_heading_down"]],"2b05":["\u2B05",["arrow_left"]],"2b06":["\u2B06",["arrow_up"]],"2b07":["\u2B07",["arrow_down"]],"2b1b":["\u2B1B",["black_large_square"]],"2b1c":["\u2B1C",["white_large_square"]],"2b50":["\u2B50",["star"]],"2b55":["\u2B55",["o"]],"3030":["\u3030",["wavy_dash"]],"303d":["\u303D",["part_alternation_mark"]],"3297":["\u3297",["congratulations"]],"3299":["\u3299",["secret"]],"1f004":["\uD83C\uDC04",["mahjong"]],"1f0cf":["\uD83C\uDCCF",["black_joker"]],"1f170":["\uD83C\uDD70",["a"]],"1f171":["\uD83C\uDD71",["b"]],"1f17e":["\uD83C\uDD7E",["o2"]],"1f17f":["\uD83C\uDD7F",["parking"]],"1f18e":["\uD83C\uDD8E",["ab"]],"1f191":["\uD83C\uDD91",["cl"]],"1f192":["\uD83C\uDD92",["cool"]],"1f193":["\uD83C\uDD93",["free"]],"1f194":["\uD83C\uDD94",["id"]],"1f195":["\uD83C\uDD95",["new"]],"1f196":["\uD83C\uDD96",["ng"]],"1f197":["\uD83C\uDD97",["ok"]],"1f198":["\uD83C\uDD98",["sos"]],"1f199":["\uD83C\uDD99",["up"]],"1f19a":["\uD83C\uDD9A",["vs"]],"1f201":["\uD83C\uDE01",["koko"]],"1f202":["\uD83C\uDE02",["sa"]],"1f21a":["\uD83C\uDE1A",["u7121"]],"1f22f":["\uD83C\uDE2F",["u6307"]],"1f232":["\uD83C\uDE32",["u7981"]],"1f233":["\uD83C\uDE33",["u7a7a"]],"1f234":["\uD83C\uDE34",["u5408"]],"1f235":["\uD83C\uDE35",["u6e80"]],"1f236":["\uD83C\uDE36",["u6709"]],"1f237":["\uD83C\uDE37",["u6708"]],"1f238":["\uD83C\uDE38",["u7533"]],"1f239":["\uD83C\uDE39",["u5272"]],"1f23a":["\uD83C\uDE3A",["u55b6"]],"1f250":["\uD83C\uDE50",["ideograph_advantage"]],"1f251":["\uD83C\uDE51",["accept"]],"1f300":["\uD83C\uDF00",["cyclone"]],"1f301":["\uD83C\uDF01",["foggy"]],"1f302":["\uD83C\uDF02",["closed_umbrella"]],"1f303":["\uD83C\uDF03",["stars"]],"1f304":["\uD83C\uDF04",["sunrise_over_mountains"]],"1f305":["\uD83C\uDF05",["sunrise"]],"1f306":["\uD83C\uDF06",["city_sunset"]],"1f307":["\uD83C\uDF07",["city_sunrise"]],"1f308":["\uD83C\uDF08",["rainbow"]],"1f309":["\uD83C\uDF09",["bridge_at_night"]],"1f30a":["\uD83C\uDF0A",["ocean"]],"1f30b":["\uD83C\uDF0B",["volcano"]],"1f30c":["\uD83C\uDF0C",["milky_way"]],"1f30d":["\uD83C\uDF0D",["earth_africa"]],"1f30e":["\uD83C\uDF0E",["earth_americas"]],"1f30f":["\uD83C\uDF0F",["earth_asia"]],"1f310":["\uD83C\uDF10",["globe_with_meridians"]],"1f311":["\uD83C\uDF11",["new_moon"]],"1f312":["\uD83C\uDF12",["waxing_crescent_moon"]],"1f313":["\uD83C\uDF13",["first_quarter_moon"]],"1f314":["\uD83C\uDF14",["moon","waxing_gibbous_moon"]],"1f315":["\uD83C\uDF15",["full_moon"]],"1f316":["\uD83C\uDF16",["waning_gibbous_moon"]],"1f317":["\uD83C\uDF17",["last_quarter_moon"]],"1f318":["\uD83C\uDF18",["waning_crescent_moon"]],"1f319":["\uD83C\uDF19",["crescent_moon"]],"1f31a":["\uD83C\uDF1A",["new_moon_with_face"]],"1f31b":["\uD83C\uDF1B",["first_quarter_moon_with_face"]],"1f31c":["\uD83C\uDF1C",["last_quarter_moon_with_face"]],"1f31d":["\uD83C\uDF1D",["full_moon_with_face"]],"1f31e":["\uD83C\uDF1E",["sun_with_face"]],"1f31f":["\uD83C\uDF1F",["star2"]],"1f330":["\uD83C\uDF30",["chestnut"]],"1f331":["\uD83C\uDF31",["seedling"]],"1f332":["\uD83C\uDF32",["evergreen_tree"]],"1f333":["\uD83C\uDF33",["deciduous_tree"]],"1f334":["\uD83C\uDF34",["palm_tree"]],"1f335":["\uD83C\uDF35",["cactus"]],"1f337":["\uD83C\uDF37",["tulip"]],"1f338":["\uD83C\uDF38",["cherry_blossom"]],"1f339":["\uD83C\uDF39",["rose"]],"1f33a":["\uD83C\uDF3A",["hibiscus"]],"1f33b":["\uD83C\uDF3B",["sunflower"]],"1f33c":["\uD83C\uDF3C",["blossom"]],"1f33d":["\uD83C\uDF3D",["corn"]],"1f33e":["\uD83C\uDF3E",["ear_of_rice"]],"1f33f":["\uD83C\uDF3F",["herb"]],"1f340":["\uD83C\uDF40",["four_leaf_clover"]],"1f341":["\uD83C\uDF41",["maple_leaf"]],"1f342":["\uD83C\uDF42",["fallen_leaf"]],"1f343":["\uD83C\uDF43",["leaves"]],"1f344":["\uD83C\uDF44",["mushroom"]],"1f345":["\uD83C\uDF45",["tomato"]],"1f346":["\uD83C\uDF46",["eggplant"]],"1f347":["\uD83C\uDF47",["grapes"]],"1f348":["\uD83C\uDF48",["melon"]],"1f349":["\uD83C\uDF49",["watermelon"]],"1f34a":["\uD83C\uDF4A",["tangerine"]],"1f34b":["\uD83C\uDF4B",["lemon"]],"1f34c":["\uD83C\uDF4C",["banana"]],"1f34d":["\uD83C\uDF4D",["pineapple"]],"1f34e":["\uD83C\uDF4E",["apple"]],"1f34f":["\uD83C\uDF4F",["green_apple"]],"1f350":["\uD83C\uDF50",["pear"]],"1f351":["\uD83C\uDF51",["peach"]],"1f352":["\uD83C\uDF52",["cherries"]],"1f353":["\uD83C\uDF53",["strawberry"]],"1f354":["\uD83C\uDF54",["hamburger"]],"1f355":["\uD83C\uDF55",["pizza"]],"1f356":["\uD83C\uDF56",["meat_on_bone"]],"1f357":["\uD83C\uDF57",["poultry_leg"]],"1f358":["\uD83C\uDF58",["rice_cracker"]],"1f359":["\uD83C\uDF59",["rice_ball"]],"1f35a":["\uD83C\uDF5A",["rice"]],"1f35b":["\uD83C\uDF5B",["curry"]],"1f35c":["\uD83C\uDF5C",["ramen"]],"1f35d":["\uD83C\uDF5D",["spaghetti"]],"1f35e":["\uD83C\uDF5E",["bread"]],"1f35f":["\uD83C\uDF5F",["fries"]],"1f360":["\uD83C\uDF60",["sweet_potato"]],"1f361":["\uD83C\uDF61",["dango"]],"1f362":["\uD83C\uDF62",["oden"]],"1f363":["\uD83C\uDF63",["sushi"]],"1f364":["\uD83C\uDF64",["fried_shrimp"]],"1f365":["\uD83C\uDF65",["fish_cake"]],"1f366":["\uD83C\uDF66",["icecream"]],"1f367":["\uD83C\uDF67",["shaved_ice"]],"1f368":["\uD83C\uDF68",["ice_cream"]],"1f369":["\uD83C\uDF69",["doughnut"]],"1f36a":["\uD83C\uDF6A",["cookie"]],"1f36b":["\uD83C\uDF6B",["chocolate_bar"]],"1f36c":["\uD83C\uDF6C",["candy"]],"1f36d":["\uD83C\uDF6D",["lollipop"]],"1f36e":["\uD83C\uDF6E",["custard"]],"1f36f":["\uD83C\uDF6F",["honey_pot"]],"1f370":["\uD83C\uDF70",["cake"]],"1f371":["\uD83C\uDF71",["bento"]],"1f372":["\uD83C\uDF72",["stew"]],"1f373":["\uD83C\uDF73",["egg"]],"1f374":["\uD83C\uDF74",["fork_and_knife"]],"1f375":["\uD83C\uDF75",["tea"]],"1f376":["\uD83C\uDF76",["sake"]],"1f377":["\uD83C\uDF77",["wine_glass"]],"1f378":["\uD83C\uDF78",["cocktail"]],"1f379":["\uD83C\uDF79",["tropical_drink"]],"1f37a":["\uD83C\uDF7A",["beer"]],"1f37b":["\uD83C\uDF7B",["beers"]],"1f37c":["\uD83C\uDF7C",["baby_bottle"]],"1f380":["\uD83C\uDF80",["ribbon"]],"1f381":["\uD83C\uDF81",["gift"]],"1f382":["\uD83C\uDF82",["birthday"]],"1f383":["\uD83C\uDF83",["jack_o_lantern"]],"1f384":["\uD83C\uDF84",["christmas_tree"]],"1f385":["\uD83C\uDF85",["santa"]],"1f386":["\uD83C\uDF86",["fireworks"]],"1f387":["\uD83C\uDF87",["sparkler"]],"1f388":["\uD83C\uDF88",["balloon"]],"1f389":["\uD83C\uDF89",["tada"]],"1f38a":["\uD83C\uDF8A",["confetti_ball"]],"1f38b":["\uD83C\uDF8B",["tanabata_tree"]],"1f38c":["\uD83C\uDF8C",["crossed_flags"]],"1f38d":["\uD83C\uDF8D",["bamboo"]],"1f38e":["\uD83C\uDF8E",["dolls"]],"1f38f":["\uD83C\uDF8F",["flags"]],"1f390":["\uD83C\uDF90",["wind_chime"]],"1f391":["\uD83C\uDF91",["rice_scene"]],"1f392":["\uD83C\uDF92",["school_satchel"]],"1f393":["\uD83C\uDF93",["mortar_board"]],"1f3a0":["\uD83C\uDFA0",["carousel_horse"]],"1f3a1":["\uD83C\uDFA1",["ferris_wheel"]],"1f3a2":["\uD83C\uDFA2",["roller_coaster"]],"1f3a3":["\uD83C\uDFA3",["fishing_pole_and_fish"]],"1f3a4":["\uD83C\uDFA4",["microphone"]],"1f3a5":["\uD83C\uDFA5",["movie_camera"]],"1f3a6":["\uD83C\uDFA6",["cinema"]],"1f3a7":["\uD83C\uDFA7",["headphones"]],"1f3a8":["\uD83C\uDFA8",["art"]],"1f3a9":["\uD83C\uDFA9",["tophat"]],"1f3aa":["\uD83C\uDFAA",["circus_tent"]],"1f3ab":["\uD83C\uDFAB",["ticket"]],"1f3ac":["\uD83C\uDFAC",["clapper"]],"1f3ad":["\uD83C\uDFAD",["performing_arts"]],"1f3ae":["\uD83C\uDFAE",["video_game"]],"1f3af":["\uD83C\uDFAF",["dart"]],"1f3b0":["\uD83C\uDFB0",["slot_machine"]],"1f3b1":["\uD83C\uDFB1",["8ball"]],"1f3b2":["\uD83C\uDFB2",["game_die"]],"1f3b3":["\uD83C\uDFB3",["bowling"]],"1f3b4":["\uD83C\uDFB4",["flower_playing_cards"]],"1f3b5":["\uD83C\uDFB5",["musical_note"]],"1f3b6":["\uD83C\uDFB6",["notes"]],"1f3b7":["\uD83C\uDFB7",["saxophone"]],"1f3b8":["\uD83C\uDFB8",["guitar"]],"1f3b9":["\uD83C\uDFB9",["musical_keyboard"]],"1f3ba":["\uD83C\uDFBA",["trumpet"]],"1f3bb":["\uD83C\uDFBB",["violin"]],"1f3bc":["\uD83C\uDFBC",["musical_score"]],"1f3bd":["\uD83C\uDFBD",["running_shirt_with_sash"]],"1f3be":["\uD83C\uDFBE",["tennis"]],"1f3bf":["\uD83C\uDFBF",["ski"]],"1f3c0":["\uD83C\uDFC0",["basketball"]],"1f3c1":["\uD83C\uDFC1",["checkered_flag"]],"1f3c2":["\uD83C\uDFC2",["snowboarder"]],"1f3c3":["\uD83C\uDFC3",["runner","running"]],"1f3c4":["\uD83C\uDFC4",["surfer"]],"1f3c6":["\uD83C\uDFC6",["trophy"]],"1f3c7":["\uD83C\uDFC7",["horse_racing"]],"1f3c8":["\uD83C\uDFC8",["football"]],"1f3c9":["\uD83C\uDFC9",["rugby_football"]],"1f3ca":["\uD83C\uDFCA",["swimmer"]],"1f3e0":["\uD83C\uDFE0",["house"]],"1f3e1":["\uD83C\uDFE1",["house_with_garden"]],"1f3e2":["\uD83C\uDFE2",["office"]],"1f3e3":["\uD83C\uDFE3",["post_office"]],"1f3e4":["\uD83C\uDFE4",["european_post_office"]],"1f3e5":["\uD83C\uDFE5",["hospital"]],"1f3e6":["\uD83C\uDFE6",["bank"]],"1f3e7":["\uD83C\uDFE7",["atm"]],"1f3e8":["\uD83C\uDFE8",["hotel"]],"1f3e9":["\uD83C\uDFE9",["love_hotel"]],"1f3ea":["\uD83C\uDFEA",["convenience_store"]],"1f3eb":["\uD83C\uDFEB",["school"]],"1f3ec":["\uD83C\uDFEC",["department_store"]],"1f3ed":["\uD83C\uDFED",["factory"]],"1f3ee":["\uD83C\uDFEE",["izakaya_lantern","lantern"]],"1f3ef":["\uD83C\uDFEF",["japanese_castle"]],"1f3f0":["\uD83C\uDFF0",["european_castle"]],"1f400":["\uD83D\uDC00",["rat"]],"1f401":["\uD83D\uDC01",["mouse2"]],"1f402":["\uD83D\uDC02",["ox"]],"1f403":["\uD83D\uDC03",["water_buffalo"]],"1f404":["\uD83D\uDC04",["cow2"]],"1f405":["\uD83D\uDC05",["tiger2"]],"1f406":["\uD83D\uDC06",["leopard"]],"1f407":["\uD83D\uDC07",["rabbit2"]],"1f408":["\uD83D\uDC08",["cat2"]],"1f409":["\uD83D\uDC09",["dragon"]],"1f40a":["\uD83D\uDC0A",["crocodile"]],"1f40b":["\uD83D\uDC0B",["whale2"]],"1f40c":["\uD83D\uDC0C",["snail"]],"1f40d":["\uD83D\uDC0D",["snake"]],"1f40e":["\uD83D\uDC0E",["racehorse"]],"1f40f":["\uD83D\uDC0F",["ram"]],"1f410":["\uD83D\uDC10",["goat"]],"1f411":["\uD83D\uDC11",["sheep"]],"1f412":["\uD83D\uDC12",["monkey"]],"1f413":["\uD83D\uDC13",["rooster"]],"1f414":["\uD83D\uDC14",["chicken"]],"1f415":["\uD83D\uDC15",["dog2"]],"1f416":["\uD83D\uDC16",["pig2"]],"1f417":["\uD83D\uDC17",["boar"]],"1f418":["\uD83D\uDC18",["elephant"]],"1f419":["\uD83D\uDC19",["octopus"]],"1f41a":["\uD83D\uDC1A",["shell"]],"1f41b":["\uD83D\uDC1B",["bug"]],"1f41c":["\uD83D\uDC1C",["ant"]],"1f41d":["\uD83D\uDC1D",["bee","honeybee"]],"1f41e":["\uD83D\uDC1E",["beetle"]],"1f41f":["\uD83D\uDC1F",["fish"]],"1f420":["\uD83D\uDC20",["tropical_fish"]],"1f421":["\uD83D\uDC21",["blowfish"]],"1f422":["\uD83D\uDC22",["turtle"]],"1f423":["\uD83D\uDC23",["hatching_chick"]],"1f424":["\uD83D\uDC24",["baby_chick"]],"1f425":["\uD83D\uDC25",["hatched_chick"]],"1f426":["\uD83D\uDC26",["bird"]],"1f427":["\uD83D\uDC27",["penguin"]],"1f428":["\uD83D\uDC28",["koala"]],"1f429":["\uD83D\uDC29",["poodle"]],"1f42a":["\uD83D\uDC2A",["dromedary_camel"]],"1f42b":["\uD83D\uDC2B",["camel"]],"1f42c":["\uD83D\uDC2C",["dolphin","flipper"]],"1f42d":["\uD83D\uDC2D",["mouse"]],"1f42e":["\uD83D\uDC2E",["cow"]],"1f42f":["\uD83D\uDC2F",["tiger"]],"1f430":["\uD83D\uDC30",["rabbit"]],"1f431":["\uD83D\uDC31",["cat"]],"1f432":["\uD83D\uDC32",["dragon_face"]],"1f433":["\uD83D\uDC33",["whale"]],"1f434":["\uD83D\uDC34",["horse"]],"1f435":["\uD83D\uDC35",["monkey_face"]],"1f436":["\uD83D\uDC36",["dog"]],"1f437":["\uD83D\uDC37",["pig"]],"1f438":["\uD83D\uDC38",["frog"]],"1f439":["\uD83D\uDC39",["hamster"]],"1f43a":["\uD83D\uDC3A",["wolf"]],"1f43b":["\uD83D\uDC3B",["bear"]],"1f43c":["\uD83D\uDC3C",["panda_face"]],"1f43d":["\uD83D\uDC3D",["pig_nose"]],"1f43e":["\uD83D\uDC3E",["feet","paw_prints"]],"1f440":["\uD83D\uDC40",["eyes"]],"1f442":["\uD83D\uDC42",["ear"]],"1f443":["\uD83D\uDC43",["nose"]],"1f444":["\uD83D\uDC44",["lips"]],"1f445":["\uD83D\uDC45",["tongue"]],"1f446":["\uD83D\uDC46",["point_up_2"]],"1f447":["\uD83D\uDC47",["point_down"]],"1f448":["\uD83D\uDC48",["point_left"]],"1f449":["\uD83D\uDC49",["point_right"]],"1f44a":["\uD83D\uDC4A",["facepunch","punch"]],"1f44b":["\uD83D\uDC4B",["wave"]],"1f44c":["\uD83D\uDC4C",["ok_hand"]],"1f44d":["\uD83D\uDC4D",["+1","thumbsup"]],"1f44e":["\uD83D\uDC4E",["-1","thumbsdown"]],"1f44f":["\uD83D\uDC4F",["clap"]],"1f450":["\uD83D\uDC50",["open_hands"]],"1f451":["\uD83D\uDC51",["crown"]],"1f452":["\uD83D\uDC52",["womans_hat"]],"1f453":["\uD83D\uDC53",["eyeglasses"]],"1f454":["\uD83D\uDC54",["necktie"]],"1f455":["\uD83D\uDC55",["shirt","tshirt"]],"1f456":["\uD83D\uDC56",["jeans"]],"1f457":["\uD83D\uDC57",["dress"]],"1f458":["\uD83D\uDC58",["kimono"]],"1f459":["\uD83D\uDC59",["bikini"]],"1f45a":["\uD83D\uDC5A",["womans_clothes"]],"1f45b":["\uD83D\uDC5B",["purse"]],"1f45c":["\uD83D\uDC5C",["handbag"]],"1f45d":["\uD83D\uDC5D",["pouch"]],"1f45e":["\uD83D\uDC5E",["mans_shoe","shoe"]],"1f45f":["\uD83D\uDC5F",["athletic_shoe"]],"1f460":["\uD83D\uDC60",["high_heel"]],"1f461":["\uD83D\uDC61",["sandal"]],"1f462":["\uD83D\uDC62",["boot"]],"1f463":["\uD83D\uDC63",["footprints"]],"1f464":["\uD83D\uDC64",["bust_in_silhouette"]],"1f465":["\uD83D\uDC65",["busts_in_silhouette"]],"1f466":["\uD83D\uDC66",["boy"]],"1f467":["\uD83D\uDC67",["girl"]],"1f468":["\uD83D\uDC68",["man"]],"1f469":["\uD83D\uDC69",["woman"]],"1f46a":["\uD83D\uDC6A",["family"]],"1f46b":["\uD83D\uDC6B",["couple"]],"1f46c":["\uD83D\uDC6C",["two_men_holding_hands"]],"1f46d":["\uD83D\uDC6D",["two_women_holding_hands"]],"1f46e":["\uD83D\uDC6E",["cop"]],"1f46f":["\uD83D\uDC6F",["dancers"]],"1f470":["\uD83D\uDC70",["bride_with_veil"]],"1f471":["\uD83D\uDC71",["person_with_blond_hair"]],"1f472":["\uD83D\uDC72",["man_with_gua_pi_mao"]],"1f473":["\uD83D\uDC73",["man_with_turban"]],"1f474":["\uD83D\uDC74",["older_man"]],"1f475":["\uD83D\uDC75",["older_woman"]],"1f476":["\uD83D\uDC76",["baby"]],"1f477":["\uD83D\uDC77",["construction_worker"]],"1f478":["\uD83D\uDC78",["princess"]],"1f479":["\uD83D\uDC79",["japanese_ogre"]],"1f47a":["\uD83D\uDC7A",["japanese_goblin"]],"1f47b":["\uD83D\uDC7B",["ghost"]],"1f47c":["\uD83D\uDC7C",["angel"]],"1f47d":["\uD83D\uDC7D",["alien"]],"1f47e":["\uD83D\uDC7E",["space_invader"]],"1f47f":["\uD83D\uDC7F",["imp"]],"1f480":["\uD83D\uDC80",["skull"]],"1f481":["\uD83D\uDC81",["information_desk_person"]],"1f482":["\uD83D\uDC82",["guardsman"]],"1f483":["\uD83D\uDC83",["dancer"]],"1f484":["\uD83D\uDC84",["lipstick"]],"1f485":["\uD83D\uDC85",["nail_care"]],"1f486":["\uD83D\uDC86",["massage"]],"1f487":["\uD83D\uDC87",["haircut"]],"1f488":["\uD83D\uDC88",["barber"]],"1f489":["\uD83D\uDC89",["syringe"]],"1f48a":["\uD83D\uDC8A",["pill"]],"1f48b":["\uD83D\uDC8B",["kiss"]],"1f48c":["\uD83D\uDC8C",["love_letter"]],"1f48d":["\uD83D\uDC8D",["ring"]],"1f48e":["\uD83D\uDC8E",["gem"]],"1f48f":["\uD83D\uDC8F",["couplekiss"]],"1f490":["\uD83D\uDC90",["bouquet"]],"1f491":["\uD83D\uDC91",["couple_with_heart"]],"1f492":["\uD83D\uDC92",["wedding"]],"1f493":["\uD83D\uDC93",["heartbeat"]],"1f494":["\uD83D\uDC94",["broken_heart"],"<\/3"],"1f495":["\uD83D\uDC95",["two_hearts"]],"1f496":["\uD83D\uDC96",["sparkling_heart"]],"1f497":["\uD83D\uDC97",["heartpulse"]],"1f498":["\uD83D\uDC98",["cupid"]],"1f499":["\uD83D\uDC99",["blue_heart"],"<3"],"1f49a":["\uD83D\uDC9A",["green_heart"],"<3"],"1f49b":["\uD83D\uDC9B",["yellow_heart"],"<3"],"1f49c":["\uD83D\uDC9C",["purple_heart"],"<3"],"1f49d":["\uD83D\uDC9D",["gift_heart"]],"1f49e":["\uD83D\uDC9E",["revolving_hearts"]],"1f49f":["\uD83D\uDC9F",["heart_decoration"]],"1f4a0":["\uD83D\uDCA0",["diamond_shape_with_a_dot_inside"]],"1f4a1":["\uD83D\uDCA1",["bulb"]],"1f4a2":["\uD83D\uDCA2",["anger"]],"1f4a3":["\uD83D\uDCA3",["bomb"]],"1f4a4":["\uD83D\uDCA4",["zzz"]],"1f4a5":["\uD83D\uDCA5",["boom","collision"]],"1f4a6":["\uD83D\uDCA6",["sweat_drops"]],"1f4a7":["\uD83D\uDCA7",["droplet"]],"1f4a8":["\uD83D\uDCA8",["dash"]],"1f4a9":["\uD83D\uDCA9",["hankey","poop","shit"]],"1f4aa":["\uD83D\uDCAA",["muscle"]],"1f4ab":["\uD83D\uDCAB",["dizzy"]],"1f4ac":["\uD83D\uDCAC",["speech_balloon"]],"1f4ad":["\uD83D\uDCAD",["thought_balloon"]],"1f4ae":["\uD83D\uDCAE",["white_flower"]],"1f4af":["\uD83D\uDCAF",["100"]],"1f4b0":["\uD83D\uDCB0",["moneybag"]],"1f4b1":["\uD83D\uDCB1",["currency_exchange"]],"1f4b2":["\uD83D\uDCB2",["heavy_dollar_sign"]],"1f4b3":["\uD83D\uDCB3",["credit_card"]],"1f4b4":["\uD83D\uDCB4",["yen"]],"1f4b5":["\uD83D\uDCB5",["dollar"]],"1f4b6":["\uD83D\uDCB6",["euro"]],"1f4b7":["\uD83D\uDCB7",["pound"]],"1f4b8":["\uD83D\uDCB8",["money_with_wings"]],"1f4b9":["\uD83D\uDCB9",["chart"]],"1f4ba":["\uD83D\uDCBA",["seat"]],"1f4bb":["\uD83D\uDCBB",["computer"]],"1f4bc":["\uD83D\uDCBC",["briefcase"]],"1f4bd":["\uD83D\uDCBD",["minidisc"]],"1f4be":["\uD83D\uDCBE",["floppy_disk"]],"1f4bf":["\uD83D\uDCBF",["cd"]],"1f4c0":["\uD83D\uDCC0",["dvd"]],"1f4c1":["\uD83D\uDCC1",["file_folder"]],"1f4c2":["\uD83D\uDCC2",["open_file_folder"]],"1f4c3":["\uD83D\uDCC3",["page_with_curl"]],"1f4c4":["\uD83D\uDCC4",["page_facing_up"]],"1f4c5":["\uD83D\uDCC5",["date"]],"1f4c6":["\uD83D\uDCC6",["calendar"]],"1f4c7":["\uD83D\uDCC7",["card_index"]],"1f4c8":["\uD83D\uDCC8",["chart_with_upwards_trend"]],"1f4c9":["\uD83D\uDCC9",["chart_with_downwards_trend"]],"1f4ca":["\uD83D\uDCCA",["bar_chart"]],"1f4cb":["\uD83D\uDCCB",["clipboard"]],"1f4cc":["\uD83D\uDCCC",["pushpin"]],"1f4cd":["\uD83D\uDCCD",["round_pushpin"]],"1f4ce":["\uD83D\uDCCE",["paperclip"]],"1f4cf":["\uD83D\uDCCF",["straight_ruler"]],"1f4d0":["\uD83D\uDCD0",["triangular_ruler"]],"1f4d1":["\uD83D\uDCD1",["bookmark_tabs"]],"1f4d2":["\uD83D\uDCD2",["ledger"]],"1f4d3":["\uD83D\uDCD3",["notebook"]],"1f4d4":["\uD83D\uDCD4",["notebook_with_decorative_cover"]],"1f4d5":["\uD83D\uDCD5",["closed_book"]],"1f4d6":["\uD83D\uDCD6",["book","open_book"]],"1f4d7":["\uD83D\uDCD7",["green_book"]],"1f4d8":["\uD83D\uDCD8",["blue_book"]],"1f4d9":["\uD83D\uDCD9",["orange_book"]],"1f4da":["\uD83D\uDCDA",["books"]],"1f4db":["\uD83D\uDCDB",["name_badge"]],"1f4dc":["\uD83D\uDCDC",["scroll"]],"1f4dd":["\uD83D\uDCDD",["memo","pencil"]],"1f4de":["\uD83D\uDCDE",["telephone_receiver"]],"1f4df":["\uD83D\uDCDF",["pager"]],"1f4e0":["\uD83D\uDCE0",["fax"]],"1f4e1":["\uD83D\uDCE1",["satellite"]],"1f4e2":["\uD83D\uDCE2",["loudspeaker"]],"1f4e3":["\uD83D\uDCE3",["mega"]],"1f4e4":["\uD83D\uDCE4",["outbox_tray"]],"1f4e5":["\uD83D\uDCE5",["inbox_tray"]],"1f4e6":["\uD83D\uDCE6",["package"]],"1f4e7":["\uD83D\uDCE7",["e-mail"]],"1f4e8":["\uD83D\uDCE8",["incoming_envelope"]],"1f4e9":["\uD83D\uDCE9",["envelope_with_arrow"]],"1f4ea":["\uD83D\uDCEA",["mailbox_closed"]],"1f4eb":["\uD83D\uDCEB",["mailbox"]],"1f4ec":["\uD83D\uDCEC",["mailbox_with_mail"]],"1f4ed":["\uD83D\uDCED",["mailbox_with_no_mail"]],"1f4ee":["\uD83D\uDCEE",["postbox"]],"1f4ef":["\uD83D\uDCEF",["postal_horn"]],"1f4f0":["\uD83D\uDCF0",["newspaper"]],"1f4f1":["\uD83D\uDCF1",["iphone"]],"1f4f2":["\uD83D\uDCF2",["calling"]],"1f4f3":["\uD83D\uDCF3",["vibration_mode"]],"1f4f4":["\uD83D\uDCF4",["mobile_phone_off"]],"1f4f5":["\uD83D\uDCF5",["no_mobile_phones"]],"1f4f6":["\uD83D\uDCF6",["signal_strength"]],"1f4f7":["\uD83D\uDCF7",["camera"]],"1f4f9":["\uD83D\uDCF9",["video_camera"]],"1f4fa":["\uD83D\uDCFA",["tv"]],"1f4fb":["\uD83D\uDCFB",["radio"]],"1f4fc":["\uD83D\uDCFC",["vhs"]],"1f500":["\uD83D\uDD00",["twisted_rightwards_arrows"]],"1f501":["\uD83D\uDD01",["repeat"]],"1f502":["\uD83D\uDD02",["repeat_one"]],"1f503":["\uD83D\uDD03",["arrows_clockwise"]],"1f504":["\uD83D\uDD04",["arrows_counterclockwise"]],"1f505":["\uD83D\uDD05",["low_brightness"]],"1f506":["\uD83D\uDD06",["high_brightness"]],"1f507":["\uD83D\uDD07",["mute"]],"1f509":["\uD83D\uDD09",["sound"]],"1f50a":["\uD83D\uDD0A",["speaker"]],"1f50b":["\uD83D\uDD0B",["battery"]],"1f50c":["\uD83D\uDD0C",["electric_plug"]],"1f50d":["\uD83D\uDD0D",["mag"]],"1f50e":["\uD83D\uDD0E",["mag_right"]],"1f50f":["\uD83D\uDD0F",["lock_with_ink_pen"]],"1f510":["\uD83D\uDD10",["closed_lock_with_key"]],"1f511":["\uD83D\uDD11",["key"]],"1f512":["\uD83D\uDD12",["lock"]],"1f513":["\uD83D\uDD13",["unlock"]],"1f514":["\uD83D\uDD14",["bell"]],"1f515":["\uD83D\uDD15",["no_bell"]],"1f516":["\uD83D\uDD16",["bookmark"]],"1f517":["\uD83D\uDD17",["link"]],"1f518":["\uD83D\uDD18",["radio_button"]],"1f519":["\uD83D\uDD19",["back"]],"1f51a":["\uD83D\uDD1A",["end"]],"1f51b":["\uD83D\uDD1B",["on"]],"1f51c":["\uD83D\uDD1C",["soon"]],"1f51d":["\uD83D\uDD1D",["top"]],"1f51e":["\uD83D\uDD1E",["underage"]],"1f51f":["\uD83D\uDD1F",["keycap_ten"]],"1f520":["\uD83D\uDD20",["capital_abcd"]],"1f521":["\uD83D\uDD21",["abcd"]],"1f522":["\uD83D\uDD22",["1234"]],"1f523":["\uD83D\uDD23",["symbols"]],"1f524":["\uD83D\uDD24",["abc"]],"1f525":["\uD83D\uDD25",["fire"]],"1f526":["\uD83D\uDD26",["flashlight"]],"1f527":["\uD83D\uDD27",["wrench"]],"1f528":["\uD83D\uDD28",["hammer"]],"1f529":["\uD83D\uDD29",["nut_and_bolt"]],"1f52a":["\uD83D\uDD2A",["hocho"]],"1f52b":["\uD83D\uDD2B",["gun"]],"1f52c":["\uD83D\uDD2C",["microscope"]],"1f52d":["\uD83D\uDD2D",["telescope"]],"1f52e":["\uD83D\uDD2E",["crystal_ball"]],"1f52f":["\uD83D\uDD2F",["six_pointed_star"]],"1f530":["\uD83D\uDD30",["beginner"]],"1f531":["\uD83D\uDD31",["trident"]],"1f532":["\uD83D\uDD32",["black_square_button"]],"1f533":["\uD83D\uDD33",["white_square_button"]],"1f534":["\uD83D\uDD34",["red_circle"]],"1f535":["\uD83D\uDD35",["large_blue_circle"]],"1f536":["\uD83D\uDD36",["large_orange_diamond"]],"1f537":["\uD83D\uDD37",["large_blue_diamond"]],"1f538":["\uD83D\uDD38",["small_orange_diamond"]],"1f539":["\uD83D\uDD39",["small_blue_diamond"]],"1f53a":["\uD83D\uDD3A",["small_red_triangle"]],"1f53b":["\uD83D\uDD3B",["small_red_triangle_down"]],"1f53c":["\uD83D\uDD3C",["arrow_up_small"]],"1f53d":["\uD83D\uDD3D",["arrow_down_small"]],"1f550":["\uD83D\uDD50",["clock1"]],"1f551":["\uD83D\uDD51",["clock2"]],"1f552":["\uD83D\uDD52",["clock3"]],"1f553":["\uD83D\uDD53",["clock4"]],"1f554":["\uD83D\uDD54",["clock5"]],"1f555":["\uD83D\uDD55",["clock6"]],"1f556":["\uD83D\uDD56",["clock7"]],"1f557":["\uD83D\uDD57",["clock8"]],"1f558":["\uD83D\uDD58",["clock9"]],"1f559":["\uD83D\uDD59",["clock10"]],"1f55a":["\uD83D\uDD5A",["clock11"]],"1f55b":["\uD83D\uDD5B",["clock12"]],"1f55c":["\uD83D\uDD5C",["clock130"]],"1f55d":["\uD83D\uDD5D",["clock230"]],"1f55e":["\uD83D\uDD5E",["clock330"]],"1f55f":["\uD83D\uDD5F",["clock430"]],"1f560":["\uD83D\uDD60",["clock530"]],"1f561":["\uD83D\uDD61",["clock630"]],"1f562":["\uD83D\uDD62",["clock730"]],"1f563":["\uD83D\uDD63",["clock830"]],"1f564":["\uD83D\uDD64",["clock930"]],"1f565":["\uD83D\uDD65",["clock1030"]],"1f566":["\uD83D\uDD66",["clock1130"]],"1f567":["\uD83D\uDD67",["clock1230"]],"1f5fb":["\uD83D\uDDFB",["mount_fuji"]],"1f5fc":["\uD83D\uDDFC",["tokyo_tower"]],"1f5fd":["\uD83D\uDDFD",["statue_of_liberty"]],"1f5fe":["\uD83D\uDDFE",["japan"]],"1f5ff":["\uD83D\uDDFF",["moyai"]],"1f600":["\uD83D\uDE00",["grinning"]],"1f601":["\uD83D\uDE01",["grin"]],"1f602":["\uD83D\uDE02",["joy"]],"1f603":["\uD83D\uDE03",["smiley"],":)"],"1f604":["\uD83D\uDE04",["smile"],":)"],"1f605":["\uD83D\uDE05",["sweat_smile"]],"1f606":["\uD83D\uDE06",["laughing","satisfied"]],"1f607":["\uD83D\uDE07",["innocent"]],"1f608":["\uD83D\uDE08",["smiling_imp"]],"1f609":["\uD83D\uDE09",["wink"],";)"],"1f60a":["\uD83D\uDE0A",["blush"]],"1f60b":["\uD83D\uDE0B",["yum"]],"1f60c":["\uD83D\uDE0C",["relieved"]],"1f60d":["\uD83D\uDE0D",["heart_eyes"]],"1f60e":["\uD83D\uDE0E",["sunglasses"]],"1f60f":["\uD83D\uDE0F",["smirk"]],"1f610":["\uD83D\uDE10",["neutral_face"]],"1f611":["\uD83D\uDE11",["expressionless"]],"1f612":["\uD83D\uDE12",["unamused"]],"1f613":["\uD83D\uDE13",["sweat"]],"1f614":["\uD83D\uDE14",["pensive"]],"1f615":["\uD83D\uDE15",["confused"]],"1f616":["\uD83D\uDE16",["confounded"]],"1f617":["\uD83D\uDE17",["kissing"]],"1f618":["\uD83D\uDE18",["kissing_heart"]],"1f619":["\uD83D\uDE19",["kissing_smiling_eyes"]],"1f61a":["\uD83D\uDE1A",["kissing_closed_eyes"]],"1f61b":["\uD83D\uDE1B",["stuck_out_tongue"]],"1f61c":["\uD83D\uDE1C",["stuck_out_tongue_winking_eye"],";p"],"1f61d":["\uD83D\uDE1D",["stuck_out_tongue_closed_eyes"]],"1f61e":["\uD83D\uDE1E",["disappointed"],":("],"1f61f":["\uD83D\uDE1F",["worried"]],"1f620":["\uD83D\uDE20",["angry"]],"1f621":["\uD83D\uDE21",["rage"]],"1f622":["\uD83D\uDE22",["cry"],":'("],"1f623":["\uD83D\uDE23",["persevere"]],"1f624":["\uD83D\uDE24",["triumph"]],"1f625":["\uD83D\uDE25",["disappointed_relieved"]],"1f626":["\uD83D\uDE26",["frowning"]],"1f627":["\uD83D\uDE27",["anguished"]],"1f628":["\uD83D\uDE28",["fearful"]],"1f629":["\uD83D\uDE29",["weary"]],"1f62a":["\uD83D\uDE2A",["sleepy"]],"1f62b":["\uD83D\uDE2B",["tired_face"]],"1f62c":["\uD83D\uDE2C",["grimacing"]],"1f62d":["\uD83D\uDE2D",["sob"],":'("],"1f62e":["\uD83D\uDE2E",["open_mouth"]],"1f62f":["\uD83D\uDE2F",["hushed"]],"1f630":["\uD83D\uDE30",["cold_sweat"]],"1f631":["\uD83D\uDE31",["scream"]],"1f632":["\uD83D\uDE32",["astonished"]],"1f633":["\uD83D\uDE33",["flushed"]],"1f634":["\uD83D\uDE34",["sleeping"]],"1f635":["\uD83D\uDE35",["dizzy_face"]],"1f636":["\uD83D\uDE36",["no_mouth"]],"1f637":["\uD83D\uDE37",["mask"]],"1f638":["\uD83D\uDE38",["smile_cat"]],"1f639":["\uD83D\uDE39",["joy_cat"]],"1f63a":["\uD83D\uDE3A",["smiley_cat"]],"1f63b":["\uD83D\uDE3B",["heart_eyes_cat"]],"1f63c":["\uD83D\uDE3C",["smirk_cat"]],"1f63d":["\uD83D\uDE3D",["kissing_cat"]],"1f63e":["\uD83D\uDE3E",["pouting_cat"]],"1f63f":["\uD83D\uDE3F",["crying_cat_face"]],"1f640":["\uD83D\uDE40",["scream_cat"]],"1f645":["\uD83D\uDE45",["no_good"]],"1f646":["\uD83D\uDE46",["ok_woman"]],"1f647":["\uD83D\uDE47",["bow"]],"1f648":["\uD83D\uDE48",["see_no_evil"]],"1f649":["\uD83D\uDE49",["hear_no_evil"]],"1f64a":["\uD83D\uDE4A",["speak_no_evil"]],"1f64b":["\uD83D\uDE4B",["raising_hand"]],"1f64c":["\uD83D\uDE4C",["raised_hands"]],"1f64d":["\uD83D\uDE4D",["person_frowning"]],"1f64e":["\uD83D\uDE4E",["person_with_pouting_face"]],"1f64f":["\uD83D\uDE4F",["pray"]],"1f680":["\uD83D\uDE80",["rocket"]],"1f681":["\uD83D\uDE81",["helicopter"]],"1f682":["\uD83D\uDE82",["steam_locomotive"]],"1f683":["\uD83D\uDE83",["railway_car","train"]],"1f684":["\uD83D\uDE84",["bullettrain_side"]],"1f685":["\uD83D\uDE85",["bullettrain_front"]],"1f686":["\uD83D\uDE86",["train2"]],"1f687":["\uD83D\uDE87",["metro"]],"1f688":["\uD83D\uDE88",["light_rail"]],"1f689":["\uD83D\uDE89",["station"]],"1f68a":["\uD83D\uDE8A",["tram"]],"1f68c":["\uD83D\uDE8C",["bus"]],"1f68d":["\uD83D\uDE8D",["oncoming_bus"]],"1f68e":["\uD83D\uDE8E",["trolleybus"]],"1f68f":["\uD83D\uDE8F",["busstop"]],"1f690":["\uD83D\uDE90",["minibus"]],"1f691":["\uD83D\uDE91",["ambulance"]],"1f692":["\uD83D\uDE92",["fire_engine"]],"1f693":["\uD83D\uDE93",["police_car"]],"1f694":["\uD83D\uDE94",["oncoming_police_car"]],"1f695":["\uD83D\uDE95",["taxi"]],"1f696":["\uD83D\uDE96",["oncoming_taxi"]],"1f697":["\uD83D\uDE97",["car","red_car"]],"1f698":["\uD83D\uDE98",["oncoming_automobile"]],"1f699":["\uD83D\uDE99",["blue_car"]],"1f69a":["\uD83D\uDE9A",["truck"]],"1f69b":["\uD83D\uDE9B",["articulated_lorry"]],"1f69c":["\uD83D\uDE9C",["tractor"]],"1f69d":["\uD83D\uDE9D",["monorail"]],"1f69e":["\uD83D\uDE9E",["mountain_railway"]],"1f69f":["\uD83D\uDE9F",["suspension_railway"]],"1f6a0":["\uD83D\uDEA0",["mountain_cableway"]],"1f6a1":["\uD83D\uDEA1",["aerial_tramway"]],"1f6a2":["\uD83D\uDEA2",["ship"]],"1f6a3":["\uD83D\uDEA3",["rowboat"]],"1f6a4":["\uD83D\uDEA4",["speedboat"]],"1f6a5":["\uD83D\uDEA5",["traffic_light"]],"1f6a6":["\uD83D\uDEA6",["vertical_traffic_light"]],"1f6a7":["\uD83D\uDEA7",["construction"]],"1f6a8":["\uD83D\uDEA8",["rotating_light"]],"1f6a9":["\uD83D\uDEA9",["triangular_flag_on_post"]],"1f6aa":["\uD83D\uDEAA",["door"]],"1f6ab":["\uD83D\uDEAB",["no_entry_sign"]],"1f6ac":["\uD83D\uDEAC",["smoking"]],"1f6ad":["\uD83D\uDEAD",["no_smoking"]],"1f6ae":["\uD83D\uDEAE",["put_litter_in_its_place"]],"1f6af":["\uD83D\uDEAF",["do_not_litter"]],"1f6b0":["\uD83D\uDEB0",["potable_water"]],"1f6b1":["\uD83D\uDEB1",["non-potable_water"]],"1f6b2":["\uD83D\uDEB2",["bike"]],"1f6b3":["\uD83D\uDEB3",["no_bicycles"]],"1f6b4":["\uD83D\uDEB4",["bicyclist"]],"1f6b5":["\uD83D\uDEB5",["mountain_bicyclist"]],"1f6b6":["\uD83D\uDEB6",["walking"]],"1f6b7":["\uD83D\uDEB7",["no_pedestrians"]],"1f6b8":["\uD83D\uDEB8",["children_crossing"]],"1f6b9":["\uD83D\uDEB9",["mens"]],"1f6ba":["\uD83D\uDEBA",["womens"]],"1f6bb":["\uD83D\uDEBB",["restroom"]],"1f6bc":["\uD83D\uDEBC",["baby_symbol"]],"1f6bd":["\uD83D\uDEBD",["toilet"]],"1f6be":["\uD83D\uDEBE",["wc"]],"1f6bf":["\uD83D\uDEBF",["shower"]],"1f6c0":["\uD83D\uDEC0",["bath"]],"1f6c1":["\uD83D\uDEC1",["bathtub"]],"1f6c2":["\uD83D\uDEC2",["passport_control"]],"1f6c3":["\uD83D\uDEC3",["customs"]],"1f6c4":["\uD83D\uDEC4",["baggage_claim"]],"1f6c5":["\uD83D\uDEC5",["left_luggage"]],"0023":["\u0023\u20E3",["hash"]],"0030":["\u0030\u20E3",["zero"]],"0031":["\u0031\u20E3",["one"]],"0032":["\u0032\u20E3",["two"]],"0033":["\u0033\u20E3",["three"]],"0034":["\u0034\u20E3",["four"]],"0035":["\u0035\u20E3",["five"]],"0036":["\u0036\u20E3",["six"]],"0037":["\u0037\u20E3",["seven"]],"0038":["\u0038\u20E3",["eight"]],"0039":["\u0039\u20E3",["nine"]],"1f1e8-1f1f3":["\uD83C\uDDE8\uD83C\uDDF3",["cn"]],"1f1e9-1f1ea":["\uD83C\uDDE9\uD83C\uDDEA",["de"]],"1f1ea-1f1f8":["\uD83C\uDDEA\uD83C\uDDF8",["es"]],"1f1eb-1f1f7":["\uD83C\uDDEB\uD83C\uDDF7",["fr"]],"1f1ec-1f1e7":["\uD83C\uDDEC\uD83C\uDDE7",["gb","uk"]],"1f1ee-1f1f9":["\uD83C\uDDEE\uD83C\uDDF9",["it"]],"1f1ef-1f1f5":["\uD83C\uDDEF\uD83C\uDDF5",["jp"]],"1f1f0-1f1f7":["\uD83C\uDDF0\uD83C\uDDF7",["kr"]],"1f1f7-1f1fa":["\uD83C\uDDF7\uD83C\uDDFA",["ru"]],"1f1fa-1f1f8":["\uD83C\uDDFA\uD83C\uDDF8",["us"]]} diff --git a/js/lib/mtproto.js b/js/lib/mtproto.js new file mode 100644 index 00000000..8d236540 --- /dev/null +++ b/js/lib/mtproto.js @@ -0,0 +1,2612 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +var _logTimer = (new Date()).getTime(); +function dLog () { + try { + var t = '[' + (((new Date()).getTime() - _logTimer) / 1000).toFixed(3) + '] '; + if (window.console && console.log) { + var args = Array.prototype.slice.call(arguments); + args.unshift(t); + console.log.apply(console, args); + } + } catch (e) {} + + return true; +} + +function bigint (num) { + return new BigInteger(num.toString(16), 16); +} + +function dHexDump (bytes) { + var arr = []; + for (var i = 0; i < bytes.length; i++) { + if (i && !(i % 2)) { + if (!(i % 16)) { + arr.push("\n"); + } else if (!(i % 4)) { + arr.push(' '); + } else { + arr.push(' '); + } + } + arr.push((bytes[i] < 16 ? '0' : '') + bytes[i].toString(16)); + } + + console.log(arr.join('')); +} + +function bytesToHex (bytes) { + var arr = []; + for (var i = 0; i < bytes.length; i++) { + arr.push((bytes[i] < 16 ? '0' : '') + bytes[i].toString(16)); + } + return arr.join(''); +} + +function bytesFromHex (hexString) { + var len = hexString.length, + i, + bytes = []; + + for (i = 0; i < len; i += 2) { + bytes.push(parseInt(hexString.substr(i, 2), 16)); + } + + return bytes; +} + +function bytesCmp (bytes1, bytes2) { + var len = bytes1.length; + if (len != bytes2.length) { + return false; + } + + for (var i = 0; i < len; i++) { + if (bytes1[i] != bytes2[i]) { + return false; + } + } + return true; +} + +function bytesXor (bytes1, bytes2) { + var len = bytes1.length, + bytes = []; + + for (var i = 0; i < len; ++i) { + bytes[i] = bytes1[i] ^ bytes2[i]; + } + + return bytes; +} + +function bytesToWords (bytes) { + var len = bytes.length, + words = []; + + for (var i = 0; i < len; i++) { + words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8); + } + + return new CryptoJS.lib.WordArray.init(words, len); +} + +function bytesFromWords (wordArray) { + var words = wordArray.words, + sigBytes = wordArray.sigBytes, + bytes = []; + + for (var i = 0; i < sigBytes; i++) { + bytes.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff); + } + + return bytes; +} + +function bytesFromBigInt (bigInt, len) { + var bytes = bigInt.toByteArray(); + + while (!bytes[0] && (!len || bytes.length > len)) { + bytes = bytes.slice(1); + } + + return bytes; +} + +function bytesToArrayBuffer (b) { + var len = b.length, + array = new Uint8Array(len); + + for (var i = 0; i < len; ++i) { + array[i] = b[i]; + } + + return array.buffer; +} + +function bytesFromArrayBuffer (buffer) { + var len = buffer.byteLength, + byteView = new Uint8Array(buffer), + bytes = []; + + for (var i = 0; i < len; ++i) { + bytes[i] = byteView[i]; + } + + return bytes; +} + +function longToInts (sLong) { + var divRem = new BigInteger(sLong, 10).divideAndRemainder(bigint(0x100000000)); + + return [divRem[0].intValue(), divRem[1].intValue()]; +} + +function longToBytes (sLong) { + return bytesFromWords({words: longToInts(sLong), sigBytes: 8}).reverse(); +} + +function longFromInts (high, low) { + return bigint(high).shiftLeft(32).add(bigint(low)).toString(10); +} + +function intToUint (val) { + val = parseInt(val); + if (val < 0) { + val = val + 4294967296; + } + return val; +} + +function uintToInt (val) { + if (val > 2147483647) { + val = val - 4294967296; + } + return val; +} + +function sha1Hash (bytes) { + // dLog('SHA-1 hash start'); + var hashBytes = sha1.hash(bytes, true); + // dLog('SHA-1 hash finish'); + + return hashBytes; +} + + + +function rsaEncrypt (publicKey, bytes) { + var needPadding = 255 - bytes.length; + if (needPadding > 0) { + var padding = new Array(needPadding); + (new SecureRandom()).nextBytes(padding); + + bytes = bytes.concat(padding); + } + + // dLog('RSA encrypt start'); + var N = new BigInteger(publicKey.modulus, 16), + E = new BigInteger(publicKey.exponent, 16), + X = new BigInteger(bytes), + encryptedBigInt = X.modPowInt(E, N), + encryptedBytes = bytesFromBigInt(encryptedBigInt, 256); + + // dLog('RSA encrypt finish'); + + return encryptedBytes; +} + +function aesEncrypt (bytes, keyBytes, ivBytes) { + // dLog('AES encrypt start', bytes.length/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/); + + var needPadding = 16 - (bytes.length % 16); + if (needPadding > 0 && needPadding < 16) { + var padding = new Array(needPadding); + (new SecureRandom()).nextBytes(padding); + + bytes = bytes.concat(padding); + } + + var encryptedWords = CryptoJS.AES.encrypt(bytesToWords(bytes), bytesToWords(keyBytes), { + iv: bytesToWords(ivBytes), + padding: CryptoJS.pad.NoPadding, + mode: CryptoJS.mode.IGE + }).ciphertext; + + var encryptedBytes = bytesFromWords(encryptedWords); + + // dLog('AES encrypt finish'); + + return encryptedBytes; +} + +function aesDecrypt (encryptedBytes, keyBytes, ivBytes) { + dLog('AES decrypt start', encryptedBytes.length/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/); + + var decryptedWords = CryptoJS.AES.decrypt({ciphertext: bytesToWords(encryptedBytes)}, bytesToWords(keyBytes), { + iv: bytesToWords(ivBytes), + padding: CryptoJS.pad.NoPadding, + mode: CryptoJS.mode.IGE + }); + + var bytes = bytesFromWords(decryptedWords); + + dLog('AES decrypt finish'); + + return bytes; +} + +function gzipUncompress (bytes) { + // dLog('Gzip uncompress start'); + var result = (new Zlib.Gunzip(bytes)).decompress(); + // dLog('Gzip uncompress finish'); + return result; +} + +function nextRandomInt (maxValue) { + return Math.floor(Math.random() * maxValue); +}; + +function pqPrimeFactorization (pqBytes) { + dLog('PQ start'); + + var what = new BigInteger(pqBytes), + g; + + var it = 0; + for (var i = 0; i < 3; i++) { + var q = (nextRandomInt(128) & 15) + 17, + x = bigint(nextRandomInt(1000000000) + 1), + y = x.clone(), + lim = 1 << (i + 18); + + for (var j = 1; j < lim; j++) { + ++it; + var a = x.clone(), + b = x.clone(), + c = bigint(q); + + while (!b.equals(BigInteger.ZERO)) { + if (!b.and(BigInteger.ONE).equals(BigInteger.ZERO)) { + c = c.add(a); + if (c.compareTo(what) > 0) { + c = c.subtract(what); + } + } + a = a.add(a); + if (a.compareTo(what) > 0) { + a = a.subtract(what); + } + b = b.shiftRight(1); + } + + x = c.clone(); + var z = x.compareTo(y) < 0 ? y.subtract(x) : x.subtract(y); + g = z.gcd(what); + if (!g.equals(BigInteger.ONE)) { + break; + } + if ((j & (j - 1)) == 0) { + y = x.clone(); + } + } + if (g.compareTo(BigInteger.ONE) > 0) { + break; + } + } + + var f = what.divide(g), P, Q; + + if (g.compareTo(f) > 0) { + P = f; + Q = g; + } else { + P = g; + Q = f; + } + + dLog('PQ finish', it + ' iterations'); + + return [bytesFromBigInt(P), bytesFromBigInt(Q)]; +} + + +function TLSerialization (options) { + options = options || {}; + this.maxLength = options.startMaxLength || 2048; // 2Kb + this.offset = 0; // in bytes + + this.createBuffer(); + + // this.debug = options.debug !== undefined ? options.debug : true; + this.mtproto = options.mtproto || false; + return this; +} + +TLSerialization.prototype.createBuffer = function () { + this.buffer = new ArrayBuffer(this.maxLength); + this.intView = new Int32Array(this.buffer); + this.byteView = new Uint8Array(this.buffer); +}; + +TLSerialization.prototype.getArray = function () { + var resultBuffer = new ArrayBuffer(this.offset); + var resultArray = new Int32Array(resultBuffer); + + resultArray.set(this.intView.subarray(0, this.offset / 4)); + + return resultArray; +}; + +TLSerialization.prototype.getBuffer = function () { + return this.getArray().buffer; +}; + +TLSerialization.prototype.getBytes = function () { + var bytes = []; + for (var i = 0; i < this.offset; i++) { + bytes.push(this.byteView[i]); + } + return bytes; +}; + +TLSerialization.prototype.checkLength = function (needBytes) { + if (this.offset + needBytes < this.maxLength) { + return; + } + + dLog('Increase buffer', this.offset, needBytes, this.maxLength); + console.trace(); + this.maxLength = Math.max(this.maxLength * 2, this.offset + needBytes + 16); + var previousBuffer = this.buffer, + previousArray = new Int32Array(previousBuffer); + + this.createBuffer(); + + new Int32Array(this.buffer).set(previousArray); +}; + +TLSerialization.prototype.writeInt = function (i, field) { + this.debug && dLog('>>>', i.toString(16), i, field); + + this.checkLength(4); + this.intView[this.offset / 4] = i; + this.offset += 4; +}; + +TLSerialization.prototype.storeInt = function (i, field) { + this.writeInt(i, (field || '') + ':int'); +}; + +TLSerialization.prototype.storeBool = function (i, field) { + if (i) { + this.writeInt(0x997275b5, (field || '') + ':bool'); + } else { + this.writeInt(0xbc799737, (field || '') + ':bool'); + } +}; + +TLSerialization.prototype.storeLongP = function (iHigh, iLow, field) { + this.writeInt(iLow, (field || '') + ':long[low]'); + this.writeInt(iHigh, (field || '') + ':long[high]'); +}; + +TLSerialization.prototype.storeLong = function (sLong, field) { + if (angular.isArray(sLong)) { + if (sLong.length == 2) { + return this.storeLongP(sLong[0], sLong[1], field); + } else { + return this.storeIntBytes(sLong, 64, field); + } + } + + var divRem = new BigInteger(sLong, 10).divideAndRemainder(bigint(0x100000000)); + + this.writeInt(intToUint(divRem[1].intValue()), (field || '') + ':long[low]'); + this.writeInt(intToUint(divRem[0].intValue()), (field || '') + ':long[high]'); +}; + +TLSerialization.prototype.storeDouble = function (f) { + var buffer = new ArrayBuffer(8); + var intView = new Int32Array(buffer); + var doubleView = new Float64Array(buffer); + + doubleView[0] = f; + + this.writeInt(intView[0], (field || '') + ':double[low]'); + this.writeInt(intView[1], (field || '') + ':double[high]'); +}; + +TLSerialization.prototype.storeString = function (s, field) { + this.debug && dLog('>>>', s, (field || '') + ':string'); + + var sUTF8 = unescape(encodeURIComponent(s)); + + this.checkLength(sUTF8.length + 8); + + + var len = sUTF8.length; + if (len <= 253) { + this.byteView[this.offset++] = len; + } else { + this.byteView[this.offset++] = 254; + this.byteView[this.offset++] = len & 0xFF; + this.byteView[this.offset++] = (len & 0xFF00) >> 8; + this.byteView[this.offset++] = (len & 0xFF0000) >> 16; + } + for (var i = 0; i < len; i++) { + this.byteView[this.offset++] = sUTF8.charCodeAt(i); + } + + // Padding + while (this.offset % 4) { + this.byteView[this.offset++] = 0; + } +} + + +TLSerialization.prototype.storeBytes = function (bytes, field) { + this.debug && dLog('>>>', bytesToHex(bytes), (field || '') + ':bytes'); + + this.checkLength(bytes.length + 8); + + var len = bytes.length; + if (len <= 253) { + this.byteView[this.offset++] = len; + } else { + this.byteView[this.offset++] = 254; + this.byteView[this.offset++] = len & 0xFF; + this.byteView[this.offset++] = (len & 0xFF00) >> 8; + this.byteView[this.offset++] = (len & 0xFF0000) >> 16; + } + for (var i = 0; i < len; i++) { + this.byteView[this.offset++] = bytes[i]; + } + + // Padding + while (this.offset % 4) { + this.byteView[this.offset++] = 0; + } +} + +TLSerialization.prototype.storeIntBytes = function (bytes, bits, field) { + var len = bytes.length; + if ((bits % 32) || (len * 8) != bits) { + throw new Error('Invalid bits: ' + bits + ', ' + bytes.length); + } + + this.debug && dLog('>>>', bytesToHex(bytes), (field || '') + ':int' + bits); + this.checkLength(len); + + for (var i = 0; i < len; i++) { + this.byteView[this.offset++] = bytes[i]; + } +}; + +TLSerialization.prototype.storeRawBytes = function (bytes, field) { + var len = bytes.length; + + this.debug && dLog('>>>', bytesToHex(bytes), (field || '')); + this.checkLength(len); + + for (var i = 0; i < len; i++) { + this.byteView[this.offset++] = bytes[i]; + } +}; + + +TLSerialization.prototype.storeMethod = function (methodName, params) { + var schema = this.mtproto ? Config.Schema.MTProto : Config.Schema.API, + methodData = false, + i; + + for (i = 0; i < schema.methods.length; i++) { + if (schema.methods[i].method == methodName) { + methodData = schema.methods[i]; + break + } + } + if (!methodData) { + throw new Error('No method ' + methodName + ' found'); + } + + this.storeInt(intToUint(methodData.id), methodName + '[id]'); + + var self = this; + angular.forEach(methodData.params, function (param) { + self.storeObject(params[param.name], param.type, methodName + '[' + param.name + ']'); + }); +}; + +TLSerialization.prototype.storeObject = function (obj, type, field) { + switch (type) { + case 'int': return this.storeInt(obj, field); + case 'long': return this.storeLong(obj, field); + case 'int128': return this.storeIntBytes(obj, 128, field); + case 'int256': return this.storeIntBytes(obj, 256, field); + case 'int512': return this.storeIntBytes(obj, 512, field); + case 'string': return this.storeString(obj, field); + case 'bytes': return this.storeBytes(obj, field); + case 'double': return this.storeDouble(obj, field); + case 'Bool': return this.storeBool(obj, field); + } + + if (angular.isArray(obj)) { + if (type.substr(0, 6) == 'Vector') { + this.writeInt(0x1cb5c415, field + '[id]'); + } + else if (type.substr(0, 6) != 'vector') { + throw new Error('Invalid vector type ' + type); + } + var itemType = type.substr(7, type.length - 8); // for "Vector" + this.writeInt(obj.length, field + '[count]'); + for (var i = 0; i < obj.length; i++) { + this.storeObject(obj[i], itemType, field + '[' + i + ']'); + } + return true; + } + else if (type.substr(0, 6).toLowerCase() == 'vector') { + throw new Error('Invalid vector object'); + } + + if (!angular.isObject(obj)) { + throw new Error('Invalid object for type ' + type); + } + + var schema = this.mtproto ? Config.Schema.MTProto : Config.Schema.API, + predicate = obj['_'], + isBare = false, + constructorData = false, + i; + + if (isBare = (type.charAt(0) == '%')) { + type = type.substr(1); + } + + for (i = 0; i < schema.constructors.length; i++) { + if (schema.constructors[i].predicate == predicate) { + constructorData = schema.constructors[i]; + break + } + } + if (!constructorData) { + throw new Error('No predicate ' + predicate + ' found'); + } + + if (predicate == type) { + isBare = true; + } + + if (!isBare) { + this.writeInt(intToUint(constructorData.id), field + '[' + predicate + '][id]'); + } + + var self = this; + angular.forEach(constructorData.params, function (param) { + self.storeObject(obj[param.name], param.type, field + '[' + predicate + '][' + param.name + ']'); + }); +}; + + + +function TLDeserialization (buffer, options) { + options = options || {}; + + this.offset = 0; // in bytes + + this.buffer = buffer; + this.intView = new Uint32Array(this.buffer); + this.byteView = new Uint8Array(this.buffer); + + // this.debug = options.debug !== undefined ? options.debug : true; + this.mtproto = options.mtproto || false; + return this; +} + +TLDeserialization.prototype.readInt = function (field) { + if (this.offset >= this.intView.length * 4) { + throw new Error('Nothing to fetch'); + } + + var i = this.intView[this.offset / 4]; + + this.debug && dLog('<<<', i.toString(16), i, field); + + this.offset += 4; + + return i; +}; + +TLDeserialization.prototype.fetchInt = function (field) { + return this.readInt((field || '') + ':int'); +} + +TLDeserialization.prototype.fetchDouble = function (field) { + var buffer = new ArrayBuffer(8); + var intView = new Int32Array(buffer); + var doubleView = new Float64Array(buffer); + + intView[0] = this.readInt((field || '') + ':double[low]'), + intView[1] = this.readInt((field || '') + ':double[high]'); + + return doubleView[0]; +}; + +TLDeserialization.prototype.fetchLong = function (field) { + var iLow = this.readInt((field || '') + ':long[low]'), + iHigh = this.readInt((field || '') + ':long[high]'); + + var longDec = bigint(iHigh).shiftLeft(32).add(bigint(iLow)).toString(); + + return longDec; +} + +TLDeserialization.prototype.fetchBool = function (field) { + var i = this.readInt((field || '') + ':bool'); + if (i == 0x997275b5) { + return true; + } else if (i == 0xbc799737) { + return false + } + throw new Error('Unknown Bool constructor ' + i); +} + +TLDeserialization.prototype.fetchString = function (field) { + var len = this.byteView[this.offset++]; + + if (len == 254) { + var len = this.byteView[this.offset++] | + (this.byteView[this.offset++] << 8) | + (this.byteView[this.offset++] << 16); + } + + var sUTF8 = ''; + for (var i = 0; i < len; i++) { + sUTF8 += String.fromCharCode(this.byteView[this.offset++]); + } + + // Padding + while (this.offset % 4) { + this.offset++; + } + + try { + var s = decodeURIComponent(escape(sUTF8)); + } catch (e) { + var s = sUTF8; + } + + this.debug && dLog('<<<', s, (field || '') + ':string'); + + return s; +} + + +TLDeserialization.prototype.fetchBytes = function (field) { + var len = this.byteView[this.offset++]; + + if (len == 254) { + var len = this.byteView[this.offset++] | + (this.byteView[this.offset++] << 8) | + (this.byteView[this.offset++] << 16); + } + + var bytes = []; + for (var i = 0; i < len; i++) { + bytes.push(this.byteView[this.offset++]); + } + + // Padding + while (this.offset % 4) { + this.offset++; + } + + this.debug && dLog('<<<', bytesToHex(bytes), (field || '') + ':bytes'); + + return bytes; +} + +TLDeserialization.prototype.fetchIntBytes = function (bits, field) { + if (bits % 32) { + throw new Error('Invalid bits: ' + bits); + } + + var len = bits / 8; + var bytes = []; + for (var i = 0; i < len; i++) { + bytes.push(this.byteView[this.offset++]); + } + + this.debug && dLog('<<<', bytesToHex(bytes), (field || '') + ':int' + bits); + + return bytes; +}; + + +TLDeserialization.prototype.fetchRawBytes = function (len, field) { + if (len === false) { + len = this.readInt((field || '') + '_length'); + } + + var bytes = []; + for (var i = 0; i < len; i++) { + bytes.push(this.byteView[this.offset++]); + } + + this.debug && dLog('<<<', bytesToHex(bytes), (field || '')); + + return bytes; +}; + +TLDeserialization.prototype.fetchObject = function (type, field) { + switch (type) { + case 'int': return this.fetchInt(field); + case 'long': return this.fetchLong(field); + case 'int128': return this.fetchIntBytes(128, field); + case 'int256': return this.fetchIntBytes(256, field); + case 'int512': return this.fetchIntBytes(512, field); + case 'string': return this.fetchString(field); + case 'bytes': return this.fetchBytes(field); + case 'double': return this.fetchDouble(field); + case 'Bool': return this.fetchBool(field); + } + + field = field || type || 'Object'; + + if (type.substr(0, 6) == 'Vector' || type.substr(0, 6) == 'vector') { + if (type.charAt(0) == 'V') { + var constructor = this.readInt(field + '[id]'); + if (constructor != 0x1cb5c415) { + throw new Error('Invalid vector constructor ' + constructor); + } + } + var len = this.readInt(field + '[count]'); + var result = []; + if (len > 0) { + var itemType = type.substr(7, type.length - 8); // for "Vector" + for (var i = 0; i < len; i++) { + result.push(this.fetchObject(itemType, field + '[' + i + ']')) + } + } + + return result; + } + + var schema = this.mtproto ? Config.Schema.MTProto : Config.Schema.API, + predicate = false, + constructorData = false; + + if (type.charAt(0) == '%') { + var checkType = type.substr(1); + for (i = 0; i < schema.constructors.length; i++) { + if (schema.constructors[i].type == checkType) { + constructorData = schema.constructors[i]; + break + } + } + if (!constructorData) { + throw new Error('Constructor not found for type: ' + type); + } + } + else if (type.charAt(0) >= 97 && type.charAt(0) <= 122) { + for (i = 0; i < schema.constructors.length; i++) { + if (schema.constructors[i].predicate == type) { + constructorData = schema.constructors[i]; + break + } + } + if (!constructorData) { + throw new Error('Constructor not found for predicate: ' + type); + } + } + else { + var constructor = this.readInt(field + '[id]'), + constructorCmp = uintToInt(constructor); + + if (constructorCmp == 0x3072cfa1) { // Gzip packed + var compressed = this.fetchBytes(field + '[packed_string]'), + uncompressed = gzipUncompress(compressed), + buffer = bytesToArrayBuffer(uncompressed), + newDeserializer = (new TLDeserialization(buffer)); + + return newDeserializer.fetchObject(type, field); + } + + for (i = 0; i < schema.constructors.length; i++) { + if (schema.constructors[i].id == constructorCmp) { + constructorData = schema.constructors[i]; + break; + } + } + + var fallback = false; + if (!constructorData && this.mtproto) { + var schemaFallback = Config.Schema.API; + for (i = 0; i < schemaFallback.constructors.length; i++) { + if (schemaFallback.constructors[i].id == constructorCmp) { + constructorData = schemaFallback.constructors[i]; + + delete this.mtproto; + fallback = true; + break; + } + } + } + if (!constructorData) { + throw new Error('Constructor not found: ' + constructor); + } + } + + predicate = constructorData.predicate; + + var result = {'_': predicate}; + + var self = this; + angular.forEach(constructorData.params, function (param) { + result[param.name] = self.fetchObject(param.type, field + '[' + predicate + '][' + param.name + ']'); + }); + + if (fallback) { + this.mtproto = true; + } + + return result; +}; + +TLDeserialization.prototype.getOffset = function () { + return this.offset; +}; + +TLDeserialization.prototype.fetchEnd = function () { + if (this.offset != this.byteView.length) { + throw new Error('Fetch end with non-empty buffer'); + } + return true; +}; + +if (typeof angular != 'undefined') angular.module('mtproto.services', ['myApp.services']). + +factory('MtpDcConfigurator', function () { + var dcOptions = window._testMode + ? [ + {id: 1, host: '173.240.5.253', port: 80}, + {id: 2, host: '95.142.192.65', port: 80}, + {id: 3, host: '174.140.142.5', port: 80} + ] + : [ + {id: 1, host: '173.240.5.1', port: 80}, + {id: 2, host: '95.142.192.66', port: 80}, + {id: 3, host: '174.140.142.6', port: 80}, + {id: 4, host: '31.210.235.12', port: 80}, + {id: 5, host: '116.51.22.2', port: 80}, + ]; + + var chosenServers = {}; + + function chooseServer(dcID) { + if (chosenServers[dcID] === undefined) { + var chosenServer = false, + i, dcOption; + for (i = 0; i < dcOptions.length; i++) { + dcOption = dcOptions[i]; + if (dcOption.id == dcID) { + chosenServer = dcOption.host + ':' + dcOption.port; + } + } + chosenServers[dcID] = chosenServer; + } + + return chosenServers[dcID]; + } + + return { + chooseServer: chooseServer + }; +}). + +factory('MtpRsaKeysManager', function () { + +/** +* Server public key, obtained from here: https://core.telegram.org/api/obtaining_api_id +* +* -----BEGIN RSA PUBLIC KEY----- +* MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6 +* lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS +* an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw +* Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+ +* 8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n +* Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB +* -----END RSA PUBLIC KEY----- +*/ + + var publisKeysHex = [{ + modulus: 'c150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135a6f91f8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e580230e3ae97d95c8b19442b3c0a10d8f5633fecedd6926a7f6dab0ddb7d457f9ea81b8465fcd6fffeed114011df91c059caedaf97625f6c96ecc74725556934ef781d866b34f011fce4d835a090196e9a5f0e4449af7eb697ddb9076494ca5f81104a305b6dd27665722c46b60e5df680fb16b210607ef217652e60236c255f6a28315f4083a96791d7214bf64c1df4fd0db1944fb26a2a57031b32eee64ad15a8ba68885cde74a5bfc920f6abf59ba5c75506373e7130f9042da922179251f', + exponent: '010001' + }]; + + var publicKeysParsed = {}; + var prepared = false; + + function prepareRsaKeys () { + if (prepared) { + return; + } + + for (var i = 0; i < publisKeysHex.length; i++) { + var keyParsed = publisKeysHex[i]; + + var RSAPublicKey = new TLSerialization(); + RSAPublicKey.storeBytes(bytesFromHex(keyParsed.modulus), 'n'); + RSAPublicKey.storeBytes(bytesFromHex(keyParsed.exponent), 'e'); + + var buffer = RSAPublicKey.getBuffer(); + + var fingerprintBytes = sha1Hash(buffer).slice(-8); + fingerprintBytes.reverse(); + + var fingerprint = new BigInteger(fingerprintBytes).toString(16); + + publicKeysParsed[fingerprint] = { + modulus: keyParsed.modulus, + exponent: keyParsed.exponent + }; + } + + prepared = true; + }; + + function selectRsaKeyByFingerPrint (fingerprints) { + prepareRsaKeys(); + + var fingerprintHex, foundKey, i; + for (i = 0; i < fingerprints.length; i++) { + fingerprintHex = new BigInteger(fingerprints[i], 10).toString(16); + if (foundKey = publicKeysParsed[fingerprintHex]) { + return angular.extend({fingerprint: fingerprints[i]}, foundKey); + } + } + + return false; + }; + + return { + prepare: prepareRsaKeys, + select: selectRsaKeyByFingerPrint + }; +}). + +service('MtpSecureRandom', SecureRandom). + +factory('MtpMessageIdGenerator', function (AppConfigManager) { + var lastMessageID = [0, 0], + timeOffset = 0; + + AppConfigManager.get('server_time_offset').then(function (to) { + if (to) { + timeOffset = to; + } + }); + + function generateMessageID () { + var timeTicks = +new Date() + timeOffset, + timeSec = Math.floor(timeTicks / 1000), + timeMSec = timeTicks % 1000, + random = nextRandomInt(0xFFFF); + + var messageID = [timeSec, (timeMSec << 21) | (random << 3) | 4]; + if (lastMessageID[0] > messageID[0] || + lastMessageID[0] == messageID[0] && lastMessageID[1] >= messageID[1]) { + + messageID = [lastMessageID[0], lastMessageID[1] + 4]; + } + + lastMessageID = messageID; + + // dLog('generated msg id', messageID); + + return longFromInts(messageID[0], messageID[1]); + }; + + function applyServerTime (serverTime, localTime) { + timeOffset = serverTime - Math.floor((localTime || +new Date()) / 1000); + AppConfigManager.set({server_time_offset: timeOffset}); + }; + + return { + generateID: generateMessageID, + applyServerTime: applyServerTime + }; +}). + +factory('MtpAuthorizer', function (MtpDcConfigurator, MtpRsaKeysManager, MtpSecureRandom, MtpMessageIdGenerator, $http, $q, $timeout) { + + function mtpSendPlainRequest (dcID, requestBuffer) { + var requestLength = requestBuffer.byteLength, + requestArray = new Int32Array(requestBuffer); + + var header = new TLSerialization(); + header.storeLongP(0, 0, 'auth_key_id'); // Auth key + header.storeLong(MtpMessageIdGenerator.generateID(), 'msg_id'); // Msg_id + header.storeInt(requestLength, 'request_length'); + + var headerBuffer = header.getBuffer(), + headerArray = new Int32Array(headerBuffer), + headerLength = headerBuffer.byteLength; + + var resultBuffer = new ArrayBuffer(headerLength + requestLength), + resultArray = new Int32Array(resultBuffer); + + resultArray.set(headerArray); + resultArray.set(requestArray, headerArray.length); + + delete $http.defaults.headers.post['Content-Type']; + delete $http.defaults.headers.common['Accept']; + + return $http.post('http://' + MtpDcConfigurator.chooseServer(dcID) + '/apiw1', resultArray, { + responseType: 'arraybuffer', + transformRequest: null, + transformResponse: function (responseBuffer) { + var deserializer = new TLDeserialization(responseBuffer, {mtproto: true}); + + var auth_key_id = deserializer.fetchLong('auth_key_id'); + var msg_id = deserializer.fetchLong('msg_id'); + var msg_len = deserializer.fetchInt('msg_len'); + + rng_seed_time(); + + return deserializer; + } + }); + }; + + function mtpSendReqPQ (auth) { + var deferred = auth.deferred; + + var request = new TLSerialization({mtproto: true}); + + request.storeMethod('req_pq', {nonce: auth.nonce}); + + mtpSendPlainRequest(auth.dcID, request.getBuffer()).then(function (result) { + var deserializer = result.data; + var response = deserializer.fetchObject('ResPQ'); + + if (response._ != 'resPQ') { + throw new Error('resPQ response invalid: ' + response._); + } + + if (!bytesCmp (auth.nonce, response.nonce)) { + throw new Error('resPQ nonce mismatch'); + } + + auth.serverNonce = response.server_nonce; + auth.pq = response.pq; + auth.fingerprints = response.server_public_key_fingerprints; + + dLog('ResPQ', bytesToHex(auth.serverNonce), bytesToHex(auth.pq), auth.fingerprints); + + auth.publicKey = MtpRsaKeysManager.select(auth.fingerprints); + + if (!auth.publicKey) { + throw new Error('No public key found'); + } + + if (!!window.Worker) { + var worker = new Worker('js/lib/pq_worker.js'); + + worker.onmessage = function (e) { + auth.p = e.data[0]; + auth.q = e.data[1]; + mtpSendReqDhParams(auth); + }; + worker.onerror = function(error) { + dLog('Worker error', error); + deferred.reject(error); + }; + worker.postMessage(auth.pq) + } else { + var pAndQ = pqPrimeFactorization(auth.pq); + auth.p = pAndQ[0]; + auth.q = pAndQ[1]; + + mtpSendReqDhParams(auth); + } + }, function (error) { + deferred.reject(error); + }); + + $timeout(function () { + MtpRsaKeysManager.prepare(); + }); + }; + + function mtpSendReqDhParams (auth) { + var deferred = auth.deferred; + + auth.newNonce = new Array(32); + MtpSecureRandom.nextBytes(auth.newNonce); + + var data = new TLSerialization({mtproto: true}); + data.storeObject({ + _: 'p_q_inner_data', + pq: auth.pq, + p: auth.p, + q: auth.q, + nonce: auth.nonce, + server_nonce: auth.serverNonce, + new_nonce: auth.newNonce + }, 'P_Q_inner_data', 'DECRYPTED_DATA'); + + var dataWithHash = sha1Hash(data.getBuffer()).concat(data.getBytes()); + + var request = new TLSerialization({mtproto: true}); + request.storeMethod('req_DH_params', { + nonce: auth.nonce, + server_nonce: auth.serverNonce, + p: auth.p, + q: auth.q, + public_key_fingerprint: auth.publicKey.fingerprint, + encrypted_data: rsaEncrypt(auth.publicKey, dataWithHash) + }); + + mtpSendPlainRequest(auth.dcID, request.getBuffer()).then(function (result) { + var deserializer = result.data; + var response = deserializer.fetchObject('Server_DH_Params', 'RESPONSE'); + + if (response._ != 'server_DH_params_fail' && response._ != 'server_DH_params_ok') { + deferred.reject(new Error('Server_DH_Params response invalid: ' + response._)); + return false; + } + + if (!bytesCmp (auth.nonce, response.nonce)) { + deferred.reject(new Error('Server_DH_Params nonce mismatch')); + return false; + } + + if (!bytesCmp (auth.serverNonce, response.server_nonce)) { + deferred.reject(new Error('Server_DH_Params server_nonce mismatch')); + return false; + } + + if (response._ == 'server_DH_params_fail') { + var newNonceHash = sha1Hash(auth.newNonce).slice(-16) + if (!bytesCmp (newNonceHash, response.new_nonce_hash)) { + deferred.reject(new Error('server_DH_params_fail new_nonce_hash mismatch')); + return false; + } + deferred.reject(new Error('server_DH_params_fail')); + return false; + } + + try { + mtpDecryptServerDhDataAnswer(auth, response.encrypted_answer); + } catch (e) { + deferred.reject(e); + return false; + } + + mtpSendSetClientDhParams(auth); + }, function (error) { + deferred.reject(error); + }); + }; + + function mtpDecryptServerDhDataAnswer (auth, encryptedAnswer) { + auth.localTime = +new Date(); + + auth.tmpAesKey = sha1Hash(auth.newNonce.concat(auth.serverNonce)).concat(sha1Hash(auth.serverNonce.concat(auth.newNonce)).slice(0, 12)); + auth.tmpAesIv = sha1Hash(auth.serverNonce.concat(auth.newNonce)).slice(12).concat(sha1Hash([].concat(auth.newNonce, auth.newNonce)), auth.newNonce.slice(0, 4)); + + var answerWithHash = aesDecrypt(encryptedAnswer, auth.tmpAesKey, auth.tmpAesIv); + + var hash = answerWithHash.slice(0, 20); + var answerWithPadding = answerWithHash.slice(20); + var buffer = bytesToArrayBuffer(answerWithPadding); + + var deserializer = new TLDeserialization(buffer, {mtproto: true}); + var response = deserializer.fetchObject('Server_DH_inner_data'); + + if (response._ != 'server_DH_inner_data') { + throw new Error('server_DH_inner_data response invalid: ' + constructor); + } + + if (!bytesCmp (auth.nonce, response.nonce)) { + throw new Error('server_DH_inner_data nonce mismatch'); + } + + if (!bytesCmp (auth.serverNonce, response.server_nonce)) { + throw new Error('server_DH_inner_data serverNonce mismatch'); + } + + auth.g = response.g; + auth.dhPrime = response.dh_prime; + auth.gA = response.g_a; + auth.serverTime = response.server_time; + auth.retry = 0; + + var offset = deserializer.getOffset(); + + if (!bytesCmp(hash, sha1Hash(answerWithPadding.slice(0, offset)))) { + throw new Error('server_DH_inner_data SHA1-hash mismatch'); + } + + MtpMessageIdGenerator.applyServerTime(auth.serverTime, auth.localTime); + }; + + function mtpSendSetClientDhParams(auth) { + var deferred = auth.deferred; + + auth.b = new Array(256); + MtpSecureRandom.nextBytes(auth.b); + + var bBigInt = new BigInteger(auth.b); + var dhPrimeBigInt = new BigInteger(auth.dhPrime); + + var gB = bytesFromBigInt(bigint(auth.g).modPow(bBigInt, dhPrimeBigInt)); + + var data = new TLSerialization({mtproto: true}); + data.storeObject({ + _: 'client_DH_inner_data', + nonce: auth.nonce, + server_nonce: auth.serverNonce, + retry_id: [0, auth.retry++], + g_b: gB, + }, 'Client_DH_Inner_Data'); + + var dataWithHash = sha1Hash(data.getBuffer()).concat(data.getBytes()); + + var encryptedData = aesEncrypt(dataWithHash, auth.tmpAesKey, auth.tmpAesIv); + + var request = new TLSerialization({mtproto: true}); + request.storeMethod('set_client_DH_params', { + nonce: auth.nonce, + server_nonce: auth.serverNonce, + encrypted_data: encryptedData + }); + + mtpSendPlainRequest(auth.dcID, request.getBuffer()).then(function (result) { + var deserializer = result.data; + var response = deserializer.fetchObject('Set_client_DH_params_answer'); + + if (response._ != 'dh_gen_ok' && response._ != 'dh_gen_retry' && response._ != 'dh_gen_fail') { + deferred.reject(new Error('Set_client_DH_params_answer response invalid: ' + response._)); + return false; + } + + if (!bytesCmp (auth.nonce, response.nonce)) { + deferred.reject(new Error('Set_client_DH_params_answer nonce mismatch')); + return false + } + + if (!bytesCmp (auth.serverNonce, response.server_nonce)) { + deferred.reject(new Error('Set_client_DH_params_answer server_nonce mismatch')); + return false; + } + + var bBigInt = new BigInteger(auth.b); + var dhPrimeBigInt = new BigInteger(auth.dhPrime); + + var authKey = bytesFromBigInt((new BigInteger(auth.gA)).modPow(bBigInt, dhPrimeBigInt)), + authKeyHash = sha1Hash(authKey), + authKeyAux = authKeyHash.slice(0, 8), + authKeyID = authKeyHash.slice(-8); + + switch (response._) { + case 'dh_gen_ok': + var newNonceHash1 = sha1Hash(auth.newNonce.concat([1], authKeyAux)).slice(-16); + + if (!bytesCmp(newNonceHash1, response.new_nonce_hash1)) { + deferred.reject(new Error('Set_client_DH_params_answer new_nonce_hash1 mismatch')); + return false; + } + + var serverSalt = bytesXor(auth.newNonce.slice(0, 8), auth.serverNonce.slice(0, 8)); + dLog('Auth successfull!', authKeyID, authKey, serverSalt); + + auth.authKeyID = authKeyID; + auth.authKey = authKey; + auth.serverSalt = serverSalt; + + deferred.resolve(auth); + break; + + case 'dh_gen_retry': + var newNonceHash2 = sha1Hash(auth.newNonce.concat([2], authKeyAux)).slice(-16); + if (!bytesCmp(newNonceHash2, response.new_nonce_hash2)) { + deferred.reject(new Error('Set_client_DH_params_answer new_nonce_hash2 mismatch')); + return false; + } + + return mtpSendSetClientDhParams(auth); + + case 'dh_gen_fail': + var newNonceHash3 = sha1Hash(auth.newNonce.concat([3], authKeyAux)).slice(-16); + if (!bytesCmp(newNonceHash3, response.new_nonce_hash3)) { + deferred.reject(new Error('Set_client_DH_params_answer new_nonce_hash3 mismatch')); + return false; + } + + deferred.reject(new Error('Set_client_DH_params_answer fail')); + return false; + } + + }, function (error) { + deferred.reject(error); + }); + }; + + var cached = {}; + + function mtpAuth (dcID) { + if (cached[dcID] !== undefined) { + return cached[dcID]; + } + + var nonce = []; + for (var i = 0; i < 16; i++) { + nonce.push(nextRandomInt(0xFF)); + } + + if (!MtpDcConfigurator.chooseServer(dcID)) { + return $q.reject(new Error('No server found for dc ' + dcID)); + } + + var auth = { + dcID: dcID, + nonce: nonce, + deferred: $q.defer() + }; + + $timeout(function () { + mtpSendReqPQ(auth); + }); + + return cached[dcID] = auth.deferred.promise; + }; + + return { + auth: mtpAuth + }; + +}). + +factory('MtpAesService', function ($q) { + if (!window.Worker/* || true*/) { + return { + encrypt: function (bytes, keyBytes, ivBytes) { + return $q.when(aesEncrypt(bytes, keyBytes, ivBytes)); + }, + decrypt: function (encryptedBytes, keyBytes, ivBytes) { + return $q.when(aesDecrypt(encryptedBytes, keyBytes, ivBytes)); + } + }; + } + + var worker = new Worker('js/lib/aes_worker.js'), + taskID = 0, + awaiting = {}; + + worker.onmessage = function (e) { + var deferred = awaiting[e.data.taskID]; + if (deferred !== undefined) { + deferred.resolve(e.data.result); + delete awaiting[e.data.taskID]; + } + // dLog('AES worker message', e.data, deferred); + }; + worker.onerror = function(error) { + dLog('AES Worker error', error); + }; + + return { + encrypt: function (bytes, keyBytes, ivBytes) { + var deferred = $q.defer(); + + awaiting[taskID] = deferred; + + // dLog('AES post message', {taskID: taskID, task: 'encrypt', bytes: bytes, keyBytes: keyBytes, ivBytes: ivBytes}) + worker.postMessage({taskID: taskID, task: 'encrypt', bytes: bytes, keyBytes: keyBytes, ivBytes: ivBytes}); + + taskID++ + + return deferred.promise; + }, + decrypt: function (encryptedBytes, keyBytes, ivBytes) { + var deferred = $q.defer(); + + awaiting[taskID] = deferred; + worker.postMessage({taskID: taskID, task: 'decrypt', encryptedBytes: encryptedBytes, keyBytes: keyBytes, ivBytes: ivBytes}); + + taskID++; + + return deferred.promise; + } + } +}). + + +factory('MtpSha1Service', function ($q) { + if (!window.Worker/* || true*/) { + return { + hash: function (bytes) { + return $q.when(sha1Hash(bytes)); + } + }; + } + + var worker = new Worker('js/lib/sha1_worker.js'), + taskID = 0, + awaiting = {}; + + worker.onmessage = function (e) { + var deferred = awaiting[e.data.taskID]; + if (deferred !== undefined) { + deferred.resolve(e.data.result); + delete awaiting[e.data.taskID]; + } + // dLog('sha1 got message', e.data, deferred); + }; + worker.onerror = function(error) { + dLog('SHA-1 Worker error', error); + }; + + return { + hash: function (bytes) { + var deferred = $q.defer(); + + awaiting[taskID] = deferred; + // dLog(11, taskID, bytes); + worker.postMessage({taskID: taskID, bytes: bytes}); + + taskID++; + + return deferred.promise; + } + } +}). + +factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerator, MtpSecureRandom, MtpSha1Service, MtpAesService, AppConfigManager, $http, $q, $timeout) { + + var updatesProcessor; + + function MtpNetworker(dcID, authKey, serverSalt) { + this.dcID = dcID; + + this.authKey = authKey; + this.authKeyID = sha1Hash(authKey).slice(-8); + + this.serverSalt = serverSalt; + + this.sessionID = new Array(8); + MtpSecureRandom.nextBytes(this.sessionID); + + if (true) { + this.sessionID[0] = 0xA; + this.sessionID[1] = 0xB; + this.sessionID[3] = 0xC; + this.sessionID[4] = 0xD; + } + + this.seqNo = 0; + this.currentRequests = 0; + + this.sentMessages = {}; + this.serverMessages = []; + this.clientMessages = []; + + this.pendingMessages = {}; + this.pendingAcks = []; + this.pendingResends = []; + this.connectionInited = false; + + this.pendingTimeouts = []; + + this.longPollInt = setInterval(this.checkLongPoll.bind(this), 10000); + this.checkLongPoll(); + }; + + + MtpNetworker.prototype.generateSeqNo = function (notContentRelated) { + var seqNo = this.seqNo * 2; + + if (!notContentRelated) { + seqNo++; + this.seqNo++; + } + + return seqNo; + } + + MtpNetworker.prototype.wrapMtpCall = function (method, params, options) { + var serializer = new TLSerialization({mtproto: true}); + + serializer.storeMethod(method, params); + + var messageID = MtpMessageIdGenerator.generateID(), + seqNo = this.generateSeqNo(), + message = { + msg_id: messageID, + seq_no: seqNo, + body: serializer.getBytes() + }; + + // dLog('MT call', method, params, messageID, seqNo); + + return this.pushMessage(message, options); + }; + + MtpNetworker.prototype.wrapMtpMessage = function (object, options) { + options = options || {}; + + var serializer = new TLSerialization({mtproto: true}); + serializer.storeObject(object, 'Object'); + + var messageID = MtpMessageIdGenerator.generateID(), + seqNo = this.generateSeqNo(options.notContentRelated), + message = { + msg_id: messageID, + seq_no: seqNo, + body: serializer.getBytes() + }; + + // dLog('MT message', object, messageID, seqNo); + + return this.pushMessage(message, options); + }; + + MtpNetworker.prototype.wrapApiCall = function (method, params, options) { + var serializer = new TLSerialization(options); + + if (!this.connectionInited) { + serializer.storeInt(962726977, 'InokeWithLayer10'); + serializer.storeInt(0x69796de9, 'initConnection'); + serializer.storeInt(777, 'api_id'); + serializer.storeString(navigator.userAgent, 'device_model'); + serializer.storeString(navigator.platform, 'system_version'); + serializer.storeString('0.1', 'app_version'); + serializer.storeString(navigator.language, 'lang_code'); + } + + serializer.storeMethod(method, params); + + var messageID = MtpMessageIdGenerator.generateID(), + seqNo = this.generateSeqNo(), + message = { + msg_id: messageID, + seq_no: seqNo, + body: serializer.getBytes(), + isAPI: true + }; + + dLog('Api call', method, messageID, seqNo); + // dLog('Api call', method, params, messageID, seqNo); + + return this.pushMessage(message, options); + }; + + MtpNetworker.prototype.checkLongPoll = function(force) { + // dLog('Check lp', this.longPollPending, (new Date().getTime())); + if (this.longPollPending && (new Date().getTime()) < this.longPollPending) { + return false; + } + this.sendLongPoll(); + }; + + MtpNetworker.prototype.sendLongPoll = function() { + var maxWait = 25000; + this.longPollPending = (new Date().getTime()) + maxWait; + // dLog('Set lp', this.longPollPending, (new Date().getTime())); + + this.wrapMtpCall('http_wait', {max_delay: 0, wait_after: 0, max_wait: maxWait}, {noResponse: true}). + then((function () { + delete this.longPollPending; + setTimeout(this.checkLongPoll.bind(this), 0); + }).bind(this)); + }; + + MtpNetworker.prototype.pushMessage = function(message, options) { + var deferred = $q.defer(); + + this.sentMessages[message.msg_id] = angular.extend(message, options || {}, {deferred: deferred}); + this.pendingMessages[message.msg_id] = 0; + + if (!options || !options.noShedule) { + this.sheduleRequest(); + } + + return deferred.promise; + }; + + MtpNetworker.prototype.pushResend = function(messageID, delay) { + var value = delay ? (new Date()).getTime() + delay : 0; + var sentMessage = this.sentMessages[messageID]; + if (sentMessage.container) { + for (var i = 0; i < sentMessage.inner.length; i++) { + this.pendingMessages[sentMessage.inner[i]] = value; + } + } else { + this.pendingMessages[messageID] = value; + } + + // dLog('Resend due', messageID, this.pendingMessages); + + this.sheduleRequest(delay); + }; + + MtpNetworker.prototype.getMsgKeyIv = function (msgKey, isOut) { + var authKey = this.authKey, + x = isOut ? 0 : 8; + + var promises = { + sha1a: MtpSha1Service.hash(msgKey.concat(authKey.slice(x, x + 32))), + sha1b: MtpSha1Service.hash(authKey.slice(32 + x, 48 + x).concat(msgKey, authKey.slice(48 + x, 64 + x))), + sha1c: MtpSha1Service.hash(authKey.slice(64 + x, 96 + x).concat(msgKey)), + sha1d: MtpSha1Service.hash(msgKey.concat(authKey.slice(96 + x, 128 + x))) + }; + + return $q.all(promises).then(function (result) { + var aesKey = result.sha1a.slice(0, 8).concat(result.sha1b.slice(8, 20), result.sha1c.slice(4, 16)); + var aesIv = result.sha1a.slice(8, 20).concat(result.sha1b.slice(0, 8), result.sha1c.slice(16, 20), result.sha1d.slice(0, 8)); + + return [aesKey, aesIv]; + }); + }; + + + MtpNetworker.prototype.performSheduledRequest = function() { + // dLog('start sheduled'); + delete this.nextReq; + if (this.pendingAcks.length) { + var ackMsgIDs = []; + for (var i = 0; i < this.pendingAcks.length; i++) { + ackMsgIDs.push(this.pendingAcks[i]); + } + // dLog('acking messages', ackMsgIDs); + this.wrapMtpMessage({_: 'msgs_ack', msg_ids: ackMsgIDs}, {notContentRelated: true, noShedule: true}); + } + + if (this.pendingResends.length) { + var resendMsgIDs = []; + for (var i = 0; i < this.pendingResends.length; i++) { + resendMsgIDs.push(this.pendingResends[i]); + } + // dLog('resendReq messages', resendMsgIDs); + this.wrapMtpMessage({_: 'msg_resend_req', msg_ids: resendMsgIDs}, {noShedule: true}); + } + + var messages = [], + message, + messagesByteLen = 0, + currentTime = (new Date()).getTime(), + self = this; + + angular.forEach(this.pendingMessages, function (value, messageID) { + if (!value || value >= currentTime) { + if (message = self.sentMessages[messageID]) { + messages.push(message); + messagesByteLen += message.body.length + 32; + } else { + // dLog(message, messageID); + } + delete self.pendingMessages[messageID]; + } + }); + + if (!messages.length) { + // dLog('no sheduled messages'); + return; + } + + var noResponseMsgs = []; + + if (messages.length > 1) { + var container = new TLSerialization({mtproto: true, startMaxLength: messagesByteLen + 64}); + container.storeInt(0x73f1f8dc, 'CONTAINER[id]'); + container.storeInt(messages.length, 'CONTAINER[count]'); + var onloads = []; + var innerMessages = []; + for (var i = 0; i < messages.length; i++) { + container.storeLong(messages[i].msg_id, 'CONTAINER[' + i + '][msg_id]'); + innerMessages.push(messages[i].msg_id); + container.storeInt(messages[i].seq_no, 'CONTAINER[' + i + '][seq_no]'); + container.storeInt(messages[i].body.length, 'CONTAINER[' + i + '][bytes]'); + container.storeRawBytes(messages[i].body, 'CONTAINER[' + i + '][body]'); + if (messages[i].noResponse) { + noResponseMsgs.push(messages[i].msg_id); + } + } + + var containerSentMessage = { + msg_id: MtpMessageIdGenerator.generateID(), + seq_no: this.generateSeqNo(true), + container: true, + inner: innerMessages + } + + message = angular.extend({body: container.getBytes()}, containerSentMessage); + + this.sentMessages[message.msg_id] = containerSentMessage; + + // dLog('Container', innerMessages, message.msg_id, message.seq_no); + } else { + if (message.noResponse) { + noResponseMsgs.push(message.msg_id); + } + this.sentMessages[message.msg_id] = message; + } + + this.pendingAcks = []; + var self = this; + + this.sendEncryptedRequest(message).then(function (result) { + self.parseResponse(result.data); + + if (noResponseMsgs.length) { + $timeout(function () { + angular.forEach(noResponseMsgs, function (msgID) { + if (self.sentMessages[msgID]) { + var deferred = self.sentMessages[msgID].deferred; + delete self.sentMessages[msgID]; + deferred.resolve(); + } + }); + }, 200); + } + }); + }; + + MtpNetworker.prototype.getEncryptedMessage = function (bytes) { + var self = this; + + // dLog('enc', bytes); + + return MtpSha1Service.hash(bytes).then(function (bytesHash) { + // dLog('bytesHash', bytesHash); + var msgKey = bytesHash.slice(-16); + return self.getMsgKeyIv(msgKey, true).then(function (keyIv) { + // dLog('keyIv', keyIv); + return MtpAesService.encrypt(bytes, keyIv[0], keyIv[1]).then(function (encryptedBytes) { + // dLog('encryptedBytes', encryptedBytes); + return { + bytes: encryptedBytes, + msgKey: msgKey + }; + }) + }) + }) + }; + + MtpNetworker.prototype.getDecryptedMessage = function (msgKey, encryptedData) { + return this.getMsgKeyIv(msgKey, false).then(function (keyIv) { + return MtpAesService.decrypt(encryptedData, keyIv[0], keyIv[1]); + }); + }; + + MtpNetworker.prototype.sendEncryptedRequest = function (message) { + var self = this; + // dLog('send encrypted', message); + // console.trace(); + var data = new TLSerialization({startMaxLength: message.body.length + 64}); + + data.storeIntBytes(this.serverSalt, 64, 'salt'); + data.storeIntBytes(this.sessionID, 64, 'session_id'); + + data.storeLong(message.msg_id, 'message_id'); + data.storeInt(message.seq_no, 'seq_no'); + + data.storeInt(message.body.length, 'message_data_length'); + data.storeRawBytes(message.body, 'message_data'); + + return this.getEncryptedMessage(data.getBytes()).then(function (encryptedResult) { + // dLog('got enc result', encryptedResult); + var request = new TLSerialization({startMaxLength: encryptedResult.bytes.length + 256}); + request.storeIntBytes(self.authKeyID, 64, 'auth_key_id'); + request.storeIntBytes(encryptedResult.msgKey, 128, 'msg_key'); + request.storeRawBytes(encryptedResult.bytes, 'encrypted_data'); + + delete $http.defaults.headers.post['Content-Type']; + delete $http.defaults.headers.common['Accept']; + + return $http.post('http://' + MtpDcConfigurator.chooseServer(self.dcID) + '/apiw1', request.getArray(), { + responseType: 'arraybuffer', + transformRequest: null + }); + }); + }; + + MtpNetworker.prototype.parseResponse = function (responseBuffer) { + var self = this; + + var deserializer = new TLDeserialization(responseBuffer); + + var authKeyID = deserializer.fetchIntBytes(64, 'auth_key_id'); + if (!bytesCmp(authKeyID, this.authKeyID)) { + throw new Error('Invalid server auth_key_id: ' + bytesToHex(authKeyID)); + } + var msgKey = deserializer.fetchIntBytes(128, 'msg_key'); + + var dataLength = responseBuffer.byteLength - deserializer.getOffset(); + var encryptedData = deserializer.fetchRawBytes(dataLength, 'encrypted_data'); + + this.getDecryptedMessage(msgKey, encryptedData).then(function (dataWithPadding) { + var buffer = bytesToArrayBuffer(dataWithPadding); + + var deserializer = new TLDeserialization(buffer, {mtproto: true}); + + var salt = deserializer.fetchIntBytes(64, 'salt'); + var sessionID = deserializer.fetchIntBytes(64, 'session_id'); + var messageID = deserializer.fetchLong('message_id'); + + var seqNo = deserializer.fetchInt('seq_no'); + + var messageBody = deserializer.fetchRawBytes(false, 'message_data'); + + var offset = deserializer.getOffset(); + + MtpSha1Service.hash(dataWithPadding.slice(0, offset)).then(function (dataHashed) { + if (!bytesCmp(msgKey, dataHashed.slice(-16))) { + throw new Error('server msgKey mismatch'); + } + + var buffer = bytesToArrayBuffer(messageBody); + var deserializer = new TLDeserialization(buffer, {mtproto: true}); + + var response = deserializer.fetchObject('', 'INPUT'); + + // dLog('Server response', response); + + self.processResponse(response, messageID, sessionID, seqNo); + }); + }); + }; + + MtpNetworker.prototype.applyServerSalt = function (newServerSalt) { + var serverSalt = longToBytes(newServerSalt); + + var storeObj = {}; + storeObj['dc' + this.dcID + '_server_salt'] = bytesToHex(serverSalt); + AppConfigManager.set(storeObj); + + this.serverSalt = serverSalt; + return true; + }; + + MtpNetworker.prototype.sheduleRequest = function (delay) { + var nextReq = new Date() + delay; + + if (delay && this.nextReq && this.nextReq <= nextReq) { + return false; + } + + // dLog('shedule req', delay); + // console.trace(); + + clearTimeout(this.nextReqTO); + + this.nextReqTO = setTimeout(this.performSheduledRequest.bind(this), delay || 0); + this.nextReq = nextReq; + }; + + MtpNetworker.prototype.onSessionCreate = function (sessionID, messageID) { + dLog('New session created', bytesToHex(sessionID)); + }; + + MtpNetworker.prototype.ackMessage = function (msgID) { + // dLog('ack message', msgID); + this.pendingAcks.push(msgID); + this.sheduleRequest(30000); + }; + + MtpNetworker.prototype.reqResendMessage = function (msgID) { + dLog('req resend', msgID); + this.pendingResends.push(msgID); + this.sheduleRequest(100); + }; + + MtpNetworker.prototype.processResponse = function (response, messageID, sessionID, seqNo) { + return this.processMessage(response, messageID, sessionID); + }; + + MtpNetworker.prototype.processMessageAck = function (messageID) { + var sentMessage = this.sentMessages[messageID]; + if (sentMessage && !sentMessage.acked) { + delete sentMessage.body; + sentMessage.acked = true; + + return true; + } + + return false; + }; + + MtpNetworker.prototype.processError = function (rawError) { + var matches = (rawError.error_message || '').match(/^([A-Z_0-9]+\b)(: (.+))?/) || []; + rawError.error_code = uintToInt(rawError.error_code); + + return { + code: !rawError.error_code || rawError.error_code <= 0 ? 500 : rawError.error_code, + type: matches[1] || 'UNKNOWN', + description: matches[3] || ('CODE#' + rawError.error_code + ' ' + rawError.error_message), + originalError: rawError + }; + }; + + + MtpNetworker.prototype.processMessage = function (message, messageID, sessionID) { + // dLog('process message', message, messageID, sessionID); + switch (message._) { + case 'msg_container': + var len = message.messages.length; + for (var i = 0; i < len; i++) { + this.processMessage(message.messages[i], messageID, sessionID); + } + break; + + case 'bad_server_salt': + var sentMsg = this.sentMessages[message.bad_msg_id]; + if (!sentMsg || sentMsg.seq_no != message.bad_msg_seqno) { + dLog(message.bad_msg_id, message.bad_msg_seqno); + throw new Error('Bad server salt for invalid message'); + } + + this.applyServerSalt(message.new_server_salt); + this.pushResend(message.bad_msg_id); + this.ackMessage(messageID); + break; + + case 'message': + this.serverMessages.push(message.msg_id); + this.processMessage(message.body, message.msg_id, sessionID); + break; + + case 'new_session_created': + this.ackMessage(messageID); + + this.processMessageAck(message.first_msg_id); + this.applyServerSalt(message.server_salt); + this.onSessionCreate(sessionID, messageID); + break; + + case 'msgs_ack': + for (var i = 0; i < message.msg_ids.length; i++) { + this.processMessageAck(message.msg_ids[i]); + } + break; + + case 'msg_detailed_info': + if (!this.sentMessages[message.msg_id]) { + this.ackMessage(message.answer_msg_id); + break; + } + case 'msg_new_detailed_info': + // this.ackMessage(message.answer_msg_id); + this.reqResendMessage(message.answer_msg_id); + break; + + case 'rpc_result': + this.ackMessage(messageID); + + var sentMessageID = message.req_msg_id, + sentMessage = this.sentMessages[sentMessageID]; + + this.processMessageAck(sentMessageID); + if (sentMessage) { + var deferred = sentMessage.deferred; + if (message.result._ == 'rpc_error') { + var error = this.processError(message.result); + dLog('rpc error', error) + if (deferred) { + deferred.reject(error) + } + } else { + if (deferred) { + dLog('rpc response', message.result); + sentMessage.deferred.resolve(message.result); + } + if (sentMessage.isAPI) { + this.connectionInited = true; + } + } + + delete this.sentMessages[sentMessageID]; + } + break; + + default: + this.ackMessage(messageID); + + // dLog('Update', message); + if (updatesProcessor) { + updatesProcessor(message); + } + break; + + } + }; + + return { + getNetworker: function (dcID, authKey, serverSalt) { + return new MtpNetworker(dcID, authKey, serverSalt); + }, + setUpdatesProcessor: function (callback) { + updatesProcessor = callback; + } + }; + +}). + +factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworkerFactory, $q) { + var cachedNetworkers = {}, + cachedExportPromise = {}, + baseDcID = false; + + AppConfigManager.get('dc').then(function (dcID) { + if (dcID) { + baseDcID = dcID; + } + }); + + function mtpSetUserAuth (dcID, userAuth) { + AppConfigManager.set({ + dc: dcID, + user_auth: angular.extend({dcID: dcID}, userAuth) + }); + + baseDcID = dcID; + } + + function mtpLogOut () { + return mtpInvokeApi('auth.logOut').then(function () { + AppConfigManager.remove('dc', 'user_auth'); + + baseDcID = false; + }); + } + + function mtpGetNetworker (dcID) { + if (!dcID) { + throw new Exception('get Networker without dcID'); + } + + if (cachedNetworkers[dcID] !== undefined) { + return $q.when(cachedNetworkers[dcID]); + } + + var deferred = $q.defer(), + ak = 'dc' + dcID + '_auth_key', + ssk = 'dc' + dcID + '_server_salt'; + + AppConfigManager.get(ak, ssk).then(function (result) { + + if (cachedNetworkers[dcID] !== undefined) { + return deferred.resolve(cachedNetworkers[dcID]); + } + + var authKeyHex = result[0], + serverSaltHex = result[1]; + // dLog('ass', dcID, authKeyHex, serverSaltHex); + if (authKeyHex && authKeyHex.length == 512) { + var authKey = bytesFromHex(authKeyHex); + var serverSalt = bytesFromHex(serverSaltHex); + + return deferred.resolve(cachedNetworkers[dcID] = MtpNetworkerFactory.getNetworker(dcID, authKey, serverSalt)); + } + + MtpAuthorizer.auth(dcID).then(function (auth) { + var storeObj = {}; + storeObj[ak] = bytesToHex(auth.authKey); + storeObj[ssk] = bytesToHex(auth.serverSalt); + AppConfigManager.set(storeObj); + + deferred.resolve( + cachedNetworkers[dcID] = MtpNetworkerFactory.getNetworker(dcID, auth.authKey, auth.serverSalt) + ); + }, function (error) { + dLog('Get networker error', error, error.stack); + deferred.reject(error); + }); + + }); + + return deferred.promise; + }; + + function mtpInvokeApi (method, params, options) { + var deferred = $q.defer(); + + options = options || {}; + var dcID = options.dcID || baseDcID || 1; + + var cachedNetworker; + + mtpGetNetworker(dcID).then(function (networker) { + return (cachedNetworker = networker).wrapApiCall(method, params, options).then( + function (result) { + deferred.resolve(result); + // setTimeout(function () { + // deferred.resolve(result); + // },1000); + }, + function (error) { + dLog('error', error.code, error.type, baseDcID, dcID); + if (error.code == 401 && error.type == 'AUTH_KEY_UNREGISTERED' && baseDcID && dcID != baseDcID) { + if (cachedExportPromise[dcID] === undefined) { + var exportDeferred = $q.defer(); + + mtpInvokeApi('auth.exportAuthorization', {dc_id: dcID}).then(function (exportedAuth) { + mtpInvokeApi('auth.importAuthorization', { + id: exportedAuth.id, + bytes: exportedAuth.bytes + }, {dcID: dcID}).then(function () { + exportDeferred.resolve(); + }, function (e) { + exportDeferred.reject(e); + }) + }, function (e) { + exportDeferred.reject(e) + }); + + cachedExportPromise[dcID] = exportDeferred.promise; + } + + // dLog('promise', cachedExportPromise[dcID]); + + cachedExportPromise[dcID] = cachedExportPromise[dcID].then(function () { + (cachedNetworker = networker).wrapApiCall(method, params, options).then(function (result) { + deferred.resolve(result); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + } else { + deferred.reject(error); + } + }); + }); + + return deferred.promise; + }; + + function mtpGetUserID () { + var deferred = $q.defer(); + + AppConfigManager.get('user_auth').then(function (auth) { + deferred.resolve(auth.id || 0); + }); + + return deferred.promise; + } + + return { + getUserID: mtpGetUserID, + invokeApi: mtpInvokeApi, + setUserAuth: mtpSetUserAuth, + logOut: mtpLogOut + } +}). + + +factory('MtpApiFileManager', function (MtpApiManager, $q, $window) { + + var cachedFS = false; + var apiUploadPromise = $q.when(); + var cachedSavePromises = {}; + var cachedDownloadPromises = {}; + + var downloadPull = []; + var downloadActive = 0; + var downloadLimit = 5; + + function downloadRequest(cb, activeDelta) { + var deferred = $q.defer(); + downloadPull.push({cb: cb, deferred: deferred, activeDelta: activeDelta}); + downloadCheck(); + + return deferred.promise; + }; + + var index = 0; + + function downloadCheck() { + if (downloadActive >= downloadLimit || !downloadPull.length) { + return false; + } + + var data = downloadPull.shift(), + activeDelta = data.activeDelta || 1; + + downloadActive += activeDelta; + + var a = index++; + data.cb() + .then(function (result) { + downloadActive -= activeDelta; + downloadCheck(); + + data.deferred.resolve(result); + + }, function (error) { + downloadActive -= activeDelta; + downloadCheck(); + + data.deferred.reject(error); + }) + }; + + function requestFS (argument) { + if (cachedFS) { + return $q.when(cachedFS); + } + + var deferred = $q.defer(); + + $window.requestFileSystem = $window.requestFileSystem || $window.webkitRequestFileSystem; + + $window.requestFileSystem($window.TEMPORARY, 5*1024*1024, function (fs) { + cachedFS = fs; + deferred.resolve(); + }, function (e) { + deferred.reject(e); + }); + + return deferred.promise; + }; + + function fileWriteBytes(fileWriter, bytes) { + var deferred = $q.defer(); + + fileWriter.onwriteend = function(e) { + deferred.resolve(); + }; + fileWriter.onerror = function (e) { + deferred.reject(); + }; + + if (false) { // is file bytes + fileWriter.write(bytes); + } else { + fileWriter.write(new Blob([bytesToArrayBuffer(bytes)])); + } + + return deferred.promise; + } + + function getFileName(location) { + switch (location._) { + case 'inputVideoFileLocation': + return 'video' + location.id + '.mp4'; + + case 'inputDocumentFileLocation': + return 'doc' + location.id; + } + return location.volume_id + '_' + location.local_id + '_' + location.secret + '.jpg'; + }; + + function getTempFileName(file) { + var size = file.size || -1; + var random = nextRandomInt(0xFFFFFFFF); + return '_temp' + random + '_' + size; + }; + + function getCachedFile (location) { + var fileName = getFileName(location); + + if (cachedSavePromises[fileName]) { + return cachedSavePromises[fileName]; + } + var deferred = $q.defer(), + errorHandler = function (error) { + deferred.reject(); + }; + + requestFS().then(function () { + cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) { + deferred.resolve(fileEntry.toURL()); + }, errorHandler); + }, errorHandler); + + return deferred.promise; + } + + function saveSmallFile (location, bytes) { + var fileName = getFileName(location); + + if (cachedSavePromises[fileName]) { + return cachedSavePromises[fileName]; + } + var deferred = $q.defer(), + cacheFileWriter, + errorHandler = function (error) { + deferred.reject(error); + if (cacheFileWriter) cacheFileWriter.truncate(); + }; + + requestFS().then(function () { + cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) { + deferred.resolve(fileEntry.toURL()); + }, function () { + cachedFS.root.getFile(fileName, {create: true}, function(fileEntry) { + fileEntry.createWriter(function (fileWriter) { + cacheFileWriter = fileWriter; + fileWriteBytes(fileWriter, bytes).then(function () { + deferred.resolve(fileEntry.toURL()); + }, errorHandler); + }, errorHandler); + }, errorHandler); + }); + }, errorHandler); + + return cachedSavePromises[fileName] = deferred.promise; + } + + function downloadSmallFile(location) { + // dLog('dload small', location); + var fileName = getFileName(location), + cachedPromise = cachedSavePromises[fileName] || cachedDownloadPromises[fileName]; + + if (cachedPromise) { + return cachedPromise; + } + + var deferred = $q.defer(), + cacheFileWriter, + errorHandler = function (error) { + deferred.reject(error); + if (cacheFileWriter) cacheFileWriter.truncate(); + }, + doDownload = function () { + cachedFS.root.getFile(fileName, {create: true}, function(fileEntry) { + var downloadPromise = downloadRequest(function () { + // dLog('next small promise'); + return MtpApiManager.invokeApi('upload.getFile', { + location: angular.extend({}, location, {_: 'inputFileLocation'}), + offset: 0, + limit: 0 + }, {dcID: location.dc_id}); + }); + + fileEntry.createWriter(function (fileWriter) { + cacheFileWriter = fileWriter; + downloadPromise.then(function (result) { + fileWriteBytes(fileWriter, result.bytes).then(function () { + // dLog('Success', location, fileEntry.toURL()); + deferred.resolve(fileEntry.toURL()); + }, errorHandler); + }, errorHandler); + }, errorHandler); + }, errorHandler); + }; + + requestFS().then(function () { + cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) { + fileEntry.file(function(file) { + if (file.size) { + deferred.resolve(fileEntry.toURL()); + } else { + dLog('Small file empty', file); + doDownload(); + } + }, errorHandler); + }, doDownload); + }, errorHandler); + + return cachedDownloadPromises[fileName] = deferred.promise; + } + + function downloadFile (dcID, location, size, fileEntry) { + dLog('dload file', dcID, location, size); + var fileName = getFileName(location), + cachedPromise = cachedSavePromises[fileName] || cachedDownloadPromises[fileName]; + + if (cachedPromise) { + return cachedPromise; + } + + var deferred = $q.defer(), + errorHandler = function (error) { + console.error(error); + // dLog('fail'); + deferred.reject(error); + if (cacheFileWriter) cacheFileWriter.truncate(); + }, + saveToFileEntry = function (fileEntry) { + fileEntry.createWriter(function (fileWriter) { + cacheFileWriter = fileWriter; + + // var limit = size > 102400 ? 65536 : 4096; + var limit = size > 30400 ? 524288 : 4096; + // var limit = size > 30400 ? 20480 : 4096; + var writeFilePromise = $q.when(), + writeFileDeferred; + for (var offset = 0; offset < size; offset += limit) { + writeFileDeferred = $q.defer(); + (function (isFinal, offset, writeFileDeferred, writeFilePromise) { + return downloadRequest(function () { + // dLog('next big promise'); + return MtpApiManager.invokeApi('upload.getFile', { + location: location, + offset: offset, + limit: limit + }, {dcID: dcID}); + + }, 6).then(function (result) { + + // dLog('waiting for file promise', offset); + writeFilePromise.then(function () { + // dLog('resolved file promise', offset); + + return fileWriteBytes(fileWriter, result.bytes).then(function () { + + // dLog('resolve file promise', offset); + writeFileDeferred.resolve(); + + }, errorHandler).then(function () { + + if (isFinal) { + deferred.resolve(fileEntry.toURL('image/jpeg')); + } else { + // dLog('notify', {done: offset + limit, total: size}); + deferred.notify({done: offset + limit, total: size}); + }; + + }); + + }); + + }); + + })(offset + limit >= size, offset, writeFileDeferred, writeFilePromise); + + writeFilePromise = writeFileDeferred.promise; + + } + }, errorHandler); + + }, + doDownload = function () { + cachedFS.root.getFile(fileName, {create: true}, saveToFileEntry, errorHandler); + }; + + if (fileEntry) { + saveToFileEntry(fileEntry); + } else { + requestFS().then(function () { + cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) { + fileEntry.file(function(file) { + dLog('check size', file.size, size); + if (file.size >= size && false) { + deferred.resolve(fileEntry.toURL()); + } else { + dLog('File bad size', file, size); + doDownload(); + } + }, errorHandler); + }, doDownload); + }, errorHandler); + } + + return cachedDownloadPromises[fileName] = deferred.promise; + } + + function writeFile (file) { + dLog('write file', file); + var fileName = getTempFileName(file); + + var deferred = $q.defer(), + cacheFileWriter, + errorHandler = function (error) { + dLog('fail'); + deferred.reject(error); + if (cacheFileWriter) cacheFileWriter.truncate(); + }; + + requestFS().then(function () { + cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) { + deferred.resolve(fileEntry); + }, function () { + cachedFS.root.getFile(fileName, {create: true}, function(fileEntry) { + fileEntry.createWriter(function (fileWriter) { + cacheFileWriter = fileWriter; + fileWriteBytes(fileWriter, file).then(function () { + deferred.resolve(fileEntry); + }, errorHandler); + }, errorHandler); + }); + }); + }); + }; + + function uploadFile (file) { + var fileSize = file.size, + // partSize = fileSize > 102400 ? 65536 : 4096, + partSize = fileSize > 102400 ? 524288 : 4096, + totalParts = Math.ceil(fileSize / partSize), + doneParts = 0; + + if (totalParts > 1500) { + return $q.reject({type: 'FILE_TOO_BIG'}); + } + + var fileID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)], + deferred = $q.defer(), + errorHandler = function (error) { + dLog('error', error); + deferred.reject(error); + }, + part = 0, + offset, + resultInputFile = { + _: 'inputFile', + id:fileID, + parts: totalParts, + name: file.name, + md5_checksum: '' + }; + + + var fileReadPromise = $q.when(); + + for (offset = 0; offset < fileSize; offset += partSize) { + (function (offset, part) { + fileReadPromise = fileReadPromise.then(function () { + var fileReadDeferred = $q.defer(); + + var reader = new FileReader(); + var blob = file.slice(offset, offset + partSize); + + reader.onloadend = function (e) { + if (e.target.readyState != FileReader.DONE) { + return; + } + var apiCurPromise = apiUploadPromise = apiUploadPromise.then(function () { + return MtpApiManager.invokeApi('upload.saveFilePart', { + file_id: fileID, + file_part: part, + bytes: bytesFromArrayBuffer(e.target.result) + }, {startMaxLength: partSize + 256}); + }, errorHandler); + + apiCurPromise.then(function (result) { + doneParts++; + fileReadDeferred.resolve(); + if (doneParts >= totalParts) { + deferred.resolve(resultInputFile); + } else { + dLog('Progress', doneParts * partSize / fileSize); + deferred.notify({done: doneParts * partSize, total: fileSize}); + } + }, errorHandler); + }; + + reader.readAsArrayBuffer(blob); + + return fileReadDeferred.promise; + }); + })(offset, part++); + } + + return deferred.promise; + } + + + return { + getCachedFile: getCachedFile, + downloadFile: downloadFile, + downloadSmallFile: downloadSmallFile, + saveSmallFile: saveSmallFile, + uploadFile: uploadFile + }; +}) + + + + + + diff --git a/js/lib/pq_worker.js b/js/lib/pq_worker.js new file mode 100644 index 00000000..3385fd8a --- /dev/null +++ b/js/lib/pq_worker.js @@ -0,0 +1,12 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +importScripts('mtproto.js', 'jsbn.js'); + +onmessage = function (e) { + postMessage(pqPrimeFactorization(e.data)); +} \ No newline at end of file diff --git a/js/lib/sha1_worker.js b/js/lib/sha1_worker.js new file mode 100644 index 00000000..44a35fb5 --- /dev/null +++ b/js/lib/sha1_worker.js @@ -0,0 +1,14 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +importScripts('mtproto.js', '../../vendor/cryptoJS/crypto.js'); + +onmessage = function (e) { + var taskID = e.data.taskID; + + postMessage({taskID: taskID, result: sha1Hash(e.data.bytes)}); +} \ No newline at end of file diff --git a/js/services.js b/js/services.js new file mode 100644 index 00000000..f2569107 --- /dev/null +++ b/js/services.js @@ -0,0 +1,1439 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +'use strict'; + +/* Services */ + +angular.module('myApp.services', []) + +.service('AppConfigManager', function ($q) { + var testPrefix = window._testMode ? 't_' : ''; + var cache = {}; + var useLs = !window.chrome || !chrome.storage || !chrome.storage.local; + + function getValue() { + var keys = Array.prototype.slice.call(arguments), + result = [], + single = keys.length == 1, + allFound = true; + + for (var i = 0; i < keys.length; i++) { + keys[i] = testPrefix + keys[i]; + } + + angular.forEach(keys, function (key) { + if (cache[key] !== undefined) { + result.push(cache[key]); + } + else if (useLs) { + var value = localStorage.getItem(key); + value = (value === undefined || value === null) ? false : JSON.parse(value); + result.push(cache[key] = value); + } + else { + allFound = false; + } + }); + + if (allFound) { + return $q.when(single ? result[0] : result); + } + + var deferred = $q.defer(); + + // dLog('get', keys); + chrome.storage.local.get(keys, function (resultObj) { + // dLog('got', resultObj); + result = []; + angular.forEach(keys, function (key) { + var value = resultObj[key]; + // dLog('p1', key, value); + value = value === undefined || value === null ? false : JSON.parse(value); + // dLog('p2', value); + result.push(cache[key] = value); + }); + + // dLog('got parsed', result); + deferred.resolve(single ? result[0] : result); + }); + + return deferred.promise; + }; + + function setValue(obj) { + var keyValues = {}; + angular.forEach(obj, function (value, key) { + keyValues[testPrefix + key] = JSON.stringify(value); + cache[testPrefix + key] = value; + }); + + if (useLs) { + angular.forEach(keyValues, function (value, key) { + localStorage.setItem(key, value); + }); + return $q.when(); + } + + var deferred = $q.defer(); + + chrome.storage.local.set(keyValues, function () { + deferred.resolve(); + }); + + return deferred.promise; + }; + + function removeValue () { + var keys = Array.prototype.slice.call(arguments); + + for (var i = 0; i < keys.length; i++) { + keys[i] = testPrefix + keys[i]; + } + + angular.forEach(keys, function(key){ + delete cache[key]; + }); + + if (useLs) { + angular.forEach(keys, function(key){ + localStorage.removeItem(key); + }); + + return $q.when(); + } + + var deferred = $q.defer(); + + chrome.storage.local.remove(keys, function () { + deferred.resolve(); + }); + + return deferred.promise; + }; + + return { + get: getValue, + set: setValue, + remove: removeValue + }; +}) + +.service('AppUsersManager', function ($rootScope, $modal, MtpApiFileManager, MtpApiManager, RichTextProcessor) { + var users = {}; + + function saveApiUsers (apiUsers) { + angular.forEach(apiUsers, saveApiUser); + }; + + function saveApiUser (apiUser) { + if (!angular.isObject(apiUser)) { + return; + } + + if (apiUser.first_name) { + apiUser.rFirstName = RichTextProcessor.wrapRichText(apiUser.first_name, {noLinks: true, noLinebreaks: true}); + apiUser.rFullName = RichTextProcessor.wrapRichText(apiUser.first_name + ' ' + (apiUser.last_name || ''), {noLinks: true, noLinebreaks: true}); + } else { + apiUser.rFirstName = RichTextProcessor.wrapRichText(apiUser.last_name, {noLinks: true, noLinebreaks: true}) || 'DELETED'; + apiUser.rFullName = RichTextProcessor.wrapRichText(apiUser.last_name, {noLinks: true, noLinebreaks: true}) || 'DELETED'; + } + + if (users[apiUser.id] === undefined) { + users[apiUser.id] = apiUser; + } else { + angular.extend(users[apiUser.id], apiUser); + } + }; + + function getUser (id) { + if (angular.isObject(id)) { + return id; + } + return users[id] || {id: id, deleted: true}; + } + + function getUserPhoto(id, placeholder) { + var user = getUser(id); + + return { + placeholder: 'img/placeholders/' + placeholder + 'Avatar'+((Math.abs(id) % 8) + 1)+'@2x.png', + location: user && user.photo && user.photo.photo_small + }; + } + + function getUserString (id) { + var user = getUser(id); + return 'u' + id + (user.access_hash ? '_' + user.access_hash : ''); + } + + function getUserInput (id) { + var user = getUser(id); + if (user._ == 'userSelf') { + return {_: 'inputUserSelf'}; + } + return { + _: 'inputUserForeign', + user_id: id, + access_hash: user.access_hash || 0 + }; + } + + function wrapForFull (id) { + var user = getUser(id); + + user.thumb = { + placeholder: 'img/placeholders/UserAvatar'+((Math.abs(id) % 8) + 1)+'@2x.png', + location: user && user.photo && user.photo.photo_small, + width: 120, + height: 120, + size: 0 + }; + user.peerString = getUserString(id); + + return user; + } + + function openUser (userID, accessHash) { + var scope = $rootScope.$new(); + scope.userID = userID; + + var modalInstance = $modal.open({ + templateUrl: 'partials/user_modal.html', + controller: 'UserModalController', + scope: scope, + windowClass: 'user_modal_window', + resolve: { + userFull: MtpApiManager.invokeApi('users.getFullUser', { + id: getUserInput(userID) + }).then(function (result) { + saveApiUser(result.user); + return result; + }) + } + }); + } + + $rootScope.openUser = openUser; + + $rootScope.$on('apiUpdate', function (e, update) { + // dLog('on apiUpdate', update); + switch (update._) { + case 'updateUserStatus': + var userID = update.user_id; + if (users[userID]) { + users[userID].status = update.status; + $rootScope.$broadcast('user_update', userID); + } + break; + + case 'updateUserPhoto': + var userID = update.user_id; + if (users[userID]) { + users[userID].photo = update.photo; + $rootScope.$broadcast('user_update', userID); + } + break; + } + }); + + + return { + saveApiUsers: saveApiUsers, + saveApiUser: saveApiUser, + getUser: getUser, + getUserPhoto: getUserPhoto, + getUserString: getUserString, + wrapForFull: wrapForFull, + openUser: openUser + } +}) + +.service('AppChatsManager', function ($rootScope, $modal, MtpApiFileManager, MtpApiManager, AppUsersManager, RichTextProcessor) { + var chats = {}; + + function saveApiChats (apiChats) { + angular.forEach(apiChats, saveApiChat); + }; + + function saveApiChat (apiChat) { + if (!angular.isObject(apiChat)) { + return; + } + apiChat.rTitle = RichTextProcessor.wrapRichText(apiChat.title, {noLinks: true, noLinebreaks: true}) || 'DELETED'; + if (chats[apiChat.id] === undefined) { + chats[apiChat.id] = apiChat; + } else { + angular.extend(chats[apiChat.id], apiChat); + } + }; + + function getChat (id) { + return chats[id] || {id: id, deleted: true}; + } + + function getChatPhoto(id, placeholder) { + var chat = getChat(id); + + return { + placeholder: 'img/placeholders/' + placeholder + 'Avatar'+((Math.abs(id) % 4) + 1)+'@2x.png', + location: chat && chat.photo && chat.photo.photo_small + }; + } + + function getChatString (id) { + var chat = getChat(id); + return 'g' + id; + } + + function wrapForFull (id, fullChat) { + var chatFull = angular.copy(fullChat), + chat = getChat(id); + + if (chatFull.participants._ == 'chatParticipants') { + angular.forEach(chatFull.participants.participants, function(participant){ + participant.user = AppUsersManager.getUser(participant.user_id); + participant.userPhoto = AppUsersManager.getUserPhoto(participant.user_id, 'User'); + participant.inviter = AppUsersManager.getUser(participant.inviter_id); + }); + } + + chatFull.thumb = { + placeholder: 'img/placeholders/GroupAvatar'+((Math.abs(id) % 4) + 1)+'@2x.png', + location: chat && chat.photo && chat.photo.photo_small, + width: 120, + height: 120, + size: 0 + }; + chatFull.peerString = getChatString(id); + chatFull.chat = chat; + + return chatFull; + } + + function openChat (chatID, accessHash) { + var scope = $rootScope.$new(); + scope.chatID = chatID; + + var modalInstance = $modal.open({ + templateUrl: 'partials/chat_modal.html', + controller: 'ChatModalController', + windowClass: 'chat_modal_window', + scope: scope, + resolve: { + fullChat: function () { + return MtpApiManager.invokeApi('messages.getFullChat', { + chat_id: chatID + }).then(function (result) { + saveApiChats(result.chats); + AppUsersManager.saveApiUsers(result.users); + return result.full_chat; + }) + } + } + }); + } + + $rootScope.openChat = openChat; + + + return { + saveApiChats: saveApiChats, + saveApiChat: saveApiChat, + getChat: getChat, + getChatPhoto: getChatPhoto, + getChatString: getChatString, + wrapForFull: wrapForFull, + openChat: openChat + } +}) + +.service('AppPeersManager', function (AppUsersManager, AppChatsManager) { + return { + getInputPeer: function (peerString) { + var isUser = peerString.charAt(0) == 'u', + peerParams = peerString.substr(1).split('_'); + + return isUser + ? {_: 'inputPeerForeign', user_id: peerParams[0], access_hash: peerParams[1]} + : {_: 'inputPeerChat', chat_id: peerParams[0]}; + }, + getInputPeerByID: function (peerID) { + if (peerID > 0) { + return { + _: 'inputPeerForeign', + user_id: peerID, + access_hash: AppUsersManager.getUser(peerID).access_hash || 0 + }; + } else if (peerID < 0) { + return { + _: 'inputPeerChat', + chat_id: -peerID + }; + } + }, + getOutputPeer: function (peerID) { + return peerID > 0 + ? {_: 'peerUser', user_id: peerID} + : {_: 'peerChat', chat_id: -peerID}; + }, + getPeerID: function (peerString) { + if (angular.isObject(peerString)) { + return peerString.user_id + ? peerString.user_id + : -peerString.chat_id; + } + var isUser = peerString.charAt(0) == 'u', + peerParams = peerString.substr(1).split('_'); + + return isUser ? peerParams[0] : -peerParams[0] || 0; + }, + getPeer: function (peerID) { + return peerID > 0 + ? AppUsersManager.getUser(peerID) + : AppChatsManager.getChat(-peerID); + }, + getPeerPhoto: function (peerID, userPlaceholder, chatPlaceholder) { + return peerID > 0 + ? AppUsersManager.getUserPhoto(peerID, userPlaceholder) + : AppChatsManager.getChatPhoto(-peerID, chatPlaceholder) + } + } +}) + +.service('AppMessagesManager', function ($q, $rootScope, $filter, $sanitize, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, MtpApiManager, RichTextProcessor) { + + var messagesStorage = {}; + var messagesForHistory = {}; + var historiesStorage = {}; + var dialogsStorage = {count: null, dialogs: []}; + + function getDialogs (offset, limit) { + if (dialogsStorage.count !== null && dialogsStorage.dialogs.length >= offset + limit) { + return $q.when({ + count: dialogsStorage.count, + dialogs: dialogsStorage.dialogs.slice(offset, offset + limit) + }); + } + + var deferred = $q.defer(); + + MtpApiManager.invokeApi('messages.getDialogs', { + offset: offset, + limit: limit, + max_id: 0 + }).then(function (dialogsResult) { + AppUsersManager.saveApiUsers(dialogsResult.users); + AppChatsManager.saveApiChats(dialogsResult.chats); + saveMessages(dialogsResult.messages); + + dialogsStorage.count = dialogsResult._ == 'messages.dialogsSlice' + ? dialogsResult.count + : dialogsResult.dialogs.length; + + angular.forEach(dialogsResult.dialogs, function (dialog) { + dialogsStorage.dialogs.push({ + peerID: AppPeersManager.getPeerID(dialog.peer), + top_message: dialog.top_message, + unread_count: dialog.unread_count + }); + }); + + deferred.resolve({ + count: dialogsStorage.count, + dialogs: dialogsStorage.dialogs.slice(offset, offset + limit) + }); + }, function (error) { + deferred.reject(error); + }); + + return deferred.promise; + } + + function getHistory (inputPeer, maxID, limit) { + + var peerID = AppPeersManager.getPeerID(inputPeer), + historyStorage = historiesStorage[peerID], + offset = 0; + + if (historyStorage === undefined) { + historyStorage = historiesStorage[peerID] = {count: null, history: []}; + } + + + if (maxID > 0) { + for (offset = 0; offset < historyStorage.history.length; offset++) { + if (maxID > historyStorage.history[offset]) { + break; + } + } + } + // dLog('history storage', angular.copy(historyStorage.history), maxID, offset); + + if (historyStorage.count !== null && historyStorage.history.length >= offset + limit) { + return $q.when({ + count: historyStorage.count, + history: historyStorage.history.slice(offset, offset + limit) + }); + } + + var deferred = $q.defer(); + + MtpApiManager.invokeApi('messages.getHistory', { + peer: inputPeer, + offset: offset, + limit: limit, + max_id: 0 + }).then(function (historyResult) { + AppUsersManager.saveApiUsers(historyResult.users); + AppChatsManager.saveApiChats(historyResult.chats); + saveMessages(historyResult.messages); + + historyStorage.count = historyResult._ == 'messages.messagesSlice' + ? historyResult.count + : historyResult.messages.length; + + offset = 0; + if (maxID > 0) { + for (offset = 0; offset < historyStorage.history.length; offset++) { + if (maxID > historyStorage.history[offset]) { + break; + } + } + } + + // dLog('history storage after', angular.copy(historyStorage.history), historyResult.messages, maxID, offset); + + historyStorage.history.splice(offset, historyStorage.history.length - offset); + angular.forEach(historyResult.messages, function (message) { + historyStorage.history.push(message.id); + }); + + deferred.resolve({ + count: historyStorage.count, + history: historyStorage.history.slice(offset, offset + limit) + }); + }, function (error) { + deferred.reject(error); + }); + + return deferred.promise; + } + + function processAffectedHistory (inputPeer, affectedHistory) { + if (!ApiUpdatesManager.saveSeq(affectedHistory.seq)) { + return false; + } + if (!affectedHistory.offset) { + return $q.when(); + } + + return MtpApiManager.invokeApi('messages.readHistory', { + peer: inputPeer, + offset: affectedHistory.offset, + max_id: 0 + }).then(function (affectedHistory) { + return processAffectedHistory(inputPeer, affectedHistory); + }); + } + + function readHistory (inputPeer) { + // dLog('start read'); + var peerID = AppPeersManager.getPeerID(inputPeer), + historyStorage = historiesStorage[peerID], + foundDialog = getDialogByPeerID(peerID); + + if (!historyStorage || + !historyStorage.history.length || + foundDialog[0] && !foundDialog[0].unread_count) { + // dLog('bad1'); + return false; + } + + var wasUnread = false; + // dLog(historyStorage); + for (i = 0; i < historyStorage.history.length; i++) { + messageID = historyStorage.history[i]; + message = messagesStorage[messageID]; + // dLog('ms', message); + if (message && !message.out) { + if (message.unread) { + // dLog('unread'); + wasUnread = true; + } else if (!wasUnread) { + // dLog('bad2'); + return false; + } + } + } + + var promise = MtpApiManager.invokeApi('messages.readHistory', { + peer: inputPeer, + offset: 0, + max_id: 0 + }).then(function (affectedHistory) { + return processAffectedHistory(inputPeer, affectedHistory); + }).then(function () { + if (foundDialog[0]) { + foundDialog[0].unread_count = 0; + $rootScope.$broadcast('dialog_unread', {peerID: peerID, count: 0}); + } + }); + + + var messageID, message, i, peerID, foundDialog, dialog; + for (i = 0; i < historyStorage.history.length; i++) { + messageID = historyStorage.history[i]; + message = messagesStorage[messageID]; + if (message && !message.out) { + message.unread = false; + if (messagesForHistory[messageID]) { + messagesForHistory[messageID].unread = false; + } + } + } + + return promise; + } + + function saveMessages (apiMessages) { + angular.forEach(apiMessages, function (apiMessage) { + messagesStorage[apiMessage.id] = apiMessage; + + if (apiMessage.media && apiMessage.media._ == 'messageMediaPhoto') { + AppPhotosManager.savePhoto(apiMessage.media.photo); + } + if (apiMessage.media && apiMessage.media._ == 'messageMediaVideo') { + AppVideoManager.saveVideo(apiMessage.media.video); + } + if (apiMessage.media && apiMessage.media._ == 'messageMediaDocument') { + AppDocsManager.saveDoc(apiMessage.media.document); + } + if (apiMessage.action && apiMessage.action._ == 'messageActionChatEditPhoto') { + AppPhotosManager.savePhoto(apiMessage.action.photo); + } + }); + } + + function getMessagePeer (message) { + var toID = message.to_id && AppPeersManager.getPeerID(message.to_id) || 0; + + if (toID < 0) { + return toID; + } else if (message.out) { + return toID + } + return message.from_id; + } + + function wrapForDialog (msgID, unreadCount) { + var message = angular.copy(messagesStorage[msgID]) || {id: msgID}; + + message.fromUser = AppUsersManager.getUser(message.from_id); + + if (message.chatID = message.to_id.chat_id) { + message.peerID = -message.chatID; + message.peerData = AppChatsManager.getChat(message.chatID); + message.peerString = AppChatsManager.getChatString(message.chatID); + } else { + message.peerID = message.out ? message.to_id.user_id : message.from_id; + message.peerData = AppUsersManager.getUser(message.peerID); + message.peerString = AppUsersManager.getUserString(message.peerID); + } + + message.peerPhoto = AppPeersManager.getPeerPhoto(message.peerID, 'User', 'Group'); + message.unreadCount = unreadCount; + + if (message._ == 'messageService' && message.action.user_id) { + message.action.user = AppUsersManager.getUser(message.action.user_id); + } + + if (message.message && message.message.length) { + message.richMessage = RichTextProcessor.wrapRichText(message.message.substr(0, 64), {noLinks: true, noLinebreaks: true}); + } + + + return message; + } + + function wrapForHistory (msgID) { + if (messagesForHistory[msgID] !== undefined) { + return messagesForHistory[msgID]; + } + + var message = angular.copy(messagesStorage[msgID]) || {id: msgID}; + + message.fromUser = AppUsersManager.getUser(message.from_id); + message.fromPhoto = AppUsersManager.getUserPhoto(message.from_id, 'User'); + + if (message.media) { + switch (message.media._) { + case 'messageMediaPhoto': + message.media.photo = AppPhotosManager.wrapForHistory(message.media.photo.id) + break; + + case 'messageMediaVideo': + message.media.video = AppVideoManager.wrapForHistory(message.media.video.id); + break; + } + + if (message.media.user_id) { + message.media.user = AppUsersManager.getUser(message.media.user_id); + message.media.userPhoto = AppUsersManager.getUserPhoto(message.media.user_id, 'User'); + } + } + else if (message.action) { + if (message.action._ == 'messageActionChatEditPhoto') { + message.action.photo = AppPhotosManager.wrapForHistory(message.action.photo.id); + } + + if (message.action.user_id) { + message.action.user = AppUsersManager.getUser(message.action.user_id); + message.action.userPhoto = AppUsersManager.getUserPhoto(message.action.user_id, 'User'); + } + } + + if (message.message && message.message.length) { + message.richMessage = RichTextProcessor.wrapRichText(message.message); + } + + return messagesForHistory[msgID] = message; + } + + function getDialogByPeerID (peerID) { + for (var i = 0; i < dialogsStorage.dialogs.length; i++) { + if (dialogsStorage.dialogs[i].peerID == peerID) { + return [dialogsStorage.dialogs[i], i]; + } + } + + return []; + } + + + $rootScope.$on('apiUpdate', function (e, update) { + dLog('on apiUpdate', update); + switch (update._) { + case 'updateNewMessage': + var message = update.message, + peerID = getMessagePeer(message), + historyStorage = historiesStorage[peerID]; + + if (historyStorage !== undefined) { + var topMsgID = historiesStorage[peerID].history[0]; + if (message.id <= topMsgID) { + return false; + } + } else { + historyStorage = historiesStorage[peerID] = {count: null, history: []}; + } + + saveMessages([message]); + + if (historyStorage.count !== null) { + historyStorage.count++; + } + historyStorage.history.unshift(message.id); + $rootScope.$broadcast('history_append', {peerID: peerID, messageID: message.id}); + + var foundDialog = getDialogByPeerID(peerID), + dialog; + + if (foundDialog.length) { + dialog = foundDialog[0]; + dialogsStorage.dialogs.splice(foundDialog[1], 1); + } else { + dialog = {peerID: peerID, unread_count: 0, top_message: false} + } + if (!message.out && message.unread) { + dialog.unread_count++; + } + dialog.top_message = message.id; + dialogsStorage.dialogs.unshift(dialog); + $rootScope.$broadcast('dialogs_update', dialog); + break; + + case 'updateReadMessages': + var dialogsUpdated = {}, + messageID, message, i, peerID, foundDialog, dialog; + for (i = 0; i < update.messages.length; i++) { + messageID = update.messages[i]; + message = messagesStorage[messageID]; + // dLog('read', messageID, message); + if (message) { + message.unread = false; + if (messagesForHistory[messageID]) { + messagesForHistory[messageID].unread = false; + } + peerID = getMessagePeer(message); + if (!message.out) { + foundDialog = getDialogByPeerID(peerID); + if (foundDialog) { + dialogsUpdated[peerID] = --foundDialog[0].unread_count; + } + } + } + } + + angular.forEach(dialogsUpdated, function(count, peerID) { + $rootScope.$broadcast('dialog_unread', {peerID: peerID, count: count}); + }); + break; + } + }); + + return { + getDialogs: getDialogs, + getHistory: getHistory, + readHistory: readHistory, + saveMessages: saveMessages, + getMessagePeer: getMessagePeer, + wrapForDialog: wrapForDialog, + wrapForHistory: wrapForHistory + } +}) + +.service('AppPhotosManager', function ($modal, $window, $rootScope, MtpApiFileManager, AppUsersManager) { + var photos = {}; + + function savePhoto (apiPhoto) { + photos[apiPhoto.id] = apiPhoto; + angular.forEach(apiPhoto.sizes, function (photoSize) { + if (photoSize._ == 'photoCachedSize') { + MtpApiFileManager.saveSmallFile(photoSize.location, photoSize.bytes); + + // Memory + photoSize.size = photoSize.bytes.length; + delete photoSize.bytes; + photoSize._ = 'photoSize'; + } + }); + }; + + function choosePhotoSize (photo, width, height) { + var bestPhotoSize = {_: 'photoSizeEmpty'}, + bestDiff = 0xFFFFFF; + + angular.forEach(photo.sizes, function (photoSize) { + var diff = Math.abs(photoSize.w * photoSize.h - width * height); + if (diff < bestDiff) { + bestPhotoSize = photoSize; + bestDiff = diff; + } + }); + + return bestPhotoSize; + } + + function wrapForHistory (photoID) { + var photo = angular.copy(photos[photoID]) || {_: 'photoEmpty'}, + width = 100, + height = 100, + thumbPhotoSize = choosePhotoSize(photo, width, height), + thumb = { + placeholder: 'img/placeholders/PhotoThumbConversation.jpg', + width: width, + height: height + }; + + // dLog('chosen photo size', photoID, thumbPhotoSize); + if (thumbPhotoSize && thumbPhotoSize._ != 'photoSizeEmpty') { + if (thumbPhotoSize.w > thumbPhotoSize.h) { + thumb.height = parseInt(thumbPhotoSize.h * width / thumbPhotoSize.w); + } else { + thumb.width = parseInt(thumbPhotoSize.w * height / thumbPhotoSize.h); + } + + thumb.location = thumbPhotoSize.location; + thumb.size = thumbPhotoSize.size; + } + + photo.thumb = thumb; + + return photo; + } + + function wrapForFull (photoID) { + var photo = wrapForHistory(photoID), + fullWidth = 542, + fullHeight = $($window).height() - 150, + fullPhotoSize = choosePhotoSize(photo, fullWidth, fullHeight), + full = { + placeholder: 'img/placeholders/PhotoThumbModal.jpg', + width: fullWidth, + height: fullHeight + }; + + if (fullPhotoSize && fullPhotoSize._ != 'photoSizeEmpty') { + if (fullPhotoSize.w > fullPhotoSize.h) { + full.height = parseInt(fullPhotoSize.h * fullWidth / fullPhotoSize.w); + } else { + full.width = parseInt(fullPhotoSize.w * fullHeight / fullPhotoSize.h); + if (full.width > fullWidth) { + full.height = parseInt(full.height * fullWidth / full.width); + full.width = fullWidth; + } + } + + full.location = fullPhotoSize.location; + full.size = fullPhotoSize.size; + } + + photo.full = full; + photo.fromUser = AppUsersManager.getUser(photo.user_id); + + return photo; + } + + function openPhoto (photoID, accessHash) { + var scope = $rootScope.$new(true); + scope.photoID = photoID; + + var modalInstance = $modal.open({ + templateUrl: 'partials/photo_modal.html', + controller: 'PhotoModalController', + scope: scope, + backdrop: 'static' + }); + } + + $rootScope.openPhoto = openPhoto; + + + return { + savePhoto: savePhoto, + wrapForHistory: wrapForHistory, + wrapForFull: wrapForFull, + openPhoto: openPhoto + } +}) + + +.service('AppVideoManager', function ($rootScope, $modal, $window, MtpApiFileManager, AppUsersManager) { + var videos = {}; + + function saveVideo (apiVideo) { + videos[apiVideo.id] = apiVideo; + + if (apiVideo.thumb && apiVideo.thumb._ == 'photoCachedSize') { + MtpApiFileManager.saveSmallFile(apiVideo.thumb.location, apiVideo.thumb.bytes); + + // Memory + apiVideo.thumb.size = apiVideo.thumb.bytes.length; + delete apiVideo.thumb.bytes; + apiVideo.thumb._ = 'photoSize'; + } + }; + + function wrapForHistory (videoID) { + var video = angular.copy(videos[videoID]), + width = 100, + height = 100, + thumbPhotoSize = video.thumb, + thumb = { + placeholder: 'img/placeholders/VideoThumbConversation.jpg', + width: width, + height: height + }; + + if (thumbPhotoSize && thumbPhotoSize._ != 'photoSizeEmpty') { + if (thumbPhotoSize.w > thumbPhotoSize.h) { + thumb.height = parseInt(thumbPhotoSize.h * width / thumbPhotoSize.w); + } else { + thumb.width = parseInt(thumbPhotoSize.w * height / thumbPhotoSize.h); + } + + thumb.location = thumbPhotoSize.location; + thumb.size = thumbPhotoSize.size; + } + + video.thumb = thumb; + + return video; + } + + function wrapForFull (videoID) { + var video = wrapForHistory(videoID), + fullWidth = 542, + fullHeight = $($window).height() - 150, + fullPhotoSize = video, + full = { + placeholder: 'img/placeholders/VideoThumbModal.jpg', + width: fullWidth, + height: fullHeight, + }; + + if (video.w > video.h) { + full.height = parseInt(video.h * fullWidth / video.w); + } else { + full.width = parseInt(video.w * fullHeight / video.h); + if (full.width > fullWidth) { + full.height = parseInt(full.height * fullWidth / full.width); + full.width = fullWidth; + } + } + + video.full = full; + video.fromUser = AppUsersManager.getUser(video.user_id); + + return video; + } + + function openVideo (videoID, accessHash) { + var scope = $rootScope.$new(true); + scope.videoID = videoID; + scope.progress = {enabled: false}; + scope.player = {}; + scope.close = function () { + modalInstance.close(); + } + + var modalInstance = $modal.open({ + templateUrl: 'partials/video_modal.html', + controller: 'VideoModalController', + scope: scope + }); + } + + $rootScope.openVideo = openVideo; + + return { + saveVideo: saveVideo, + wrapForHistory: wrapForHistory, + wrapForFull: wrapForFull, + openVideo: openVideo + } +}) + +.service('AppDocsManager', function ($rootScope, $modal, $window, $timeout, MtpApiFileManager, AppUsersManager) { + var docs = {}; + + function saveDoc (apiDoc) { + docs[apiDoc.id] = apiDoc; + + if (apiDoc.thumb && apiDoc.thumb._ == 'photoCachedSize') { + MtpApiFileManager.saveSmallFile(apiDoc.thumb.location, apiDoc.thumb.bytes); + + // Memory + apiDoc.thumb.size = apiDoc.thumb.bytes.length; + delete apiDoc.thumb.bytes; + apiDoc.thumb._ = 'photoSize'; + } + }; + + function wrapForHistory (docID) { + var doc = angular.copy(docs[docID]), + width = 100, + height = 100, + thumbPhotoSize = doc.thumb, + thumb = { + placeholder: 'img/placeholders/DocThumbConversation.jpg', + width: width, + height: height + }; + + if (thumbPhotoSize && thumbPhotoSize._ != 'photoSizeEmpty') { + if (thumbPhotoSize.w > thumbPhotoSize.h) { + thumb.height = parseInt(thumbPhotoSize.h * width / thumbPhotoSize.w); + } else { + thumb.width = parseInt(thumbPhotoSize.w * height / thumbPhotoSize.h); + } + + thumb.location = thumbPhotoSize.location; + thumb.size = thumbPhotoSize.size; + } + + doc.thumb = thumb; + + return doc; + } + + function openDoc (docID, accessHash) { + var doc = docs[docID], + inputFileLocation = { + _: 'inputDocumentFileLocation', + id: docID, + access_hash: accessHash || doc.access_hash + }, + scope = {}; + + scope.progress = {enabled: true, percent: 1}; + + + if (window.chrome && chrome.fileSystem && chrome.fileSystem.chooseEntry) { + var ext = (doc.file_name.split('.', 2) || [])[1] || '', + mime = doc.mime_type; + chrome.fileSystem.chooseEntry({ + type: 'saveFile', + suggestedName: doc.file_name, + accepts: [{ + mimeTypes: [mime], + extensions: [ext] + }] + }, function (writableFileEntry) { + MtpApiFileManager.downloadFile(doc.dc_id, inputFileLocation, doc.size, writableFileEntry).then(function (url) { + dLog('file save done'); + }); + + }); + } else { + MtpApiFileManager.downloadFile(doc.dc_id, inputFileLocation, doc.size).then(function (url) { + scope.progress.enabled = false; + + var a = $('Download').attr('href', url).attr('target', '_blank').attr('download', doc.file_name).appendTo('body'); + a[0].dataset.downloadurl = ['png', doc.file_name, url].join(':'); + a[0].click(); + $timeout(function () { + a.remove(); + }, 100); + }, function (e) { + dLog('document download failed', e); + }, function (progress) { + scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); + }); + } + } + + $rootScope.openDoc = openDoc; + + return { + saveDoc: saveDoc, + wrapForHistory: wrapForHistory, + openDoc: openDoc + } +}) + +.service('ExternalResourcesManager', function ($q, $http) { + var urlPromises = {}; + + function downloadImage (url) { + if (urlPromises[url] !== undefined) { + return urlPromises[url]; + } + + var deferred = $q.defer(); + + $http.get(url, {responseType: 'blob', transformRequest: null}) + .then( + function (response) { + deferred.resolve(window.webkitURL.createObjectURL(response.data)); + }, function (error) { + deferred.reject(error); + } + ); + + return urlPromises[url] = deferred.promise; + } + + return { + downloadImage: downloadImage + } +}) + + +.service('ApiUpdatesManager', function ($rootScope, MtpNetworkerFactory, AppUsersManager, AppChatsManager, AppPeersManager, MtpApiManager) { + + var curState = {invalid: true}; + + function processUpdateMessage (updateMessage) { + if (curState.invalid) { + return false; + } + + if (updateMessage.seq) { + if (!saveSeq(updateMessage.seq, updateMessage.seq_start)) { + return false; + } + if (updateMessage.date) { + curState.date = updateMessage.date; + } + } + + + switch (updateMessage._) { + case 'updatesTooLong': + getDifference(); + break; + + case 'updateShort': + saveUpdate(updateMessage.update); + break; + + case 'updatesCombined': + case 'updates': + AppUsersManager.saveApiUsers(updateMessage.users); + AppChatsManager.saveApiChats(updateMessage.chats); + + angular.forEach(updateMessage.updates, function (update) { + saveUpdate(update); + }); + break; + + case 'updateShortMessage': + var fromUser = AppUsersManager.getUser(updateMessage.from_id); + if (!fromUser || fromUser.deleted) { + getDifference(); + break; + } + saveUpdate({ + _: 'updateNewMessage', + message: { + _: 'message', + id: updateMessage.id, + from_id: updateMessage.from_id, + to_id: AppPeersManager.getOutputPeer(MtpApiManager.getUserID()), + out: false, + unread: true, + date: updateMessage.date, + message: updateMessage.message, + media: {_: 'messageMediaEmpty'} + }, + pts: updateMessage.pts + }); + break; + + case 'updateShortChatMessage': + var fromUser = AppUsersManager.getUser(updateMessage.from_id), + chat = AppChatsManager.getChat(updateMessage.chat_id); + + if (!fromUser || fromUser.deleted || !chat || chat.deleted) { + getDifference(); + break; + } + saveUpdate({ + _: 'updateNewMessage', + message: { + _: 'message', + id: updateMessage.id, + from_id: updateMessage.from_id, + to_id: AppPeersManager.getOutputPeer(-updateMessage.chat_id), + out: false, + unread: true, + date: updateMessage.date, + message: updateMessage.message, + media: {_: 'messageMediaEmpty'} + }, + pts: updateMessage.pts + }); + break; + } + } + + function getDifference (force) { + if (curState.invalid && !force) { + return false; + } + + curState.invalid = true; + MtpApiManager.invokeApi('updates.getDifference', {pts: curState.pts, date: curState.date, qts: 0}).then(function (differenceResult) { + if (differenceResult._ == 'updates.differenceEmpty') { + curState.date = differenceResult.date; + curState.seq = differenceResult.seq; + delete curState.invalid; + return false; + } + + AppUsersManager.saveApiUsers(differenceResult.users); + AppChatsManager.saveApiChats(differenceResult.chats); + + angular.forEach(differenceResult.new_messages, function (apiMessage) { + saveUpdate({ + _: 'updateNewMessage', + message: apiMessage, + pts: curState.pts + }, true); + }); + + angular.forEach(differenceResult.other_updates, function(update){ + saveUpdate(update, true); + }); + + var nextState = differenceResult.intermediate_state || differenceResult.state; + curState.seq = nextState.seq; + curState.pts = nextState.pts; + curState.date = nextState.date; + + if (differenceResult._ == 'updates.differenceSlice') { + getDifference(true); + } else { + delete curState.invalid; + } + }); + } + + function saveUpdate (update, force) { + if (curState.invalid && !force) { + return false; + } + if (update.pts) { + curState.pts = update.pts; + } + + $rootScope.$broadcast('apiUpdate', update); + } + + function saveSeq (seq, seqStart) { + // dLog('saving seq', curState.invalid, seq, seqStart, curState.seq); + + if (curState.invalid) { + return false; + } + + seqStart = seqStart || seq; + + if (seqStart != curState.seq + 1) { + // dLog('seq hole', seqStart, curState.seq); + if (seqStart != curState.seq) { + getDifference(); + } + return false; + } + + curState.seq = seq; + + return true; + } + + function attach () { + MtpNetworkerFactory.setUpdatesProcessor(processUpdateMessage); + MtpApiManager.invokeApi('updates.getState').then(function (stateResult) { + curState.seq = stateResult.seq; + curState.pts = stateResult.pts; + curState.date = stateResult.date; + delete curState.invalid; + }) + } + + + return { + saveUpdate: saveUpdate, + saveSeq: saveSeq, + attach: attach + } +}) + +.service('RichTextProcessor', function ($sce, $sanitize) { + + var emojiUtf = [], + emojiMap = {}, + emojiData = Config.Emoji, + emojiCode; + + for (emojiCode in emojiData) { + emojiUtf.push(emojiData[emojiCode][0]); + emojiMap[emojiData[emojiCode][0]] = emojiCode; + } + + var regExp = new RegExp('((?:(ftp|https?)://|(?:mailto:)?([A-Za-z0-9._%+-]+@))(\\S*\\.\\S*[^\\s.;,(){}<>"\']))|(\\n)|(' + emojiUtf.join('|') + ')', 'i'); + + // dLog(regExp); + + + return { + wrapRichText: wrapRichText + }; + + function encodeEntities(value) { + return value. + replace(/&/g, '&'). + replace(/([^\#-~| |!])/g, function (value) { // non-alphanumeric + return '&#' + value.charCodeAt(0) + ';'; + }). + replace(//g, '>'); + }; + + + function wrapRichText(text, options) { + if (!text || !text.length) { + return ''; + } + + options = options || {}; + + text = text.replace(/\ufe0f/g, '', text); + + var match, + raw = text, + html = [], + url, + emojiTitle, + emojiFound = false; + + + while ((match = raw.match(regExp))) { + // dLog(2, match); + html.push(encodeEntities(raw.substr(0, match.index))); + + if (match[1]) { // URL + if (!options.noLinks) { + if (match[3]) { + html.push( + '', + encodeEntities(match[3] + match[4]), + '' + ); + } else { + html.push( + '', + encodeEntities((match[2] != 'http' ? match[2] + '://' : '') + match[4]), + '' + ); + } + } else { + html.push(encodeEntities(match[0])); + } + } + else if (match[5]) { // New line + if (!options.noLinebreaks) { + html.push('
'); + } else { + html.push(' '); + } + } + else if (match[6]) { + + if (emojiCode = emojiMap[match[6]]) { + emojiFound = true; + emojiTitle = encodeEntities(emojiData[emojiCode][1][0]); + html.push( + ':', + emojiTitle, + ':' + ); + } else { + html.push(encodeEntities(match[6])); + } + } + raw = raw.substr(match.index + match[0].length); + } + + html.push(encodeEntities(raw)); + + text = $sanitize(html.join('')); + + // dLog(3, text, html); + + if (emojiFound) { + text = text.replace(//g, + ''); + } + + // dLog(4, text, html); + + return $sce.trustAs('html', text); + } + +}) diff --git a/js/util.js b/js/util.js new file mode 100644 index 00000000..e65c18d5 --- /dev/null +++ b/js/util.js @@ -0,0 +1,55 @@ +/*! + * Webogram v0.1 - messaging web application for MTProto + * https://github.com/zhukov/webogram + * Copyright (C) 2014 Igor Zhukov + * https://github.com/zhukov/webogram/blob/master/LICENSE + */ + +function checkClick (e, noprevent) { + if (e.which == 1 && (e.ctrlKey || e.metaKey) || e.which == 2) { + return true; + } + + if (!noprevent) { + e.preventDefault(); + } + + return false; +} + +function checkDragEvent(e) { + if (!e || e.target && (e.target.tagName == 'IMG' || e.target.tagName == 'A')) return false; + if (e.dataTransfer && e.dataTransfer.types) { + for (var i = 0; i < e.dataTransfer.types.length; i++) { + if (e.dataTransfer.types[i] == 'Files') { + return true; + } + } + } else { + return true; + } + + return false; +} + +function cancelEvent (event) { + event = event || window.event; + + event.stopPropagation && event.stopPropagation(); + event.preventDefault && event.preventDefault(); + + return false; +} + +function onCtrlEnter (textarea, cb) { + $(textarea).on('keydown', function (e) { + if (e.keyCode == 13 && (e.ctrlKey || e.metaKey)) { + cb(); + return cancelEvent(e); + } + }); +} + +function onContentLoaded (cb) { + setTimeout(cb, 0); +}; \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 00000000..7a13a6bb --- /dev/null +++ b/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "Telegram UNOFFICIAL", + "version": "0.0.9", + "short_name": "Webogram", + "manifest_version": 2, + "app": { + "background": { + "scripts": ["vendor/angular/angular.js", "js/background.js"] + } + }, + "permissions": [ + "webview", + {"fileSystem": ["write"]}, + "storage" + ], + "icons": { "16": "img/icons/icon16.png", + "128": "img/icons/icon128.png" } +} \ No newline at end of file diff --git a/partials/chat_modal.html b/partials/chat_modal.html new file mode 100644 index 00000000..60855a4d --- /dev/null +++ b/partials/chat_modal.html @@ -0,0 +1,41 @@ +
+ + + + + +
\ No newline at end of file diff --git a/partials/dialog.html b/partials/dialog.html new file mode 100644 index 00000000..e81014e9 --- /dev/null +++ b/partials/dialog.html @@ -0,0 +1,73 @@ + + +
+
+ {{dialogMessage.date | dateOrTime}} +
+ + {{dialogMessage.unreadCount}} + +
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ + You{{((dialogMessage.out || dialogMessage.peerID < 0) && (dialogMessage.message.length || dialogMessage.media && dialogMessage.media._ != 'messageMediaEmpty')) ? ':' : ''}} + + + + + Photo + + + Video + + + Document + + + Location + + + Contact + + + + + + created the group + + + changed group name + + + changed group photo + + + removed group photo + + + invited + + + kicked + + + + +
+ +
+
diff --git a/partials/head.html b/partials/head.html new file mode 100644 index 00000000..66c5f874 --- /dev/null +++ b/partials/head.html @@ -0,0 +1,17 @@ +
+ +
\ No newline at end of file diff --git a/partials/im.html b/partials/im.html new file mode 100644 index 00000000..c9bf9224 --- /dev/null +++ b/partials/im.html @@ -0,0 +1,118 @@ +
+ +
+ +
+ +
+ +
+
+
+ +
+
+
+
+ +
+
No history to display
+ +
+
+ +
+ +
+
+ +
+

+ + + + + + +

+
+ +
+

+ + + {{historyPeer.data | userStatus}} +

+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+ +
+
+ is typing.. +
+
+ +
+ +
+ +
+ +
+
+ + +
+
+ +
+
+ +
+
+
Drop photos here to send
+ + +
+ +
+ +
+ + +
+ + +
+
+ +
+
+ +
+ +
+ + +
+ diff --git a/partials/login.html b/partials/login.html new file mode 100644 index 00000000..0b616d4c --- /dev/null +++ b/partials/login.html @@ -0,0 +1,28 @@ +
+ + + \ No newline at end of file diff --git a/partials/message.html b/partials/message.html new file mode 100644 index 00000000..b5b832f4 --- /dev/null +++ b/partials/message.html @@ -0,0 +1,91 @@ +
+ +
+
+ + + + + + created the group «{{historyMessage.action.title}}» + + + changed group name to «{{historyMessage.action.title}}» + + + changed group photo + + + removed group photo + + + invited + + + kicked + + + + unsupported action {{historyMessage.action}} + + + +
+ + + + + +
+ +
+ + + + +
+ + {{historyMessage.date | dateOrTime}} +
+ +
+ +
+ +
+ + + + + + + +
+ {{historyMessage.media.video.duration | duration}} + +
+
+ + + +
{{historyMessage.media.document.file_name}} {{historyMessage.media.document.size | formatSize}}
+
+ + + + + +
+ + + +
{{historyMessage.media.first_name}} {{historyMessage.media.last_name}}
+
{{historyMessage.media.phone_number}}
+
+
+ +
+
+ +
+
diff --git a/partials/photo_modal.html b/partials/photo_modal.html new file mode 100644 index 00000000..02876897 --- /dev/null +++ b/partials/photo_modal.html @@ -0,0 +1,11 @@ +
+ + + +
\ No newline at end of file diff --git a/partials/user_modal.html b/partials/user_modal.html new file mode 100644 index 00000000..543c9d3c --- /dev/null +++ b/partials/user_modal.html @@ -0,0 +1,25 @@ +
+ + + + + + +
\ No newline at end of file diff --git a/partials/video_modal.html b/partials/video_modal.html new file mode 100644 index 00000000..3916660c --- /dev/null +++ b/partials/video_modal.html @@ -0,0 +1,11 @@ +
+ + + +
\ No newline at end of file diff --git a/partials/welcome.html b/partials/welcome.html new file mode 100644 index 00000000..7396c588 --- /dev/null +++ b/partials/welcome.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/vendor/README.md b/vendor/README.md new file mode 100644 index 00000000..25961dac --- /dev/null +++ b/vendor/README.md @@ -0,0 +1,81 @@ +## Third party libraries + +### [AngularJS](http://angularjs.org/) + +**Author**: Google, Inc. +**License**: MIT, https://github.com/angular/angular.js/blob/master/LICENSE + +### [JSBN](http://www-cs-students.stanford.edu/~tjw/jsbn/) + +**Author**: Tom Wu +**License**: BSD, http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + +Biginteger for RSA, PQ prime factorization + + +### [jQuery Emojiarea](https://github.com/diy/jquery-emojiarea) + +**Author**: diy +**License**: Apache, Version 2.0, https://github.com/diy/jquery-emojiarea#license + +Emoji keyboard and rich-textfield for composing messages with emoticons + + +### [UI Bootstrap](http://angular-ui.github.io/bootstrap/) + +**Author**: AngularUI Team, https://github.com/organizations/angular-ui/teams/291112 +**License**: MIT, https://github.com/angular-ui/bootstrap/blob/master/LICENSE + +Modal windows + + +### [jQuery](https://github.com/jquery/jquery) + +**Author**: jQuery Foundation and other contributors +**License**: MIT, https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt + +Dom manupulations. + +### [Bootstrap](https://github.com/twbs/bootstrap) + +**Author**: Twitter, Inc +**License**: MIT, https://github.com/twbs/bootstrap/blob/master/LICENSE + +Normalize, CSS-framework + +### [nanoScrollerJS](https://github.com/jamesflorentino/nanoScrollerJS) + +**Author**: James Florentino +**License**: MIT, https://github.com/jamesflorentino/nanoScrollerJS/blob/master/LICENSE-MIT + +Beautiful OS X Lion-like scrollbars + + +### [CryptoJS](https://code.google.com/p/crypto-js/) + +**Author**: Jeff Mott +**License**: BSD-3-Clause, https://code.google.com/p/crypto-js/wiki/License + +AES, SHA-1 implementation + +### [zlib.js](https://github.com/imaya/zlib.js) + +**Author**: imaya +**License**: MIT, https://github.com/imaya/zlib.js/blob/master/LICENSE + +GZIP for decompressing server responses + +### [emoji-data](https://github.com/iamcal/emoji-data) + +**Author**: iamcal +**License**: not specified + +Build emoji list in apropriate format. Generate sheet in future, when needed. + + +### [gemoji](https://github.com/github/gemoji) + +**Author**: GitHub Inc, 37signals, id Software, whynne@deviantart, Apple Inc. +**License**: https://github.com/github/gemoji/blob/master/LICENSE + +Emoji images \ No newline at end of file diff --git a/vendor/angular/angular-animate.js b/vendor/angular/angular-animate.js new file mode 100644 index 00000000..ce9a2d47 --- /dev/null +++ b/vendor/angular/angular-animate.js @@ -0,0 +1,1294 @@ +/** + * @license AngularJS v1.2.3 + * (c) 2010-2014 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +/* jshint maxlen: false */ + +/** + * @ngdoc overview + * @name ngAnimate + * @description + * + * # ngAnimate + * + * The `ngAnimate` module provides support for JavaScript, CSS3 transition and CSS3 keyframe animation hooks within existing core and custom directives. + * + * {@installModule animate} + * + *
+ * + * # Usage + * + * To see animations in action, all that is required is to define the appropriate CSS classes + * or to register a JavaScript animation via the myModule.animation() function. The directives that support animation automatically are: + * `ngRepeat`, `ngInclude`, `ngIf`, `ngSwitch`, `ngShow`, `ngHide`, `ngView` and `ngClass`. Custom directives can take advantage of animation + * by using the `$animate` service. + * + * Below is a more detailed breakdown of the supported animation events provided by pre-existing ng directives: + * + * | Directive | Supported Animations | + * |---------------------------------------------------------- |----------------------------------------------------| + * | {@link ng.directive:ngRepeat#usage_animations ngRepeat} | enter, leave and move | + * | {@link ngRoute.directive:ngView#usage_animations ngView} | enter and leave | + * | {@link ng.directive:ngInclude#usage_animations ngInclude} | enter and leave | + * | {@link ng.directive:ngSwitch#usage_animations ngSwitch} | enter and leave | + * | {@link ng.directive:ngIf#usage_animations ngIf} | enter and leave | + * | {@link ng.directive:ngClass#usage_animations ngClass} | add and remove | + * | {@link ng.directive:ngShow#usage_animations ngShow & ngHide} | add and remove (the ng-hide class value) | + * + * You can find out more information about animations upon visiting each directive page. + * + * Below is an example of how to apply animations to a directive that supports animation hooks: + * + *
+ * 
+ *
+ * 
+ * 
+ * 
+ * + * Keep in mind that if an animation is running, any child elements cannot be animated until the parent element's + * animation has completed. + * + *

CSS-defined Animations

+ * The animate service will automatically apply two CSS classes to the animated element and these two CSS classes + * are designed to contain the start and end CSS styling. Both CSS transitions and keyframe animations are supported + * and can be used to play along with this naming structure. + * + * The following code below demonstrates how to perform animations using **CSS transitions** with Angular: + * + *
+ * 
+ *
+ * 
+ *
+ *
+ *
+ * + * The following code below demonstrates how to perform animations using **CSS animations** with Angular: + * + *
+ * 
+ *
+ * 
+ *
+ *
+ *
+ * + * Both CSS3 animations and transitions can be used together and the animate service will figure out the correct duration and delay timing. + * + * Upon DOM mutation, the event class is added first (something like `ng-enter`), then the browser prepares itself to add + * the active class (in this case `ng-enter-active`) which then triggers the animation. The animation module will automatically + * detect the CSS code to determine when the animation ends. Once the animation is over then both CSS classes will be + * removed from the DOM. If a browser does not support CSS transitions or CSS animations then the animation will start and end + * immediately resulting in a DOM element that is at its final state. This final state is when the DOM element + * has no CSS transition/animation classes applied to it. + * + *

CSS Staggering Animations

+ * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a + * curtain-like effect. The ngAnimate module, as of 1.2.0, supports staggering animations and the stagger effect can be + * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for + * the animation. The style property expected within the stagger class can either be a **transition-delay** or an + * **animation-delay** property (or both if your animation contains both transitions and keyframe animations). + * + *
+ * .my-animation.ng-enter {
+ *   /* standard transition code */
+ *   -webkit-transition: 1s linear all;
+ *   transition: 1s linear all;
+ *   opacity:0;
+ * }
+ * .my-animation.ng-enter-stagger {
+ *   /* this will have a 100ms delay between each successive leave animation */
+ *   -webkit-transition-delay: 0.1s;
+ *   transition-delay: 0.1s;
+ *
+ *   /* in case the stagger doesn't work then these two values
+ *    must be set to 0 to avoid an accidental CSS inheritance */
+ *   -webkit-transition-duration: 0s;
+ *   transition-duration: 0s;
+ * }
+ * .my-animation.ng-enter.ng-enter-active {
+ *   /* standard transition styles */
+ *   opacity:1;
+ * }
+ * 
+ * + * Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations + * on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this + * are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation + * will also be reset if more than 10ms has passed after the last animation has been fired. + * + * The following code will issue the **ng-leave-stagger** event on the element provided: + * + *
+ * var kids = parent.children();
+ *
+ * $animate.leave(kids[0]); //stagger index=0
+ * $animate.leave(kids[1]); //stagger index=1
+ * $animate.leave(kids[2]); //stagger index=2
+ * $animate.leave(kids[3]); //stagger index=3
+ * $animate.leave(kids[4]); //stagger index=4
+ *
+ * $timeout(function() {
+ *   //stagger has reset itself
+ *   $animate.leave(kids[5]); //stagger index=0
+ *   $animate.leave(kids[6]); //stagger index=1
+ * }, 100, false);
+ * 
+ * + * Stagger animations are currently only supported within CSS-defined animations. + * + *

JavaScript-defined Animations

+ * In the event that you do not want to use CSS3 transitions or CSS3 animations or if you wish to offer animations on browsers that do not + * yet support CSS transitions/animations, then you can make use of JavaScript animations defined inside of your AngularJS module. + * + *
+ * //!annotate="YourApp" Your AngularJS Module|Replace this or ngModule with the module that you used to define your application.
+ * var ngModule = angular.module('YourApp', []);
+ * ngModule.animation('.my-crazy-animation', function() {
+ *   return {
+ *     enter: function(element, done) {
+ *       //run the animation here and call done when the animation is complete
+ *       return function(cancelled) {
+ *         //this (optional) function will be called when the animation
+ *         //completes or when the animation is cancelled (the cancelled
+ *         //flag will be set to true if cancelled).
+ *       }
+ *     }
+ *     leave: function(element, done) { },
+ *     move: function(element, done) { },
+ *
+ *     //animation that can be triggered before the class is added
+ *     beforeAddClass: function(element, className, done) { },
+ *
+ *     //animation that can be triggered after the class is added
+ *     addClass: function(element, className, done) { },
+ *
+ *     //animation that can be triggered before the class is removed
+ *     beforeRemoveClass: function(element, className, done) { },
+ *
+ *     //animation that can be triggered after the class is removed
+ *     removeClass: function(element, className, done) { }
+ *   }
+ * });
+ * 
+ * + * JavaScript-defined animations are created with a CSS-like class selector and a collection of events which are set to run + * a javascript callback function. When an animation is triggered, $animate will look for a matching animation which fits + * the element's CSS class attribute value and then run the matching animation event function (if found). + * In other words, if the CSS classes present on the animated element match any of the JavaScript animations then the callback function will + * be executed. It should be also noted that only simple, single class selectors are allowed (compound class selectors are not supported). + * + * Within a JavaScript animation, an object containing various event callback animation functions is expected to be returned. + * As explained above, these callbacks are triggered based on the animation event. Therefore if an enter animation is run, + * and the JavaScript animation is found, then the enter callback will handle that animation (in addition to the CSS keyframe animation + * or transition code that is defined via a stylesheet). + * + */ + +angular.module('ngAnimate', ['ng']) + + /** + * @ngdoc object + * @name ngAnimate.$animateProvider + * @description + * + * The `$animateProvider` allows developers to register JavaScript animation event handlers directly inside of a module. + * When an animation is triggered, the $animate service will query the $animate service to find any animations that match + * the provided name value. + * + * Requires the {@link ngAnimate `ngAnimate`} module to be installed. + * + * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application. + * + */ + .config(['$provide', '$animateProvider', function($provide, $animateProvider) { + var noop = angular.noop; + var forEach = angular.forEach; + var selectors = $animateProvider.$$selectors; + + var ELEMENT_NODE = 1; + var NG_ANIMATE_STATE = '$$ngAnimateState'; + var NG_ANIMATE_CLASS_NAME = 'ng-animate'; + var rootAnimateState = {running: true}; + + $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$timeout', '$rootScope', '$document', + function($delegate, $injector, $sniffer, $rootElement, $timeout, $rootScope, $document) { + + $rootElement.data(NG_ANIMATE_STATE, rootAnimateState); + + // disable animations during bootstrap, but once we bootstrapped, wait again + // for another digest until enabling animations. The reason why we digest twice + // is because all structural animations (enter, leave and move) all perform a + // post digest operation before animating. If we only wait for a single digest + // to pass then the structural animation would render its animation on page load. + // (which is what we're trying to avoid when the application first boots up.) + $rootScope.$$postDigest(function() { + $rootScope.$$postDigest(function() { + rootAnimateState.running = false; + }); + }); + + function lookup(name) { + if (name) { + var matches = [], + flagMap = {}, + classes = name.substr(1).split('.'); + + //the empty string value is the default animation + //operation which performs CSS transition and keyframe + //animations sniffing. This is always included for each + //element animation procedure if the browser supports + //transitions and/or keyframe animations + if ($sniffer.transitions || $sniffer.animations) { + classes.push(''); + } + + for(var i=0; i < classes.length; i++) { + var klass = classes[i], + selectorFactoryName = selectors[klass]; + if(selectorFactoryName && !flagMap[klass]) { + matches.push($injector.get(selectorFactoryName)); + flagMap[klass] = true; + } + } + return matches; + } + } + + /** + * @ngdoc object + * @name ngAnimate.$animate + * @function + * + * @description + * The `$animate` service provides animation detection support while performing DOM operations (enter, leave and move) as well as during addClass and removeClass operations. + * When any of these operations are run, the $animate service + * will examine any JavaScript-defined animations (which are defined by using the $animateProvider provider object) + * as well as any CSS-defined animations against the CSS classes present on the element once the DOM operation is run. + * + * The `$animate` service is used behind the scenes with pre-existing directives and animation with these directives + * will work out of the box without any extra configuration. + * + * Requires the {@link ngAnimate `ngAnimate`} module to be installed. + * + * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application. + * + */ + return { + /** + * @ngdoc function + * @name ngAnimate.$animate#enter + * @methodOf ngAnimate.$animate + * @function + * + * @description + * Appends the element to the parentElement element that resides in the document and then runs the enter animation. Once + * the animation is started, the following CSS classes will be present on the element for the duration of the animation: + * + * Below is a breakdown of each step that occurs during enter animation: + * + * | Animation Step | What the element class attribute looks like | + * |----------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.enter(...) is called | class="my-animation" | + * | 2. element is inserted into the parentElement element or beside the afterElement element | class="my-animation" | + * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" | + * | 4. the .ng-enter class is added to the element | class="my-animation ng-animate ng-enter" | + * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-enter" | + * | 6. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-enter" | + * | 7. the .ng-enter-active and .ng-animate-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-enter ng-enter-active" | + * | 8. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-enter ng-enter-active" | + * | 9. The animation ends and all generated CSS classes are removed from the element | class="my-animation" | + * | 10. The doneCallback() callback is fired (if provided) | class="my-animation" | + * + * @param {jQuery/jqLite element} element the element that will be the focus of the enter animation + * @param {jQuery/jqLite element} parentElement the parent element of the element that will be the focus of the enter animation + * @param {jQuery/jqLite element} afterElement the sibling element (which is the previous element) of the element that will be the focus of the enter animation + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + enter : function(element, parentElement, afterElement, doneCallback) { + this.enabled(false, element); + $delegate.enter(element, parentElement, afterElement); + $rootScope.$$postDigest(function() { + performAnimation('enter', 'ng-enter', element, parentElement, afterElement, noop, doneCallback); + }); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#leave + * @methodOf ngAnimate.$animate + * @function + * + * @description + * Runs the leave animation operation and, upon completion, removes the element from the DOM. Once + * the animation is started, the following CSS classes will be added for the duration of the animation: + * + * Below is a breakdown of each step that occurs during enter animation: + * + * | Animation Step | What the element class attribute looks like | + * |----------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.leave(...) is called | class="my-animation" | + * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" | + * | 3. the .ng-leave class is added to the element | class="my-animation ng-animate ng-leave" | + * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-leave" | + * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-leave" | + * | 6. the .ng-leave-active and .ng-animate-active classes is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-leave ng-leave-active" | + * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-leave ng-leave-active" | + * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" | + * | 9. The element is removed from the DOM | ... | + * | 10. The doneCallback() callback is fired (if provided) | ... | + * + * @param {jQuery/jqLite element} element the element that will be the focus of the leave animation + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + leave : function(element, doneCallback) { + cancelChildAnimations(element); + this.enabled(false, element); + $rootScope.$$postDigest(function() { + performAnimation('leave', 'ng-leave', element, null, null, function() { + $delegate.leave(element); + }, doneCallback); + }); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#move + * @methodOf ngAnimate.$animate + * @function + * + * @description + * Fires the move DOM operation. Just before the animation starts, the animate service will either append it into the parentElement container or + * add the element directly after the afterElement element if present. Then the move animation will be run. Once + * the animation is started, the following CSS classes will be added for the duration of the animation: + * + * Below is a breakdown of each step that occurs during move animation: + * + * | Animation Step | What the element class attribute looks like | + * |----------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.move(...) is called | class="my-animation" | + * | 2. element is moved into the parentElement element or beside the afterElement element | class="my-animation" | + * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" | + * | 4. the .ng-move class is added to the element | class="my-animation ng-animate ng-move" | + * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-move" | + * | 6. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-move" | + * | 7. the .ng-move-active and .ng-animate-active classes is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-move ng-move-active" | + * | 8. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-move ng-move-active" | + * | 9. The animation ends and all generated CSS classes are removed from the element | class="my-animation" | + * | 10. The doneCallback() callback is fired (if provided) | class="my-animation" | + * + * @param {jQuery/jqLite element} element the element that will be the focus of the move animation + * @param {jQuery/jqLite element} parentElement the parentElement element of the element that will be the focus of the move animation + * @param {jQuery/jqLite element} afterElement the sibling element (which is the previous element) of the element that will be the focus of the move animation + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + move : function(element, parentElement, afterElement, doneCallback) { + cancelChildAnimations(element); + this.enabled(false, element); + $delegate.move(element, parentElement, afterElement); + $rootScope.$$postDigest(function() { + performAnimation('move', 'ng-move', element, parentElement, afterElement, noop, doneCallback); + }); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#addClass + * @methodOf ngAnimate.$animate + * + * @description + * Triggers a custom animation event based off the className variable and then attaches the className value to the element as a CSS class. + * Unlike the other animation methods, the animate service will suffix the className value with {@type -add} in order to provide + * the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if no CSS transitions + * or keyframes are defined on the -add or base CSS class). + * + * Below is a breakdown of each step that occurs during addClass animation: + * + * | Animation Step | What the element class attribute looks like | + * |------------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.addClass(element, 'super') is called | class="my-animation" | + * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" | + * | 3. the .super-add class are added to the element | class="my-animation ng-animate super-add" | + * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate super-add" | + * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate super-add" | + * | 6. the .super, .super-add-active and .ng-animate-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active super super-add super-add-active" | + * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation super-add super-add-active" | + * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation super" | + * | 9. The super class is kept on the element | class="my-animation super" | + * | 10. The doneCallback() callback is fired (if provided) | class="my-animation super" | + * + * @param {jQuery/jqLite element} element the element that will be animated + * @param {string} className the CSS class that will be added to the element and then animated + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + addClass : function(element, className, doneCallback) { + performAnimation('addClass', className, element, null, null, function() { + $delegate.addClass(element, className); + }, doneCallback); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#removeClass + * @methodOf ngAnimate.$animate + * + * @description + * Triggers a custom animation event based off the className variable and then removes the CSS class provided by the className value + * from the element. Unlike the other animation methods, the animate service will suffix the className value with {@type -remove} in + * order to provide the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if + * no CSS transitions or keyframes are defined on the -remove or base CSS classes). + * + * Below is a breakdown of each step that occurs during removeClass animation: + * + * | Animation Step | What the element class attribute looks like | + * |-----------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.removeClass(element, 'super') is called | class="my-animation super" | + * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation super ng-animate" | + * | 3. the .super-remove class are added to the element | class="my-animation super ng-animate super-remove"| + * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation super ng-animate super-remove" | + * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation super ng-animate super-remove" | + * | 6. the .super-remove-active and .ng-animate-active classes are added and .super is removed (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active super-remove super-remove-active" | + * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active super-remove super-remove-active" | + * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" | + * | 9. The doneCallback() callback is fired (if provided) | class="my-animation" | + * + * + * @param {jQuery/jqLite element} element the element that will be animated + * @param {string} className the CSS class that will be animated and then removed from the element + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + removeClass : function(element, className, doneCallback) { + performAnimation('removeClass', className, element, null, null, function() { + $delegate.removeClass(element, className); + }, doneCallback); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#enabled + * @methodOf ngAnimate.$animate + * @function + * + * @param {boolean=} value If provided then set the animation on or off. + * @param {jQuery/jqLite element=} element If provided then the element will be used to represent the enable/disable operation + * @return {boolean} Current animation state. + * + * @description + * Globally enables/disables animations. + * + */ + enabled : function(value, element) { + switch(arguments.length) { + case 2: + if(value) { + cleanup(element); + } else { + var data = element.data(NG_ANIMATE_STATE) || {}; + data.disabled = true; + element.data(NG_ANIMATE_STATE, data); + } + break; + + case 1: + rootAnimateState.disabled = !value; + break; + + default: + value = !rootAnimateState.disabled; + break; + } + return !!value; + } + }; + + /* + all animations call this shared animation triggering function internally. + The animationEvent variable refers to the JavaScript animation event that will be triggered + and the className value is the name of the animation that will be applied within the + CSS code. Element, parentElement and afterElement are provided DOM elements for the animation + and the onComplete callback will be fired once the animation is fully complete. + */ + function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) { + var currentClassName = element.attr('class') || ''; + var classes = currentClassName + ' ' + className; + var animationLookup = (' ' + classes).replace(/\s+/g,'.'); + if (!parentElement) { + parentElement = afterElement ? afterElement.parent() : element.parent(); + } + + var matches = lookup(animationLookup); + var isClassBased = animationEvent == 'addClass' || animationEvent == 'removeClass'; + var ngAnimateState = element.data(NG_ANIMATE_STATE) || {}; + + //skip the animation if animations are disabled, a parent is already being animated, + //the element is not currently attached to the document body or then completely close + //the animation if any matching animations are not found at all. + //NOTE: IE8 + IE9 should close properly (run closeAnimation()) in case a NO animation is not found. + if (animationsDisabled(element, parentElement) || matches.length === 0) { + fireDOMOperation(); + closeAnimation(); + return; + } + + var animations = []; + //only add animations if the currently running animation is not structural + //or if there is no animation running at all + if(!ngAnimateState.running || !(isClassBased && ngAnimateState.structural)) { + forEach(matches, function(animation) { + //add the animation to the queue to if it is allowed to be cancelled + if(!animation.allowCancel || animation.allowCancel(element, animationEvent, className)) { + var beforeFn, afterFn = animation[animationEvent]; + + //Special case for a leave animation since there is no point in performing an + //animation on a element node that has already been removed from the DOM + if(animationEvent == 'leave') { + beforeFn = afterFn; + afterFn = null; //this must be falsy so that the animation is skipped for leave + } else { + beforeFn = animation['before' + animationEvent.charAt(0).toUpperCase() + animationEvent.substr(1)]; + } + animations.push({ + before : beforeFn, + after : afterFn + }); + } + }); + } + + //this would mean that an animation was not allowed so let the existing + //animation do it's thing and close this one early + if(animations.length === 0) { + fireDOMOperation(); + fireDoneCallbackAsync(); + return; + } + + //this value will be searched for class-based CSS className lookup. Therefore, + //we prefix and suffix the current className value with spaces to avoid substring + //lookups of className tokens + var futureClassName = ' ' + currentClassName + ' '; + if(ngAnimateState.running) { + //if an animation is currently running on the element then lets take the steps + //to cancel that animation and fire any required callbacks + $timeout.cancel(ngAnimateState.closeAnimationTimeout); + cleanup(element); + cancelAnimations(ngAnimateState.animations); + + //if the class is removed during the reflow then it will revert the styles temporarily + //back to the base class CSS styling causing a jump-like effect to occur. This check + //here ensures that the domOperation is only performed after the reflow has commenced + if(ngAnimateState.beforeComplete) { + (ngAnimateState.done || noop)(true); + } else if(isClassBased && !ngAnimateState.structural) { + //class-based animations will compare element className values after cancelling the + //previous animation to see if the element properties already contain the final CSS + //class and if so then the animation will be skipped. Since the domOperation will + //be performed only after the reflow is complete then our element's className value + //will be invalid. Therefore the same string manipulation that would occur within the + //DOM operation will be performed below so that the class comparison is valid... + futureClassName = ngAnimateState.event == 'removeClass' ? + futureClassName.replace(ngAnimateState.className, '') : + futureClassName + ngAnimateState.className + ' '; + } + } + + //There is no point in perform a class-based animation if the element already contains + //(on addClass) or doesn't contain (on removeClass) the className being animated. + //The reason why this is being called after the previous animations are cancelled + //is so that the CSS classes present on the element can be properly examined. + var classNameToken = ' ' + className + ' '; + if((animationEvent == 'addClass' && futureClassName.indexOf(classNameToken) >= 0) || + (animationEvent == 'removeClass' && futureClassName.indexOf(classNameToken) == -1)) { + fireDOMOperation(); + fireDoneCallbackAsync(); + return; + } + + //the ng-animate class does nothing, but it's here to allow for + //parent animations to find and cancel child animations when needed + element.addClass(NG_ANIMATE_CLASS_NAME); + + element.data(NG_ANIMATE_STATE, { + running:true, + event:animationEvent, + className:className, + structural:!isClassBased, + animations:animations, + done:onBeforeAnimationsComplete + }); + + //first we run the before animations and when all of those are complete + //then we perform the DOM operation and run the next set of animations + invokeRegisteredAnimationFns(animations, 'before', onBeforeAnimationsComplete); + + function onBeforeAnimationsComplete(cancelled) { + fireDOMOperation(); + if(cancelled === true) { + closeAnimation(); + return; + } + + //set the done function to the final done function + //so that the DOM event won't be executed twice by accident + //if the after animation is cancelled as well + var data = element.data(NG_ANIMATE_STATE); + if(data) { + data.done = closeAnimation; + element.data(NG_ANIMATE_STATE, data); + } + invokeRegisteredAnimationFns(animations, 'after', closeAnimation); + } + + function invokeRegisteredAnimationFns(animations, phase, allAnimationFnsComplete) { + var endFnName = phase + 'End'; + forEach(animations, function(animation, index) { + var animationPhaseCompleted = function() { + progress(index, phase); + }; + + //there are no before functions for enter + move since the DOM + //operations happen before the performAnimation method fires + if(phase == 'before' && (animationEvent == 'enter' || animationEvent == 'move')) { + animationPhaseCompleted(); + return; + } + + if(animation[phase]) { + animation[endFnName] = isClassBased ? + animation[phase](element, className, animationPhaseCompleted) : + animation[phase](element, animationPhaseCompleted); + } else { + animationPhaseCompleted(); + } + }); + + function progress(index, phase) { + var phaseCompletionFlag = phase + 'Complete'; + var currentAnimation = animations[index]; + currentAnimation[phaseCompletionFlag] = true; + (currentAnimation[endFnName] || noop)(); + + for(var i=0;i 0) { + aDuration *= parseInt(elementStyles[ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY], 10) || 1; + } + + animationDuration = Math.max(aDuration, animationDuration); + } + }); + data = { + total : 0, + transitionPropertyStyle: transitionPropertyStyle, + transitionDurationStyle: transitionDurationStyle, + transitionDelayStyle: transitionDelayStyle, + transitionDelay: transitionDelay, + transitionDuration: transitionDuration, + animationDelayStyle: animationDelayStyle, + animationDelay: animationDelay, + animationDuration: animationDuration + }; + if(cacheKey) { + lookupCache[cacheKey] = data; + } + } + return data; + } + + function parseMaxTime(str) { + var maxValue = 0; + var values = angular.isString(str) ? + str.split(/\s*,\s*/) : + []; + forEach(values, function(value) { + maxValue = Math.max(parseFloat(value) || 0, maxValue); + }); + return maxValue; + } + + function getCacheKey(element) { + var parentElement = element.parent(); + var parentID = parentElement.data(NG_ANIMATE_PARENT_KEY); + if(!parentID) { + parentElement.data(NG_ANIMATE_PARENT_KEY, ++parentCounter); + parentID = parentCounter; + } + return parentID + '-' + element[0].className; + } + + function animateSetup(element, className) { + var cacheKey = getCacheKey(element); + var eventCacheKey = cacheKey + ' ' + className; + var stagger = {}; + var ii = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0; + + if(ii > 0) { + var staggerClassName = className + '-stagger'; + var staggerCacheKey = cacheKey + ' ' + staggerClassName; + var applyClasses = !lookupCache[staggerCacheKey]; + + applyClasses && element.addClass(staggerClassName); + + stagger = getElementAnimationDetails(element, staggerCacheKey); + + applyClasses && element.removeClass(staggerClassName); + } + + element.addClass(className); + + var timings = getElementAnimationDetails(element, eventCacheKey); + + /* there is no point in performing a reflow if the animation + timeout is empty (this would cause a flicker bug normally + in the page. There is also no point in performing an animation + that only has a delay and no duration */ + var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration); + if(maxDuration === 0) { + element.removeClass(className); + return false; + } + + var node = element[0]; + //temporarily disable the transition so that the enter styles + //don't animate twice (this is here to avoid a bug in Chrome/FF). + var activeClassName = ''; + if(timings.transitionDuration > 0) { + element.addClass(NG_ANIMATE_FALLBACK_CLASS_NAME); + activeClassName += NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME + ' '; + blockTransitions(element); + } else { + blockKeyframeAnimations(element); + } + + forEach(className.split(' '), function(klass, i) { + activeClassName += (i > 0 ? ' ' : '') + klass + '-active'; + }); + + element.data(NG_ANIMATE_CSS_DATA_KEY, { + className : className, + activeClassName : activeClassName, + maxDuration : maxDuration, + classes : className + ' ' + activeClassName, + timings : timings, + stagger : stagger, + ii : ii + }); + + return true; + } + + function blockTransitions(element) { + element[0].style[TRANSITION_PROP + PROPERTY_KEY] = 'none'; + } + + function blockKeyframeAnimations(element) { + element[0].style[ANIMATION_PROP] = 'none 0s'; + } + + function unblockTransitions(element) { + var node = element[0], prop = TRANSITION_PROP + PROPERTY_KEY; + if(node.style[prop] && node.style[prop].length > 0) { + node.style[prop] = ''; + } + } + + function unblockKeyframeAnimations(element) { + var node = element[0], prop = ANIMATION_PROP; + if(node.style[prop] && node.style[prop].length > 0) { + element[0].style[prop] = ''; + } + } + + function animateRun(element, className, activeAnimationComplete) { + var data = element.data(NG_ANIMATE_CSS_DATA_KEY); + if(!element.hasClass(className) || !data) { + activeAnimationComplete(); + return; + } + + var node = element[0]; + var timings = data.timings; + var stagger = data.stagger; + var maxDuration = data.maxDuration; + var activeClassName = data.activeClassName; + var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * 1000; + var startTime = Date.now(); + var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT; + var ii = data.ii; + + var applyFallbackStyle, style = '', appliedStyles = []; + if(timings.transitionDuration > 0) { + var propertyStyle = timings.transitionPropertyStyle; + if(propertyStyle.indexOf('all') == -1) { + applyFallbackStyle = true; + var fallbackProperty = $sniffer.msie ? '-ms-zoom' : 'border-spacing'; + style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ', ' + fallbackProperty + '; '; + style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ', ' + timings.transitionDuration + 's; '; + appliedStyles.push(CSS_PREFIX + 'transition-property'); + appliedStyles.push(CSS_PREFIX + 'transition-duration'); + } + } + + if(ii > 0) { + if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) { + var delayStyle = timings.transitionDelayStyle; + if(applyFallbackStyle) { + delayStyle += ', ' + timings.transitionDelay + 's'; + } + + style += CSS_PREFIX + 'transition-delay: ' + + prepareStaggerDelay(delayStyle, stagger.transitionDelay, ii) + '; '; + appliedStyles.push(CSS_PREFIX + 'transition-delay'); + } + + if(stagger.animationDelay > 0 && stagger.animationDuration === 0) { + style += CSS_PREFIX + 'animation-delay: ' + + prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, ii) + '; '; + appliedStyles.push(CSS_PREFIX + 'animation-delay'); + } + } + + if(appliedStyles.length > 0) { + var oldStyle = node.getAttribute('style') || ''; + node.setAttribute('style', oldStyle + ' ' + style); + } + + element.on(css3AnimationEvents, onAnimationProgress); + element.addClass(activeClassName); + + // This will automatically be called by $animate so + // there is no need to attach this internally to the + // timeout done method. + return function onEnd(cancelled) { + element.off(css3AnimationEvents, onAnimationProgress); + element.removeClass(activeClassName); + animateClose(element, className); + for (var i in appliedStyles) { + node.style.removeProperty(appliedStyles[i]); + } + }; + + function onAnimationProgress(event) { + event.stopPropagation(); + var ev = event.originalEvent || event; + var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now(); + /* $manualTimeStamp is a mocked timeStamp value which is set + * within browserTrigger(). This is only here so that tests can + * mock animations properly. Real events fallback to event.timeStamp, + * or, if they don't, then a timeStamp is automatically created for them. + * We're checking to see if the timeStamp surpasses the expected delay, + * but we're using elapsedTime instead of the timeStamp on the 2nd + * pre-condition since animations sometimes close off early */ + if(Math.max(timeStamp - startTime, 0) >= maxDelayTime && ev.elapsedTime >= maxDuration) { + activeAnimationComplete(); + } + } + } + + function prepareStaggerDelay(delayStyle, staggerDelay, index) { + var style = ''; + forEach(delayStyle.split(','), function(val, i) { + style += (i > 0 ? ',' : '') + + (index * staggerDelay + parseInt(val, 10)) + 's'; + }); + return style; + } + + function animateBefore(element, className) { + if(animateSetup(element, className)) { + return function(cancelled) { + cancelled && animateClose(element, className); + }; + } + } + + function animateAfter(element, className, afterAnimationComplete) { + if(element.data(NG_ANIMATE_CSS_DATA_KEY)) { + return animateRun(element, className, afterAnimationComplete); + } else { + animateClose(element, className); + afterAnimationComplete(); + } + } + + function animate(element, className, animationComplete) { + //If the animateSetup function doesn't bother returning a + //cancellation function then it means that there is no animation + //to perform at all + var preReflowCancellation = animateBefore(element, className); + if(!preReflowCancellation) { + animationComplete(); + return; + } + + //There are two cancellation functions: one is before the first + //reflow animation and the second is during the active state + //animation. The first function will take care of removing the + //data from the element which will not make the 2nd animation + //happen in the first place + var cancel = preReflowCancellation; + afterReflow(function() { + unblockTransitions(element); + unblockKeyframeAnimations(element); + //once the reflow is complete then we point cancel to + //the new cancellation function which will remove all of the + //animation properties from the active animation + cancel = animateAfter(element, className, animationComplete); + }); + + return function(cancelled) { + (cancel || noop)(cancelled); + }; + } + + function animateClose(element, className) { + element.removeClass(className); + element.removeClass(NG_ANIMATE_FALLBACK_CLASS_NAME); + element.removeData(NG_ANIMATE_CSS_DATA_KEY); + } + + return { + allowCancel : function(element, animationEvent, className) { + //always cancel the current animation if it is a + //structural animation + var oldClasses = (element.data(NG_ANIMATE_CSS_DATA_KEY) || {}).classes; + if(!oldClasses || ['enter','leave','move'].indexOf(animationEvent) >= 0) { + return true; + } + + var parentElement = element.parent(); + var clone = angular.element(element[0].cloneNode()); + + //make the element super hidden and override any CSS style values + clone.attr('style','position:absolute; top:-9999px; left:-9999px'); + clone.removeAttr('id'); + clone.html(''); + + forEach(oldClasses.split(' '), function(klass) { + clone.removeClass(klass); + }); + + var suffix = animationEvent == 'addClass' ? '-add' : '-remove'; + clone.addClass(suffixClasses(className, suffix)); + parentElement.append(clone); + + var timings = getElementAnimationDetails(clone); + clone.remove(); + + return Math.max(timings.transitionDuration, timings.animationDuration) > 0; + }, + + enter : function(element, animationCompleted) { + return animate(element, 'ng-enter', animationCompleted); + }, + + leave : function(element, animationCompleted) { + return animate(element, 'ng-leave', animationCompleted); + }, + + move : function(element, animationCompleted) { + return animate(element, 'ng-move', animationCompleted); + }, + + beforeAddClass : function(element, className, animationCompleted) { + var cancellationMethod = animateBefore(element, suffixClasses(className, '-add')); + if(cancellationMethod) { + afterReflow(function() { + unblockTransitions(element); + unblockKeyframeAnimations(element); + animationCompleted(); + }); + return cancellationMethod; + } + animationCompleted(); + }, + + addClass : function(element, className, animationCompleted) { + return animateAfter(element, suffixClasses(className, '-add'), animationCompleted); + }, + + beforeRemoveClass : function(element, className, animationCompleted) { + var cancellationMethod = animateBefore(element, suffixClasses(className, '-remove')); + if(cancellationMethod) { + afterReflow(function() { + unblockTransitions(element); + unblockKeyframeAnimations(element); + animationCompleted(); + }); + return cancellationMethod; + } + animationCompleted(); + }, + + removeClass : function(element, className, animationCompleted) { + return animateAfter(element, suffixClasses(className, '-remove'), animationCompleted); + } + }; + + function suffixClasses(classes, suffix) { + var className = ''; + classes = angular.isArray(classes) ? classes : classes.split(/\s+/); + forEach(classes, function(klass, i) { + if(klass && klass.length > 0) { + className += (i > 0 ? ' ' : '') + klass + suffix; + } + }); + return className; + } + }]); + }]); + + +})(window, window.angular); diff --git a/vendor/angular/angular-animate.min.js b/vendor/angular/angular-animate.min.js new file mode 100644 index 00000000..796fbbb2 --- /dev/null +++ b/vendor/angular/angular-animate.min.js @@ -0,0 +1,22 @@ +/* + AngularJS v1.2.3 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(C,k,F){'use strict';k.module("ngAnimate",["ng"]).config(["$provide","$animateProvider",function(M,G){var p=k.noop,r=k.forEach,N=G.$$selectors,T=1,h="$$ngAnimateState",H="ng-animate",l={running:!0};M.decorator("$animate",["$delegate","$injector","$sniffer","$rootElement","$timeout","$rootScope","$document",function(v,C,I,g,s,q,F){function O(a){if(a){var d=[],c={};a=a.substr(1).split(".");(I.transitions||I.animations)&&a.push("");for(var e=0;e=v&&a.elapsedTime>=q&&e()}var n=a.data(y);if(a.hasClass(d)&&n){var l=a[0],g=n.timings,m=n.stagger, +q=n.maxDuration,r=n.activeClassName,v=1E3*Math.max(g.transitionDelay,g.animationDelay),w=Date.now(),t=Q+" "+P,u=n.ii,x,n="",p=[];if(0 + * + * See {@link ngCookies.$cookies `$cookies`} and + * {@link ngCookies.$cookieStore `$cookieStore`} for usage. + */ + + +angular.module('ngCookies', ['ng']). + /** + * @ngdoc object + * @name ngCookies.$cookies + * @requires $browser + * + * @description + * Provides read/write access to browser's cookies. + * + * Only a simple Object is exposed and by adding or removing properties to/from + * this object, new cookies are created/deleted at the end of current $eval. + * + * Requires the {@link ngCookies `ngCookies`} module to be installed. + * + * @example + + + + + + */ + factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) { + var cookies = {}, + lastCookies = {}, + lastBrowserCookies, + runEval = false, + copy = angular.copy, + isUndefined = angular.isUndefined; + + //creates a poller fn that copies all cookies from the $browser to service & inits the service + $browser.addPollFn(function() { + var currentCookies = $browser.cookies(); + if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl + lastBrowserCookies = currentCookies; + copy(currentCookies, lastCookies); + copy(currentCookies, cookies); + if (runEval) $rootScope.$apply(); + } + })(); + + runEval = true; + + //at the end of each eval, push cookies + //TODO: this should happen before the "delayed" watches fire, because if some cookies are not + // strings or browser refuses to store some cookies, we update the model in the push fn. + $rootScope.$watch(push); + + return cookies; + + + /** + * Pushes all the cookies from the service to the browser and verifies if all cookies were + * stored. + */ + function push() { + var name, + value, + browserCookies, + updated; + + //delete any cookies deleted in $cookies + for (name in lastCookies) { + if (isUndefined(cookies[name])) { + $browser.cookies(name, undefined); + } + } + + //update all cookies updated in $cookies + for(name in cookies) { + value = cookies[name]; + if (!angular.isString(value)) { + if (angular.isDefined(lastCookies[name])) { + cookies[name] = lastCookies[name]; + } else { + delete cookies[name]; + } + } else if (value !== lastCookies[name]) { + $browser.cookies(name, value); + updated = true; + } + } + + //verify what was actually stored + if (updated){ + updated = false; + browserCookies = $browser.cookies(); + + for (name in cookies) { + if (cookies[name] !== browserCookies[name]) { + //delete or reset all cookies that the browser dropped from $cookies + if (isUndefined(browserCookies[name])) { + delete cookies[name]; + } else { + cookies[name] = browserCookies[name]; + } + updated = true; + } + } + } + } + }]). + + + /** + * @ngdoc object + * @name ngCookies.$cookieStore + * @requires $cookies + * + * @description + * Provides a key-value (string-object) storage, that is backed by session cookies. + * Objects put or retrieved from this storage are automatically serialized or + * deserialized by angular's toJson/fromJson. + * + * Requires the {@link ngCookies `ngCookies`} module to be installed. + * + * @example + */ + factory('$cookieStore', ['$cookies', function($cookies) { + + return { + /** + * @ngdoc method + * @name ngCookies.$cookieStore#get + * @methodOf ngCookies.$cookieStore + * + * @description + * Returns the value of given cookie key + * + * @param {string} key Id to use for lookup. + * @returns {Object} Deserialized cookie value. + */ + get: function(key) { + var value = $cookies[key]; + return value ? angular.fromJson(value) : value; + }, + + /** + * @ngdoc method + * @name ngCookies.$cookieStore#put + * @methodOf ngCookies.$cookieStore + * + * @description + * Sets a value for given cookie key + * + * @param {string} key Id for the `value`. + * @param {Object} value Value to be stored. + */ + put: function(key, value) { + $cookies[key] = angular.toJson(value); + }, + + /** + * @ngdoc method + * @name ngCookies.$cookieStore#remove + * @methodOf ngCookies.$cookieStore + * + * @description + * Remove given cookie + * + * @param {string} key Id of the key-value pair to delete. + */ + remove: function(key) { + delete $cookies[key]; + } + }; + + }]); + + +})(window, window.angular); diff --git a/vendor/angular/angular-cookies.min.js b/vendor/angular/angular-cookies.min.js new file mode 100644 index 00000000..c6956ac8 --- /dev/null +++ b/vendor/angular/angular-cookies.min.js @@ -0,0 +1,8 @@ +/* + AngularJS v1.2.3 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(d,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&d.$apply())})();k=!0;d.$watch(function(){var a,e,d;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)(e=c[a],f.isString(e))?e!==g[a]&&(b.cookies(a,e),d=!0):f.isDefined(g[a])?c[a]=g[a]:delete c[a];if(d)for(a in e=b.cookies(),c)c[a]!==e[a]&&(m(e[a])?delete c[a]:c[a]=e[a])}); +return c}]).factory("$cookieStore",["$cookies",function(d){return{get:function(b){return(b=d[b])?f.fromJson(b):b},put:function(b,c){d[b]=f.toJson(c)},remove:function(b){delete d[b]}}}])})(window,window.angular); +//# sourceMappingURL=angular-cookies.min.js.map diff --git a/vendor/angular/angular-cookies.min.js.map b/vendor/angular/angular-cookies.min.js.map new file mode 100644 index 00000000..a7fd1e9c --- /dev/null +++ b/vendor/angular/angular-cookies.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"angular-cookies.min.js", +"lineCount":7, +"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAoBtCD,CAAAE,OAAA,CAAe,WAAf,CAA4B,CAAC,IAAD,CAA5B,CAAAC,QAAA,CA4BW,UA5BX,CA4BuB,CAAC,YAAD,CAAe,UAAf,CAA2B,QAAS,CAACC,CAAD,CAAaC,CAAb,CAAuB,CAAA,IACxEC,EAAU,EAD8D,CAExEC,EAAc,EAF0D,CAGxEC,CAHwE,CAIxEC,EAAU,CAAA,CAJ8D,CAKxEC,EAAOV,CAAAU,KALiE,CAMxEC,EAAcX,CAAAW,YAGlBN,EAAAO,UAAA,CAAmB,QAAQ,EAAG,CAC5B,IAAIC,EAAiBR,CAAAC,QAAA,EACjBE,EAAJ,EAA0BK,CAA1B,GACEL,CAGA,CAHqBK,CAGrB,CAFAH,CAAA,CAAKG,CAAL,CAAqBN,CAArB,CAEA,CADAG,CAAA,CAAKG,CAAL,CAAqBP,CAArB,CACA,CAAIG,CAAJ,EAAaL,CAAAU,OAAA,EAJf,CAF4B,CAA9B,CAAA,EAUAL,EAAA,CAAU,CAAA,CAKVL,EAAAW,OAAA,CASAC,QAAa,EAAG,CAAA,IACVC,CADU,CAEVC,CAFU,CAIVC,CAGJ,KAAKF,CAAL,GAAaV,EAAb,CACMI,CAAA,CAAYL,CAAA,CAAQW,CAAR,CAAZ,CAAJ,EACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBhB,CAAvB,CAKJ,KAAIgB,CAAJ,GAAYX,EAAZ,CAEE,CADAY,CACK,CADGZ,CAAA,CAAQW,CAAR,CACH,CAAAjB,CAAAoB,SAAA,CAAiBF,CAAjB,CAAL,EAMWA,CANX,GAMqBX,CAAA,CAAYU,CAAZ,CANrB,GAOEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBC,CAAvB,CACA,CAAAC,CAAA,CAAU,CAAA,CARZ,EACMnB,CAAAqB,UAAA,CAAkBd,CAAA,CAAYU,CAAZ,CAAlB,CAAJ,CACEX,CAAA,CAAQW,CAAR,CADF,CACkBV,CAAA,CAAYU,CAAZ,CADlB,CAGE,OAAOX,CAAA,CAAQW,CAAR,CASb,IAAIE,CAAJ,CAIE,IAAKF,CAAL,GAFAK,EAEahB,CAFID,CAAAC,QAAA,EAEJA,CAAAA,CAAb,CACMA,CAAA,CAAQW,CAAR,CAAJ,GAAsBK,CAAA,CAAeL,CAAf,CAAtB,GAEMN,CAAA,CAAYW,CAAA,CAAeL,CAAf,CAAZ,CAAJ,CACE,OAAOX,CAAA,CAAQW,CAAR,CADT,CAGEX,CAAA,CAAQW,CAAR,CAHF,CAGkBK,CAAA,CAAeL,CAAf,CALpB,CAlCU,CAThB,CAEA;MAAOX,EA1BqE,CAA3D,CA5BvB,CAAAH,QAAA,CA4HW,cA5HX,CA4H2B,CAAC,UAAD,CAAa,QAAQ,CAACoB,CAAD,CAAW,CAErD,MAAO,KAYAC,QAAQ,CAACC,CAAD,CAAM,CAEjB,MAAO,CADHP,CACG,CADKK,CAAA,CAASE,CAAT,CACL,EAAQzB,CAAA0B,SAAA,CAAiBR,CAAjB,CAAR,CAAkCA,CAFxB,CAZd,KA4BAS,QAAQ,CAACF,CAAD,CAAMP,CAAN,CAAa,CACxBK,CAAA,CAASE,CAAT,CAAA,CAAgBzB,CAAA4B,OAAA,CAAeV,CAAf,CADQ,CA5BrB,QA0CGW,QAAQ,CAACJ,CAAD,CAAM,CACpB,OAAOF,CAAA,CAASE,CAAT,CADa,CA1CjB,CAF8C,CAAhC,CA5H3B,CApBsC,CAArC,CAAA,CAoME1B,MApMF,CAoMUA,MAAAC,QApMV;", +"sources":["angular-cookies.js"], +"names":["window","angular","undefined","module","factory","$rootScope","$browser","cookies","lastCookies","lastBrowserCookies","runEval","copy","isUndefined","addPollFn","currentCookies","$apply","$watch","push","name","value","updated","isString","isDefined","browserCookies","$cookies","get","key","fromJson","put","toJson","remove"] +} diff --git a/vendor/angular/angular-csp.css b/vendor/angular/angular-csp.css new file mode 100644 index 00000000..585878ef --- /dev/null +++ b/vendor/angular/angular-csp.css @@ -0,0 +1,24 @@ +/* Include this file in your html if you are using the CSP mode. */ + +@charset "UTF-8"; + +[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], +.ng-cloak, .x-ng-cloak, +.ng-hide { + display: none !important; +} + +ng\:form { + display: block; +} + +/* The styles below ensure that the CSS transition will ALWAYS + * animate and close. A nasty bug occurs with CSS transitions where + * when the active class isn't set, or if the active class doesn't + * contain any styles to transition to, then, if ngAnimate is used, + * it will appear as if the webpage is broken due to the forever hanging + * animations. The border-spacing (!ie) and zoom (ie) CSS properties are + * used below since they trigger a transition without making the browser + * animate anything and they're both highly underused CSS properties */ +.ng-animate-start { border-spacing:1px 1px; -ms-zoom:1.0001; } +.ng-animate-active { border-spacing:0px 0px; -ms-zoom:1; } diff --git a/vendor/angular/angular-loader.js b/vendor/angular/angular-loader.js new file mode 100644 index 00000000..431ff1f0 --- /dev/null +++ b/vendor/angular/angular-loader.js @@ -0,0 +1,410 @@ +/** + * @license AngularJS v1.2.3 + * (c) 2010-2014 Google, Inc. http://angularjs.org + * License: MIT + */ + +(function() {'use strict'; + +/** + * @description + * + * This object provides a utility for producing rich Error messages within + * Angular. It can be called as follows: + * + * var exampleMinErr = minErr('example'); + * throw exampleMinErr('one', 'This {0} is {1}', foo, bar); + * + * The above creates an instance of minErr in the example namespace. The + * resulting error will have a namespaced error code of example.one. The + * resulting error will replace {0} with the value of foo, and {1} with the + * value of bar. The object is not restricted in the number of arguments it can + * take. + * + * If fewer arguments are specified than necessary for interpolation, the extra + * interpolation markers will be preserved in the final string. + * + * Since data will be parsed statically during a build step, some restrictions + * are applied with respect to how minErr instances are created and called. + * Instances should have names of the form namespaceMinErr for a minErr created + * using minErr('namespace') . Error codes, namespaces and template strings + * should all be static strings, not variables or general expressions. + * + * @param {string} module The namespace to use for the new minErr instance. + * @returns {function(string, string, ...): Error} instance + */ + +function minErr(module) { + return function () { + var code = arguments[0], + prefix = '[' + (module ? module + ':' : '') + code + '] ', + template = arguments[1], + templateArgs = arguments, + stringify = function (obj) { + if (typeof obj === 'function') { + return obj.toString().replace(/ \{[\s\S]*$/, ''); + } else if (typeof obj === 'undefined') { + return 'undefined'; + } else if (typeof obj !== 'string') { + return JSON.stringify(obj); + } + return obj; + }, + message, i; + + message = prefix + template.replace(/\{\d+\}/g, function (match) { + var index = +match.slice(1, -1), arg; + + if (index + 2 < templateArgs.length) { + arg = templateArgs[index + 2]; + if (typeof arg === 'function') { + return arg.toString().replace(/ ?\{[\s\S]*$/, ''); + } else if (typeof arg === 'undefined') { + return 'undefined'; + } else if (typeof arg !== 'string') { + return toJson(arg); + } + return arg; + } + return match; + }); + + message = message + '\nhttp://errors.angularjs.org/1.2.3/' + + (module ? module + '/' : '') + code; + for (i = 2; i < arguments.length; i++) { + message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + + encodeURIComponent(stringify(arguments[i])); + } + + return new Error(message); + }; +} + +/** + * @ngdoc interface + * @name angular.Module + * @description + * + * Interface for configuring angular {@link angular.module modules}. + */ + +function setupModuleLoader(window) { + + var $injectorMinErr = minErr('$injector'); + var ngMinErr = minErr('ng'); + + function ensure(obj, name, factory) { + return obj[name] || (obj[name] = factory()); + } + + var angular = ensure(window, 'angular', Object); + + // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap + angular.$$minErr = angular.$$minErr || minErr; + + return ensure(angular, 'module', function() { + /** @type {Object.} */ + var modules = {}; + + /** + * @ngdoc function + * @name angular.module + * @description + * + * The `angular.module` is a global place for creating, registering and retrieving Angular + * modules. + * All modules (angular core or 3rd party) that should be available to an application must be + * registered using this mechanism. + * + * When passed two or more arguments, a new module is created. If passed only one argument, an + * existing module (the name passed as the first argument to `module`) is retrieved. + * + * + * # Module + * + * A module is a collection of services, directives, filters, and configuration information. + * `angular.module` is used to configure the {@link AUTO.$injector $injector}. + * + *
+     * // Create a new module
+     * var myModule = angular.module('myModule', []);
+     *
+     * // register a new service
+     * myModule.value('appName', 'MyCoolApp');
+     *
+     * // configure existing services inside initialization blocks.
+     * myModule.config(function($locationProvider) {
+     *   // Configure existing providers
+     *   $locationProvider.hashPrefix('!');
+     * });
+     * 
+ * + * Then you can create an injector and load your modules like this: + * + *
+     * var injector = angular.injector(['ng', 'MyModule'])
+     * 
+ * + * However it's more likely that you'll just use + * {@link ng.directive:ngApp ngApp} or + * {@link angular.bootstrap} to simplify this process for you. + * + * @param {!string} name The name of the module to create or retrieve. + * @param {Array.=} requires If specified then new module is being created. If + * unspecified then the the module is being retrieved for further configuration. + * @param {Function} configFn Optional configuration function for the module. Same as + * {@link angular.Module#methods_config Module#config()}. + * @returns {module} new module with the {@link angular.Module} api. + */ + return function module(name, requires, configFn) { + var assertNotHasOwnProperty = function(name, context) { + if (name === 'hasOwnProperty') { + throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); + } + }; + + assertNotHasOwnProperty(name, 'module'); + if (requires && modules.hasOwnProperty(name)) { + modules[name] = null; + } + return ensure(modules, name, function() { + if (!requires) { + throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + + "the module name or forgot to load it. If registering a module ensure that you " + + "specify the dependencies as the second argument.", name); + } + + /** @type {!Array.>} */ + var invokeQueue = []; + + /** @type {!Array.} */ + var runBlocks = []; + + var config = invokeLater('$injector', 'invoke'); + + /** @type {angular.Module} */ + var moduleInstance = { + // Private state + _invokeQueue: invokeQueue, + _runBlocks: runBlocks, + + /** + * @ngdoc property + * @name angular.Module#requires + * @propertyOf angular.Module + * @returns {Array.} List of module names which must be loaded before this module. + * @description + * Holds the list of modules which the injector will load before the current module is + * loaded. + */ + requires: requires, + + /** + * @ngdoc property + * @name angular.Module#name + * @propertyOf angular.Module + * @returns {string} Name of the module. + * @description + */ + name: name, + + + /** + * @ngdoc method + * @name angular.Module#provider + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} providerType Construction function for creating new instance of the + * service. + * @description + * See {@link AUTO.$provide#provider $provide.provider()}. + */ + provider: invokeLater('$provide', 'provider'), + + /** + * @ngdoc method + * @name angular.Module#factory + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} providerFunction Function for creating new instance of the service. + * @description + * See {@link AUTO.$provide#factory $provide.factory()}. + */ + factory: invokeLater('$provide', 'factory'), + + /** + * @ngdoc method + * @name angular.Module#service + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} constructor A constructor function that will be instantiated. + * @description + * See {@link AUTO.$provide#service $provide.service()}. + */ + service: invokeLater('$provide', 'service'), + + /** + * @ngdoc method + * @name angular.Module#value + * @methodOf angular.Module + * @param {string} name service name + * @param {*} object Service instance object. + * @description + * See {@link AUTO.$provide#value $provide.value()}. + */ + value: invokeLater('$provide', 'value'), + + /** + * @ngdoc method + * @name angular.Module#constant + * @methodOf angular.Module + * @param {string} name constant name + * @param {*} object Constant value. + * @description + * Because the constant are fixed, they get applied before other provide methods. + * See {@link AUTO.$provide#constant $provide.constant()}. + */ + constant: invokeLater('$provide', 'constant', 'unshift'), + + /** + * @ngdoc method + * @name angular.Module#animation + * @methodOf angular.Module + * @param {string} name animation name + * @param {Function} animationFactory Factory function for creating new instance of an + * animation. + * @description + * + * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. + * + * + * Defines an animation hook that can be later used with + * {@link ngAnimate.$animate $animate} service and directives that use this service. + * + *
+           * module.animation('.animation-name', function($inject1, $inject2) {
+           *   return {
+           *     eventName : function(element, done) {
+           *       //code to run the animation
+           *       //once complete, then run done()
+           *       return function cancellationFunction(element) {
+           *         //code to cancel the animation
+           *       }
+           *     }
+           *   }
+           * })
+           * 
+ * + * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and + * {@link ngAnimate ngAnimate module} for more information. + */ + animation: invokeLater('$animateProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#filter + * @methodOf angular.Module + * @param {string} name Filter name. + * @param {Function} filterFactory Factory function for creating new instance of filter. + * @description + * See {@link ng.$filterProvider#register $filterProvider.register()}. + */ + filter: invokeLater('$filterProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#controller + * @methodOf angular.Module + * @param {string|Object} name Controller name, or an object map of controllers where the + * keys are the names and the values are the constructors. + * @param {Function} constructor Controller constructor function. + * @description + * See {@link ng.$controllerProvider#register $controllerProvider.register()}. + */ + controller: invokeLater('$controllerProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#directive + * @methodOf angular.Module + * @param {string|Object} name Directive name, or an object map of directives where the + * keys are the names and the values are the factories. + * @param {Function} directiveFactory Factory function for creating new instance of + * directives. + * @description + * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}. + */ + directive: invokeLater('$compileProvider', 'directive'), + + /** + * @ngdoc method + * @name angular.Module#config + * @methodOf angular.Module + * @param {Function} configFn Execute this function on module load. Useful for service + * configuration. + * @description + * Use this method to register work which needs to be performed on module loading. + */ + config: config, + + /** + * @ngdoc method + * @name angular.Module#run + * @methodOf angular.Module + * @param {Function} initializationFn Execute this function after injector creation. + * Useful for application initialization. + * @description + * Use this method to register work which should be performed when the injector is done + * loading all modules. + */ + run: function(block) { + runBlocks.push(block); + return this; + } + }; + + if (configFn) { + config(configFn); + } + + return moduleInstance; + + /** + * @param {string} provider + * @param {string} method + * @param {String=} insertMethod + * @returns {angular.Module} + */ + function invokeLater(provider, method, insertMethod) { + return function() { + invokeQueue[insertMethod || 'push']([provider, method, arguments]); + return moduleInstance; + }; + } + }); + }; + }); + +} + +setupModuleLoader(window); +})(window); + +/** + * Closure compiler type information + * + * @typedef { { + * requires: !Array., + * invokeQueue: !Array.>, + * + * service: function(string, Function):angular.Module, + * factory: function(string, Function):angular.Module, + * value: function(string, *):angular.Module, + * + * filter: function(string, Function):angular.Module, + * + * init: function(Function):angular.Module + * } } + */ +angular.Module; + diff --git a/vendor/angular/angular-loader.min.js b/vendor/angular/angular-loader.min.js new file mode 100644 index 00000000..33c58308 --- /dev/null +++ b/vendor/angular/angular-loader.min.js @@ -0,0 +1,9 @@ +/* + AngularJS v1.2.3 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(){'use strict';function d(a){return function(){var c=arguments[0],b,c="["+(a?a+":":"")+c+"] http://errors.angularjs.org/1.2.3/"+(a?a+"/":"")+c;for(b=1;b + * + * See {@link ngResource.$resource `$resource`} for usage. + */ + +/** + * @ngdoc object + * @name ngResource.$resource + * @requires $http + * + * @description + * A factory which creates a resource object that lets you interact with + * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources. + * + * The returned resource object has action methods which provide high-level behaviors without + * the need to interact with the low level {@link ng.$http $http} service. + * + * Requires the {@link ngResource `ngResource`} module to be installed. + * + * @param {string} url A parametrized URL template with parameters prefixed by `:` as in + * `/user/:username`. If you are using a URL with a port number (e.g. + * `http://example.com:8080/api`), it will be respected. + * + * If you are using a url with a suffix, just add the suffix, like this: + * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')` + * or even `$resource('http://example.com/resource/:resource_id.:format')` + * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be + * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you + * can escape it with `/\.`. + * + * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in + * `actions` methods. If any of the parameter value is a function, it will be executed every time + * when a param value needs to be obtained for a request (unless the param was overridden). + * + * Each key value in the parameter object is first bound to url template if present and then any + * excess keys are appended to the url search query after the `?`. + * + * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in + * URL `/path/greet?salutation=Hello`. + * + * If the parameter value is prefixed with `@` then the value of that parameter is extracted from + * the data object (useful for non-GET operations). + * + * @param {Object.=} actions Hash with declaration of custom action that should extend the + * default set of resource actions. The declaration should be created in the format of {@link + * ng.$http#usage_parameters $http.config}: + * + * {action1: {method:?, params:?, isArray:?, headers:?, ...}, + * action2: {method:?, params:?, isArray:?, headers:?, ...}, + * ...} + * + * Where: + * + * - **`action`** – {string} – The name of action. This name becomes the name of the method on + * your resource object. + * - **`method`** – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, + * `DELETE`, and `JSONP`. + * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of + * the parameter value is a function, it will be executed every time when a param value needs to + * be obtained for a request (unless the param was overridden). + * - **`url`** – {string} – action specific `url` override. The url templating is supported just + * like for the resource-level urls. + * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, + * see `returns` section. + * - **`transformRequest`** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * request body and headers and returns its transformed (typically serialized) version. + * - **`transformResponse`** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * response body and headers and returns its transformed (typically deserialized) version. + * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the + * GET request, otherwise if a cache instance built with + * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for + * caching. + * - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that + * should abort the request when resolved. + * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the + * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5 + * requests with credentials} for more information. + * - **`responseType`** - `{string}` - see {@link + * https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}. + * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods - + * `response` and `responseError`. Both `response` and `responseError` interceptors get called + * with `http response` object. See {@link ng.$http $http interceptors}. + * + * @returns {Object} A resource "class" object with methods for the default set of resource actions + * optionally extended with custom `actions`. The default set contains these actions: + * + * { 'get': {method:'GET'}, + * 'save': {method:'POST'}, + * 'query': {method:'GET', isArray:true}, + * 'remove': {method:'DELETE'}, + * 'delete': {method:'DELETE'} }; + * + * Calling these methods invoke an {@link ng.$http} with the specified http method, + * destination and parameters. When the data is returned from the server then the object is an + * instance of the resource class. The actions `save`, `remove` and `delete` are available on it + * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create, + * read, update, delete) on server-side data like this: + *
+        var User = $resource('/user/:userId', {userId:'@id'});
+        var user = User.get({userId:123}, function() {
+          user.abc = true;
+          user.$save();
+        });
+     
+ * + * It is important to realize that invoking a $resource object method immediately returns an + * empty reference (object or array depending on `isArray`). Once the data is returned from the + * server the existing reference is populated with the actual data. This is a useful trick since + * usually the resource is assigned to a model which is then rendered by the view. Having an empty + * object results in no rendering, once the data arrives from the server then the object is + * populated with the data and the view automatically re-renders itself showing the new data. This + * means that in most cases one never has to write a callback function for the action methods. + * + * The action methods on the class object or instance object can be invoked with the following + * parameters: + * + * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])` + * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])` + * - non-GET instance actions: `instance.$action([parameters], [success], [error])` + * + * Success callback is called with (value, responseHeaders) arguments. Error callback is called + * with (httpResponse) argument. + * + * Class actions return empty instance (with additional properties below). + * Instance actions return promise of the action. + * + * The Resource instances and collection have these additional properties: + * + * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this + * instance or collection. + * + * On success, the promise is resolved with the same resource instance or collection object, + * updated with data from server. This makes it easy to use in + * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view + * rendering until the resource(s) are loaded. + * + * On failure, the promise is resolved with the {@link ng.$http http response} object, without + * the `resource` property. + * + * - `$resolved`: `true` after first server interaction is completed (either with success or + * rejection), `false` before that. Knowing if the Resource has been resolved is useful in + * data-binding. + * + * @example + * + * # Credit card resource + * + *
+     // Define CreditCard class
+     var CreditCard = $resource('/user/:userId/card/:cardId',
+      {userId:123, cardId:'@id'}, {
+       charge: {method:'POST', params:{charge:true}}
+      });
+
+     // We can retrieve a collection from the server
+     var cards = CreditCard.query(function() {
+       // GET: /user/123/card
+       // server returns: [ {id:456, number:'1234', name:'Smith'} ];
+
+       var card = cards[0];
+       // each item is an instance of CreditCard
+       expect(card instanceof CreditCard).toEqual(true);
+       card.name = "J. Smith";
+       // non GET methods are mapped onto the instances
+       card.$save();
+       // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
+       // server returns: {id:456, number:'1234', name: 'J. Smith'};
+
+       // our custom method is mapped as well.
+       card.$charge({amount:9.99});
+       // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
+     });
+
+     // we can create an instance as well
+     var newCard = new CreditCard({number:'0123'});
+     newCard.name = "Mike Smith";
+     newCard.$save();
+     // POST: /user/123/card {number:'0123', name:'Mike Smith'}
+     // server returns: {id:789, number:'01234', name: 'Mike Smith'};
+     expect(newCard.id).toEqual(789);
+ * 
+ * + * The object returned from this function execution is a resource "class" which has "static" method + * for each action in the definition. + * + * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and + * `headers`. + * When the data is returned from the server then the object is an instance of the resource type and + * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD + * operations (create, read, update, delete) on server-side data. + +
+     var User = $resource('/user/:userId', {userId:'@id'});
+     var user = User.get({userId:123}, function() {
+       user.abc = true;
+       user.$save();
+     });
+   
+ * + * It's worth noting that the success callback for `get`, `query` and other methods gets passed + * in the response that came from the server as well as $http header getter function, so one + * could rewrite the above example and get access to http headers as: + * +
+     var User = $resource('/user/:userId', {userId:'@id'});
+     User.get({userId:123}, function(u, getResponseHeaders){
+       u.abc = true;
+       u.$save(function(u, putResponseHeaders) {
+         //u => saved user object
+         //putResponseHeaders => $http header getter
+       });
+     });
+   
+ */ +angular.module('ngResource', ['ng']). + factory('$resource', ['$http', '$q', function($http, $q) { + + var DEFAULT_ACTIONS = { + 'get': {method:'GET'}, + 'save': {method:'POST'}, + 'query': {method:'GET', isArray:true}, + 'remove': {method:'DELETE'}, + 'delete': {method:'DELETE'} + }; + var noop = angular.noop, + forEach = angular.forEach, + extend = angular.extend, + copy = angular.copy, + isFunction = angular.isFunction; + + /** + * We need our custom method because encodeURIComponent is too aggressive and doesn't follow + * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path + * segments: + * segment = *pchar + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * pct-encoded = "%" HEXDIG HEXDIG + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ + function encodeUriSegment(val) { + return encodeUriQuery(val, true). + replace(/%26/gi, '&'). + replace(/%3D/gi, '='). + replace(/%2B/gi, '+'); + } + + + /** + * This method is intended for encoding *key* or *value* parts of query component. We need a + * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't + * have to be encoded per http://tools.ietf.org/html/rfc3986: + * query = *( pchar / "/" / "?" ) + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * pct-encoded = "%" HEXDIG HEXDIG + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ + function encodeUriQuery(val, pctEncodeSpaces) { + return encodeURIComponent(val). + replace(/%40/gi, '@'). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); + } + + function Route(template, defaults) { + this.template = template; + this.defaults = defaults || {}; + this.urlParams = {}; + } + + Route.prototype = { + setUrlParams: function(config, params, actionUrl) { + var self = this, + url = actionUrl || self.template, + val, + encodedVal; + + var urlParams = self.urlParams = {}; + forEach(url.split(/\W/), function(param){ + if (param === 'hasOwnProperty') { + throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name."); + } + if (!(new RegExp("^\\d+$").test(param)) && param && + (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) { + urlParams[param] = true; + } + }); + url = url.replace(/\\:/g, ':'); + + params = params || {}; + forEach(self.urlParams, function(_, urlParam){ + val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam]; + if (angular.isDefined(val) && val !== null) { + encodedVal = encodeUriSegment(val); + url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), encodedVal + "$1"); + } else { + url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match, + leadingSlashes, tail) { + if (tail.charAt(0) == '/') { + return tail; + } else { + return leadingSlashes + tail; + } + }); + } + }); + + // strip trailing slashes and set the url + url = url.replace(/\/+$/, ''); + // then replace collapse `/.` if found in the last URL path segment before the query + // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x` + url = url.replace(/\/\.(?=\w+($|\?))/, '.'); + // replace escaped `/\.` with `/.` + config.url = url.replace(/\/\\\./, '/.'); + + + // set params - delegate param encoding to $http + forEach(params, function(value, key){ + if (!self.urlParams[key]) { + config.params = config.params || {}; + config.params[key] = value; + } + }); + } + }; + + + function resourceFactory(url, paramDefaults, actions) { + var route = new Route(url); + + actions = extend({}, DEFAULT_ACTIONS, actions); + + function extractParams(data, actionParams){ + var ids = {}; + actionParams = extend({}, paramDefaults, actionParams); + forEach(actionParams, function(value, key){ + if (isFunction(value)) { value = value(); } + ids[key] = value && value.charAt && value.charAt(0) == '@' ? + lookupDottedPath(data, value.substr(1)) : value; + }); + return ids; + } + + function defaultResponseInterceptor(response) { + return response.resource; + } + + function Resource(value){ + copy(value || {}, this); + } + + forEach(actions, function(action, name) { + var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method); + + Resource[name] = function(a1, a2, a3, a4) { + var params = {}, data, success, error; + + /* jshint -W086 */ /* (purposefully fall through case statements) */ + switch(arguments.length) { + case 4: + error = a4; + success = a3; + //fallthrough + case 3: + case 2: + if (isFunction(a2)) { + if (isFunction(a1)) { + success = a1; + error = a2; + break; + } + + success = a2; + error = a3; + //fallthrough + } else { + params = a1; + data = a2; + success = a3; + break; + } + case 1: + if (isFunction(a1)) success = a1; + else if (hasBody) data = a1; + else params = a1; + break; + case 0: break; + default: + throw $resourceMinErr('badargs', + "Expected up to 4 arguments [params, data, success, error], got {0} arguments", + arguments.length); + } + /* jshint +W086 */ /* (purposefully fall through case statements) */ + + var isInstanceCall = this instanceof Resource; + var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data)); + var httpConfig = {}; + var responseInterceptor = action.interceptor && action.interceptor.response || + defaultResponseInterceptor; + var responseErrorInterceptor = action.interceptor && action.interceptor.responseError || + undefined; + + forEach(action, function(value, key) { + if (key != 'params' && key != 'isArray' && key != 'interceptor') { + httpConfig[key] = copy(value); + } + }); + + if (hasBody) httpConfig.data = data; + route.setUrlParams(httpConfig, + extend({}, extractParams(data, action.params || {}), params), + action.url); + + var promise = $http(httpConfig).then(function(response) { + var data = response.data, + promise = value.$promise; + + if (data) { + // Need to convert action.isArray to boolean in case it is undefined + // jshint -W018 + if ( angular.isArray(data) !== (!!action.isArray) ) { + throw $resourceMinErr('badcfg', 'Error in resource configuration. Expected ' + + 'response to contain an {0} but got an {1}', + action.isArray?'array':'object', angular.isArray(data)?'array':'object'); + } + // jshint +W018 + if (action.isArray) { + value.length = 0; + forEach(data, function(item) { + value.push(new Resource(item)); + }); + } else { + copy(data, value); + value.$promise = promise; + } + } + + value.$resolved = true; + + response.resource = value; + + return response; + }, function(response) { + value.$resolved = true; + + (error||noop)(response); + + return $q.reject(response); + }); + + promise = promise.then( + function(response) { + var value = responseInterceptor(response); + (success||noop)(value, response.headers); + return value; + }, + responseErrorInterceptor); + + if (!isInstanceCall) { + // we are creating instance / collection + // - set the initial promise + // - return the instance / collection + value.$promise = promise; + value.$resolved = false; + + return value; + } + + // instance call + return promise; + }; + + + Resource.prototype['$' + name] = function(params, success, error) { + if (isFunction(params)) { + error = success; success = params; params = {}; + } + var result = Resource[name].call(this, params, this, success, error); + return result.$promise || result; + }; + }); + + Resource.bind = function(additionalParamDefaults){ + return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions); + }; + + return Resource; + } + + return resourceFactory; + }]); + + +})(window, window.angular); diff --git a/vendor/angular/angular-resource.min.js b/vendor/angular/angular-resource.min.js new file mode 100644 index 00000000..728aee8f --- /dev/null +++ b/vendor/angular/angular-resource.min.js @@ -0,0 +1,12 @@ +/* + AngularJS v1.2.3 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(H,f,z){'use strict';var u=f.$$minErr("$resource"),A=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;f.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(D,E){function n(f,h){this.template=f;this.defaults=h||{};this.urlParams={}}function v(m,h,k){function r(d,c){var e={};c=w({},h,c);s(c,function(a,c){t(a)&&(a=a());var g;if(a&&a.charAt&&"@"==a.charAt(0)){g=d;var b=a.substr(1);if(null==b||""===b||"hasOwnProperty"===b||!A.test("."+b))throw u("badmember",b);for(var b=b.split("."),f=0,h= +b.length;f + */ + /* global -ngRouteModule */ +var ngRouteModule = angular.module('ngRoute', ['ng']). + provider('$route', $RouteProvider); + +/** + * @ngdoc object + * @name ngRoute.$routeProvider + * @function + * + * @description + * + * Used for configuring routes. + * + * ## Example + * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`. + * + * ## Dependencies + * Requires the {@link ngRoute `ngRoute`} module to be installed. + */ +function $RouteProvider(){ + function inherit(parent, extra) { + return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra); + } + + var routes = {}; + + /** + * @ngdoc method + * @name ngRoute.$routeProvider#when + * @methodOf ngRoute.$routeProvider + * + * @param {string} path Route path (matched against `$location.path`). If `$location.path` + * contains redundant trailing slash or is missing one, the route will still match and the + * `$location.path` will be updated to add or drop the trailing slash to exactly match the + * route definition. + * + * * `path` can contain named groups starting with a colon (`:name`). All characters up + * to the next slash are matched and stored in `$routeParams` under the given `name` + * when the route matches. + * * `path` can contain named groups starting with a colon and ending with a star (`:name*`). + * All characters are eagerly stored in `$routeParams` under the given `name` + * when the route matches. + * * `path` can contain optional named groups with a question mark (`:name?`). + * + * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match + * `/color/brown/largecode/code/with/slashs/edit` and extract: + * + * * `color: brown` + * * `largecode: code/with/slashs`. + * + * + * @param {Object} route Mapping information to be assigned to `$route.current` on route + * match. + * + * Object properties: + * + * - `controller` – `{(string|function()=}` – Controller fn that should be associated with + * newly created scope or the name of a {@link angular.Module#controller registered + * controller} if passed as a string. + * - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be + * published to scope under the `controllerAs` name. + * - `template` – `{string=|function()=}` – html template as a string or a function that + * returns an html template as a string which should be used by {@link + * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives. + * This property takes precedence over `templateUrl`. + * + * If `template` is a function, it will be called with the following parameters: + * + * - `{Array.}` - route parameters extracted from the current + * `$location.path()` by applying the current route + * + * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html + * template that should be used by {@link ngRoute.directive:ngView ngView}. + * + * If `templateUrl` is a function, it will be called with the following parameters: + * + * - `{Array.}` - route parameters extracted from the current + * `$location.path()` by applying the current route + * + * - `resolve` - `{Object.=}` - An optional map of dependencies which should + * be injected into the controller. If any of these dependencies are promises, the router + * will wait for them all to be resolved or one to be rejected before the controller is + * instantiated. + * If all the promises are resolved successfully, the values of the resolved promises are + * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is + * fired. If any of the promises are rejected the + * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object + * is: + * + * - `key` – `{string}`: a name of a dependency to be injected into the controller. + * - `factory` - `{string|function}`: If `string` then it is an alias for a service. + * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected} + * and the return value is treated as the dependency. If the result is a promise, it is + * resolved before its value is injected into the controller. Be aware that + * `ngRoute.$routeParams` will still refer to the previous route within these resolve + * functions. Use `$route.current.params` to access the new route parameters, instead. + * + * - `redirectTo` – {(string|function())=} – value to update + * {@link ng.$location $location} path with and trigger route redirection. + * + * If `redirectTo` is a function, it will be called with the following parameters: + * + * - `{Object.}` - route parameters extracted from the current + * `$location.path()` by applying the current route templateUrl. + * - `{string}` - current `$location.path()` + * - `{Object}` - current `$location.search()` + * + * The custom `redirectTo` function is expected to return a string which will be used + * to update `$location.path()` and `$location.search()`. + * + * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()` + * or `$location.hash()` changes. + * + * If the option is set to `false` and url in the browser changes, then + * `$routeUpdate` event is broadcasted on the root scope. + * + * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive + * + * If the option is set to `true`, then the particular route can be matched without being + * case sensitive + * + * @returns {Object} self + * + * @description + * Adds a new route definition to the `$route` service. + */ + this.when = function(path, route) { + routes[path] = angular.extend( + {reloadOnSearch: true}, + route, + path && pathRegExp(path, route) + ); + + // create redirection for trailing slashes + if (path) { + var redirectPath = (path[path.length-1] == '/') + ? path.substr(0, path.length-1) + : path +'/'; + + routes[redirectPath] = angular.extend( + {redirectTo: path}, + pathRegExp(redirectPath, route) + ); + } + + return this; + }; + + /** + * @param path {string} path + * @param opts {Object} options + * @return {?Object} + * + * @description + * Normalizes the given path, returning a regular expression + * and the original path. + * + * Inspired by pathRexp in visionmedia/express/lib/utils.js. + */ + function pathRegExp(path, opts) { + var insensitive = opts.caseInsensitiveMatch, + ret = { + originalPath: path, + regexp: path + }, + keys = ret.keys = []; + + path = path + .replace(/([().])/g, '\\$1') + .replace(/(\/)?:(\w+)([\?|\*])?/g, function(_, slash, key, option){ + var optional = option === '?' ? option : null; + var star = option === '*' ? option : null; + keys.push({ name: key, optional: !!optional }); + slash = slash || ''; + return '' + + (optional ? '' : slash) + + '(?:' + + (optional ? slash : '') + + (star && '(.+?)' || '([^/]+)') + + (optional || '') + + ')' + + (optional || ''); + }) + .replace(/([\/$\*])/g, '\\$1'); + + ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : ''); + return ret; + } + + /** + * @ngdoc method + * @name ngRoute.$routeProvider#otherwise + * @methodOf ngRoute.$routeProvider + * + * @description + * Sets route definition that will be used on route change when no other route definition + * is matched. + * + * @param {Object} params Mapping information to be assigned to `$route.current`. + * @returns {Object} self + */ + this.otherwise = function(params) { + this.when(null, params); + return this; + }; + + + this.$get = ['$rootScope', + '$location', + '$routeParams', + '$q', + '$injector', + '$http', + '$templateCache', + '$sce', + function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) { + + /** + * @ngdoc object + * @name ngRoute.$route + * @requires $location + * @requires $routeParams + * + * @property {Object} current Reference to the current route definition. + * The route definition contains: + * + * - `controller`: The controller constructor as define in route definition. + * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for + * controller instantiation. The `locals` contain + * the resolved values of the `resolve` map. Additionally the `locals` also contain: + * + * - `$scope` - The current route scope. + * - `$template` - The current route template HTML. + * + * @property {Array.} routes Array of all configured routes. + * + * @description + * `$route` is used for deep-linking URLs to controllers and views (HTML partials). + * It watches `$location.url()` and tries to map the path to an existing route definition. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API. + * + * The `$route` service is typically used in conjunction with the + * {@link ngRoute.directive:ngView `ngView`} directive and the + * {@link ngRoute.$routeParams `$routeParams`} service. + * + * @example + This example shows how changing the URL hash causes the `$route` to match a route against the + URL, and the `ngView` pulls in the partial. + + Note that this example is using {@link ng.directive:script inlined templates} + to get it working on jsfiddle as well. + + + +
+ Choose: + Moby | + Moby: Ch1 | + Gatsby | + Gatsby: Ch4 | + Scarlet Letter
+ +
+
+ +
$location.path() = {{$location.path()}}
+
$route.current.templateUrl = {{$route.current.templateUrl}}
+
$route.current.params = {{$route.current.params}}
+
$route.current.scope.name = {{$route.current.scope.name}}
+
$routeParams = {{$routeParams}}
+
+
+ + + controller: {{name}}
+ Book Id: {{params.bookId}}
+
+ + + controller: {{name}}
+ Book Id: {{params.bookId}}
+ Chapter Id: {{params.chapterId}} +
+ + + angular.module('ngViewExample', ['ngRoute']) + + .config(function($routeProvider, $locationProvider) { + $routeProvider.when('/Book/:bookId', { + templateUrl: 'book.html', + controller: BookCntl, + resolve: { + // I will cause a 1 second delay + delay: function($q, $timeout) { + var delay = $q.defer(); + $timeout(delay.resolve, 1000); + return delay.promise; + } + } + }); + $routeProvider.when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: ChapterCntl + }); + + // configure html5 to get links working on jsfiddle + $locationProvider.html5Mode(true); + }); + + function MainCntl($scope, $route, $routeParams, $location) { + $scope.$route = $route; + $scope.$location = $location; + $scope.$routeParams = $routeParams; + } + + function BookCntl($scope, $routeParams) { + $scope.name = "BookCntl"; + $scope.params = $routeParams; + } + + function ChapterCntl($scope, $routeParams) { + $scope.name = "ChapterCntl"; + $scope.params = $routeParams; + } + + + + it('should load and compile correct template', function() { + element('a:contains("Moby: Ch1")').click(); + var content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: ChapterCntl/); + expect(content).toMatch(/Book Id\: Moby/); + expect(content).toMatch(/Chapter Id\: 1/); + + element('a:contains("Scarlet")').click(); + sleep(2); // promises are not part of scenario waiting + content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: BookCntl/); + expect(content).toMatch(/Book Id\: Scarlet/); + }); + +
+ */ + + /** + * @ngdoc event + * @name ngRoute.$route#$routeChangeStart + * @eventOf ngRoute.$route + * @eventType broadcast on root scope + * @description + * Broadcasted before a route change. At this point the route services starts + * resolving all of the dependencies needed for the route change to occurs. + * Typically this involves fetching the view template as well as any dependencies + * defined in `resolve` route property. Once all of the dependencies are resolved + * `$routeChangeSuccess` is fired. + * + * @param {Object} angularEvent Synthetic event object. + * @param {Route} next Future route information. + * @param {Route} current Current route information. + */ + + /** + * @ngdoc event + * @name ngRoute.$route#$routeChangeSuccess + * @eventOf ngRoute.$route + * @eventType broadcast on root scope + * @description + * Broadcasted after a route dependencies are resolved. + * {@link ngRoute.directive:ngView ngView} listens for the directive + * to instantiate the controller and render the view. + * + * @param {Object} angularEvent Synthetic event object. + * @param {Route} current Current route information. + * @param {Route|Undefined} previous Previous route information, or undefined if current is + * first route entered. + */ + + /** + * @ngdoc event + * @name ngRoute.$route#$routeChangeError + * @eventOf ngRoute.$route + * @eventType broadcast on root scope + * @description + * Broadcasted if any of the resolve promises are rejected. + * + * @param {Object} angularEvent Synthetic event object + * @param {Route} current Current route information. + * @param {Route} previous Previous route information. + * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise. + */ + + /** + * @ngdoc event + * @name ngRoute.$route#$routeUpdate + * @eventOf ngRoute.$route + * @eventType broadcast on root scope + * @description + * + * The `reloadOnSearch` property has been set to false, and we are reusing the same + * instance of the Controller. + */ + + var forceReload = false, + $route = { + routes: routes, + + /** + * @ngdoc method + * @name ngRoute.$route#reload + * @methodOf ngRoute.$route + * + * @description + * Causes `$route` service to reload the current route even if + * {@link ng.$location $location} hasn't changed. + * + * As a result of that, {@link ngRoute.directive:ngView ngView} + * creates new scope, reinstantiates the controller. + */ + reload: function() { + forceReload = true; + $rootScope.$evalAsync(updateRoute); + } + }; + + $rootScope.$on('$locationChangeSuccess', updateRoute); + + return $route; + + ///////////////////////////////////////////////////// + + /** + * @param on {string} current url + * @param route {Object} route regexp to match the url against + * @return {?Object} + * + * @description + * Check if the route matches the current url. + * + * Inspired by match in + * visionmedia/express/lib/router/router.js. + */ + function switchRouteMatcher(on, route) { + var keys = route.keys, + params = {}; + + if (!route.regexp) return null; + + var m = route.regexp.exec(on); + if (!m) return null; + + for (var i = 1, len = m.length; i < len; ++i) { + var key = keys[i - 1]; + + var val = 'string' == typeof m[i] + ? decodeURIComponent(m[i]) + : m[i]; + + if (key && val) { + params[key.name] = val; + } + } + return params; + } + + function updateRoute() { + var next = parseRoute(), + last = $route.current; + + if (next && last && next.$$route === last.$$route + && angular.equals(next.pathParams, last.pathParams) + && !next.reloadOnSearch && !forceReload) { + last.params = next.params; + angular.copy(last.params, $routeParams); + $rootScope.$broadcast('$routeUpdate', last); + } else if (next || last) { + forceReload = false; + $rootScope.$broadcast('$routeChangeStart', next, last); + $route.current = next; + if (next) { + if (next.redirectTo) { + if (angular.isString(next.redirectTo)) { + $location.path(interpolate(next.redirectTo, next.params)).search(next.params) + .replace(); + } else { + $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search())) + .replace(); + } + } + } + + $q.when(next). + then(function() { + if (next) { + var locals = angular.extend({}, next.resolve), + template, templateUrl; + + angular.forEach(locals, function(value, key) { + locals[key] = angular.isString(value) ? + $injector.get(value) : $injector.invoke(value); + }); + + if (angular.isDefined(template = next.template)) { + if (angular.isFunction(template)) { + template = template(next.params); + } + } else if (angular.isDefined(templateUrl = next.templateUrl)) { + if (angular.isFunction(templateUrl)) { + templateUrl = templateUrl(next.params); + } + templateUrl = $sce.getTrustedResourceUrl(templateUrl); + if (angular.isDefined(templateUrl)) { + next.loadedTemplateUrl = templateUrl; + template = $http.get(templateUrl, {cache: $templateCache}). + then(function(response) { return response.data; }); + } + } + if (angular.isDefined(template)) { + locals['$template'] = template; + } + return $q.all(locals); + } + }). + // after route change + then(function(locals) { + if (next == $route.current) { + if (next) { + next.locals = locals; + angular.copy(next.params, $routeParams); + } + $rootScope.$broadcast('$routeChangeSuccess', next, last); + } + }, function(error) { + if (next == $route.current) { + $rootScope.$broadcast('$routeChangeError', next, last, error); + } + }); + } + } + + + /** + * @returns the current active route, by matching it against the URL + */ + function parseRoute() { + // Match a route + var params, match; + angular.forEach(routes, function(route, path) { + if (!match && (params = switchRouteMatcher($location.path(), route))) { + match = inherit(route, { + params: angular.extend({}, $location.search(), params), + pathParams: params}); + match.$$route = route; + } + }); + // No route matched; fallback to "otherwise" route + return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); + } + + /** + * @returns interpolation of the redirect path with the parameters + */ + function interpolate(string, params) { + var result = []; + angular.forEach((string||'').split(':'), function(segment, i) { + if (i === 0) { + result.push(segment); + } else { + var segmentMatch = segment.match(/(\w+)(.*)/); + var key = segmentMatch[1]; + result.push(params[key]); + result.push(segmentMatch[2] || ''); + delete params[key]; + } + }); + return result.join(''); + } + }]; +} + +ngRouteModule.provider('$routeParams', $RouteParamsProvider); + + +/** + * @ngdoc object + * @name ngRoute.$routeParams + * @requires $route + * + * @description + * The `$routeParams` service allows you to retrieve the current set of route parameters. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * The route parameters are a combination of {@link ng.$location `$location`}'s + * {@link ng.$location#methods_search `search()`} and {@link ng.$location#methods_path `path()`}. + * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched. + * + * In case of parameter name collision, `path` params take precedence over `search` params. + * + * The service guarantees that the identity of the `$routeParams` object will remain unchanged + * (but its properties will likely change) even when a route change occurs. + * + * Note that the `$routeParams` are only updated *after* a route change completes successfully. + * This means that you cannot rely on `$routeParams` being correct in route resolve functions. + * Instead you can use `$route.current.params` to access the new route's parameters. + * + * @example + *
+ *  // Given:
+ *  // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
+ *  // Route: /Chapter/:chapterId/Section/:sectionId
+ *  //
+ *  // Then
+ *  $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
+ * 
+ */ +function $RouteParamsProvider() { + this.$get = function() { return {}; }; +} + +ngRouteModule.directive('ngView', ngViewFactory); + +/** + * @ngdoc directive + * @name ngRoute.directive:ngView + * @restrict ECA + * + * @description + * # Overview + * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by + * including the rendered template of the current route into the main layout (`index.html`) file. + * Every time the current route changes, the included view changes with it according to the + * configuration of the `$route` service. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * @animations + * enter - animation is used to bring new content into the browser. + * leave - animation is used to animate existing content away. + * + * The enter and leave animation occur concurrently. + * + * @scope + * @priority 400 + * @example + + +
+ Choose: + Moby | + Moby: Ch1 | + Gatsby | + Gatsby: Ch4 | + Scarlet Letter
+ +
+
+
+
+ +
$location.path() = {{main.$location.path()}}
+
$route.current.templateUrl = {{main.$route.current.templateUrl}}
+
$route.current.params = {{main.$route.current.params}}
+
$route.current.scope.name = {{main.$route.current.scope.name}}
+
$routeParams = {{main.$routeParams}}
+
+
+ + +
+ controller: {{book.name}}
+ Book Id: {{book.params.bookId}}
+
+
+ + +
+ controller: {{chapter.name}}
+ Book Id: {{chapter.params.bookId}}
+ Chapter Id: {{chapter.params.chapterId}} +
+
+ + + .view-animate-container { + position:relative; + height:100px!important; + position:relative; + background:white; + border:1px solid black; + height:40px; + overflow:hidden; + } + + .view-animate { + padding:10px; + } + + .view-animate.ng-enter, .view-animate.ng-leave { + -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + + display:block; + width:100%; + border-left:1px solid black; + + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + padding:10px; + } + + .view-animate.ng-enter { + left:100%; + } + .view-animate.ng-enter.ng-enter-active { + left:0; + } + .view-animate.ng-leave.ng-leave-active { + left:-100%; + } + + + + angular.module('ngViewExample', ['ngRoute', 'ngAnimate'], + function($routeProvider, $locationProvider) { + $routeProvider.when('/Book/:bookId', { + templateUrl: 'book.html', + controller: BookCntl, + controllerAs: 'book' + }); + $routeProvider.when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: ChapterCntl, + controllerAs: 'chapter' + }); + + // configure html5 to get links working on jsfiddle + $locationProvider.html5Mode(true); + }); + + function MainCntl($route, $routeParams, $location) { + this.$route = $route; + this.$location = $location; + this.$routeParams = $routeParams; + } + + function BookCntl($routeParams) { + this.name = "BookCntl"; + this.params = $routeParams; + } + + function ChapterCntl($routeParams) { + this.name = "ChapterCntl"; + this.params = $routeParams; + } + + + + it('should load and compile correct template', function() { + element('a:contains("Moby: Ch1")').click(); + var content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: ChapterCntl/); + expect(content).toMatch(/Book Id\: Moby/); + expect(content).toMatch(/Chapter Id\: 1/); + + element('a:contains("Scarlet")').click(); + content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: BookCntl/); + expect(content).toMatch(/Book Id\: Scarlet/); + }); + +
+ */ + + +/** + * @ngdoc event + * @name ngRoute.directive:ngView#$viewContentLoaded + * @eventOf ngRoute.directive:ngView + * @eventType emit on the current ngView scope + * @description + * Emitted every time the ngView content is reloaded. + */ +ngViewFactory.$inject = ['$route', '$anchorScroll', '$compile', '$controller', '$animate']; +function ngViewFactory( $route, $anchorScroll, $compile, $controller, $animate) { + return { + restrict: 'ECA', + terminal: true, + priority: 400, + transclude: 'element', + link: function(scope, $element, attr, ctrl, $transclude) { + var currentScope, + currentElement, + autoScrollExp = attr.autoscroll, + onloadExp = attr.onload || ''; + + scope.$on('$routeChangeSuccess', update); + update(); + + function cleanupLastView() { + if (currentScope) { + currentScope.$destroy(); + currentScope = null; + } + if(currentElement) { + $animate.leave(currentElement); + currentElement = null; + } + } + + function update() { + var locals = $route.current && $route.current.locals, + template = locals && locals.$template; + + if (template) { + var newScope = scope.$new(); + + // Note: This will also link all children of ng-view that were contained in the original + // html. If that content contains controllers, ... they could pollute/change the scope. + // However, using ng-view on an element with additional content does not make sense... + // Note: We can't remove them in the cloneAttchFn of $transclude as that + // function is called before linking the content, which would apply child + // directives to non existing elements. + var clone = $transclude(newScope, angular.noop); + clone.html(template); + $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () { + if (angular.isDefined(autoScrollExp) + && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + }); + + cleanupLastView(); + + var link = $compile(clone.contents()), + current = $route.current; + + currentScope = current.scope = newScope; + currentElement = clone; + + if (current.controller) { + locals.$scope = currentScope; + var controller = $controller(current.controller, locals); + if (current.controllerAs) { + currentScope[current.controllerAs] = controller; + } + clone.data('$ngControllerController', controller); + clone.children().data('$ngControllerController', controller); + } + + link(currentScope); + currentScope.$emit('$viewContentLoaded'); + currentScope.$eval(onloadExp); + } else { + cleanupLastView(); + } + } + } + }; +} + + +})(window, window.angular); diff --git a/vendor/angular/angular-route.min.js b/vendor/angular/angular-route.min.js new file mode 100644 index 00000000..5870a6a8 --- /dev/null +++ b/vendor/angular/angular-route.min.js @@ -0,0 +1,14 @@ +/* + AngularJS v1.2.3 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(t,c,A){'use strict';function x(r,m,d,b,h){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(l,z,k,B,w){function v(){g&&(g.$destroy(),g=null);q&&(h.leave(q),q=null)}function u(){var a=r.current&&r.current.locals,e=a&&a.$template;if(e){var y=l.$new(),s=w(y,c.noop);s.html(e);h.enter(s,null,q||z,function(){!c.isDefined(n)||n&&!l.$eval(n)||m()});v();var e=d(s.contents()),f=r.current;g=f.scope=y;q=s;f.controller&&(a.$scope=g,a=b(f.controller,a),f.controllerAs&& +(g[f.controllerAs]=a),s.data("$ngControllerController",a),s.children().data("$ngControllerController",a));e(g);g.$emit("$viewContentLoaded");g.$eval(p)}else v()}var g,q,n=k.autoscroll,p=k.onload||"";l.$on("$routeChangeSuccess",u);u()}}}t=c.module("ngRoute",["ng"]).provider("$route",function(){function r(b,h){return c.extend(new (c.extend(function(){},{prototype:b})),h)}function m(b,c){var l=c.caseInsensitiveMatch,d={originalPath:b,regexp:b},k=d.keys=[];b=b.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?|\*])?/g, +function(b,c,h,d){b="?"===d?d:null;d="*"===d?d:null;k.push({name:h,optional:!!b});c=c||"";return""+(b?"":c)+"(?:"+(b?c:"")+(d&&"(.+?)"||"([^/]+)")+(b||"")+")"+(b||"")}).replace(/([\/$\*])/g,"\\$1");d.regexp=RegExp("^"+b+"$",l?"i":"");return d}var d={};this.when=function(b,h){d[b]=c.extend({reloadOnSearch:!0},h,b&&m(b,h));if(b){var l="/"==b[b.length-1]?b.substr(0,b.length-1):b+"/";d[l]=c.extend({redirectTo:b},m(l,h))}return this};this.otherwise=function(b){this.when(null,b);return this};this.$get= +["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(b,h,l,m,k,t,w,v){function u(){var a=g(),e=p.current;if(a&&e&&a.$$route===e.$$route&&c.equals(a.pathParams,e.pathParams)&&!a.reloadOnSearch&&!n)e.params=a.params,c.copy(e.params,l),b.$broadcast("$routeUpdate",e);else if(a||e)n=!1,b.$broadcast("$routeChangeStart",a,e),(p.current=a)&&a.redirectTo&&(c.isString(a.redirectTo)?h.path(q(a.redirectTo,a.params)).search(a.params).replace():h.url(a.redirectTo(a.pathParams, +h.path(),h.search())).replace()),m.when(a).then(function(){if(a){var b=c.extend({},a.resolve),e,f;c.forEach(b,function(a,e){b[e]=c.isString(a)?k.get(a):k.invoke(a)});c.isDefined(e=a.template)?c.isFunction(e)&&(e=e(a.params)):c.isDefined(f=a.templateUrl)&&(c.isFunction(f)&&(f=f(a.params)),f=v.getTrustedResourceUrl(f),c.isDefined(f)&&(a.loadedTemplateUrl=f,e=t.get(f,{cache:w}).then(function(a){return a.data})));c.isDefined(e)&&(b.$template=e);return m.all(b)}}).then(function(d){a==p.current&&(a&&(a.locals= +d,c.copy(a.params,l)),b.$broadcast("$routeChangeSuccess",a,e))},function(c){a==p.current&&b.$broadcast("$routeChangeError",a,e,c)})}function g(){var a,b;c.forEach(d,function(d,l){var f;if(f=!b){var g=h.path();f=d.keys;var m={};if(d.regexp)if(g=d.regexp.exec(g)){for(var k=1,q=g.length;k + * + * See {@link ngSanitize.$sanitize `$sanitize`} for usage. + */ + +/* + * HTML Parser By Misko Hevery (misko@hevery.com) + * based on: HTML Parser By John Resig (ejohn.org) + * Original code by Erik Arvidsson, Mozilla Public License + * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js + * + * // Use like so: + * htmlParser(htmlString, { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * }); + * + */ + + +/** + * @ngdoc service + * @name ngSanitize.$sanitize + * @function + * + * @description + * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are + * then serialized back to properly escaped html string. This means that no unsafe input can make + * it into the returned string, however, since our parser is more strict than a typical browser + * parser, it's possible that some obscure input, which would be recognized as valid HTML by a + * browser, won't make it through the sanitizer. + * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and + * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}. + * + * @param {string} html Html input. + * @returns {string} Sanitized html. + * + * @example + + + +
+ Snippet: + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectiveHowSourceRendered
ng-bind-htmlAutomatically uses $sanitize
<div ng-bind-html="snippet">
</div>
ng-bind-htmlBypass $sanitize by explicitly trusting the dangerous value +
<div ng-bind-html="deliberatelyTrustDangerousSnippet()">
+</div>
+
ng-bindAutomatically escapes
<div ng-bind="snippet">
</div>
+
+
+ + it('should sanitize the html snippet by default', function() { + expect(using('#bind-html-with-sanitize').element('div').html()). + toBe('

an html\nclick here\nsnippet

'); + }); + + it('should inline raw snippet if bound to a trusted value', function() { + expect(using('#bind-html-with-trust').element("div").html()). + toBe("

an html\n" + + "click here\n" + + "snippet

"); + }); + + it('should escape snippet without any filter', function() { + expect(using('#bind-default').element('div').html()). + toBe("<p style=\"color:blue\">an html\n" + + "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + + "snippet</p>"); + }); + + it('should update', function() { + input('snippet').enter('new text'); + expect(using('#bind-html-with-sanitize').element('div').html()).toBe('new text'); + expect(using('#bind-html-with-trust').element('div').html()).toBe( + 'new text'); + expect(using('#bind-default').element('div').html()).toBe( + "new <b onclick=\"alert(1)\">text</b>"); + }); +
+
+ */ +function $SanitizeProvider() { + this.$get = ['$$sanitizeUri', function($$sanitizeUri) { + return function(html) { + var buf = []; + htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) { + return !/^unsafe/.test($$sanitizeUri(uri, isImage)); + })); + return buf.join(''); + }; + }]; +} + +function sanitizeText(chars) { + var buf = []; + var writer = htmlSanitizeWriter(buf, angular.noop); + writer.chars(chars); + return buf.join(''); +} + + +// Regular Expressions for parsing tags and attributes +var START_TAG_REGEXP = + /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, + END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/, + ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, + BEGIN_TAG_REGEXP = /^/g, + DOCTYPE_REGEXP = /]*?)>/i, + CDATA_REGEXP = //g, + // Match everything outside of normal chars and " (quote character) + NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; + + +// Good source of info about elements and attributes +// http://dev.w3.org/html5/spec/Overview.html#semantics +// http://simon.html5.org/html-elements + +// Safe Void Elements - HTML5 +// http://dev.w3.org/html5/spec/Overview.html#void-elements +var voidElements = makeMap("area,br,col,hr,img,wbr"); + +// Elements that you can, intentionally, leave open (and which close themselves) +// http://dev.w3.org/html5/spec/Overview.html#optional-tags +var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"), + optionalEndTagInlineElements = makeMap("rp,rt"), + optionalEndTagElements = angular.extend({}, + optionalEndTagInlineElements, + optionalEndTagBlockElements); + +// Safe Block Elements - HTML5 +var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," + + "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," + + "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")); + +// Inline Elements - HTML5 +var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," + + "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," + + "samp,small,span,strike,strong,sub,sup,time,tt,u,var")); + + +// Special Elements (can contain anything) +var specialElements = makeMap("script,style"); + +var validElements = angular.extend({}, + voidElements, + blockElements, + inlineElements, + optionalEndTagElements); + +//Attributes that have href and hence need to be sanitized +var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap"); +var validAttrs = angular.extend({}, uriAttrs, makeMap( + 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+ + 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+ + 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+ + 'scope,scrolling,shape,span,start,summary,target,title,type,'+ + 'valign,value,vspace,width')); + +function makeMap(str) { + var obj = {}, items = str.split(','), i; + for (i = 0; i < items.length; i++) obj[items[i]] = true; + return obj; +} + + +/** + * @example + * htmlParser(htmlString, { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * }); + * + * @param {string} html string + * @param {object} handler + */ +function htmlParser( html, handler ) { + var index, chars, match, stack = [], last = html; + stack.last = function() { return stack[ stack.length - 1 ]; }; + + while ( html ) { + chars = true; + + // Make sure we're not in a script or style element + if ( !stack.last() || !specialElements[ stack.last() ] ) { + + // Comment + if ( html.indexOf("", index) === index) { + if (handler.comment) handler.comment( html.substring( 4, index ) ); + html = html.substring( index + 3 ); + chars = false; + } + // DOCTYPE + } else if ( DOCTYPE_REGEXP.test(html) ) { + match = html.match( DOCTYPE_REGEXP ); + + if ( match ) { + html = html.replace( match[0] , ''); + chars = false; + } + // end tag + } else if ( BEGING_END_TAGE_REGEXP.test(html) ) { + match = html.match( END_TAG_REGEXP ); + + if ( match ) { + html = html.substring( match[0].length ); + match[0].replace( END_TAG_REGEXP, parseEndTag ); + chars = false; + } + + // start tag + } else if ( BEGIN_TAG_REGEXP.test(html) ) { + match = html.match( START_TAG_REGEXP ); + + if ( match ) { + html = html.substring( match[0].length ); + match[0].replace( START_TAG_REGEXP, parseStartTag ); + chars = false; + } + } + + if ( chars ) { + index = html.indexOf("<"); + + var text = index < 0 ? html : html.substring( 0, index ); + html = index < 0 ? "" : html.substring( index ); + + if (handler.chars) handler.chars( decodeEntities(text) ); + } + + } else { + html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'), + function(all, text){ + text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1"); + + if (handler.chars) handler.chars( decodeEntities(text) ); + + return ""; + }); + + parseEndTag( "", stack.last() ); + } + + if ( html == last ) { + throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " + + "of html: {0}", html); + } + last = html; + } + + // Clean up any remaining tags + parseEndTag(); + + function parseStartTag( tag, tagName, rest, unary ) { + tagName = angular.lowercase(tagName); + if ( blockElements[ tagName ] ) { + while ( stack.last() && inlineElements[ stack.last() ] ) { + parseEndTag( "", stack.last() ); + } + } + + if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) { + parseEndTag( "", tagName ); + } + + unary = voidElements[ tagName ] || !!unary; + + if ( !unary ) + stack.push( tagName ); + + var attrs = {}; + + rest.replace(ATTR_REGEXP, + function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) { + var value = doubleQuotedValue + || singleQuotedValue + || unquotedValue + || ''; + + attrs[name] = decodeEntities(value); + }); + if (handler.start) handler.start( tagName, attrs, unary ); + } + + function parseEndTag( tag, tagName ) { + var pos = 0, i; + tagName = angular.lowercase(tagName); + if ( tagName ) + // Find the closest opened tag of the same type + for ( pos = stack.length - 1; pos >= 0; pos-- ) + if ( stack[ pos ] == tagName ) + break; + + if ( pos >= 0 ) { + // Close all the open elements, up the stack + for ( i = stack.length - 1; i >= pos; i-- ) + if (handler.end) handler.end( stack[ i ] ); + + // Remove the open elements from the stack + stack.length = pos; + } + } +} + +/** + * decodes all entities into regular string + * @param value + * @returns {string} A string with decoded entities. + */ +var hiddenPre=document.createElement("pre"); +function decodeEntities(value) { + if (!value) { + return ''; + } + // Note: IE8 does not preserve spaces at the start/end of innerHTML + var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/; + var parts = spaceRe.exec(value); + parts[0] = ''; + if (parts[2]) { + hiddenPre.innerHTML=parts[2].replace(//g, '>'); +} + +/** + * create an HTML/XML writer which writes to buffer + * @param {Array} buf use buf.jain('') to get out sanitized html string + * @returns {object} in the form of { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * } + */ +function htmlSanitizeWriter(buf, uriValidator){ + var ignore = false; + var out = angular.bind(buf, buf.push); + return { + start: function(tag, attrs, unary){ + tag = angular.lowercase(tag); + if (!ignore && specialElements[tag]) { + ignore = tag; + } + if (!ignore && validElements[tag] === true) { + out('<'); + out(tag); + angular.forEach(attrs, function(value, key){ + var lkey=angular.lowercase(key); + var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); + if (validAttrs[lkey] === true && + (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { + out(' '); + out(key); + out('="'); + out(encodeEntities(value)); + out('"'); + } + }); + out(unary ? '/>' : '>'); + } + }, + end: function(tag){ + tag = angular.lowercase(tag); + if (!ignore && validElements[tag] === true) { + out(''); + } + if (tag == ignore) { + ignore = false; + } + }, + chars: function(chars){ + if (!ignore) { + out(encodeEntities(chars)); + } + } + }; +} + + +// define ngSanitize module and register $sanitize service +angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider); + +/* global sanitizeText: false */ + +/** + * @ngdoc filter + * @name ngSanitize.filter:linky + * @function + * + * @description + * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and + * plain email address links. + * + * Requires the {@link ngSanitize `ngSanitize`} module to be installed. + * + * @param {string} text Input text. + * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in. + * @returns {string} Html-linkified text. + * + * @usage + + * + * @example + + + +
+ Snippet: + + + + + + + + + + + + + + + + + + + + + +
FilterSourceRendered
linky filter +
<div ng-bind-html="snippet | linky">
</div>
+
+
+
linky target +
<div ng-bind-html="snippetWithTarget | linky:'_blank'">
</div>
+
+
+
no filter
<div ng-bind="snippet">
</div>
+ + + it('should linkify the snippet with urls', function() { + expect(using('#linky-filter').binding('snippet | linky')). + toBe('Pretty text with some links: ' + + 'http://angularjs.org/, ' + + 'us@somewhere.org, ' + + 'another@somewhere.org, ' + + 'and one more: ftp://127.0.0.1/.'); + }); + + it ('should not linkify snippet without the linky filter', function() { + expect(using('#escaped-html').binding('snippet')). + toBe("Pretty text with some links:\n" + + "http://angularjs.org/,\n" + + "mailto:us@somewhere.org,\n" + + "another@somewhere.org,\n" + + "and one more: ftp://127.0.0.1/."); + }); + + it('should update', function() { + input('snippet').enter('new http://link.'); + expect(using('#linky-filter').binding('snippet | linky')). + toBe('new http://link.'); + expect(using('#escaped-html').binding('snippet')).toBe('new http://link.'); + }); + + it('should work with the target property', function() { + expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")). + toBe('http://angularjs.org/'); + }); + + + */ +angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { + var LINKY_URL_REGEXP = + /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/, + MAILTO_REGEXP = /^mailto:/; + + return function(text, target) { + if (!text) return text; + var match; + var raw = text; + var html = []; + var url; + var i; + while ((match = raw.match(LINKY_URL_REGEXP))) { + // We can not end in these as they are sometimes found at the end of the sentence + url = match[0]; + // if we did not match ftp/http/mailto then assume mailto + if (match[2] == match[3]) url = 'mailto:' + url; + i = match.index; + addText(raw.substr(0, i)); + addLink(url, match[0].replace(MAILTO_REGEXP, '')); + raw = raw.substring(i + match[0].length); + } + addText(raw); + return $sanitize(html.join('')); + + function addText(text) { + if (!text) { + return; + } + html.push(sanitizeText(text)); + } + + function addLink(url, text) { + html.push(''); + addText(text); + html.push(''); + } + }; +}]); + + +})(window, window.angular); diff --git a/vendor/angular/angular-sanitize.min.js b/vendor/angular/angular-sanitize.min.js new file mode 100644 index 00000000..ed3ec446 --- /dev/null +++ b/vendor/angular/angular-sanitize.min.js @@ -0,0 +1,14 @@ +/* + AngularJS v1.2.3 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(n,h,q){'use strict';function F(a){var e=[];t(e,h.noop).chars(a);return e.join("")}function k(a){var e={};a=a.split(",");var d;for(d=0;d=c;d--)e.end&&e.end(f[d]);f.length=c}}var b,g,f=[],l=a;for(f.last=function(){return f[f.length-1]};a;){g=!0;if(f.last()&&y[f.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(a,b){b=b.replace(I,"$1").replace(J,"$1");e.chars&&e.chars(r(b));return""}),c("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(e.comment&&e.comment(a.substring(4,b)),a=a.substring(b+3),g=!1);else if(z.test(a)){if(b=a.match(z))a= +a.replace(b[0],""),g=!1}else if(K.test(a)){if(b=a.match(A))a=a.substring(b[0].length),b[0].replace(A,c),g=!1}else L.test(a)&&(b=a.match(B))&&(a=a.substring(b[0].length),b[0].replace(B,d),g=!1);g&&(b=a.indexOf("<"),g=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),e.chars&&e.chars(r(g)))}if(a==l)throw M("badparse",a);l=a}c()}function r(a){if(!a)return"";a=/^(\s*)([\s\S]*?)(\s*)$/.exec(a);a[0]="";a[2]&&(s.innerHTML=a[2].replace(//g,">")}function t(a,e){var d=!1,c=h.bind(a,a.push);return{start:function(a,g,f){a=h.lowercase(a);!d&&y[a]&&(d=a);d||!0!==D[a]||(c("<"),c(a),h.forEach(g,function(d,f){var g=h.lowercase(f),k="img"===a&&"src"===g||"background"===g;!0!==O[g]||!0===E[g]&&!e(d,k)||(c(" "),c(f),c('="'),c(C(d)),c('"'))}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==D[a]||(c(""));a==d&&(d=!1)},chars:function(a){d|| +c(C(a))}}}var M=h.$$minErr("$sanitize"),B=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,A=/^<\s*\/\s*([\w:-]+)[^>]*>/,H=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,L=/^]*?)>/i,J=/]/,d=/^mailto:/;return function(c,b){function g(a){a&&m.push(F(a))}function f(a,c){m.push("');g(c);m.push("")}if(!c)return c;for(var l,k=c,m=[],p,n;l=k.match(e);)p=l[0],l[2]==l[3]&&(p="mailto:"+p),n=l.index,g(k.substr(0,n)),f(p,l[0].replace(d,"")),k=k.substring(n+l[0].length);g(k);return a(m.join(""))}}])})(window,window.angular); +//# sourceMappingURL=angular-sanitize.min.js.map diff --git a/vendor/angular/angular-sanitize.min.js.map b/vendor/angular/angular-sanitize.min.js.map new file mode 100644 index 00000000..f211e9a6 --- /dev/null +++ b/vendor/angular/angular-sanitize.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"angular-sanitize.min.js", +"lineCount":13, +"mappings":"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", +"sources":["angular-sanitize.js"], +"names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","makeMap","str","obj","items","split","i","length","htmlParser","html","handler","parseStartTag","tag","tagName","rest","unary","lowercase","blockElements","stack","last","inlineElements","parseEndTag","optionalEndTagElements","voidElements","push","attrs","replace","ATTR_REGEXP","match","name","doubleQuotedValue","singleQuotedValue","unquotedValue","decodeEntities","start","pos","end","index","stack.last","specialElements","RegExp","all","text","COMMENT_REGEXP","CDATA_REGEXP","indexOf","lastIndexOf","comment","substring","DOCTYPE_REGEXP","test","BEGING_END_TAGE_REGEXP","END_TAG_REGEXP","BEGIN_TAG_REGEXP","START_TAG_REGEXP","$sanitizeMinErr","value","parts","spaceRe","exec","hiddenPre","innerHTML","innerText","textContent","encodeEntities","NON_ALPHANUMERIC_REGEXP","charCodeAt","uriValidator","ignore","out","bind","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","extend","document","createElement","module","provider","$SanitizeProvider","$get","$$sanitizeUri","uri","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","target","addText","addLink","url","isDefined","raw","substr"] +} diff --git a/vendor/angular/angular-touch.js b/vendor/angular/angular-touch.js new file mode 100644 index 00000000..cd45d0cf --- /dev/null +++ b/vendor/angular/angular-touch.js @@ -0,0 +1,563 @@ +/** + * @license AngularJS v1.2.3 + * (c) 2010-2014 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +/** + * @ngdoc overview + * @name ngTouch + * @description + * + * # ngTouch + * + * The `ngTouch` module provides touch events and other helpers for touch-enabled devices. + * The implementation is based on jQuery Mobile touch event handling + * ([jquerymobile.com](http://jquerymobile.com/)). + * + * {@installModule touch} + * + * See {@link ngTouch.$swipe `$swipe`} for usage. + * + *
+ * + */ + +// define ngTouch module +/* global -ngTouch */ +var ngTouch = angular.module('ngTouch', []); + +/* global ngTouch: false */ + + /** + * @ngdoc object + * @name ngTouch.$swipe + * + * @description + * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe + * behavior, to make implementing swipe-related directives more convenient. + * + * Requires the {@link ngTouch `ngTouch`} module to be installed. + * + * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by + * `ngCarousel` in a separate component. + * + * # Usage + * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element + * which is to be watched for swipes, and an object with four handler functions. See the + * documentation for `bind` below. + */ + +ngTouch.factory('$swipe', [function() { + // The total distance in any direction before we make the call on swipe vs. scroll. + var MOVE_BUFFER_RADIUS = 10; + + function getCoordinates(event) { + var touches = event.touches && event.touches.length ? event.touches : [event]; + var e = (event.changedTouches && event.changedTouches[0]) || + (event.originalEvent && event.originalEvent.changedTouches && + event.originalEvent.changedTouches[0]) || + touches[0].originalEvent || touches[0]; + + return { + x: e.clientX, + y: e.clientY + }; + } + + return { + /** + * @ngdoc method + * @name ngTouch.$swipe#bind + * @methodOf ngTouch.$swipe + * + * @description + * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an + * object containing event handlers. + * + * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end` + * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`. + * + * `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is + * watching for `touchmove` or `mousemove` events. These events are ignored until the total + * distance moved in either dimension exceeds a small threshold. + * + * Once this threshold is exceeded, either the horizontal or vertical delta is greater. + * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow. + * - If the vertical distance is greater, this is a scroll, and we let the browser take over. + * A `cancel` event is sent. + * + * `move` is called on `mousemove` and `touchmove` after the above logic has determined that + * a swipe is in progress. + * + * `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`. + * + * `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling + * as described above. + * + */ + bind: function(element, eventHandlers) { + // Absolute total movement, used to control swipe vs. scroll. + var totalX, totalY; + // Coordinates of the start position. + var startCoords; + // Last event's position. + var lastPos; + // Whether a swipe is active. + var active = false; + + element.on('touchstart mousedown', function(event) { + startCoords = getCoordinates(event); + active = true; + totalX = 0; + totalY = 0; + lastPos = startCoords; + eventHandlers['start'] && eventHandlers['start'](startCoords, event); + }); + + element.on('touchcancel', function(event) { + active = false; + eventHandlers['cancel'] && eventHandlers['cancel'](event); + }); + + element.on('touchmove mousemove', function(event) { + if (!active) return; + + // Android will send a touchcancel if it thinks we're starting to scroll. + // So when the total distance (+ or - or both) exceeds 10px in either direction, + // we either: + // - On totalX > totalY, we send preventDefault() and treat this as a swipe. + // - On totalY > totalX, we let the browser handle it as a scroll. + + if (!startCoords) return; + var coords = getCoordinates(event); + + totalX += Math.abs(coords.x - lastPos.x); + totalY += Math.abs(coords.y - lastPos.y); + + lastPos = coords; + + if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) { + return; + } + + // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll. + if (totalY > totalX) { + // Allow native scrolling to take over. + active = false; + eventHandlers['cancel'] && eventHandlers['cancel'](event); + return; + } else { + // Prevent the browser from scrolling. + event.preventDefault(); + eventHandlers['move'] && eventHandlers['move'](coords, event); + } + }); + + element.on('touchend mouseup', function(event) { + if (!active) return; + active = false; + eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event); + }); + } + }; +}]); + +/* global ngTouch: false */ + +/** + * @ngdoc directive + * @name ngTouch.directive:ngClick + * + * @description + * A more powerful replacement for the default ngClick designed to be used on touchscreen + * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending + * the click event. This version handles them immediately, and then prevents the + * following click event from propagating. + * + * Requires the {@link ngTouch `ngTouch`} module to be installed. + * + * This directive can fall back to using an ordinary click event, and so works on desktop + * browsers as well as mobile. + * + * This directive also sets the CSS class `ng-click-active` while the element is being held + * down (by a mouse click or touch) so you can restyle the depressed element if you wish. + * + * @element ANY + * @param {expression} ngClick {@link guide/expression Expression} to evaluate + * upon tap. (Event object is available as `$event`) + * + * @example + + + + count: {{ count }} + + + */ + +ngTouch.config(['$provide', function($provide) { + $provide.decorator('ngClickDirective', ['$delegate', function($delegate) { + // drop the default ngClick directive + $delegate.shift(); + return $delegate; + }]); +}]); + +ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement', + function($parse, $timeout, $rootElement) { + var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag. + var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers. + var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click + var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks. + + var ACTIVE_CLASS_NAME = 'ng-click-active'; + var lastPreventedTime; + var touchCoordinates; + + + // TAP EVENTS AND GHOST CLICKS + // + // Why tap events? + // Mobile browsers detect a tap, then wait a moment (usually ~300ms) to see if you're + // double-tapping, and then fire a click event. + // + // This delay sucks and makes mobile apps feel unresponsive. + // So we detect touchstart, touchmove, touchcancel and touchend ourselves and determine when + // the user has tapped on something. + // + // What happens when the browser then generates a click event? + // The browser, of course, also detects the tap and fires a click after a delay. This results in + // tapping/clicking twice. So we do "clickbusting" to prevent it. + // + // How does it work? + // We attach global touchstart and click handlers, that run during the capture (early) phase. + // So the sequence for a tap is: + // - global touchstart: Sets an "allowable region" at the point touched. + // - element's touchstart: Starts a touch + // (- touchmove or touchcancel ends the touch, no click follows) + // - element's touchend: Determines if the tap is valid (didn't move too far away, didn't hold + // too long) and fires the user's tap handler. The touchend also calls preventGhostClick(). + // - preventGhostClick() removes the allowable region the global touchstart created. + // - The browser generates a click event. + // - The global click handler catches the click, and checks whether it was in an allowable region. + // - If preventGhostClick was called, the region will have been removed, the click is busted. + // - If the region is still there, the click proceeds normally. Therefore clicks on links and + // other elements without ngTap on them work normally. + // + // This is an ugly, terrible hack! + // Yeah, tell me about it. The alternatives are using the slow click events, or making our users + // deal with the ghost clicks, so I consider this the least of evils. Fortunately Angular + // encapsulates this ugly logic away from the user. + // + // Why not just put click handlers on the element? + // We do that too, just to be sure. The problem is that the tap event might have caused the DOM + // to change, so that the click fires in the same position but something else is there now. So + // the handlers are global and care only about coordinates and not elements. + + // Checks if the coordinates are close enough to be within the region. + function hit(x1, y1, x2, y2) { + return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD; + } + + // Checks a list of allowable regions against a click location. + // Returns true if the click should be allowed. + // Splices out the allowable region from the list after it has been used. + function checkAllowableRegions(touchCoordinates, x, y) { + for (var i = 0; i < touchCoordinates.length; i += 2) { + if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) { + touchCoordinates.splice(i, i + 2); + return true; // allowable region + } + } + return false; // No allowable region; bust it. + } + + // Global click handler that prevents the click if it's in a bustable zone and preventGhostClick + // was called recently. + function onClick(event) { + if (Date.now() - lastPreventedTime > PREVENT_DURATION) { + return; // Too old. + } + + var touches = event.touches && event.touches.length ? event.touches : [event]; + var x = touches[0].clientX; + var y = touches[0].clientY; + // Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label + // and on the input element). Depending on the exact browser, this second click we don't want + // to bust has either (0,0) or negative coordinates. + if (x < 1 && y < 1) { + return; // offscreen + } + + // Look for an allowable region containing this click. + // If we find one, that means it was created by touchstart and not removed by + // preventGhostClick, so we don't bust it. + if (checkAllowableRegions(touchCoordinates, x, y)) { + return; + } + + // If we didn't find an allowable region, bust the click. + event.stopPropagation(); + event.preventDefault(); + + // Blur focused form elements + event.target && event.target.blur(); + } + + + // Global touchstart handler that creates an allowable region for a click event. + // This allowable region can be removed by preventGhostClick if we want to bust it. + function onTouchStart(event) { + var touches = event.touches && event.touches.length ? event.touches : [event]; + var x = touches[0].clientX; + var y = touches[0].clientY; + touchCoordinates.push(x, y); + + $timeout(function() { + // Remove the allowable region. + for (var i = 0; i < touchCoordinates.length; i += 2) { + if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) { + touchCoordinates.splice(i, i + 2); + return; + } + } + }, PREVENT_DURATION, false); + } + + // On the first call, attaches some event handlers. Then whenever it gets called, it creates a + // zone around the touchstart where clicks will get busted. + function preventGhostClick(x, y) { + if (!touchCoordinates) { + $rootElement[0].addEventListener('click', onClick, true); + $rootElement[0].addEventListener('touchstart', onTouchStart, true); + touchCoordinates = []; + } + + lastPreventedTime = Date.now(); + + checkAllowableRegions(touchCoordinates, x, y); + } + + // Actual linking function. + return function(scope, element, attr) { + var clickHandler = $parse(attr.ngClick), + tapping = false, + tapElement, // Used to blur the element after a tap. + startTime, // Used to check if the tap was held too long. + touchStartX, + touchStartY; + + function resetState() { + tapping = false; + element.removeClass(ACTIVE_CLASS_NAME); + } + + element.on('touchstart', function(event) { + tapping = true; + tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement. + // Hack for Safari, which can target text nodes instead of containers. + if(tapElement.nodeType == 3) { + tapElement = tapElement.parentNode; + } + + element.addClass(ACTIVE_CLASS_NAME); + + startTime = Date.now(); + + var touches = event.touches && event.touches.length ? event.touches : [event]; + var e = touches[0].originalEvent || touches[0]; + touchStartX = e.clientX; + touchStartY = e.clientY; + }); + + element.on('touchmove', function(event) { + resetState(); + }); + + element.on('touchcancel', function(event) { + resetState(); + }); + + element.on('touchend', function(event) { + var diff = Date.now() - startTime; + + var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches : + ((event.touches && event.touches.length) ? event.touches : [event]); + var e = touches[0].originalEvent || touches[0]; + var x = e.clientX; + var y = e.clientY; + var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) ); + + if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) { + // Call preventGhostClick so the clickbuster will catch the corresponding click. + preventGhostClick(x, y); + + // Blur the focused element (the button, probably) before firing the callback. + // This doesn't work perfectly on Android Chrome, but seems to work elsewhere. + // I couldn't get anything to work reliably on Android Chrome. + if (tapElement) { + tapElement.blur(); + } + + if (!angular.isDefined(attr.disabled) || attr.disabled === false) { + element.triggerHandler('click', [event]); + } + } + + resetState(); + }); + + // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click + // something else nearby. + element.onclick = function(event) { }; + + // Actual click handler. + // There are three different kinds of clicks, only two of which reach this point. + // - On desktop browsers without touch events, their clicks will always come here. + // - On mobile browsers, the simulated "fast" click will call this. + // - But the browser's follow-up slow click will be "busted" before it reaches this handler. + // Therefore it's safe to use this directive on both mobile and desktop. + element.on('click', function(event, touchend) { + scope.$apply(function() { + clickHandler(scope, {$event: (touchend || event)}); + }); + }); + + element.on('mousedown', function(event) { + element.addClass(ACTIVE_CLASS_NAME); + }); + + element.on('mousemove mouseup', function(event) { + element.removeClass(ACTIVE_CLASS_NAME); + }); + + }; +}]); + +/* global ngTouch: false */ + +/** + * @ngdoc directive + * @name ngTouch.directive:ngSwipeLeft + * + * @description + * Specify custom behavior when an element is swiped to the left on a touchscreen device. + * A leftward swipe is a quick, right-to-left slide of the finger. + * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag + * too. + * + * Requires the {@link ngTouch `ngTouch`} module to be installed. + * + * @element ANY + * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate + * upon left swipe. (Event object is available as `$event`) + * + * @example + + +
+ Some list content, like an email in the inbox +
+
+ + +
+
+
+ */ + +/** + * @ngdoc directive + * @name ngTouch.directive:ngSwipeRight + * + * @description + * Specify custom behavior when an element is swiped to the right on a touchscreen device. + * A rightward swipe is a quick, left-to-right slide of the finger. + * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag + * too. + * + * Requires the {@link ngTouch `ngTouch`} module to be installed. + * + * @element ANY + * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate + * upon right swipe. (Event object is available as `$event`) + * + * @example + + +
+ Some list content, like an email in the inbox +
+
+ + +
+
+
+ */ + +function makeSwipeDirective(directiveName, direction, eventName) { + ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) { + // The maximum vertical delta for a swipe should be less than 75px. + var MAX_VERTICAL_DISTANCE = 75; + // Vertical distance should not be more than a fraction of the horizontal distance. + var MAX_VERTICAL_RATIO = 0.3; + // At least a 30px lateral motion is necessary for a swipe. + var MIN_HORIZONTAL_DISTANCE = 30; + + return function(scope, element, attr) { + var swipeHandler = $parse(attr[directiveName]); + + var startCoords, valid; + + function validSwipe(coords) { + // Check that it's within the coordinates. + // Absolute vertical distance must be within tolerances. + // Horizontal distance, we take the current X - the starting X. + // This is negative for leftward swipes and positive for rightward swipes. + // After multiplying by the direction (-1 for left, +1 for right), legal swipes + // (ie. same direction as the directive wants) will have a positive delta and + // illegal ones a negative delta. + // Therefore this delta must be positive, and larger than the minimum. + if (!startCoords) return false; + var deltaY = Math.abs(coords.y - startCoords.y); + var deltaX = (coords.x - startCoords.x) * direction; + return valid && // Short circuit for already-invalidated swipes. + deltaY < MAX_VERTICAL_DISTANCE && + deltaX > 0 && + deltaX > MIN_HORIZONTAL_DISTANCE && + deltaY / deltaX < MAX_VERTICAL_RATIO; + } + + $swipe.bind(element, { + 'start': function(coords, event) { + startCoords = coords; + valid = true; + }, + 'cancel': function(event) { + valid = false; + }, + 'end': function(coords, event) { + if (validSwipe(coords)) { + scope.$apply(function() { + element.triggerHandler(eventName); + swipeHandler(scope, {$event: event}); + }); + } + } + }); + }; + }]); +} + +// Left is negative X-coordinate, right is positive. +makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft'); +makeSwipeDirective('ngSwipeRight', 1, 'swiperight'); + + + +})(window, window.angular); diff --git a/vendor/angular/angular-touch.min.js b/vendor/angular/angular-touch.min.js new file mode 100644 index 00000000..9e554042 --- /dev/null +++ b/vendor/angular/angular-touch.min.js @@ -0,0 +1,13 @@ +/* + AngularJS v1.2.3 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(y,v,z){'use strict';function t(g,a,b){q.directive(g,["$parse","$swipe",function(l,n){var r=75,h=0.3,d=30;return function(p,m,k){function e(e){if(!u)return!1;var c=Math.abs(e.y-u.y);e=(e.x-u.x)*a;return f&&cd&&c/el&&10>n|| +(n>l?(d=!1,b.cancel&&b.cancel(a)):(a.preventDefault(),b.move&&b.move(m,a)))}});a.on("touchend mouseup",function(a){d&&(d=!1,b.end&&b.end(g(a),a))})}}}]);q.config(["$provide",function(g){g.decorator("ngClickDirective",["$delegate",function(a){a.shift();return a}])}]);q.directive("ngClick",["$parse","$timeout","$rootElement",function(g,a,b){function l(a,c,b){for(var f=0;fh)){var c= +a.touches&&a.touches.length?a.touches:[a],b=c[0].clientX,c=c[0].clientY;1>b&&1>c||l(k,b,c)||(a.stopPropagation(),a.preventDefault(),a.target&&a.target.blur())}}function r(b){b=b.touches&&b.touches.length?b.touches:[b];var c=b[0].clientX,d=b[0].clientY;k.push(c,d);a(function(){for(var a=0;ah&&12>p)&&(k||(b[0].addEventListener("click",n,!0),b[0].addEventListener("touchstart",r,!0),k=[]),m=Date.now(),l(k,e,g),s&&s.blur(),v.isDefined(d.disabled)&&!1!==d.disabled||c.triggerHandler("click",[a]));f()});c.onclick=function(a){};c.on("click",function(b,c){a.$apply(function(){h(a,{$event:c||b})})});c.on("mousedown",function(a){c.addClass(p)});c.on("mousemove mouseup",function(a){c.removeClass(p)})}}]);t("ngSwipeLeft",-1,"swipeleft");t("ngSwipeRight",1,"swiperight")})(window, +window.angular); +//# sourceMappingURL=angular-touch.min.js.map diff --git a/vendor/angular/angular-touch.min.js.map b/vendor/angular/angular-touch.min.js.map new file mode 100644 index 00000000..6681ba1b --- /dev/null +++ b/vendor/angular/angular-touch.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"angular-touch.min.js", +"lineCount":12, +"mappings":"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", +"sources":["angular-touch.js"], +"names":["window","angular","undefined","makeSwipeDirective","directiveName","direction","eventName","ngTouch","directive","$parse","$swipe","MAX_VERTICAL_DISTANCE","MAX_VERTICAL_RATIO","MIN_HORIZONTAL_DISTANCE","scope","element","attr","validSwipe","coords","startCoords","deltaY","Math","abs","y","deltaX","x","valid","swipeHandler","bind","start","event","cancel","end","$apply","triggerHandler","module","factory","getCoordinates","touches","length","e","changedTouches","originalEvent","clientX","clientY","eventHandlers","totalX","totalY","lastPos","active","on","MOVE_BUFFER_RADIUS","preventDefault","config","$provide","decorator","$delegate","shift","$timeout","$rootElement","checkAllowableRegions","touchCoordinates","i","x1","CLICKBUSTER_THRESHOLD","y1","splice","onClick","Date","now","lastPreventedTime","PREVENT_DURATION","stopPropagation","target","blur","onTouchStart","push","ACTIVE_CLASS_NAME","resetState","tapping","removeClass","clickHandler","ngClick","tapElement","startTime","touchStartX","touchStartY","srcElement","nodeType","parentNode","addClass","diff","dist","sqrt","pow","TAP_DURATION","MOVE_TOLERANCE","addEventListener","isDefined","disabled","onclick","element.onclick","touchend"] +} diff --git a/vendor/angular/angular.js b/vendor/angular/angular.js new file mode 100644 index 00000000..8b538ce2 --- /dev/null +++ b/vendor/angular/angular.js @@ -0,0 +1,20282 @@ +/** + * @license AngularJS v1.2.3 + * (c) 2010-2014 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, document, undefined) {'use strict'; + +/** + * @description + * + * This object provides a utility for producing rich Error messages within + * Angular. It can be called as follows: + * + * var exampleMinErr = minErr('example'); + * throw exampleMinErr('one', 'This {0} is {1}', foo, bar); + * + * The above creates an instance of minErr in the example namespace. The + * resulting error will have a namespaced error code of example.one. The + * resulting error will replace {0} with the value of foo, and {1} with the + * value of bar. The object is not restricted in the number of arguments it can + * take. + * + * If fewer arguments are specified than necessary for interpolation, the extra + * interpolation markers will be preserved in the final string. + * + * Since data will be parsed statically during a build step, some restrictions + * are applied with respect to how minErr instances are created and called. + * Instances should have names of the form namespaceMinErr for a minErr created + * using minErr('namespace') . Error codes, namespaces and template strings + * should all be static strings, not variables or general expressions. + * + * @param {string} module The namespace to use for the new minErr instance. + * @returns {function(string, string, ...): Error} instance + */ + +function minErr(module) { + return function () { + var code = arguments[0], + prefix = '[' + (module ? module + ':' : '') + code + '] ', + template = arguments[1], + templateArgs = arguments, + stringify = function (obj) { + if (typeof obj === 'function') { + return obj.toString().replace(/ \{[\s\S]*$/, ''); + } else if (typeof obj === 'undefined') { + return 'undefined'; + } else if (typeof obj !== 'string') { + return JSON.stringify(obj); + } + return obj; + }, + message, i; + + message = prefix + template.replace(/\{\d+\}/g, function (match) { + var index = +match.slice(1, -1), arg; + + if (index + 2 < templateArgs.length) { + arg = templateArgs[index + 2]; + if (typeof arg === 'function') { + return arg.toString().replace(/ ?\{[\s\S]*$/, ''); + } else if (typeof arg === 'undefined') { + return 'undefined'; + } else if (typeof arg !== 'string') { + return toJson(arg); + } + return arg; + } + return match; + }); + + message = message + '\nhttp://errors.angularjs.org/1.2.3/' + + (module ? module + '/' : '') + code; + for (i = 2; i < arguments.length; i++) { + message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + + encodeURIComponent(stringify(arguments[i])); + } + + return new Error(message); + }; +} + +/* We need to tell jshint what variables are being exported */ +/* global + -angular, + -msie, + -jqLite, + -jQuery, + -slice, + -push, + -toString, + -ngMinErr, + -_angular, + -angularModule, + -nodeName_, + -uid, + + -lowercase, + -uppercase, + -manualLowercase, + -manualUppercase, + -nodeName_, + -isArrayLike, + -forEach, + -sortedKeys, + -forEachSorted, + -reverseParams, + -nextUid, + -setHashKey, + -extend, + -int, + -inherit, + -noop, + -identity, + -valueFn, + -isUndefined, + -isDefined, + -isObject, + -isString, + -isNumber, + -isDate, + -isArray, + -isFunction, + -isRegExp, + -isWindow, + -isScope, + -isFile, + -isBoolean, + -trim, + -isElement, + -makeMap, + -map, + -size, + -includes, + -indexOf, + -arrayRemove, + -isLeafNode, + -copy, + -shallowCopy, + -equals, + -csp, + -concat, + -sliceArgs, + -bind, + -toJsonReplacer, + -toJson, + -fromJson, + -toBoolean, + -startingTag, + -tryDecodeURIComponent, + -parseKeyValue, + -toKeyValue, + -encodeUriSegment, + -encodeUriQuery, + -angularInit, + -bootstrap, + -snake_case, + -bindJQuery, + -assertArg, + -assertArgFn, + -assertNotHasOwnProperty, + -getter, + -getBlockElements, + +*/ + +//////////////////////////////////// + +/** + * @ngdoc function + * @name angular.lowercase + * @function + * + * @description Converts the specified string to lowercase. + * @param {string} string String to be converted to lowercase. + * @returns {string} Lowercased string. + */ +var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;}; + + +/** + * @ngdoc function + * @name angular.uppercase + * @function + * + * @description Converts the specified string to uppercase. + * @param {string} string String to be converted to uppercase. + * @returns {string} Uppercased string. + */ +var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;}; + + +var manualLowercase = function(s) { + /* jshint bitwise: false */ + return isString(s) + ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);}) + : s; +}; +var manualUppercase = function(s) { + /* jshint bitwise: false */ + return isString(s) + ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);}) + : s; +}; + + +// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish +// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods +// with correct but slower alternatives. +if ('i' !== 'I'.toLowerCase()) { + lowercase = manualLowercase; + uppercase = manualUppercase; +} + + +var /** holds major version number for IE or NaN for real browsers */ + msie, + jqLite, // delay binding since jQuery could be loaded after us. + jQuery, // delay binding + slice = [].slice, + push = [].push, + toString = Object.prototype.toString, + ngMinErr = minErr('ng'), + + + _angular = window.angular, + /** @name angular */ + angular = window.angular || (window.angular = {}), + angularModule, + nodeName_, + uid = ['0', '0', '0']; + +/** + * IE 11 changed the format of the UserAgent string. + * See http://msdn.microsoft.com/en-us/library/ms537503.aspx + */ +msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]); +if (isNaN(msie)) { + msie = int((/trident\/.*; rv:(\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]); +} + + +/** + * @private + * @param {*} obj + * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, + * String ...) + */ +function isArrayLike(obj) { + if (obj == null || isWindow(obj)) { + return false; + } + + var length = obj.length; + + if (obj.nodeType === 1 && length) { + return true; + } + + return isString(obj) || isArray(obj) || length === 0 || + typeof length === 'number' && length > 0 && (length - 1) in obj; +} + +/** + * @ngdoc function + * @name angular.forEach + * @function + * + * @description + * Invokes the `iterator` function once for each item in `obj` collection, which can be either an + * object or an array. The `iterator` function is invoked with `iterator(value, key)`, where `value` + * is the value of an object property or an array element and `key` is the object property key or + * array element index. Specifying a `context` for the function is optional. + * + * Note: this function was previously known as `angular.foreach`. + * +
+     var values = {name: 'misko', gender: 'male'};
+     var log = [];
+     angular.forEach(values, function(value, key){
+       this.push(key + ': ' + value);
+     }, log);
+     expect(log).toEqual(['name: misko', 'gender:male']);
+   
+ * + * @param {Object|Array} obj Object to iterate over. + * @param {Function} iterator Iterator function. + * @param {Object=} context Object to become context (`this`) for the iterator function. + * @returns {Object|Array} Reference to `obj`. + */ +function forEach(obj, iterator, context) { + var key; + if (obj) { + if (isFunction(obj)){ + for (key in obj) { + if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) { + iterator.call(context, obj[key], key); + } + } + } else if (obj.forEach && obj.forEach !== forEach) { + obj.forEach(iterator, context); + } else if (isArrayLike(obj)) { + for (key = 0; key < obj.length; key++) + iterator.call(context, obj[key], key); + } else { + for (key in obj) { + if (obj.hasOwnProperty(key)) { + iterator.call(context, obj[key], key); + } + } + } + } + return obj; +} + +function sortedKeys(obj) { + var keys = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + keys.push(key); + } + } + return keys.sort(); +} + +function forEachSorted(obj, iterator, context) { + var keys = sortedKeys(obj); + for ( var i = 0; i < keys.length; i++) { + iterator.call(context, obj[keys[i]], keys[i]); + } + return keys; +} + + +/** + * when using forEach the params are value, key, but it is often useful to have key, value. + * @param {function(string, *)} iteratorFn + * @returns {function(*, string)} + */ +function reverseParams(iteratorFn) { + return function(value, key) { iteratorFn(key, value); }; +} + +/** + * A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric + * characters such as '012ABC'. The reason why we are not using simply a number counter is that + * the number string gets longer over time, and it can also overflow, where as the nextId + * will grow much slower, it is a string, and it will never overflow. + * + * @returns an unique alpha-numeric string + */ +function nextUid() { + var index = uid.length; + var digit; + + while(index) { + index--; + digit = uid[index].charCodeAt(0); + if (digit == 57 /*'9'*/) { + uid[index] = 'A'; + return uid.join(''); + } + if (digit == 90 /*'Z'*/) { + uid[index] = '0'; + } else { + uid[index] = String.fromCharCode(digit + 1); + return uid.join(''); + } + } + uid.unshift('0'); + return uid.join(''); +} + + +/** + * Set or clear the hashkey for an object. + * @param obj object + * @param h the hashkey (!truthy to delete the hashkey) + */ +function setHashKey(obj, h) { + if (h) { + obj.$$hashKey = h; + } + else { + delete obj.$$hashKey; + } +} + +/** + * @ngdoc function + * @name angular.extend + * @function + * + * @description + * Extends the destination object `dst` by copying all of the properties from the `src` object(s) + * to `dst`. You can specify multiple `src` objects. + * + * @param {Object} dst Destination object. + * @param {...Object} src Source object(s). + * @returns {Object} Reference to `dst`. + */ +function extend(dst) { + var h = dst.$$hashKey; + forEach(arguments, function(obj){ + if (obj !== dst) { + forEach(obj, function(value, key){ + dst[key] = value; + }); + } + }); + + setHashKey(dst,h); + return dst; +} + +function int(str) { + return parseInt(str, 10); +} + + +function inherit(parent, extra) { + return extend(new (extend(function() {}, {prototype:parent}))(), extra); +} + +/** + * @ngdoc function + * @name angular.noop + * @function + * + * @description + * A function that performs no operations. This function can be useful when writing code in the + * functional style. +
+     function foo(callback) {
+       var result = calculateResult();
+       (callback || angular.noop)(result);
+     }
+   
+ */ +function noop() {} +noop.$inject = []; + + +/** + * @ngdoc function + * @name angular.identity + * @function + * + * @description + * A function that returns its first argument. This function is useful when writing code in the + * functional style. + * +
+     function transformer(transformationFn, value) {
+       return (transformationFn || angular.identity)(value);
+     };
+   
+ */ +function identity($) {return $;} +identity.$inject = []; + + +function valueFn(value) {return function() {return value;};} + +/** + * @ngdoc function + * @name angular.isUndefined + * @function + * + * @description + * Determines if a reference is undefined. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is undefined. + */ +function isUndefined(value){return typeof value == 'undefined';} + + +/** + * @ngdoc function + * @name angular.isDefined + * @function + * + * @description + * Determines if a reference is defined. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is defined. + */ +function isDefined(value){return typeof value != 'undefined';} + + +/** + * @ngdoc function + * @name angular.isObject + * @function + * + * @description + * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not + * considered to be objects. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is an `Object` but not `null`. + */ +function isObject(value){return value != null && typeof value == 'object';} + + +/** + * @ngdoc function + * @name angular.isString + * @function + * + * @description + * Determines if a reference is a `String`. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is a `String`. + */ +function isString(value){return typeof value == 'string';} + + +/** + * @ngdoc function + * @name angular.isNumber + * @function + * + * @description + * Determines if a reference is a `Number`. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is a `Number`. + */ +function isNumber(value){return typeof value == 'number';} + + +/** + * @ngdoc function + * @name angular.isDate + * @function + * + * @description + * Determines if a value is a date. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is a `Date`. + */ +function isDate(value){ + return toString.apply(value) == '[object Date]'; +} + + +/** + * @ngdoc function + * @name angular.isArray + * @function + * + * @description + * Determines if a reference is an `Array`. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is an `Array`. + */ +function isArray(value) { + return toString.apply(value) == '[object Array]'; +} + + +/** + * @ngdoc function + * @name angular.isFunction + * @function + * + * @description + * Determines if a reference is a `Function`. + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is a `Function`. + */ +function isFunction(value){return typeof value == 'function';} + + +/** + * Determines if a value is a regular expression object. + * + * @private + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is a `RegExp`. + */ +function isRegExp(value) { + return toString.apply(value) == '[object RegExp]'; +} + + +/** + * Checks if `obj` is a window object. + * + * @private + * @param {*} obj Object to check + * @returns {boolean} True if `obj` is a window obj. + */ +function isWindow(obj) { + return obj && obj.document && obj.location && obj.alert && obj.setInterval; +} + + +function isScope(obj) { + return obj && obj.$evalAsync && obj.$watch; +} + + +function isFile(obj) { + return toString.apply(obj) === '[object File]'; +} + + +function isBoolean(value) { + return typeof value == 'boolean'; +} + + +var trim = (function() { + // native trim is way faster: http://jsperf.com/angular-trim-test + // but IE doesn't have it... :-( + // TODO: we should move this into IE/ES5 polyfill + if (!String.prototype.trim) { + return function(value) { + return isString(value) ? value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : value; + }; + } + return function(value) { + return isString(value) ? value.trim() : value; + }; +})(); + + +/** + * @ngdoc function + * @name angular.isElement + * @function + * + * @description + * Determines if a reference is a DOM element (or wrapped jQuery element). + * + * @param {*} value Reference to check. + * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element). + */ +function isElement(node) { + return node && + (node.nodeName // we are a direct element + || (node.on && node.find)); // we have an on and find method part of jQuery API +} + +/** + * @param str 'key1,key2,...' + * @returns {object} in the form of {key1:true, key2:true, ...} + */ +function makeMap(str){ + var obj = {}, items = str.split(","), i; + for ( i = 0; i < items.length; i++ ) + obj[ items[i] ] = true; + return obj; +} + + +if (msie < 9) { + nodeName_ = function(element) { + element = element.nodeName ? element : element[0]; + return (element.scopeName && element.scopeName != 'HTML') + ? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName; + }; +} else { + nodeName_ = function(element) { + return element.nodeName ? element.nodeName : element[0].nodeName; + }; +} + + +function map(obj, iterator, context) { + var results = []; + forEach(obj, function(value, index, list) { + results.push(iterator.call(context, value, index, list)); + }); + return results; +} + + +/** + * @description + * Determines the number of elements in an array, the number of properties an object has, or + * the length of a string. + * + * Note: This function is used to augment the Object type in Angular expressions. See + * {@link angular.Object} for more information about Angular arrays. + * + * @param {Object|Array|string} obj Object, array, or string to inspect. + * @param {boolean} [ownPropsOnly=false] Count only "own" properties in an object + * @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array. + */ +function size(obj, ownPropsOnly) { + var count = 0, key; + + if (isArray(obj) || isString(obj)) { + return obj.length; + } else if (isObject(obj)){ + for (key in obj) + if (!ownPropsOnly || obj.hasOwnProperty(key)) + count++; + } + + return count; +} + + +function includes(array, obj) { + return indexOf(array, obj) != -1; +} + +function indexOf(array, obj) { + if (array.indexOf) return array.indexOf(obj); + + for ( var i = 0; i < array.length; i++) { + if (obj === array[i]) return i; + } + return -1; +} + +function arrayRemove(array, value) { + var index = indexOf(array, value); + if (index >=0) + array.splice(index, 1); + return value; +} + +function isLeafNode (node) { + if (node) { + switch (node.nodeName) { + case "OPTION": + case "PRE": + case "TITLE": + return true; + } + } + return false; +} + +/** + * @ngdoc function + * @name angular.copy + * @function + * + * @description + * Creates a deep copy of `source`, which should be an object or an array. + * + * * If no destination is supplied, a copy of the object or array is created. + * * If a destination is provided, all of its elements (for array) or properties (for objects) + * are deleted and then all elements/properties from the source are copied to it. + * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned. + * * If `source` is identical to 'destination' an exception will be thrown. + * + * @param {*} source The source that will be used to make a copy. + * Can be any type, including primitives, `null`, and `undefined`. + * @param {(Object|Array)=} destination Destination into which the source is copied. If + * provided, must be of the same type as `source`. + * @returns {*} The copy or updated `destination`, if `destination` was specified. + * + * @example + + +
+
+ Name:
+ E-mail:
+ Gender: male + female
+ + +
+
form = {{user | json}}
+
master = {{master | json}}
+
+ + +
+
+ */ +function copy(source, destination){ + if (isWindow(source) || isScope(source)) { + throw ngMinErr('cpws', + "Can't copy! Making copies of Window or Scope instances is not supported."); + } + + if (!destination) { + destination = source; + if (source) { + if (isArray(source)) { + destination = copy(source, []); + } else if (isDate(source)) { + destination = new Date(source.getTime()); + } else if (isRegExp(source)) { + destination = new RegExp(source.source); + } else if (isObject(source)) { + destination = copy(source, {}); + } + } + } else { + if (source === destination) throw ngMinErr('cpi', + "Can't copy! Source and destination are identical."); + if (isArray(source)) { + destination.length = 0; + for ( var i = 0; i < source.length; i++) { + destination.push(copy(source[i])); + } + } else { + var h = destination.$$hashKey; + forEach(destination, function(value, key){ + delete destination[key]; + }); + for ( var key in source) { + destination[key] = copy(source[key]); + } + setHashKey(destination,h); + } + } + return destination; +} + +/** + * Create a shallow copy of an object + */ +function shallowCopy(src, dst) { + dst = dst || {}; + + for(var key in src) { + // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src + // so we don't need to worry hasOwnProperty here + if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') { + dst[key] = src[key]; + } + } + + return dst; +} + + +/** + * @ngdoc function + * @name angular.equals + * @function + * + * @description + * Determines if two objects or two values are equivalent. Supports value types, regular + * expressions, arrays and objects. + * + * Two objects or values are considered equivalent if at least one of the following is true: + * + * * Both objects or values pass `===` comparison. + * * Both objects or values are of the same type and all of their properties are equal by + * comparing them with `angular.equals`. + * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal) + * * Both values represent the same regular expression (In JavasScript, + * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual + * representation matches). + * + * During a property comparison, properties of `function` type and properties with names + * that begin with `$` are ignored. + * + * Scope and DOMWindow objects are being compared only by identify (`===`). + * + * @param {*} o1 Object or value to compare. + * @param {*} o2 Object or value to compare. + * @returns {boolean} True if arguments are equal. + */ +function equals(o1, o2) { + if (o1 === o2) return true; + if (o1 === null || o2 === null) return false; + if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN + var t1 = typeof o1, t2 = typeof o2, length, key, keySet; + if (t1 == t2) { + if (t1 == 'object') { + if (isArray(o1)) { + if (!isArray(o2)) return false; + if ((length = o1.length) == o2.length) { + for(key=0; key 2 ? sliceArgs(arguments, 2) : []; + if (isFunction(fn) && !(fn instanceof RegExp)) { + return curryArgs.length + ? function() { + return arguments.length + ? fn.apply(self, curryArgs.concat(slice.call(arguments, 0))) + : fn.apply(self, curryArgs); + } + : function() { + return arguments.length + ? fn.apply(self, arguments) + : fn.call(self); + }; + } else { + // in IE, native methods are not functions so they cannot be bound (note: they don't need to be) + return fn; + } +} + + +function toJsonReplacer(key, value) { + var val = value; + + if (typeof key === 'string' && key.charAt(0) === '$') { + val = undefined; + } else if (isWindow(value)) { + val = '$WINDOW'; + } else if (value && document === value) { + val = '$DOCUMENT'; + } else if (isScope(value)) { + val = '$SCOPE'; + } + + return val; +} + + +/** + * @ngdoc function + * @name angular.toJson + * @function + * + * @description + * Serializes input into a JSON-formatted string. Properties with leading $ characters will be + * stripped since angular uses this notation internally. + * + * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON. + * @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace. + * @returns {string|undefined} JSON-ified string representing `obj`. + */ +function toJson(obj, pretty) { + if (typeof obj === 'undefined') return undefined; + return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null); +} + + +/** + * @ngdoc function + * @name angular.fromJson + * @function + * + * @description + * Deserializes a JSON string. + * + * @param {string} json JSON string to deserialize. + * @returns {Object|Array|Date|string|number} Deserialized thingy. + */ +function fromJson(json) { + return isString(json) + ? JSON.parse(json) + : json; +} + + +function toBoolean(value) { + if (value && value.length !== 0) { + var v = lowercase("" + value); + value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]'); + } else { + value = false; + } + return value; +} + +/** + * @returns {string} Returns the string representation of the element. + */ +function startingTag(element) { + element = jqLite(element).clone(); + try { + // turns out IE does not let you set .html() on elements which + // are not allowed to have children. So we just ignore it. + element.html(''); + } catch(e) {} + // As Per DOM Standards + var TEXT_NODE = 3; + var elemHtml = jqLite('
').append(element).html(); + try { + return element[0].nodeType === TEXT_NODE ? lowercase(elemHtml) : + elemHtml. + match(/^(<[^>]+>)/)[1]. + replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); }); + } catch(e) { + return lowercase(elemHtml); + } + +} + + +///////////////////////////////////////////////// + +/** + * Tries to decode the URI component without throwing an exception. + * + * @private + * @param str value potential URI component to check. + * @returns {boolean} True if `value` can be decoded + * with the decodeURIComponent function. + */ +function tryDecodeURIComponent(value) { + try { + return decodeURIComponent(value); + } catch(e) { + // Ignore any invalid uri component + } +} + + +/** + * Parses an escaped url query string into key-value pairs. + * @returns Object.<(string|boolean)> + */ +function parseKeyValue(/**string*/keyValue) { + var obj = {}, key_value, key; + forEach((keyValue || "").split('&'), function(keyValue){ + if ( keyValue ) { + key_value = keyValue.split('='); + key = tryDecodeURIComponent(key_value[0]); + if ( isDefined(key) ) { + var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true; + if (!obj[key]) { + obj[key] = val; + } else if(isArray(obj[key])) { + obj[key].push(val); + } else { + obj[key] = [obj[key],val]; + } + } + } + }); + return obj; +} + +function toKeyValue(obj) { + var parts = []; + forEach(obj, function(value, key) { + if (isArray(value)) { + forEach(value, function(arrayValue) { + parts.push(encodeUriQuery(key, true) + + (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true))); + }); + } else { + parts.push(encodeUriQuery(key, true) + + (value === true ? '' : '=' + encodeUriQuery(value, true))); + } + }); + return parts.length ? parts.join('&') : ''; +} + + +/** + * We need our custom method because encodeURIComponent is too aggressive and doesn't follow + * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path + * segments: + * segment = *pchar + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * pct-encoded = "%" HEXDIG HEXDIG + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ +function encodeUriSegment(val) { + return encodeUriQuery(val, true). + replace(/%26/gi, '&'). + replace(/%3D/gi, '='). + replace(/%2B/gi, '+'); +} + + +/** + * This method is intended for encoding *key* or *value* parts of query component. We need a custom + * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be + * encoded per http://tools.ietf.org/html/rfc3986: + * query = *( pchar / "/" / "?" ) + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * pct-encoded = "%" HEXDIG HEXDIG + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ +function encodeUriQuery(val, pctEncodeSpaces) { + return encodeURIComponent(val). + replace(/%40/gi, '@'). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); +} + + +/** + * @ngdoc directive + * @name ng.directive:ngApp + * + * @element ANY + * @param {angular.Module} ngApp an optional application + * {@link angular.module module} name to load. + * + * @description + * + * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive + * designates the **root element** of the application and is typically placed near the root element + * of the page - e.g. on the `` or `` tags. + * + * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp` + * found in the document will be used to define the root element to auto-bootstrap as an + * application. To run multiple applications in an HTML document you must manually bootstrap them using + * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other. + * + * You can specify an **AngularJS module** to be used as the root module for the application. This + * module will be loaded into the {@link AUTO.$injector} when the application is bootstrapped and + * should contain the application code needed or have dependencies on other modules that will + * contain the code. See {@link angular.module} for more information. + * + * In the example below if the `ngApp` directive were not placed on the `html` element then the + * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}` + * would not be resolved to `3`. + * + * `ngApp` is the easiest, and most common, way to bootstrap an application. + * + + +
+ I can add: {{a}} + {{b}} = {{ a+b }} + + + angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) { + $scope.a = 1; + $scope.b = 2; + }); + + + * + */ +function angularInit(element, bootstrap) { + var elements = [element], + appElement, + module, + names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'], + NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/; + + function append(element) { + element && elements.push(element); + } + + forEach(names, function(name) { + names[name] = true; + append(document.getElementById(name)); + name = name.replace(':', '\\:'); + if (element.querySelectorAll) { + forEach(element.querySelectorAll('.' + name), append); + forEach(element.querySelectorAll('.' + name + '\\:'), append); + forEach(element.querySelectorAll('[' + name + ']'), append); + } + }); + + forEach(elements, function(element) { + if (!appElement) { + var className = ' ' + element.className + ' '; + var match = NG_APP_CLASS_REGEXP.exec(className); + if (match) { + appElement = element; + module = (match[2] || '').replace(/\s+/g, ','); + } else { + forEach(element.attributes, function(attr) { + if (!appElement && names[attr.name]) { + appElement = element; + module = attr.value; + } + }); + } + } + }); + if (appElement) { + bootstrap(appElement, module ? [module] : []); + } +} + +/** + * @ngdoc function + * @name angular.bootstrap + * @description + * Use this function to manually start up angular application. + * + * See: {@link guide/bootstrap Bootstrap} + * + * Note that ngScenario-based end-to-end tests cannot use this function to bootstrap manually. + * They must use {@link api/ng.directive:ngApp ngApp}. + * + * @param {Element} element DOM element which is the root of angular application. + * @param {Array=} modules an array of modules to load into the application. + * Each item in the array should be the name of a predefined module or a (DI annotated) + * function that will be invoked by the injector as a run block. + * See: {@link angular.module modules} + * @returns {AUTO.$injector} Returns the newly created injector for this app. + */ +function bootstrap(element, modules) { + var doBootstrap = function() { + element = jqLite(element); + + if (element.injector()) { + var tag = (element[0] === document) ? 'document' : startingTag(element); + throw ngMinErr('btstrpd', "App Already Bootstrapped with this Element '{0}'", tag); + } + + modules = modules || []; + modules.unshift(['$provide', function($provide) { + $provide.value('$rootElement', element); + }]); + modules.unshift('ng'); + var injector = createInjector(modules); + injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', '$animate', + function(scope, element, compile, injector, animate) { + scope.$apply(function() { + element.data('$injector', injector); + compile(element)(scope); + }); + }] + ); + return injector; + }; + + var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/; + + if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) { + return doBootstrap(); + } + + window.name = window.name.replace(NG_DEFER_BOOTSTRAP, ''); + angular.resumeBootstrap = function(extraModules) { + forEach(extraModules, function(module) { + modules.push(module); + }); + doBootstrap(); + }; +} + +var SNAKE_CASE_REGEXP = /[A-Z]/g; +function snake_case(name, separator){ + separator = separator || '_'; + return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) { + return (pos ? separator : '') + letter.toLowerCase(); + }); +} + +function bindJQuery() { + // bind to jQuery if present; + jQuery = window.jQuery; + // reset to jQuery or default to us. + if (jQuery) { + jqLite = jQuery; + extend(jQuery.fn, { + scope: JQLitePrototype.scope, + isolateScope: JQLitePrototype.isolateScope, + controller: JQLitePrototype.controller, + injector: JQLitePrototype.injector, + inheritedData: JQLitePrototype.inheritedData + }); + // Method signature: + // jqLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) + jqLitePatchJQueryRemove('remove', true, true, false); + jqLitePatchJQueryRemove('empty', false, false, false); + jqLitePatchJQueryRemove('html', false, false, true); + } else { + jqLite = JQLite; + } + angular.element = jqLite; +} + +/** + * throw error if the argument is falsy. + */ +function assertArg(arg, name, reason) { + if (!arg) { + throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required")); + } + return arg; +} + +function assertArgFn(arg, name, acceptArrayAnnotation) { + if (acceptArrayAnnotation && isArray(arg)) { + arg = arg[arg.length - 1]; + } + + assertArg(isFunction(arg), name, 'not a function, got ' + + (arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg)); + return arg; +} + +/** + * throw error if the name given is hasOwnProperty + * @param {String} name the name to test + * @param {String} context the context in which the name is used, such as module or directive + */ +function assertNotHasOwnProperty(name, context) { + if (name === 'hasOwnProperty') { + throw ngMinErr('badname', "hasOwnProperty is not a valid {0} name", context); + } +} + +/** + * Return the value accessible from the object by path. Any undefined traversals are ignored + * @param {Object} obj starting object + * @param {string} path path to traverse + * @param {boolean=true} bindFnToScope + * @returns value as accessible by path + */ +//TODO(misko): this function needs to be removed +function getter(obj, path, bindFnToScope) { + if (!path) return obj; + var keys = path.split('.'); + var key; + var lastInstance = obj; + var len = keys.length; + + for (var i = 0; i < len; i++) { + key = keys[i]; + if (obj) { + obj = (lastInstance = obj)[key]; + } + } + if (!bindFnToScope && isFunction(obj)) { + return bind(lastInstance, obj); + } + return obj; +} + +/** + * Return the siblings between `startNode` and `endNode`, inclusive + * @param {Object} object with `startNode` and `endNode` properties + * @returns jQlite object containing the elements + */ +function getBlockElements(block) { + if (block.startNode === block.endNode) { + return jqLite(block.startNode); + } + + var element = block.startNode; + var elements = [element]; + + do { + element = element.nextSibling; + if (!element) break; + elements.push(element); + } while (element !== block.endNode); + + return jqLite(elements); +} + +/** + * @ngdoc interface + * @name angular.Module + * @description + * + * Interface for configuring angular {@link angular.module modules}. + */ + +function setupModuleLoader(window) { + + var $injectorMinErr = minErr('$injector'); + var ngMinErr = minErr('ng'); + + function ensure(obj, name, factory) { + return obj[name] || (obj[name] = factory()); + } + + var angular = ensure(window, 'angular', Object); + + // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap + angular.$$minErr = angular.$$minErr || minErr; + + return ensure(angular, 'module', function() { + /** @type {Object.} */ + var modules = {}; + + /** + * @ngdoc function + * @name angular.module + * @description + * + * The `angular.module` is a global place for creating, registering and retrieving Angular + * modules. + * All modules (angular core or 3rd party) that should be available to an application must be + * registered using this mechanism. + * + * When passed two or more arguments, a new module is created. If passed only one argument, an + * existing module (the name passed as the first argument to `module`) is retrieved. + * + * + * # Module + * + * A module is a collection of services, directives, filters, and configuration information. + * `angular.module` is used to configure the {@link AUTO.$injector $injector}. + * + *
+     * // Create a new module
+     * var myModule = angular.module('myModule', []);
+     *
+     * // register a new service
+     * myModule.value('appName', 'MyCoolApp');
+     *
+     * // configure existing services inside initialization blocks.
+     * myModule.config(function($locationProvider) {
+     *   // Configure existing providers
+     *   $locationProvider.hashPrefix('!');
+     * });
+     * 
+ * + * Then you can create an injector and load your modules like this: + * + *
+     * var injector = angular.injector(['ng', 'MyModule'])
+     * 
+ * + * However it's more likely that you'll just use + * {@link ng.directive:ngApp ngApp} or + * {@link angular.bootstrap} to simplify this process for you. + * + * @param {!string} name The name of the module to create or retrieve. + * @param {Array.=} requires If specified then new module is being created. If + * unspecified then the the module is being retrieved for further configuration. + * @param {Function} configFn Optional configuration function for the module. Same as + * {@link angular.Module#methods_config Module#config()}. + * @returns {module} new module with the {@link angular.Module} api. + */ + return function module(name, requires, configFn) { + var assertNotHasOwnProperty = function(name, context) { + if (name === 'hasOwnProperty') { + throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); + } + }; + + assertNotHasOwnProperty(name, 'module'); + if (requires && modules.hasOwnProperty(name)) { + modules[name] = null; + } + return ensure(modules, name, function() { + if (!requires) { + throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + + "the module name or forgot to load it. If registering a module ensure that you " + + "specify the dependencies as the second argument.", name); + } + + /** @type {!Array.>} */ + var invokeQueue = []; + + /** @type {!Array.} */ + var runBlocks = []; + + var config = invokeLater('$injector', 'invoke'); + + /** @type {angular.Module} */ + var moduleInstance = { + // Private state + _invokeQueue: invokeQueue, + _runBlocks: runBlocks, + + /** + * @ngdoc property + * @name angular.Module#requires + * @propertyOf angular.Module + * @returns {Array.} List of module names which must be loaded before this module. + * @description + * Holds the list of modules which the injector will load before the current module is + * loaded. + */ + requires: requires, + + /** + * @ngdoc property + * @name angular.Module#name + * @propertyOf angular.Module + * @returns {string} Name of the module. + * @description + */ + name: name, + + + /** + * @ngdoc method + * @name angular.Module#provider + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} providerType Construction function for creating new instance of the + * service. + * @description + * See {@link AUTO.$provide#provider $provide.provider()}. + */ + provider: invokeLater('$provide', 'provider'), + + /** + * @ngdoc method + * @name angular.Module#factory + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} providerFunction Function for creating new instance of the service. + * @description + * See {@link AUTO.$provide#factory $provide.factory()}. + */ + factory: invokeLater('$provide', 'factory'), + + /** + * @ngdoc method + * @name angular.Module#service + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} constructor A constructor function that will be instantiated. + * @description + * See {@link AUTO.$provide#service $provide.service()}. + */ + service: invokeLater('$provide', 'service'), + + /** + * @ngdoc method + * @name angular.Module#value + * @methodOf angular.Module + * @param {string} name service name + * @param {*} object Service instance object. + * @description + * See {@link AUTO.$provide#value $provide.value()}. + */ + value: invokeLater('$provide', 'value'), + + /** + * @ngdoc method + * @name angular.Module#constant + * @methodOf angular.Module + * @param {string} name constant name + * @param {*} object Constant value. + * @description + * Because the constant are fixed, they get applied before other provide methods. + * See {@link AUTO.$provide#constant $provide.constant()}. + */ + constant: invokeLater('$provide', 'constant', 'unshift'), + + /** + * @ngdoc method + * @name angular.Module#animation + * @methodOf angular.Module + * @param {string} name animation name + * @param {Function} animationFactory Factory function for creating new instance of an + * animation. + * @description + * + * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. + * + * + * Defines an animation hook that can be later used with + * {@link ngAnimate.$animate $animate} service and directives that use this service. + * + *
+           * module.animation('.animation-name', function($inject1, $inject2) {
+           *   return {
+           *     eventName : function(element, done) {
+           *       //code to run the animation
+           *       //once complete, then run done()
+           *       return function cancellationFunction(element) {
+           *         //code to cancel the animation
+           *       }
+           *     }
+           *   }
+           * })
+           * 
+ * + * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and + * {@link ngAnimate ngAnimate module} for more information. + */ + animation: invokeLater('$animateProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#filter + * @methodOf angular.Module + * @param {string} name Filter name. + * @param {Function} filterFactory Factory function for creating new instance of filter. + * @description + * See {@link ng.$filterProvider#register $filterProvider.register()}. + */ + filter: invokeLater('$filterProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#controller + * @methodOf angular.Module + * @param {string|Object} name Controller name, or an object map of controllers where the + * keys are the names and the values are the constructors. + * @param {Function} constructor Controller constructor function. + * @description + * See {@link ng.$controllerProvider#register $controllerProvider.register()}. + */ + controller: invokeLater('$controllerProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#directive + * @methodOf angular.Module + * @param {string|Object} name Directive name, or an object map of directives where the + * keys are the names and the values are the factories. + * @param {Function} directiveFactory Factory function for creating new instance of + * directives. + * @description + * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}. + */ + directive: invokeLater('$compileProvider', 'directive'), + + /** + * @ngdoc method + * @name angular.Module#config + * @methodOf angular.Module + * @param {Function} configFn Execute this function on module load. Useful for service + * configuration. + * @description + * Use this method to register work which needs to be performed on module loading. + */ + config: config, + + /** + * @ngdoc method + * @name angular.Module#run + * @methodOf angular.Module + * @param {Function} initializationFn Execute this function after injector creation. + * Useful for application initialization. + * @description + * Use this method to register work which should be performed when the injector is done + * loading all modules. + */ + run: function(block) { + runBlocks.push(block); + return this; + } + }; + + if (configFn) { + config(configFn); + } + + return moduleInstance; + + /** + * @param {string} provider + * @param {string} method + * @param {String=} insertMethod + * @returns {angular.Module} + */ + function invokeLater(provider, method, insertMethod) { + return function() { + invokeQueue[insertMethod || 'push']([provider, method, arguments]); + return moduleInstance; + }; + } + }); + }; + }); + +} + +/* global + angularModule: true, + version: true, + + $LocaleProvider, + $CompileProvider, + + htmlAnchorDirective, + inputDirective, + inputDirective, + formDirective, + scriptDirective, + selectDirective, + styleDirective, + optionDirective, + ngBindDirective, + ngBindHtmlDirective, + ngBindTemplateDirective, + ngClassDirective, + ngClassEvenDirective, + ngClassOddDirective, + ngCspDirective, + ngCloakDirective, + ngControllerDirective, + ngFormDirective, + ngHideDirective, + ngIfDirective, + ngIncludeDirective, + ngInitDirective, + ngNonBindableDirective, + ngPluralizeDirective, + ngRepeatDirective, + ngShowDirective, + ngStyleDirective, + ngSwitchDirective, + ngSwitchWhenDirective, + ngSwitchDefaultDirective, + ngOptionsDirective, + ngTranscludeDirective, + ngModelDirective, + ngListDirective, + ngChangeDirective, + requiredDirective, + requiredDirective, + ngValueDirective, + ngAttributeAliasDirectives, + ngEventDirectives, + + $AnchorScrollProvider, + $AnimateProvider, + $BrowserProvider, + $CacheFactoryProvider, + $ControllerProvider, + $DocumentProvider, + $ExceptionHandlerProvider, + $FilterProvider, + $InterpolateProvider, + $IntervalProvider, + $HttpProvider, + $HttpBackendProvider, + $LocationProvider, + $LogProvider, + $ParseProvider, + $RootScopeProvider, + $QProvider, + $$SanitizeUriProvider, + $SceProvider, + $SceDelegateProvider, + $SnifferProvider, + $TemplateCacheProvider, + $TimeoutProvider, + $WindowProvider +*/ + + +/** + * @ngdoc property + * @name angular.version + * @description + * An object that contains information about the current AngularJS version. This object has the + * following properties: + * + * - `full` – `{string}` – Full version string, such as "0.9.18". + * - `major` – `{number}` – Major version number, such as "0". + * - `minor` – `{number}` – Minor version number, such as "9". + * - `dot` – `{number}` – Dot version number, such as "18". + * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". + */ +var version = { + full: '1.2.3', // all of these placeholder strings will be replaced by grunt's + major: 1, // package task + minor: 2, + dot: 3, + codeName: 'unicorn-zapper' +}; + + +function publishExternalAPI(angular){ + extend(angular, { + 'bootstrap': bootstrap, + 'copy': copy, + 'extend': extend, + 'equals': equals, + 'element': jqLite, + 'forEach': forEach, + 'injector': createInjector, + 'noop':noop, + 'bind':bind, + 'toJson': toJson, + 'fromJson': fromJson, + 'identity':identity, + 'isUndefined': isUndefined, + 'isDefined': isDefined, + 'isString': isString, + 'isFunction': isFunction, + 'isObject': isObject, + 'isNumber': isNumber, + 'isElement': isElement, + 'isArray': isArray, + 'version': version, + 'isDate': isDate, + 'lowercase': lowercase, + 'uppercase': uppercase, + 'callbacks': {counter: 0}, + '$$minErr': minErr, + '$$csp': csp + }); + + angularModule = setupModuleLoader(window); + try { + angularModule('ngLocale'); + } catch (e) { + angularModule('ngLocale', []).provider('$locale', $LocaleProvider); + } + + angularModule('ng', ['ngLocale'], ['$provide', + function ngModule($provide) { + // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it. + $provide.provider({ + $$sanitizeUri: $$SanitizeUriProvider + }); + $provide.provider('$compile', $CompileProvider). + directive({ + a: htmlAnchorDirective, + input: inputDirective, + textarea: inputDirective, + form: formDirective, + script: scriptDirective, + select: selectDirective, + style: styleDirective, + option: optionDirective, + ngBind: ngBindDirective, + ngBindHtml: ngBindHtmlDirective, + ngBindTemplate: ngBindTemplateDirective, + ngClass: ngClassDirective, + ngClassEven: ngClassEvenDirective, + ngClassOdd: ngClassOddDirective, + ngCloak: ngCloakDirective, + ngController: ngControllerDirective, + ngForm: ngFormDirective, + ngHide: ngHideDirective, + ngIf: ngIfDirective, + ngInclude: ngIncludeDirective, + ngInit: ngInitDirective, + ngNonBindable: ngNonBindableDirective, + ngPluralize: ngPluralizeDirective, + ngRepeat: ngRepeatDirective, + ngShow: ngShowDirective, + ngStyle: ngStyleDirective, + ngSwitch: ngSwitchDirective, + ngSwitchWhen: ngSwitchWhenDirective, + ngSwitchDefault: ngSwitchDefaultDirective, + ngOptions: ngOptionsDirective, + ngTransclude: ngTranscludeDirective, + ngModel: ngModelDirective, + ngList: ngListDirective, + ngChange: ngChangeDirective, + required: requiredDirective, + ngRequired: requiredDirective, + ngValue: ngValueDirective + }). + directive(ngAttributeAliasDirectives). + directive(ngEventDirectives); + $provide.provider({ + $anchorScroll: $AnchorScrollProvider, + $animate: $AnimateProvider, + $browser: $BrowserProvider, + $cacheFactory: $CacheFactoryProvider, + $controller: $ControllerProvider, + $document: $DocumentProvider, + $exceptionHandler: $ExceptionHandlerProvider, + $filter: $FilterProvider, + $interpolate: $InterpolateProvider, + $interval: $IntervalProvider, + $http: $HttpProvider, + $httpBackend: $HttpBackendProvider, + $location: $LocationProvider, + $log: $LogProvider, + $parse: $ParseProvider, + $rootScope: $RootScopeProvider, + $q: $QProvider, + $sce: $SceProvider, + $sceDelegate: $SceDelegateProvider, + $sniffer: $SnifferProvider, + $templateCache: $TemplateCacheProvider, + $timeout: $TimeoutProvider, + $window: $WindowProvider + }); + } + ]); +} + +/* global + + -JQLitePrototype, + -addEventListenerFn, + -removeEventListenerFn, + -BOOLEAN_ATTR +*/ + +////////////////////////////////// +//JQLite +////////////////////////////////// + +/** + * @ngdoc function + * @name angular.element + * @function + * + * @description + * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. + * + * If jQuery is available, `angular.element` is an alias for the + * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element` + * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite." + * + *
jqLite is a tiny, API-compatible subset of jQuery that allows + * Angular to manipulate the DOM in a cross-browser compatible way. **jqLite** implements only the most + * commonly needed functionality with the goal of having a very small footprint.
+ * + * To use jQuery, simply load it before `DOMContentLoaded` event fired. + * + *
**Note:** all element references in Angular are always wrapped with jQuery or + * jqLite; they are never raw DOM references.
+ * + * ## Angular's jqLite + * jqLite provides only the following jQuery methods: + * + * - [`addClass()`](http://api.jquery.com/addClass/) + * - [`after()`](http://api.jquery.com/after/) + * - [`append()`](http://api.jquery.com/append/) + * - [`attr()`](http://api.jquery.com/attr/) + * - [`bind()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData + * - [`children()`](http://api.jquery.com/children/) - Does not support selectors + * - [`clone()`](http://api.jquery.com/clone/) + * - [`contents()`](http://api.jquery.com/contents/) + * - [`css()`](http://api.jquery.com/css/) + * - [`data()`](http://api.jquery.com/data/) + * - [`eq()`](http://api.jquery.com/eq/) + * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name + * - [`hasClass()`](http://api.jquery.com/hasClass/) + * - [`html()`](http://api.jquery.com/html/) + * - [`next()`](http://api.jquery.com/next/) - Does not support selectors + * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData + * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors + * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors + * - [`prepend()`](http://api.jquery.com/prepend/) + * - [`prop()`](http://api.jquery.com/prop/) + * - [`ready()`](http://api.jquery.com/ready/) + * - [`remove()`](http://api.jquery.com/remove/) + * - [`removeAttr()`](http://api.jquery.com/removeAttr/) + * - [`removeClass()`](http://api.jquery.com/removeClass/) + * - [`removeData()`](http://api.jquery.com/removeData/) + * - [`replaceWith()`](http://api.jquery.com/replaceWith/) + * - [`text()`](http://api.jquery.com/text/) + * - [`toggleClass()`](http://api.jquery.com/toggleClass/) + * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers. + * - [`unbind()`](http://api.jquery.com/off/) - Does not support namespaces + * - [`val()`](http://api.jquery.com/val/) + * - [`wrap()`](http://api.jquery.com/wrap/) + * + * ## jQuery/jqLite Extras + * Angular also provides the following additional methods and events to both jQuery and jqLite: + * + * ### Events + * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event + * on all DOM nodes being removed. This can be used to clean up any 3rd party bindings to the DOM + * element before it is removed. + * + * ### Methods + * - `controller(name)` - retrieves the controller of the current element or its parent. By default + * retrieves controller associated with the `ngController` directive. If `name` is provided as + * camelCase directive name, then the controller for this directive will be retrieved (e.g. + * `'ngModel'`). + * - `injector()` - retrieves the injector of the current element or its parent. + * - `scope()` - retrieves the {@link api/ng.$rootScope.Scope scope} of the current + * element or its parent. + * - `isolateScope()` - retrieves an isolate {@link api/ng.$rootScope.Scope scope} if one is attached directly to the + * current element. This getter should be used only on elements that contain a directive which starts a new isolate + * scope. Calling `scope()` on this element always returns the original non-isolate scope. + * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top + * parent element is reached. + * + * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery. + * @returns {Object} jQuery object. + */ + +var jqCache = JQLite.cache = {}, + jqName = JQLite.expando = 'ng-' + new Date().getTime(), + jqId = 1, + addEventListenerFn = (window.document.addEventListener + ? function(element, type, fn) {element.addEventListener(type, fn, false);} + : function(element, type, fn) {element.attachEvent('on' + type, fn);}), + removeEventListenerFn = (window.document.removeEventListener + ? function(element, type, fn) {element.removeEventListener(type, fn, false); } + : function(element, type, fn) {element.detachEvent('on' + type, fn); }); + +function jqNextId() { return ++jqId; } + + +var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g; +var MOZ_HACK_REGEXP = /^moz([A-Z])/; +var jqLiteMinErr = minErr('jqLite'); + +/** + * Converts snake_case to camelCase. + * Also there is special case for Moz prefix starting with upper case letter. + * @param name Name to normalize + */ +function camelCase(name) { + return name. + replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) { + return offset ? letter.toUpperCase() : letter; + }). + replace(MOZ_HACK_REGEXP, 'Moz$1'); +} + +///////////////////////////////////////////// +// jQuery mutation patch +// +// In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a +// $destroy event on all DOM nodes being removed. +// +///////////////////////////////////////////// + +function jqLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) { + var originalJqFn = jQuery.fn[name]; + originalJqFn = originalJqFn.$original || originalJqFn; + removePatch.$original = originalJqFn; + jQuery.fn[name] = removePatch; + + function removePatch(param) { + // jshint -W040 + var list = filterElems && param ? [this.filter(param)] : [this], + fireEvent = dispatchThis, + set, setIndex, setLength, + element, childIndex, childLength, children; + + if (!getterIfNoArguments || param != null) { + while(list.length) { + set = list.shift(); + for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) { + element = jqLite(set[setIndex]); + if (fireEvent) { + element.triggerHandler('$destroy'); + } else { + fireEvent = !fireEvent; + } + for(childIndex = 0, childLength = (children = element.children()).length; + childIndex < childLength; + childIndex++) { + list.push(jQuery(children[childIndex])); + } + } + } + } + return originalJqFn.apply(this, arguments); + } +} + +///////////////////////////////////////////// +function JQLite(element) { + if (element instanceof JQLite) { + return element; + } + if (!(this instanceof JQLite)) { + if (isString(element) && element.charAt(0) != '<') { + throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element'); + } + return new JQLite(element); + } + + if (isString(element)) { + var div = document.createElement('div'); + // Read about the NoScope elements here: + // http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx + div.innerHTML = '
 
' + element; // IE insanity to make NoScope elements work! + div.removeChild(div.firstChild); // remove the superfluous div + jqLiteAddNodes(this, div.childNodes); + var fragment = jqLite(document.createDocumentFragment()); + fragment.append(this); // detach the elements from the temporary DOM div. + } else { + jqLiteAddNodes(this, element); + } +} + +function jqLiteClone(element) { + return element.cloneNode(true); +} + +function jqLiteDealoc(element){ + jqLiteRemoveData(element); + for ( var i = 0, children = element.childNodes || []; i < children.length; i++) { + jqLiteDealoc(children[i]); + } +} + +function jqLiteOff(element, type, fn, unsupported) { + if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument'); + + var events = jqLiteExpandoStore(element, 'events'), + handle = jqLiteExpandoStore(element, 'handle'); + + if (!handle) return; //no listeners registered + + if (isUndefined(type)) { + forEach(events, function(eventHandler, type) { + removeEventListenerFn(element, type, eventHandler); + delete events[type]; + }); + } else { + forEach(type.split(' '), function(type) { + if (isUndefined(fn)) { + removeEventListenerFn(element, type, events[type]); + delete events[type]; + } else { + arrayRemove(events[type] || [], fn); + } + }); + } +} + +function jqLiteRemoveData(element, name) { + var expandoId = element[jqName], + expandoStore = jqCache[expandoId]; + + if (expandoStore) { + if (name) { + delete jqCache[expandoId].data[name]; + return; + } + + if (expandoStore.handle) { + expandoStore.events.$destroy && expandoStore.handle({}, '$destroy'); + jqLiteOff(element); + } + delete jqCache[expandoId]; + element[jqName] = undefined; // ie does not allow deletion of attributes on elements. + } +} + +function jqLiteExpandoStore(element, key, value) { + var expandoId = element[jqName], + expandoStore = jqCache[expandoId || -1]; + + if (isDefined(value)) { + if (!expandoStore) { + element[jqName] = expandoId = jqNextId(); + expandoStore = jqCache[expandoId] = {}; + } + expandoStore[key] = value; + } else { + return expandoStore && expandoStore[key]; + } +} + +function jqLiteData(element, key, value) { + var data = jqLiteExpandoStore(element, 'data'), + isSetter = isDefined(value), + keyDefined = !isSetter && isDefined(key), + isSimpleGetter = keyDefined && !isObject(key); + + if (!data && !isSimpleGetter) { + jqLiteExpandoStore(element, 'data', data = {}); + } + + if (isSetter) { + data[key] = value; + } else { + if (keyDefined) { + if (isSimpleGetter) { + // don't create data in this case. + return data && data[key]; + } else { + extend(data, key); + } + } else { + return data; + } + } +} + +function jqLiteHasClass(element, selector) { + if (!element.getAttribute) return false; + return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " "). + indexOf( " " + selector + " " ) > -1); +} + +function jqLiteRemoveClass(element, cssClasses) { + if (cssClasses && element.setAttribute) { + forEach(cssClasses.split(' '), function(cssClass) { + element.setAttribute('class', trim( + (" " + (element.getAttribute('class') || '') + " ") + .replace(/[\n\t]/g, " ") + .replace(" " + trim(cssClass) + " ", " ")) + ); + }); + } +} + +function jqLiteAddClass(element, cssClasses) { + if (cssClasses && element.setAttribute) { + var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ') + .replace(/[\n\t]/g, " "); + + forEach(cssClasses.split(' '), function(cssClass) { + cssClass = trim(cssClass); + if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) { + existingClasses += cssClass + ' '; + } + }); + + element.setAttribute('class', trim(existingClasses)); + } +} + +function jqLiteAddNodes(root, elements) { + if (elements) { + elements = (!elements.nodeName && isDefined(elements.length) && !isWindow(elements)) + ? elements + : [ elements ]; + for(var i=0; i < elements.length; i++) { + root.push(elements[i]); + } + } +} + +function jqLiteController(element, name) { + return jqLiteInheritedData(element, '$' + (name || 'ngController' ) + 'Controller'); +} + +function jqLiteInheritedData(element, name, value) { + element = jqLite(element); + + // if element is the document object work with the html element instead + // this makes $(document).scope() possible + if(element[0].nodeType == 9) { + element = element.find('html'); + } + var names = isArray(name) ? name : [name]; + + while (element.length) { + + for (var i = 0, ii = names.length; i < ii; i++) { + if ((value = element.data(names[i])) !== undefined) return value; + } + element = element.parent(); + } +} + +////////////////////////////////////////// +// Functions which are declared directly. +////////////////////////////////////////// +var JQLitePrototype = JQLite.prototype = { + ready: function(fn) { + var fired = false; + + function trigger() { + if (fired) return; + fired = true; + fn(); + } + + // check if document already is loaded + if (document.readyState === 'complete'){ + setTimeout(trigger); + } else { + this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9 + // we can not use jqLite since we are not done loading and jQuery could be loaded later. + // jshint -W064 + JQLite(window).on('load', trigger); // fallback to window.onload for others + // jshint +W064 + } + }, + toString: function() { + var value = []; + forEach(this, function(e){ value.push('' + e);}); + return '[' + value.join(', ') + ']'; + }, + + eq: function(index) { + return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]); + }, + + length: 0, + push: push, + sort: [].sort, + splice: [].splice +}; + +////////////////////////////////////////// +// Functions iterating getter/setters. +// these functions return self on setter and +// value on get. +////////////////////////////////////////// +var BOOLEAN_ATTR = {}; +forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) { + BOOLEAN_ATTR[lowercase(value)] = value; +}); +var BOOLEAN_ELEMENTS = {}; +forEach('input,select,option,textarea,button,form,details'.split(','), function(value) { + BOOLEAN_ELEMENTS[uppercase(value)] = true; +}); + +function getBooleanAttrName(element, name) { + // check dom last since we will most likely fail on name + var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()]; + + // booleanAttr is here twice to minimize DOM access + return booleanAttr && BOOLEAN_ELEMENTS[element.nodeName] && booleanAttr; +} + +forEach({ + data: jqLiteData, + inheritedData: jqLiteInheritedData, + + scope: function(element) { + // Can't use jqLiteData here directly so we stay compatible with jQuery! + return jqLite(element).data('$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']); + }, + + isolateScope: function(element) { + // Can't use jqLiteData here directly so we stay compatible with jQuery! + return jqLite(element).data('$isolateScope') || jqLite(element).data('$isolateScopeNoTemplate'); + }, + + controller: jqLiteController , + + injector: function(element) { + return jqLiteInheritedData(element, '$injector'); + }, + + removeAttr: function(element,name) { + element.removeAttribute(name); + }, + + hasClass: jqLiteHasClass, + + css: function(element, name, value) { + name = camelCase(name); + + if (isDefined(value)) { + element.style[name] = value; + } else { + var val; + + if (msie <= 8) { + // this is some IE specific weirdness that jQuery 1.6.4 does not sure why + val = element.currentStyle && element.currentStyle[name]; + if (val === '') val = 'auto'; + } + + val = val || element.style[name]; + + if (msie <= 8) { + // jquery weirdness :-/ + val = (val === '') ? undefined : val; + } + + return val; + } + }, + + attr: function(element, name, value){ + var lowercasedName = lowercase(name); + if (BOOLEAN_ATTR[lowercasedName]) { + if (isDefined(value)) { + if (!!value) { + element[name] = true; + element.setAttribute(name, lowercasedName); + } else { + element[name] = false; + element.removeAttribute(lowercasedName); + } + } else { + return (element[name] || + (element.attributes.getNamedItem(name)|| noop).specified) + ? lowercasedName + : undefined; + } + } else if (isDefined(value)) { + element.setAttribute(name, value); + } else if (element.getAttribute) { + // the extra argument "2" is to get the right thing for a.href in IE, see jQuery code + // some elements (e.g. Document) don't have get attribute, so return undefined + var ret = element.getAttribute(name, 2); + // normalize non-existing attributes to undefined (as jQuery) + return ret === null ? undefined : ret; + } + }, + + prop: function(element, name, value) { + if (isDefined(value)) { + element[name] = value; + } else { + return element[name]; + } + }, + + text: (function() { + var NODE_TYPE_TEXT_PROPERTY = []; + if (msie < 9) { + NODE_TYPE_TEXT_PROPERTY[1] = 'innerText'; /** Element **/ + NODE_TYPE_TEXT_PROPERTY[3] = 'nodeValue'; /** Text **/ + } else { + NODE_TYPE_TEXT_PROPERTY[1] = /** Element **/ + NODE_TYPE_TEXT_PROPERTY[3] = 'textContent'; /** Text **/ + } + getText.$dv = ''; + return getText; + + function getText(element, value) { + var textProp = NODE_TYPE_TEXT_PROPERTY[element.nodeType]; + if (isUndefined(value)) { + return textProp ? element[textProp] : ''; + } + element[textProp] = value; + } + })(), + + val: function(element, value) { + if (isUndefined(value)) { + if (nodeName_(element) === 'SELECT' && element.multiple) { + var result = []; + forEach(element.options, function (option) { + if (option.selected) { + result.push(option.value || option.text); + } + }); + return result.length === 0 ? null : result; + } + return element.value; + } + element.value = value; + }, + + html: function(element, value) { + if (isUndefined(value)) { + return element.innerHTML; + } + for (var i = 0, childNodes = element.childNodes; i < childNodes.length; i++) { + jqLiteDealoc(childNodes[i]); + } + element.innerHTML = value; + } +}, function(fn, name){ + /** + * Properties: writes return selection, reads return first value + */ + JQLite.prototype[name] = function(arg1, arg2) { + var i, key; + + // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it + // in a way that survives minification. + if (((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2) === undefined) { + if (isObject(arg1)) { + + // we are a write, but the object properties are the key/values + for(i=0; i < this.length; i++) { + if (fn === jqLiteData) { + // data() takes the whole object in jQuery + fn(this[i], arg1); + } else { + for (key in arg1) { + fn(this[i], key, arg1[key]); + } + } + } + // return self for chaining + return this; + } else { + // we are a read, so read the first child. + var value = fn.$dv; + // Only if we have $dv do we iterate over all, otherwise it is just the first element. + var jj = (value === undefined) ? Math.min(this.length, 1) : this.length; + for (var j = 0; j < jj; j++) { + var nodeValue = fn(this[j], arg1, arg2); + value = value ? value + nodeValue : nodeValue; + } + return value; + } + } else { + // we are a write, so apply to all children + for(i=0; i < this.length; i++) { + fn(this[i], arg1, arg2); + } + // return self for chaining + return this; + } + }; +}); + +function createEventHandler(element, events) { + var eventHandler = function (event, type) { + if (!event.preventDefault) { + event.preventDefault = function() { + event.returnValue = false; //ie + }; + } + + if (!event.stopPropagation) { + event.stopPropagation = function() { + event.cancelBubble = true; //ie + }; + } + + if (!event.target) { + event.target = event.srcElement || document; + } + + if (isUndefined(event.defaultPrevented)) { + var prevent = event.preventDefault; + event.preventDefault = function() { + event.defaultPrevented = true; + prevent.call(event); + }; + event.defaultPrevented = false; + } + + event.isDefaultPrevented = function() { + return event.defaultPrevented || event.returnValue === false; + }; + + forEach(events[type || event.type], function(fn) { + fn.call(element, event); + }); + + // Remove monkey-patched methods (IE), + // as they would cause memory leaks in IE8. + if (msie <= 8) { + // IE7/8 does not allow to delete property on native object + event.preventDefault = null; + event.stopPropagation = null; + event.isDefaultPrevented = null; + } else { + // It shouldn't affect normal browsers (native methods are defined on prototype). + delete event.preventDefault; + delete event.stopPropagation; + delete event.isDefaultPrevented; + } + }; + eventHandler.elem = element; + return eventHandler; +} + +////////////////////////////////////////// +// Functions iterating traversal. +// These functions chain results into a single +// selector. +////////////////////////////////////////// +forEach({ + removeData: jqLiteRemoveData, + + dealoc: jqLiteDealoc, + + on: function onFn(element, type, fn, unsupported){ + if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters'); + + var events = jqLiteExpandoStore(element, 'events'), + handle = jqLiteExpandoStore(element, 'handle'); + + if (!events) jqLiteExpandoStore(element, 'events', events = {}); + if (!handle) jqLiteExpandoStore(element, 'handle', handle = createEventHandler(element, events)); + + forEach(type.split(' '), function(type){ + var eventFns = events[type]; + + if (!eventFns) { + if (type == 'mouseenter' || type == 'mouseleave') { + var contains = document.body.contains || document.body.compareDocumentPosition ? + function( a, b ) { + // jshint bitwise: false + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + events[type] = []; + + // Refer to jQuery's implementation of mouseenter & mouseleave + // Read about mouseenter and mouseleave: + // http://www.quirksmode.org/js/events_mouse.html#link8 + var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"}; + + onFn(element, eventmap[type], function(event) { + var target = this, related = event.relatedTarget; + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !contains(target, related)) ){ + handle(event, type); + } + }); + + } else { + addEventListenerFn(element, type, handle); + events[type] = []; + } + eventFns = events[type]; + } + eventFns.push(fn); + }); + }, + + off: jqLiteOff, + + replaceWith: function(element, replaceNode) { + var index, parent = element.parentNode; + jqLiteDealoc(element); + forEach(new JQLite(replaceNode), function(node){ + if (index) { + parent.insertBefore(node, index.nextSibling); + } else { + parent.replaceChild(node, element); + } + index = node; + }); + }, + + children: function(element) { + var children = []; + forEach(element.childNodes, function(element){ + if (element.nodeType === 1) + children.push(element); + }); + return children; + }, + + contents: function(element) { + return element.childNodes || []; + }, + + append: function(element, node) { + forEach(new JQLite(node), function(child){ + if (element.nodeType === 1 || element.nodeType === 11) { + element.appendChild(child); + } + }); + }, + + prepend: function(element, node) { + if (element.nodeType === 1) { + var index = element.firstChild; + forEach(new JQLite(node), function(child){ + element.insertBefore(child, index); + }); + } + }, + + wrap: function(element, wrapNode) { + wrapNode = jqLite(wrapNode)[0]; + var parent = element.parentNode; + if (parent) { + parent.replaceChild(wrapNode, element); + } + wrapNode.appendChild(element); + }, + + remove: function(element) { + jqLiteDealoc(element); + var parent = element.parentNode; + if (parent) parent.removeChild(element); + }, + + after: function(element, newElement) { + var index = element, parent = element.parentNode; + forEach(new JQLite(newElement), function(node){ + parent.insertBefore(node, index.nextSibling); + index = node; + }); + }, + + addClass: jqLiteAddClass, + removeClass: jqLiteRemoveClass, + + toggleClass: function(element, selector, condition) { + if (isUndefined(condition)) { + condition = !jqLiteHasClass(element, selector); + } + (condition ? jqLiteAddClass : jqLiteRemoveClass)(element, selector); + }, + + parent: function(element) { + var parent = element.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + + next: function(element) { + if (element.nextElementSibling) { + return element.nextElementSibling; + } + + // IE8 doesn't have nextElementSibling + var elm = element.nextSibling; + while (elm != null && elm.nodeType !== 1) { + elm = elm.nextSibling; + } + return elm; + }, + + find: function(element, selector) { + return element.getElementsByTagName(selector); + }, + + clone: jqLiteClone, + + triggerHandler: function(element, eventName, eventData) { + var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName]; + + eventData = eventData || []; + + var event = [{ + preventDefault: noop, + stopPropagation: noop + }]; + + forEach(eventFns, function(fn) { + fn.apply(element, event.concat(eventData)); + }); + } +}, function(fn, name){ + /** + * chaining functions + */ + JQLite.prototype[name] = function(arg1, arg2, arg3) { + var value; + for(var i=0; i < this.length; i++) { + if (isUndefined(value)) { + value = fn(this[i], arg1, arg2, arg3); + if (isDefined(value)) { + // any function which returns a value needs to be wrapped + value = jqLite(value); + } + } else { + jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3)); + } + } + return isDefined(value) ? value : this; + }; + + // bind legacy bind/unbind to on/off + JQLite.prototype.bind = JQLite.prototype.on; + JQLite.prototype.unbind = JQLite.prototype.off; +}); + +/** + * Computes a hash of an 'obj'. + * Hash of a: + * string is string + * number is number as string + * object is either result of calling $$hashKey function on the object or uniquely generated id, + * that is also assigned to the $$hashKey property of the object. + * + * @param obj + * @returns {string} hash string such that the same input will have the same hash string. + * The resulting string key is in 'type:hashKey' format. + */ +function hashKey(obj) { + var objType = typeof obj, + key; + + if (objType == 'object' && obj !== null) { + if (typeof (key = obj.$$hashKey) == 'function') { + // must invoke on object to keep the right this + key = obj.$$hashKey(); + } else if (key === undefined) { + key = obj.$$hashKey = nextUid(); + } + } else { + key = obj; + } + + return objType + ':' + key; +} + +/** + * HashMap which can use objects as keys + */ +function HashMap(array){ + forEach(array, this.put, this); +} +HashMap.prototype = { + /** + * Store key value pair + * @param key key to store can be any type + * @param value value to store can be any type + */ + put: function(key, value) { + this[hashKey(key)] = value; + }, + + /** + * @param key + * @returns the value for the key + */ + get: function(key) { + return this[hashKey(key)]; + }, + + /** + * Remove the key/value pair + * @param key + */ + remove: function(key) { + var value = this[key = hashKey(key)]; + delete this[key]; + return value; + } +}; + +/** + * @ngdoc function + * @name angular.injector + * @function + * + * @description + * Creates an injector function that can be used for retrieving services as well as for + * dependency injection (see {@link guide/di dependency injection}). + * + + * @param {Array.} modules A list of module functions or their aliases. See + * {@link angular.module}. The `ng` module must be explicitly added. + * @returns {function()} Injector function. See {@link AUTO.$injector $injector}. + * + * @example + * Typical usage + *
+ *   // create an injector
+ *   var $injector = angular.injector(['ng']);
+ *
+ *   // use the injector to kick off your application
+ *   // use the type inference to auto inject arguments, or use implicit injection
+ *   $injector.invoke(function($rootScope, $compile, $document){
+ *     $compile($document)($rootScope);
+ *     $rootScope.$digest();
+ *   });
+ * 
+ */ + + +/** + * @ngdoc overview + * @name AUTO + * @description + * + * Implicit module which gets automatically added to each {@link AUTO.$injector $injector}. + */ + +var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; +var FN_ARG_SPLIT = /,/; +var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; +var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; +var $injectorMinErr = minErr('$injector'); +function annotate(fn) { + var $inject, + fnText, + argDecl, + last; + + if (typeof fn == 'function') { + if (!($inject = fn.$inject)) { + $inject = []; + if (fn.length) { + fnText = fn.toString().replace(STRIP_COMMENTS, ''); + argDecl = fnText.match(FN_ARGS); + forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){ + arg.replace(FN_ARG, function(all, underscore, name){ + $inject.push(name); + }); + }); + } + fn.$inject = $inject; + } + } else if (isArray(fn)) { + last = fn.length - 1; + assertArgFn(fn[last], 'fn'); + $inject = fn.slice(0, last); + } else { + assertArgFn(fn, 'fn', true); + } + return $inject; +} + +/////////////////////////////////////// + +/** + * @ngdoc object + * @name AUTO.$injector + * @function + * + * @description + * + * `$injector` is used to retrieve object instances as defined by + * {@link AUTO.$provide provider}, instantiate types, invoke methods, + * and load modules. + * + * The following always holds true: + * + *
+ *   var $injector = angular.injector();
+ *   expect($injector.get('$injector')).toBe($injector);
+ *   expect($injector.invoke(function($injector){
+ *     return $injector;
+ *   }).toBe($injector);
+ * 
+ * + * # Injection Function Annotation + * + * JavaScript does not have annotations, and annotations are needed for dependency injection. The + * following are all valid ways of annotating function with injection arguments and are equivalent. + * + *
+ *   // inferred (only works if code not minified/obfuscated)
+ *   $injector.invoke(function(serviceA){});
+ *
+ *   // annotated
+ *   function explicit(serviceA) {};
+ *   explicit.$inject = ['serviceA'];
+ *   $injector.invoke(explicit);
+ *
+ *   // inline
+ *   $injector.invoke(['serviceA', function(serviceA){}]);
+ * 
+ * + * ## Inference + * + * In JavaScript calling `toString()` on a function returns the function definition. The definition + * can then be parsed and the function arguments can be extracted. *NOTE:* This does not work with + * minification, and obfuscation tools since these tools change the argument names. + * + * ## `$inject` Annotation + * By adding a `$inject` property onto a function the injection parameters can be specified. + * + * ## Inline + * As an array of injection names, where the last item in the array is the function to call. + */ + +/** + * @ngdoc method + * @name AUTO.$injector#get + * @methodOf AUTO.$injector + * + * @description + * Return an instance of the service. + * + * @param {string} name The name of the instance to retrieve. + * @return {*} The instance. + */ + +/** + * @ngdoc method + * @name AUTO.$injector#invoke + * @methodOf AUTO.$injector + * + * @description + * Invoke the method and supply the method arguments from the `$injector`. + * + * @param {!function} fn The function to invoke. Function parameters are injected according to the + * {@link guide/di $inject Annotation} rules. + * @param {Object=} self The `this` for the invoked method. + * @param {Object=} locals Optional object. If preset then any argument names are read from this + * object first, before the `$injector` is consulted. + * @returns {*} the value returned by the invoked `fn` function. + */ + +/** + * @ngdoc method + * @name AUTO.$injector#has + * @methodOf AUTO.$injector + * + * @description + * Allows the user to query if the particular service exist. + * + * @param {string} Name of the service to query. + * @returns {boolean} returns true if injector has given service. + */ + +/** + * @ngdoc method + * @name AUTO.$injector#instantiate + * @methodOf AUTO.$injector + * @description + * Create a new instance of JS type. The method takes a constructor function invokes the new + * operator and supplies all of the arguments to the constructor function as specified by the + * constructor annotation. + * + * @param {function} Type Annotated constructor function. + * @param {Object=} locals Optional object. If preset then any argument names are read from this + * object first, before the `$injector` is consulted. + * @returns {Object} new instance of `Type`. + */ + +/** + * @ngdoc method + * @name AUTO.$injector#annotate + * @methodOf AUTO.$injector + * + * @description + * Returns an array of service names which the function is requesting for injection. This API is + * used by the injector to determine which services need to be injected into the function when the + * function is invoked. There are three ways in which the function can be annotated with the needed + * dependencies. + * + * # Argument names + * + * The simplest form is to extract the dependencies from the arguments of the function. This is done + * by converting the function into a string using `toString()` method and extracting the argument + * names. + *
+ *   // Given
+ *   function MyController($scope, $route) {
+ *     // ...
+ *   }
+ *
+ *   // Then
+ *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
+ * 
+ * + * This method does not work with code minification / obfuscation. For this reason the following + * annotation strategies are supported. + * + * # The `$inject` property + * + * If a function has an `$inject` property and its value is an array of strings, then the strings + * represent names of services to be injected into the function. + *
+ *   // Given
+ *   var MyController = function(obfuscatedScope, obfuscatedRoute) {
+ *     // ...
+ *   }
+ *   // Define function dependencies
+ *   MyController.$inject = ['$scope', '$route'];
+ *
+ *   // Then
+ *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
+ * 
+ * + * # The array notation + * + * It is often desirable to inline Injected functions and that's when setting the `$inject` property + * is very inconvenient. In these situations using the array notation to specify the dependencies in + * a way that survives minification is a better choice: + * + *
+ *   // We wish to write this (not minification / obfuscation safe)
+ *   injector.invoke(function($compile, $rootScope) {
+ *     // ...
+ *   });
+ *
+ *   // We are forced to write break inlining
+ *   var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) {
+ *     // ...
+ *   };
+ *   tmpFn.$inject = ['$compile', '$rootScope'];
+ *   injector.invoke(tmpFn);
+ *
+ *   // To better support inline function the inline annotation is supported
+ *   injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
+ *     // ...
+ *   }]);
+ *
+ *   // Therefore
+ *   expect(injector.annotate(
+ *      ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])
+ *    ).toEqual(['$compile', '$rootScope']);
+ * 
+ * + * @param {function|Array.} fn Function for which dependent service names need to + * be retrieved as described above. + * + * @returns {Array.} The names of the services which the function requires. + */ + + + + +/** + * @ngdoc object + * @name AUTO.$provide + * + * @description + * + * The {@link AUTO.$provide $provide} service has a number of methods for registering components + * with the {@link AUTO.$injector $injector}. Many of these functions are also exposed on + * {@link angular.Module}. + * + * An Angular **service** is a singleton object created by a **service factory**. These **service + * factories** are functions which, in turn, are created by a **service provider**. + * The **service providers** are constructor functions. When instantiated they must contain a + * property called `$get`, which holds the **service factory** function. + * + * When you request a service, the {@link AUTO.$injector $injector} is responsible for finding the + * correct **service provider**, instantiating it and then calling its `$get` **service factory** + * function to get the instance of the **service**. + * + * Often services have no configuration options and there is no need to add methods to the service + * provider. The provider will be no more than a constructor function with a `$get` property. For + * these cases the {@link AUTO.$provide $provide} service has additional helper methods to register + * services without specifying a provider. + * + * * {@link AUTO.$provide#methods_provider provider(provider)} - registers a **service provider** with the + * {@link AUTO.$injector $injector} + * * {@link AUTO.$provide#methods_constant constant(obj)} - registers a value/object that can be accessed by + * providers and services. + * * {@link AUTO.$provide#methods_value value(obj)} - registers a value/object that can only be accessed by + * services, not providers. + * * {@link AUTO.$provide#methods_factory factory(fn)} - registers a service **factory function**, `fn`, + * that will be wrapped in a **service provider** object, whose `$get` property will contain the + * given factory function. + * * {@link AUTO.$provide#methods_service service(class)} - registers a **constructor function**, `class` that + * that will be wrapped in a **service provider** object, whose `$get` property will instantiate + * a new object using the given constructor function. + * + * See the individual methods for more information and examples. + */ + +/** + * @ngdoc method + * @name AUTO.$provide#provider + * @methodOf AUTO.$provide + * @description + * + * Register a **provider function** with the {@link AUTO.$injector $injector}. Provider functions + * are constructor functions, whose instances are responsible for "providing" a factory for a + * service. + * + * Service provider names start with the name of the service they provide followed by `Provider`. + * For example, the {@link ng.$log $log} service has a provider called + * {@link ng.$logProvider $logProvider}. + * + * Service provider objects can have additional methods which allow configuration of the provider + * and its service. Importantly, you can configure what kind of service is created by the `$get` + * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a + * method {@link ng.$logProvider#debugEnabled debugEnabled} + * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the + * console or not. + * + * @param {string} name The name of the instance. NOTE: the provider will be available under `name + + 'Provider'` key. + * @param {(Object|function())} provider If the provider is: + * + * - `Object`: then it should have a `$get` method. The `$get` method will be invoked using + * {@link AUTO.$injector#invoke $injector.invoke()} when an instance needs to be + * created. + * - `Constructor`: a new instance of the provider will be created using + * {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as + * `object`. + * + * @returns {Object} registered provider instance + + * @example + * + * The following example shows how to create a simple event tracking service and register it using + * {@link AUTO.$provide#methods_provider $provide.provider()}. + * + *
+ *  // Define the eventTracker provider
+ *  function EventTrackerProvider() {
+ *    var trackingUrl = '/track';
+ *
+ *    // A provider method for configuring where the tracked events should been saved
+ *    this.setTrackingUrl = function(url) {
+ *      trackingUrl = url;
+ *    };
+ *
+ *    // The service factory function
+ *    this.$get = ['$http', function($http) {
+ *      var trackedEvents = {};
+ *      return {
+ *        // Call this to track an event
+ *        event: function(event) {
+ *          var count = trackedEvents[event] || 0;
+ *          count += 1;
+ *          trackedEvents[event] = count;
+ *          return count;
+ *        },
+ *        // Call this to save the tracked events to the trackingUrl
+ *        save: function() {
+ *          $http.post(trackingUrl, trackedEvents);
+ *        }
+ *      };
+ *    }];
+ *  }
+ *
+ *  describe('eventTracker', function() {
+ *    var postSpy;
+ *
+ *    beforeEach(module(function($provide) {
+ *      // Register the eventTracker provider
+ *      $provide.provider('eventTracker', EventTrackerProvider);
+ *    }));
+ *
+ *    beforeEach(module(function(eventTrackerProvider) {
+ *      // Configure eventTracker provider
+ *      eventTrackerProvider.setTrackingUrl('/custom-track');
+ *    }));
+ *
+ *    it('tracks events', inject(function(eventTracker) {
+ *      expect(eventTracker.event('login')).toEqual(1);
+ *      expect(eventTracker.event('login')).toEqual(2);
+ *    }));
+ *
+ *    it('saves to the tracking url', inject(function(eventTracker, $http) {
+ *      postSpy = spyOn($http, 'post');
+ *      eventTracker.event('login');
+ *      eventTracker.save();
+ *      expect(postSpy).toHaveBeenCalled();
+ *      expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');
+ *      expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');
+ *      expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });
+ *    }));
+ *  });
+ * 
+ */ + +/** + * @ngdoc method + * @name AUTO.$provide#factory + * @methodOf AUTO.$provide + * @description + * + * Register a **service factory**, which will be called to return the service instance. + * This is short for registering a service where its provider consists of only a `$get` property, + * which is the given service factory function. + * You should use {@link AUTO.$provide#factory $provide.factory(getFn)} if you do not need to + * configure your service in a provider. + * + * @param {string} name The name of the instance. + * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand + * for `$provide.provider(name, {$get: $getFn})`. + * @returns {Object} registered provider instance + * + * @example + * Here is an example of registering a service + *
+ *   $provide.factory('ping', ['$http', function($http) {
+ *     return function ping() {
+ *       return $http.send('/ping');
+ *     };
+ *   }]);
+ * 
+ * You would then inject and use this service like this: + *
+ *   someModule.controller('Ctrl', ['ping', function(ping) {
+ *     ping();
+ *   }]);
+ * 
+ */ + + +/** + * @ngdoc method + * @name AUTO.$provide#service + * @methodOf AUTO.$provide + * @description + * + * Register a **service constructor**, which will be invoked with `new` to create the service + * instance. + * This is short for registering a service where its provider's `$get` property is the service + * constructor function that will be used to instantiate the service instance. + * + * You should use {@link AUTO.$provide#methods_service $provide.service(class)} if you define your service + * as a type/class. This is common when using {@link http://coffeescript.org CoffeeScript}. + * + * @param {string} name The name of the instance. + * @param {Function} constructor A class (constructor function) that will be instantiated. + * @returns {Object} registered provider instance + * + * @example + * Here is an example of registering a service using + * {@link AUTO.$provide#methods_service $provide.service(class)} that is defined as a CoffeeScript class. + *
+ *   class Ping
+ *     constructor: (@$http)->
+ *     send: ()=>
+ *       @$http.get('/ping')
+ *
+ *   $provide.service('ping', ['$http', Ping])
+ * 
+ * You would then inject and use this service like this: + *
+ *   someModule.controller 'Ctrl', ['ping', (ping)->
+ *     ping.send()
+ *   ]
+ * 
+ */ + + +/** + * @ngdoc method + * @name AUTO.$provide#value + * @methodOf AUTO.$provide + * @description + * + * Register a **value service** with the {@link AUTO.$injector $injector}, such as a string, a + * number, an array, an object or a function. This is short for registering a service where its + * provider's `$get` property is a factory function that takes no arguments and returns the **value + * service**. + * + * Value services are similar to constant services, except that they cannot be injected into a + * module configuration function (see {@link angular.Module#config}) but they can be overridden by + * an Angular + * {@link AUTO.$provide#decorator decorator}. + * + * @param {string} name The name of the instance. + * @param {*} value The value. + * @returns {Object} registered provider instance + * + * @example + * Here are some examples of creating value services. + *
+ *   $provide.value('ADMIN_USER', 'admin');
+ *
+ *   $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
+ *
+ *   $provide.value('halfOf', function(value) {
+ *     return value / 2;
+ *   });
+ * 
+ */ + + +/** + * @ngdoc method + * @name AUTO.$provide#constant + * @methodOf AUTO.$provide + * @description + * + * Register a **constant service**, such as a string, a number, an array, an object or a function, + * with the {@link AUTO.$injector $injector}. Unlike {@link AUTO.$provide#value value} it can be + * injected into a module configuration function (see {@link angular.Module#config}) and it cannot + * be overridden by an Angular {@link AUTO.$provide#decorator decorator}. + * + * @param {string} name The name of the constant. + * @param {*} value The constant value. + * @returns {Object} registered instance + * + * @example + * Here a some examples of creating constants: + *
+ *   $provide.constant('SHARD_HEIGHT', 306);
+ *
+ *   $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);
+ *
+ *   $provide.constant('double', function(value) {
+ *     return value * 2;
+ *   });
+ * 
+ */ + + +/** + * @ngdoc method + * @name AUTO.$provide#decorator + * @methodOf AUTO.$provide + * @description + * + * Register a **service decorator** with the {@link AUTO.$injector $injector}. A service decorator + * intercepts the creation of a service, allowing it to override or modify the behaviour of the + * service. The object returned by the decorator may be the original service, or a new service + * object which replaces or wraps and delegates to the original service. + * + * @param {string} name The name of the service to decorate. + * @param {function()} decorator This function will be invoked when the service needs to be + * instantiated and should return the decorated service instance. The function is called using + * the {@link AUTO.$injector#invoke injector.invoke} method and is therefore fully injectable. + * Local injection arguments: + * + * * `$delegate` - The original service instance, which can be monkey patched, configured, + * decorated or delegated to. + * + * @example + * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting + * calls to {@link ng.$log#error $log.warn()}. + *
+ *   $provider.decorator('$log', ['$delegate', function($delegate) {
+ *     $delegate.warn = $delegate.error;
+ *     return $delegate;
+ *   }]);
+ * 
+ */ + + +function createInjector(modulesToLoad) { + var INSTANTIATING = {}, + providerSuffix = 'Provider', + path = [], + loadedModules = new HashMap(), + providerCache = { + $provide: { + provider: supportObject(provider), + factory: supportObject(factory), + service: supportObject(service), + value: supportObject(value), + constant: supportObject(constant), + decorator: decorator + } + }, + providerInjector = (providerCache.$injector = + createInternalInjector(providerCache, function() { + throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- ')); + })), + instanceCache = {}, + instanceInjector = (instanceCache.$injector = + createInternalInjector(instanceCache, function(servicename) { + var provider = providerInjector.get(servicename + providerSuffix); + return instanceInjector.invoke(provider.$get, provider); + })); + + + forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); }); + + return instanceInjector; + + //////////////////////////////////// + // $provider + //////////////////////////////////// + + function supportObject(delegate) { + return function(key, value) { + if (isObject(key)) { + forEach(key, reverseParams(delegate)); + } else { + return delegate(key, value); + } + }; + } + + function provider(name, provider_) { + assertNotHasOwnProperty(name, 'service'); + if (isFunction(provider_) || isArray(provider_)) { + provider_ = providerInjector.instantiate(provider_); + } + if (!provider_.$get) { + throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name); + } + return providerCache[name + providerSuffix] = provider_; + } + + function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); } + + function service(name, constructor) { + return factory(name, ['$injector', function($injector) { + return $injector.instantiate(constructor); + }]); + } + + function value(name, val) { return factory(name, valueFn(val)); } + + function constant(name, value) { + assertNotHasOwnProperty(name, 'constant'); + providerCache[name] = value; + instanceCache[name] = value; + } + + function decorator(serviceName, decorFn) { + var origProvider = providerInjector.get(serviceName + providerSuffix), + orig$get = origProvider.$get; + + origProvider.$get = function() { + var origInstance = instanceInjector.invoke(orig$get, origProvider); + return instanceInjector.invoke(decorFn, null, {$delegate: origInstance}); + }; + } + + //////////////////////////////////// + // Module Loading + //////////////////////////////////// + function loadModules(modulesToLoad){ + var runBlocks = [], moduleFn, invokeQueue, i, ii; + forEach(modulesToLoad, function(module) { + if (loadedModules.get(module)) return; + loadedModules.put(module, true); + + try { + if (isString(module)) { + moduleFn = angularModule(module); + runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks); + + for(invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) { + var invokeArgs = invokeQueue[i], + provider = providerInjector.get(invokeArgs[0]); + + provider[invokeArgs[1]].apply(provider, invokeArgs[2]); + } + } else if (isFunction(module)) { + runBlocks.push(providerInjector.invoke(module)); + } else if (isArray(module)) { + runBlocks.push(providerInjector.invoke(module)); + } else { + assertArgFn(module, 'module'); + } + } catch (e) { + if (isArray(module)) { + module = module[module.length - 1]; + } + if (e.message && e.stack && e.stack.indexOf(e.message) == -1) { + // Safari & FF's stack traces don't contain error.message content + // unlike those of Chrome and IE + // So if stack doesn't contain message, we create a new string that contains both. + // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here. + /* jshint -W022 */ + e = e.message + '\n' + e.stack; + } + throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}", + module, e.stack || e.message || e); + } + }); + return runBlocks; + } + + //////////////////////////////////// + // internal Injector + //////////////////////////////////// + + function createInternalInjector(cache, factory) { + + function getService(serviceName) { + if (cache.hasOwnProperty(serviceName)) { + if (cache[serviceName] === INSTANTIATING) { + throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); + } + return cache[serviceName]; + } else { + try { + path.unshift(serviceName); + cache[serviceName] = INSTANTIATING; + return cache[serviceName] = factory(serviceName); + } finally { + path.shift(); + } + } + } + + function invoke(fn, self, locals){ + var args = [], + $inject = annotate(fn), + length, i, + key; + + for(i = 0, length = $inject.length; i < length; i++) { + key = $inject[i]; + if (typeof key !== 'string') { + throw $injectorMinErr('itkn', + 'Incorrect injection token! Expected service name as string, got {0}', key); + } + args.push( + locals && locals.hasOwnProperty(key) + ? locals[key] + : getService(key) + ); + } + if (!fn.$inject) { + // this means that we must be an array. + fn = fn[length]; + } + + + // Performance optimization: http://jsperf.com/apply-vs-call-vs-invoke + switch (self ? -1 : args.length) { + case 0: return fn(); + case 1: return fn(args[0]); + case 2: return fn(args[0], args[1]); + case 3: return fn(args[0], args[1], args[2]); + case 4: return fn(args[0], args[1], args[2], args[3]); + case 5: return fn(args[0], args[1], args[2], args[3], args[4]); + case 6: return fn(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + case 8: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); + case 9: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], + args[8]); + case 10: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], + args[8], args[9]); + default: return fn.apply(self, args); + } + } + + function instantiate(Type, locals) { + var Constructor = function() {}, + instance, returnedValue; + + // Check if Type is annotated and use just the given function at n-1 as parameter + // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]); + Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype; + instance = new Constructor(); + returnedValue = invoke(Type, instance, locals); + + return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance; + } + + return { + invoke: invoke, + instantiate: instantiate, + get: getService, + annotate: annotate, + has: function(name) { + return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name); + } + }; + } +} + +/** + * @ngdoc function + * @name ng.$anchorScroll + * @requires $window + * @requires $location + * @requires $rootScope + * + * @description + * When called, it checks current value of `$location.hash()` and scroll to related element, + * according to rules specified in + * {@link http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document Html5 spec}. + * + * It also watches the `$location.hash()` and scrolls whenever it changes to match any anchor. + * This can be disabled by calling `$anchorScrollProvider.disableAutoScrolling()`. + * + * @example + + +
+ Go to bottom + You're at the bottom! +
+
+ + function ScrollCtrl($scope, $location, $anchorScroll) { + $scope.gotoBottom = function (){ + // set the location.hash to the id of + // the element you wish to scroll to. + $location.hash('bottom'); + + // call $anchorScroll() + $anchorScroll(); + } + } + + + #scrollArea { + height: 350px; + overflow: auto; + } + + #bottom { + display: block; + margin-top: 2000px; + } + +
+ */ +function $AnchorScrollProvider() { + + var autoScrollingEnabled = true; + + this.disableAutoScrolling = function() { + autoScrollingEnabled = false; + }; + + this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) { + var document = $window.document; + + // helper function to get first anchor from a NodeList + // can't use filter.filter, as it accepts only instances of Array + // and IE can't convert NodeList to an array using [].slice + // TODO(vojta): use filter if we change it to accept lists as well + function getFirstAnchor(list) { + var result = null; + forEach(list, function(element) { + if (!result && lowercase(element.nodeName) === 'a') result = element; + }); + return result; + } + + function scroll() { + var hash = $location.hash(), elm; + + // empty hash, scroll to the top of the page + if (!hash) $window.scrollTo(0, 0); + + // element with given id + else if ((elm = document.getElementById(hash))) elm.scrollIntoView(); + + // first anchor with given name :-D + else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) elm.scrollIntoView(); + + // no element and hash == 'top', scroll to the top of the page + else if (hash === 'top') $window.scrollTo(0, 0); + } + + // does not scroll when user clicks on anchor link that is currently on + // (no url change, no $location.hash() change), browser native does scroll + if (autoScrollingEnabled) { + $rootScope.$watch(function autoScrollWatch() {return $location.hash();}, + function autoScrollWatchAction() { + $rootScope.$evalAsync(scroll); + }); + } + + return scroll; + }]; +} + +var $animateMinErr = minErr('$animate'); + +/** + * @ngdoc object + * @name ng.$animateProvider + * + * @description + * Default implementation of $animate that doesn't perform any animations, instead just + * synchronously performs DOM + * updates and calls done() callbacks. + * + * In order to enable animations the ngAnimate module has to be loaded. + * + * To see the functional implementation check out src/ngAnimate/animate.js + */ +var $AnimateProvider = ['$provide', function($provide) { + + + this.$$selectors = {}; + + + /** + * @ngdoc function + * @name ng.$animateProvider#register + * @methodOf ng.$animateProvider + * + * @description + * Registers a new injectable animation factory function. The factory function produces the + * animation object which contains callback functions for each event that is expected to be + * animated. + * + * * `eventFn`: `function(Element, doneFunction)` The element to animate, the `doneFunction` + * must be called once the element animation is complete. If a function is returned then the + * animation service will use this function to cancel the animation whenever a cancel event is + * triggered. + * + * + *
+   *   return {
+     *     eventFn : function(element, done) {
+     *       //code to run the animation
+     *       //once complete, then run done()
+     *       return function cancellationFunction() {
+     *         //code to cancel the animation
+     *       }
+     *     }
+     *   }
+   *
+ * + * @param {string} name The name of the animation. + * @param {function} factory The factory function that will be executed to return the animation + * object. + */ + this.register = function(name, factory) { + var key = name + '-animation'; + if (name && name.charAt(0) != '.') throw $animateMinErr('notcsel', + "Expecting class selector starting with '.' got '{0}'.", name); + this.$$selectors[name.substr(1)] = key; + $provide.factory(key, factory); + }; + + this.$get = ['$timeout', function($timeout) { + + /** + * + * @ngdoc object + * @name ng.$animate + * @description The $animate service provides rudimentary DOM manipulation functions to + * insert, remove and move elements within the DOM, as well as adding and removing classes. + * This service is the core service used by the ngAnimate $animator service which provides + * high-level animation hooks for CSS and JavaScript. + * + * $animate is available in the AngularJS core, however, the ngAnimate module must be included + * to enable full out animation support. Otherwise, $animate will only perform simple DOM + * manipulation operations. + * + * To learn more about enabling animation support, click here to visit the {@link ngAnimate + * ngAnimate module page} as well as the {@link ngAnimate.$animate ngAnimate $animate service + * page}. + */ + return { + + /** + * + * @ngdoc function + * @name ng.$animate#enter + * @methodOf ng.$animate + * @function + * @description Inserts the element into the DOM either after the `after` element or within + * the `parent` element. Once complete, the done() callback will be fired (if provided). + * @param {jQuery/jqLite element} element the element which will be inserted into the DOM + * @param {jQuery/jqLite element} parent the parent element which will append the element as + * a child (if the after element is not present) + * @param {jQuery/jqLite element} after the sibling element which will append the element + * after itself + * @param {function=} done callback function that will be called after the element has been + * inserted into the DOM + */ + enter : function(element, parent, after, done) { + if (after) { + after.after(element); + } else { + if (!parent || !parent[0]) { + parent = after.parent(); + } + parent.append(element); + } + done && $timeout(done, 0, false); + }, + + /** + * + * @ngdoc function + * @name ng.$animate#leave + * @methodOf ng.$animate + * @function + * @description Removes the element from the DOM. Once complete, the done() callback will be + * fired (if provided). + * @param {jQuery/jqLite element} element the element which will be removed from the DOM + * @param {function=} done callback function that will be called after the element has been + * removed from the DOM + */ + leave : function(element, done) { + element.remove(); + done && $timeout(done, 0, false); + }, + + /** + * + * @ngdoc function + * @name ng.$animate#move + * @methodOf ng.$animate + * @function + * @description Moves the position of the provided element within the DOM to be placed + * either after the `after` element or inside of the `parent` element. Once complete, the + * done() callback will be fired (if provided). + * + * @param {jQuery/jqLite element} element the element which will be moved around within the + * DOM + * @param {jQuery/jqLite element} parent the parent element where the element will be + * inserted into (if the after element is not present) + * @param {jQuery/jqLite element} after the sibling element where the element will be + * positioned next to + * @param {function=} done the callback function (if provided) that will be fired after the + * element has been moved to its new position + */ + move : function(element, parent, after, done) { + // Do not remove element before insert. Removing will cause data associated with the + // element to be dropped. Insert will implicitly do the remove. + this.enter(element, parent, after, done); + }, + + /** + * + * @ngdoc function + * @name ng.$animate#addClass + * @methodOf ng.$animate + * @function + * @description Adds the provided className CSS class value to the provided element. Once + * complete, the done() callback will be fired (if provided). + * @param {jQuery/jqLite element} element the element which will have the className value + * added to it + * @param {string} className the CSS class which will be added to the element + * @param {function=} done the callback function (if provided) that will be fired after the + * className value has been added to the element + */ + addClass : function(element, className, done) { + className = isString(className) ? + className : + isArray(className) ? className.join(' ') : ''; + forEach(element, function (element) { + jqLiteAddClass(element, className); + }); + done && $timeout(done, 0, false); + }, + + /** + * + * @ngdoc function + * @name ng.$animate#removeClass + * @methodOf ng.$animate + * @function + * @description Removes the provided className CSS class value from the provided element. + * Once complete, the done() callback will be fired (if provided). + * @param {jQuery/jqLite element} element the element which will have the className value + * removed from it + * @param {string} className the CSS class which will be removed from the element + * @param {function=} done the callback function (if provided) that will be fired after the + * className value has been removed from the element + */ + removeClass : function(element, className, done) { + className = isString(className) ? + className : + isArray(className) ? className.join(' ') : ''; + forEach(element, function (element) { + jqLiteRemoveClass(element, className); + }); + done && $timeout(done, 0, false); + }, + + enabled : noop + }; + }]; +}]; + +/** + * ! This is a private undocumented service ! + * + * @name ng.$browser + * @requires $log + * @description + * This object has two goals: + * + * - hide all the global state in the browser caused by the window object + * - abstract away all the browser specific features and inconsistencies + * + * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser` + * service, which can be used for convenient testing of the application without the interaction with + * the real browser apis. + */ +/** + * @param {object} window The global window object. + * @param {object} document jQuery wrapped document. + * @param {function()} XHR XMLHttpRequest constructor. + * @param {object} $log console.log or an object with the same interface. + * @param {object} $sniffer $sniffer service + */ +function Browser(window, document, $log, $sniffer) { + var self = this, + rawDocument = document[0], + location = window.location, + history = window.history, + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + pendingDeferIds = {}; + + self.isMock = false; + + var outstandingRequestCount = 0; + var outstandingRequestCallbacks = []; + + // TODO(vojta): remove this temporary api + self.$$completeOutstandingRequest = completeOutstandingRequest; + self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; }; + + /** + * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks` + * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed. + */ + function completeOutstandingRequest(fn) { + try { + fn.apply(null, sliceArgs(arguments, 1)); + } finally { + outstandingRequestCount--; + if (outstandingRequestCount === 0) { + while(outstandingRequestCallbacks.length) { + try { + outstandingRequestCallbacks.pop()(); + } catch (e) { + $log.error(e); + } + } + } + } + } + + /** + * @private + * Note: this method is used only by scenario runner + * TODO(vojta): prefix this method with $$ ? + * @param {function()} callback Function that will be called when no outstanding request + */ + self.notifyWhenNoOutstandingRequests = function(callback) { + // force browser to execute all pollFns - this is needed so that cookies and other pollers fire + // at some deterministic time in respect to the test runner's actions. Leaving things up to the + // regular poller would result in flaky tests. + forEach(pollFns, function(pollFn){ pollFn(); }); + + if (outstandingRequestCount === 0) { + callback(); + } else { + outstandingRequestCallbacks.push(callback); + } + }; + + ////////////////////////////////////////////////////////////// + // Poll Watcher API + ////////////////////////////////////////////////////////////// + var pollFns = [], + pollTimeout; + + /** + * @name ng.$browser#addPollFn + * @methodOf ng.$browser + * + * @param {function()} fn Poll function to add + * + * @description + * Adds a function to the list of functions that poller periodically executes, + * and starts polling if not started yet. + * + * @returns {function()} the added function + */ + self.addPollFn = function(fn) { + if (isUndefined(pollTimeout)) startPoller(100, setTimeout); + pollFns.push(fn); + return fn; + }; + + /** + * @param {number} interval How often should browser call poll functions (ms) + * @param {function()} setTimeout Reference to a real or fake `setTimeout` function. + * + * @description + * Configures the poller to run in the specified intervals, using the specified + * setTimeout fn and kicks it off. + */ + function startPoller(interval, setTimeout) { + (function check() { + forEach(pollFns, function(pollFn){ pollFn(); }); + pollTimeout = setTimeout(check, interval); + })(); + } + + ////////////////////////////////////////////////////////////// + // URL API + ////////////////////////////////////////////////////////////// + + var lastBrowserUrl = location.href, + baseElement = document.find('base'), + newLocation = null; + + /** + * @name ng.$browser#url + * @methodOf ng.$browser + * + * @description + * GETTER: + * Without any argument, this method just returns current value of location.href. + * + * SETTER: + * With at least one argument, this method sets url to new value. + * If html5 history api supported, pushState/replaceState is used, otherwise + * location.href/location.replace is used. + * Returns its own instance to allow chaining + * + * NOTE: this api is intended for use only by the $location service. Please use the + * {@link ng.$location $location service} to change url. + * + * @param {string} url New url (when used as setter) + * @param {boolean=} replace Should new url replace current history record ? + */ + self.url = function(url, replace) { + // Android Browser BFCache causes location reference to become stale. + if (location !== window.location) location = window.location; + + // setter + if (url) { + if (lastBrowserUrl == url) return; + lastBrowserUrl = url; + if ($sniffer.history) { + if (replace) history.replaceState(null, '', url); + else { + history.pushState(null, '', url); + // Crazy Opera Bug: http://my.opera.com/community/forums/topic.dml?id=1185462 + baseElement.attr('href', baseElement.attr('href')); + } + } else { + newLocation = url; + if (replace) { + location.replace(url); + } else { + location.href = url; + } + } + return self; + // getter + } else { + // - newLocation is a workaround for an IE7-9 issue with location.replace and location.href + // methods not updating location.href synchronously. + // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172 + return newLocation || location.href.replace(/%27/g,"'"); + } + }; + + var urlChangeListeners = [], + urlChangeInit = false; + + function fireUrlChange() { + newLocation = null; + if (lastBrowserUrl == self.url()) return; + + lastBrowserUrl = self.url(); + forEach(urlChangeListeners, function(listener) { + listener(self.url()); + }); + } + + /** + * @name ng.$browser#onUrlChange + * @methodOf ng.$browser + * @TODO(vojta): refactor to use node's syntax for events + * + * @description + * Register callback function that will be called, when url changes. + * + * It's only called when the url is changed by outside of angular: + * - user types different url into address bar + * - user clicks on history (forward/back) button + * - user clicks on a link + * + * It's not called when url is changed by $browser.url() method + * + * The listener gets called with new url as parameter. + * + * NOTE: this api is intended for use only by the $location service. Please use the + * {@link ng.$location $location service} to monitor url changes in angular apps. + * + * @param {function(string)} listener Listener function to be called when url changes. + * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous. + */ + self.onUrlChange = function(callback) { + if (!urlChangeInit) { + // We listen on both (hashchange/popstate) when available, as some browsers (e.g. Opera) + // don't fire popstate when user change the address bar and don't fire hashchange when url + // changed by push/replaceState + + // html5 history api - popstate event + if ($sniffer.history) jqLite(window).on('popstate', fireUrlChange); + // hashchange event + if ($sniffer.hashchange) jqLite(window).on('hashchange', fireUrlChange); + // polling + else self.addPollFn(fireUrlChange); + + urlChangeInit = true; + } + + urlChangeListeners.push(callback); + return callback; + }; + + ////////////////////////////////////////////////////////////// + // Misc API + ////////////////////////////////////////////////////////////// + + /** + * @name ng.$browser#baseHref + * @methodOf ng.$browser + * + * @description + * Returns current + * (always relative - without domain) + * + * @returns {string=} current + */ + self.baseHref = function() { + var href = baseElement.attr('href'); + return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : ''; + }; + + ////////////////////////////////////////////////////////////// + // Cookies API + ////////////////////////////////////////////////////////////// + var lastCookies = {}; + var lastCookieString = ''; + var cookiePath = self.baseHref(); + + /** + * @name ng.$browser#cookies + * @methodOf ng.$browser + * + * @param {string=} name Cookie name + * @param {string=} value Cookie value + * + * @description + * The cookies method provides a 'private' low level access to browser cookies. + * It is not meant to be used directly, use the $cookie service instead. + * + * The return values vary depending on the arguments that the method was called with as follows: + * + * - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify + * it + * - cookies(name, value) -> set name to value, if value is undefined delete the cookie + * - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that + * way) + * + * @returns {Object} Hash of all cookies (if called without any parameter) + */ + self.cookies = function(name, value) { + /* global escape: false, unescape: false */ + var cookieLength, cookieArray, cookie, i, index; + + if (name) { + if (value === undefined) { + rawDocument.cookie = escape(name) + "=;path=" + cookiePath + + ";expires=Thu, 01 Jan 1970 00:00:00 GMT"; + } else { + if (isString(value)) { + cookieLength = (rawDocument.cookie = escape(name) + '=' + escape(value) + + ';path=' + cookiePath).length + 1; + + // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum: + // - 300 cookies + // - 20 cookies per unique domain + // - 4096 bytes per cookie + if (cookieLength > 4096) { + $log.warn("Cookie '"+ name + + "' possibly not set or overflowed because it was too large ("+ + cookieLength + " > 4096 bytes)!"); + } + } + } + } else { + if (rawDocument.cookie !== lastCookieString) { + lastCookieString = rawDocument.cookie; + cookieArray = lastCookieString.split("; "); + lastCookies = {}; + + for (i = 0; i < cookieArray.length; i++) { + cookie = cookieArray[i]; + index = cookie.indexOf('='); + if (index > 0) { //ignore nameless cookies + name = unescape(cookie.substring(0, index)); + // the first value that is seen for a cookie is the most + // specific one. values for the same cookie name that + // follow are for less specific paths. + if (lastCookies[name] === undefined) { + lastCookies[name] = unescape(cookie.substring(index + 1)); + } + } + } + } + return lastCookies; + } + }; + + + /** + * @name ng.$browser#defer + * @methodOf ng.$browser + * @param {function()} fn A function, who's execution should be deferred. + * @param {number=} [delay=0] of milliseconds to defer the function execution. + * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`. + * + * @description + * Executes a fn asynchronously via `setTimeout(fn, delay)`. + * + * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using + * `setTimeout` in tests, the fns are queued in an array, which can be programmatically flushed + * via `$browser.defer.flush()`. + * + */ + self.defer = function(fn, delay) { + var timeoutId; + outstandingRequestCount++; + timeoutId = setTimeout(function() { + delete pendingDeferIds[timeoutId]; + completeOutstandingRequest(fn); + }, delay || 0); + pendingDeferIds[timeoutId] = true; + return timeoutId; + }; + + + /** + * @name ng.$browser#defer.cancel + * @methodOf ng.$browser.defer + * + * @description + * Cancels a deferred task identified with `deferId`. + * + * @param {*} deferId Token returned by the `$browser.defer` function. + * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully + * canceled. + */ + self.defer.cancel = function(deferId) { + if (pendingDeferIds[deferId]) { + delete pendingDeferIds[deferId]; + clearTimeout(deferId); + completeOutstandingRequest(noop); + return true; + } + return false; + }; + +} + +function $BrowserProvider(){ + this.$get = ['$window', '$log', '$sniffer', '$document', + function( $window, $log, $sniffer, $document){ + return new Browser($window, $document, $log, $sniffer); + }]; +} + +/** + * @ngdoc object + * @name ng.$cacheFactory + * + * @description + * Factory that constructs cache objects and gives access to them. + * + *
+ *
+ *  var cache = $cacheFactory('cacheId');
+ *  expect($cacheFactory.get('cacheId')).toBe(cache);
+ *  expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
+ *
+ *  cache.put("key", "value");
+ *  cache.put("another key", "another value");
+ *
+ *  // We've specified no options on creation
+ *  expect(cache.info()).toEqual({id: 'cacheId', size: 2});
+ *
+ * 
+ * + * + * @param {string} cacheId Name or id of the newly created cache. + * @param {object=} options Options object that specifies the cache behavior. Properties: + * + * - `{number=}` `capacity` — turns the cache into LRU cache. + * + * @returns {object} Newly created cache object with the following set of methods: + * + * - `{object}` `info()` — Returns id, size, and options of cache. + * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns + * it. + * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss. + * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache. + * - `{void}` `removeAll()` — Removes all cached values. + * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory. + * + */ +function $CacheFactoryProvider() { + + this.$get = function() { + var caches = {}; + + function cacheFactory(cacheId, options) { + if (cacheId in caches) { + throw minErr('$cacheFactory')('iid', "CacheId '{0}' is already taken!", cacheId); + } + + var size = 0, + stats = extend({}, options, {id: cacheId}), + data = {}, + capacity = (options && options.capacity) || Number.MAX_VALUE, + lruHash = {}, + freshEnd = null, + staleEnd = null; + + return caches[cacheId] = { + + put: function(key, value) { + var lruEntry = lruHash[key] || (lruHash[key] = {key: key}); + + refresh(lruEntry); + + if (isUndefined(value)) return; + if (!(key in data)) size++; + data[key] = value; + + if (size > capacity) { + this.remove(staleEnd.key); + } + + return value; + }, + + + get: function(key) { + var lruEntry = lruHash[key]; + + if (!lruEntry) return; + + refresh(lruEntry); + + return data[key]; + }, + + + remove: function(key) { + var lruEntry = lruHash[key]; + + if (!lruEntry) return; + + if (lruEntry == freshEnd) freshEnd = lruEntry.p; + if (lruEntry == staleEnd) staleEnd = lruEntry.n; + link(lruEntry.n,lruEntry.p); + + delete lruHash[key]; + delete data[key]; + size--; + }, + + + removeAll: function() { + data = {}; + size = 0; + lruHash = {}; + freshEnd = staleEnd = null; + }, + + + destroy: function() { + data = null; + stats = null; + lruHash = null; + delete caches[cacheId]; + }, + + + info: function() { + return extend({}, stats, {size: size}); + } + }; + + + /** + * makes the `entry` the freshEnd of the LRU linked list + */ + function refresh(entry) { + if (entry != freshEnd) { + if (!staleEnd) { + staleEnd = entry; + } else if (staleEnd == entry) { + staleEnd = entry.n; + } + + link(entry.n, entry.p); + link(entry, freshEnd); + freshEnd = entry; + freshEnd.n = null; + } + } + + + /** + * bidirectionally links two entries of the LRU linked list + */ + function link(nextEntry, prevEntry) { + if (nextEntry != prevEntry) { + if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify + if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify + } + } + } + + + /** + * @ngdoc method + * @name ng.$cacheFactory#info + * @methodOf ng.$cacheFactory + * + * @description + * Get information about all the of the caches that have been created + * + * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info` + */ + cacheFactory.info = function() { + var info = {}; + forEach(caches, function(cache, cacheId) { + info[cacheId] = cache.info(); + }); + return info; + }; + + + /** + * @ngdoc method + * @name ng.$cacheFactory#get + * @methodOf ng.$cacheFactory + * + * @description + * Get access to a cache object by the `cacheId` used when it was created. + * + * @param {string} cacheId Name or id of a cache to access. + * @returns {object} Cache object identified by the cacheId or undefined if no such cache. + */ + cacheFactory.get = function(cacheId) { + return caches[cacheId]; + }; + + + return cacheFactory; + }; +} + +/** + * @ngdoc object + * @name ng.$templateCache + * + * @description + * The first time a template is used, it is loaded in the template cache for quick retrieval. You + * can load templates directly into the cache in a `script` tag, or by consuming the + * `$templateCache` service directly. + * + * Adding via the `script` tag: + *
+ * 
+ * 
+ * 
+ * 
+ *   ...
+ * 
+ * 
+ * + * **Note:** the `script` tag containing the template does not need to be included in the `head` of + * the document, but it must be below the `ng-app` definition. + * + * Adding via the $templateCache service: + * + *
+ * var myApp = angular.module('myApp', []);
+ * myApp.run(function($templateCache) {
+ *   $templateCache.put('templateId.html', 'This is the content of the template');
+ * });
+ * 
+ * + * To retrieve the template later, simply use it in your HTML: + *
+ * 
+ *
+ * + * or get it via Javascript: + *
+ * $templateCache.get('templateId.html')
+ * 
+ * + * See {@link ng.$cacheFactory $cacheFactory}. + * + */ +function $TemplateCacheProvider() { + this.$get = ['$cacheFactory', function($cacheFactory) { + return $cacheFactory('templates'); + }]; +} + +/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE! + * + * DOM-related variables: + * + * - "node" - DOM Node + * - "element" - DOM Element or Node + * - "$node" or "$element" - jqLite-wrapped node or element + * + * + * Compiler related stuff: + * + * - "linkFn" - linking fn of a single directive + * - "nodeLinkFn" - function that aggregates all linking fns for a particular node + * - "childLinkFn" - function that aggregates all linking fns for child nodes of a particular node + * - "compositeLinkFn" - function that aggregates all linking fns for a compilation root (nodeList) + */ + + +/** + * @ngdoc function + * @name ng.$compile + * @function + * + * @description + * Compiles a piece of HTML string or DOM into a template and produces a template function, which + * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together. + * + * The compilation is a process of walking the DOM tree and matching DOM elements to + * {@link ng.$compileProvider#methods_directive directives}. + * + *
+ * **Note:** This document is an in-depth reference of all directive options. + * For a gentle introduction to directives with examples of common use cases, + * see the {@link guide/directive directive guide}. + *
+ * + * ## Comprehensive Directive API + * + * There are many different options for a directive. + * + * The difference resides in the return value of the factory function. + * You can either return a "Directive Definition Object" (see below) that defines the directive properties, + * or just the `postLink` function (all other properties will have the default values). + * + *
+ * **Best Practice:** It's recommended to use the "directive definition object" form. + *
+ * + * Here's an example directive declared with a Directive Definition Object: + * + *
+ *   var myModule = angular.module(...);
+ *
+ *   myModule.directive('directiveName', function factory(injectables) {
+ *     var directiveDefinitionObject = {
+ *       priority: 0,
+ *       template: '
', // or // function(tElement, tAttrs) { ... }, + * // or + * // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, + * replace: false, + * transclude: false, + * restrict: 'A', + * scope: false, + * controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... }, + * require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'], + * compile: function compile(tElement, tAttrs, transclude) { + * return { + * pre: function preLink(scope, iElement, iAttrs, controller) { ... }, + * post: function postLink(scope, iElement, iAttrs, controller) { ... } + * } + * // or + * // return function postLink( ... ) { ... } + * }, + * // or + * // link: { + * // pre: function preLink(scope, iElement, iAttrs, controller) { ... }, + * // post: function postLink(scope, iElement, iAttrs, controller) { ... } + * // } + * // or + * // link: function postLink( ... ) { ... } + * }; + * return directiveDefinitionObject; + * }); + *
+ * + *
+ * **Note:** Any unspecified options will use the default value. You can see the default values below. + *
+ * + * Therefore the above can be simplified as: + * + *
+ *   var myModule = angular.module(...);
+ *
+ *   myModule.directive('directiveName', function factory(injectables) {
+ *     var directiveDefinitionObject = {
+ *       link: function postLink(scope, iElement, iAttrs) { ... }
+ *     };
+ *     return directiveDefinitionObject;
+ *     // or
+ *     // return function postLink(scope, iElement, iAttrs) { ... }
+ *   });
+ * 
+ * + * + * + * ### Directive Definition Object + * + * The directive definition object provides instructions to the {@link api/ng.$compile + * compiler}. The attributes are: + * + * #### `priority` + * When there are multiple directives defined on a single DOM element, sometimes it + * is necessary to specify the order in which the directives are applied. The `priority` is used + * to sort the directives before their `compile` functions get called. Priority is defined as a + * number. Directives with greater numerical `priority` are compiled first. Pre-link functions + * are also run in priority order, but post-link functions are run in reverse order. The order + * of directives with the same priority is undefined. The default priority is `0`. + * + * #### `terminal` + * If set to true then the current `priority` will be the last set of directives + * which will execute (any directives at the current priority will still execute + * as the order of execution on same `priority` is undefined). + * + * #### `scope` + * **If set to `true`,** then a new scope will be created for this directive. If multiple directives on the + * same element request a new scope, only one new scope is created. The new scope rule does not + * apply for the root of the template since the root of the template always gets a new scope. + * + * **If set to `{}` (object hash),** then a new "isolate" scope is created. The 'isolate' scope differs from + * normal scope in that it does not prototypically inherit from the parent scope. This is useful + * when creating reusable components, which should not accidentally read or modify data in the + * parent scope. + * + * The 'isolate' scope takes an object hash which defines a set of local scope properties + * derived from the parent scope. These local properties are useful for aliasing values for + * templates. Locals definition is a hash of local scope property to its source: + * + * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is + * always a string since DOM attributes are strings. If no `attr` name is specified then the + * attribute name is assumed to be the same as the local name. + * Given `` and widget definition + * of `scope: { localName:'@myAttr' }`, then widget scope property `localName` will reflect + * the interpolated value of `hello {{name}}`. As the `name` attribute changes so will the + * `localName` property on the widget scope. The `name` is read from the parent scope (not + * component scope). + * + * * `=` or `=attr` - set up bi-directional binding between a local scope property and the + * parent scope property of name defined via the value of the `attr` attribute. If no `attr` + * name is specified then the attribute name is assumed to be the same as the local name. + * Given `` and widget definition of + * `scope: { localModel:'=myAttr' }`, then widget scope property `localModel` will reflect the + * value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected + * in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent + * scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You + * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional. + * + * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. + * If no `attr` name is specified then the attribute name is assumed to be the same as the + * local name. Given `` and widget definition of + * `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to + * a function wrapper for the `count = count + value` expression. Often it's desirable to + * pass data from the isolated scope via an expression and to the parent scope, this can be + * done by passing a map of local variable names and values into the expression wrapper fn. + * For example, if the expression is `increment(amount)` then we can specify the amount value + * by calling the `localFn` as `localFn({amount: 22})`. + * + * + * + * #### `controller` + * Controller constructor function. The controller is instantiated before the + * pre-linking phase and it is shared with other directives (see + * `require` attribute). This allows the directives to communicate with each other and augment + * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals: + * + * * `$scope` - Current scope associated with the element + * * `$element` - Current element + * * `$attrs` - Current attributes object for the element + * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope. + * The scope can be overridden by an optional first argument. + * `function([scope], cloneLinkingFn)`. + * + * + * #### `require` + * Require another directive and inject its controller as the fourth argument to the linking function. The + * `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the + * injected argument will be an array in corresponding order. If no such directive can be + * found, or if the directive does not have a controller, then an error is raised. The name can be prefixed with: + * + * * (no prefix) - Locate the required controller on the current element. Throw an error if not found. + * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found. + * * `^` - Locate the required controller by searching the element's parents. Throw an error if not found. + * * `?^` - Attempt to locate the required controller by searching the element's parentsor pass `null` to the + * `link` fn if not found. + * + * + * #### `controllerAs` + * Controller alias at the directive scope. An alias for the controller so it + * can be referenced at the directive template. The directive needs to define a scope for this + * configuration to be used. Useful in the case when directive is used as component. + * + * + * #### `restrict` + * String of subset of `EACM` which restricts the directive to a specific directive + * declaration style. If omitted, the default (attributes only) is used. + * + * * `E` - Element name: `` + * * `A` - Attribute (default): `
` + * * `C` - Class: `
` + * * `M` - Comment: `` + * + * + * #### `template` + * replace the current element with the contents of the HTML. The replacement process + * migrates all of the attributes / classes from the old element to the new one. See the + * {@link guide/directive#creating-custom-directives_creating-directives_template-expanding-directive + * Directives Guide} for an example. + * + * You can specify `template` as a string representing the template or as a function which takes + * two arguments `tElement` and `tAttrs` (described in the `compile` function api below) and + * returns a string value representing the template. + * + * + * #### `templateUrl` + * Same as `template` but the template is loaded from the specified URL. Because + * the template loading is asynchronous the compilation/linking is suspended until the template + * is loaded. + * + * You can specify `templateUrl` as a string representing the URL or as a function which takes two + * arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns + * a string value representing the url. In either case, the template URL is passed through {@link + * api/ng.$sce#methods_getTrustedResourceUrl $sce.getTrustedResourceUrl}. + * + * + * #### `replace` + * specify where the template should be inserted. Defaults to `false`. + * + * * `true` - the template will replace the current element. + * * `false` - the template will replace the contents of the current element. + * + * + * #### `transclude` + * compile the content of the element and make it available to the directive. + * Typically used with {@link api/ng.directive:ngTransclude + * ngTransclude}. The advantage of transclusion is that the linking function receives a + * transclusion function which is pre-bound to the correct scope. In a typical setup the widget + * creates an `isolate` scope, but the transclusion is not a child, but a sibling of the `isolate` + * scope. This makes it possible for the widget to have private state, and the transclusion to + * be bound to the parent (pre-`isolate`) scope. + * + * * `true` - transclude the content of the directive. + * * `'element'` - transclude the whole element including any directives defined at lower priority. + * + * + * #### `compile` + * + *
+ *   function compile(tElement, tAttrs, transclude) { ... }
+ * 
+ * + * The compile function deals with transforming the template DOM. Since most directives do not do + * template transformation, it is not used often. Examples that require compile functions are + * directives that transform template DOM, such as {@link + * api/ng.directive:ngRepeat ngRepeat}, or load the contents + * asynchronously, such as {@link api/ngRoute.directive:ngView ngView}. The + * compile function takes the following arguments. + * + * * `tElement` - template element - The element where the directive has been declared. It is + * safe to do template transformation on the element and child elements only. + * + * * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared + * between all directive compile functions. + * + * * `transclude` - [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)` + * + *
+ * **Note:** The template instance and the link instance may be different objects if the template has + * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that + * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration + * should be done in a linking function rather than in a compile function. + *
+ * + *
+ * **Note:** The `transclude` function that is passed to the compile function is deprecated, as it + * e.g. does not know about the right outer scope. Please use the transclude function that is passed + * to the link function instead. + *
+ + * A compile function can have a return value which can be either a function or an object. + * + * * returning a (post-link) function - is equivalent to registering the linking function via the + * `link` property of the config object when the compile function is empty. + * + * * returning an object with function(s) registered via `pre` and `post` properties - allows you to + * control when a linking function should be called during the linking phase. See info about + * pre-linking and post-linking functions below. + * + * + * #### `link` + * This property is used only if the `compile` property is not defined. + * + *
+ *   function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
+ * 
+ * + * The link function is responsible for registering DOM listeners as well as updating the DOM. It is + * executed after the template has been cloned. This is where most of the directive logic will be + * put. + * + * * `scope` - {@link api/ng.$rootScope.Scope Scope} - The scope to be used by the + * directive for registering {@link api/ng.$rootScope.Scope#methods_$watch watches}. + * + * * `iElement` - instance element - The element where the directive is to be used. It is safe to + * manipulate the children of the element only in `postLink` function since the children have + * already been linked. + * + * * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared + * between all directive linking functions. + * + * * `controller` - a controller instance - A controller instance if at least one directive on the + * element defines a controller. The controller is shared among all the directives, which allows + * the directives to use the controllers as a communication channel. + * + * * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope. + * The scope can be overridden by an optional first argument. This is the same as the `$transclude` + * parameter of directive controllers. + * `function([scope], cloneLinkingFn)`. + * + * + * #### Pre-linking function + * + * Executed before the child elements are linked. Not safe to do DOM transformation since the + * compiler linking function will fail to locate the correct elements for linking. + * + * #### Post-linking function + * + * Executed after the child elements are linked. It is safe to do DOM transformation in the post-linking function. + * + * + * ### Attributes + * + * The {@link api/ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the + * `link()` or `compile()` functions. It has a variety of uses. + * + * accessing *Normalized attribute names:* + * Directives like 'ngBind' can be expressed in many ways: 'ng:bind', `data-ng-bind`, or 'x-ng-bind'. + * the attributes object allows for normalized access to + * the attributes. + * + * * *Directive inter-communication:* All directives share the same instance of the attributes + * object which allows the directives to use the attributes object as inter directive + * communication. + * + * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object + * allowing other directives to read the interpolated value. + * + * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes + * that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also + * the only way to easily get the actual value because during the linking phase the interpolation + * hasn't been evaluated yet and so the value is at this time set to `undefined`. + * + *
+ * function linkingFn(scope, elm, attrs, ctrl) {
+ *   // get the attribute value
+ *   console.log(attrs.ngModel);
+ *
+ *   // change the attribute
+ *   attrs.$set('ngModel', 'new value');
+ *
+ *   // observe changes to interpolated attribute
+ *   attrs.$observe('ngModel', function(value) {
+ *     console.log('ngModel has changed value to ' + value);
+ *   });
+ * }
+ * 
+ * + * Below is an example using `$compileProvider`. + * + *
+ * **Note**: Typically directives are registered with `module.directive`. The example below is + * to illustrate how `$compile` works. + *
+ * + + + +
+
+
+
+
+
+ + it('should auto compile', function() { + expect(element('div[compile]').text()).toBe('Hello Angular'); + input('html').enter('{{name}}!'); + expect(element('div[compile]').text()).toBe('Angular!'); + }); + +
+ + * + * + * @param {string|DOMElement} element Element or HTML string to compile into a template function. + * @param {function(angular.Scope[, cloneAttachFn]} transclude function available to directives. + * @param {number} maxPriority only apply directives lower then given priority (Only effects the + * root element(s), not their children) + * @returns {function(scope[, cloneAttachFn])} a link function which is used to bind template + * (a DOM element/tree) to a scope. Where: + * + * * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to. + * * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the + * `template` and call the `cloneAttachFn` function allowing the caller to attach the + * cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is + * called as:
`cloneAttachFn(clonedElement, scope)` where: + * + * * `clonedElement` - is a clone of the original `element` passed into the compiler. + * * `scope` - is the current scope with which the linking function is working with. + * + * Calling the linking function returns the element of the template. It is either the original + * element passed in, or the clone of the element if the `cloneAttachFn` is provided. + * + * After linking the view is not updated until after a call to $digest which typically is done by + * Angular automatically. + * + * If you need access to the bound view, there are two ways to do it: + * + * - If you are not asking the linking function to clone the template, create the DOM element(s) + * before you send them to the compiler and keep this reference around. + *
+ *     var element = $compile('

{{total}}

')(scope); + *
+ * + * - if on the other hand, you need the element to be cloned, the view reference from the original + * example would not point to the clone, but rather to the original template that was cloned. In + * this case, you can access the clone via the cloneAttachFn: + *
+ *     var templateHTML = angular.element('

{{total}}

'), + * scope = ....; + * + * var clonedElement = $compile(templateHTML)(scope, function(clonedElement, scope) { + * //attach the clone to DOM document at the right place + * }); + * + * //now we have reference to the cloned DOM via `clone` + *
+ * + * + * For information on how the compiler works, see the + * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide. + */ + +var $compileMinErr = minErr('$compile'); + +/** + * @ngdoc service + * @name ng.$compileProvider + * @function + * + * @description + */ +$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider']; +function $CompileProvider($provide, $$sanitizeUriProvider) { + var hasDirectives = {}, + Suffix = 'Directive', + COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/, + CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/; + + // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes + // The assumption is that future DOM event attribute names will begin with + // 'on' and be composed of only English letters. + var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/; + + /** + * @ngdoc function + * @name ng.$compileProvider#directive + * @methodOf ng.$compileProvider + * @function + * + * @description + * Register a new directive with the compiler. + * + * @param {string|Object} name Name of the directive in camel-case (i.e. ngBind which + * will match as ng-bind), or an object map of directives where the keys are the + * names and the values are the factories. + * @param {function|Array} directiveFactory An injectable directive factory function. See + * {@link guide/directive} for more info. + * @returns {ng.$compileProvider} Self for chaining. + */ + this.directive = function registerDirective(name, directiveFactory) { + assertNotHasOwnProperty(name, 'directive'); + if (isString(name)) { + assertArg(directiveFactory, 'directiveFactory'); + if (!hasDirectives.hasOwnProperty(name)) { + hasDirectives[name] = []; + $provide.factory(name + Suffix, ['$injector', '$exceptionHandler', + function($injector, $exceptionHandler) { + var directives = []; + forEach(hasDirectives[name], function(directiveFactory, index) { + try { + var directive = $injector.invoke(directiveFactory); + if (isFunction(directive)) { + directive = { compile: valueFn(directive) }; + } else if (!directive.compile && directive.link) { + directive.compile = valueFn(directive.link); + } + directive.priority = directive.priority || 0; + directive.index = index; + directive.name = directive.name || name; + directive.require = directive.require || (directive.controller && directive.name); + directive.restrict = directive.restrict || 'A'; + directives.push(directive); + } catch (e) { + $exceptionHandler(e); + } + }); + return directives; + }]); + } + hasDirectives[name].push(directiveFactory); + } else { + forEach(name, reverseParams(registerDirective)); + } + return this; + }; + + + /** + * @ngdoc function + * @name ng.$compileProvider#aHrefSanitizationWhitelist + * @methodOf ng.$compileProvider + * @function + * + * @description + * Retrieves or overrides the default regular expression that is used for whitelisting of safe + * urls during a[href] sanitization. + * + * The sanitization is a security measure aimed at prevent XSS attacks via html links. + * + * Any url about to be assigned to a[href] via data-binding is first normalized and turned into + * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist` + * regular expression. If a match is found, the original url is written into the dom. Otherwise, + * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM. + * + * @param {RegExp=} regexp New regexp to whitelist urls with. + * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for + * chaining otherwise. + */ + this.aHrefSanitizationWhitelist = function(regexp) { + if (isDefined(regexp)) { + $$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp); + return this; + } else { + return $$sanitizeUriProvider.aHrefSanitizationWhitelist(); + } + }; + + + /** + * @ngdoc function + * @name ng.$compileProvider#imgSrcSanitizationWhitelist + * @methodOf ng.$compileProvider + * @function + * + * @description + * Retrieves or overrides the default regular expression that is used for whitelisting of safe + * urls during img[src] sanitization. + * + * The sanitization is a security measure aimed at prevent XSS attacks via html links. + * + * Any url about to be assigned to img[src] via data-binding is first normalized and turned into + * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist` + * regular expression. If a match is found, the original url is written into the dom. Otherwise, + * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM. + * + * @param {RegExp=} regexp New regexp to whitelist urls with. + * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for + * chaining otherwise. + */ + this.imgSrcSanitizationWhitelist = function(regexp) { + if (isDefined(regexp)) { + $$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp); + return this; + } else { + return $$sanitizeUriProvider.imgSrcSanitizationWhitelist(); + } + }; + + this.$get = [ + '$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse', + '$controller', '$rootScope', '$document', '$sce', '$animate', '$$sanitizeUri', + function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse, + $controller, $rootScope, $document, $sce, $animate, $$sanitizeUri) { + + var Attributes = function(element, attr) { + this.$$element = element; + this.$attr = attr || {}; + }; + + Attributes.prototype = { + $normalize: directiveNormalize, + + + /** + * @ngdoc function + * @name ng.$compile.directive.Attributes#$addClass + * @methodOf ng.$compile.directive.Attributes + * @function + * + * @description + * Adds the CSS class value specified by the classVal parameter to the element. If animations + * are enabled then an animation will be triggered for the class addition. + * + * @param {string} classVal The className value that will be added to the element + */ + $addClass : function(classVal) { + if(classVal && classVal.length > 0) { + $animate.addClass(this.$$element, classVal); + } + }, + + /** + * @ngdoc function + * @name ng.$compile.directive.Attributes#$removeClass + * @methodOf ng.$compile.directive.Attributes + * @function + * + * @description + * Removes the CSS class value specified by the classVal parameter from the element. If + * animations are enabled then an animation will be triggered for the class removal. + * + * @param {string} classVal The className value that will be removed from the element + */ + $removeClass : function(classVal) { + if(classVal && classVal.length > 0) { + $animate.removeClass(this.$$element, classVal); + } + }, + + /** + * @ngdoc function + * @name ng.$compile.directive.Attributes#$updateClass + * @methodOf ng.$compile.directive.Attributes + * @function + * + * @description + * Adds and removes the appropriate CSS class values to the element based on the difference + * between the new and old CSS class values (specified as newClasses and oldClasses). + * + * @param {string} newClasses The current CSS className value + * @param {string} oldClasses The former CSS className value + */ + $updateClass : function(newClasses, oldClasses) { + this.$removeClass(tokenDifference(oldClasses, newClasses)); + this.$addClass(tokenDifference(newClasses, oldClasses)); + }, + + /** + * Set a normalized attribute on the element in a way such that all directives + * can share the attribute. This function properly handles boolean attributes. + * @param {string} key Normalized key. (ie ngAttribute) + * @param {string|boolean} value The value to set. If `null` attribute will be deleted. + * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute. + * Defaults to true. + * @param {string=} attrName Optional none normalized name. Defaults to key. + */ + $set: function(key, value, writeAttr, attrName) { + // TODO: decide whether or not to throw an error if "class" + //is set through this function since it may cause $updateClass to + //become unstable. + + var booleanKey = getBooleanAttrName(this.$$element[0], key), + normalizedVal, + nodeName; + + if (booleanKey) { + this.$$element.prop(key, value); + attrName = booleanKey; + } + + this[key] = value; + + // translate normalized key to actual key + if (attrName) { + this.$attr[key] = attrName; + } else { + attrName = this.$attr[key]; + if (!attrName) { + this.$attr[key] = attrName = snake_case(key, '-'); + } + } + + nodeName = nodeName_(this.$$element); + + // sanitize a[href] and img[src] values + if ((nodeName === 'A' && key === 'href') || + (nodeName === 'IMG' && key === 'src')) { + this[key] = value = $$sanitizeUri(value, key === 'src'); + } + + if (writeAttr !== false) { + if (value === null || value === undefined) { + this.$$element.removeAttr(attrName); + } else { + this.$$element.attr(attrName, value); + } + } + + // fire observers + var $$observers = this.$$observers; + $$observers && forEach($$observers[key], function(fn) { + try { + fn(value); + } catch (e) { + $exceptionHandler(e); + } + }); + }, + + + /** + * @ngdoc function + * @name ng.$compile.directive.Attributes#$observe + * @methodOf ng.$compile.directive.Attributes + * @function + * + * @description + * Observes an interpolated attribute. + * + * The observer function will be invoked once during the next `$digest` following + * compilation. The observer is then invoked whenever the interpolated value + * changes. + * + * @param {string} key Normalized key. (ie ngAttribute) . + * @param {function(interpolatedValue)} fn Function that will be called whenever + the interpolated value of the attribute changes. + * See the {@link guide/directive#Attributes Directives} guide for more info. + * @returns {function()} the `fn` parameter. + */ + $observe: function(key, fn) { + var attrs = this, + $$observers = (attrs.$$observers || (attrs.$$observers = {})), + listeners = ($$observers[key] || ($$observers[key] = [])); + + listeners.push(fn); + $rootScope.$evalAsync(function() { + if (!listeners.$$inter) { + // no one registered attribute interpolation function, so lets call it manually + fn(attrs[key]); + } + }); + return fn; + } + }; + + var startSymbol = $interpolate.startSymbol(), + endSymbol = $interpolate.endSymbol(), + denormalizeTemplate = (startSymbol == '{{' || endSymbol == '}}') + ? identity + : function denormalizeTemplate(template) { + return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol); + }, + NG_ATTR_BINDING = /^ngAttr[A-Z]/; + + + return compile; + + //================================ + + function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, + previousCompileContext) { + if (!($compileNodes instanceof jqLite)) { + // jquery always rewraps, whereas we need to preserve the original selector so that we can + // modify it. + $compileNodes = jqLite($compileNodes); + } + // We can not compile top level text elements since text nodes can be merged and we will + // not be able to attach scope data to them, so we will wrap them in + forEach($compileNodes, function(node, index){ + if (node.nodeType == 3 /* text node */ && node.nodeValue.match(/\S+/) /* non-empty */ ) { + $compileNodes[index] = node = jqLite(node).wrap('').parent()[0]; + } + }); + var compositeLinkFn = + compileNodes($compileNodes, transcludeFn, $compileNodes, + maxPriority, ignoreDirective, previousCompileContext); + return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){ + assertArg(scope, 'scope'); + // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart + // and sometimes changes the structure of the DOM. + var $linkNode = cloneConnectFn + ? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!! + : $compileNodes; + + forEach(transcludeControllers, function(instance, name) { + $linkNode.data('$' + name + 'Controller', instance); + }); + + // Attach scope only to non-text nodes. + for(var i = 0, ii = $linkNode.length; i + addDirective(directives, + directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority, ignoreDirective); + + // iterate over the attributes + for (var attr, name, nName, ngAttrName, value, nAttrs = node.attributes, + j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) { + var attrStartName = false; + var attrEndName = false; + + attr = nAttrs[j]; + if (!msie || msie >= 8 || attr.specified) { + name = attr.name; + // support ngAttr attribute binding + ngAttrName = directiveNormalize(name); + if (NG_ATTR_BINDING.test(ngAttrName)) { + name = snake_case(ngAttrName.substr(6), '-'); + } + + var directiveNName = ngAttrName.replace(/(Start|End)$/, ''); + if (ngAttrName === directiveNName + 'Start') { + attrStartName = name; + attrEndName = name.substr(0, name.length - 5) + 'end'; + name = name.substr(0, name.length - 6); + } + + nName = directiveNormalize(name.toLowerCase()); + attrsMap[nName] = name; + attrs[nName] = value = trim((msie && name == 'href') + ? decodeURIComponent(node.getAttribute(name, 2)) + : attr.value); + if (getBooleanAttrName(node, nName)) { + attrs[nName] = true; // presence means true + } + addAttrInterpolateDirective(node, directives, value, nName); + addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, + attrEndName); + } + } + + // use class as directive + className = node.className; + if (isString(className) && className !== '') { + while (match = CLASS_DIRECTIVE_REGEXP.exec(className)) { + nName = directiveNormalize(match[2]); + if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) { + attrs[nName] = trim(match[3]); + } + className = className.substr(match.index + match[0].length); + } + } + break; + case 3: /* Text Node */ + addTextInterpolateDirective(directives, node.nodeValue); + break; + case 8: /* Comment */ + try { + match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue); + if (match) { + nName = directiveNormalize(match[1]); + if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) { + attrs[nName] = trim(match[2]); + } + } + } catch (e) { + // turns out that under some circumstances IE9 throws errors when one attempts to read + // comment's node value. + // Just ignore it and continue. (Can't seem to reproduce in test case.) + } + break; + } + + directives.sort(byPriority); + return directives; + } + + /** + * Given a node with an directive-start it collects all of the siblings until it finds + * directive-end. + * @param node + * @param attrStart + * @param attrEnd + * @returns {*} + */ + function groupScan(node, attrStart, attrEnd) { + var nodes = []; + var depth = 0; + if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) { + var startNode = node; + do { + if (!node) { + throw $compileMinErr('uterdir', + "Unterminated attribute, found '{0}' but no matching '{1}' found.", + attrStart, attrEnd); + } + if (node.nodeType == 1 /** Element **/) { + if (node.hasAttribute(attrStart)) depth++; + if (node.hasAttribute(attrEnd)) depth--; + } + nodes.push(node); + node = node.nextSibling; + } while (depth > 0); + } else { + nodes.push(node); + } + + return jqLite(nodes); + } + + /** + * Wrapper for linking function which converts normal linking function into a grouped + * linking function. + * @param linkFn + * @param attrStart + * @param attrEnd + * @returns {Function} + */ + function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) { + return function(scope, element, attrs, controllers, transcludeFn) { + element = groupScan(element[0], attrStart, attrEnd); + return linkFn(scope, element, attrs, controllers, transcludeFn); + }; + } + + /** + * Once the directives have been collected, their compile functions are executed. This method + * is responsible for inlining directive templates as well as terminating the application + * of the directives if the terminal directive has been reached. + * + * @param {Array} directives Array of collected directives to execute their compile function. + * this needs to be pre-sorted by priority order. + * @param {Node} compileNode The raw DOM node to apply the compile functions to + * @param {Object} templateAttrs The shared attribute function + * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the + * scope argument is auto-generated to the new + * child of the transcluded parent scope. + * @param {JQLite} jqCollection If we are working on the root of the compile tree then this + * argument has the root jqLite array so that we can replace nodes + * on it. + * @param {Object=} originalReplaceDirective An optional directive that will be ignored when + * compiling the transclusion. + * @param {Array.} preLinkFns + * @param {Array.} postLinkFns + * @param {Object} previousCompileContext Context used for previous compilation of the current + * node + * @returns linkFn + */ + function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, + jqCollection, originalReplaceDirective, preLinkFns, postLinkFns, + previousCompileContext) { + previousCompileContext = previousCompileContext || {}; + + var terminalPriority = -Number.MAX_VALUE, + newScopeDirective, + controllerDirectives = previousCompileContext.controllerDirectives, + newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective, + templateDirective = previousCompileContext.templateDirective, + nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective, + hasTranscludeDirective = false, + hasElementTranscludeDirective = false, + $compileNode = templateAttrs.$$element = jqLite(compileNode), + directive, + directiveName, + $template, + replaceDirective = originalReplaceDirective, + childTranscludeFn = transcludeFn, + linkFn, + directiveValue; + + // executes all directives on the current element + for(var i = 0, ii = directives.length; i < ii; i++) { + directive = directives[i]; + var attrStart = directive.$$start; + var attrEnd = directive.$$end; + + // collect multiblock sections + if (attrStart) { + $compileNode = groupScan(compileNode, attrStart, attrEnd); + } + $template = undefined; + + if (terminalPriority > directive.priority) { + break; // prevent further processing of directives + } + + if (directiveValue = directive.scope) { + newScopeDirective = newScopeDirective || directive; + + // skip the check for directives with async templates, we'll check the derived sync + // directive when the template arrives + if (!directive.templateUrl) { + assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive, + $compileNode); + if (isObject(directiveValue)) { + newIsolateScopeDirective = directive; + } + } + } + + directiveName = directive.name; + + if (!directive.templateUrl && directive.controller) { + directiveValue = directive.controller; + controllerDirectives = controllerDirectives || {}; + assertNoDuplicate("'" + directiveName + "' controller", + controllerDirectives[directiveName], directive, $compileNode); + controllerDirectives[directiveName] = directive; + } + + if (directiveValue = directive.transclude) { + hasTranscludeDirective = true; + + // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion. + // This option should only be used by directives that know how to how to safely handle element transclusion, + // where the transcluded nodes are added or replaced after linking. + if (!directive.$$tlb) { + assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode); + nonTlbTranscludeDirective = directive; + } + + if (directiveValue == 'element') { + hasElementTranscludeDirective = true; + terminalPriority = directive.priority; + $template = groupScan(compileNode, attrStart, attrEnd); + $compileNode = templateAttrs.$$element = + jqLite(document.createComment(' ' + directiveName + ': ' + + templateAttrs[directiveName] + ' ')); + compileNode = $compileNode[0]; + replaceWith(jqCollection, jqLite(sliceArgs($template)), compileNode); + + childTranscludeFn = compile($template, transcludeFn, terminalPriority, + replaceDirective && replaceDirective.name, { + // Don't pass in: + // - controllerDirectives - otherwise we'll create duplicates controllers + // - newIsolateScopeDirective or templateDirective - combining templates with + // element transclusion doesn't make sense. + // + // We need only nonTlbTranscludeDirective so that we prevent putting transclusion + // on the same element more than once. + nonTlbTranscludeDirective: nonTlbTranscludeDirective + }); + } else { + $template = jqLite(jqLiteClone(compileNode)).contents(); + $compileNode.html(''); // clear contents + childTranscludeFn = compile($template, transcludeFn); + } + } + + if (directive.template) { + assertNoDuplicate('template', templateDirective, directive, $compileNode); + templateDirective = directive; + + directiveValue = (isFunction(directive.template)) + ? directive.template($compileNode, templateAttrs) + : directive.template; + + directiveValue = denormalizeTemplate(directiveValue); + + if (directive.replace) { + replaceDirective = directive; + $template = jqLite('
' + + trim(directiveValue) + + '
').contents(); + compileNode = $template[0]; + + if ($template.length != 1 || compileNode.nodeType !== 1) { + throw $compileMinErr('tplrt', + "Template for directive '{0}' must have exactly one root element. {1}", + directiveName, ''); + } + + replaceWith(jqCollection, $compileNode, compileNode); + + var newTemplateAttrs = {$attr: {}}; + + // combine directives from the original node and from the template: + // - take the array of directives for this element + // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed) + // - collect directives from the template and sort them by priority + // - combine directives as: processed + template + unprocessed + var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs); + var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1)); + + if (newIsolateScopeDirective) { + markDirectivesAsIsolate(templateDirectives); + } + directives = directives.concat(templateDirectives).concat(unprocessedDirectives); + mergeTemplateAttributes(templateAttrs, newTemplateAttrs); + + ii = directives.length; + } else { + $compileNode.html(directiveValue); + } + } + + if (directive.templateUrl) { + assertNoDuplicate('template', templateDirective, directive, $compileNode); + templateDirective = directive; + + if (directive.replace) { + replaceDirective = directive; + } + + nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, + templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, { + controllerDirectives: controllerDirectives, + newIsolateScopeDirective: newIsolateScopeDirective, + templateDirective: templateDirective, + nonTlbTranscludeDirective: nonTlbTranscludeDirective + }); + ii = directives.length; + } else if (directive.compile) { + try { + linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn); + if (isFunction(linkFn)) { + addLinkFns(null, linkFn, attrStart, attrEnd); + } else if (linkFn) { + addLinkFns(linkFn.pre, linkFn.post, attrStart, attrEnd); + } + } catch (e) { + $exceptionHandler(e, startingTag($compileNode)); + } + } + + if (directive.terminal) { + nodeLinkFn.terminal = true; + terminalPriority = Math.max(terminalPriority, directive.priority); + } + + } + + nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true; + nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn; + + // might be normal or delayed nodeLinkFn depending on if templateUrl is present + return nodeLinkFn; + + //////////////////// + + function addLinkFns(pre, post, attrStart, attrEnd) { + if (pre) { + if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd); + pre.require = directive.require; + if (newIsolateScopeDirective === directive || directive.$$isolateScope) { + pre = cloneAndAnnotateFn(pre, {isolateScope: true}); + } + preLinkFns.push(pre); + } + if (post) { + if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd); + post.require = directive.require; + if (newIsolateScopeDirective === directive || directive.$$isolateScope) { + post = cloneAndAnnotateFn(post, {isolateScope: true}); + } + postLinkFns.push(post); + } + } + + + function getControllers(require, $element, elementControllers) { + var value, retrievalMethod = 'data', optional = false; + if (isString(require)) { + while((value = require.charAt(0)) == '^' || value == '?') { + require = require.substr(1); + if (value == '^') { + retrievalMethod = 'inheritedData'; + } + optional = optional || value == '?'; + } + value = null; + + if (elementControllers && retrievalMethod === 'data') { + value = elementControllers[require]; + } + value = value || $element[retrievalMethod]('$' + require + 'Controller'); + + if (!value && !optional) { + throw $compileMinErr('ctreq', + "Controller '{0}', required by directive '{1}', can't be found!", + require, directiveName); + } + return value; + } else if (isArray(require)) { + value = []; + forEach(require, function(require) { + value.push(getControllers(require, $element, elementControllers)); + }); + } + return value; + } + + + function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) { + var attrs, $element, i, ii, linkFn, controller, isolateScope, elementControllers = {}, transcludeFn; + + if (compileNode === linkNode) { + attrs = templateAttrs; + } else { + attrs = shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr)); + } + $element = attrs.$$element; + + if (newIsolateScopeDirective) { + var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/; + var $linkNode = jqLite(linkNode); + + isolateScope = scope.$new(true); + + if (templateDirective && (templateDirective === newIsolateScopeDirective.$$originalDirective)) { + $linkNode.data('$isolateScope', isolateScope) ; + } else { + $linkNode.data('$isolateScopeNoTemplate', isolateScope); + } + + + + safeAddClass($linkNode, 'ng-isolate-scope'); + + forEach(newIsolateScopeDirective.scope, function(definition, scopeName) { + var match = definition.match(LOCAL_REGEXP) || [], + attrName = match[3] || scopeName, + optional = (match[2] == '?'), + mode = match[1], // @, =, or & + lastValue, + parentGet, parentSet; + + isolateScope.$$isolateBindings[scopeName] = mode + attrName; + + switch (mode) { + + case '@': + attrs.$observe(attrName, function(value) { + isolateScope[scopeName] = value; + }); + attrs.$$observers[attrName].$$scope = scope; + if( attrs[attrName] ) { + // If the attribute has been provided then we trigger an interpolation to ensure + // the value is there for use in the link fn + isolateScope[scopeName] = $interpolate(attrs[attrName])(scope); + } + break; + + case '=': + if (optional && !attrs[attrName]) { + return; + } + parentGet = $parse(attrs[attrName]); + parentSet = parentGet.assign || function() { + // reset the change, or we will throw this exception on every $digest + lastValue = isolateScope[scopeName] = parentGet(scope); + throw $compileMinErr('nonassign', + "Expression '{0}' used with directive '{1}' is non-assignable!", + attrs[attrName], newIsolateScopeDirective.name); + }; + lastValue = isolateScope[scopeName] = parentGet(scope); + isolateScope.$watch(function parentValueWatch() { + var parentValue = parentGet(scope); + + if (parentValue !== isolateScope[scopeName]) { + // we are out of sync and need to copy + if (parentValue !== lastValue) { + // parent changed and it has precedence + lastValue = isolateScope[scopeName] = parentValue; + } else { + // if the parent can be assigned then do so + parentSet(scope, parentValue = lastValue = isolateScope[scopeName]); + } + } + return parentValue; + }); + break; + + case '&': + parentGet = $parse(attrs[attrName]); + isolateScope[scopeName] = function(locals) { + return parentGet(scope, locals); + }; + break; + + default: + throw $compileMinErr('iscp', + "Invalid isolate scope definition for directive '{0}'." + + " Definition: {... {1}: '{2}' ...}", + newIsolateScopeDirective.name, scopeName, definition); + } + }); + } + transcludeFn = boundTranscludeFn && controllersBoundTransclude; + if (controllerDirectives) { + forEach(controllerDirectives, function(directive) { + var locals = { + $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope, + $element: $element, + $attrs: attrs, + $transclude: transcludeFn + }, controllerInstance; + + controller = directive.controller; + if (controller == '@') { + controller = attrs[directive.name]; + } + + controllerInstance = $controller(controller, locals); + // For directives with element transclusion the element is a comment, + // but jQuery .data doesn't support attaching data to comment nodes as it's hard to + // clean up (http://bugs.jquery.com/ticket/8335). + // Instead, we save the controllers for the element in a local hash and attach to .data + // later, once we have the actual element. + elementControllers[directive.name] = controllerInstance; + if (!hasElementTranscludeDirective) { + $element.data('$' + directive.name + 'Controller', controllerInstance); + } + + if (directive.controllerAs) { + locals.$scope[directive.controllerAs] = controllerInstance; + } + }); + } + + // PRELINKING + for(i = 0, ii = preLinkFns.length; i < ii; i++) { + try { + linkFn = preLinkFns[i]; + linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, + linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn); + } catch (e) { + $exceptionHandler(e, startingTag($element)); + } + } + + // RECURSION + // We only pass the isolate scope, if the isolate directive has a template, + // otherwise the child elements do not belong to the isolate directive. + var scopeToChild = scope; + if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) { + scopeToChild = isolateScope; + } + childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn); + + // POSTLINKING + for(i = postLinkFns.length - 1; i >= 0; i--) { + try { + linkFn = postLinkFns[i]; + linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, + linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn); + } catch (e) { + $exceptionHandler(e, startingTag($element)); + } + } + + // This is the function that is injected as `$transclude`. + function controllersBoundTransclude(scope, cloneAttachFn) { + var transcludeControllers; + + // no scope passed + if (arguments.length < 2) { + cloneAttachFn = scope; + scope = undefined; + } + + if (hasElementTranscludeDirective) { + transcludeControllers = elementControllers; + } + + return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers); + } + } + } + + function markDirectivesAsIsolate(directives) { + // mark all directives as needing isolate scope. + for (var j = 0, jj = directives.length; j < jj; j++) { + directives[j] = inherit(directives[j], {$$isolateScope: true}); + } + } + + /** + * looks up the directive and decorates it with exception handling and proper parameters. We + * call this the boundDirective. + * + * @param {string} name name of the directive to look up. + * @param {string} location The directive must be found in specific format. + * String containing any of theses characters: + * + * * `E`: element name + * * `A': attribute + * * `C`: class + * * `M`: comment + * @returns true if directive was added. + */ + function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName, + endAttrName) { + if (name === ignoreDirective) return null; + var match = null; + if (hasDirectives.hasOwnProperty(name)) { + for(var directive, directives = $injector.get(name + Suffix), + i = 0, ii = directives.length; i directive.priority) && + directive.restrict.indexOf(location) != -1) { + if (startAttrName) { + directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName}); + } + tDirectives.push(directive); + match = directive; + } + } catch(e) { $exceptionHandler(e); } + } + } + return match; + } + + + /** + * When the element is replaced with HTML template then the new attributes + * on the template need to be merged with the existing attributes in the DOM. + * The desired effect is to have both of the attributes present. + * + * @param {object} dst destination attributes (original DOM) + * @param {object} src source attributes (from the directive template) + */ + function mergeTemplateAttributes(dst, src) { + var srcAttr = src.$attr, + dstAttr = dst.$attr, + $element = dst.$$element; + + // reapply the old attributes to the new element + forEach(dst, function(value, key) { + if (key.charAt(0) != '$') { + if (src[key]) { + value += (key === 'style' ? ';' : ' ') + src[key]; + } + dst.$set(key, value, true, srcAttr[key]); + } + }); + + // copy the new attributes on the old attrs object + forEach(src, function(value, key) { + if (key == 'class') { + safeAddClass($element, value); + dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value; + } else if (key == 'style') { + $element.attr('style', $element.attr('style') + ';' + value); + dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value; + // `dst` will never contain hasOwnProperty as DOM parser won't let it. + // You will get an "InvalidCharacterError: DOM Exception 5" error if you + // have an attribute like "has-own-property" or "data-has-own-property", etc. + } else if (key.charAt(0) != '$' && !dst.hasOwnProperty(key)) { + dst[key] = value; + dstAttr[key] = srcAttr[key]; + } + }); + } + + + function compileTemplateUrl(directives, $compileNode, tAttrs, + $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) { + var linkQueue = [], + afterTemplateNodeLinkFn, + afterTemplateChildLinkFn, + beforeTemplateCompileNode = $compileNode[0], + origAsyncDirective = directives.shift(), + // The fact that we have to copy and patch the directive seems wrong! + derivedSyncDirective = extend({}, origAsyncDirective, { + templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective + }), + templateUrl = (isFunction(origAsyncDirective.templateUrl)) + ? origAsyncDirective.templateUrl($compileNode, tAttrs) + : origAsyncDirective.templateUrl; + + $compileNode.html(''); + + $http.get($sce.getTrustedResourceUrl(templateUrl), {cache: $templateCache}). + success(function(content) { + var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn; + + content = denormalizeTemplate(content); + + if (origAsyncDirective.replace) { + $template = jqLite('
' + trim(content) + '
').contents(); + compileNode = $template[0]; + + if ($template.length != 1 || compileNode.nodeType !== 1) { + throw $compileMinErr('tplrt', + "Template for directive '{0}' must have exactly one root element. {1}", + origAsyncDirective.name, templateUrl); + } + + tempTemplateAttrs = {$attr: {}}; + replaceWith($rootElement, $compileNode, compileNode); + var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs); + + if (isObject(origAsyncDirective.scope)) { + markDirectivesAsIsolate(templateDirectives); + } + directives = templateDirectives.concat(directives); + mergeTemplateAttributes(tAttrs, tempTemplateAttrs); + } else { + compileNode = beforeTemplateCompileNode; + $compileNode.html(content); + } + + directives.unshift(derivedSyncDirective); + + afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, + childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns, + previousCompileContext); + forEach($rootElement, function(node, i) { + if (node == compileNode) { + $rootElement[i] = $compileNode[0]; + } + }); + afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn); + + + while(linkQueue.length) { + var scope = linkQueue.shift(), + beforeTemplateLinkNode = linkQueue.shift(), + linkRootElement = linkQueue.shift(), + boundTranscludeFn = linkQueue.shift(), + linkNode = $compileNode[0]; + + if (beforeTemplateLinkNode !== beforeTemplateCompileNode) { + // it was cloned therefore we have to clone as well. + linkNode = jqLiteClone(compileNode); + replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode); + } + if (afterTemplateNodeLinkFn.transclude) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude); + } else { + childBoundTranscludeFn = boundTranscludeFn; + } + afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, + childBoundTranscludeFn); + } + linkQueue = null; + }). + error(function(response, code, headers, config) { + throw $compileMinErr('tpload', 'Failed to load template: {0}', config.url); + }); + + return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) { + if (linkQueue) { + linkQueue.push(scope); + linkQueue.push(node); + linkQueue.push(rootElement); + linkQueue.push(boundTranscludeFn); + } else { + afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, boundTranscludeFn); + } + }; + } + + + /** + * Sorting function for bound directives. + */ + function byPriority(a, b) { + var diff = b.priority - a.priority; + if (diff !== 0) return diff; + if (a.name !== b.name) return (a.name < b.name) ? -1 : 1; + return a.index - b.index; + } + + + function assertNoDuplicate(what, previousDirective, directive, element) { + if (previousDirective) { + throw $compileMinErr('multidir', 'Multiple directives [{0}, {1}] asking for {2} on: {3}', + previousDirective.name, directive.name, what, startingTag(element)); + } + } + + + function addTextInterpolateDirective(directives, text) { + var interpolateFn = $interpolate(text, true); + if (interpolateFn) { + directives.push({ + priority: 0, + compile: valueFn(function textInterpolateLinkFn(scope, node) { + var parent = node.parent(), + bindings = parent.data('$binding') || []; + bindings.push(interpolateFn); + safeAddClass(parent.data('$binding', bindings), 'ng-binding'); + scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { + node[0].nodeValue = value; + }); + }) + }); + } + } + + + function getTrustedContext(node, attrNormalizedName) { + if (attrNormalizedName == "srcdoc") { + return $sce.HTML; + } + var tag = nodeName_(node); + // maction[xlink:href] can source SVG. It's not limited to . + if (attrNormalizedName == "xlinkHref" || + (tag == "FORM" && attrNormalizedName == "action") || + (tag != "IMG" && (attrNormalizedName == "src" || + attrNormalizedName == "ngSrc"))) { + return $sce.RESOURCE_URL; + } + } + + + function addAttrInterpolateDirective(node, directives, value, name) { + var interpolateFn = $interpolate(value, true); + + // no interpolation found -> ignore + if (!interpolateFn) return; + + + if (name === "multiple" && nodeName_(node) === "SELECT") { + throw $compileMinErr("selmulti", + "Binding to the 'multiple' attribute is not supported. Element: {0}", + startingTag(node)); + } + + directives.push({ + priority: 100, + compile: function() { + return { + pre: function attrInterpolatePreLinkFn(scope, element, attr) { + var $$observers = (attr.$$observers || (attr.$$observers = {})); + + if (EVENT_HANDLER_ATTR_REGEXP.test(name)) { + throw $compileMinErr('nodomevents', + "Interpolations for HTML DOM event attributes are disallowed. Please use the " + + "ng- versions (such as ng-click instead of onclick) instead."); + } + + // we need to interpolate again, in case the attribute value has been updated + // (e.g. by another directive's compile function) + interpolateFn = $interpolate(attr[name], true, getTrustedContext(node, name)); + + // if attribute was updated so that there is no interpolation going on we don't want to + // register any observers + if (!interpolateFn) return; + + // TODO(i): this should likely be attr.$set(name, iterpolateFn(scope) so that we reset the + // actual attr value + attr[name] = interpolateFn(scope); + ($$observers[name] || ($$observers[name] = [])).$$inter = true; + (attr.$$observers && attr.$$observers[name].$$scope || scope). + $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) { + //special case for class attribute addition + removal + //so that class changes can tap into the animation + //hooks provided by the $animate service. Be sure to + //skip animations when the first digest occurs (when + //both the new and the old values are the same) since + //the CSS classes are the non-interpolated values + if(name === 'class' && newValue != oldValue) { + attr.$updateClass(newValue, oldValue); + } else { + attr.$set(name, newValue); + } + }); + } + }; + } + }); + } + + + /** + * This is a special jqLite.replaceWith, which can replace items which + * have no parents, provided that the containing jqLite collection is provided. + * + * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes + * in the root of the tree. + * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep + * the shell, but replace its DOM node reference. + * @param {Node} newNode The new DOM node. + */ + function replaceWith($rootElement, elementsToRemove, newNode) { + var firstElementToRemove = elementsToRemove[0], + removeCount = elementsToRemove.length, + parent = firstElementToRemove.parentNode, + i, ii; + + if ($rootElement) { + for(i = 0, ii = $rootElement.length; i < ii; i++) { + if ($rootElement[i] == firstElementToRemove) { + $rootElement[i++] = newNode; + for (var j = i, j2 = j + removeCount - 1, + jj = $rootElement.length; + j < jj; j++, j2++) { + if (j2 < jj) { + $rootElement[j] = $rootElement[j2]; + } else { + delete $rootElement[j]; + } + } + $rootElement.length -= removeCount - 1; + break; + } + } + } + + if (parent) { + parent.replaceChild(newNode, firstElementToRemove); + } + var fragment = document.createDocumentFragment(); + fragment.appendChild(firstElementToRemove); + newNode[jqLite.expando] = firstElementToRemove[jqLite.expando]; + for (var k = 1, kk = elementsToRemove.length; k < kk; k++) { + var element = elementsToRemove[k]; + jqLite(element).remove(); // must do this way to clean up expando + fragment.appendChild(element); + delete elementsToRemove[k]; + } + + elementsToRemove[0] = newNode; + elementsToRemove.length = 1; + } + + + function cloneAndAnnotateFn(fn, annotation) { + return extend(function() { return fn.apply(null, arguments); }, fn, annotation); + } + }]; +} + +var PREFIX_REGEXP = /^(x[\:\-_]|data[\:\-_])/i; +/** + * Converts all accepted directives format into proper directive name. + * All of these will become 'myDirective': + * my:Directive + * my-directive + * x-my-directive + * data-my:directive + * + * Also there is special case for Moz prefix starting with upper case letter. + * @param name Name to normalize + */ +function directiveNormalize(name) { + return camelCase(name.replace(PREFIX_REGEXP, '')); +} + +/** + * @ngdoc object + * @name ng.$compile.directive.Attributes + * + * @description + * A shared object between directive compile / linking functions which contains normalized DOM + * element attributes. The values reflect current binding state `{{ }}`. The normalization is + * needed since all of these are treated as equivalent in Angular: + * + * + */ + +/** + * @ngdoc property + * @name ng.$compile.directive.Attributes#$attr + * @propertyOf ng.$compile.directive.Attributes + * @returns {object} A map of DOM element attribute names to the normalized name. This is + * needed to do reverse lookup from normalized name back to actual name. + */ + + +/** + * @ngdoc function + * @name ng.$compile.directive.Attributes#$set + * @methodOf ng.$compile.directive.Attributes + * @function + * + * @description + * Set DOM element attribute value. + * + * + * @param {string} name Normalized element attribute name of the property to modify. The name is + * revers translated using the {@link ng.$compile.directive.Attributes#$attr $attr} + * property to the original name. + * @param {string} value Value to set the attribute to. The value can be an interpolated string. + */ + + + +/** + * Closure compiler type information + */ + +function nodesetLinkingFn( + /* angular.Scope */ scope, + /* NodeList */ nodeList, + /* Element */ rootElement, + /* function(Function) */ boundTranscludeFn +){} + +function directiveLinkingFn( + /* nodesetLinkingFn */ nodesetLinkingFn, + /* angular.Scope */ scope, + /* Node */ node, + /* Element */ rootElement, + /* function(Function) */ boundTranscludeFn +){} + +function tokenDifference(str1, str2) { + var values = '', + tokens1 = str1.split(/\s+/), + tokens2 = str2.split(/\s+/); + + outer: + for(var i = 0; i < tokens1.length; i++) { + var token = tokens1[i]; + for(var j = 0; j < tokens2.length; j++) { + if(token == tokens2[j]) continue outer; + } + values += (values.length > 0 ? ' ' : '') + token; + } + return values; +} + +/** + * @ngdoc object + * @name ng.$controllerProvider + * @description + * The {@link ng.$controller $controller service} is used by Angular to create new + * controllers. + * + * This provider allows controller registration via the + * {@link ng.$controllerProvider#methods_register register} method. + */ +function $ControllerProvider() { + var controllers = {}, + CNTRL_REG = /^(\S+)(\s+as\s+(\w+))?$/; + + + /** + * @ngdoc function + * @name ng.$controllerProvider#register + * @methodOf ng.$controllerProvider + * @param {string|Object} name Controller name, or an object map of controllers where the keys are + * the names and the values are the constructors. + * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI + * annotations in the array notation). + */ + this.register = function(name, constructor) { + assertNotHasOwnProperty(name, 'controller'); + if (isObject(name)) { + extend(controllers, name); + } else { + controllers[name] = constructor; + } + }; + + + this.$get = ['$injector', '$window', function($injector, $window) { + + /** + * @ngdoc function + * @name ng.$controller + * @requires $injector + * + * @param {Function|string} constructor If called with a function then it's considered to be the + * controller constructor function. Otherwise it's considered to be a string which is used + * to retrieve the controller constructor using the following steps: + * + * * check if a controller with given name is registered via `$controllerProvider` + * * check if evaluating the string on the current scope returns a constructor + * * check `window[constructor]` on the global `window` object + * + * @param {Object} locals Injection locals for Controller. + * @return {Object} Instance of given controller. + * + * @description + * `$controller` service is responsible for instantiating controllers. + * + * It's just a simple call to {@link AUTO.$injector $injector}, but extracted into + * a service, so that one can override this service with {@link https://gist.github.com/1649788 + * BC version}. + */ + return function(expression, locals) { + var instance, match, constructor, identifier; + + if(isString(expression)) { + match = expression.match(CNTRL_REG), + constructor = match[1], + identifier = match[3]; + expression = controllers.hasOwnProperty(constructor) + ? controllers[constructor] + : getter(locals.$scope, constructor, true) || getter($window, constructor, true); + + assertArgFn(expression, constructor, true); + } + + instance = $injector.instantiate(expression, locals); + + if (identifier) { + if (!(locals && typeof locals.$scope == 'object')) { + throw minErr('$controller')('noscp', + "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", + constructor || expression.name, identifier); + } + + locals.$scope[identifier] = instance; + } + + return instance; + }; + }]; +} + +/** + * @ngdoc object + * @name ng.$document + * @requires $window + * + * @description + * A {@link angular.element jQuery (lite)}-wrapped reference to the browser's `window.document` + * element. + */ +function $DocumentProvider(){ + this.$get = ['$window', function(window){ + return jqLite(window.document); + }]; +} + +/** + * @ngdoc function + * @name ng.$exceptionHandler + * @requires $log + * + * @description + * Any uncaught exception in angular expressions is delegated to this service. + * The default implementation simply delegates to `$log.error` which logs it into + * the browser console. + * + * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by + * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing. + * + * ## Example: + * + *
+ *   angular.module('exceptionOverride', []).factory('$exceptionHandler', function () {
+ *     return function (exception, cause) {
+ *       exception.message += ' (caused by "' + cause + '")';
+ *       throw exception;
+ *     };
+ *   });
+ * 
+ * + * This example will override the normal action of `$exceptionHandler`, to make angular + * exceptions fail hard when they happen, instead of just logging to the console. + * + * @param {Error} exception Exception associated with the error. + * @param {string=} cause optional information about the context in which + * the error was thrown. + * + */ +function $ExceptionHandlerProvider() { + this.$get = ['$log', function($log) { + return function(exception, cause) { + $log.error.apply($log, arguments); + }; + }]; +} + +/** + * Parse headers into key value object + * + * @param {string} headers Raw headers as a string + * @returns {Object} Parsed headers as key value object + */ +function parseHeaders(headers) { + var parsed = {}, key, val, i; + + if (!headers) return parsed; + + forEach(headers.split('\n'), function(line) { + i = line.indexOf(':'); + key = lowercase(trim(line.substr(0, i))); + val = trim(line.substr(i + 1)); + + if (key) { + if (parsed[key]) { + parsed[key] += ', ' + val; + } else { + parsed[key] = val; + } + } + }); + + return parsed; +} + + +/** + * Returns a function that provides access to parsed headers. + * + * Headers are lazy parsed when first requested. + * @see parseHeaders + * + * @param {(string|Object)} headers Headers to provide access to. + * @returns {function(string=)} Returns a getter function which if called with: + * + * - if called with single an argument returns a single header value or null + * - if called with no arguments returns an object containing all headers. + */ +function headersGetter(headers) { + var headersObj = isObject(headers) ? headers : undefined; + + return function(name) { + if (!headersObj) headersObj = parseHeaders(headers); + + if (name) { + return headersObj[lowercase(name)] || null; + } + + return headersObj; + }; +} + + +/** + * Chain all given functions + * + * This function is used for both request and response transforming + * + * @param {*} data Data to transform. + * @param {function(string=)} headers Http headers getter fn. + * @param {(function|Array.)} fns Function or an array of functions. + * @returns {*} Transformed data. + */ +function transformData(data, headers, fns) { + if (isFunction(fns)) + return fns(data, headers); + + forEach(fns, function(fn) { + data = fn(data, headers); + }); + + return data; +} + + +function isSuccess(status) { + return 200 <= status && status < 300; +} + + +function $HttpProvider() { + var JSON_START = /^\s*(\[|\{[^\{])/, + JSON_END = /[\}\]]\s*$/, + PROTECTION_PREFIX = /^\)\]\}',?\n/, + CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'}; + + var defaults = this.defaults = { + // transform incoming response data + transformResponse: [function(data) { + if (isString(data)) { + // strip json vulnerability protection prefix + data = data.replace(PROTECTION_PREFIX, ''); + if (JSON_START.test(data) && JSON_END.test(data)) + data = fromJson(data); + } + return data; + }], + + // transform outgoing request data + transformRequest: [function(d) { + return isObject(d) && !isFile(d) ? toJson(d) : d; + }], + + // default headers + headers: { + common: { + 'Accept': 'application/json, text/plain, */*' + }, + post: CONTENT_TYPE_APPLICATION_JSON, + put: CONTENT_TYPE_APPLICATION_JSON, + patch: CONTENT_TYPE_APPLICATION_JSON + }, + + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN' + }; + + /** + * Are ordered by request, i.e. they are applied in the same order as the + * array, on request, but reverse order, on response. + */ + var interceptorFactories = this.interceptors = []; + + /** + * For historical reasons, response interceptors are ordered by the order in which + * they are applied to the response. (This is the opposite of interceptorFactories) + */ + var responseInterceptorFactories = this.responseInterceptors = []; + + this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector', + function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) { + + var defaultCache = $cacheFactory('$http'); + + /** + * Interceptors stored in reverse order. Inner interceptors before outer interceptors. + * The reversal is needed so that we can build up the interception chain around the + * server request. + */ + var reversedInterceptors = []; + + forEach(interceptorFactories, function(interceptorFactory) { + reversedInterceptors.unshift(isString(interceptorFactory) + ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory)); + }); + + forEach(responseInterceptorFactories, function(interceptorFactory, index) { + var responseFn = isString(interceptorFactory) + ? $injector.get(interceptorFactory) + : $injector.invoke(interceptorFactory); + + /** + * Response interceptors go before "around" interceptors (no real reason, just + * had to pick one.) But they are already reversed, so we can't use unshift, hence + * the splice. + */ + reversedInterceptors.splice(index, 0, { + response: function(response) { + return responseFn($q.when(response)); + }, + responseError: function(response) { + return responseFn($q.reject(response)); + } + }); + }); + + + /** + * @ngdoc function + * @name ng.$http + * @requires $httpBackend + * @requires $browser + * @requires $cacheFactory + * @requires $rootScope + * @requires $q + * @requires $injector + * + * @description + * The `$http` service is a core Angular service that facilitates communication with the remote + * HTTP servers via the browser's {@link https://developer.mozilla.org/en/xmlhttprequest + * XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}. + * + * For unit testing applications that use `$http` service, see + * {@link ngMock.$httpBackend $httpBackend mock}. + * + * For a higher level of abstraction, please check out the {@link ngResource.$resource + * $resource} service. + * + * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by + * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage + * it is important to familiarize yourself with these APIs and the guarantees they provide. + * + * + * # General usage + * The `$http` service is a function which takes a single argument — a configuration object — + * that is used to generate an HTTP request and returns a {@link ng.$q promise} + * with two $http specific methods: `success` and `error`. + * + *
+     *   $http({method: 'GET', url: '/someUrl'}).
+     *     success(function(data, status, headers, config) {
+     *       // this callback will be called asynchronously
+     *       // when the response is available
+     *     }).
+     *     error(function(data, status, headers, config) {
+     *       // called asynchronously if an error occurs
+     *       // or server returns response with an error status.
+     *     });
+     * 
+ * + * Since the returned value of calling the $http function is a `promise`, you can also use + * the `then` method to register callbacks, and these callbacks will receive a single argument – + * an object representing the response. See the API signature and type info below for more + * details. + * + * A response status code between 200 and 299 is considered a success status and + * will result in the success callback being called. Note that if the response is a redirect, + * XMLHttpRequest will transparently follow it, meaning that the error callback will not be + * called for such responses. + * + * # Calling $http from outside AngularJS + * The `$http` service will not actually send the request until the next `$digest()` is + * executed. Normally this is not an issue, since almost all the time your call to `$http` will + * be from within a `$apply()` block. + * If you are calling `$http` from outside Angular, then you should wrap it in a call to + * `$apply` to cause a $digest to occur and also to handle errors in the block correctly. + * + * ``` + * $scope.$apply(function() { + * $http(...); + * }); + * ``` + * + * # Writing Unit Tests that use $http + * When unit testing you are mostly responsible for scheduling the `$digest` cycle. If you do + * not trigger a `$digest` before calling `$httpBackend.flush()` then the request will not have + * been made and `$httpBackend.expect(...)` expectations will fail. The solution is to run the + * code that calls the `$http()` method inside a $apply block as explained in the previous + * section. + * + * ``` + * $httpBackend.expectGET(...); + * $scope.$apply(function() { + * $http.get(...); + * }); + * $httpBackend.flush(); + * ``` + * + * # Shortcut methods + * + * Since all invocations of the $http service require passing in an HTTP method and URL, and + * POST/PUT requests require request data to be provided as well, shortcut methods + * were created: + * + *
+     *   $http.get('/someUrl').success(successCallback);
+     *   $http.post('/someUrl', data).success(successCallback);
+     * 
+ * + * Complete list of shortcut methods: + * + * - {@link ng.$http#methods_get $http.get} + * - {@link ng.$http#methods_head $http.head} + * - {@link ng.$http#methods_post $http.post} + * - {@link ng.$http#methods_put $http.put} + * - {@link ng.$http#methods_delete $http.delete} + * - {@link ng.$http#methods_jsonp $http.jsonp} + * + * + * # Setting HTTP Headers + * + * The $http service will automatically add certain HTTP headers to all requests. These defaults + * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration + * object, which currently contains this default configuration: + * + * - `$httpProvider.defaults.headers.common` (headers that are common for all requests): + * - `Accept: application/json, text/plain, * / *` + * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests) + * - `Content-Type: application/json` + * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests) + * - `Content-Type: application/json` + * + * To add or overwrite these defaults, simply add or remove a property from these configuration + * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object + * with the lowercased HTTP method name as the key, e.g. + * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }. + * + * The defaults can also be set at runtime via the `$http.defaults` object in the same + * fashion. In addition, you can supply a `headers` property in the config object passed when + * calling `$http(config)`, which overrides the defaults without changing them globally. + * + * + * # Transforming Requests and Responses + * + * Both requests and responses can be transformed using transform functions. By default, Angular + * applies these transformations: + * + * Request transformations: + * + * - If the `data` property of the request configuration object contains an object, serialize it + * into JSON format. + * + * Response transformations: + * + * - If XSRF prefix is detected, strip it (see Security Considerations section below). + * - If JSON response is detected, deserialize it using a JSON parser. + * + * To globally augment or override the default transforms, modify the + * `$httpProvider.defaults.transformRequest` and `$httpProvider.defaults.transformResponse` + * properties. These properties are by default an array of transform functions, which allows you + * to `push` or `unshift` a new transformation function into the transformation chain. You can + * also decide to completely override any default transformations by assigning your + * transformation functions to these properties directly without the array wrapper. + * + * Similarly, to locally override the request/response transforms, augment the + * `transformRequest` and/or `transformResponse` properties of the configuration object passed + * into `$http`. + * + * + * # Caching + * + * To enable caching, set the request configuration `cache` property to `true` (to use default + * cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}). + * When the cache is enabled, `$http` stores the response from the server in the specified + * cache. The next time the same request is made, the response is served from the cache without + * sending a request to the server. + * + * Note that even if the response is served from cache, delivery of the data is asynchronous in + * the same way that real requests are. + * + * If there are multiple GET requests for the same URL that should be cached using the same + * cache, but the cache is not populated yet, only one request to the server will be made and + * the remaining requests will be fulfilled using the response from the first request. + * + * You can change the default cache to a new object (built with + * {@link ng.$cacheFactory `$cacheFactory`}) by updating the + * {@link ng.$http#properties_defaults `$http.defaults.cache`} property. All requests who set + * their `cache` property to `true` will now use this cache object. + * + * If you set the default cache to `false` then only requests that specify their own custom + * cache object will be cached. + * + * # Interceptors + * + * Before you start creating interceptors, be sure to understand the + * {@link ng.$q $q and deferred/promise APIs}. + * + * For purposes of global error handling, authentication, or any kind of synchronous or + * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be + * able to intercept requests before they are handed to the server and + * responses before they are handed over to the application code that + * initiated these requests. The interceptors leverage the {@link ng.$q + * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing. + * + * The interceptors are service factories that are registered with the `$httpProvider` by + * adding them to the `$httpProvider.interceptors` array. The factory is called and + * injected with dependencies (if specified) and returns the interceptor. + * + * There are two kinds of interceptors (and two kinds of rejection interceptors): + * + * * `request`: interceptors get called with http `config` object. The function is free to + * modify the `config` or create a new one. The function needs to return the `config` + * directly or as a promise. + * * `requestError`: interceptor gets called when a previous interceptor threw an error or + * resolved with a rejection. + * * `response`: interceptors get called with http `response` object. The function is free to + * modify the `response` or create a new one. The function needs to return the `response` + * directly or as a promise. + * * `responseError`: interceptor gets called when a previous interceptor threw an error or + * resolved with a rejection. + * + * + *
+     *   // register the interceptor as a service
+     *   $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
+     *     return {
+     *       // optional method
+     *       'request': function(config) {
+     *         // do something on success
+     *         return config || $q.when(config);
+     *       },
+     *
+     *       // optional method
+     *      'requestError': function(rejection) {
+     *         // do something on error
+     *         if (canRecover(rejection)) {
+     *           return responseOrNewPromise
+     *         }
+     *         return $q.reject(rejection);
+     *       },
+     *
+     *
+     *
+     *       // optional method
+     *       'response': function(response) {
+     *         // do something on success
+     *         return response || $q.when(response);
+     *       },
+     *
+     *       // optional method
+     *      'responseError': function(rejection) {
+     *         // do something on error
+     *         if (canRecover(rejection)) {
+     *           return responseOrNewPromise
+     *         }
+     *         return $q.reject(rejection);
+     *       };
+     *     }
+     *   });
+     *
+     *   $httpProvider.interceptors.push('myHttpInterceptor');
+     *
+     *
+     *   // register the interceptor via an anonymous factory
+     *   $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
+     *     return {
+     *      'request': function(config) {
+     *          // same as above
+     *       },
+     *       'response': function(response) {
+     *          // same as above
+     *       }
+     *     };
+     *   });
+     * 
+ * + * # Response interceptors (DEPRECATED) + * + * Before you start creating interceptors, be sure to understand the + * {@link ng.$q $q and deferred/promise APIs}. + * + * For purposes of global error handling, authentication or any kind of synchronous or + * asynchronous preprocessing of received responses, it is desirable to be able to intercept + * responses for http requests before they are handed over to the application code that + * initiated these requests. The response interceptors leverage the {@link ng.$q + * promise apis} to fulfil this need for both synchronous and asynchronous preprocessing. + * + * The interceptors are service factories that are registered with the $httpProvider by + * adding them to the `$httpProvider.responseInterceptors` array. The factory is called and + * injected with dependencies (if specified) and returns the interceptor — a function that + * takes a {@link ng.$q promise} and returns the original or a new promise. + * + *
+     *   // register the interceptor as a service
+     *   $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
+     *     return function(promise) {
+     *       return promise.then(function(response) {
+     *         // do something on success
+     *         return response;
+     *       }, function(response) {
+     *         // do something on error
+     *         if (canRecover(response)) {
+     *           return responseOrNewPromise
+     *         }
+     *         return $q.reject(response);
+     *       });
+     *     }
+     *   });
+     *
+     *   $httpProvider.responseInterceptors.push('myHttpInterceptor');
+     *
+     *
+     *   // register the interceptor via an anonymous factory
+     *   $httpProvider.responseInterceptors.push(function($q, dependency1, dependency2) {
+     *     return function(promise) {
+     *       // same as above
+     *     }
+     *   });
+     * 
+ * + * + * # Security Considerations + * + * When designing web applications, consider security threats from: + * + * - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx + * JSON vulnerability} + * - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} + * + * Both server and the client must cooperate in order to eliminate these threats. Angular comes + * pre-configured with strategies that address these issues, but for this to work backend server + * cooperation is required. + * + * ## JSON Vulnerability Protection + * + * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx + * JSON vulnerability} allows third party website to turn your JSON resource URL into + * {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To + * counter this your server can prefix all JSON requests with following string `")]}',\n"`. + * Angular will automatically strip the prefix before processing it as JSON. + * + * For example if your server needs to return: + *
+     * ['one','two']
+     * 
+ * + * which is vulnerable to attack, your server can return: + *
+     * )]}',
+     * ['one','two']
+     * 
+ * + * Angular will strip the prefix, before processing the JSON. + * + * + * ## Cross Site Request Forgery (XSRF) Protection + * + * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which + * an unauthorized site can gain your user's private data. Angular provides a mechanism + * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie + * (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only + * JavaScript that runs on your domain could read the cookie, your server can be assured that + * the XHR came from JavaScript running on your domain. The header will not be set for + * cross-domain requests. + * + * To take advantage of this, your server needs to set a token in a JavaScript readable session + * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the + * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure + * that only JavaScript running on your domain could have sent the request. The token must be + * unique for each user and must be verifiable by the server (to prevent the JavaScript from + * making up its own tokens). We recommend that the token is a digest of your site's + * authentication cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} + * for added security. + * + * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName + * properties of either $httpProvider.defaults, or the per-request config object. + * + * + * @param {object} config Object describing the request to be made and how it should be + * processed. The object has following properties: + * + * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc) + * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested. + * - **params** – `{Object.}` – Map of strings or objects which will be turned + * to `?key1=value1&key2=value2` after the url. If the value is not a string, it will be + * JSONified. + * - **data** – `{string|Object}` – Data to be sent as the request message data. + * - **headers** – `{Object}` – Map of strings or functions which return strings representing + * HTTP headers to send to the server. If the return value of a function is null, the + * header will not be sent. + * - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token. + * - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token. + * - **transformRequest** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * request body and headers and returns its transformed (typically serialized) version. + * - **transformResponse** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * response body and headers and returns its transformed (typically deserialized) version. + * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the + * GET request, otherwise if a cache instance built with + * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for + * caching. + * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} + * that should abort the request when resolved. + * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the + * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5 + * requests with credentials} for more information. + * - **responseType** - `{string}` - see {@link + * https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}. + * + * @returns {HttpPromise} Returns a {@link ng.$q promise} object with the + * standard `then` method and two http specific methods: `success` and `error`. The `then` + * method takes two arguments a success and an error callback which will be called with a + * response object. The `success` and `error` methods take a single argument - a function that + * will be called when the request succeeds or fails respectively. The arguments passed into + * these functions are destructured representation of the response object passed into the + * `then` method. The response object has these properties: + * + * - **data** – `{string|Object}` – The response body transformed with the transform + * functions. + * - **status** – `{number}` – HTTP status code of the response. + * - **headers** – `{function([headerName])}` – Header getter function. + * - **config** – `{Object}` – The configuration object that was used to generate the request. + * + * @property {Array.} pendingRequests Array of config objects for currently pending + * requests. This is primarily meant to be used for debugging purposes. + * + * + * @example + + +
+ + +
+ + + +
http status code: {{status}}
+
http response data: {{data}}
+
+
+ + function FetchCtrl($scope, $http, $templateCache) { + $scope.method = 'GET'; + $scope.url = 'http-hello.html'; + + $scope.fetch = function() { + $scope.code = null; + $scope.response = null; + + $http({method: $scope.method, url: $scope.url, cache: $templateCache}). + success(function(data, status) { + $scope.status = status; + $scope.data = data; + }). + error(function(data, status) { + $scope.data = data || "Request failed"; + $scope.status = status; + }); + }; + + $scope.updateModel = function(method, url) { + $scope.method = method; + $scope.url = url; + }; + } + + + Hello, $http! + + + it('should make an xhr GET request', function() { + element(':button:contains("Sample GET")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('200'); + expect(binding('data')).toMatch(/Hello, \$http!/); + }); + + it('should make a JSONP request to angularjs.org', function() { + element(':button:contains("Sample JSONP")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('200'); + expect(binding('data')).toMatch(/Super Hero!/); + }); + + it('should make JSONP request to invalid URL and invoke the error handler', + function() { + element(':button:contains("Invalid JSONP")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('0'); + expect(binding('data')).toBe('Request failed'); + }); + +
+ */ + function $http(requestConfig) { + var config = { + transformRequest: defaults.transformRequest, + transformResponse: defaults.transformResponse + }; + var headers = mergeHeaders(requestConfig); + + extend(config, requestConfig); + config.headers = headers; + config.method = uppercase(config.method); + + var xsrfValue = urlIsSameOrigin(config.url) + ? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName] + : undefined; + if (xsrfValue) { + headers[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue; + } + + + var serverRequest = function(config) { + headers = config.headers; + var reqData = transformData(config.data, headersGetter(headers), config.transformRequest); + + // strip content-type if data is undefined + if (isUndefined(config.data)) { + forEach(headers, function(value, header) { + if (lowercase(header) === 'content-type') { + delete headers[header]; + } + }); + } + + if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) { + config.withCredentials = defaults.withCredentials; + } + + // send request + return sendReq(config, reqData, headers).then(transformResponse, transformResponse); + }; + + var chain = [serverRequest, undefined]; + var promise = $q.when(config); + + // apply interceptors + forEach(reversedInterceptors, function(interceptor) { + if (interceptor.request || interceptor.requestError) { + chain.unshift(interceptor.request, interceptor.requestError); + } + if (interceptor.response || interceptor.responseError) { + chain.push(interceptor.response, interceptor.responseError); + } + }); + + while(chain.length) { + var thenFn = chain.shift(); + var rejectFn = chain.shift(); + + promise = promise.then(thenFn, rejectFn); + } + + promise.success = function(fn) { + promise.then(function(response) { + fn(response.data, response.status, response.headers, config); + }); + return promise; + }; + + promise.error = function(fn) { + promise.then(null, function(response) { + fn(response.data, response.status, response.headers, config); + }); + return promise; + }; + + return promise; + + function transformResponse(response) { + // make a copy since the response must be cacheable + var resp = extend({}, response, { + data: transformData(response.data, response.headers, config.transformResponse) + }); + return (isSuccess(response.status)) + ? resp + : $q.reject(resp); + } + + function mergeHeaders(config) { + var defHeaders = defaults.headers, + reqHeaders = extend({}, config.headers), + defHeaderName, lowercaseDefHeaderName, reqHeaderName; + + defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]); + + // execute if header value is function + execHeaders(defHeaders); + execHeaders(reqHeaders); + + // using for-in instead of forEach to avoid unecessary iteration after header has been found + defaultHeadersIteration: + for (defHeaderName in defHeaders) { + lowercaseDefHeaderName = lowercase(defHeaderName); + + for (reqHeaderName in reqHeaders) { + if (lowercase(reqHeaderName) === lowercaseDefHeaderName) { + continue defaultHeadersIteration; + } + } + + reqHeaders[defHeaderName] = defHeaders[defHeaderName]; + } + + return reqHeaders; + + function execHeaders(headers) { + var headerContent; + + forEach(headers, function(headerFn, header) { + if (isFunction(headerFn)) { + headerContent = headerFn(); + if (headerContent != null) { + headers[header] = headerContent; + } else { + delete headers[header]; + } + } + }); + } + } + } + + $http.pendingRequests = []; + + /** + * @ngdoc method + * @name ng.$http#get + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `GET` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name ng.$http#delete + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `DELETE` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name ng.$http#head + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `HEAD` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name ng.$http#jsonp + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `JSONP` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request. + * Should contain `JSON_CALLBACK` string. + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + createShortMethods('get', 'delete', 'head', 'jsonp'); + + /** + * @ngdoc method + * @name ng.$http#post + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `POST` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {*} data Request content + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name ng.$http#put + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `PUT` request. + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {*} data Request content + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + createShortMethodsWithData('post', 'put'); + + /** + * @ngdoc property + * @name ng.$http#defaults + * @propertyOf ng.$http + * + * @description + * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of + * default headers, withCredentials as well as request and response transformations. + * + * See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above. + */ + $http.defaults = defaults; + + + return $http; + + + function createShortMethods(names) { + forEach(arguments, function(name) { + $http[name] = function(url, config) { + return $http(extend(config || {}, { + method: name, + url: url + })); + }; + }); + } + + + function createShortMethodsWithData(name) { + forEach(arguments, function(name) { + $http[name] = function(url, data, config) { + return $http(extend(config || {}, { + method: name, + url: url, + data: data + })); + }; + }); + } + + + /** + * Makes the request. + * + * !!! ACCESSES CLOSURE VARS: + * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests + */ + function sendReq(config, reqData, reqHeaders) { + var deferred = $q.defer(), + promise = deferred.promise, + cache, + cachedResp, + url = buildUrl(config.url, config.params); + + $http.pendingRequests.push(config); + promise.then(removePendingReq, removePendingReq); + + + if ((config.cache || defaults.cache) && config.cache !== false && config.method == 'GET') { + cache = isObject(config.cache) ? config.cache + : isObject(defaults.cache) ? defaults.cache + : defaultCache; + } + + if (cache) { + cachedResp = cache.get(url); + if (isDefined(cachedResp)) { + if (cachedResp.then) { + // cached request has already been sent, but there is no response yet + cachedResp.then(removePendingReq, removePendingReq); + return cachedResp; + } else { + // serving from cache + if (isArray(cachedResp)) { + resolvePromise(cachedResp[1], cachedResp[0], copy(cachedResp[2])); + } else { + resolvePromise(cachedResp, 200, {}); + } + } + } else { + // put the promise for the non-transformed response into cache as a placeholder + cache.put(url, promise); + } + } + + // if we won't have the response in cache, send the request to the backend + if (isUndefined(cachedResp)) { + $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout, + config.withCredentials, config.responseType); + } + + return promise; + + + /** + * Callback registered to $httpBackend(): + * - caches the response if desired + * - resolves the raw $http promise + * - calls $apply + */ + function done(status, response, headersString) { + if (cache) { + if (isSuccess(status)) { + cache.put(url, [status, response, parseHeaders(headersString)]); + } else { + // remove promise from the cache + cache.remove(url); + } + } + + resolvePromise(response, status, headersString); + if (!$rootScope.$$phase) $rootScope.$apply(); + } + + + /** + * Resolves the raw $http promise. + */ + function resolvePromise(response, status, headers) { + // normalize internal statuses to 0 + status = Math.max(status, 0); + + (isSuccess(status) ? deferred.resolve : deferred.reject)({ + data: response, + status: status, + headers: headersGetter(headers), + config: config + }); + } + + + function removePendingReq() { + var idx = indexOf($http.pendingRequests, config); + if (idx !== -1) $http.pendingRequests.splice(idx, 1); + } + } + + + function buildUrl(url, params) { + if (!params) return url; + var parts = []; + forEachSorted(params, function(value, key) { + if (value === null || isUndefined(value)) return; + if (!isArray(value)) value = [value]; + + forEach(value, function(v) { + if (isObject(v)) { + v = toJson(v); + } + parts.push(encodeUriQuery(key) + '=' + + encodeUriQuery(v)); + }); + }); + return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&'); + } + + + }]; +} + +var XHR = window.XMLHttpRequest || function() { + /* global ActiveXObject */ + try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} + try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} + try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} + throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest."); +}; + + +/** + * @ngdoc object + * @name ng.$httpBackend + * @requires $browser + * @requires $window + * @requires $document + * + * @description + * HTTP backend used by the {@link ng.$http service} that delegates to + * XMLHttpRequest object or JSONP and deals with browser incompatibilities. + * + * You should never need to use this service directly, instead use the higher-level abstractions: + * {@link ng.$http $http} or {@link ngResource.$resource $resource}. + * + * During testing this implementation is swapped with {@link ngMock.$httpBackend mock + * $httpBackend} which can be trained with responses. + */ +function $HttpBackendProvider() { + this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) { + return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0]); + }]; +} + +function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) { + var ABORTED = -1; + + // TODO(vojta): fix the signature + return function(method, url, post, callback, headers, timeout, withCredentials, responseType) { + var status; + $browser.$$incOutstandingRequestCount(); + url = url || $browser.url(); + + if (lowercase(method) == 'jsonp') { + var callbackId = '_' + (callbacks.counter++).toString(36); + callbacks[callbackId] = function(data) { + callbacks[callbackId].data = data; + }; + + var jsonpDone = jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId), + function() { + if (callbacks[callbackId].data) { + completeRequest(callback, 200, callbacks[callbackId].data); + } else { + completeRequest(callback, status || -2); + } + delete callbacks[callbackId]; + }); + } else { + var xhr = new XHR(); + xhr.open(method, url, true); + forEach(headers, function(value, key) { + if (isDefined(value)) { + xhr.setRequestHeader(key, value); + } + }); + + // In IE6 and 7, this might be called synchronously when xhr.send below is called and the + // response is in the cache. the promise api will ensure that to the app code the api is + // always async + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + var responseHeaders = null, + response = null; + + if(status !== ABORTED) { + responseHeaders = xhr.getAllResponseHeaders(); + response = xhr.responseType ? xhr.response : xhr.responseText; + } + + // responseText is the old-school way of retrieving response (supported by IE8 & 9) + // response/responseType properties were introduced in XHR Level2 spec (supported by IE10) + completeRequest(callback, + status || xhr.status, + response, + responseHeaders); + } + }; + + if (withCredentials) { + xhr.withCredentials = true; + } + + if (responseType) { + xhr.responseType = responseType; + } + + xhr.send(post || null); + } + + if (timeout > 0) { + var timeoutId = $browserDefer(timeoutRequest, timeout); + } else if (timeout && timeout.then) { + timeout.then(timeoutRequest); + } + + + function timeoutRequest() { + status = ABORTED; + jsonpDone && jsonpDone(); + xhr && xhr.abort(); + } + + function completeRequest(callback, status, response, headersString) { + var protocol = urlResolve(url).protocol; + + // cancel timeout and subsequent timeout promise resolution + timeoutId && $browserDefer.cancel(timeoutId); + jsonpDone = xhr = null; + + // fix status code for file protocol (it's always 0) + status = (protocol == 'file' && status === 0) ? (response ? 200 : 404) : status; + + // normalize IE bug (http://bugs.jquery.com/ticket/1450) + status = status == 1223 ? 204 : status; + + callback(status, response, headersString); + $browser.$$completeOutstandingRequest(noop); + } + }; + + function jsonpReq(url, done) { + // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.: + // - fetches local scripts via XHR and evals them + // - adds and immediately removes script elements from the document + var script = rawDocument.createElement('script'), + doneWrapper = function() { + script.onreadystatechange = script.onload = script.onerror = null; + rawDocument.body.removeChild(script); + if (done) done(); + }; + + script.type = 'text/javascript'; + script.src = url; + + if (msie && msie <= 8) { + script.onreadystatechange = function() { + if (/loaded|complete/.test(script.readyState)) { + doneWrapper(); + } + }; + } else { + script.onload = script.onerror = function() { + doneWrapper(); + }; + } + + rawDocument.body.appendChild(script); + return doneWrapper; + } +} + +var $interpolateMinErr = minErr('$interpolate'); + +/** + * @ngdoc object + * @name ng.$interpolateProvider + * @function + * + * @description + * + * Used for configuring the interpolation markup. Defaults to `{{` and `}}`. + * + * @example + + + +
+ //demo.label// +
+
+ + it('should interpolate binding with custom symbols', function() { + expect(binding('demo.label')).toBe('This binding is brought you by // interpolation symbols.'); + }); + +
+ */ +function $InterpolateProvider() { + var startSymbol = '{{'; + var endSymbol = '}}'; + + /** + * @ngdoc method + * @name ng.$interpolateProvider#startSymbol + * @methodOf ng.$interpolateProvider + * @description + * Symbol to denote start of expression in the interpolated string. Defaults to `{{`. + * + * @param {string=} value new value to set the starting symbol to. + * @returns {string|self} Returns the symbol when used as getter and self if used as setter. + */ + this.startSymbol = function(value){ + if (value) { + startSymbol = value; + return this; + } else { + return startSymbol; + } + }; + + /** + * @ngdoc method + * @name ng.$interpolateProvider#endSymbol + * @methodOf ng.$interpolateProvider + * @description + * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`. + * + * @param {string=} value new value to set the ending symbol to. + * @returns {string|self} Returns the symbol when used as getter and self if used as setter. + */ + this.endSymbol = function(value){ + if (value) { + endSymbol = value; + return this; + } else { + return endSymbol; + } + }; + + + this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) { + var startSymbolLength = startSymbol.length, + endSymbolLength = endSymbol.length; + + /** + * @ngdoc function + * @name ng.$interpolate + * @function + * + * @requires $parse + * @requires $sce + * + * @description + * + * Compiles a string with markup into an interpolation function. This service is used by the + * HTML {@link ng.$compile $compile} service for data binding. See + * {@link ng.$interpolateProvider $interpolateProvider} for configuring the + * interpolation markup. + * + * +
+         var $interpolate = ...; // injected
+         var exp = $interpolate('Hello {{name}}!');
+         expect(exp({name:'Angular'}).toEqual('Hello Angular!');
+       
+ * + * + * @param {string} text The text with markup to interpolate. + * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have + * embedded expression in order to return an interpolation function. Strings with no + * embedded expression will return null for the interpolation function. + * @param {string=} trustedContext when provided, the returned function passes the interpolated + * result through {@link ng.$sce#methods_getTrusted $sce.getTrusted(interpolatedResult, + * trustedContext)} before returning it. Refer to the {@link ng.$sce $sce} service that + * provides Strict Contextual Escaping for details. + * @returns {function(context)} an interpolation function which is used to compute the + * interpolated string. The function has these parameters: + * + * * `context`: an object against which any expressions embedded in the strings are evaluated + * against. + * + */ + function $interpolate(text, mustHaveExpression, trustedContext) { + var startIndex, + endIndex, + index = 0, + parts = [], + length = text.length, + hasInterpolation = false, + fn, + exp, + concat = []; + + while(index < length) { + if ( ((startIndex = text.indexOf(startSymbol, index)) != -1) && + ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) ) { + (index != startIndex) && parts.push(text.substring(index, startIndex)); + parts.push(fn = $parse(exp = text.substring(startIndex + startSymbolLength, endIndex))); + fn.exp = exp; + index = endIndex + endSymbolLength; + hasInterpolation = true; + } else { + // we did not find anything, so we have to add the remainder to the parts array + (index != length) && parts.push(text.substring(index)); + index = length; + } + } + + if (!(length = parts.length)) { + // we added, nothing, must have been an empty string. + parts.push(''); + length = 1; + } + + // Concatenating expressions makes it hard to reason about whether some combination of + // concatenated values are unsafe to use and could easily lead to XSS. By requiring that a + // single expression be used for iframe[src], object[src], etc., we ensure that the value + // that's used is assigned or constructed by some JS code somewhere that is more testable or + // make it obvious that you bound the value to some user controlled value. This helps reduce + // the load when auditing for XSS issues. + if (trustedContext && parts.length > 1) { + throw $interpolateMinErr('noconcat', + "Error while interpolating: {0}\nStrict Contextual Escaping disallows " + + "interpolations that concatenate multiple expressions when a trusted value is " + + "required. See http://docs.angularjs.org/api/ng.$sce", text); + } + + if (!mustHaveExpression || hasInterpolation) { + concat.length = length; + fn = function(context) { + try { + for(var i = 0, ii = length, part; i 0 && iteration >= count) { + deferred.resolve(iteration); + clearInterval(promise.$$intervalId); + delete intervals[promise.$$intervalId]; + } + + if (!skipApply) $rootScope.$apply(); + + }, delay); + + intervals[promise.$$intervalId] = deferred; + + return promise; + } + + + /** + * @ngdoc function + * @name ng.$interval#cancel + * @methodOf ng.$interval + * + * @description + * Cancels a task associated with the `promise`. + * + * @param {number} promise Promise returned by the `$interval` function. + * @returns {boolean} Returns `true` if the task was successfully canceled. + */ + interval.cancel = function(promise) { + if (promise && promise.$$intervalId in intervals) { + intervals[promise.$$intervalId].reject('canceled'); + clearInterval(promise.$$intervalId); + delete intervals[promise.$$intervalId]; + return true; + } + return false; + }; + + return interval; + }]; +} + +/** + * @ngdoc object + * @name ng.$locale + * + * @description + * $locale service provides localization rules for various Angular components. As of right now the + * only public api is: + * + * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`) + */ +function $LocaleProvider(){ + this.$get = function() { + return { + id: 'en-us', + + NUMBER_FORMATS: { + DECIMAL_SEP: '.', + GROUP_SEP: ',', + PATTERNS: [ + { // Decimal Pattern + minInt: 1, + minFrac: 0, + maxFrac: 3, + posPre: '', + posSuf: '', + negPre: '-', + negSuf: '', + gSize: 3, + lgSize: 3 + },{ //Currency Pattern + minInt: 1, + minFrac: 2, + maxFrac: 2, + posPre: '\u00A4', + posSuf: '', + negPre: '(\u00A4', + negSuf: ')', + gSize: 3, + lgSize: 3 + } + ], + CURRENCY_SYM: '$' + }, + + DATETIME_FORMATS: { + MONTH: + 'January,February,March,April,May,June,July,August,September,October,November,December' + .split(','), + SHORTMONTH: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','), + DAY: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','), + SHORTDAY: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(','), + AMPMS: ['AM','PM'], + medium: 'MMM d, y h:mm:ss a', + short: 'M/d/yy h:mm a', + fullDate: 'EEEE, MMMM d, y', + longDate: 'MMMM d, y', + mediumDate: 'MMM d, y', + shortDate: 'M/d/yy', + mediumTime: 'h:mm:ss a', + shortTime: 'h:mm a' + }, + + pluralCat: function(num) { + if (num === 1) { + return 'one'; + } + return 'other'; + } + }; + }; +} + +var PATH_MATCH = /^([^\?#]*)(\?([^#]*))?(#(.*))?$/, + DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21}; +var $locationMinErr = minErr('$location'); + + +/** + * Encode path using encodeUriSegment, ignoring forward slashes + * + * @param {string} path Path to encode + * @returns {string} + */ +function encodePath(path) { + var segments = path.split('/'), + i = segments.length; + + while (i--) { + segments[i] = encodeUriSegment(segments[i]); + } + + return segments.join('/'); +} + +function parseAbsoluteUrl(absoluteUrl, locationObj, appBase) { + var parsedUrl = urlResolve(absoluteUrl, appBase); + + locationObj.$$protocol = parsedUrl.protocol; + locationObj.$$host = parsedUrl.hostname; + locationObj.$$port = int(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null; +} + + +function parseAppUrl(relativeUrl, locationObj, appBase) { + var prefixed = (relativeUrl.charAt(0) !== '/'); + if (prefixed) { + relativeUrl = '/' + relativeUrl; + } + var match = urlResolve(relativeUrl, appBase); + locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ? + match.pathname.substring(1) : match.pathname); + locationObj.$$search = parseKeyValue(match.search); + locationObj.$$hash = decodeURIComponent(match.hash); + + // make sure path starts with '/'; + if (locationObj.$$path && locationObj.$$path.charAt(0) != '/') { + locationObj.$$path = '/' + locationObj.$$path; + } +} + + +/** + * + * @param {string} begin + * @param {string} whole + * @returns {string} returns text from whole after begin or undefined if it does not begin with + * expected string. + */ +function beginsWith(begin, whole) { + if (whole.indexOf(begin) === 0) { + return whole.substr(begin.length); + } +} + + +function stripHash(url) { + var index = url.indexOf('#'); + return index == -1 ? url : url.substr(0, index); +} + + +function stripFile(url) { + return url.substr(0, stripHash(url).lastIndexOf('/') + 1); +} + +/* return the server only (scheme://host:port) */ +function serverBase(url) { + return url.substring(0, url.indexOf('/', url.indexOf('//') + 2)); +} + + +/** + * LocationHtml5Url represents an url + * This object is exposed as $location service when HTML5 mode is enabled and supported + * + * @constructor + * @param {string} appBase application base URL + * @param {string} basePrefix url path prefix + */ +function LocationHtml5Url(appBase, basePrefix) { + this.$$html5 = true; + basePrefix = basePrefix || ''; + var appBaseNoFile = stripFile(appBase); + parseAbsoluteUrl(appBase, this, appBase); + + + /** + * Parse given html5 (regular) url string into properties + * @param {string} newAbsoluteUrl HTML5 url + * @private + */ + this.$$parse = function(url) { + var pathUrl = beginsWith(appBaseNoFile, url); + if (!isString(pathUrl)) { + throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url, + appBaseNoFile); + } + + parseAppUrl(pathUrl, this, appBase); + + if (!this.$$path) { + this.$$path = '/'; + } + + this.$$compose(); + }; + + /** + * Compose url and update `absUrl` property + * @private + */ + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + this.$$absUrl = appBaseNoFile + this.$$url.substr(1); // first char is always '/' + }; + + this.$$rewrite = function(url) { + var appUrl, prevAppUrl; + + if ( (appUrl = beginsWith(appBase, url)) !== undefined ) { + prevAppUrl = appUrl; + if ( (appUrl = beginsWith(basePrefix, appUrl)) !== undefined ) { + return appBaseNoFile + (beginsWith('/', appUrl) || appUrl); + } else { + return appBase + prevAppUrl; + } + } else if ( (appUrl = beginsWith(appBaseNoFile, url)) !== undefined ) { + return appBaseNoFile + appUrl; + } else if (appBaseNoFile == url + '/') { + return appBaseNoFile; + } + }; +} + + +/** + * LocationHashbangUrl represents url + * This object is exposed as $location service when developer doesn't opt into html5 mode. + * It also serves as the base class for html5 mode fallback on legacy browsers. + * + * @constructor + * @param {string} appBase application base URL + * @param {string} hashPrefix hashbang prefix + */ +function LocationHashbangUrl(appBase, hashPrefix) { + var appBaseNoFile = stripFile(appBase); + + parseAbsoluteUrl(appBase, this, appBase); + + + /** + * Parse given hashbang url into properties + * @param {string} url Hashbang url + * @private + */ + this.$$parse = function(url) { + var withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url); + var withoutHashUrl = withoutBaseUrl.charAt(0) == '#' + ? beginsWith(hashPrefix, withoutBaseUrl) + : (this.$$html5) + ? withoutBaseUrl + : ''; + + if (!isString(withoutHashUrl)) { + throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url, + hashPrefix); + } + parseAppUrl(withoutHashUrl, this, appBase); + + this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase); + + this.$$compose(); + + /* + * In Windows, on an anchor node on documents loaded from + * the filesystem, the browser will return a pathname + * prefixed with the drive name ('/C:/path') when a + * pathname without a drive is set: + * * a.setAttribute('href', '/foo') + * * a.pathname === '/C:/foo' //true + * + * Inside of Angular, we're always using pathnames that + * do not include drive names for routing. + */ + function removeWindowsDriveName (path, url, base) { + /* + Matches paths for file protocol on windows, + such as /C:/foo/bar, and captures only /foo/bar. + */ + var windowsFilePathExp = /^\/?.*?:(\/.*)/; + + var firstPathSegmentMatch; + + //Get the relative path from the input URL. + if (url.indexOf(base) === 0) { + url = url.replace(base, ''); + } + + /* + * The input URL intentionally contains a + * first path segment that ends with a colon. + */ + if (windowsFilePathExp.exec(url)) { + return path; + } + + firstPathSegmentMatch = windowsFilePathExp.exec(path); + return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path; + } + }; + + /** + * Compose hashbang url and update `absUrl` property + * @private + */ + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : ''); + }; + + this.$$rewrite = function(url) { + if(stripHash(appBase) == stripHash(url)) { + return url; + } + }; +} + + +/** + * LocationHashbangUrl represents url + * This object is exposed as $location service when html5 history api is enabled but the browser + * does not support it. + * + * @constructor + * @param {string} appBase application base URL + * @param {string} hashPrefix hashbang prefix + */ +function LocationHashbangInHtml5Url(appBase, hashPrefix) { + this.$$html5 = true; + LocationHashbangUrl.apply(this, arguments); + + var appBaseNoFile = stripFile(appBase); + + this.$$rewrite = function(url) { + var appUrl; + + if ( appBase == stripHash(url) ) { + return url; + } else if ( (appUrl = beginsWith(appBaseNoFile, url)) ) { + return appBase + hashPrefix + appUrl; + } else if ( appBaseNoFile === url + '/') { + return appBaseNoFile; + } + }; +} + + +LocationHashbangInHtml5Url.prototype = + LocationHashbangUrl.prototype = + LocationHtml5Url.prototype = { + + /** + * Are we in html5 mode? + * @private + */ + $$html5: false, + + /** + * Has any change been replacing ? + * @private + */ + $$replace: false, + + /** + * @ngdoc method + * @name ng.$location#absUrl + * @methodOf ng.$location + * + * @description + * This method is getter only. + * + * Return full url representation with all segments encoded according to rules specified in + * {@link http://www.ietf.org/rfc/rfc3986.txt RFC 3986}. + * + * @return {string} full url + */ + absUrl: locationGetter('$$absUrl'), + + /** + * @ngdoc method + * @name ng.$location#url + * @methodOf ng.$location + * + * @description + * This method is getter / setter. + * + * Return url (e.g. `/path?a=b#hash`) when called without any parameter. + * + * Change path, search and hash, when called with parameter and return `$location`. + * + * @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`) + * @param {string=} replace The path that will be changed + * @return {string} url + */ + url: function(url, replace) { + if (isUndefined(url)) + return this.$$url; + + var match = PATH_MATCH.exec(url); + if (match[1]) this.path(decodeURIComponent(match[1])); + if (match[2] || match[1]) this.search(match[3] || ''); + this.hash(match[5] || '', replace); + + return this; + }, + + /** + * @ngdoc method + * @name ng.$location#protocol + * @methodOf ng.$location + * + * @description + * This method is getter only. + * + * Return protocol of current url. + * + * @return {string} protocol of current url + */ + protocol: locationGetter('$$protocol'), + + /** + * @ngdoc method + * @name ng.$location#host + * @methodOf ng.$location + * + * @description + * This method is getter only. + * + * Return host of current url. + * + * @return {string} host of current url. + */ + host: locationGetter('$$host'), + + /** + * @ngdoc method + * @name ng.$location#port + * @methodOf ng.$location + * + * @description + * This method is getter only. + * + * Return port of current url. + * + * @return {Number} port + */ + port: locationGetter('$$port'), + + /** + * @ngdoc method + * @name ng.$location#path + * @methodOf ng.$location + * + * @description + * This method is getter / setter. + * + * Return path of current url when called without any parameter. + * + * Change path when called with parameter and return `$location`. + * + * Note: Path should always begin with forward slash (/), this method will add the forward slash + * if it is missing. + * + * @param {string=} path New path + * @return {string} path + */ + path: locationGetterSetter('$$path', function(path) { + return path.charAt(0) == '/' ? path : '/' + path; + }), + + /** + * @ngdoc method + * @name ng.$location#search + * @methodOf ng.$location + * + * @description + * This method is getter / setter. + * + * Return search part (as object) of current url when called without any parameter. + * + * Change search part when called with parameter and return `$location`. + * + * @param {string|Object.|Object.>} search New search params - string or + * hash object. Hash object may contain an array of values, which will be decoded as duplicates in + * the url. + * + * @param {(string|Array)=} paramValue If `search` is a string, then `paramValue` will override only a + * single search parameter. If `paramValue` is an array, it will set the parameter as a + * comma-separated value. If `paramValue` is `null`, the parameter will be deleted. + * + * @return {string} search + */ + search: function(search, paramValue) { + switch (arguments.length) { + case 0: + return this.$$search; + case 1: + if (isString(search)) { + this.$$search = parseKeyValue(search); + } else if (isObject(search)) { + this.$$search = search; + } else { + throw $locationMinErr('isrcharg', + 'The first argument of the `$location#search()` call must be a string or an object.'); + } + break; + default: + if (isUndefined(paramValue) || paramValue === null) { + delete this.$$search[search]; + } else { + this.$$search[search] = paramValue; + } + } + + this.$$compose(); + return this; + }, + + /** + * @ngdoc method + * @name ng.$location#hash + * @methodOf ng.$location + * + * @description + * This method is getter / setter. + * + * Return hash fragment when called without any parameter. + * + * Change hash fragment when called with parameter and return `$location`. + * + * @param {string=} hash New hash fragment + * @return {string} hash + */ + hash: locationGetterSetter('$$hash', identity), + + /** + * @ngdoc method + * @name ng.$location#replace + * @methodOf ng.$location + * + * @description + * If called, all changes to $location during current `$digest` will be replacing current history + * record, instead of adding new one. + */ + replace: function() { + this.$$replace = true; + return this; + } +}; + +function locationGetter(property) { + return function() { + return this[property]; + }; +} + + +function locationGetterSetter(property, preprocess) { + return function(value) { + if (isUndefined(value)) + return this[property]; + + this[property] = preprocess(value); + this.$$compose(); + + return this; + }; +} + + +/** + * @ngdoc object + * @name ng.$location + * + * @requires $browser + * @requires $sniffer + * @requires $rootElement + * + * @description + * The $location service parses the URL in the browser address bar (based on the + * {@link https://developer.mozilla.org/en/window.location window.location}) and makes the URL + * available to your application. Changes to the URL in the address bar are reflected into + * $location service and changes to $location are reflected into the browser address bar. + * + * **The $location service:** + * + * - Exposes the current URL in the browser address bar, so you can + * - Watch and observe the URL. + * - Change the URL. + * - Synchronizes the URL with the browser when the user + * - Changes the address bar. + * - Clicks the back or forward button (or clicks a History link). + * - Clicks on a link. + * - Represents the URL object as a set of methods (protocol, host, port, path, search, hash). + * + * For more information see {@link guide/dev_guide.services.$location Developer Guide: Angular + * Services: Using $location} + */ + +/** + * @ngdoc object + * @name ng.$locationProvider + * @description + * Use the `$locationProvider` to configure how the application deep linking paths are stored. + */ +function $LocationProvider(){ + var hashPrefix = '', + html5Mode = false; + + /** + * @ngdoc property + * @name ng.$locationProvider#hashPrefix + * @methodOf ng.$locationProvider + * @description + * @param {string=} prefix Prefix for hash part (containing path and search) + * @returns {*} current value if used as getter or itself (chaining) if used as setter + */ + this.hashPrefix = function(prefix) { + if (isDefined(prefix)) { + hashPrefix = prefix; + return this; + } else { + return hashPrefix; + } + }; + + /** + * @ngdoc property + * @name ng.$locationProvider#html5Mode + * @methodOf ng.$locationProvider + * @description + * @param {boolean=} mode Use HTML5 strategy if available. + * @returns {*} current value if used as getter or itself (chaining) if used as setter + */ + this.html5Mode = function(mode) { + if (isDefined(mode)) { + html5Mode = mode; + return this; + } else { + return html5Mode; + } + }; + + /** + * @ngdoc event + * @name ng.$location#$locationChangeStart + * @eventOf ng.$location + * @eventType broadcast on root scope + * @description + * Broadcasted before a URL will change. This change can be prevented by calling + * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more + * details about event object. Upon successful change + * {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired. + * + * @param {Object} angularEvent Synthetic event object. + * @param {string} newUrl New URL + * @param {string=} oldUrl URL that was before it was changed. + */ + + /** + * @ngdoc event + * @name ng.$location#$locationChangeSuccess + * @eventOf ng.$location + * @eventType broadcast on root scope + * @description + * Broadcasted after a URL was changed. + * + * @param {Object} angularEvent Synthetic event object. + * @param {string} newUrl New URL + * @param {string=} oldUrl URL that was before it was changed. + */ + + this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', + function( $rootScope, $browser, $sniffer, $rootElement) { + var $location, + LocationMode, + baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to '' + initialUrl = $browser.url(), + appBase; + + if (html5Mode) { + appBase = serverBase(initialUrl) + (baseHref || '/'); + LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url; + } else { + appBase = stripHash(initialUrl); + LocationMode = LocationHashbangUrl; + } + $location = new LocationMode(appBase, '#' + hashPrefix); + $location.$$parse($location.$$rewrite(initialUrl)); + + $rootElement.on('click', function(event) { + // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser) + // currently we open nice url link and redirect then + + if (event.ctrlKey || event.metaKey || event.which == 2) return; + + var elm = jqLite(event.target); + + // traverse the DOM up to find first A tag + while (lowercase(elm[0].nodeName) !== 'a') { + // ignore rewriting if no A tag (reached root element, or no parent - removed from document) + if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return; + } + + var absHref = elm.prop('href'); + var rewrittenUrl = $location.$$rewrite(absHref); + + if (absHref && !elm.attr('target') && rewrittenUrl && !event.isDefaultPrevented()) { + event.preventDefault(); + if (rewrittenUrl != $browser.url()) { + // update location manually + $location.$$parse(rewrittenUrl); + $rootScope.$apply(); + // hack to work around FF6 bug 684208 when scenario runner clicks on links + window.angular['ff-684208-preventDefault'] = true; + } + } + }); + + + // rewrite hashbang url <> html5 url + if ($location.absUrl() != initialUrl) { + $browser.url($location.absUrl(), true); + } + + // update $location when $browser url changes + $browser.onUrlChange(function(newUrl) { + if ($location.absUrl() != newUrl) { + if ($rootScope.$broadcast('$locationChangeStart', newUrl, + $location.absUrl()).defaultPrevented) { + $browser.url($location.absUrl()); + return; + } + $rootScope.$evalAsync(function() { + var oldUrl = $location.absUrl(); + + $location.$$parse(newUrl); + afterLocationChange(oldUrl); + }); + if (!$rootScope.$$phase) $rootScope.$digest(); + } + }); + + // update browser + var changeCounter = 0; + $rootScope.$watch(function $locationWatch() { + var oldUrl = $browser.url(); + var currentReplace = $location.$$replace; + + if (!changeCounter || oldUrl != $location.absUrl()) { + changeCounter++; + $rootScope.$evalAsync(function() { + if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl). + defaultPrevented) { + $location.$$parse(oldUrl); + } else { + $browser.url($location.absUrl(), currentReplace); + afterLocationChange(oldUrl); + } + }); + } + $location.$$replace = false; + + return changeCounter; + }); + + return $location; + + function afterLocationChange(oldUrl) { + $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl); + } +}]; +} + +/** + * @ngdoc object + * @name ng.$log + * @requires $window + * + * @description + * Simple service for logging. Default implementation safely writes the message + * into the browser's console (if present). + * + * The main purpose of this service is to simplify debugging and troubleshooting. + * + * The default is to log `debug` messages. You can use + * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this. + * + * @example + + + function LogCtrl($scope, $log) { + $scope.$log = $log; + $scope.message = 'Hello World!'; + } + + +
+

Reload this page with open console, enter text and hit the log button...

+ Message: + + + + + +
+
+
+ */ + +/** + * @ngdoc object + * @name ng.$logProvider + * @description + * Use the `$logProvider` to configure how the application logs messages + */ +function $LogProvider(){ + var debug = true, + self = this; + + /** + * @ngdoc property + * @name ng.$logProvider#debugEnabled + * @methodOf ng.$logProvider + * @description + * @param {string=} flag enable or disable debug level messages + * @returns {*} current value if used as getter or itself (chaining) if used as setter + */ + this.debugEnabled = function(flag) { + if (isDefined(flag)) { + debug = flag; + return this; + } else { + return debug; + } + }; + + this.$get = ['$window', function($window){ + return { + /** + * @ngdoc method + * @name ng.$log#log + * @methodOf ng.$log + * + * @description + * Write a log message + */ + log: consoleLog('log'), + + /** + * @ngdoc method + * @name ng.$log#info + * @methodOf ng.$log + * + * @description + * Write an information message + */ + info: consoleLog('info'), + + /** + * @ngdoc method + * @name ng.$log#warn + * @methodOf ng.$log + * + * @description + * Write a warning message + */ + warn: consoleLog('warn'), + + /** + * @ngdoc method + * @name ng.$log#error + * @methodOf ng.$log + * + * @description + * Write an error message + */ + error: consoleLog('error'), + + /** + * @ngdoc method + * @name ng.$log#debug + * @methodOf ng.$log + * + * @description + * Write a debug message + */ + debug: (function () { + var fn = consoleLog('debug'); + + return function() { + if (debug) { + fn.apply(self, arguments); + } + }; + }()) + }; + + function formatError(arg) { + if (arg instanceof Error) { + if (arg.stack) { + arg = (arg.message && arg.stack.indexOf(arg.message) === -1) + ? 'Error: ' + arg.message + '\n' + arg.stack + : arg.stack; + } else if (arg.sourceURL) { + arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line; + } + } + return arg; + } + + function consoleLog(type) { + var console = $window.console || {}, + logFn = console[type] || console.log || noop; + + if (logFn.apply) { + return function() { + var args = []; + forEach(arguments, function(arg) { + args.push(formatError(arg)); + }); + return logFn.apply(console, args); + }; + } + + // we are IE which either doesn't have window.console => this is noop and we do nothing, + // or we are IE where console.log doesn't have apply so we log at least first 2 args + return function(arg1, arg2) { + logFn(arg1, arg2 == null ? '' : arg2); + }; + } + }]; +} + +var $parseMinErr = minErr('$parse'); +var promiseWarningCache = {}; +var promiseWarning; + +// Sandboxing Angular Expressions +// ------------------------------ +// Angular expressions are generally considered safe because these expressions only have direct +// access to $scope and locals. However, one can obtain the ability to execute arbitrary JS code by +// obtaining a reference to native JS functions such as the Function constructor. +// +// As an example, consider the following Angular expression: +// +// {}.toString.constructor(alert("evil JS code")) +// +// We want to prevent this type of access. For the sake of performance, during the lexing phase we +// disallow any "dotted" access to any member named "constructor". +// +// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor +// while evaluating the expression, which is a stronger but more expensive test. Since reflective +// calls are expensive anyway, this is not such a big deal compared to static dereferencing. +// +// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits +// against the expression language, but not to prevent exploits that were enabled by exposing +// sensitive JavaScript or browser apis on Scope. Exposing such objects on a Scope is never a good +// practice and therefore we are not even trying to protect against interaction with an object +// explicitly exposed in this way. +// +// A developer could foil the name check by aliasing the Function constructor under a different +// name on the scope. +// +// In general, it is not possible to access a Window object from an angular expression unless a +// window or some DOM object that has a reference to window is published onto a Scope. + +function ensureSafeMemberName(name, fullExpression) { + if (name === "constructor") { + throw $parseMinErr('isecfld', + 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } + return name; +} + +function ensureSafeObject(obj, fullExpression) { + // nifty check if obj is Function that is fast and works across iframes and other contexts + if (obj && obj.constructor === obj) { + throw $parseMinErr('isecfn', + 'Referencing Function in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } else if (// isWindow(obj) + obj && obj.document && obj.location && obj.alert && obj.setInterval) { + throw $parseMinErr('isecwindow', + 'Referencing the Window in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } else if (// isElement(obj) + obj && (obj.nodeName || (obj.on && obj.find))) { + throw $parseMinErr('isecdom', + 'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } else { + return obj; + } +} + +var OPERATORS = { + /* jshint bitwise : false */ + 'null':function(){return null;}, + 'true':function(){return true;}, + 'false':function(){return false;}, + undefined:noop, + '+':function(self, locals, a,b){ + a=a(self, locals); b=b(self, locals); + if (isDefined(a)) { + if (isDefined(b)) { + return a + b; + } + return a; + } + return isDefined(b)?b:undefined;}, + '-':function(self, locals, a,b){ + a=a(self, locals); b=b(self, locals); + return (isDefined(a)?a:0)-(isDefined(b)?b:0); + }, + '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);}, + '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);}, + '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);}, + '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);}, + '=':noop, + '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);}, + '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);}, + '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);}, + '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);}, + '<':function(self, locals, a,b){return a(self, locals)':function(self, locals, a,b){return a(self, locals)>b(self, locals);}, + '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);}, + '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);}, + '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);}, + '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);}, + '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);}, +// '|':function(self, locals, a,b){return a|b;}, + '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));}, + '!':function(self, locals, a){return !a(self, locals);} +}; +/* jshint bitwise: true */ +var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'}; + + +///////////////////////////////////////// + + +/** + * @constructor + */ +var Lexer = function (options) { + this.options = options; +}; + +Lexer.prototype = { + constructor: Lexer, + + lex: function (text) { + this.text = text; + + this.index = 0; + this.ch = undefined; + this.lastCh = ':'; // can start regexp + + this.tokens = []; + + var token; + var json = []; + + while (this.index < this.text.length) { + this.ch = this.text.charAt(this.index); + if (this.is('"\'')) { + this.readString(this.ch); + } else if (this.isNumber(this.ch) || this.is('.') && this.isNumber(this.peek())) { + this.readNumber(); + } else if (this.isIdent(this.ch)) { + this.readIdent(); + // identifiers can only be if the preceding char was a { or , + if (this.was('{,') && json[0] === '{' && + (token = this.tokens[this.tokens.length - 1])) { + token.json = token.text.indexOf('.') === -1; + } + } else if (this.is('(){}[].,;:?')) { + this.tokens.push({ + index: this.index, + text: this.ch, + json: (this.was(':[,') && this.is('{[')) || this.is('}]:,') + }); + if (this.is('{[')) json.unshift(this.ch); + if (this.is('}]')) json.shift(); + this.index++; + } else if (this.isWhitespace(this.ch)) { + this.index++; + continue; + } else { + var ch2 = this.ch + this.peek(); + var ch3 = ch2 + this.peek(2); + var fn = OPERATORS[this.ch]; + var fn2 = OPERATORS[ch2]; + var fn3 = OPERATORS[ch3]; + if (fn3) { + this.tokens.push({index: this.index, text: ch3, fn: fn3}); + this.index += 3; + } else if (fn2) { + this.tokens.push({index: this.index, text: ch2, fn: fn2}); + this.index += 2; + } else if (fn) { + this.tokens.push({ + index: this.index, + text: this.ch, + fn: fn, + json: (this.was('[,:') && this.is('+-')) + }); + this.index += 1; + } else { + this.throwError('Unexpected next character ', this.index, this.index + 1); + } + } + this.lastCh = this.ch; + } + return this.tokens; + }, + + is: function(chars) { + return chars.indexOf(this.ch) !== -1; + }, + + was: function(chars) { + return chars.indexOf(this.lastCh) !== -1; + }, + + peek: function(i) { + var num = i || 1; + return (this.index + num < this.text.length) ? this.text.charAt(this.index + num) : false; + }, + + isNumber: function(ch) { + return ('0' <= ch && ch <= '9'); + }, + + isWhitespace: function(ch) { + // IE treats non-breaking space as \u00A0 + return (ch === ' ' || ch === '\r' || ch === '\t' || + ch === '\n' || ch === '\v' || ch === '\u00A0'); + }, + + isIdent: function(ch) { + return ('a' <= ch && ch <= 'z' || + 'A' <= ch && ch <= 'Z' || + '_' === ch || ch === '$'); + }, + + isExpOperator: function(ch) { + return (ch === '-' || ch === '+' || this.isNumber(ch)); + }, + + throwError: function(error, start, end) { + end = end || this.index; + var colStr = (isDefined(start) + ? 's ' + start + '-' + this.index + ' [' + this.text.substring(start, end) + ']' + : ' ' + end); + throw $parseMinErr('lexerr', 'Lexer Error: {0} at column{1} in expression [{2}].', + error, colStr, this.text); + }, + + readNumber: function() { + var number = ''; + var start = this.index; + while (this.index < this.text.length) { + var ch = lowercase(this.text.charAt(this.index)); + if (ch == '.' || this.isNumber(ch)) { + number += ch; + } else { + var peekCh = this.peek(); + if (ch == 'e' && this.isExpOperator(peekCh)) { + number += ch; + } else if (this.isExpOperator(ch) && + peekCh && this.isNumber(peekCh) && + number.charAt(number.length - 1) == 'e') { + number += ch; + } else if (this.isExpOperator(ch) && + (!peekCh || !this.isNumber(peekCh)) && + number.charAt(number.length - 1) == 'e') { + this.throwError('Invalid exponent'); + } else { + break; + } + } + this.index++; + } + number = 1 * number; + this.tokens.push({ + index: start, + text: number, + json: true, + fn: function() { return number; } + }); + }, + + readIdent: function() { + var parser = this; + + var ident = ''; + var start = this.index; + + var lastDot, peekIndex, methodName, ch; + + while (this.index < this.text.length) { + ch = this.text.charAt(this.index); + if (ch === '.' || this.isIdent(ch) || this.isNumber(ch)) { + if (ch === '.') lastDot = this.index; + ident += ch; + } else { + break; + } + this.index++; + } + + //check if this is not a method invocation and if it is back out to last dot + if (lastDot) { + peekIndex = this.index; + while (peekIndex < this.text.length) { + ch = this.text.charAt(peekIndex); + if (ch === '(') { + methodName = ident.substr(lastDot - start + 1); + ident = ident.substr(0, lastDot - start); + this.index = peekIndex; + break; + } + if (this.isWhitespace(ch)) { + peekIndex++; + } else { + break; + } + } + } + + + var token = { + index: start, + text: ident + }; + + // OPERATORS is our own object so we don't need to use special hasOwnPropertyFn + if (OPERATORS.hasOwnProperty(ident)) { + token.fn = OPERATORS[ident]; + token.json = OPERATORS[ident]; + } else { + var getter = getterFn(ident, this.options, this.text); + token.fn = extend(function(self, locals) { + return (getter(self, locals)); + }, { + assign: function(self, value) { + return setter(self, ident, value, parser.text, parser.options); + } + }); + } + + this.tokens.push(token); + + if (methodName) { + this.tokens.push({ + index:lastDot, + text: '.', + json: false + }); + this.tokens.push({ + index: lastDot + 1, + text: methodName, + json: false + }); + } + }, + + readString: function(quote) { + var start = this.index; + this.index++; + var string = ''; + var rawString = quote; + var escape = false; + while (this.index < this.text.length) { + var ch = this.text.charAt(this.index); + rawString += ch; + if (escape) { + if (ch === 'u') { + var hex = this.text.substring(this.index + 1, this.index + 5); + if (!hex.match(/[\da-f]{4}/i)) + this.throwError('Invalid unicode escape [\\u' + hex + ']'); + this.index += 4; + string += String.fromCharCode(parseInt(hex, 16)); + } else { + var rep = ESCAPE[ch]; + if (rep) { + string += rep; + } else { + string += ch; + } + } + escape = false; + } else if (ch === '\\') { + escape = true; + } else if (ch === quote) { + this.index++; + this.tokens.push({ + index: start, + text: rawString, + string: string, + json: true, + fn: function() { return string; } + }); + return; + } else { + string += ch; + } + this.index++; + } + this.throwError('Unterminated quote', start); + } +}; + + +/** + * @constructor + */ +var Parser = function (lexer, $filter, options) { + this.lexer = lexer; + this.$filter = $filter; + this.options = options; +}; + +Parser.ZERO = function () { return 0; }; + +Parser.prototype = { + constructor: Parser, + + parse: function (text, json) { + this.text = text; + + //TODO(i): strip all the obsolte json stuff from this file + this.json = json; + + this.tokens = this.lexer.lex(text); + + if (json) { + // The extra level of aliasing is here, just in case the lexer misses something, so that + // we prevent any accidental execution in JSON. + this.assignment = this.logicalOR; + + this.functionCall = + this.fieldAccess = + this.objectIndex = + this.filterChain = function() { + this.throwError('is not valid json', {text: text, index: 0}); + }; + } + + var value = json ? this.primary() : this.statements(); + + if (this.tokens.length !== 0) { + this.throwError('is an unexpected token', this.tokens[0]); + } + + value.literal = !!value.literal; + value.constant = !!value.constant; + + return value; + }, + + primary: function () { + var primary; + if (this.expect('(')) { + primary = this.filterChain(); + this.consume(')'); + } else if (this.expect('[')) { + primary = this.arrayDeclaration(); + } else if (this.expect('{')) { + primary = this.object(); + } else { + var token = this.expect(); + primary = token.fn; + if (!primary) { + this.throwError('not a primary expression', token); + } + if (token.json) { + primary.constant = true; + primary.literal = true; + } + } + + var next, context; + while ((next = this.expect('(', '[', '.'))) { + if (next.text === '(') { + primary = this.functionCall(primary, context); + context = null; + } else if (next.text === '[') { + context = primary; + primary = this.objectIndex(primary); + } else if (next.text === '.') { + context = primary; + primary = this.fieldAccess(primary); + } else { + this.throwError('IMPOSSIBLE'); + } + } + return primary; + }, + + throwError: function(msg, token) { + throw $parseMinErr('syntax', + 'Syntax Error: Token \'{0}\' {1} at column {2} of the expression [{3}] starting at [{4}].', + token.text, msg, (token.index + 1), this.text, this.text.substring(token.index)); + }, + + peekToken: function() { + if (this.tokens.length === 0) + throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text); + return this.tokens[0]; + }, + + peek: function(e1, e2, e3, e4) { + if (this.tokens.length > 0) { + var token = this.tokens[0]; + var t = token.text; + if (t === e1 || t === e2 || t === e3 || t === e4 || + (!e1 && !e2 && !e3 && !e4)) { + return token; + } + } + return false; + }, + + expect: function(e1, e2, e3, e4){ + var token = this.peek(e1, e2, e3, e4); + if (token) { + if (this.json && !token.json) { + this.throwError('is not valid json', token); + } + this.tokens.shift(); + return token; + } + return false; + }, + + consume: function(e1){ + if (!this.expect(e1)) { + this.throwError('is unexpected, expecting [' + e1 + ']', this.peek()); + } + }, + + unaryFn: function(fn, right) { + return extend(function(self, locals) { + return fn(self, locals, right); + }, { + constant:right.constant + }); + }, + + ternaryFn: function(left, middle, right){ + return extend(function(self, locals){ + return left(self, locals) ? middle(self, locals) : right(self, locals); + }, { + constant: left.constant && middle.constant && right.constant + }); + }, + + binaryFn: function(left, fn, right) { + return extend(function(self, locals) { + return fn(self, locals, left, right); + }, { + constant:left.constant && right.constant + }); + }, + + statements: function() { + var statements = []; + while (true) { + if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']')) + statements.push(this.filterChain()); + if (!this.expect(';')) { + // optimize for the common case where there is only one statement. + // TODO(size): maybe we should not support multiple statements? + return (statements.length === 1) + ? statements[0] + : function(self, locals) { + var value; + for (var i = 0; i < statements.length; i++) { + var statement = statements[i]; + if (statement) { + value = statement(self, locals); + } + } + return value; + }; + } + } + }, + + filterChain: function() { + var left = this.expression(); + var token; + while (true) { + if ((token = this.expect('|'))) { + left = this.binaryFn(left, token.fn, this.filter()); + } else { + return left; + } + } + }, + + filter: function() { + var token = this.expect(); + var fn = this.$filter(token.text); + var argsFn = []; + while (true) { + if ((token = this.expect(':'))) { + argsFn.push(this.expression()); + } else { + var fnInvoke = function(self, locals, input) { + var args = [input]; + for (var i = 0; i < argsFn.length; i++) { + args.push(argsFn[i](self, locals)); + } + return fn.apply(self, args); + }; + return function() { + return fnInvoke; + }; + } + } + }, + + expression: function() { + return this.assignment(); + }, + + assignment: function() { + var left = this.ternary(); + var right; + var token; + if ((token = this.expect('='))) { + if (!left.assign) { + this.throwError('implies assignment but [' + + this.text.substring(0, token.index) + '] can not be assigned to', token); + } + right = this.ternary(); + return function(scope, locals) { + return left.assign(scope, right(scope, locals), locals); + }; + } + return left; + }, + + ternary: function() { + var left = this.logicalOR(); + var middle; + var token; + if ((token = this.expect('?'))) { + middle = this.ternary(); + if ((token = this.expect(':'))) { + return this.ternaryFn(left, middle, this.ternary()); + } else { + this.throwError('expected :', token); + } + } else { + return left; + } + }, + + logicalOR: function() { + var left = this.logicalAND(); + var token; + while (true) { + if ((token = this.expect('||'))) { + left = this.binaryFn(left, token.fn, this.logicalAND()); + } else { + return left; + } + } + }, + + logicalAND: function() { + var left = this.equality(); + var token; + if ((token = this.expect('&&'))) { + left = this.binaryFn(left, token.fn, this.logicalAND()); + } + return left; + }, + + equality: function() { + var left = this.relational(); + var token; + if ((token = this.expect('==','!=','===','!=='))) { + left = this.binaryFn(left, token.fn, this.equality()); + } + return left; + }, + + relational: function() { + var left = this.additive(); + var token; + if ((token = this.expect('<', '>', '<=', '>='))) { + left = this.binaryFn(left, token.fn, this.relational()); + } + return left; + }, + + additive: function() { + var left = this.multiplicative(); + var token; + while ((token = this.expect('+','-'))) { + left = this.binaryFn(left, token.fn, this.multiplicative()); + } + return left; + }, + + multiplicative: function() { + var left = this.unary(); + var token; + while ((token = this.expect('*','/','%'))) { + left = this.binaryFn(left, token.fn, this.unary()); + } + return left; + }, + + unary: function() { + var token; + if (this.expect('+')) { + return this.primary(); + } else if ((token = this.expect('-'))) { + return this.binaryFn(Parser.ZERO, token.fn, this.unary()); + } else if ((token = this.expect('!'))) { + return this.unaryFn(token.fn, this.unary()); + } else { + return this.primary(); + } + }, + + fieldAccess: function(object) { + var parser = this; + var field = this.expect().text; + var getter = getterFn(field, this.options, this.text); + + return extend(function(scope, locals, self) { + return getter(self || object(scope, locals), locals); + }, { + assign: function(scope, value, locals) { + return setter(object(scope, locals), field, value, parser.text, parser.options); + } + }); + }, + + objectIndex: function(obj) { + var parser = this; + + var indexFn = this.expression(); + this.consume(']'); + + return extend(function(self, locals) { + var o = obj(self, locals), + i = indexFn(self, locals), + v, p; + + if (!o) return undefined; + v = ensureSafeObject(o[i], parser.text); + if (v && v.then && parser.options.unwrapPromises) { + p = v; + if (!('$$v' in v)) { + p.$$v = undefined; + p.then(function(val) { p.$$v = val; }); + } + v = v.$$v; + } + return v; + }, { + assign: function(self, value, locals) { + var key = indexFn(self, locals); + // prevent overwriting of Function.constructor which would break ensureSafeObject check + var safe = ensureSafeObject(obj(self, locals), parser.text); + return safe[key] = value; + } + }); + }, + + functionCall: function(fn, contextGetter) { + var argsFn = []; + if (this.peekToken().text !== ')') { + do { + argsFn.push(this.expression()); + } while (this.expect(',')); + } + this.consume(')'); + + var parser = this; + + return function(scope, locals) { + var args = []; + var context = contextGetter ? contextGetter(scope, locals) : scope; + + for (var i = 0; i < argsFn.length; i++) { + args.push(argsFn[i](scope, locals)); + } + var fnPtr = fn(scope, locals, context) || noop; + + ensureSafeObject(context, parser.text); + ensureSafeObject(fnPtr, parser.text); + + // IE stupidity! (IE doesn't have apply for some native functions) + var v = fnPtr.apply + ? fnPtr.apply(context, args) + : fnPtr(args[0], args[1], args[2], args[3], args[4]); + + return ensureSafeObject(v, parser.text); + }; + }, + + // This is used with json array declaration + arrayDeclaration: function () { + var elementFns = []; + var allConstant = true; + if (this.peekToken().text !== ']') { + do { + var elementFn = this.expression(); + elementFns.push(elementFn); + if (!elementFn.constant) { + allConstant = false; + } + } while (this.expect(',')); + } + this.consume(']'); + + return extend(function(self, locals) { + var array = []; + for (var i = 0; i < elementFns.length; i++) { + array.push(elementFns[i](self, locals)); + } + return array; + }, { + literal: true, + constant: allConstant + }); + }, + + object: function () { + var keyValues = []; + var allConstant = true; + if (this.peekToken().text !== '}') { + do { + var token = this.expect(), + key = token.string || token.text; + this.consume(':'); + var value = this.expression(); + keyValues.push({key: key, value: value}); + if (!value.constant) { + allConstant = false; + } + } while (this.expect(',')); + } + this.consume('}'); + + return extend(function(self, locals) { + var object = {}; + for (var i = 0; i < keyValues.length; i++) { + var keyValue = keyValues[i]; + object[keyValue.key] = keyValue.value(self, locals); + } + return object; + }, { + literal: true, + constant: allConstant + }); + } +}; + + +////////////////////////////////////////////////// +// Parser helper functions +////////////////////////////////////////////////// + +function setter(obj, path, setValue, fullExp, options) { + //needed? + options = options || {}; + + var element = path.split('.'), key; + for (var i = 0; element.length > 1; i++) { + key = ensureSafeMemberName(element.shift(), fullExp); + var propertyObj = obj[key]; + if (!propertyObj) { + propertyObj = {}; + obj[key] = propertyObj; + } + obj = propertyObj; + if (obj.then && options.unwrapPromises) { + promiseWarning(fullExp); + if (!("$$v" in obj)) { + (function(promise) { + promise.then(function(val) { promise.$$v = val; }); } + )(obj); + } + if (obj.$$v === undefined) { + obj.$$v = {}; + } + obj = obj.$$v; + } + } + key = ensureSafeMemberName(element.shift(), fullExp); + obj[key] = setValue; + return setValue; +} + +var getterFnCache = {}; + +/** + * Implementation of the "Black Hole" variant from: + * - http://jsperf.com/angularjs-parse-getter/4 + * - http://jsperf.com/path-evaluation-simplified/7 + */ +function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { + ensureSafeMemberName(key0, fullExp); + ensureSafeMemberName(key1, fullExp); + ensureSafeMemberName(key2, fullExp); + ensureSafeMemberName(key3, fullExp); + ensureSafeMemberName(key4, fullExp); + + return !options.unwrapPromises + ? function cspSafeGetter(scope, locals) { + var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope; + + if (pathVal === null || pathVal === undefined) return pathVal; + pathVal = pathVal[key0]; + + if (!key1 || pathVal === null || pathVal === undefined) return pathVal; + pathVal = pathVal[key1]; + + if (!key2 || pathVal === null || pathVal === undefined) return pathVal; + pathVal = pathVal[key2]; + + if (!key3 || pathVal === null || pathVal === undefined) return pathVal; + pathVal = pathVal[key3]; + + if (!key4 || pathVal === null || pathVal === undefined) return pathVal; + pathVal = pathVal[key4]; + + return pathVal; + } + : function cspSafePromiseEnabledGetter(scope, locals) { + var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope, + promise; + + if (pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key0]; + if (pathVal && pathVal.then) { + promiseWarning(fullExp); + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key1 || pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key1]; + if (pathVal && pathVal.then) { + promiseWarning(fullExp); + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key2 || pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key2]; + if (pathVal && pathVal.then) { + promiseWarning(fullExp); + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key3 || pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key3]; + if (pathVal && pathVal.then) { + promiseWarning(fullExp); + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key4 || pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key4]; + if (pathVal && pathVal.then) { + promiseWarning(fullExp); + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + return pathVal; + }; +} + +function getterFn(path, options, fullExp) { + // Check whether the cache has this getter already. + // We can use hasOwnProperty directly on the cache because we ensure, + // see below, that the cache never stores a path called 'hasOwnProperty' + if (getterFnCache.hasOwnProperty(path)) { + return getterFnCache[path]; + } + + var pathKeys = path.split('.'), + pathKeysLength = pathKeys.length, + fn; + + if (options.csp) { + if (pathKeysLength < 6) { + fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, + options); + } else { + fn = function(scope, locals) { + var i = 0, val; + do { + val = cspSafeGetterFn(pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], + pathKeys[i++], fullExp, options)(scope, locals); + + locals = undefined; // clear after first iteration + scope = val; + } while (i < pathKeysLength); + return val; + }; + } + } else { + var code = 'var l, fn, p;\n'; + forEach(pathKeys, function(key, index) { + ensureSafeMemberName(key, fullExp); + code += 'if(s === null || s === undefined) return s;\n' + + 'l=s;\n' + + 's='+ (index + // we simply dereference 's' on any .dot notation + ? 's' + // but if we are first then we check locals first, and if so read it first + : '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' + + (options.unwrapPromises + ? 'if (s && s.then) {\n' + + ' pw("' + fullExp.replace(/(["\r\n])/g, '\\$1') + '");\n' + + ' if (!("$$v" in s)) {\n' + + ' p=s;\n' + + ' p.$$v = undefined;\n' + + ' p.then(function(v) {p.$$v=v;});\n' + + '}\n' + + ' s=s.$$v\n' + + '}\n' + : ''); + }); + code += 'return s;'; + + /* jshint -W054 */ + var evaledFnGetter = new Function('s', 'k', 'pw', code); // s=scope, k=locals, pw=promiseWarning + /* jshint +W054 */ + evaledFnGetter.toString = function() { return code; }; + fn = function(scope, locals) { + return evaledFnGetter(scope, locals, promiseWarning); + }; + } + + // Only cache the value if it's not going to mess up the cache object + // This is more performant that using Object.prototype.hasOwnProperty.call + if (path !== 'hasOwnProperty') { + getterFnCache[path] = fn; + } + return fn; +} + +/////////////////////////////////// + +/** + * @ngdoc function + * @name ng.$parse + * @function + * + * @description + * + * Converts Angular {@link guide/expression expression} into a function. + * + *
+ *   var getter = $parse('user.name');
+ *   var setter = getter.assign;
+ *   var context = {user:{name:'angular'}};
+ *   var locals = {user:{name:'local'}};
+ *
+ *   expect(getter(context)).toEqual('angular');
+ *   setter(context, 'newValue');
+ *   expect(context.user.name).toEqual('newValue');
+ *   expect(getter(context, locals)).toEqual('local');
+ * 
+ * + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + * + * The returned function also has the following properties: + * * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript + * literal. + * * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript + * constant literals. + * * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be + * set to a function to change its value on the given context. + * + */ + + +/** + * @ngdoc object + * @name ng.$parseProvider + * @function + * + * @description + * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse} + * service. + */ +function $ParseProvider() { + var cache = {}; + + var $parseOptions = { + csp: false, + unwrapPromises: false, + logPromiseWarnings: true + }; + + + /** + * @deprecated Promise unwrapping via $parse is deprecated and will be removed in the future. + * + * @ngdoc method + * @name ng.$parseProvider#unwrapPromises + * @methodOf ng.$parseProvider + * @description + * + * **This feature is deprecated, see deprecation notes below for more info** + * + * If set to true (default is false), $parse will unwrap promises automatically when a promise is + * found at any part of the expression. In other words, if set to true, the expression will always + * result in a non-promise value. + * + * While the promise is unresolved, it's treated as undefined, but once resolved and fulfilled, + * the fulfillment value is used in place of the promise while evaluating the expression. + * + * **Deprecation notice** + * + * This is a feature that didn't prove to be wildly useful or popular, primarily because of the + * dichotomy between data access in templates (accessed as raw values) and controller code + * (accessed as promises). + * + * In most code we ended up resolving promises manually in controllers anyway and thus unifying + * the model access there. + * + * Other downsides of automatic promise unwrapping: + * + * - when building components it's often desirable to receive the raw promises + * - adds complexity and slows down expression evaluation + * - makes expression code pre-generation unattractive due to the amount of code that needs to be + * generated + * - makes IDE auto-completion and tool support hard + * + * **Warning Logs** + * + * If the unwrapping is enabled, Angular will log a warning about each expression that unwraps a + * promise (to reduce the noise, each expression is logged only once). To disable this logging use + * `$parseProvider.logPromiseWarnings(false)` api. + * + * + * @param {boolean=} value New value. + * @returns {boolean|self} Returns the current setting when used as getter and self if used as + * setter. + */ + this.unwrapPromises = function(value) { + if (isDefined(value)) { + $parseOptions.unwrapPromises = !!value; + return this; + } else { + return $parseOptions.unwrapPromises; + } + }; + + + /** + * @deprecated Promise unwrapping via $parse is deprecated and will be removed in the future. + * + * @ngdoc method + * @name ng.$parseProvider#logPromiseWarnings + * @methodOf ng.$parseProvider + * @description + * + * Controls whether Angular should log a warning on any encounter of a promise in an expression. + * + * The default is set to `true`. + * + * This setting applies only if `$parseProvider.unwrapPromises` setting is set to true as well. + * + * @param {boolean=} value New value. + * @returns {boolean|self} Returns the current setting when used as getter and self if used as + * setter. + */ + this.logPromiseWarnings = function(value) { + if (isDefined(value)) { + $parseOptions.logPromiseWarnings = value; + return this; + } else { + return $parseOptions.logPromiseWarnings; + } + }; + + + this.$get = ['$filter', '$sniffer', '$log', function($filter, $sniffer, $log) { + $parseOptions.csp = $sniffer.csp; + + promiseWarning = function promiseWarningFn(fullExp) { + if (!$parseOptions.logPromiseWarnings || promiseWarningCache.hasOwnProperty(fullExp)) return; + promiseWarningCache[fullExp] = true; + $log.warn('[$parse] Promise found in the expression `' + fullExp + '`. ' + + 'Automatic unwrapping of promises in Angular expressions is deprecated.'); + }; + + return function(exp) { + var parsedExpression; + + switch (typeof exp) { + case 'string': + + if (cache.hasOwnProperty(exp)) { + return cache[exp]; + } + + var lexer = new Lexer($parseOptions); + var parser = new Parser(lexer, $filter, $parseOptions); + parsedExpression = parser.parse(exp, false); + + if (exp !== 'hasOwnProperty') { + // Only cache the value if it's not going to mess up the cache object + // This is more performant that using Object.prototype.hasOwnProperty.call + cache[exp] = parsedExpression; + } + + return parsedExpression; + + case 'function': + return exp; + + default: + return noop; + } + }; + }]; +} + +/** + * @ngdoc service + * @name ng.$q + * @requires $rootScope + * + * @description + * A promise/deferred implementation inspired by [Kris Kowal's Q](https://github.com/kriskowal/q). + * + * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an + * interface for interacting with an object that represents the result of an action that is + * performed asynchronously, and may or may not be finished at any given point in time. + * + * From the perspective of dealing with error handling, deferred and promise APIs are to + * asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming. + * + *
+ *   // for the purpose of this example let's assume that variables `$q` and `scope` are
+ *   // available in the current lexical scope (they could have been injected or passed in).
+ *
+ *   function asyncGreet(name) {
+ *     var deferred = $q.defer();
+ *
+ *     setTimeout(function() {
+ *       // since this fn executes async in a future turn of the event loop, we need to wrap
+ *       // our code into an $apply call so that the model changes are properly observed.
+ *       scope.$apply(function() {
+ *         deferred.notify('About to greet ' + name + '.');
+ *
+ *         if (okToGreet(name)) {
+ *           deferred.resolve('Hello, ' + name + '!');
+ *         } else {
+ *           deferred.reject('Greeting ' + name + ' is not allowed.');
+ *         }
+ *       });
+ *     }, 1000);
+ *
+ *     return deferred.promise;
+ *   }
+ *
+ *   var promise = asyncGreet('Robin Hood');
+ *   promise.then(function(greeting) {
+ *     alert('Success: ' + greeting);
+ *   }, function(reason) {
+ *     alert('Failed: ' + reason);
+ *   }, function(update) {
+ *     alert('Got notification: ' + update);
+ *   });
+ * 
+ * + * At first it might not be obvious why this extra complexity is worth the trouble. The payoff + * comes in the way of guarantees that promise and deferred APIs make, see + * https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md. + * + * Additionally the promise api allows for composition that is very hard to do with the + * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach. + * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the + * section on serial or parallel joining of promises. + * + * + * # The Deferred API + * + * A new instance of deferred is constructed by calling `$q.defer()`. + * + * The purpose of the deferred object is to expose the associated Promise instance as well as APIs + * that can be used for signaling the successful or unsuccessful completion, as well as the status + * of the task. + * + * **Methods** + * + * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection + * constructed via `$q.reject`, the promise will be rejected instead. + * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to + * resolving it with a rejection constructed via `$q.reject`. + * - `notify(value)` - provides updates on the status of the promises execution. This may be called + * multiple times before the promise is either resolved or rejected. + * + * **Properties** + * + * - promise – `{Promise}` – promise object associated with this deferred. + * + * + * # The Promise API + * + * A new promise instance is created when a deferred instance is created and can be retrieved by + * calling `deferred.promise`. + * + * The purpose of the promise object is to allow for interested parties to get access to the result + * of the deferred task when it completes. + * + * **Methods** + * + * - `then(successCallback, errorCallback, notifyCallback)` – regardless of when the promise was or + * will be resolved or rejected, `then` calls one of the success or error callbacks asynchronously + * as soon as the result is available. The callbacks are called with a single argument: the result + * or rejection reason. Additionally, the notify callback may be called zero or more times to + * provide a progress indication, before the promise is resolved or rejected. + * + * This method *returns a new promise* which is resolved or rejected via the return value of the + * `successCallback`, `errorCallback`. It also notifies via the return value of the + * `notifyCallback` method. The promise can not be resolved or rejected from the notifyCallback + * method. + * + * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)` + * + * - `finally(callback)` – allows you to observe either the fulfillment or rejection of a promise, + * but to do so without modifying the final value. This is useful to release resources or do some + * clean-up that needs to be done whether the promise was rejected or resolved. See the [full + * specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for + * more information. + * + * Because `finally` is a reserved word in JavaScript and reserved keywords are not supported as + * property names by ES3, you'll need to invoke the method like `promise['finally'](callback)` to + * make your code IE8 compatible. + * + * # Chaining promises + * + * Because calling the `then` method of a promise returns a new derived promise, it is easily + * possible to create a chain of promises: + * + *
+ *   promiseB = promiseA.then(function(result) {
+ *     return result + 1;
+ *   });
+ *
+ *   // promiseB will be resolved immediately after promiseA is resolved and its value
+ *   // will be the result of promiseA incremented by 1
+ * 
+ * + * It is possible to create chains of any length and since a promise can be resolved with another + * promise (which will defer its resolution further), it is possible to pause/defer resolution of + * the promises at any point in the chain. This makes it possible to implement powerful APIs like + * $http's response interceptors. + * + * + * # Differences between Kris Kowal's Q and $q + * + * There are three main differences: + * + * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation + * mechanism in angular, which means faster propagation of resolution or rejection into your + * models and avoiding unnecessary browser repaints, which would result in flickering UI. + * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains + * all the important functionality needed for common async tasks. + * + * # Testing + * + *
+ *    it('should simulate promise', inject(function($q, $rootScope) {
+ *      var deferred = $q.defer();
+ *      var promise = deferred.promise;
+ *      var resolvedValue;
+ *
+ *      promise.then(function(value) { resolvedValue = value; });
+ *      expect(resolvedValue).toBeUndefined();
+ *
+ *      // Simulate resolving of promise
+ *      deferred.resolve(123);
+ *      // Note that the 'then' function does not get called synchronously.
+ *      // This is because we want the promise API to always be async, whether or not
+ *      // it got called synchronously or asynchronously.
+ *      expect(resolvedValue).toBeUndefined();
+ *
+ *      // Propagate promise resolution to 'then' functions using $apply().
+ *      $rootScope.$apply();
+ *      expect(resolvedValue).toEqual(123);
+ *    }));
+ *  
+ */ +function $QProvider() { + + this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) { + return qFactory(function(callback) { + $rootScope.$evalAsync(callback); + }, $exceptionHandler); + }]; +} + + +/** + * Constructs a promise manager. + * + * @param {function(function)} nextTick Function for executing functions in the next turn. + * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for + * debugging purposes. + * @returns {object} Promise manager. + */ +function qFactory(nextTick, exceptionHandler) { + + /** + * @ngdoc + * @name ng.$q#defer + * @methodOf ng.$q + * @description + * Creates a `Deferred` object which represents a task which will finish in the future. + * + * @returns {Deferred} Returns a new instance of deferred. + */ + var defer = function() { + var pending = [], + value, deferred; + + deferred = { + + resolve: function(val) { + if (pending) { + var callbacks = pending; + pending = undefined; + value = ref(val); + + if (callbacks.length) { + nextTick(function() { + var callback; + for (var i = 0, ii = callbacks.length; i < ii; i++) { + callback = callbacks[i]; + value.then(callback[0], callback[1], callback[2]); + } + }); + } + } + }, + + + reject: function(reason) { + deferred.resolve(reject(reason)); + }, + + + notify: function(progress) { + if (pending) { + var callbacks = pending; + + if (pending.length) { + nextTick(function() { + var callback; + for (var i = 0, ii = callbacks.length; i < ii; i++) { + callback = callbacks[i]; + callback[2](progress); + } + }); + } + } + }, + + + promise: { + then: function(callback, errback, progressback) { + var result = defer(); + + var wrappedCallback = function(value) { + try { + result.resolve((isFunction(callback) ? callback : defaultCallback)(value)); + } catch(e) { + result.reject(e); + exceptionHandler(e); + } + }; + + var wrappedErrback = function(reason) { + try { + result.resolve((isFunction(errback) ? errback : defaultErrback)(reason)); + } catch(e) { + result.reject(e); + exceptionHandler(e); + } + }; + + var wrappedProgressback = function(progress) { + try { + result.notify((isFunction(progressback) ? progressback : defaultCallback)(progress)); + } catch(e) { + exceptionHandler(e); + } + }; + + if (pending) { + pending.push([wrappedCallback, wrappedErrback, wrappedProgressback]); + } else { + value.then(wrappedCallback, wrappedErrback, wrappedProgressback); + } + + return result.promise; + }, + + "catch": function(callback) { + return this.then(null, callback); + }, + + "finally": function(callback) { + + function makePromise(value, resolved) { + var result = defer(); + if (resolved) { + result.resolve(value); + } else { + result.reject(value); + } + return result.promise; + } + + function handleCallback(value, isResolved) { + var callbackOutput = null; + try { + callbackOutput = (callback ||defaultCallback)(); + } catch(e) { + return makePromise(e, false); + } + if (callbackOutput && isFunction(callbackOutput.then)) { + return callbackOutput.then(function() { + return makePromise(value, isResolved); + }, function(error) { + return makePromise(error, false); + }); + } else { + return makePromise(value, isResolved); + } + } + + return this.then(function(value) { + return handleCallback(value, true); + }, function(error) { + return handleCallback(error, false); + }); + } + } + }; + + return deferred; + }; + + + var ref = function(value) { + if (value && isFunction(value.then)) return value; + return { + then: function(callback) { + var result = defer(); + nextTick(function() { + result.resolve(callback(value)); + }); + return result.promise; + } + }; + }; + + + /** + * @ngdoc + * @name ng.$q#reject + * @methodOf ng.$q + * @description + * Creates a promise that is resolved as rejected with the specified `reason`. This api should be + * used to forward rejection in a chain of promises. If you are dealing with the last promise in + * a promise chain, you don't need to worry about it. + * + * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of + * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via + * a promise error callback and you want to forward the error to the promise derived from the + * current promise, you have to "rethrow" the error by returning a rejection constructed via + * `reject`. + * + *
+   *   promiseB = promiseA.then(function(result) {
+   *     // success: do something and resolve promiseB
+   *     //          with the old or a new result
+   *     return result;
+   *   }, function(reason) {
+   *     // error: handle the error if possible and
+   *     //        resolve promiseB with newPromiseOrValue,
+   *     //        otherwise forward the rejection to promiseB
+   *     if (canHandle(reason)) {
+   *      // handle the error and recover
+   *      return newPromiseOrValue;
+   *     }
+   *     return $q.reject(reason);
+   *   });
+   * 
+ * + * @param {*} reason Constant, message, exception or an object representing the rejection reason. + * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`. + */ + var reject = function(reason) { + return { + then: function(callback, errback) { + var result = defer(); + nextTick(function() { + try { + result.resolve((isFunction(errback) ? errback : defaultErrback)(reason)); + } catch(e) { + result.reject(e); + exceptionHandler(e); + } + }); + return result.promise; + } + }; + }; + + + /** + * @ngdoc + * @name ng.$q#when + * @methodOf ng.$q + * @description + * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. + * This is useful when you are dealing with an object that might or might not be a promise, or if + * the promise comes from a source that can't be trusted. + * + * @param {*} value Value or a promise + * @returns {Promise} Returns a promise of the passed value or promise + */ + var when = function(value, callback, errback, progressback) { + var result = defer(), + done; + + var wrappedCallback = function(value) { + try { + return (isFunction(callback) ? callback : defaultCallback)(value); + } catch (e) { + exceptionHandler(e); + return reject(e); + } + }; + + var wrappedErrback = function(reason) { + try { + return (isFunction(errback) ? errback : defaultErrback)(reason); + } catch (e) { + exceptionHandler(e); + return reject(e); + } + }; + + var wrappedProgressback = function(progress) { + try { + return (isFunction(progressback) ? progressback : defaultCallback)(progress); + } catch (e) { + exceptionHandler(e); + } + }; + + nextTick(function() { + ref(value).then(function(value) { + if (done) return; + done = true; + result.resolve(ref(value).then(wrappedCallback, wrappedErrback, wrappedProgressback)); + }, function(reason) { + if (done) return; + done = true; + result.resolve(wrappedErrback(reason)); + }, function(progress) { + if (done) return; + result.notify(wrappedProgressback(progress)); + }); + }); + + return result.promise; + }; + + + function defaultCallback(value) { + return value; + } + + + function defaultErrback(reason) { + return reject(reason); + } + + + /** + * @ngdoc + * @name ng.$q#all + * @methodOf ng.$q + * @description + * Combines multiple promises into a single promise that is resolved when all of the input + * promises are resolved. + * + * @param {Array.|Object.} promises An array or hash of promises. + * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values, + * each value corresponding to the promise at the same index/key in the `promises` array/hash. + * If any of the promises is resolved with a rejection, this resulting promise will be rejected + * with the same rejection value. + */ + function all(promises) { + var deferred = defer(), + counter = 0, + results = isArray(promises) ? [] : {}; + + forEach(promises, function(promise, key) { + counter++; + ref(promise).then(function(value) { + if (results.hasOwnProperty(key)) return; + results[key] = value; + if (!(--counter)) deferred.resolve(results); + }, function(reason) { + if (results.hasOwnProperty(key)) return; + deferred.reject(reason); + }); + }); + + if (counter === 0) { + deferred.resolve(results); + } + + return deferred.promise; + } + + return { + defer: defer, + reject: reject, + when: when, + all: all + }; +} + +/** + * DESIGN NOTES + * + * The design decisions behind the scope are heavily favored for speed and memory consumption. + * + * The typical use of scope is to watch the expressions, which most of the time return the same + * value as last time so we optimize the operation. + * + * Closures construction is expensive in terms of speed as well as memory: + * - No closures, instead use prototypical inheritance for API + * - Internal state needs to be stored on scope directly, which means that private state is + * exposed as $$____ properties + * + * Loop operations are optimized by using while(count--) { ... } + * - this means that in order to keep the same order of execution as addition we have to add + * items to the array at the beginning (shift) instead of at the end (push) + * + * Child scopes are created and removed often + * - Using an array would be slow since inserts in middle are expensive so we use linked list + * + * There are few watches then a lot of observers. This is why you don't want the observer to be + * implemented in the same way as watch. Watch requires return of initialization function which + * are expensive to construct. + */ + + +/** + * @ngdoc object + * @name ng.$rootScopeProvider + * @description + * + * Provider for the $rootScope service. + */ + +/** + * @ngdoc function + * @name ng.$rootScopeProvider#digestTtl + * @methodOf ng.$rootScopeProvider + * @description + * + * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and + * assuming that the model is unstable. + * + * The current default is 10 iterations. + * + * In complex applications it's possible that the dependencies between `$watch`s will result in + * several digest iterations. However if an application needs more than the default 10 digest + * iterations for its model to stabilize then you should investigate what is causing the model to + * continuously change during the digest. + * + * Increasing the TTL could have performance implications, so you should not change it without + * proper justification. + * + * @param {number} limit The number of digest iterations. + */ + + +/** + * @ngdoc object + * @name ng.$rootScope + * @description + * + * Every application has a single root {@link ng.$rootScope.Scope scope}. + * All other scopes are descendant scopes of the root scope. Scopes provide separation + * between the model and the view, via a mechanism for watching the model for changes. + * They also provide an event emission/broadcast and subscription facility. See the + * {@link guide/scope developer guide on scopes}. + */ +function $RootScopeProvider(){ + var TTL = 10; + var $rootScopeMinErr = minErr('$rootScope'); + + this.digestTtl = function(value) { + if (arguments.length) { + TTL = value; + } + return TTL; + }; + + this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser', + function( $injector, $exceptionHandler, $parse, $browser) { + + /** + * @ngdoc function + * @name ng.$rootScope.Scope + * + * @description + * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the + * {@link AUTO.$injector $injector}. Child scopes are created using the + * {@link ng.$rootScope.Scope#methods_$new $new()} method. (Most scopes are created automatically when + * compiled HTML template is executed.) + * + * Here is a simple scope snippet to show how you can interact with the scope. + *
+     * 
+     * 
+ * + * # Inheritance + * A scope can inherit from a parent scope, as in this example: + *
+         var parent = $rootScope;
+         var child = parent.$new();
+
+         parent.salutation = "Hello";
+         child.name = "World";
+         expect(child.salutation).toEqual('Hello');
+
+         child.salutation = "Welcome";
+         expect(child.salutation).toEqual('Welcome');
+         expect(parent.salutation).toEqual('Hello');
+     * 
+ * + * + * @param {Object.=} providers Map of service factory which need to be + * provided for the current scope. Defaults to {@link ng}. + * @param {Object.=} instanceCache Provides pre-instantiated services which should + * append/override services provided by `providers`. This is handy + * when unit-testing and having the need to override a default + * service. + * @returns {Object} Newly created scope. + * + */ + function Scope() { + this.$id = nextUid(); + this.$$phase = this.$parent = this.$$watchers = + this.$$nextSibling = this.$$prevSibling = + this.$$childHead = this.$$childTail = null; + this['this'] = this.$root = this; + this.$$destroyed = false; + this.$$asyncQueue = []; + this.$$postDigestQueue = []; + this.$$listeners = {}; + this.$$isolateBindings = {}; + } + + /** + * @ngdoc property + * @name ng.$rootScope.Scope#$id + * @propertyOf ng.$rootScope.Scope + * @returns {number} Unique scope ID (monotonically increasing alphanumeric sequence) useful for + * debugging. + */ + + + Scope.prototype = { + constructor: Scope, + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$new + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Creates a new child {@link ng.$rootScope.Scope scope}. + * + * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} and + * {@link ng.$rootScope.Scope#$digest $digest()} events. The scope can be removed from the + * scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}. + * + * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is + * desired for the scope and its child scopes to be permanently detached from the parent and + * thus stop participating in model change detection and listener notification by invoking. + * + * @param {boolean} isolate If true, then the scope does not prototypically inherit from the + * parent scope. The scope is isolated, as it can not see parent scope properties. + * When creating widgets, it is useful for the widget to not accidentally read parent + * state. + * + * @returns {Object} The newly created child scope. + * + */ + $new: function(isolate) { + var Child, + child; + + if (isolate) { + child = new Scope(); + child.$root = this.$root; + // ensure that there is just one async queue per $rootScope and its children + child.$$asyncQueue = this.$$asyncQueue; + child.$$postDigestQueue = this.$$postDigestQueue; + } else { + Child = function() {}; // should be anonymous; This is so that when the minifier munges + // the name it does not become random set of chars. This will then show up as class + // name in the debugger. + Child.prototype = this; + child = new Child(); + child.$id = nextUid(); + } + child['this'] = child; + child.$$listeners = {}; + child.$parent = this; + child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null; + child.$$prevSibling = this.$$childTail; + if (this.$$childHead) { + this.$$childTail.$$nextSibling = child; + this.$$childTail = child; + } else { + this.$$childHead = this.$$childTail = child; + } + return child; + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$watch + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Registers a `listener` callback to be executed whenever the `watchExpression` changes. + * + * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest + * $digest()} and should return the value that will be watched. (Since + * {@link ng.$rootScope.Scope#$digest $digest()} reruns when it detects changes the + * `watchExpression` can execute multiple times per + * {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.) + * - The `listener` is called only when the value from the current `watchExpression` and the + * previous call to `watchExpression` are not equal (with the exception of the initial run, + * see below). The inequality is determined according to + * {@link angular.equals} function. To save the value of the object for later comparison, + * the {@link angular.copy} function is used. It also means that watching complex options + * will have adverse memory and performance implications. + * - The watch `listener` may change the model, which may trigger other `listener`s to fire. + * This is achieved by rerunning the watchers until no changes are detected. The rerun + * iteration limit is 10 to prevent an infinite loop deadlock. + * + * + * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called, + * you can register a `watchExpression` function with no `listener`. (Since `watchExpression` + * can execute multiple times per {@link ng.$rootScope.Scope#$digest $digest} cycle when a + * change is detected, be prepared for multiple calls to your listener.) + * + * After a watcher is registered with the scope, the `listener` fn is called asynchronously + * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the + * watcher. In rare cases, this is undesirable because the listener is called when the result + * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you + * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the + * listener was called due to initialization. + * + * The example below contains an illustration of using a function as your $watch listener + * + * + * # Example + *
+           // let's assume that scope was dependency injected as the $rootScope
+           var scope = $rootScope;
+           scope.name = 'misko';
+           scope.counter = 0;
+
+           expect(scope.counter).toEqual(0);
+           scope.$watch('name', function(newValue, oldValue) {
+             scope.counter = scope.counter + 1;
+           });
+           expect(scope.counter).toEqual(0);
+
+           scope.$digest();
+           // no variable change
+           expect(scope.counter).toEqual(0);
+
+           scope.name = 'adam';
+           scope.$digest();
+           expect(scope.counter).toEqual(1);
+
+
+
+           // Using a listener function
+           var food;
+           scope.foodCounter = 0;
+           expect(scope.foodCounter).toEqual(0);
+           scope.$watch(
+             // This is the listener function
+             function() { return food; },
+             // This is the change handler
+             function(newValue, oldValue) {
+               if ( newValue !== oldValue ) {
+                 // Only increment the counter if the value changed
+                 scope.foodCounter = scope.foodCounter + 1;
+               }
+             }
+           );
+           // No digest has been run so the counter will be zero
+           expect(scope.foodCounter).toEqual(0);
+
+           // Run the digest but since food has not changed cout will still be zero
+           scope.$digest();
+           expect(scope.foodCounter).toEqual(0);
+
+           // Update food and run digest.  Now the counter will increment
+           food = 'cheeseburger';
+           scope.$digest();
+           expect(scope.foodCounter).toEqual(1);
+
+       * 
+ * + * + * + * @param {(function()|string)} watchExpression Expression that is evaluated on each + * {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers + * a call to the `listener`. + * + * - `string`: Evaluated as {@link guide/expression expression} + * - `function(scope)`: called with current `scope` as a parameter. + * @param {(function()|string)=} listener Callback called whenever the return value of + * the `watchExpression` changes. + * + * - `string`: Evaluated as {@link guide/expression expression} + * - `function(newValue, oldValue, scope)`: called with current and previous values as + * parameters. + * + * @param {boolean=} objectEquality Compare object for equality rather than for reference. + * @returns {function()} Returns a deregistration function for this listener. + */ + $watch: function(watchExp, listener, objectEquality) { + var scope = this, + get = compileToFn(watchExp, 'watch'), + array = scope.$$watchers, + watcher = { + fn: listener, + last: initWatchVal, + get: get, + exp: watchExp, + eq: !!objectEquality + }; + + // in the case user pass string, we need to compile it, do we really need this ? + if (!isFunction(listener)) { + var listenFn = compileToFn(listener || noop, 'listener'); + watcher.fn = function(newVal, oldVal, scope) {listenFn(scope);}; + } + + if (typeof watchExp == 'string' && get.constant) { + var originalFn = watcher.fn; + watcher.fn = function(newVal, oldVal, scope) { + originalFn.call(this, newVal, oldVal, scope); + arrayRemove(array, watcher); + }; + } + + if (!array) { + array = scope.$$watchers = []; + } + // we use unshift since we use a while loop in $digest for speed. + // the while loop reads in reverse order. + array.unshift(watcher); + + return function() { + arrayRemove(array, watcher); + }; + }, + + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$watchCollection + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Shallow watches the properties of an object and fires whenever any of the properties change + * (for arrays, this implies watching the array items; for object maps, this implies watching + * the properties). If a change is detected, the `listener` callback is fired. + * + * - The `obj` collection is observed via standard $watch operation and is examined on every + * call to $digest() to see if any items have been added, removed, or moved. + * - The `listener` is called whenever anything within the `obj` has changed. Examples include + * adding, removing, and moving items belonging to an object or array. + * + * + * # Example + *
+          $scope.names = ['igor', 'matias', 'misko', 'james'];
+          $scope.dataCount = 4;
+
+          $scope.$watchCollection('names', function(newNames, oldNames) {
+            $scope.dataCount = newNames.length;
+          });
+
+          expect($scope.dataCount).toEqual(4);
+          $scope.$digest();
+
+          //still at 4 ... no changes
+          expect($scope.dataCount).toEqual(4);
+
+          $scope.names.pop();
+          $scope.$digest();
+
+          //now there's been a change
+          expect($scope.dataCount).toEqual(3);
+       * 
+ * + * + * @param {string|Function(scope)} obj Evaluated as {@link guide/expression expression}. The + * expression value should evaluate to an object or an array which is observed on each + * {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the + * collection will trigger a call to the `listener`. + * + * @param {function(newCollection, oldCollection, scope)} listener a callback function that is + * fired with both the `newCollection` and `oldCollection` as parameters. + * The `newCollection` object is the newly modified data obtained from the `obj` expression + * and the `oldCollection` object is a copy of the former collection data. + * The `scope` refers to the current scope. + * + * @returns {function()} Returns a de-registration function for this listener. When the + * de-registration function is executed, the internal watch operation is terminated. + */ + $watchCollection: function(obj, listener) { + var self = this; + var oldValue; + var newValue; + var changeDetected = 0; + var objGetter = $parse(obj); + var internalArray = []; + var internalObject = {}; + var oldLength = 0; + + function $watchCollectionWatch() { + newValue = objGetter(self); + var newLength, key; + + if (!isObject(newValue)) { + if (oldValue !== newValue) { + oldValue = newValue; + changeDetected++; + } + } else if (isArrayLike(newValue)) { + if (oldValue !== internalArray) { + // we are transitioning from something which was not an array into array. + oldValue = internalArray; + oldLength = oldValue.length = 0; + changeDetected++; + } + + newLength = newValue.length; + + if (oldLength !== newLength) { + // if lengths do not match we need to trigger change notification + changeDetected++; + oldValue.length = oldLength = newLength; + } + // copy the items to oldValue and look for changes. + for (var i = 0; i < newLength; i++) { + if (oldValue[i] !== newValue[i]) { + changeDetected++; + oldValue[i] = newValue[i]; + } + } + } else { + if (oldValue !== internalObject) { + // we are transitioning from something which was not an object into object. + oldValue = internalObject = {}; + oldLength = 0; + changeDetected++; + } + // copy the items to oldValue and look for changes. + newLength = 0; + for (key in newValue) { + if (newValue.hasOwnProperty(key)) { + newLength++; + if (oldValue.hasOwnProperty(key)) { + if (oldValue[key] !== newValue[key]) { + changeDetected++; + oldValue[key] = newValue[key]; + } + } else { + oldLength++; + oldValue[key] = newValue[key]; + changeDetected++; + } + } + } + if (oldLength > newLength) { + // we used to have more keys, need to find them and destroy them. + changeDetected++; + for(key in oldValue) { + if (oldValue.hasOwnProperty(key) && !newValue.hasOwnProperty(key)) { + oldLength--; + delete oldValue[key]; + } + } + } + } + return changeDetected; + } + + function $watchCollectionAction() { + listener(newValue, oldValue, self); + } + + return this.$watch($watchCollectionWatch, $watchCollectionAction); + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$digest + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and + * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change + * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} + * until no more listeners are firing. This means that it is possible to get into an infinite + * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of + * iterations exceeds 10. + * + * Usually, you don't call `$digest()` directly in + * {@link ng.directive:ngController controllers} or in + * {@link ng.$compileProvider#methods_directive directives}. + * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within + * a {@link ng.$compileProvider#methods_directive directives}), which will force a `$digest()`. + * + * If you want to be notified whenever `$digest()` is called, + * you can register a `watchExpression` function with + * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`. + * + * In unit tests, you may need to call `$digest()` to simulate the scope life cycle. + * + * # Example + *
+           var scope = ...;
+           scope.name = 'misko';
+           scope.counter = 0;
+
+           expect(scope.counter).toEqual(0);
+           scope.$watch('name', function(newValue, oldValue) {
+             scope.counter = scope.counter + 1;
+           });
+           expect(scope.counter).toEqual(0);
+
+           scope.$digest();
+           // no variable change
+           expect(scope.counter).toEqual(0);
+
+           scope.name = 'adam';
+           scope.$digest();
+           expect(scope.counter).toEqual(1);
+       * 
+ * + */ + $digest: function() { + var watch, value, last, + watchers, + asyncQueue = this.$$asyncQueue, + postDigestQueue = this.$$postDigestQueue, + length, + dirty, ttl = TTL, + next, current, target = this, + watchLog = [], + logIdx, logMsg, asyncTask; + + beginPhase('$digest'); + + do { // "while dirty" loop + dirty = false; + current = target; + + while(asyncQueue.length) { + try { + asyncTask = asyncQueue.shift(); + asyncTask.scope.$eval(asyncTask.expression); + } catch (e) { + $exceptionHandler(e); + } + } + + do { // "traverse the scopes" loop + if ((watchers = current.$$watchers)) { + // process our watches + length = watchers.length; + while (length--) { + try { + watch = watchers[length]; + // Most common watches are on primitives, in which case we can short + // circuit it with === operator, only when === fails do we use .equals + if (watch && (value = watch.get(current)) !== (last = watch.last) && + !(watch.eq + ? equals(value, last) + : (typeof value == 'number' && typeof last == 'number' + && isNaN(value) && isNaN(last)))) { + dirty = true; + watch.last = watch.eq ? copy(value) : value; + watch.fn(value, ((last === initWatchVal) ? value : last), current); + if (ttl < 5) { + logIdx = 4 - ttl; + if (!watchLog[logIdx]) watchLog[logIdx] = []; + logMsg = (isFunction(watch.exp)) + ? 'fn: ' + (watch.exp.name || watch.exp.toString()) + : watch.exp; + logMsg += '; newVal: ' + toJson(value) + '; oldVal: ' + toJson(last); + watchLog[logIdx].push(logMsg); + } + } + } catch (e) { + $exceptionHandler(e); + } + } + } + + // Insanity Warning: scope depth-first traversal + // yes, this code is a bit crazy, but it works and we have tests to prove it! + // this piece should be kept in sync with the traversal in $broadcast + if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) { + while(current !== target && !(next = current.$$nextSibling)) { + current = current.$parent; + } + } + } while ((current = next)); + + if(dirty && !(ttl--)) { + clearPhase(); + throw $rootScopeMinErr('infdig', + '{0} $digest() iterations reached. Aborting!\n' + + 'Watchers fired in the last 5 iterations: {1}', + TTL, toJson(watchLog)); + } + } while (dirty || asyncQueue.length); + + clearPhase(); + + while(postDigestQueue.length) { + try { + postDigestQueue.shift()(); + } catch (e) { + $exceptionHandler(e); + } + } + }, + + + /** + * @ngdoc event + * @name ng.$rootScope.Scope#$destroy + * @eventOf ng.$rootScope.Scope + * @eventType broadcast on scope being destroyed + * + * @description + * Broadcasted when a scope and its children are being destroyed. + * + * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to + * clean up DOM bindings before an element is removed from the DOM. + */ + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$destroy + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Removes the current scope (and all of its children) from the parent scope. Removal implies + * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer + * propagate to the current scope and its children. Removal also implies that the current + * scope is eligible for garbage collection. + * + * The `$destroy()` is usually used by directives such as + * {@link ng.directive:ngRepeat ngRepeat} for managing the + * unrolling of the loop. + * + * Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope. + * Application code can register a `$destroy` event handler that will give it a chance to + * perform any necessary cleanup. + * + * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to + * clean up DOM bindings before an element is removed from the DOM. + */ + $destroy: function() { + // we can't destroy the root scope or a scope that has been already destroyed + if ($rootScope == this || this.$$destroyed) return; + var parent = this.$parent; + + this.$broadcast('$destroy'); + this.$$destroyed = true; + + if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling; + if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling; + if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling; + if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling; + + // This is bogus code that works around Chrome's GC leak + // see: https://github.com/angular/angular.js/issues/1313#issuecomment-10378451 + this.$parent = this.$$nextSibling = this.$$prevSibling = this.$$childHead = + this.$$childTail = null; + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$eval + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Executes the `expression` on the current scope and returns the result. Any exceptions in + * the expression are propagated (uncaught). This is useful when evaluating Angular + * expressions. + * + * # Example + *
+           var scope = ng.$rootScope.Scope();
+           scope.a = 1;
+           scope.b = 2;
+
+           expect(scope.$eval('a+b')).toEqual(3);
+           expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);
+       * 
+ * + * @param {(string|function())=} expression An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with the current `scope` parameter. + * + * @param {(object)=} locals Local variables object, useful for overriding values in scope. + * @returns {*} The result of evaluating the expression. + */ + $eval: function(expr, locals) { + return $parse(expr)(this, locals); + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$evalAsync + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Executes the expression on the current scope at a later point in time. + * + * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only + * that: + * + * - it will execute after the function that scheduled the evaluation (preferably before DOM + * rendering). + * - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after + * `expression` execution. + * + * Any exceptions from the execution of the expression are forwarded to the + * {@link ng.$exceptionHandler $exceptionHandler} service. + * + * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle + * will be scheduled. However, it is encouraged to always call code that changes the model + * from within an `$apply` call. That includes code evaluated via `$evalAsync`. + * + * @param {(string|function())=} expression An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with the current `scope` parameter. + * + */ + $evalAsync: function(expr) { + // if we are outside of an $digest loop and this is the first time we are scheduling async + // task also schedule async auto-flush + if (!$rootScope.$$phase && !$rootScope.$$asyncQueue.length) { + $browser.defer(function() { + if ($rootScope.$$asyncQueue.length) { + $rootScope.$digest(); + } + }); + } + + this.$$asyncQueue.push({scope: this, expression: expr}); + }, + + $$postDigest : function(fn) { + this.$$postDigestQueue.push(fn); + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$apply + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * `$apply()` is used to execute an expression in angular from outside of the angular + * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). + * Because we are calling into the angular framework we need to perform proper scope life + * cycle of {@link ng.$exceptionHandler exception handling}, + * {@link ng.$rootScope.Scope#$digest executing watches}. + * + * ## Life cycle + * + * # Pseudo-Code of `$apply()` + *
+           function $apply(expr) {
+             try {
+               return $eval(expr);
+             } catch (e) {
+               $exceptionHandler(e);
+             } finally {
+               $root.$digest();
+             }
+           }
+       * 
+ * + * + * Scope's `$apply()` method transitions through the following stages: + * + * 1. The {@link guide/expression expression} is executed using the + * {@link ng.$rootScope.Scope#$eval $eval()} method. + * 2. Any exceptions from the execution of the expression are forwarded to the + * {@link ng.$exceptionHandler $exceptionHandler} service. + * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the + * expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method. + * + * + * @param {(string|function())=} exp An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with current `scope` parameter. + * + * @returns {*} The result of evaluating the expression. + */ + $apply: function(expr) { + try { + beginPhase('$apply'); + return this.$eval(expr); + } catch (e) { + $exceptionHandler(e); + } finally { + clearPhase(); + try { + $rootScope.$digest(); + } catch (e) { + $exceptionHandler(e); + throw e; + } + } + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$on + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for + * discussion of event life cycle. + * + * The event listener function format is: `function(event, args...)`. The `event` object + * passed into the listener has the following attributes: + * + * - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or + * `$broadcast`-ed. + * - `currentScope` - `{Scope}`: the current scope which is handling the event. + * - `name` - `{string}`: name of the event. + * - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel + * further event propagation (available only for events that were `$emit`-ed). + * - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag + * to true. + * - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called. + * + * @param {string} name Event name to listen on. + * @param {function(event, args...)} listener Function to call when the event is emitted. + * @returns {function()} Returns a deregistration function for this listener. + */ + $on: function(name, listener) { + var namedListeners = this.$$listeners[name]; + if (!namedListeners) { + this.$$listeners[name] = namedListeners = []; + } + namedListeners.push(listener); + + return function() { + namedListeners[indexOf(namedListeners, listener)] = null; + }; + }, + + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$emit + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Dispatches an event `name` upwards through the scope hierarchy notifying the + * registered {@link ng.$rootScope.Scope#$on} listeners. + * + * The event life cycle starts at the scope on which `$emit` was called. All + * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get + * notified. Afterwards, the event traverses upwards toward the root scope and calls all + * registered listeners along the way. The event will stop propagating if one of the listeners + * cancels it. + * + * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed + * onto the {@link ng.$exceptionHandler $exceptionHandler} service. + * + * @param {string} name Event name to emit. + * @param {...*} args Optional set of arguments which will be passed onto the event listeners. + * @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}). + */ + $emit: function(name, args) { + var empty = [], + namedListeners, + scope = this, + stopPropagation = false, + event = { + name: name, + targetScope: scope, + stopPropagation: function() {stopPropagation = true;}, + preventDefault: function() { + event.defaultPrevented = true; + }, + defaultPrevented: false + }, + listenerArgs = concat([event], arguments, 1), + i, length; + + do { + namedListeners = scope.$$listeners[name] || empty; + event.currentScope = scope; + for (i=0, length=namedListeners.length; i= 8 ) { + normalizedVal = urlResolve(uri).href; + if (normalizedVal !== '' && !normalizedVal.match(regex)) { + return 'unsafe:'+normalizedVal; + } + } + return uri; + }; + }; +} + +var $sceMinErr = minErr('$sce'); + +var SCE_CONTEXTS = { + HTML: 'html', + CSS: 'css', + URL: 'url', + // RESOURCE_URL is a subtype of URL used in contexts where a privileged resource is sourced from a + // url. (e.g. ng-include, script src, templateUrl) + RESOURCE_URL: 'resourceUrl', + JS: 'js' +}; + +// Helper functions follow. + +// Copied from: +// http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962 +// Prereq: s is a string. +function escapeForRegexp(s) { + return s.replace(/([-()\[\]{}+?*.$\^|,:# -1) { + throw $sceMinErr('iwcard', + 'Illegal sequence *** in string matcher. String: {0}', matcher); + } + matcher = escapeForRegexp(matcher). + replace('\\*\\*', '.*'). + replace('\\*', '[^:/.?&;]*'); + return new RegExp('^' + matcher + '$'); + } else if (isRegExp(matcher)) { + // The only other type of matcher allowed is a Regexp. + // Match entire URL / disallow partial matches. + // Flags are reset (i.e. no global, ignoreCase or multiline) + return new RegExp('^' + matcher.source + '$'); + } else { + throw $sceMinErr('imatcher', + 'Matchers may only be "self", string patterns or RegExp objects'); + } +} + + +function adjustMatchers(matchers) { + var adjustedMatchers = []; + if (isDefined(matchers)) { + forEach(matchers, function(matcher) { + adjustedMatchers.push(adjustMatcher(matcher)); + }); + } + return adjustedMatchers; +} + + +/** + * @ngdoc service + * @name ng.$sceDelegate + * @function + * + * @description + * + * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict + * Contextual Escaping (SCE)} services to AngularJS. + * + * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of + * the `$sce` service to customize the way Strict Contextual Escaping works in AngularJS. This is + * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to + * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things + * work because `$sce` delegates to `$sceDelegate` for these operations. + * + * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service. + * + * The default instance of `$sceDelegate` should work out of the box with little pain. While you + * can override it completely to change the behavior of `$sce`, the common case would + * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting + * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as + * templates. Refer {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist + * $sceDelegateProvider.resourceUrlWhitelist} and {@link + * ng.$sceDelegateProvider#methods_resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} + */ + +/** + * @ngdoc object + * @name ng.$sceDelegateProvider + * @description + * + * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate + * $sceDelegate} service. This allows one to get/set the whitelists and blacklists used to ensure + * that the URLs used for sourcing Angular templates are safe. Refer {@link + * ng.$sceDelegateProvider#methods_resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and + * {@link ng.$sceDelegateProvider#methods_resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} + * + * For the general details about this service in Angular, read the main page for {@link ng.$sce + * Strict Contextual Escaping (SCE)}. + * + * **Example**: Consider the following case. + * + * - your app is hosted at url `http://myapp.example.com/` + * - but some of your templates are hosted on other domains you control such as + * `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc. + * - and you have an open redirect at `http://myapp.example.com/clickThru?...`. + * + * Here is what a secure configuration for this scenario might look like: + * + *
+ *    angular.module('myApp', []).config(function($sceDelegateProvider) {
+ *      $sceDelegateProvider.resourceUrlWhitelist([
+ *        // Allow same origin resource loads.
+ *        'self',
+ *        // Allow loading from our assets domain.  Notice the difference between * and **.
+ *        'http://srv*.assets.example.com/**']);
+ *
+ *      // The blacklist overrides the whitelist so the open redirect here is blocked.
+ *      $sceDelegateProvider.resourceUrlBlacklist([
+ *        'http://myapp.example.com/clickThru**']);
+ *      });
+ * 
+ */ + +function $SceDelegateProvider() { + this.SCE_CONTEXTS = SCE_CONTEXTS; + + // Resource URLs can also be trusted by policy. + var resourceUrlWhitelist = ['self'], + resourceUrlBlacklist = []; + + /** + * @ngdoc function + * @name ng.sceDelegateProvider#resourceUrlWhitelist + * @methodOf ng.$sceDelegateProvider + * @function + * + * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value + * provided. This must be an array or null. A snapshot of this array is used so further + * changes to the array are ignored. + * + * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items + * allowed in this array. + * + * Note: **an empty whitelist array will block all URLs**! + * + * @return {Array} the currently set whitelist array. + * + * The **default value** when no whitelist has been explicitly set is `['self']` allowing only + * same origin resource requests. + * + * @description + * Sets/Gets the whitelist of trusted resource URLs. + */ + this.resourceUrlWhitelist = function (value) { + if (arguments.length) { + resourceUrlWhitelist = adjustMatchers(value); + } + return resourceUrlWhitelist; + }; + + /** + * @ngdoc function + * @name ng.sceDelegateProvider#resourceUrlBlacklist + * @methodOf ng.$sceDelegateProvider + * @function + * + * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value + * provided. This must be an array or null. A snapshot of this array is used so further + * changes to the array are ignored. + * + * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items + * allowed in this array. + * + * The typical usage for the blacklist is to **block + * [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as + * these would otherwise be trusted but actually return content from the redirected domain. + * + * Finally, **the blacklist overrides the whitelist** and has the final say. + * + * @return {Array} the currently set blacklist array. + * + * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there + * is no blacklist.) + * + * @description + * Sets/Gets the blacklist of trusted resource URLs. + */ + + this.resourceUrlBlacklist = function (value) { + if (arguments.length) { + resourceUrlBlacklist = adjustMatchers(value); + } + return resourceUrlBlacklist; + }; + + this.$get = ['$injector', function($injector) { + + var htmlSanitizer = function htmlSanitizer(html) { + throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.'); + }; + + if ($injector.has('$sanitize')) { + htmlSanitizer = $injector.get('$sanitize'); + } + + + function matchUrl(matcher, parsedUrl) { + if (matcher === 'self') { + return urlIsSameOrigin(parsedUrl); + } else { + // definitely a regex. See adjustMatchers() + return !!matcher.exec(parsedUrl.href); + } + } + + function isResourceUrlAllowedByPolicy(url) { + var parsedUrl = urlResolve(url.toString()); + var i, n, allowed = false; + // Ensure that at least one item from the whitelist allows this url. + for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) { + if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) { + allowed = true; + break; + } + } + if (allowed) { + // Ensure that no item from the blacklist blocked this url. + for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) { + if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) { + allowed = false; + break; + } + } + } + return allowed; + } + + function generateHolderType(Base) { + var holderType = function TrustedValueHolderType(trustedValue) { + this.$$unwrapTrustedValue = function() { + return trustedValue; + }; + }; + if (Base) { + holderType.prototype = new Base(); + } + holderType.prototype.valueOf = function sceValueOf() { + return this.$$unwrapTrustedValue(); + }; + holderType.prototype.toString = function sceToString() { + return this.$$unwrapTrustedValue().toString(); + }; + return holderType; + } + + var trustedValueHolderBase = generateHolderType(), + byType = {}; + + byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase); + byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase); + byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase); + byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase); + byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]); + + /** + * @ngdoc method + * @name ng.$sceDelegate#trustAs + * @methodOf ng.$sceDelegate + * + * @description + * Returns an object that is trusted by angular for use in specified strict + * contextual escaping contexts (such as ng-html-bind-unsafe, ng-include, any src + * attribute interpolation, any dom event binding attribute interpolation + * such as for onclick, etc.) that uses the provided value. + * See {@link ng.$sce $sce} for enabling strict contextual escaping. + * + * @param {string} type The kind of context in which this value is safe for use. e.g. url, + * resourceUrl, html, js and css. + * @param {*} value The value that that should be considered trusted/safe. + * @returns {*} A value that can be used to stand in for the provided `value` in places + * where Angular expects a $sce.trustAs() return value. + */ + function trustAs(type, trustedValue) { + var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null); + if (!Constructor) { + throw $sceMinErr('icontext', + 'Attempted to trust a value in invalid context. Context: {0}; Value: {1}', + type, trustedValue); + } + if (trustedValue === null || trustedValue === undefined || trustedValue === '') { + return trustedValue; + } + // All the current contexts in SCE_CONTEXTS happen to be strings. In order to avoid trusting + // mutable objects, we ensure here that the value passed in is actually a string. + if (typeof trustedValue !== 'string') { + throw $sceMinErr('itype', + 'Attempted to trust a non-string value in a content requiring a string: Context: {0}', + type); + } + return new Constructor(trustedValue); + } + + /** + * @ngdoc method + * @name ng.$sceDelegate#valueOf + * @methodOf ng.$sceDelegate + * + * @description + * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#methods_trustAs + * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link + * ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}. + * + * If the passed parameter is not a value that had been returned by {@link + * ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}, returns it as-is. + * + * @param {*} value The result of a prior {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`} + * call or anything else. + * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#methods_trustAs + * `$sceDelegate.trustAs`} if `value` is the result of such a call. Otherwise, returns + * `value` unchanged. + */ + function valueOf(maybeTrusted) { + if (maybeTrusted instanceof trustedValueHolderBase) { + return maybeTrusted.$$unwrapTrustedValue(); + } else { + return maybeTrusted; + } + } + + /** + * @ngdoc method + * @name ng.$sceDelegate#getTrusted + * @methodOf ng.$sceDelegate + * + * @description + * Takes the result of a {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`} call and + * returns the originally supplied value if the queried context type is a supertype of the + * created type. If this condition isn't satisfied, throws an exception. + * + * @param {string} type The kind of context in which this value is to be used. + * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#methods_trustAs + * `$sceDelegate.trustAs`} call. + * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#methods_trustAs + * `$sceDelegate.trustAs`} if valid in this context. Otherwise, throws an exception. + */ + function getTrusted(type, maybeTrusted) { + if (maybeTrusted === null || maybeTrusted === undefined || maybeTrusted === '') { + return maybeTrusted; + } + var constructor = (byType.hasOwnProperty(type) ? byType[type] : null); + if (constructor && maybeTrusted instanceof constructor) { + return maybeTrusted.$$unwrapTrustedValue(); + } + // If we get here, then we may only take one of two actions. + // 1. sanitize the value for the requested type, or + // 2. throw an exception. + if (type === SCE_CONTEXTS.RESOURCE_URL) { + if (isResourceUrlAllowedByPolicy(maybeTrusted)) { + return maybeTrusted; + } else { + throw $sceMinErr('insecurl', + 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}', + maybeTrusted.toString()); + } + } else if (type === SCE_CONTEXTS.HTML) { + return htmlSanitizer(maybeTrusted); + } + throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.'); + } + + return { trustAs: trustAs, + getTrusted: getTrusted, + valueOf: valueOf }; + }]; +} + + +/** + * @ngdoc object + * @name ng.$sceProvider + * @description + * + * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service. + * - enable/disable Strict Contextual Escaping (SCE) in a module + * - override the default implementation with a custom delegate + * + * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}. + */ + +/* jshint maxlen: false*/ + +/** + * @ngdoc service + * @name ng.$sce + * @function + * + * @description + * + * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS. + * + * # Strict Contextual Escaping + * + * Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain + * contexts to result in a value that is marked as safe to use for that context. One example of + * such a context is binding arbitrary html controlled by the user via `ng-bind-html`. We refer + * to these contexts as privileged or SCE contexts. + * + * As of version 1.2, Angular ships with SCE enabled by default. + * + * Note: When enabled (the default), IE8 in quirks mode is not supported. In this mode, IE8 allows + * one to execute arbitrary javascript by the use of the expression() syntax. Refer + * to learn more about them. + * You can ensure your document is in standards mode and not quirks mode by adding `` + * to the top of your HTML document. + * + * SCE assists in writing code in way that (a) is secure by default and (b) makes auditing for + * security vulnerabilities such as XSS, clickjacking, etc. a lot easier. + * + * Here's an example of a binding in a privileged context: + * + *
+ *     
+ *     
+ *
+ * + * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE + * disabled, this application allows the user to render arbitrary HTML into the DIV. + * In a more realistic example, one may be rendering user comments, blog articles, etc. via + * bindings. (HTML is just one example of a context where rendering user controlled input creates + * security vulnerabilities.) + * + * For the case of HTML, you might use a library, either on the client side, or on the server side, + * to sanitize unsafe HTML before binding to the value and rendering it in the document. + * + * How would you ensure that every place that used these types of bindings was bound to a value that + * was sanitized by your library (or returned as safe for rendering by your server?) How can you + * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some + * properties/fields and forgot to update the binding to the sanitized value? + * + * To be secure by default, you want to ensure that any such bindings are disallowed unless you can + * determine that something explicitly says it's safe to use a value for binding in that + * context. You can then audit your code (a simple grep would do) to ensure that this is only done + * for those values that you can easily tell are safe - because they were received from your server, + * sanitized by your library, etc. You can organize your codebase to help with this - perhaps + * allowing only the files in a specific directory to do this. Ensuring that the internal API + * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task. + * + * In the case of AngularJS' SCE service, one uses {@link ng.$sce#methods_trustAs $sce.trustAs} + * (and shorthand methods such as {@link ng.$sce#methods_trustAsHtml $sce.trustAsHtml}, etc.) to + * obtain values that will be accepted by SCE / privileged contexts. + * + * + * ## How does it work? + * + * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#methods_getTrusted + * $sce.getTrusted(context, value)} rather than to the value directly. Directives use {@link + * ng.$sce#methods_parse $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the + * {@link ng.$sce#methods_getTrusted $sce.getTrusted} behind the scenes on non-constant literals. + * + * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link + * ng.$sce#methods_parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly + * simplified): + * + *
+ *   var ngBindHtmlDirective = ['$sce', function($sce) {
+ *     return function(scope, element, attr) {
+ *       scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
+ *         element.html(value || '');
+ *       });
+ *     };
+ *   }];
+ * 
+ * + * ## Impact on loading templates + * + * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as + * `templateUrl`'s specified by {@link guide/directive directives}. + * + * By default, Angular only loads templates from the same domain and protocol as the application + * document. This is done by calling {@link ng.$sce#methods_getTrustedResourceUrl + * $sce.getTrustedResourceUrl} on the template URL. To load templates from other domains and/or + * protocols, you may either either {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelist + * them} or {@link ng.$sce#methods_trustAsResourceUrl wrap it} into a trusted value. + * + * *Please note*: + * The browser's + * {@link https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest + * Same Origin Policy} and {@link http://www.w3.org/TR/cors/ Cross-Origin Resource Sharing (CORS)} + * policy apply in addition to this and may further restrict whether the template is successfully + * loaded. This means that without the right CORS policy, loading templates from a different domain + * won't work on all browsers. Also, loading templates from `file://` URL does not work on some + * browsers. + * + * ## This feels like too much overhead for the developer? + * + * It's important to remember that SCE only applies to interpolation expressions. + * + * If your expressions are constant literals, they're automatically trusted and you don't need to + * call `$sce.trustAs` on them. (e.g. + * `
`) just works. + * + * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them + * through {@link ng.$sce#methods_getTrusted $sce.getTrusted}. SCE doesn't play a role here. + * + * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load + * templates in `ng-include` from your application's domain without having to even know about SCE. + * It blocks loading templates from other domains or loading templates over http from an https + * served document. You can change these by setting your own custom {@link + * ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelists} and {@link + * ng.$sceDelegateProvider#methods_resourceUrlBlacklist blacklists} for matching such URLs. + * + * This significantly reduces the overhead. It is far easier to pay the small overhead and have an + * application that's secure and can be audited to verify that with much more ease than bolting + * security onto an application later. + * + * + * ## What trusted context types are supported? + * + * | Context | Notes | + * |---------------------|----------------| + * | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. | + * | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. | + * | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`
Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. | + * | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently unused. Feel free to use it in your own directives. | + * + * ## Format of items in {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#methods_resourceUrlBlacklist Blacklist}
+ * + * Each element in these arrays must be one of the following: + * + * - **'self'** + * - The special **string**, `'self'`, can be used to match against all URLs of the **same + * domain** as the application document using the **same protocol**. + * - **String** (except the special value `'self'`) + * - The string is matched against the full *normalized / absolute URL* of the resource + * being tested (substring matches are not good enough.) + * - There are exactly **two wildcard sequences** - `*` and `**`. All other characters + * match themselves. + * - `*`: matches zero or more occurances of any character other than one of the following 6 + * characters: '`:`', '`/`', '`.`', '`?`', '`&`' and ';'. It's a useful wildcard for use + * in a whitelist. + * - `**`: matches zero or more occurances of *any* character. As such, it's not + * not appropriate to use in for a scheme, domain, etc. as it would match too much. (e.g. + * http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might + * not have been the intention.) It's usage at the very end of the path is ok. (e.g. + * http://foo.example.com/templates/**). + * - **RegExp** (*see caveat below*) + * - *Caveat*: While regular expressions are powerful and offer great flexibility, their syntax + * (and all the inevitable escaping) makes them *harder to maintain*. It's easy to + * accidentally introduce a bug when one updates a complex expression (imho, all regexes should + * have good test coverage.). For instance, the use of `.` in the regex is correct only in a + * small number of cases. A `.` character in the regex used when matching the scheme or a + * subdomain could be matched against a `:` or literal `.` that was likely not intended. It + * is highly recommended to use the string patterns and only fall back to regular expressions + * if they as a last resort. + * - The regular expression must be an instance of RegExp (i.e. not a string.) It is + * matched against the **entire** *normalized / absolute URL* of the resource being tested + * (even when the RegExp did not have the `^` and `$` codes.) In addition, any flags + * present on the RegExp (such as multiline, global, ignoreCase) are ignored. + * - If you are generating your Javascript from some other templating engine (not + * recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)), + * remember to escape your regular expression (and be aware that you might need more than + * one level of escaping depending on your templating engine and the way you interpolated + * the value.) Do make use of your platform's escaping mechanism as it might be good + * enough before coding your own. e.g. Ruby has + * [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape) + * and Python has [re.escape](http://docs.python.org/library/re.html#re.escape). + * Javascript lacks a similar built in function for escaping. Take a look at Google + * Closure library's [goog.string.regExpEscape(s)]( + * http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962). + * + * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example. + * + * ## Show me an example using SCE. + * + * @example + + +
+

+ User comments
+ By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when + $sanitize is available. If $sanitize isn't available, this results in an error instead of an + exploit. +
+
+ {{userComment.name}}: + +
+
+
+
+
+ + + var mySceApp = angular.module('mySceApp', ['ngSanitize']); + + mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { + var self = this; + $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { + self.userComments = userComments; + }); + self.explicitlyTrustedHtml = $sce.trustAsHtml( + 'Hover over this text.'); + }); + + + +[ + { "name": "Alice", + "htmlComment": + "Is anyone reading this?" + }, + { "name": "Bob", + "htmlComment": "Yes! Am I the only other one?" + } +] + + + + describe('SCE doc demo', function() { + it('should sanitize untrusted values', function() { + expect(element('.htmlComment').html()).toBe('Is anyone reading this?'); + }); + it('should NOT sanitize explicitly trusted values', function() { + expect(element('#explicitlyTrustedHtml').html()).toBe( + 'Hover over this text.'); + }); + }); + +
+ * + * + * + * ## Can I disable SCE completely? + * + * Yes, you can. However, this is strongly discouraged. SCE gives you a lot of security benefits + * for little coding overhead. It will be much harder to take an SCE disabled application and + * either secure it on your own or enable SCE at a later stage. It might make sense to disable SCE + * for cases where you have a lot of existing code that was written before SCE was introduced and + * you're migrating them a module at a time. + * + * That said, here's how you can completely disable SCE: + * + *
+ *   angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
+ *     // Completely disable SCE.  For demonstration purposes only!
+ *     // Do not use in new projects.
+ *     $sceProvider.enabled(false);
+ *   });
+ * 
+ * + */ +/* jshint maxlen: 100 */ + +function $SceProvider() { + var enabled = true; + + /** + * @ngdoc function + * @name ng.sceProvider#enabled + * @methodOf ng.$sceProvider + * @function + * + * @param {boolean=} value If provided, then enables/disables SCE. + * @return {boolean} true if SCE is enabled, false otherwise. + * + * @description + * Enables/disables SCE and returns the current value. + */ + this.enabled = function (value) { + if (arguments.length) { + enabled = !!value; + } + return enabled; + }; + + + /* Design notes on the default implementation for SCE. + * + * The API contract for the SCE delegate + * ------------------------------------- + * The SCE delegate object must provide the following 3 methods: + * + * - trustAs(contextEnum, value) + * This method is used to tell the SCE service that the provided value is OK to use in the + * contexts specified by contextEnum. It must return an object that will be accepted by + * getTrusted() for a compatible contextEnum and return this value. + * + * - valueOf(value) + * For values that were not produced by trustAs(), return them as is. For values that were + * produced by trustAs(), return the corresponding input value to trustAs. Basically, if + * trustAs is wrapping the given values into some type, this operation unwraps it when given + * such a value. + * + * - getTrusted(contextEnum, value) + * This function should return the a value that is safe to use in the context specified by + * contextEnum or throw and exception otherwise. + * + * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be + * opaque or wrapped in some holder object. That happens to be an implementation detail. For + * instance, an implementation could maintain a registry of all trusted objects by context. In + * such a case, trustAs() would return the same object that was passed in. getTrusted() would + * return the same object passed in if it was found in the registry under a compatible context or + * throw an exception otherwise. An implementation might only wrap values some of the time based + * on some criteria. getTrusted() might return a value and not throw an exception for special + * constants or objects even if not wrapped. All such implementations fulfill this contract. + * + * + * A note on the inheritance model for SCE contexts + * ------------------------------------------------ + * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types. This + * is purely an implementation details. + * + * The contract is simply this: + * + * getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value) + * will also succeed. + * + * Inheritance happens to capture this in a natural way. In some future, we + * may not use inheritance anymore. That is OK because no code outside of + * sce.js and sceSpecs.js would need to be aware of this detail. + */ + + this.$get = ['$parse', '$sniffer', '$sceDelegate', function( + $parse, $sniffer, $sceDelegate) { + // Prereq: Ensure that we're not running in IE8 quirks mode. In that mode, IE allows + // the "expression(javascript expression)" syntax which is insecure. + if (enabled && $sniffer.msie && $sniffer.msieDocumentMode < 8) { + throw $sceMinErr('iequirks', + 'Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks ' + + 'mode. You can fix this by adding the text to the top of your HTML ' + + 'document. See http://docs.angularjs.org/api/ng.$sce for more information.'); + } + + var sce = copy(SCE_CONTEXTS); + + /** + * @ngdoc function + * @name ng.sce#isEnabled + * @methodOf ng.$sce + * @function + * + * @return {Boolean} true if SCE is enabled, false otherwise. If you want to set the value, you + * have to do it at module config time on {@link ng.$sceProvider $sceProvider}. + * + * @description + * Returns a boolean indicating if SCE is enabled. + */ + sce.isEnabled = function () { + return enabled; + }; + sce.trustAs = $sceDelegate.trustAs; + sce.getTrusted = $sceDelegate.getTrusted; + sce.valueOf = $sceDelegate.valueOf; + + if (!enabled) { + sce.trustAs = sce.getTrusted = function(type, value) { return value; }; + sce.valueOf = identity; + } + + /** + * @ngdoc method + * @name ng.$sce#parse + * @methodOf ng.$sce + * + * @description + * Converts Angular {@link guide/expression expression} into a function. This is like {@link + * ng.$parse $parse} and is identical when the expression is a literal constant. Otherwise, it + * wraps the expression in a call to {@link ng.$sce#methods_getTrusted $sce.getTrusted(*type*, + * *result*)} + * + * @param {string} type The kind of SCE context in which this result will be used. + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + sce.parseAs = function sceParseAs(type, expr) { + var parsed = $parse(expr); + if (parsed.literal && parsed.constant) { + return parsed; + } else { + return function sceParseAsTrusted(self, locals) { + return sce.getTrusted(type, parsed(self, locals)); + }; + } + }; + + /** + * @ngdoc method + * @name ng.$sce#trustAs + * @methodOf ng.$sce + * + * @description + * Delegates to {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}. As such, + * returns an objectthat is trusted by angular for use in specified strict contextual + * escaping contexts (such as ng-html-bind-unsafe, ng-include, any src attribute + * interpolation, any dom event binding attribute interpolation such as for onclick, etc.) + * that uses the provided value. See * {@link ng.$sce $sce} for enabling strict contextual + * escaping. + * + * @param {string} type The kind of context in which this value is safe for use. e.g. url, + * resource_url, html, js and css. + * @param {*} value The value that that should be considered trusted/safe. + * @returns {*} A value that can be used to stand in for the provided `value` in places + * where Angular expects a $sce.trustAs() return value. + */ + + /** + * @ngdoc method + * @name ng.$sce#trustAsHtml + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.trustAsHtml(value)` → + * {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs($sce.HTML, value)`} + * + * @param {*} value The value to trustAs. + * @returns {*} An object that can be passed to {@link ng.$sce#methods_getTrustedHtml + * $sce.getTrustedHtml(value)} to obtain the original value. (privileged directives + * only accept expressions that are either literal constants or are the + * return value of {@link ng.$sce#methods_trustAs $sce.trustAs}.) + */ + + /** + * @ngdoc method + * @name ng.$sce#trustAsUrl + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.trustAsUrl(value)` → + * {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs($sce.URL, value)`} + * + * @param {*} value The value to trustAs. + * @returns {*} An object that can be passed to {@link ng.$sce#methods_getTrustedUrl + * $sce.getTrustedUrl(value)} to obtain the original value. (privileged directives + * only accept expressions that are either literal constants or are the + * return value of {@link ng.$sce#methods_trustAs $sce.trustAs}.) + */ + + /** + * @ngdoc method + * @name ng.$sce#trustAsResourceUrl + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.trustAsResourceUrl(value)` → + * {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`} + * + * @param {*} value The value to trustAs. + * @returns {*} An object that can be passed to {@link ng.$sce#methods_getTrustedResourceUrl + * $sce.getTrustedResourceUrl(value)} to obtain the original value. (privileged directives + * only accept expressions that are either literal constants or are the return + * value of {@link ng.$sce#methods_trustAs $sce.trustAs}.) + */ + + /** + * @ngdoc method + * @name ng.$sce#trustAsJs + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.trustAsJs(value)` → + * {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs($sce.JS, value)`} + * + * @param {*} value The value to trustAs. + * @returns {*} An object that can be passed to {@link ng.$sce#methods_getTrustedJs + * $sce.getTrustedJs(value)} to obtain the original value. (privileged directives + * only accept expressions that are either literal constants or are the + * return value of {@link ng.$sce#methods_trustAs $sce.trustAs}.) + */ + + /** + * @ngdoc method + * @name ng.$sce#getTrusted + * @methodOf ng.$sce + * + * @description + * Delegates to {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted`}. As such, + * takes the result of a {@link ng.$sce#methods_trustAs `$sce.trustAs`}() call and returns the + * originally supplied value if the queried context type is a supertype of the created type. + * If this condition isn't satisfied, throws an exception. + * + * @param {string} type The kind of context in which this value is to be used. + * @param {*} maybeTrusted The result of a prior {@link ng.$sce#methods_trustAs `$sce.trustAs`} + * call. + * @returns {*} The value the was originally provided to + * {@link ng.$sce#methods_trustAs `$sce.trustAs`} if valid in this context. + * Otherwise, throws an exception. + */ + + /** + * @ngdoc method + * @name ng.$sce#getTrustedHtml + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.getTrustedHtml(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`} + * + * @param {*} value The value to pass to `$sce.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)` + */ + + /** + * @ngdoc method + * @name ng.$sce#getTrustedCss + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.getTrustedCss(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`} + * + * @param {*} value The value to pass to `$sce.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)` + */ + + /** + * @ngdoc method + * @name ng.$sce#getTrustedUrl + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.getTrustedUrl(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.URL, value)`} + * + * @param {*} value The value to pass to `$sce.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)` + */ + + /** + * @ngdoc method + * @name ng.$sce#getTrustedResourceUrl + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.getTrustedResourceUrl(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`} + * + * @param {*} value The value to pass to `$sceDelegate.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)` + */ + + /** + * @ngdoc method + * @name ng.$sce#getTrustedJs + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.getTrustedJs(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.JS, value)`} + * + * @param {*} value The value to pass to `$sce.getTrusted`. + * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)` + */ + + /** + * @ngdoc method + * @name ng.$sce#parseAsHtml + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.parseAsHtml(expression string)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.HTML, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + /** + * @ngdoc method + * @name ng.$sce#parseAsCss + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.parseAsCss(value)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.CSS, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + /** + * @ngdoc method + * @name ng.$sce#parseAsUrl + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.parseAsUrl(value)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.URL, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + /** + * @ngdoc method + * @name ng.$sce#parseAsResourceUrl + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.parseAsResourceUrl(value)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.RESOURCE_URL, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + /** + * @ngdoc method + * @name ng.$sce#parseAsJs + * @methodOf ng.$sce + * + * @description + * Shorthand method. `$sce.parseAsJs(value)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.JS, value)`} + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context` – `{object}` – an object against which any expressions embedded in the strings + * are evaluated against (typically a scope object). + * * `locals` – `{object=}` – local variables context object, useful for overriding values in + * `context`. + */ + + // Shorthand delegations. + var parse = sce.parseAs, + getTrusted = sce.getTrusted, + trustAs = sce.trustAs; + + forEach(SCE_CONTEXTS, function (enumValue, name) { + var lName = lowercase(name); + sce[camelCase("parse_as_" + lName)] = function (expr) { + return parse(enumValue, expr); + }; + sce[camelCase("get_trusted_" + lName)] = function (value) { + return getTrusted(enumValue, value); + }; + sce[camelCase("trust_as_" + lName)] = function (value) { + return trustAs(enumValue, value); + }; + }); + + return sce; + }]; +} + +/** + * !!! This is an undocumented "private" service !!! + * + * @name ng.$sniffer + * @requires $window + * @requires $document + * + * @property {boolean} history Does the browser support html5 history api ? + * @property {boolean} hashchange Does the browser support hashchange event ? + * @property {boolean} transitions Does the browser support CSS transition events ? + * @property {boolean} animations Does the browser support CSS animation events ? + * + * @description + * This is very simple implementation of testing browser's features. + */ +function $SnifferProvider() { + this.$get = ['$window', '$document', function($window, $document) { + var eventSupport = {}, + android = + int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), + boxee = /Boxee/i.test(($window.navigator || {}).userAgent), + document = $document[0] || {}, + documentMode = document.documentMode, + vendorPrefix, + vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/, + bodyStyle = document.body && document.body.style, + transitions = false, + animations = false, + match; + + if (bodyStyle) { + for(var prop in bodyStyle) { + if(match = vendorRegex.exec(prop)) { + vendorPrefix = match[0]; + vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1); + break; + } + } + + if(!vendorPrefix) { + vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit'; + } + + transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle)); + animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle)); + + if (android && (!transitions||!animations)) { + transitions = isString(document.body.style.webkitTransition); + animations = isString(document.body.style.webkitAnimation); + } + } + + + return { + // Android has history.pushState, but it does not update location correctly + // so let's not use the history API at all. + // http://code.google.com/p/android/issues/detail?id=17471 + // https://github.com/angular/angular.js/issues/904 + + // older webit browser (533.9) on Boxee box has exactly the same problem as Android has + // so let's not use the history API also + // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined + // jshint -W018 + history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee), + // jshint +W018 + hashchange: 'onhashchange' in $window && + // IE8 compatible mode lies + (!documentMode || documentMode > 7), + hasEvent: function(event) { + // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have + // it. In particular the event is not fired when backspace or delete key are pressed or + // when cut operation is performed. + if (event == 'input' && msie == 9) return false; + + if (isUndefined(eventSupport[event])) { + var divElm = document.createElement('div'); + eventSupport[event] = 'on' + event in divElm; + } + + return eventSupport[event]; + }, + csp: csp(), + vendorPrefix: vendorPrefix, + transitions : transitions, + animations : animations, + msie : msie, + msieDocumentMode: documentMode + }; + }]; +} + +function $TimeoutProvider() { + this.$get = ['$rootScope', '$browser', '$q', '$exceptionHandler', + function($rootScope, $browser, $q, $exceptionHandler) { + var deferreds = {}; + + + /** + * @ngdoc function + * @name ng.$timeout + * @requires $browser + * + * @description + * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch + * block and delegates any exceptions to + * {@link ng.$exceptionHandler $exceptionHandler} service. + * + * The return value of registering a timeout function is a promise, which will be resolved when + * the timeout is reached and the timeout function is executed. + * + * To cancel a timeout request, call `$timeout.cancel(promise)`. + * + * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to + * synchronously flush the queue of deferred functions. + * + * @param {function()} fn A function, whose execution should be delayed. + * @param {number=} [delay=0] Delay in milliseconds. + * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise + * will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block. + * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this + * promise will be resolved with is the return value of the `fn` function. + * + * @example + + + + +
+
+ Date format:
+ Current time is: +
+ Blood 1 : {{blood_1}} + Blood 2 : {{blood_2}} + + + +
+
+ +
+
+ */ + function timeout(fn, delay, invokeApply) { + var deferred = $q.defer(), + promise = deferred.promise, + skipApply = (isDefined(invokeApply) && !invokeApply), + timeoutId; + + timeoutId = $browser.defer(function() { + try { + deferred.resolve(fn()); + } catch(e) { + deferred.reject(e); + $exceptionHandler(e); + } + finally { + delete deferreds[promise.$$timeoutId]; + } + + if (!skipApply) $rootScope.$apply(); + }, delay); + + promise.$$timeoutId = timeoutId; + deferreds[timeoutId] = deferred; + + return promise; + } + + + /** + * @ngdoc function + * @name ng.$timeout#cancel + * @methodOf ng.$timeout + * + * @description + * Cancels a task associated with the `promise`. As a result of this, the promise will be + * resolved with a rejection. + * + * @param {Promise=} promise Promise returned by the `$timeout` function. + * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully + * canceled. + */ + timeout.cancel = function(promise) { + if (promise && promise.$$timeoutId in deferreds) { + deferreds[promise.$$timeoutId].reject('canceled'); + delete deferreds[promise.$$timeoutId]; + return $browser.defer.cancel(promise.$$timeoutId); + } + return false; + }; + + return timeout; + }]; +} + +// NOTE: The usage of window and document instead of $window and $document here is +// deliberate. This service depends on the specific behavior of anchor nodes created by the +// browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and +// cause us to break tests. In addition, when the browser resolves a URL for XHR, it +// doesn't know about mocked locations and resolves URLs to the real document - which is +// exactly the behavior needed here. There is little value is mocking these out for this +// service. +var urlParsingNode = document.createElement("a"); +var originUrl = urlResolve(window.location.href, true); + + +/** + * + * Implementation Notes for non-IE browsers + * ---------------------------------------- + * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM, + * results both in the normalizing and parsing of the URL. Normalizing means that a relative + * URL will be resolved into an absolute URL in the context of the application document. + * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related + * properties are all populated to reflect the normalized URL. This approach has wide + * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See + * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html + * + * Implementation Notes for IE + * --------------------------- + * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other + * browsers. However, the parsed components will not be set if the URL assigned did not specify + * them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We + * work around that by performing the parsing in a 2nd step by taking a previously normalized + * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the + * properties such as protocol, hostname, port, etc. + * + * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one + * uses the inner HTML approach to assign the URL as part of an HTML snippet - + * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL. + * Unfortunately, setting img[src] to something like "javascript:foo" on IE throws an exception. + * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that + * method and IE < 8 is unsupported. + * + * References: + * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement + * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html + * http://url.spec.whatwg.org/#urlutils + * https://github.com/angular/angular.js/pull/2902 + * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/ + * + * @function + * @param {string} url The URL to be parsed. + * @description Normalizes and parses a URL. + * @returns {object} Returns the normalized URL as a dictionary. + * + * | member name | Description | + * |---------------|----------------| + * | href | A normalized version of the provided URL if it was not an absolute URL | + * | protocol | The protocol including the trailing colon | + * | host | The host and port (if the port is non-default) of the normalizedUrl | + * | search | The search params, minus the question mark | + * | hash | The hash string, minus the hash symbol + * | hostname | The hostname + * | port | The port, without ":" + * | pathname | The pathname, beginning with "/" + * + */ +function urlResolve(url, base) { + var href = url; + + if (msie) { + // Normalize before parse. Refer Implementation Notes on why this is + // done in two steps on IE. + urlParsingNode.setAttribute("href", href); + href = urlParsingNode.href; + } + + urlParsingNode.setAttribute('href', href); + + // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils + return { + href: urlParsingNode.href, + protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', + host: urlParsingNode.host, + search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', + hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', + hostname: urlParsingNode.hostname, + port: urlParsingNode.port, + pathname: (urlParsingNode.pathname.charAt(0) === '/') + ? urlParsingNode.pathname + : '/' + urlParsingNode.pathname + }; +} + +/** + * Parse a request URL and determine whether this is a same-origin request as the application document. + * + * @param {string|object} requestUrl The url of the request as a string that will be resolved + * or a parsed URL object. + * @returns {boolean} Whether the request is for the same origin as the application document. + */ +function urlIsSameOrigin(requestUrl) { + var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl; + return (parsed.protocol === originUrl.protocol && + parsed.host === originUrl.host); +} + +/** + * @ngdoc object + * @name ng.$window + * + * @description + * A reference to the browser's `window` object. While `window` + * is globally available in JavaScript, it causes testability problems, because + * it is a global variable. In angular we always refer to it through the + * `$window` service, so it may be overridden, removed or mocked for testing. + * + * Expressions, like the one defined for the `ngClick` directive in the example + * below, are evaluated with respect to the current scope. Therefore, there is + * no risk of inadvertently coding in a dependency on a global value in such an + * expression. + * + * @example + + + +
+ + +
+
+ + it('should display the greeting in the input box', function() { + input('greeting').enter('Hello, E2E Tests'); + // If we click the button it will block the test runner + // element(':button').click(); + }); + +
+ */ +function $WindowProvider(){ + this.$get = valueFn(window); +} + +/** + * @ngdoc object + * @name ng.$filterProvider + * @description + * + * Filters are just functions which transform input to an output. However filters need to be + * Dependency Injected. To achieve this a filter definition consists of a factory function which is + * annotated with dependencies and is responsible for creating a filter function. + * + *
+ *   // Filter registration
+ *   function MyModule($provide, $filterProvider) {
+ *     // create a service to demonstrate injection (not always needed)
+ *     $provide.value('greet', function(name){
+ *       return 'Hello ' + name + '!';
+ *     });
+ *
+ *     // register a filter factory which uses the
+ *     // greet service to demonstrate DI.
+ *     $filterProvider.register('greet', function(greet){
+ *       // return the filter function which uses the greet service
+ *       // to generate salutation
+ *       return function(text) {
+ *         // filters need to be forgiving so check input validity
+ *         return text && greet(text) || text;
+ *       };
+ *     });
+ *   }
+ * 
+ * + * The filter function is registered with the `$injector` under the filter name suffix with + * `Filter`. + * + *
+ *   it('should be the same instance', inject(
+ *     function($filterProvider) {
+ *       $filterProvider.register('reverse', function(){
+ *         return ...;
+ *       });
+ *     },
+ *     function($filter, reverseFilter) {
+ *       expect($filter('reverse')).toBe(reverseFilter);
+ *     });
+ * 
+ * + * + * For more information about how angular filters work, and how to create your own filters, see + * {@link guide/filter Filters} in the Angular Developer Guide. + */ +/** + * @ngdoc method + * @name ng.$filterProvider#register + * @methodOf ng.$filterProvider + * @description + * Register filter factory function. + * + * @param {String} name Name of the filter. + * @param {function} fn The filter factory function which is injectable. + */ + + +/** + * @ngdoc function + * @name ng.$filter + * @function + * @description + * Filters are used for formatting data displayed to the user. + * + * The general syntax in templates is as follows: + * + * {{ expression [| filter_name[:parameter_value] ... ] }} + * + * @param {String} name Name of the filter function to retrieve + * @return {Function} the filter function + */ +$FilterProvider.$inject = ['$provide']; +function $FilterProvider($provide) { + var suffix = 'Filter'; + + /** + * @ngdoc function + * @name ng.$controllerProvider#register + * @methodOf ng.$controllerProvider + * @param {string|Object} name Name of the filter function, or an object map of filters where + * the keys are the filter names and the values are the filter factories. + * @returns {Object} Registered filter instance, or if a map of filters was provided then a map + * of the registered filter instances. + */ + function register(name, factory) { + if(isObject(name)) { + var filters = {}; + forEach(name, function(filter, key) { + filters[key] = register(key, filter); + }); + return filters; + } else { + return $provide.factory(name + suffix, factory); + } + } + this.register = register; + + this.$get = ['$injector', function($injector) { + return function(name) { + return $injector.get(name + suffix); + }; + }]; + + //////////////////////////////////////// + + /* global + currencyFilter: false, + dateFilter: false, + filterFilter: false, + jsonFilter: false, + limitToFilter: false, + lowercaseFilter: false, + numberFilter: false, + orderByFilter: false, + uppercaseFilter: false, + */ + + register('currency', currencyFilter); + register('date', dateFilter); + register('filter', filterFilter); + register('json', jsonFilter); + register('limitTo', limitToFilter); + register('lowercase', lowercaseFilter); + register('number', numberFilter); + register('orderBy', orderByFilter); + register('uppercase', uppercaseFilter); +} + +/** + * @ngdoc filter + * @name ng.filter:filter + * @function + * + * @description + * Selects a subset of items from `array` and returns it as a new array. + * + * @param {Array} array The source array. + * @param {string|Object|function()} expression The predicate to be used for selecting items from + * `array`. + * + * Can be one of: + * + * - `string`: Predicate that results in a substring match using the value of `expression` + * string. All strings or objects with string properties in `array` that contain this string + * will be returned. The predicate can be negated by prefixing the string with `!`. + * + * - `Object`: A pattern object can be used to filter specific properties on objects contained + * by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items + * which have property `name` containing "M" and property `phone` containing "1". A special + * property name `$` can be used (as in `{$:"text"}`) to accept a match against any + * property of the object. That's equivalent to the simple substring match with a `string` + * as described above. + * + * - `function`: A predicate function can be used to write arbitrary filters. The function is + * called for each element of `array`. The final result is an array of those elements that + * the predicate returned true for. + * + * @param {function(expected, actual)|true|undefined} comparator Comparator which is used in + * determining if the expected value (from the filter expression) and actual value (from + * the object in the array) should be considered a match. + * + * Can be one of: + * + * - `function(expected, actual)`: + * The function will be given the object value and the predicate value to compare and + * should return true if the item should be included in filtered result. + * + * - `true`: A shorthand for `function(expected, actual) { return angular.equals(expected, actual)}`. + * this is essentially strict comparison of expected and actual. + * + * - `false|undefined`: A short hand for a function which will look for a substring match in case + * insensitive way. + * + * @example + + +
+ + Search: + + + + + + +
NamePhone
{{friend.name}}{{friend.phone}}
+
+ Any:
+ Name only
+ Phone only
+ Equality
+ + + + + + +
NamePhone
{{friend.name}}{{friend.phone}}
+
+ + it('should search across all fields when filtering with a string', function() { + input('searchText').enter('m'); + expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')). + toEqual(['Mary', 'Mike', 'Adam']); + + input('searchText').enter('76'); + expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')). + toEqual(['John', 'Julie']); + }); + + it('should search in specific fields when filtering with a predicate object', function() { + input('search.$').enter('i'); + expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')). + toEqual(['Mary', 'Mike', 'Julie', 'Juliette']); + }); + it('should use a equal comparison when comparator is true', function() { + input('search.name').enter('Julie'); + input('strict').check(); + expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')). + toEqual(['Julie']); + }); + +
+ */ +function filterFilter() { + return function(array, expression, comparator) { + if (!isArray(array)) return array; + + var comparatorType = typeof(comparator), + predicates = []; + + predicates.check = function(value) { + for (var j = 0; j < predicates.length; j++) { + if(!predicates[j](value)) { + return false; + } + } + return true; + }; + + if (comparatorType !== 'function') { + if (comparatorType === 'boolean' && comparator) { + comparator = function(obj, text) { + return angular.equals(obj, text); + }; + } else { + comparator = function(obj, text) { + text = (''+text).toLowerCase(); + return (''+obj).toLowerCase().indexOf(text) > -1; + }; + } + } + + var search = function(obj, text){ + if (typeof text == 'string' && text.charAt(0) === '!') { + return !search(obj, text.substr(1)); + } + switch (typeof obj) { + case "boolean": + case "number": + case "string": + return comparator(obj, text); + case "object": + switch (typeof text) { + case "object": + return comparator(obj, text); + default: + for ( var objKey in obj) { + if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) { + return true; + } + } + break; + } + return false; + case "array": + for ( var i = 0; i < obj.length; i++) { + if (search(obj[i], text)) { + return true; + } + } + return false; + default: + return false; + } + }; + switch (typeof expression) { + case "boolean": + case "number": + case "string": + // Set up expression object and fall through + expression = {$:expression}; + // jshint -W086 + case "object": + // jshint +W086 + for (var key in expression) { + if (key == '$') { + (function() { + if (!expression[key]) return; + var path = key; + predicates.push(function(value) { + return search(value, expression[path]); + }); + })(); + } else { + (function() { + if (typeof(expression[key]) == 'undefined') { return; } + var path = key; + predicates.push(function(value) { + return search(getter(value,path), expression[path]); + }); + })(); + } + } + break; + case 'function': + predicates.push(expression); + break; + default: + return array; + } + var filtered = []; + for ( var j = 0; j < array.length; j++) { + var value = array[j]; + if (predicates.check(value)) { + filtered.push(value); + } + } + return filtered; + }; +} + +/** + * @ngdoc filter + * @name ng.filter:currency + * @function + * + * @description + * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default + * symbol for current locale is used. + * + * @param {number} amount Input to filter. + * @param {string=} symbol Currency symbol or identifier to be displayed. + * @returns {string} Formatted number. + * + * + * @example + + + +
+
+ default currency symbol ($): {{amount | currency}}
+ custom currency identifier (USD$): {{amount | currency:"USD$"}} +
+
+ + it('should init with 1234.56', function() { + expect(binding('amount | currency')).toBe('$1,234.56'); + expect(binding('amount | currency:"USD$"')).toBe('USD$1,234.56'); + }); + it('should update', function() { + input('amount').enter('-1234'); + expect(binding('amount | currency')).toBe('($1,234.00)'); + expect(binding('amount | currency:"USD$"')).toBe('(USD$1,234.00)'); + }); + +
+ */ +currencyFilter.$inject = ['$locale']; +function currencyFilter($locale) { + var formats = $locale.NUMBER_FORMATS; + return function(amount, currencySymbol){ + if (isUndefined(currencySymbol)) currencySymbol = formats.CURRENCY_SYM; + return formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, 2). + replace(/\u00A4/g, currencySymbol); + }; +} + +/** + * @ngdoc filter + * @name ng.filter:number + * @function + * + * @description + * Formats a number as text. + * + * If the input is not a number an empty string is returned. + * + * @param {number|string} number Number to format. + * @param {(number|string)=} fractionSize Number of decimal places to round the number to. + * If this is not provided then the fraction size is computed from the current locale's number + * formatting pattern. In the case of the default locale, it will be 3. + * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit. + * + * @example + + + +
+ Enter number:
+ Default formatting: {{val | number}}
+ No fractions: {{val | number:0}}
+ Negative number: {{-val | number:4}} +
+
+ + it('should format numbers', function() { + expect(binding('val | number')).toBe('1,234.568'); + expect(binding('val | number:0')).toBe('1,235'); + expect(binding('-val | number:4')).toBe('-1,234.5679'); + }); + + it('should update', function() { + input('val').enter('3374.333'); + expect(binding('val | number')).toBe('3,374.333'); + expect(binding('val | number:0')).toBe('3,374'); + expect(binding('-val | number:4')).toBe('-3,374.3330'); + }); + +
+ */ + + +numberFilter.$inject = ['$locale']; +function numberFilter($locale) { + var formats = $locale.NUMBER_FORMATS; + return function(number, fractionSize) { + return formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP, + fractionSize); + }; +} + +var DECIMAL_SEP = '.'; +function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { + if (isNaN(number) || !isFinite(number)) return ''; + + var isNegative = number < 0; + number = Math.abs(number); + var numStr = number + '', + formatedText = '', + parts = []; + + var hasExponent = false; + if (numStr.indexOf('e') !== -1) { + var match = numStr.match(/([\d\.]+)e(-?)(\d+)/); + if (match && match[2] == '-' && match[3] > fractionSize + 1) { + numStr = '0'; + } else { + formatedText = numStr; + hasExponent = true; + } + } + + if (!hasExponent) { + var fractionLen = (numStr.split(DECIMAL_SEP)[1] || '').length; + + // determine fractionSize if it is not specified + if (isUndefined(fractionSize)) { + fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac); + } + + var pow = Math.pow(10, fractionSize); + number = Math.round(number * pow) / pow; + var fraction = ('' + number).split(DECIMAL_SEP); + var whole = fraction[0]; + fraction = fraction[1] || ''; + + var i, pos = 0, + lgroup = pattern.lgSize, + group = pattern.gSize; + + if (whole.length >= (lgroup + group)) { + pos = whole.length - lgroup; + for (i = 0; i < pos; i++) { + if ((pos - i)%group === 0 && i !== 0) { + formatedText += groupSep; + } + formatedText += whole.charAt(i); + } + } + + for (i = pos; i < whole.length; i++) { + if ((whole.length - i)%lgroup === 0 && i !== 0) { + formatedText += groupSep; + } + formatedText += whole.charAt(i); + } + + // format fraction part. + while(fraction.length < fractionSize) { + fraction += '0'; + } + + if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize); + } else { + + if (fractionSize > 0 && number > -1 && number < 1) { + formatedText = number.toFixed(fractionSize); + } + } + + parts.push(isNegative ? pattern.negPre : pattern.posPre); + parts.push(formatedText); + parts.push(isNegative ? pattern.negSuf : pattern.posSuf); + return parts.join(''); +} + +function padNumber(num, digits, trim) { + var neg = ''; + if (num < 0) { + neg = '-'; + num = -num; + } + num = '' + num; + while(num.length < digits) num = '0' + num; + if (trim) + num = num.substr(num.length - digits); + return neg + num; +} + + +function dateGetter(name, size, offset, trim) { + offset = offset || 0; + return function(date) { + var value = date['get' + name](); + if (offset > 0 || value > -offset) + value += offset; + if (value === 0 && offset == -12 ) value = 12; + return padNumber(value, size, trim); + }; +} + +function dateStrGetter(name, shortForm) { + return function(date, formats) { + var value = date['get' + name](); + var get = uppercase(shortForm ? ('SHORT' + name) : name); + + return formats[get][value]; + }; +} + +function timeZoneGetter(date) { + var zone = -1 * date.getTimezoneOffset(); + var paddedZone = (zone >= 0) ? "+" : ""; + + paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) + + padNumber(Math.abs(zone % 60), 2); + + return paddedZone; +} + +function ampmGetter(date, formats) { + return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1]; +} + +var DATE_FORMATS = { + yyyy: dateGetter('FullYear', 4), + yy: dateGetter('FullYear', 2, 0, true), + y: dateGetter('FullYear', 1), + MMMM: dateStrGetter('Month'), + MMM: dateStrGetter('Month', true), + MM: dateGetter('Month', 2, 1), + M: dateGetter('Month', 1, 1), + dd: dateGetter('Date', 2), + d: dateGetter('Date', 1), + HH: dateGetter('Hours', 2), + H: dateGetter('Hours', 1), + hh: dateGetter('Hours', 2, -12), + h: dateGetter('Hours', 1, -12), + mm: dateGetter('Minutes', 2), + m: dateGetter('Minutes', 1), + ss: dateGetter('Seconds', 2), + s: dateGetter('Seconds', 1), + // while ISO 8601 requires fractions to be prefixed with `.` or `,` + // we can be just safely rely on using `sss` since we currently don't support single or two digit fractions + sss: dateGetter('Milliseconds', 3), + EEEE: dateStrGetter('Day'), + EEE: dateStrGetter('Day', true), + a: ampmGetter, + Z: timeZoneGetter +}; + +var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/, + NUMBER_STRING = /^\-?\d+$/; + +/** + * @ngdoc filter + * @name ng.filter:date + * @function + * + * @description + * Formats `date` to a string based on the requested `format`. + * + * `format` string can be composed of the following elements: + * + * * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010) + * * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) + * * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199) + * * `'MMMM'`: Month in year (January-December) + * * `'MMM'`: Month in year (Jan-Dec) + * * `'MM'`: Month in year, padded (01-12) + * * `'M'`: Month in year (1-12) + * * `'dd'`: Day in month, padded (01-31) + * * `'d'`: Day in month (1-31) + * * `'EEEE'`: Day in Week,(Sunday-Saturday) + * * `'EEE'`: Day in Week, (Sun-Sat) + * * `'HH'`: Hour in day, padded (00-23) + * * `'H'`: Hour in day (0-23) + * * `'hh'`: Hour in am/pm, padded (01-12) + * * `'h'`: Hour in am/pm, (1-12) + * * `'mm'`: Minute in hour, padded (00-59) + * * `'m'`: Minute in hour (0-59) + * * `'ss'`: Second in minute, padded (00-59) + * * `'s'`: Second in minute (0-59) + * * `'.sss' or ',sss'`: Millisecond in second, padded (000-999) + * * `'a'`: am/pm marker + * * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200) + * + * `format` string can also be one of the following predefined + * {@link guide/i18n localizable formats}: + * + * * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale + * (e.g. Sep 3, 2010 12:05:08 pm) + * * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US locale (e.g. 9/3/10 12:05 pm) + * * `'fullDate'`: equivalent to `'EEEE, MMMM d,y'` for en_US locale + * (e.g. Friday, September 3, 2010) + * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010) + * * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US locale (e.g. Sep 3, 2010) + * * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10) + * * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm) + * * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 pm) + * + * `format` string can contain literal values. These need to be quoted with single quotes (e.g. + * `"h 'in the morning'"`). In order to output single quote, use two single quotes in a sequence + * (e.g. `"h 'o''clock'"`). + * + * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or + * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its + * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is + * specified in the string input, the time is considered to be in the local timezone. + * @param {string=} format Formatting rules (see Description). If not specified, + * `mediumDate` is used. + * @returns {string} Formatted string or the input if input is not recognized as date/millis. + * + * @example + + + {{1288323623006 | date:'medium'}}: + {{1288323623006 | date:'medium'}}
+ {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}: + {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
+ {{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}: + {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
+
+ + it('should format date', function() { + expect(binding("1288323623006 | date:'medium'")). + toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/); + expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")). + toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/); + expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")). + toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/); + }); + +
+ */ +dateFilter.$inject = ['$locale']; +function dateFilter($locale) { + + + var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; + // 1 2 3 4 5 6 7 8 9 10 11 + function jsonStringToDate(string) { + var match; + if (match = string.match(R_ISO8601_STR)) { + var date = new Date(0), + tzHour = 0, + tzMin = 0, + dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear, + timeSetter = match[8] ? date.setUTCHours : date.setHours; + + if (match[9]) { + tzHour = int(match[9] + match[10]); + tzMin = int(match[9] + match[11]); + } + dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3])); + var h = int(match[4]||0) - tzHour; + var m = int(match[5]||0) - tzMin; + var s = int(match[6]||0); + var ms = Math.round(parseFloat('0.' + (match[7]||0)) * 1000); + timeSetter.call(date, h, m, s, ms); + return date; + } + return string; + } + + + return function(date, format) { + var text = '', + parts = [], + fn, match; + + format = format || 'mediumDate'; + format = $locale.DATETIME_FORMATS[format] || format; + if (isString(date)) { + if (NUMBER_STRING.test(date)) { + date = int(date); + } else { + date = jsonStringToDate(date); + } + } + + if (isNumber(date)) { + date = new Date(date); + } + + if (!isDate(date)) { + return date; + } + + while(format) { + match = DATE_FORMATS_SPLIT.exec(format); + if (match) { + parts = concat(parts, match, 1); + format = parts.pop(); + } else { + parts.push(format); + format = null; + } + } + + forEach(parts, function(value){ + fn = DATE_FORMATS[value]; + text += fn ? fn(date, $locale.DATETIME_FORMATS) + : value.replace(/(^'|'$)/g, '').replace(/''/g, "'"); + }); + + return text; + }; +} + + +/** + * @ngdoc filter + * @name ng.filter:json + * @function + * + * @description + * Allows you to convert a JavaScript object into JSON string. + * + * This filter is mostly useful for debugging. When using the double curly {{value}} notation + * the binding is automatically converted to JSON. + * + * @param {*} object Any JavaScript object (including arrays and primitive types) to filter. + * @returns {string} JSON string. + * + * + * @example: + + +
{{ {'name':'value'} | json }}
+
+ + it('should jsonify filtered objects', function() { + expect(binding("{'name':'value'}")).toMatch(/\{\n "name": ?"value"\n}/); + }); + +
+ * + */ +function jsonFilter() { + return function(object) { + return toJson(object, true); + }; +} + + +/** + * @ngdoc filter + * @name ng.filter:lowercase + * @function + * @description + * Converts string to lowercase. + * @see angular.lowercase + */ +var lowercaseFilter = valueFn(lowercase); + + +/** + * @ngdoc filter + * @name ng.filter:uppercase + * @function + * @description + * Converts string to uppercase. + * @see angular.uppercase + */ +var uppercaseFilter = valueFn(uppercase); + +/** + * @ngdoc function + * @name ng.filter:limitTo + * @function + * + * @description + * Creates a new array or string containing only a specified number of elements. The elements + * are taken from either the beginning or the end of the source array or string, as specified by + * the value and sign (positive or negative) of `limit`. + * + * @param {Array|string} input Source array or string to be limited. + * @param {string|number} limit The length of the returned array or string. If the `limit` number + * is positive, `limit` number of items from the beginning of the source array/string are copied. + * If the number is negative, `limit` number of items from the end of the source array/string + * are copied. The `limit` will be trimmed if it exceeds `array.length` + * @returns {Array|string} A new sub-array or substring of length `limit` or less if input array + * had less than `limit` elements. + * + * @example + + + +
+ Limit {{numbers}} to: +

Output numbers: {{ numbers | limitTo:numLimit }}

+ Limit {{letters}} to: +

Output letters: {{ letters | limitTo:letterLimit }}

+
+
+ + it('should limit the number array to first three items', function() { + expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3'); + expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3'); + expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]'); + expect(binding('letters | limitTo:letterLimit')).toEqual('abc'); + }); + + it('should update the output when -3 is entered', function() { + input('numLimit').enter(-3); + input('letterLimit').enter(-3); + expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]'); + expect(binding('letters | limitTo:letterLimit')).toEqual('ghi'); + }); + + it('should not exceed the maximum size of input array', function() { + input('numLimit').enter(100); + input('letterLimit').enter(100); + expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]'); + expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi'); + }); + +
+ */ +function limitToFilter(){ + return function(input, limit) { + if (!isArray(input) && !isString(input)) return input; + + limit = int(limit); + + if (isString(input)) { + //NaN check on limit + if (limit) { + return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length); + } else { + return ""; + } + } + + var out = [], + i, n; + + // if abs(limit) exceeds maximum length, trim it + if (limit > input.length) + limit = input.length; + else if (limit < -input.length) + limit = -input.length; + + if (limit > 0) { + i = 0; + n = limit; + } else { + i = input.length + limit; + n = input.length; + } + + for (; i} expression A predicate to be + * used by the comparator to determine the order of elements. + * + * Can be one of: + * + * - `function`: Getter function. The result of this function will be sorted using the + * `<`, `=`, `>` operator. + * - `string`: An Angular expression which evaluates to an object to order by, such as 'name' + * to sort by a property called 'name'. Optionally prefixed with `+` or `-` to control + * ascending or descending sort order (for example, +name or -name). + * - `Array`: An array of function or string predicates. The first predicate in the array + * is used for sorting, but when two items are equivalent, the next predicate is used. + * + * @param {boolean=} reverse Reverse the order the array. + * @returns {Array} Sorted copy of the source array. + * + * @example + + + +
+
Sorting predicate = {{predicate}}; reverse = {{reverse}}
+
+ [ unsorted ] + + + + + + + + + + + +
Name + (^)Phone NumberAge
{{friend.name}}{{friend.phone}}{{friend.age}}
+
+
+ + it('should be reverse ordered by aged', function() { + expect(binding('predicate')).toBe('-age'); + expect(repeater('table.friend', 'friend in friends').column('friend.age')). + toEqual(['35', '29', '21', '19', '10']); + expect(repeater('table.friend', 'friend in friends').column('friend.name')). + toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']); + }); + + it('should reorder the table when user selects different predicate', function() { + element('.doc-example-live a:contains("Name")').click(); + expect(repeater('table.friend', 'friend in friends').column('friend.name')). + toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']); + expect(repeater('table.friend', 'friend in friends').column('friend.age')). + toEqual(['35', '10', '29', '19', '21']); + + element('.doc-example-live a:contains("Phone")').click(); + expect(repeater('table.friend', 'friend in friends').column('friend.phone')). + toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']); + expect(repeater('table.friend', 'friend in friends').column('friend.name')). + toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']); + }); + +
+ */ +orderByFilter.$inject = ['$parse']; +function orderByFilter($parse){ + return function(array, sortPredicate, reverseOrder) { + if (!isArray(array)) return array; + if (!sortPredicate) return array; + sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate]; + sortPredicate = map(sortPredicate, function(predicate){ + var descending = false, get = predicate || identity; + if (isString(predicate)) { + if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) { + descending = predicate.charAt(0) == '-'; + predicate = predicate.substring(1); + } + get = $parse(predicate); + } + return reverseComparator(function(a,b){ + return compare(get(a),get(b)); + }, descending); + }); + var arrayCopy = []; + for ( var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); } + return arrayCopy.sort(reverseComparator(comparator, reverseOrder)); + + function comparator(o1, o2){ + for ( var i = 0; i < sortPredicate.length; i++) { + var comp = sortPredicate[i](o1, o2); + if (comp !== 0) return comp; + } + return 0; + } + function reverseComparator(comp, descending) { + return toBoolean(descending) + ? function(a,b){return comp(b,a);} + : comp; + } + function compare(v1, v2){ + var t1 = typeof v1; + var t2 = typeof v2; + if (t1 == t2) { + if (t1 == "string") { + v1 = v1.toLowerCase(); + v2 = v2.toLowerCase(); + } + if (v1 === v2) return 0; + return v1 < v2 ? -1 : 1; + } else { + return t1 < t2 ? -1 : 1; + } + } + }; +} + +function ngDirective(directive) { + if (isFunction(directive)) { + directive = { + link: directive + }; + } + directive.restrict = directive.restrict || 'AC'; + return valueFn(directive); +} + +/** + * @ngdoc directive + * @name ng.directive:a + * @restrict E + * + * @description + * Modifies the default behavior of the html A tag so that the default action is prevented when + * the href attribute is empty. + * + * This change permits the easy creation of action links with the `ngClick` directive + * without changing the location or causing page reloads, e.g.: + * `Add Item` + */ +var htmlAnchorDirective = valueFn({ + restrict: 'E', + compile: function(element, attr) { + + if (msie <= 8) { + + // turn link into a stylable link in IE + // but only if it doesn't have name attribute, in which case it's an anchor + if (!attr.href && !attr.name) { + attr.$set('href', ''); + } + + // add a comment node to anchors to workaround IE bug that causes element content to be reset + // to new attribute content if attribute is updated with value containing @ and element also + // contains value with @ + // see issue #1949 + element.append(document.createComment('IE fix')); + } + + return function(scope, element) { + element.on('click', function(event){ + // if we have no href url, then don't navigate anywhere. + if (!element.attr('href')) { + event.preventDefault(); + } + }); + }; + } +}); + +/** + * @ngdoc directive + * @name ng.directive:ngHref + * @restrict A + * + * @description + * Using Angular markup like `{{hash}}` in an href attribute will + * make the link go to the wrong URL if the user clicks it before + * Angular has a chance to replace the `{{hash}}` markup with its + * value. Until Angular replaces the markup the link will be broken + * and will most likely return a 404 error. + * + * The `ngHref` directive solves this problem. + * + * The wrong way to write it: + *
+ * 
+ * 
+ * + * The correct way to write it: + *
+ * 
+ * 
+ * + * @element A + * @param {template} ngHref any string which can contain `{{}}` markup. + * + * @example + * This example shows various combinations of `href`, `ng-href` and `ng-click` attributes + * in links and their different behaviors: + + +
+
link 1 (link, don't reload)
+ link 2 (link, don't reload)
+ link 3 (link, reload!)
+ anchor (link, don't reload)
+ anchor (no link)
+ link (link, change location) + + + it('should execute ng-click but not reload when href without value', function() { + element('#link-1').click(); + expect(input('value').val()).toEqual('1'); + expect(element('#link-1').attr('href')).toBe(""); + }); + + it('should execute ng-click but not reload when href empty string', function() { + element('#link-2').click(); + expect(input('value').val()).toEqual('2'); + expect(element('#link-2').attr('href')).toBe(""); + }); + + it('should execute ng-click and change url when ng-href specified', function() { + expect(element('#link-3').attr('href')).toBe("/123"); + + element('#link-3').click(); + expect(browser().window().path()).toEqual('/123'); + }); + + it('should execute ng-click but not reload when href empty string and name specified', function() { + element('#link-4').click(); + expect(input('value').val()).toEqual('4'); + expect(element('#link-4').attr('href')).toBe(''); + }); + + it('should execute ng-click but not reload when no href but name specified', function() { + element('#link-5').click(); + expect(input('value').val()).toEqual('5'); + expect(element('#link-5').attr('href')).toBe(undefined); + }); + + it('should only change url when only ng-href', function() { + input('value').enter('6'); + expect(element('#link-6').attr('href')).toBe('6'); + + element('#link-6').click(); + expect(browser().location().url()).toEqual('/6'); + }); + + + */ + +/** + * @ngdoc directive + * @name ng.directive:ngSrc + * @restrict A + * + * @description + * Using Angular markup like `{{hash}}` in a `src` attribute doesn't + * work right: The browser will fetch from the URL with the literal + * text `{{hash}}` until Angular replaces the expression inside + * `{{hash}}`. The `ngSrc` directive solves this problem. + * + * The buggy way to write it: + *
+ * 
+ * 
+ * + * The correct way to write it: + *
+ * 
+ * 
+ * + * @element IMG + * @param {template} ngSrc any string which can contain `{{}}` markup. + */ + +/** + * @ngdoc directive + * @name ng.directive:ngSrcset + * @restrict A + * + * @description + * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't + * work right: The browser will fetch from the URL with the literal + * text `{{hash}}` until Angular replaces the expression inside + * `{{hash}}`. The `ngSrcset` directive solves this problem. + * + * The buggy way to write it: + *
+ * 
+ * 
+ * + * The correct way to write it: + *
+ * 
+ * 
+ * + * @element IMG + * @param {template} ngSrcset any string which can contain `{{}}` markup. + */ + +/** + * @ngdoc directive + * @name ng.directive:ngDisabled + * @restrict A + * + * @description + * + * The following markup will make the button enabled on Chrome/Firefox but not on IE8 and older IEs: + *
+ * 
+ * + *
+ *
+ * + * The HTML specification does not require browsers to preserve the values of boolean attributes + * such as disabled. (Their presence means true and their absence means false.) + * If we put an Angular interpolation expression into such an attribute then the + * binding information would be lost when the browser removes the attribute. + * The `ngDisabled` directive solves this problem for the `disabled` attribute. + * This complementary directive is not removed by the browser and so provides + * a permanent reliable place to store the binding information. + * + * @example + + + Click me to toggle:
+ +
+ + it('should toggle button', function() { + expect(element('.doc-example-live :button').prop('disabled')).toBeFalsy(); + input('checked').check(); + expect(element('.doc-example-live :button').prop('disabled')).toBeTruthy(); + }); + +
+ * + * @element INPUT + * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy, + * then special attribute "disabled" will be set on the element + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngChecked + * @restrict A + * + * @description + * The HTML specification does not require browsers to preserve the values of boolean attributes + * such as checked. (Their presence means true and their absence means false.) + * If we put an Angular interpolation expression into such an attribute then the + * binding information would be lost when the browser removes the attribute. + * The `ngChecked` directive solves this problem for the `checked` attribute. + * This complementary directive is not removed by the browser and so provides + * a permanent reliable place to store the binding information. + * @example + + + Check me to check both:
+ +
+ + it('should check both checkBoxes', function() { + expect(element('.doc-example-live #checkSlave').prop('checked')).toBeFalsy(); + input('master').check(); + expect(element('.doc-example-live #checkSlave').prop('checked')).toBeTruthy(); + }); + +
+ * + * @element INPUT + * @param {expression} ngChecked If the {@link guide/expression expression} is truthy, + * then special attribute "checked" will be set on the element + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngReadonly + * @restrict A + * + * @description + * The HTML specification does not require browsers to preserve the values of boolean attributes + * such as readonly. (Their presence means true and their absence means false.) + * If we put an Angular interpolation expression into such an attribute then the + * binding information would be lost when the browser removes the attribute. + * The `ngReadonly` directive solves this problem for the `readonly` attribute. + * This complementary directive is not removed by the browser and so provides + * a permanent reliable place to store the binding information. + + * @example + + + Check me to make text readonly:
+ +
+ + it('should toggle readonly attr', function() { + expect(element('.doc-example-live :text').prop('readonly')).toBeFalsy(); + input('checked').check(); + expect(element('.doc-example-live :text').prop('readonly')).toBeTruthy(); + }); + +
+ * + * @element INPUT + * @param {expression} ngReadonly If the {@link guide/expression expression} is truthy, + * then special attribute "readonly" will be set on the element + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngSelected + * @restrict A + * + * @description + * The HTML specification does not require browsers to preserve the values of boolean attributes + * such as selected. (Their presence means true and their absence means false.) + * If we put an Angular interpolation expression into such an attribute then the + * binding information would be lost when the browser removes the attribute. + * The `ngSelected` directive solves this problem for the `selected` atttribute. + * This complementary directive is not removed by the browser and so provides + * a permanent reliable place to store the binding information. + * @example + + + Check me to select:
+ +
+ + it('should select Greetings!', function() { + expect(element('.doc-example-live #greet').prop('selected')).toBeFalsy(); + input('selected').check(); + expect(element('.doc-example-live #greet').prop('selected')).toBeTruthy(); + }); + +
+ * + * @element OPTION + * @param {expression} ngSelected If the {@link guide/expression expression} is truthy, + * then special attribute "selected" will be set on the element + */ + +/** + * @ngdoc directive + * @name ng.directive:ngOpen + * @restrict A + * + * @description + * The HTML specification does not require browsers to preserve the values of boolean attributes + * such as open. (Their presence means true and their absence means false.) + * If we put an Angular interpolation expression into such an attribute then the + * binding information would be lost when the browser removes the attribute. + * The `ngOpen` directive solves this problem for the `open` attribute. + * This complementary directive is not removed by the browser and so provides + * a permanent reliable place to store the binding information. + + * + * @example + + + Check me check multiple:
+
+ Show/Hide me +
+
+ + it('should toggle open', function() { + expect(element('#details').prop('open')).toBeFalsy(); + input('open').check(); + expect(element('#details').prop('open')).toBeTruthy(); + }); + +
+ * + * @element DETAILS + * @param {expression} ngOpen If the {@link guide/expression expression} is truthy, + * then special attribute "open" will be set on the element + */ + +var ngAttributeAliasDirectives = {}; + + +// boolean attrs are evaluated +forEach(BOOLEAN_ATTR, function(propName, attrName) { + // binding to multiple is not supported + if (propName == "multiple") return; + + var normalized = directiveNormalize('ng-' + attrName); + ngAttributeAliasDirectives[normalized] = function() { + return { + priority: 100, + compile: function() { + return function(scope, element, attr) { + scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) { + attr.$set(attrName, !!value); + }); + }; + } + }; + }; +}); + + +// ng-src, ng-srcset, ng-href are interpolated +forEach(['src', 'srcset', 'href'], function(attrName) { + var normalized = directiveNormalize('ng-' + attrName); + ngAttributeAliasDirectives[normalized] = function() { + return { + priority: 99, // it needs to run after the attributes are interpolated + link: function(scope, element, attr) { + attr.$observe(normalized, function(value) { + if (!value) + return; + + attr.$set(attrName, value); + + // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist + // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need + // to set the property as well to achieve the desired effect. + // we use attr[attrName] value since $set can sanitize the url. + if (msie) element.prop(attrName, attr[attrName]); + }); + } + }; + }; +}); + +/* global -nullFormCtrl */ +var nullFormCtrl = { + $addControl: noop, + $removeControl: noop, + $setValidity: noop, + $setDirty: noop, + $setPristine: noop +}; + +/** + * @ngdoc object + * @name ng.directive:form.FormController + * + * @property {boolean} $pristine True if user has not interacted with the form yet. + * @property {boolean} $dirty True if user has already interacted with the form. + * @property {boolean} $valid True if all of the containing forms and controls are valid. + * @property {boolean} $invalid True if at least one containing control or form is invalid. + * + * @property {Object} $error Is an object hash, containing references to all invalid controls or + * forms, where: + * + * - keys are validation tokens (error names) — such as `required`, `url` or `email`, + * - values are arrays of controls or forms that are invalid with given error. + * + * @description + * `FormController` keeps track of all its controls and nested forms as well as state of them, + * such as being valid/invalid or dirty/pristine. + * + * Each {@link ng.directive:form form} directive creates an instance + * of `FormController`. + * + */ +//asks for $scope to fool the BC controller module +FormController.$inject = ['$element', '$attrs', '$scope']; +function FormController(element, attrs) { + var form = this, + parentForm = element.parent().controller('form') || nullFormCtrl, + invalidCount = 0, // used to easily determine if we are valid + errors = form.$error = {}, + controls = []; + + // init state + form.$name = attrs.name || attrs.ngForm; + form.$dirty = false; + form.$pristine = true; + form.$valid = true; + form.$invalid = false; + + parentForm.$addControl(form); + + // Setup initial state of the control + element.addClass(PRISTINE_CLASS); + toggleValidCss(true); + + // convenience method for easy toggling of classes + function toggleValidCss(isValid, validationErrorKey) { + validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; + element. + removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey). + addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey); + } + + /** + * @ngdoc function + * @name ng.directive:form.FormController#$addControl + * @methodOf ng.directive:form.FormController + * + * @description + * Register a control with the form. + * + * Input elements using ngModelController do this automatically when they are linked. + */ + form.$addControl = function(control) { + // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored + // and not added to the scope. Now we throw an error. + assertNotHasOwnProperty(control.$name, 'input'); + controls.push(control); + + if (control.$name) { + form[control.$name] = control; + } + }; + + /** + * @ngdoc function + * @name ng.directive:form.FormController#$removeControl + * @methodOf ng.directive:form.FormController + * + * @description + * Deregister a control from the form. + * + * Input elements using ngModelController do this automatically when they are destroyed. + */ + form.$removeControl = function(control) { + if (control.$name && form[control.$name] === control) { + delete form[control.$name]; + } + forEach(errors, function(queue, validationToken) { + form.$setValidity(validationToken, true, control); + }); + + arrayRemove(controls, control); + }; + + /** + * @ngdoc function + * @name ng.directive:form.FormController#$setValidity + * @methodOf ng.directive:form.FormController + * + * @description + * Sets the validity of a form control. + * + * This method will also propagate to parent forms. + */ + form.$setValidity = function(validationToken, isValid, control) { + var queue = errors[validationToken]; + + if (isValid) { + if (queue) { + arrayRemove(queue, control); + if (!queue.length) { + invalidCount--; + if (!invalidCount) { + toggleValidCss(isValid); + form.$valid = true; + form.$invalid = false; + } + errors[validationToken] = false; + toggleValidCss(true, validationToken); + parentForm.$setValidity(validationToken, true, form); + } + } + + } else { + if (!invalidCount) { + toggleValidCss(isValid); + } + if (queue) { + if (includes(queue, control)) return; + } else { + errors[validationToken] = queue = []; + invalidCount++; + toggleValidCss(false, validationToken); + parentForm.$setValidity(validationToken, false, form); + } + queue.push(control); + + form.$valid = false; + form.$invalid = true; + } + }; + + /** + * @ngdoc function + * @name ng.directive:form.FormController#$setDirty + * @methodOf ng.directive:form.FormController + * + * @description + * Sets the form to a dirty state. + * + * This method can be called to add the 'ng-dirty' class and set the form to a dirty + * state (ng-dirty class). This method will also propagate to parent forms. + */ + form.$setDirty = function() { + element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS); + form.$dirty = true; + form.$pristine = false; + parentForm.$setDirty(); + }; + + /** + * @ngdoc function + * @name ng.directive:form.FormController#$setPristine + * @methodOf ng.directive:form.FormController + * + * @description + * Sets the form to its pristine state. + * + * This method can be called to remove the 'ng-dirty' class and set the form to its pristine + * state (ng-pristine class). This method will also propagate to all the controls contained + * in this form. + * + * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after + * saving or resetting it. + */ + form.$setPristine = function () { + element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS); + form.$dirty = false; + form.$pristine = true; + forEach(controls, function(control) { + control.$setPristine(); + }); + }; +} + + +/** + * @ngdoc directive + * @name ng.directive:ngForm + * @restrict EAC + * + * @description + * Nestable alias of {@link ng.directive:form `form`} directive. HTML + * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a + * sub-group of controls needs to be determined. + * + * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into + * related scope, under this name. + * + */ + + /** + * @ngdoc directive + * @name ng.directive:form + * @restrict E + * + * @description + * Directive that instantiates + * {@link ng.directive:form.FormController FormController}. + * + * If the `name` attribute is specified, the form controller is published onto the current scope under + * this name. + * + * # Alias: {@link ng.directive:ngForm `ngForm`} + * + * In Angular forms can be nested. This means that the outer form is valid when all of the child + * forms are valid as well. However, browsers do not allow nesting of `
` elements, so + * Angular provides the {@link ng.directive:ngForm `ngForm`} directive which behaves identically to + * `` but can be nested. This allows you to have nested forms, which is very useful when + * using Angular validation directives in forms that are dynamically generated using the + * {@link ng.directive:ngRepeat `ngRepeat`} directive. Since you cannot dynamically generate the `name` + * attribute of input elements using interpolation, you have to wrap each set of repeated inputs in an + * `ngForm` directive and nest these in an outer `form` element. + * + * + * # CSS classes + * - `ng-valid` Is set if the form is valid. + * - `ng-invalid` Is set if the form is invalid. + * - `ng-pristine` Is set if the form is pristine. + * - `ng-dirty` Is set if the form is dirty. + * + * + * # Submitting a form and preventing the default action + * + * Since the role of forms in client-side Angular applications is different than in classical + * roundtrip apps, it is desirable for the browser not to translate the form submission into a full + * page reload that sends the data to the server. Instead some javascript logic should be triggered + * to handle the form submission in an application-specific way. + * + * For this reason, Angular prevents the default action (form submission to the server) unless the + * `` element has an `action` attribute specified. + * + * You can use one of the following two ways to specify what javascript method should be called when + * a form is submitted: + * + * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element + * - {@link ng.directive:ngClick ngClick} directive on the first + * button or input field of type submit (input[type=submit]) + * + * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit} + * or {@link ng.directive:ngClick ngClick} directives. + * This is because of the following form submission rules in the HTML specification: + * + * - If a form has only one input field then hitting enter in this field triggers form submit + * (`ngSubmit`) + * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter + * doesn't trigger submit + * - if a form has one or more input fields and one or more buttons or input[type=submit] then + * hitting enter in any of the input fields will trigger the click handler on the *first* button or + * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`) + * + * @param {string=} name Name of the form. If specified, the form controller will be published into + * related scope, under this name. + * + * @example + + + + + userType: + Required!
+ userType = {{userType}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+ +
+ + it('should initialize to model', function() { + expect(binding('userType')).toEqual('guest'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('userType').enter(''); + expect(binding('userType')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
+ */ +var formDirectiveFactory = function(isNgForm) { + return ['$timeout', function($timeout) { + var formDirective = { + name: 'form', + restrict: isNgForm ? 'EAC' : 'E', + controller: FormController, + compile: function() { + return { + pre: function(scope, formElement, attr, controller) { + if (!attr.action) { + // we can't use jq events because if a form is destroyed during submission the default + // action is not prevented. see #1238 + // + // IE 9 is not affected because it doesn't fire a submit event and try to do a full + // page reload if the form was destroyed by submission of the form via a click handler + // on a button in the form. Looks like an IE9 specific bug. + var preventDefaultListener = function(event) { + event.preventDefault + ? event.preventDefault() + : event.returnValue = false; // IE + }; + + addEventListenerFn(formElement[0], 'submit', preventDefaultListener); + + // unregister the preventDefault listener so that we don't not leak memory but in a + // way that will achieve the prevention of the default action. + formElement.on('$destroy', function() { + $timeout(function() { + removeEventListenerFn(formElement[0], 'submit', preventDefaultListener); + }, 0, false); + }); + } + + var parentFormCtrl = formElement.parent().controller('form'), + alias = attr.name || attr.ngForm; + + if (alias) { + setter(scope, alias, controller, alias); + } + if (parentFormCtrl) { + formElement.on('$destroy', function() { + parentFormCtrl.$removeControl(controller); + if (alias) { + setter(scope, alias, undefined, alias); + } + extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards + }); + } + } + }; + } + }; + + return formDirective; + }]; +}; + +var formDirective = formDirectiveFactory(); +var ngFormDirective = formDirectiveFactory(true); + +/* global + + -VALID_CLASS, + -INVALID_CLASS, + -PRISTINE_CLASS, + -DIRTY_CLASS +*/ + +var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/; +var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/; +var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/; + +var inputType = { + + /** + * @ngdoc inputType + * @name ng.directive:input.text + * + * @description + * Standard HTML text input with angular data binding. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Adds `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * + * @example + + + +
+ Single word: + + Required! + + Single word only! + + text = {{text}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + it('should initialize to model', function() { + expect(binding('text')).toEqual('guest'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('text').enter(''); + expect(binding('text')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should be invalid if multi word', function() { + input('text').enter('hello world'); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should not be trimmed', function() { + input('text').enter('untrimmed '); + expect(binding('text')).toEqual('untrimmed '); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + +
+ */ + 'text': textInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.number + * + * @description + * Text input with number validation and transformation. Sets the `number` validation + * error if not a valid number. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ Number: + + Required! + + Not valid number! + value = {{value}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + it('should initialize to model', function() { + expect(binding('value')).toEqual('12'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('value').enter(''); + expect(binding('value')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should be invalid if over max', function() { + input('value').enter('123'); + expect(binding('value')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
+ */ + 'number': numberInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.url + * + * @description + * Text input with URL validation. Sets the `url` validation error key if the content is not a + * valid URL. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ URL: + + Required! + + Not valid url! + text = {{text}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+ myForm.$error.url = {{!!myForm.$error.url}}
+
+
+ + it('should initialize to model', function() { + expect(binding('text')).toEqual('http://google.com'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('text').enter(''); + expect(binding('text')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should be invalid if not url', function() { + input('text').enter('xxx'); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
+ */ + 'url': urlInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.email + * + * @description + * Text input with email validation. Sets the `email` validation error key if not a valid email + * address. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ Email: + + Required! + + Not valid email! + text = {{text}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+ myForm.$error.email = {{!!myForm.$error.email}}
+
+
+ + it('should initialize to model', function() { + expect(binding('text')).toEqual('me@example.com'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('text').enter(''); + expect(binding('text')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should be invalid if not email', function() { + input('text').enter('xxx'); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
+ */ + 'email': emailInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.radio + * + * @description + * HTML radio button. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string} value The value to which the expression should be set when selected. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ Red
+ Green
+ Blue
+ color = {{color}}
+
+
+ + it('should change state', function() { + expect(binding('color')).toEqual('blue'); + + input('color').select('red'); + expect(binding('color')).toEqual('red'); + }); + +
+ */ + 'radio': radioInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.checkbox + * + * @description + * HTML checkbox. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} ngTrueValue The value to which the expression should be set when selected. + * @param {string=} ngFalseValue The value to which the expression should be set when not selected. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ Value1:
+ Value2:
+ value1 = {{value1}}
+ value2 = {{value2}}
+
+
+ + it('should change state', function() { + expect(binding('value1')).toEqual('true'); + expect(binding('value2')).toEqual('YES'); + + input('value1').check(); + input('value2').check(); + expect(binding('value1')).toEqual('false'); + expect(binding('value2')).toEqual('NO'); + }); + +
+ */ + 'checkbox': checkboxInputType, + + 'hidden': noop, + 'button': noop, + 'submit': noop, + 'reset': noop +}; + + +function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { + // In composition mode, users are still inputing intermediate text buffer, + // hold the listener until composition is done. + // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent + var composing = false; + + element.on('compositionstart', function() { + composing = true; + }); + + element.on('compositionend', function() { + composing = false; + }); + + var listener = function() { + if (composing) return; + var value = element.val(); + + // By default we will trim the value + // If the attribute ng-trim exists we will avoid trimming + // e.g. + if (toBoolean(attr.ngTrim || 'T')) { + value = trim(value); + } + + if (ctrl.$viewValue !== value) { + scope.$apply(function() { + ctrl.$setViewValue(value); + }); + } + }; + + // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the + // input event on backspace, delete or cut + if ($sniffer.hasEvent('input')) { + element.on('input', listener); + } else { + var timeout; + + var deferListener = function() { + if (!timeout) { + timeout = $browser.defer(function() { + listener(); + timeout = null; + }); + } + }; + + element.on('keydown', function(event) { + var key = event.keyCode; + + // ignore + // command modifiers arrows + if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; + + deferListener(); + }); + + // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it + if ($sniffer.hasEvent('paste')) { + element.on('paste cut', deferListener); + } + } + + // if user paste into input using mouse on older browser + // or form autocomplete on newer browser, we need "change" event to catch it + element.on('change', listener); + + ctrl.$render = function() { + element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue); + }; + + // pattern validator + var pattern = attr.ngPattern, + patternValidator, + match; + + var validate = function(regexp, value) { + if (ctrl.$isEmpty(value) || regexp.test(value)) { + ctrl.$setValidity('pattern', true); + return value; + } else { + ctrl.$setValidity('pattern', false); + return undefined; + } + }; + + if (pattern) { + match = pattern.match(/^\/(.*)\/([gim]*)$/); + if (match) { + pattern = new RegExp(match[1], match[2]); + patternValidator = function(value) { + return validate(pattern, value); + }; + } else { + patternValidator = function(value) { + var patternObj = scope.$eval(pattern); + + if (!patternObj || !patternObj.test) { + throw minErr('ngPattern')('noregexp', + 'Expected {0} to be a RegExp but was {1}. Element: {2}', pattern, + patternObj, startingTag(element)); + } + return validate(patternObj, value); + }; + } + + ctrl.$formatters.push(patternValidator); + ctrl.$parsers.push(patternValidator); + } + + // min length validator + if (attr.ngMinlength) { + var minlength = int(attr.ngMinlength); + var minLengthValidator = function(value) { + if (!ctrl.$isEmpty(value) && value.length < minlength) { + ctrl.$setValidity('minlength', false); + return undefined; + } else { + ctrl.$setValidity('minlength', true); + return value; + } + }; + + ctrl.$parsers.push(minLengthValidator); + ctrl.$formatters.push(minLengthValidator); + } + + // max length validator + if (attr.ngMaxlength) { + var maxlength = int(attr.ngMaxlength); + var maxLengthValidator = function(value) { + if (!ctrl.$isEmpty(value) && value.length > maxlength) { + ctrl.$setValidity('maxlength', false); + return undefined; + } else { + ctrl.$setValidity('maxlength', true); + return value; + } + }; + + ctrl.$parsers.push(maxLengthValidator); + ctrl.$formatters.push(maxLengthValidator); + } +} + +function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { + textInputType(scope, element, attr, ctrl, $sniffer, $browser); + + ctrl.$parsers.push(function(value) { + var empty = ctrl.$isEmpty(value); + if (empty || NUMBER_REGEXP.test(value)) { + ctrl.$setValidity('number', true); + return value === '' ? null : (empty ? value : parseFloat(value)); + } else { + ctrl.$setValidity('number', false); + return undefined; + } + }); + + ctrl.$formatters.push(function(value) { + return ctrl.$isEmpty(value) ? '' : '' + value; + }); + + if (attr.min) { + var minValidator = function(value) { + var min = parseFloat(attr.min); + if (!ctrl.$isEmpty(value) && value < min) { + ctrl.$setValidity('min', false); + return undefined; + } else { + ctrl.$setValidity('min', true); + return value; + } + }; + + ctrl.$parsers.push(minValidator); + ctrl.$formatters.push(minValidator); + } + + if (attr.max) { + var maxValidator = function(value) { + var max = parseFloat(attr.max); + if (!ctrl.$isEmpty(value) && value > max) { + ctrl.$setValidity('max', false); + return undefined; + } else { + ctrl.$setValidity('max', true); + return value; + } + }; + + ctrl.$parsers.push(maxValidator); + ctrl.$formatters.push(maxValidator); + } + + ctrl.$formatters.push(function(value) { + + if (ctrl.$isEmpty(value) || isNumber(value)) { + ctrl.$setValidity('number', true); + return value; + } else { + ctrl.$setValidity('number', false); + return undefined; + } + }); +} + +function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) { + textInputType(scope, element, attr, ctrl, $sniffer, $browser); + + var urlValidator = function(value) { + if (ctrl.$isEmpty(value) || URL_REGEXP.test(value)) { + ctrl.$setValidity('url', true); + return value; + } else { + ctrl.$setValidity('url', false); + return undefined; + } + }; + + ctrl.$formatters.push(urlValidator); + ctrl.$parsers.push(urlValidator); +} + +function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) { + textInputType(scope, element, attr, ctrl, $sniffer, $browser); + + var emailValidator = function(value) { + if (ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value)) { + ctrl.$setValidity('email', true); + return value; + } else { + ctrl.$setValidity('email', false); + return undefined; + } + }; + + ctrl.$formatters.push(emailValidator); + ctrl.$parsers.push(emailValidator); +} + +function radioInputType(scope, element, attr, ctrl) { + // make the name unique, if not defined + if (isUndefined(attr.name)) { + element.attr('name', nextUid()); + } + + element.on('click', function() { + if (element[0].checked) { + scope.$apply(function() { + ctrl.$setViewValue(attr.value); + }); + } + }); + + ctrl.$render = function() { + var value = attr.value; + element[0].checked = (value == ctrl.$viewValue); + }; + + attr.$observe('value', ctrl.$render); +} + +function checkboxInputType(scope, element, attr, ctrl) { + var trueValue = attr.ngTrueValue, + falseValue = attr.ngFalseValue; + + if (!isString(trueValue)) trueValue = true; + if (!isString(falseValue)) falseValue = false; + + element.on('click', function() { + scope.$apply(function() { + ctrl.$setViewValue(element[0].checked); + }); + }); + + ctrl.$render = function() { + element[0].checked = ctrl.$viewValue; + }; + + // Override the standard `$isEmpty` because a value of `false` means empty in a checkbox. + ctrl.$isEmpty = function(value) { + return value !== trueValue; + }; + + ctrl.$formatters.push(function(value) { + return value === trueValue; + }); + + ctrl.$parsers.push(function(value) { + return value ? trueValue : falseValue; + }); +} + + +/** + * @ngdoc directive + * @name ng.directive:textarea + * @restrict E + * + * @description + * HTML textarea element control with angular data-binding. The data-binding and validation + * properties of this element are exactly the same as those of the + * {@link ng.directive:input input element}. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + */ + + +/** + * @ngdoc directive + * @name ng.directive:input + * @restrict E + * + * @description + * HTML input element control with angular data-binding. Input control follows HTML5 input types + * and polyfills the HTML5 validation behavior for older browsers. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {boolean=} ngRequired Sets `required` attribute if set to true + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+
+ User name: + + Required!
+ Last name: + + Too short! + + Too long!
+
+
+ user = {{user}}
+ myForm.userName.$valid = {{myForm.userName.$valid}}
+ myForm.userName.$error = {{myForm.userName.$error}}
+ myForm.lastName.$valid = {{myForm.lastName.$valid}}
+ myForm.lastName.$error = {{myForm.lastName.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+ myForm.$error.minlength = {{!!myForm.$error.minlength}}
+ myForm.$error.maxlength = {{!!myForm.$error.maxlength}}
+
+
+ + it('should initialize to model', function() { + expect(binding('user')).toEqual('{"name":"guest","last":"visitor"}'); + expect(binding('myForm.userName.$valid')).toEqual('true'); + expect(binding('myForm.$valid')).toEqual('true'); + }); + + it('should be invalid if empty when required', function() { + input('user.name').enter(''); + expect(binding('user')).toEqual('{"last":"visitor"}'); + expect(binding('myForm.userName.$valid')).toEqual('false'); + expect(binding('myForm.$valid')).toEqual('false'); + }); + + it('should be valid if empty when min length is set', function() { + input('user.last').enter(''); + expect(binding('user')).toEqual('{"name":"guest","last":""}'); + expect(binding('myForm.lastName.$valid')).toEqual('true'); + expect(binding('myForm.$valid')).toEqual('true'); + }); + + it('should be invalid if less than required min length', function() { + input('user.last').enter('xx'); + expect(binding('user')).toEqual('{"name":"guest"}'); + expect(binding('myForm.lastName.$valid')).toEqual('false'); + expect(binding('myForm.lastName.$error')).toMatch(/minlength/); + expect(binding('myForm.$valid')).toEqual('false'); + }); + + it('should be invalid if longer than max length', function() { + input('user.last').enter('some ridiculously long name'); + expect(binding('user')) + .toEqual('{"name":"guest"}'); + expect(binding('myForm.lastName.$valid')).toEqual('false'); + expect(binding('myForm.lastName.$error')).toMatch(/maxlength/); + expect(binding('myForm.$valid')).toEqual('false'); + }); + +
+ */ +var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) { + return { + restrict: 'E', + require: '?ngModel', + link: function(scope, element, attr, ctrl) { + if (ctrl) { + (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrl, $sniffer, + $browser); + } + } + }; +}]; + +var VALID_CLASS = 'ng-valid', + INVALID_CLASS = 'ng-invalid', + PRISTINE_CLASS = 'ng-pristine', + DIRTY_CLASS = 'ng-dirty'; + +/** + * @ngdoc object + * @name ng.directive:ngModel.NgModelController + * + * @property {string} $viewValue Actual string value in the view. + * @property {*} $modelValue The value in the model, that the control is bound to. + * @property {Array.} $parsers Array of functions to execute, as a pipeline, whenever + the control reads value from the DOM. Each function is called, in turn, passing the value + through to the next. Used to sanitize / convert the value as well as validation. + For validation, the parsers should update the validity state using + {@link ng.directive:ngModel.NgModelController#methods_$setValidity $setValidity()}, + and return `undefined` for invalid values. + + * + * @property {Array.} $formatters Array of functions to execute, as a pipeline, whenever + the model value changes. Each function is called, in turn, passing the value through to the + next. Used to format / convert values for display in the control and validation. + *
+ *      function formatter(value) {
+ *        if (value) {
+ *          return value.toUpperCase();
+ *        }
+ *      }
+ *      ngModel.$formatters.push(formatter);
+ *      
+ * + * @property {Array.} $viewChangeListeners Array of functions to execute whenever the + * view value has changed. It is called with no arguments, and its return value is ignored. + * This can be used in place of additional $watches against the model value. + * + * @property {Object} $error An object hash with all errors as keys. + * + * @property {boolean} $pristine True if user has not interacted with the control yet. + * @property {boolean} $dirty True if user has already interacted with the control. + * @property {boolean} $valid True if there is no error. + * @property {boolean} $invalid True if at least one error on the control. + * + * @description + * + * `NgModelController` provides API for the `ng-model` directive. The controller contains + * services for data-binding, validation, CSS updates, and value formatting and parsing. It + * purposefully does not contain any logic which deals with DOM rendering or listening to + * DOM events. Such DOM related logic should be provided by other directives which make use of + * `NgModelController` for data-binding. + * + * ## Custom Control Example + * This example shows how to use `NgModelController` with a custom control to achieve + * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`) + * collaborate together to achieve the desired result. + * + * Note that `contenteditable` is an HTML5 attribute, which tells the browser to let the element + * contents be edited in place by the user. This will not work on older browsers. + * + * + + [contenteditable] { + border: 1px solid black; + background-color: white; + min-height: 20px; + } + + .ng-invalid { + border: 1px solid red; + } + + + + angular.module('customControl', []). + directive('contenteditable', function() { + return { + restrict: 'A', // only activate on element attribute + require: '?ngModel', // get a hold of NgModelController + link: function(scope, element, attrs, ngModel) { + if(!ngModel) return; // do nothing if no ng-model + + // Specify how UI should be updated + ngModel.$render = function() { + element.html(ngModel.$viewValue || ''); + }; + + // Listen for change events to enable binding + element.on('blur keyup change', function() { + scope.$apply(read); + }); + read(); // initialize + + // Write data to the model + function read() { + var html = element.html(); + // When we clear the content editable the browser leaves a
behind + // If strip-br attribute is provided then we strip this out + if( attrs.stripBr && html == '
' ) { + html = ''; + } + ngModel.$setViewValue(html); + } + } + }; + }); +
+ +
+
Change me!
+ Required! +
+ +
+
+ + it('should data-bind and become invalid', function() { + var contentEditable = element('[contenteditable]'); + + expect(contentEditable.text()).toEqual('Change me!'); + input('userContent').enter(''); + expect(contentEditable.text()).toEqual(''); + expect(contentEditable.prop('className')).toMatch(/ng-invalid-required/); + }); + + *
+ * + * ## Isolated Scope Pitfall + * + * Note that if you have a directive with an isolated scope, you cannot require `ngModel` + * since the model value will be looked up on the isolated scope rather than the outer scope. + * When the directive updates the model value, calling `ngModel.$setViewValue()` the property + * on the outer scope will not be updated. However you can get around this by using $parent. + * + * Here is an example of this situation. You'll notice that the first div is not updating the input. + * However the second div can update the input properly. + * + * + + angular.module('badIsolatedDirective', []).directive('isolate', function() { + return { + require: 'ngModel', + scope: { }, + template: '', + link: function(scope, element, attrs, ngModel) { + scope.$watch('innerModel', function(value) { + console.log(value); + ngModel.$setViewValue(value); + }); + } + }; + }); + + + +
+
+
+ *
+ * + * + */ +var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', + function($scope, $exceptionHandler, $attr, $element, $parse) { + this.$viewValue = Number.NaN; + this.$modelValue = Number.NaN; + this.$parsers = []; + this.$formatters = []; + this.$viewChangeListeners = []; + this.$pristine = true; + this.$dirty = false; + this.$valid = true; + this.$invalid = false; + this.$name = $attr.name; + + var ngModelGet = $parse($attr.ngModel), + ngModelSet = ngModelGet.assign; + + if (!ngModelSet) { + throw minErr('ngModel')('nonassign', "Expression '{0}' is non-assignable. Element: {1}", + $attr.ngModel, startingTag($element)); + } + + /** + * @ngdoc function + * @name ng.directive:ngModel.NgModelController#$render + * @methodOf ng.directive:ngModel.NgModelController + * + * @description + * Called when the view needs to be updated. It is expected that the user of the ng-model + * directive will implement this method. + */ + this.$render = noop; + + /** + * @ngdoc function + * @name { ng.directive:ngModel.NgModelController#$isEmpty + * @methodOf ng.directive:ngModel.NgModelController + * + * @description + * This is called when we need to determine if the value of the input is empty. + * + * For instance, the required directive does this to work out if the input has data or not. + * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`. + * + * You can override this for input directives whose concept of being empty is different to the + * default. The `checkboxInputType` directive does this because in its case a value of `false` + * implies empty. + */ + this.$isEmpty = function(value) { + return isUndefined(value) || value === '' || value === null || value !== value; + }; + + var parentForm = $element.inheritedData('$formController') || nullFormCtrl, + invalidCount = 0, // used to easily determine if we are valid + $error = this.$error = {}; // keep invalid keys here + + + // Setup initial state of the control + $element.addClass(PRISTINE_CLASS); + toggleValidCss(true); + + // convenience method for easy toggling of classes + function toggleValidCss(isValid, validationErrorKey) { + validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; + $element. + removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey). + addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey); + } + + /** + * @ngdoc function + * @name ng.directive:ngModel.NgModelController#$setValidity + * @methodOf ng.directive:ngModel.NgModelController + * + * @description + * Change the validity state, and notifies the form when the control changes validity. (i.e. it + * does not notify form if given validator is already marked as invalid). + * + * This method should be called by validators - i.e. the parser or formatter functions. + * + * @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign + * to `$error[validationErrorKey]=isValid` so that it is available for data-binding. + * The `validationErrorKey` should be in camelCase and will get converted into dash-case + * for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error` + * class and can be bound to as `{{someForm.someControl.$error.myError}}` . + * @param {boolean} isValid Whether the current state is valid (true) or invalid (false). + */ + this.$setValidity = function(validationErrorKey, isValid) { + // Purposeful use of ! here to cast isValid to boolean in case it is undefined + // jshint -W018 + if ($error[validationErrorKey] === !isValid) return; + // jshint +W018 + + if (isValid) { + if ($error[validationErrorKey]) invalidCount--; + if (!invalidCount) { + toggleValidCss(true); + this.$valid = true; + this.$invalid = false; + } + } else { + toggleValidCss(false); + this.$invalid = true; + this.$valid = false; + invalidCount++; + } + + $error[validationErrorKey] = !isValid; + toggleValidCss(isValid, validationErrorKey); + + parentForm.$setValidity(validationErrorKey, isValid, this); + }; + + /** + * @ngdoc function + * @name ng.directive:ngModel.NgModelController#$setPristine + * @methodOf ng.directive:ngModel.NgModelController + * + * @description + * Sets the control to its pristine state. + * + * This method can be called to remove the 'ng-dirty' class and set the control to its pristine + * state (ng-pristine class). + */ + this.$setPristine = function () { + this.$dirty = false; + this.$pristine = true; + $element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS); + }; + + /** + * @ngdoc function + * @name ng.directive:ngModel.NgModelController#$setViewValue + * @methodOf ng.directive:ngModel.NgModelController + * + * @description + * Update the view value. + * + * This method should be called when the view value changes, typically from within a DOM event handler. + * For example {@link ng.directive:input input} and + * {@link ng.directive:select select} directives call it. + * + * It will update the $viewValue, then pass this value through each of the functions in `$parsers`, + * which includes any validators. The value that comes out of this `$parsers` pipeline, be applied to + * `$modelValue` and the **expression** specified in the `ng-model` attribute. + * + * Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called. + * + * Note that calling this function does not trigger a `$digest`. + * + * @param {string} value Value from the view. + */ + this.$setViewValue = function(value) { + this.$viewValue = value; + + // change to dirty + if (this.$pristine) { + this.$dirty = true; + this.$pristine = false; + $element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS); + parentForm.$setDirty(); + } + + forEach(this.$parsers, function(fn) { + value = fn(value); + }); + + if (this.$modelValue !== value) { + this.$modelValue = value; + ngModelSet($scope, value); + forEach(this.$viewChangeListeners, function(listener) { + try { + listener(); + } catch(e) { + $exceptionHandler(e); + } + }); + } + }; + + // model -> value + var ctrl = this; + + $scope.$watch(function ngModelWatch() { + var value = ngModelGet($scope); + + // if scope model value and ngModel value are out of sync + if (ctrl.$modelValue !== value) { + + var formatters = ctrl.$formatters, + idx = formatters.length; + + ctrl.$modelValue = value; + while(idx--) { + value = formatters[idx](value); + } + + if (ctrl.$viewValue !== value) { + ctrl.$viewValue = value; + ctrl.$render(); + } + } + }); +}]; + + +/** + * @ngdoc directive + * @name ng.directive:ngModel + * + * @element input + * + * @description + * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a + * property on the scope using {@link ng.directive:ngModel.NgModelController NgModelController}, + * which is created and exposed by this directive. + * + * `ngModel` is responsible for: + * + * - Binding the view into the model, which other directives such as `input`, `textarea` or `select` + * require. + * - Providing validation behavior (i.e. required, number, email, url). + * - Keeping the state of the control (valid/invalid, dirty/pristine, validation errors). + * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`). + * - Registering the control with its parent {@link ng.directive:form form}. + * + * Note: `ngModel` will try to bind to the property given by evaluating the expression on the + * current scope. If the property doesn't already exist on this scope, it will be created + * implicitly and added to the scope. + * + * For best practices on using `ngModel`, see: + * + * - {@link https://github.com/angular/angular.js/wiki/Understanding-Scopes} + * + * For basic examples, how to use `ngModel`, see: + * + * - {@link ng.directive:input input} + * - {@link ng.directive:input.text text} + * - {@link ng.directive:input.checkbox checkbox} + * - {@link ng.directive:input.radio radio} + * - {@link ng.directive:input.number number} + * - {@link ng.directive:input.email email} + * - {@link ng.directive:input.url url} + * - {@link ng.directive:select select} + * - {@link ng.directive:textarea textarea} + * + */ +var ngModelDirective = function() { + return { + require: ['ngModel', '^?form'], + controller: NgModelController, + link: function(scope, element, attr, ctrls) { + // notify others, especially parent forms + + var modelCtrl = ctrls[0], + formCtrl = ctrls[1] || nullFormCtrl; + + formCtrl.$addControl(modelCtrl); + + scope.$on('$destroy', function() { + formCtrl.$removeControl(modelCtrl); + }); + } + }; +}; + + +/** + * @ngdoc directive + * @name ng.directive:ngChange + * + * @description + * Evaluate given expression when user changes the input. + * The expression is not evaluated when the value change is coming from the model. + * + * Note, this directive requires `ngModel` to be present. + * + * @element input + * @param {expression} ngChange {@link guide/expression Expression} to evaluate upon change + * in input value. + * + * @example + * + * + * + *
+ * + * + *
+ * debug = {{confirmed}}
+ * counter = {{counter}} + *
+ *
+ * + * it('should evaluate the expression if changing from view', function() { + * expect(binding('counter')).toEqual('0'); + * element('#ng-change-example1').click(); + * expect(binding('counter')).toEqual('1'); + * expect(binding('confirmed')).toEqual('true'); + * }); + * + * it('should not evaluate the expression if changing from model', function() { + * element('#ng-change-example2').click(); + * expect(binding('counter')).toEqual('0'); + * expect(binding('confirmed')).toEqual('true'); + * }); + * + *
+ */ +var ngChangeDirective = valueFn({ + require: 'ngModel', + link: function(scope, element, attr, ctrl) { + ctrl.$viewChangeListeners.push(function() { + scope.$eval(attr.ngChange); + }); + } +}); + + +var requiredDirective = function() { + return { + require: '?ngModel', + link: function(scope, elm, attr, ctrl) { + if (!ctrl) return; + attr.required = true; // force truthy in case we are on non input element + + var validator = function(value) { + if (attr.required && ctrl.$isEmpty(value)) { + ctrl.$setValidity('required', false); + return; + } else { + ctrl.$setValidity('required', true); + return value; + } + }; + + ctrl.$formatters.push(validator); + ctrl.$parsers.unshift(validator); + + attr.$observe('required', function() { + validator(ctrl.$viewValue); + }); + } + }; +}; + + +/** + * @ngdoc directive + * @name ng.directive:ngList + * + * @description + * Text input that converts between a delimited string and an array of strings. The delimiter + * can be a fixed string (by default a comma) or a regular expression. + * + * @element input + * @param {string=} ngList optional delimiter that should be used to split the value. If + * specified in form `/something/` then the value will be converted into a regular expression. + * + * @example + + + +
+ List: + + Required! +
+ names = {{names}}
+ myForm.namesInput.$valid = {{myForm.namesInput.$valid}}
+ myForm.namesInput.$error = {{myForm.namesInput.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + it('should initialize to model', function() { + expect(binding('names')).toEqual('["igor","misko","vojta"]'); + expect(binding('myForm.namesInput.$valid')).toEqual('true'); + expect(element('span.error').css('display')).toBe('none'); + }); + + it('should be invalid if empty', function() { + input('names').enter(''); + expect(binding('names')).toEqual(''); + expect(binding('myForm.namesInput.$valid')).toEqual('false'); + expect(element('span.error').css('display')).not().toBe('none'); + }); + +
+ */ +var ngListDirective = function() { + return { + require: 'ngModel', + link: function(scope, element, attr, ctrl) { + var match = /\/(.*)\//.exec(attr.ngList), + separator = match && new RegExp(match[1]) || attr.ngList || ','; + + var parse = function(viewValue) { + // If the viewValue is invalid (say required but empty) it will be `undefined` + if (isUndefined(viewValue)) return; + + var list = []; + + if (viewValue) { + forEach(viewValue.split(separator), function(value) { + if (value) list.push(trim(value)); + }); + } + + return list; + }; + + ctrl.$parsers.push(parse); + ctrl.$formatters.push(function(value) { + if (isArray(value)) { + return value.join(', '); + } + + return undefined; + }); + + // Override the standard $isEmpty because an empty array means the input is empty. + ctrl.$isEmpty = function(value) { + return !value || !value.length; + }; + } + }; +}; + + +var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/; +/** + * @ngdoc directive + * @name ng.directive:ngValue + * + * @description + * Binds the given expression to the value of `input[select]` or `input[radio]`, so + * that when the element is selected, the `ngModel` of that element is set to the + * bound value. + * + * `ngValue` is useful when dynamically generating lists of radio buttons using `ng-repeat`, as + * shown below. + * + * @element input + * @param {string=} ngValue angular expression, whose value will be bound to the `value` attribute + * of the `input` element + * + * @example + + + +
+

Which is your favorite?

+ + +
You chose {{my.favorite}}
+
+
+ + it('should initialize to model', function() { + expect(binding('my.favorite')).toEqual('unicorns'); + }); + it('should bind the values to the inputs', function() { + input('my.favorite').select('pizza'); + expect(binding('my.favorite')).toEqual('pizza'); + }); + +
+ */ +var ngValueDirective = function() { + return { + priority: 100, + compile: function(tpl, tplAttr) { + if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) { + return function ngValueConstantLink(scope, elm, attr) { + attr.$set('value', scope.$eval(attr.ngValue)); + }; + } else { + return function ngValueLink(scope, elm, attr) { + scope.$watch(attr.ngValue, function valueWatchAction(value) { + attr.$set('value', value); + }); + }; + } + } + }; +}; + +/** + * @ngdoc directive + * @name ng.directive:ngBind + * @restrict AC + * + * @description + * The `ngBind` attribute tells Angular to replace the text content of the specified HTML element + * with the value of a given expression, and to update the text content when the value of that + * expression changes. + * + * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like + * `{{ expression }}` which is similar but less verbose. + * + * It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily + * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an + * element attribute, it makes the bindings invisible to the user while the page is loading. + * + * An alternative solution to this problem would be using the + * {@link ng.directive:ngCloak ngCloak} directive. + * + * + * @element ANY + * @param {expression} ngBind {@link guide/expression Expression} to evaluate. + * + * @example + * Enter a name in the Live Preview text box; the greeting below the text box changes instantly. + + + +
+ Enter name:
+ Hello ! +
+
+ + it('should check ng-bind', function() { + expect(using('.doc-example-live').binding('name')).toBe('Whirled'); + using('.doc-example-live').input('name').enter('world'); + expect(using('.doc-example-live').binding('name')).toBe('world'); + }); + +
+ */ +var ngBindDirective = ngDirective(function(scope, element, attr) { + element.addClass('ng-binding').data('$binding', attr.ngBind); + scope.$watch(attr.ngBind, function ngBindWatchAction(value) { + // We are purposefully using == here rather than === because we want to + // catch when value is "null or undefined" + // jshint -W041 + element.text(value == undefined ? '' : value); + }); +}); + + +/** + * @ngdoc directive + * @name ng.directive:ngBindTemplate + * + * @description + * The `ngBindTemplate` directive specifies that the element + * text content should be replaced with the interpolation of the template + * in the `ngBindTemplate` attribute. + * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}` + * expressions. This directive is needed since some HTML elements + * (such as TITLE and OPTION) cannot contain SPAN elements. + * + * @element ANY + * @param {string} ngBindTemplate template of form + * {{ expression }} to eval. + * + * @example + * Try it here: enter text in text box and watch the greeting change. + + + +
+ Salutation:
+ Name:
+

+       
+
+ + it('should check ng-bind', function() { + expect(using('.doc-example-live').binding('salutation')). + toBe('Hello'); + expect(using('.doc-example-live').binding('name')). + toBe('World'); + using('.doc-example-live').input('salutation').enter('Greetings'); + using('.doc-example-live').input('name').enter('user'); + expect(using('.doc-example-live').binding('salutation')). + toBe('Greetings'); + expect(using('.doc-example-live').binding('name')). + toBe('user'); + }); + +
+ */ +var ngBindTemplateDirective = ['$interpolate', function($interpolate) { + return function(scope, element, attr) { + // TODO: move this to scenario runner + var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate)); + element.addClass('ng-binding').data('$binding', interpolateFn); + attr.$observe('ngBindTemplate', function(value) { + element.text(value); + }); + }; +}]; + + +/** + * @ngdoc directive + * @name ng.directive:ngBindHtml + * + * @description + * Creates a binding that will innerHTML the result of evaluating the `expression` into the current + * element in a secure way. By default, the innerHTML-ed content will be sanitized using the {@link + * ngSanitize.$sanitize $sanitize} service. To utilize this functionality, ensure that `$sanitize` + * is available, for example, by including {@link ngSanitize} in your module's dependencies (not in + * core Angular.) You may also bypass sanitization for values you know are safe. To do so, bind to + * an explicitly trusted value via {@link ng.$sce#methods_trustAsHtml $sce.trustAsHtml}. See the example + * under {@link ng.$sce#Example Strict Contextual Escaping (SCE)}. + * + * Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you + * will have an exception (instead of an exploit.) + * + * @element ANY + * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate. + * + * @example + Try it here: enter text in text box and watch the greeting change. + + + +
+

+
+
+ + + angular.module('ngBindHtmlExample', ['ngSanitize']) + + .controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) { + $scope.myHTML = + 'I am an HTMLstring with links! and other stuff'; + }]); + + + + it('should check ng-bind-html', function() { + expect(using('.doc-example-live').binding('myHTML')). + toBe( + 'I am an HTMLstring with links! and other stuff' + ); + }); + +
+ */ +var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) { + return function(scope, element, attr) { + element.addClass('ng-binding').data('$binding', attr.ngBindHtml); + + var parsed = $parse(attr.ngBindHtml); + function getStringValue() { return (parsed(scope) || '').toString(); } + + scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) { + element.html($sce.getTrustedHtml(parsed(scope)) || ''); + }); + }; +}]; + +function classDirective(name, selector) { + name = 'ngClass' + name; + return function() { + return { + restrict: 'AC', + link: function(scope, element, attr) { + var oldVal; + + scope.$watch(attr[name], ngClassWatchAction, true); + + attr.$observe('class', function(value) { + ngClassWatchAction(scope.$eval(attr[name])); + }); + + + if (name !== 'ngClass') { + scope.$watch('$index', function($index, old$index) { + // jshint bitwise: false + var mod = $index & 1; + if (mod !== old$index & 1) { + var classes = flattenClasses(scope.$eval(attr[name])); + mod === selector ? + attr.$addClass(classes) : + attr.$removeClass(classes); + } + }); + } + + + function ngClassWatchAction(newVal) { + if (selector === true || scope.$index % 2 === selector) { + var newClasses = flattenClasses(newVal || ''); + if(!oldVal) { + attr.$addClass(newClasses); + } else if(!equals(newVal,oldVal)) { + attr.$updateClass(newClasses, flattenClasses(oldVal)); + } + } + oldVal = copy(newVal); + } + + + function flattenClasses(classVal) { + if(isArray(classVal)) { + return classVal.join(' '); + } else if (isObject(classVal)) { + var classes = [], i = 0; + forEach(classVal, function(v, k) { + if (v) { + classes.push(k); + } + }); + return classes.join(' '); + } + + return classVal; + } + } + }; + }; +} + +/** + * @ngdoc directive + * @name ng.directive:ngClass + * @restrict AC + * + * @description + * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding + * an expression that represents all classes to be added. + * + * The directive won't add duplicate classes if a particular class was already set. + * + * When the expression changes, the previously added classes are removed and only then the + * new classes are added. + * + * @animations + * add - happens just before the class is applied to the element + * remove - happens just before the class is removed from the element + * + * @element ANY + * @param {expression} ngClass {@link guide/expression Expression} to eval. The result + * of the evaluation can be a string representing space delimited class + * names, an array, or a map of class names to boolean values. In the case of a map, the + * names of the properties whose values are truthy will be added as css classes to the + * element. + * + * @example Example that demonstrates basic bindings via ngClass directive. + + +

Map Syntax Example

+ deleted (apply "strike" class)
+ important (apply "bold" class)
+ error (apply "red" class) +
+

Using String Syntax

+ +
+

Using Array Syntax

+
+
+
+
+ + .strike { + text-decoration: line-through; + } + .bold { + font-weight: bold; + } + .red { + color: red; + } + + + it('should let you toggle the class', function() { + + expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/); + expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/); + + input('important').check(); + expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/); + + input('error').check(); + expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/); + }); + + it('should let you toggle string example', function() { + expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe(''); + input('style').enter('red'); + expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('red'); + }); + + it('array example should have 3 classes', function() { + expect(element('.doc-example-live p:last').prop('className')).toBe(''); + input('style1').enter('bold'); + input('style2').enter('strike'); + input('style3').enter('red'); + expect(element('.doc-example-live p:last').prop('className')).toBe('bold strike red'); + }); + +
+ + ## Animations + + The example below demonstrates how to perform animations using ngClass. + + + + + +
+ Sample Text +
+ + .base-class { + -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; + } + + .base-class.my-class { + color: red; + font-size:3em; + } + + + it('should check ng-class', function() { + expect(element('.doc-example-live span').prop('className')).not(). + toMatch(/my-class/); + + using('.doc-example-live').element(':button:first').click(); + + expect(element('.doc-example-live span').prop('className')). + toMatch(/my-class/); + + using('.doc-example-live').element(':button:last').click(); + + expect(element('.doc-example-live span').prop('className')).not(). + toMatch(/my-class/); + }); + +
+ + + ## ngClass and pre-existing CSS3 Transitions/Animations + The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure. + Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder + any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure + to view the step by step details of {@link ngAnimate.$animate#methods_addclass $animate.addClass} and + {@link ngAnimate.$animate#methods_removeclass $animate.removeClass}. + */ +var ngClassDirective = classDirective('', true); + +/** + * @ngdoc directive + * @name ng.directive:ngClassOdd + * @restrict AC + * + * @description + * The `ngClassOdd` and `ngClassEven` directives work exactly as + * {@link ng.directive:ngClass ngClass}, except they work in + * conjunction with `ngRepeat` and take effect only on odd (even) rows. + * + * This directive can be applied only within the scope of an + * {@link ng.directive:ngRepeat ngRepeat}. + * + * @element ANY + * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result + * of the evaluation can be a string representing space delimited class names or an array. + * + * @example + + +
    +
  1. + + {{name}} + +
  2. +
+
+ + .odd { + color: red; + } + .even { + color: blue; + } + + + it('should check ng-class-odd and ng-class-even', function() { + expect(element('.doc-example-live li:first span').prop('className')). + toMatch(/odd/); + expect(element('.doc-example-live li:last span').prop('className')). + toMatch(/even/); + }); + +
+ */ +var ngClassOddDirective = classDirective('Odd', 0); + +/** + * @ngdoc directive + * @name ng.directive:ngClassEven + * @restrict AC + * + * @description + * The `ngClassOdd` and `ngClassEven` directives work exactly as + * {@link ng.directive:ngClass ngClass}, except they work in + * conjunction with `ngRepeat` and take effect only on odd (even) rows. + * + * This directive can be applied only within the scope of an + * {@link ng.directive:ngRepeat ngRepeat}. + * + * @element ANY + * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The + * result of the evaluation can be a string representing space delimited class names or an array. + * + * @example + + +
    +
  1. + + {{name}}       + +
  2. +
+
+ + .odd { + color: red; + } + .even { + color: blue; + } + + + it('should check ng-class-odd and ng-class-even', function() { + expect(element('.doc-example-live li:first span').prop('className')). + toMatch(/odd/); + expect(element('.doc-example-live li:last span').prop('className')). + toMatch(/even/); + }); + +
+ */ +var ngClassEvenDirective = classDirective('Even', 1); + +/** + * @ngdoc directive + * @name ng.directive:ngCloak + * @restrict AC + * + * @description + * The `ngCloak` directive is used to prevent the Angular html template from being briefly + * displayed by the browser in its raw (uncompiled) form while your application is loading. Use this + * directive to avoid the undesirable flicker effect caused by the html template display. + * + * The directive can be applied to the `` element, but the preferred usage is to apply + * multiple `ngCloak` directives to small portions of the page to permit progressive rendering + * of the browser view. + * + * `ngCloak` works in cooperation with the following css rule embedded within `angular.js` and + * `angular.min.js`. + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}). + * + *
+ * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
+ *   display: none !important;
+ * }
+ * 
+ * + * When this css rule is loaded by the browser, all html elements (including their children) that + * are tagged with the `ngCloak` directive are hidden. When Angular encounters this directive + * during the compilation of the template it deletes the `ngCloak` element attribute, making + * the compiled element visible. + * + * For the best result, the `angular.js` script must be loaded in the head section of the html + * document; alternatively, the css rule above must be included in the external stylesheet of the + * application. + * + * Legacy browsers, like IE7, do not provide attribute selector support (added in CSS 2.1) so they + * cannot match the `[ng\:cloak]` selector. To work around this limitation, you must add the css + * class `ngCloak` in addition to the `ngCloak` directive as shown in the example below. + * + * @element ANY + * + * @example + + +
{{ 'hello' }}
+
{{ 'hello IE7' }}
+
+ + it('should remove the template directive and css class', function() { + expect(element('.doc-example-live #template1').attr('ng-cloak')). + not().toBeDefined(); + expect(element('.doc-example-live #template2').attr('ng-cloak')). + not().toBeDefined(); + }); + +
+ * + */ +var ngCloakDirective = ngDirective({ + compile: function(element, attr) { + attr.$set('ngCloak', undefined); + element.removeClass('ng-cloak'); + } +}); + +/** + * @ngdoc directive + * @name ng.directive:ngController + * + * @description + * The `ngController` directive attaches a controller class to the view. This is a key aspect of how angular + * supports the principles behind the Model-View-Controller design pattern. + * + * MVC components in angular: + * + * * Model — The Model is scope properties; scopes are attached to the DOM where scope properties + * are accessed through bindings. + * * View — The template (HTML with data bindings) that is rendered into the View. + * * Controller — The `ngController` directive specifies a Controller class; the class contains business + * logic behind the application to decorate the scope with functions and values + * + * Note that you can also attach controllers to the DOM by declaring it in a route definition + * via the {@link ngRoute.$route $route} service. A common mistake is to declare the controller + * again using `ng-controller` in the template itself. This will cause the controller to be attached + * and executed twice. + * + * @element ANY + * @scope + * @param {expression} ngController Name of a globally accessible constructor function or an + * {@link guide/expression expression} that on the current scope evaluates to a + * constructor function. The controller instance can be published into a scope property + * by specifying `as propertyName`. + * + * @example + * Here is a simple form for editing user contact information. Adding, removing, clearing, and + * greeting are methods declared on the controller (see source tab). These methods can + * easily be called from the angular markup. Notice that the scope becomes the `this` for the + * controller's instance. This allows for easy access to the view data from the controller. Also + * notice that any changes to the data are automatically reflected in the View without the need + * for a manual update. The example is shown in two different declaration styles you may use + * according to preference. + + + +
+ Name: + [ greet ]
+ Contact: +
    +
  • + + + [ clear + | X ] +
  • +
  • [ add ]
  • +
+
+
+ + it('should check controller as', function() { + expect(element('#ctrl-as-exmpl>:input').val()).toBe('John Smith'); + expect(element('#ctrl-as-exmpl li:nth-child(1) input').val()) + .toBe('408 555 1212'); + expect(element('#ctrl-as-exmpl li:nth-child(2) input').val()) + .toBe('john.smith@example.org'); + + element('#ctrl-as-exmpl li:first a:contains("clear")').click(); + expect(element('#ctrl-as-exmpl li:first input').val()).toBe(''); + + element('#ctrl-as-exmpl li:last a:contains("add")').click(); + expect(element('#ctrl-as-exmpl li:nth-child(3) input').val()) + .toBe('yourname@example.org'); + }); + +
+ + + +
+ Name: + [ greet ]
+ Contact: +
    +
  • + + + [ clear + | X ] +
  • +
  • [ add ]
  • +
+
+
+ + it('should check controller', function() { + expect(element('#ctrl-exmpl>:input').val()).toBe('John Smith'); + expect(element('#ctrl-exmpl li:nth-child(1) input').val()) + .toBe('408 555 1212'); + expect(element('#ctrl-exmpl li:nth-child(2) input').val()) + .toBe('john.smith@example.org'); + + element('#ctrl-exmpl li:first a:contains("clear")').click(); + expect(element('#ctrl-exmpl li:first input').val()).toBe(''); + + element('#ctrl-exmpl li:last a:contains("add")').click(); + expect(element('#ctrl-exmpl li:nth-child(3) input').val()) + .toBe('yourname@example.org'); + }); + +
+ + */ +var ngControllerDirective = [function() { + return { + scope: true, + controller: '@', + priority: 500 + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngCsp + * + * @element html + * @description + * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support. + * + * This is necessary when developing things like Google Chrome Extensions. + * + * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things). + * For us to be compatible, we just need to implement the "getterFn" in $parse without violating + * any of these restrictions. + * + * AngularJS uses `Function(string)` generated functions as a speed optimization. Applying the `ngCsp` + * directive will cause Angular to use CSP compatibility mode. When this mode is on AngularJS will + * evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will + * be raised. + * + * CSP forbids JavaScript to inline stylesheet rules. In non CSP mode Angular automatically + * includes some CSS rules (e.g. {@link ng.directive:ngCloak ngCloak}). + * To make those directives work in CSP mode, include the `angular-csp.css` manually. + * + * In order to use this feature put the `ngCsp` directive on the root element of the application. + * + * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.* + * + * @example + * This example shows how to apply the `ngCsp` directive to the `html` tag. +
+     
+     
+     ...
+     ...
+     
+   
+ */ + +// ngCsp is not implemented as a proper directive any more, because we need it be processed while we bootstrap +// the system (before $parse is instantiated), for this reason we just have a csp() fn that looks for ng-csp attribute +// anywhere in the current doc + +/** + * @ngdoc directive + * @name ng.directive:ngClick + * + * @description + * The ngClick directive allows you to specify custom behavior when + * an element is clicked. + * + * @element ANY + * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon + * click. (Event object is available as `$event`) + * + * @example + + + + count: {{count}} + + + it('should check ng-click', function() { + expect(binding('count')).toBe('0'); + element('.doc-example-live :button').click(); + expect(binding('count')).toBe('1'); + }); + + + */ +/* + * A directive that allows creation of custom onclick handlers that are defined as angular + * expressions and are compiled and executed within the current scope. + * + * Events that are handled via these handler are always configured not to propagate further. + */ +var ngEventDirectives = {}; +forEach( + 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '), + function(name) { + var directiveName = directiveNormalize('ng-' + name); + ngEventDirectives[directiveName] = ['$parse', function($parse) { + return { + compile: function($element, attr) { + var fn = $parse(attr[directiveName]); + return function(scope, element, attr) { + element.on(lowercase(name), function(event) { + scope.$apply(function() { + fn(scope, {$event:event}); + }); + }); + }; + } + }; + }]; + } +); + +/** + * @ngdoc directive + * @name ng.directive:ngDblclick + * + * @description + * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event. + * + * @element ANY + * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon + * a dblclick. (The Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMousedown + * + * @description + * The ngMousedown directive allows you to specify custom behavior on mousedown event. + * + * @element ANY + * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon + * mousedown. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMouseup + * + * @description + * Specify custom behavior on mouseup event. + * + * @element ANY + * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon + * mouseup. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + +/** + * @ngdoc directive + * @name ng.directive:ngMouseover + * + * @description + * Specify custom behavior on mouseover event. + * + * @element ANY + * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon + * mouseover. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMouseenter + * + * @description + * Specify custom behavior on mouseenter event. + * + * @element ANY + * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon + * mouseenter. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMouseleave + * + * @description + * Specify custom behavior on mouseleave event. + * + * @element ANY + * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon + * mouseleave. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMousemove + * + * @description + * Specify custom behavior on mousemove event. + * + * @element ANY + * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon + * mousemove. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngKeydown + * + * @description + * Specify custom behavior on keydown event. + * + * @element ANY + * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon + * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngKeyup + * + * @description + * Specify custom behavior on keyup event. + * + * @element ANY + * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon + * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngKeypress + * + * @description + * Specify custom behavior on keypress event. + * + * @element ANY + * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon + * keypress. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngSubmit + * + * @description + * Enables binding angular expressions to onsubmit events. + * + * Additionally it prevents the default action (which for form means sending the request to the + * server and reloading the current page) **but only if the form does not contain an `action` + * attribute**. + * + * @element form + * @param {expression} ngSubmit {@link guide/expression Expression} to eval. (Event object is available as `$event`) + * + * @example + + + +
+ Enter text and hit enter: + + +
list={{list}}
+
+
+ + it('should check ng-submit', function() { + expect(binding('list')).toBe('[]'); + element('.doc-example-live #submit').click(); + expect(binding('list')).toBe('["hello"]'); + expect(input('text').val()).toBe(''); + }); + it('should ignore empty strings', function() { + expect(binding('list')).toBe('[]'); + element('.doc-example-live #submit').click(); + element('.doc-example-live #submit').click(); + expect(binding('list')).toBe('["hello"]'); + }); + +
+ */ + +/** + * @ngdoc directive + * @name ng.directive:ngFocus + * + * @description + * Specify custom behavior on focus event. + * + * @element window, input, select, textarea, a + * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon + * focus. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + +/** + * @ngdoc directive + * @name ng.directive:ngBlur + * + * @description + * Specify custom behavior on blur event. + * + * @element window, input, select, textarea, a + * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon + * blur. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + +/** + * @ngdoc directive + * @name ng.directive:ngCopy + * + * @description + * Specify custom behavior on copy event. + * + * @element window, input, select, textarea, a + * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon + * copy. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + +/** + * @ngdoc directive + * @name ng.directive:ngCut + * + * @description + * Specify custom behavior on cut event. + * + * @element window, input, select, textarea, a + * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon + * cut. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + +/** + * @ngdoc directive + * @name ng.directive:ngPaste + * + * @description + * Specify custom behavior on paste event. + * + * @element window, input, select, textarea, a + * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon + * paste. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + +/** + * @ngdoc directive + * @name ng.directive:ngIf + * @restrict A + * + * @description + * The `ngIf` directive removes or recreates a portion of the DOM tree based on an + * {expression}. If the expression assigned to `ngIf` evaluates to a false + * value then the element is removed from the DOM, otherwise a clone of the + * element is reinserted into the DOM. + * + * `ngIf` differs from `ngShow` and `ngHide` in that `ngIf` completely removes and recreates the + * element in the DOM rather than changing its visibility via the `display` css property. A common + * case when this difference is significant is when using css selectors that rely on an element's + * position within the DOM, such as the `:first-child` or `:last-child` pseudo-classes. + * + * Note that when an element is removed using `ngIf` its scope is destroyed and a new scope + * is created when the element is restored. The scope created within `ngIf` inherits from + * its parent scope using + * {@link https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance prototypal inheritance}. + * An important implication of this is if `ngModel` is used within `ngIf` to bind to + * a javascript primitive defined in the parent scope. In this case any modifications made to the + * variable within the child scope will override (hide) the value in the parent scope. + * + * Also, `ngIf` recreates elements using their compiled state. An example of this behavior + * is if an element's class attribute is directly modified after it's compiled, using something like + * jQuery's `.addClass()` method, and the element is later removed. When `ngIf` recreates the element + * the added class will be lost because the original compiled state is used to regenerate the element. + * + * Additionally, you can provide animations via the `ngAnimate` module to animate the `enter` + * and `leave` effects. + * + * @animations + * enter - happens just after the ngIf contents change and a new DOM element is created and injected into the ngIf container + * leave - happens just before the ngIf contents are removed from the DOM + * + * @element ANY + * @scope + * @priority 600 + * @param {expression} ngIf If the {@link guide/expression expression} is falsy then + * the element is removed from the DOM tree. If it is truthy a copy of the compiled + * element is added to the DOM tree. + * + * @example + + + Click me:
+ Show when checked: + + I'm removed when the checkbox is unchecked. + +
+ + .animate-if { + background:white; + border:1px solid black; + padding:10px; + } + + /* + The transition styles can also be placed on the CSS base class above + */ + .animate-if.ng-enter, .animate-if.ng-leave { + -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; + } + + .animate-if.ng-enter, + .animate-if.ng-leave.ng-leave-active { + opacity:0; + } + + .animate-if.ng-leave, + .animate-if.ng-enter.ng-enter-active { + opacity:1; + } + +
+ */ +var ngIfDirective = ['$animate', function($animate) { + return { + transclude: 'element', + priority: 600, + terminal: true, + restrict: 'A', + $$tlb: true, + link: function ($scope, $element, $attr, ctrl, $transclude) { + var block, childScope; + $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { + + if (toBoolean(value)) { + if (!childScope) { + childScope = $scope.$new(); + $transclude(childScope, function (clone) { + block = { + startNode: clone[0], + endNode: clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ') + }; + $animate.enter(clone, $element.parent(), $element); + }); + } + } else { + + if (childScope) { + childScope.$destroy(); + childScope = null; + } + + if (block) { + $animate.leave(getBlockElements(block)); + block = null; + } + } + }); + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngInclude + * @restrict ECA + * + * @description + * Fetches, compiles and includes an external HTML fragment. + * + * By default, the template URL is restricted to the same domain and protocol as the + * application document. This is done by calling {@link ng.$sce#methods_getTrustedResourceUrl + * $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols + * you may either {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelist them} or + * {@link ng.$sce#methods_trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link + * ng.$sce Strict Contextual Escaping}. + * + * In addition, the browser's + * {@link https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest + * Same Origin Policy} and {@link http://www.w3.org/TR/cors/ Cross-Origin Resource Sharing + * (CORS)} policy may further restrict whether the template is successfully loaded. + * For example, `ngInclude` won't work for cross-domain requests on all browsers and for `file://` + * access on some browsers. + * + * @animations + * enter - animation is used to bring new content into the browser. + * leave - animation is used to animate existing content away. + * + * The enter and leave animation occur concurrently. + * + * @scope + * @priority 400 + * + * @param {string} ngInclude|src angular expression evaluating to URL. If the source is a string constant, + * make sure you wrap it in quotes, e.g. `src="'myPartialTemplate.html'"`. + * @param {string=} onload Expression to evaluate when a new partial is loaded. + * + * @param {string=} autoscroll Whether `ngInclude` should call {@link ng.$anchorScroll + * $anchorScroll} to scroll the viewport after the content is loaded. + * + * - If the attribute is not set, disable scrolling. + * - If the attribute is set without value, enable scrolling. + * - Otherwise enable scrolling only if the expression evaluates to truthy value. + * + * @example + + +
+ + url of the template: {{template.url}} +
+
+
+
+
+
+ + function Ctrl($scope) { + $scope.templates = + [ { name: 'template1.html', url: 'template1.html'} + , { name: 'template2.html', url: 'template2.html'} ]; + $scope.template = $scope.templates[0]; + } + + + Content of template1.html + + + Content of template2.html + + + .slide-animate-container { + position:relative; + background:white; + border:1px solid black; + height:40px; + overflow:hidden; + } + + .slide-animate { + padding:10px; + } + + .slide-animate.ng-enter, .slide-animate.ng-leave { + -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; + + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + display:block; + padding:10px; + } + + .slide-animate.ng-enter { + top:-50px; + } + .slide-animate.ng-enter.ng-enter-active { + top:0; + } + + .slide-animate.ng-leave { + top:0; + } + .slide-animate.ng-leave.ng-leave-active { + top:50px; + } + + + it('should load template1.html', function() { + expect(element('.doc-example-live [ng-include]').text()). + toMatch(/Content of template1.html/); + }); + it('should load template2.html', function() { + select('template').option('1'); + expect(element('.doc-example-live [ng-include]').text()). + toMatch(/Content of template2.html/); + }); + it('should change to blank', function() { + select('template').option(''); + expect(element('.doc-example-live [ng-include]')).toBe(undefined); + }); + +
+ */ + + +/** + * @ngdoc event + * @name ng.directive:ngInclude#$includeContentRequested + * @eventOf ng.directive:ngInclude + * @eventType emit on the scope ngInclude was declared in + * @description + * Emitted every time the ngInclude content is requested. + */ + + +/** + * @ngdoc event + * @name ng.directive:ngInclude#$includeContentLoaded + * @eventOf ng.directive:ngInclude + * @eventType emit on the current ngInclude scope + * @description + * Emitted every time the ngInclude content is reloaded. + */ +var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', '$animate', '$sce', + function($http, $templateCache, $anchorScroll, $compile, $animate, $sce) { + return { + restrict: 'ECA', + priority: 400, + terminal: true, + transclude: 'element', + compile: function(element, attr) { + var srcExp = attr.ngInclude || attr.src, + onloadExp = attr.onload || '', + autoScrollExp = attr.autoscroll; + + return function(scope, $element, $attr, ctrl, $transclude) { + var changeCounter = 0, + currentScope, + currentElement; + + var cleanupLastIncludeContent = function() { + if (currentScope) { + currentScope.$destroy(); + currentScope = null; + } + if(currentElement) { + $animate.leave(currentElement); + currentElement = null; + } + }; + + scope.$watch($sce.parseAsResourceUrl(srcExp), function ngIncludeWatchAction(src) { + var afterAnimation = function() { + if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + }; + var thisChangeId = ++changeCounter; + + if (src) { + $http.get(src, {cache: $templateCache}).success(function(response) { + if (thisChangeId !== changeCounter) return; + var newScope = scope.$new(); + + // Note: This will also link all children of ng-include that were contained in the original + // html. If that content contains controllers, ... they could pollute/change the scope. + // However, using ng-include on an element with additional content does not make sense... + // Note: We can't remove them in the cloneAttchFn of $transclude as that + // function is called before linking the content, which would apply child + // directives to non existing elements. + var clone = $transclude(newScope, noop); + cleanupLastIncludeContent(); + + currentScope = newScope; + currentElement = clone; + + currentElement.html(response); + $animate.enter(currentElement, null, $element, afterAnimation); + $compile(currentElement.contents())(currentScope); + currentScope.$emit('$includeContentLoaded'); + scope.$eval(onloadExp); + }).error(function() { + if (thisChangeId === changeCounter) cleanupLastIncludeContent(); + }); + scope.$emit('$includeContentRequested'); + } else { + cleanupLastIncludeContent(); + } + }); + }; + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngInit + * @restrict AC + * + * @description + * The `ngInit` directive allows you to evaluate an expression in the + * current scope. + * + *
+ * The only appropriate use of `ngInit` for aliasing special properties of + * {@link api/ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below. Besides this case, you + * should use {@link guide/controller controllers} rather than `ngInit` + * to initialize values on a scope. + *
+ * + * @element ANY + * @param {expression} ngInit {@link guide/expression Expression} to eval. + * + * @example + + + +
+
+
+ list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}}; +
+
+
+
+ + it('should alias index positions', function() { + expect(element('.example-init').text()) + .toBe('list[ 0 ][ 0 ] = a;' + + 'list[ 0 ][ 1 ] = b;' + + 'list[ 1 ][ 0 ] = c;' + + 'list[ 1 ][ 1 ] = d;'); + }); + +
+ */ +var ngInitDirective = ngDirective({ + compile: function() { + return { + pre: function(scope, element, attrs) { + scope.$eval(attrs.ngInit); + } + }; + } +}); + +/** + * @ngdoc directive + * @name ng.directive:ngNonBindable + * @restrict AC + * @priority 1000 + * + * @description + * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current + * DOM element. This is useful if the element contains what appears to be Angular directives and + * bindings but which should be ignored by Angular. This could be the case if you have a site that + * displays snippets of code, for instance. + * + * @element ANY + * + * @example + * In this example there are two locations where a simple interpolation binding (`{{}}`) is present, + * but the one wrapped in `ngNonBindable` is left alone. + * + * @example + + +
Normal: {{1 + 2}}
+
Ignored: {{1 + 2}}
+
+ + it('should check ng-non-bindable', function() { + expect(using('.doc-example-live').binding('1 + 2')).toBe('3'); + expect(using('.doc-example-live').element('div:last').text()). + toMatch(/1 \+ 2/); + }); + +
+ */ +var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); + +/** + * @ngdoc directive + * @name ng.directive:ngPluralize + * @restrict EA + * + * @description + * # Overview + * `ngPluralize` is a directive that displays messages according to en-US localization rules. + * These rules are bundled with angular.js, but can be overridden + * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive + * by specifying the mappings between + * {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html + * plural categories} and the strings to be displayed. + * + * # Plural categories and explicit number rules + * There are two + * {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html + * plural categories} in Angular's default en-US locale: "one" and "other". + * + * While a plural category may match many numbers (for example, in en-US locale, "other" can match + * any number that is not 1), an explicit number rule can only match one number. For example, the + * explicit number rule for "3" matches the number 3. There are examples of plural categories + * and explicit number rules throughout the rest of this documentation. + * + * # Configuring ngPluralize + * You configure ngPluralize by providing 2 attributes: `count` and `when`. + * You can also provide an optional attribute, `offset`. + * + * The value of the `count` attribute can be either a string or an {@link guide/expression + * Angular expression}; these are evaluated on the current scope for its bound value. + * + * The `when` attribute specifies the mappings between plural categories and the actual + * string to be displayed. The value of the attribute should be a JSON object. + * + * The following example shows how to configure ngPluralize: + * + *
+ * 
+ * 
+ *
+ * + * In the example, `"0: Nobody is viewing."` is an explicit number rule. If you did not + * specify this rule, 0 would be matched to the "other" category and "0 people are viewing" + * would be shown instead of "Nobody is viewing". You can specify an explicit number rule for + * other numbers, for example 12, so that instead of showing "12 people are viewing", you can + * show "a dozen people are viewing". + * + * You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted + * into pluralized strings. In the previous example, Angular will replace `{}` with + * `{{personCount}}`. The closed braces `{}` is a placeholder + * for {{numberExpression}}. + * + * # Configuring ngPluralize with offset + * The `offset` attribute allows further customization of pluralized text, which can result in + * a better user experience. For example, instead of the message "4 people are viewing this document", + * you might display "John, Kate and 2 others are viewing this document". + * The offset attribute allows you to offset a number by any desired value. + * Let's take a look at an example: + * + *
+ * 
+ * 
+ * 
+ * + * Notice that we are still using two plural categories(one, other), but we added + * three explicit number rules 0, 1 and 2. + * When one person, perhaps John, views the document, "John is viewing" will be shown. + * When three people view the document, no explicit number rule is found, so + * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category. + * In this case, plural category 'one' is matched and "John, Marry and one other person are viewing" + * is shown. + * + * Note that when you specify offsets, you must provide explicit number rules for + * numbers from 0 up to and including the offset. If you use an offset of 3, for example, + * you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for + * plural categories "one" and "other". + * + * @param {string|expression} count The variable to be bounded to. + * @param {string} when The mapping between plural category to its corresponding strings. + * @param {number=} offset Offset to deduct from the total number. + * + * @example + + + +
+ Person 1:
+ Person 2:
+ Number of People:
+ + + Without Offset: + +
+ + + With Offset(2): + + +
+
+ + it('should show correct pluralized string', function() { + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('1 person is viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor is viewing.'); + + using('.doc-example-live').input('personCount').enter('0'); + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('Nobody is viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Nobody is viewing.'); + + using('.doc-example-live').input('personCount').enter('2'); + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('2 people are viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor and Misko are viewing.'); + + using('.doc-example-live').input('personCount').enter('3'); + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('3 people are viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor, Misko and one other person are viewing.'); + + using('.doc-example-live').input('personCount').enter('4'); + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('4 people are viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor, Misko and 2 other people are viewing.'); + }); + + it('should show data-binded names', function() { + using('.doc-example-live').input('personCount').enter('4'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor, Misko and 2 other people are viewing.'); + + using('.doc-example-live').input('person1').enter('Di'); + using('.doc-example-live').input('person2').enter('Vojta'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Di, Vojta and 2 other people are viewing.'); + }); + +
+ */ +var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) { + var BRACE = /{}/g; + return { + restrict: 'EA', + link: function(scope, element, attr) { + var numberExp = attr.count, + whenExp = attr.$attr.when && element.attr(attr.$attr.when), // we have {{}} in attrs + offset = attr.offset || 0, + whens = scope.$eval(whenExp) || {}, + whensExpFns = {}, + startSymbol = $interpolate.startSymbol(), + endSymbol = $interpolate.endSymbol(), + isWhen = /^when(Minus)?(.+)$/; + + forEach(attr, function(expression, attributeName) { + if (isWhen.test(attributeName)) { + whens[lowercase(attributeName.replace('when', '').replace('Minus', '-'))] = + element.attr(attr.$attr[attributeName]); + } + }); + forEach(whens, function(expression, key) { + whensExpFns[key] = + $interpolate(expression.replace(BRACE, startSymbol + numberExp + '-' + + offset + endSymbol)); + }); + + scope.$watch(function ngPluralizeWatch() { + var value = parseFloat(scope.$eval(numberExp)); + + if (!isNaN(value)) { + //if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise, + //check it against pluralization rules in $locale service + if (!(value in whens)) value = $locale.pluralCat(value - offset); + return whensExpFns[value](scope, element, true); + } else { + return ''; + } + }, function ngPluralizeWatchAction(newVal) { + element.text(newVal); + }); + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngRepeat + * + * @description + * The `ngRepeat` directive instantiates a template once per item from a collection. Each template + * instance gets its own scope, where the given loop variable is set to the current collection item, + * and `$index` is set to the item index or key. + * + * Special properties are exposed on the local scope of each template instance, including: + * + * | Variable | Type | Details | + * |-----------|-----------------|-----------------------------------------------------------------------------| + * | `$index` | {@type number} | iterator offset of the repeated element (0..length-1) | + * | `$first` | {@type boolean} | true if the repeated element is first in the iterator. | + * | `$middle` | {@type boolean} | true if the repeated element is between the first and last in the iterator. | + * | `$last` | {@type boolean} | true if the repeated element is last in the iterator. | + * | `$even` | {@type boolean} | true if the iterator position `$index` is even (otherwise false). | + * | `$odd` | {@type boolean} | true if the iterator position `$index` is odd (otherwise false). | + * + * + * # Special repeat start and end points + * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending + * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively. + * The **ng-repeat-start** directive works the same as **ng-repeat**, but will repeat all the HTML code (including the tag it's defined on) + * up to and including the ending HTML tag where **ng-repeat-end** is placed. + * + * The example below makes use of this feature: + *
+ *   
+ * Header {{ item }} + *
+ *
+ * Body {{ item }} + *
+ *
+ * Footer {{ item }} + *
+ *
+ * + * And with an input of {@type ['A','B']} for the items variable in the example above, the output will evaluate to: + *
+ *   
+ * Header A + *
+ *
+ * Body A + *
+ *
+ * Footer A + *
+ *
+ * Header B + *
+ *
+ * Body B + *
+ *
+ * Footer B + *
+ *
+ * + * The custom start and end points for ngRepeat also support all other HTML directive syntax flavors provided in AngularJS (such + * as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**). + * + * @animations + * enter - when a new item is added to the list or when an item is revealed after a filter + * leave - when an item is removed from the list or when an item is filtered out + * move - when an adjacent item is filtered out causing a reorder or when the item contents are reordered + * + * @element ANY + * @scope + * @priority 1000 + * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. These + * formats are currently supported: + * + * * `variable in expression` – where variable is the user defined loop variable and `expression` + * is a scope expression giving the collection to enumerate. + * + * For example: `album in artist.albums`. + * + * * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers, + * and `expression` is the scope expression giving the collection to enumerate. + * + * For example: `(name, age) in {'adam':10, 'amalie':12}`. + * + * * `variable in expression track by tracking_expression` – You can also provide an optional tracking function + * which can be used to associate the objects in the collection with the DOM elements. If no tracking function + * is specified the ng-repeat associates elements by identity in the collection. It is an error to have + * more than one tracking function to resolve to the same key. (This would mean that two distinct objects are + * mapped to the same DOM element, which is not possible.) Filters should be applied to the expression, + * before specifying a tracking expression. + * + * For example: `item in items` is equivalent to `item in items track by $id(item)'. This implies that the DOM elements + * will be associated by item identity in the array. + * + * For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique + * `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements + * with the corresponding item in the array by identity. Moving the same object in array would move the DOM + * element in the same way in the DOM. + * + * For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this + * case the object identity does not matter. Two objects are considered equivalent as long as their `id` + * property is same. + * + * For example: `item in items | filter:searchText track by item.id` is a pattern that might be used to apply a filter + * to items in conjunction with a tracking expression. + * + * @example + * This example initializes the scope to a list of names and + * then uses `ngRepeat` to display every person: + + +
+ I have {{friends.length}} friends. They are: + +
    +
  • + [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old. +
  • +
+
+
+ + .example-animate-container { + background:white; + border:1px solid black; + list-style:none; + margin:0; + padding:0 10px; + } + + .animate-repeat { + line-height:40px; + list-style:none; + box-sizing:border-box; + } + + .animate-repeat.ng-move, + .animate-repeat.ng-enter, + .animate-repeat.ng-leave { + -webkit-transition:all linear 0.5s; + transition:all linear 0.5s; + } + + .animate-repeat.ng-leave.ng-leave-active, + .animate-repeat.ng-move, + .animate-repeat.ng-enter { + opacity:0; + max-height:0; + } + + .animate-repeat.ng-leave, + .animate-repeat.ng-move.ng-move-active, + .animate-repeat.ng-enter.ng-enter-active { + opacity:1; + max-height:40px; + } + + + it('should render initial data set', function() { + var r = using('.doc-example-live').repeater('ul li'); + expect(r.count()).toBe(10); + expect(r.row(0)).toEqual(["1","John","25"]); + expect(r.row(1)).toEqual(["2","Jessie","30"]); + expect(r.row(9)).toEqual(["10","Samantha","60"]); + expect(binding('friends.length')).toBe("10"); + }); + + it('should update repeater when filter predicate changes', function() { + var r = using('.doc-example-live').repeater('ul li'); + expect(r.count()).toBe(10); + + input('q').enter('ma'); + + expect(r.count()).toBe(2); + expect(r.row(0)).toEqual(["1","Mary","28"]); + expect(r.row(1)).toEqual(["2","Samantha","60"]); + }); + +
+ */ +var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { + var NG_REMOVED = '$$NG_REMOVED'; + var ngRepeatMinErr = minErr('ngRepeat'); + return { + transclude: 'element', + priority: 1000, + terminal: true, + $$tlb: true, + link: function($scope, $element, $attr, ctrl, $transclude){ + var expression = $attr.ngRepeat; + var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/), + trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, + lhs, rhs, valueIdentifier, keyIdentifier, + hashFnLocals = {$id: hashKey}; + + if (!match) { + throw ngRepeatMinErr('iexp', "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.", + expression); + } + + lhs = match[1]; + rhs = match[2]; + trackByExp = match[4]; + + if (trackByExp) { + trackByExpGetter = $parse(trackByExp); + trackByIdExpFn = function(key, value, index) { + // assign key, value, and $index to the locals so that they can be used in hash functions + if (keyIdentifier) hashFnLocals[keyIdentifier] = key; + hashFnLocals[valueIdentifier] = value; + hashFnLocals.$index = index; + return trackByExpGetter($scope, hashFnLocals); + }; + } else { + trackByIdArrayFn = function(key, value) { + return hashKey(value); + }; + trackByIdObjFn = function(key) { + return key; + }; + } + + match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/); + if (!match) { + throw ngRepeatMinErr('iidexp', "'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.", + lhs); + } + valueIdentifier = match[3] || match[1]; + keyIdentifier = match[2]; + + // Store a list of elements from previous run. This is a hash where key is the item from the + // iterator, and the value is objects with following properties. + // - scope: bound scope + // - element: previous element. + // - index: position + var lastBlockMap = {}; + + //watch props + $scope.$watchCollection(rhs, function ngRepeatAction(collection){ + var index, length, + previousNode = $element[0], // current position of the node + nextNode, + // Same as lastBlockMap but it has the current state. It will become the + // lastBlockMap on the next iteration. + nextBlockMap = {}, + arrayLength, + childScope, + key, value, // key/value of iteration + trackById, + trackByIdFn, + collectionKeys, + block, // last object information {scope, element, id} + nextBlockOrder = [], + elementsToRemove; + + + if (isArrayLike(collection)) { + collectionKeys = collection; + trackByIdFn = trackByIdExpFn || trackByIdArrayFn; + } else { + trackByIdFn = trackByIdExpFn || trackByIdObjFn; + // if object, extract keys, sort them and use to determine order of iteration over obj props + collectionKeys = []; + for (key in collection) { + if (collection.hasOwnProperty(key) && key.charAt(0) != '$') { + collectionKeys.push(key); + } + } + collectionKeys.sort(); + } + + arrayLength = collectionKeys.length; + + // locate existing items + length = nextBlockOrder.length = collectionKeys.length; + for(index = 0; index < length; index++) { + key = (collection === collectionKeys) ? index : collectionKeys[index]; + value = collection[key]; + trackById = trackByIdFn(key, value, index); + assertNotHasOwnProperty(trackById, '`track by` id'); + if(lastBlockMap.hasOwnProperty(trackById)) { + block = lastBlockMap[trackById]; + delete lastBlockMap[trackById]; + nextBlockMap[trackById] = block; + nextBlockOrder[index] = block; + } else if (nextBlockMap.hasOwnProperty(trackById)) { + // restore lastBlockMap + forEach(nextBlockOrder, function(block) { + if (block && block.startNode) lastBlockMap[block.id] = block; + }); + // This is a duplicate and we need to throw an error + throw ngRepeatMinErr('dupes', "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}", + expression, trackById); + } else { + // new never before seen block + nextBlockOrder[index] = { id: trackById }; + nextBlockMap[trackById] = false; + } + } + + // remove existing items + for (key in lastBlockMap) { + // lastBlockMap is our own object so we don't need to use special hasOwnPropertyFn + if (lastBlockMap.hasOwnProperty(key)) { + block = lastBlockMap[key]; + elementsToRemove = getBlockElements(block); + $animate.leave(elementsToRemove); + forEach(elementsToRemove, function(element) { element[NG_REMOVED] = true; }); + block.scope.$destroy(); + } + } + + // we are not using forEach for perf reasons (trying to avoid #call) + for (index = 0, length = collectionKeys.length; index < length; index++) { + key = (collection === collectionKeys) ? index : collectionKeys[index]; + value = collection[key]; + block = nextBlockOrder[index]; + if (nextBlockOrder[index - 1]) previousNode = nextBlockOrder[index - 1].endNode; + + if (block.startNode) { + // if we have already seen this object, then we need to reuse the + // associated scope/element + childScope = block.scope; + + nextNode = previousNode; + do { + nextNode = nextNode.nextSibling; + } while(nextNode && nextNode[NG_REMOVED]); + + if (block.startNode != nextNode) { + // existing item which got moved + $animate.move(getBlockElements(block), null, jqLite(previousNode)); + } + previousNode = block.endNode; + } else { + // new item which we don't know about + childScope = $scope.$new(); + } + + childScope[valueIdentifier] = value; + if (keyIdentifier) childScope[keyIdentifier] = key; + childScope.$index = index; + childScope.$first = (index === 0); + childScope.$last = (index === (arrayLength - 1)); + childScope.$middle = !(childScope.$first || childScope.$last); + // jshint bitwise: false + childScope.$odd = !(childScope.$even = (index&1) === 0); + // jshint bitwise: true + + if (!block.startNode) { + $transclude(childScope, function(clone) { + clone[clone.length++] = document.createComment(' end ngRepeat: ' + expression + ' '); + $animate.enter(clone, null, jqLite(previousNode)); + previousNode = clone; + block.scope = childScope; + block.startNode = previousNode && previousNode.endNode ? previousNode.endNode : clone[0]; + block.endNode = clone[clone.length - 1]; + nextBlockMap[block.id] = block; + }); + } + } + lastBlockMap = nextBlockMap; + }); + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngShow + * + * @description + * The `ngShow` directive shows or hides the given HTML element based on the expression + * provided to the ngShow attribute. The element is shown or hidden by removing or adding + * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined + * in AngularJS and sets the display style to none (using an !important flag). + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}). + * + *
+ * 
+ * 
+ * + * + *
+ *
+ * + * When the ngShow expression evaluates to false then the ng-hide CSS class is added to the class attribute + * on the element causing it to become hidden. When true, the ng-hide CSS class is removed + * from the element causing the element not to appear hidden. + * + * ## Why is !important used? + * + * You may be wondering why !important is used for the .ng-hide CSS class. This is because the `.ng-hide` selector + * can be easily overridden by heavier selectors. For example, something as simple + * as changing the display style on a HTML list item would make hidden elements appear visible. + * This also becomes a bigger issue when dealing with CSS frameworks. + * + * By using !important, the show and hide behavior will work as expected despite any clash between CSS selector + * specificity (when !important isn't used with any conflicting styles). If a developer chooses to override the + * styling to change how to hide an element then it is just a matter of using !important in their own CSS code. + * + * ### Overriding .ng-hide + * + * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by + * restating the styles for the .ng-hide class in CSS: + *
+ * .ng-hide {
+ *   //!annotate CSS Specificity|Not to worry, this will override the AngularJS default...
+ *   display:block!important;
+ *
+ *   //this is just another form of hiding an element
+ *   position:absolute;
+ *   top:-9999px;
+ *   left:-9999px;
+ * }
+ * 
+ * + * Just remember to include the important flag so the CSS override will function. + * + * ## A note about animations with ngShow + * + * Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression + * is true and false. This system works like the animation system present with ngClass except that + * you must also include the !important flag to override the display property + * so that you can perform an animation when the element is hidden during the time of the animation. + * + *
+ * //
+ * //a working example can be found at the bottom of this page
+ * //
+ * .my-element.ng-hide-add, .my-element.ng-hide-remove {
+ *   transition:0.5s linear all;
+ *   display:block!important;
+ * }
+ *
+ * .my-element.ng-hide-add { ... }
+ * .my-element.ng-hide-add.ng-hide-add-active { ... }
+ * .my-element.ng-hide-remove { ... }
+ * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
+ * 
+ * + * @animations + * addClass: .ng-hide - happens after the ngShow expression evaluates to a truthy value and the just before contents are set to visible + * removeClass: .ng-hide - happens after the ngShow expression evaluates to a non truthy value and just before the contents are set to hidden + * + * @element ANY + * @param {expression} ngShow If the {@link guide/expression expression} is truthy + * then the element is shown or hidden respectively. + * + * @example + + + Click me:
+
+ Show: +
+ I show up when your checkbox is checked. +
+
+
+ Hide: +
+ I hide when your checkbox is checked. +
+
+
+ + .animate-show { + -webkit-transition:all linear 0.5s; + transition:all linear 0.5s; + line-height:20px; + opacity:1; + padding:10px; + border:1px solid black; + background:white; + } + + .animate-show.ng-hide-add, + .animate-show.ng-hide-remove { + display:block!important; + } + + .animate-show.ng-hide { + line-height:0; + opacity:0; + padding:0 10px; + } + + .check-element { + padding:10px; + border:1px solid black; + background:white; + } + + + it('should check ng-show / ng-hide', function() { + expect(element('.doc-example-live span:first:hidden').count()).toEqual(1); + expect(element('.doc-example-live span:last:visible').count()).toEqual(1); + + input('checked').check(); + + expect(element('.doc-example-live span:first:visible').count()).toEqual(1); + expect(element('.doc-example-live span:last:hidden').count()).toEqual(1); + }); + +
+ */ +var ngShowDirective = ['$animate', function($animate) { + return function(scope, element, attr) { + scope.$watch(attr.ngShow, function ngShowWatchAction(value){ + $animate[toBoolean(value) ? 'removeClass' : 'addClass'](element, 'ng-hide'); + }); + }; +}]; + + +/** + * @ngdoc directive + * @name ng.directive:ngHide + * + * @description + * The `ngHide` directive shows or hides the given HTML element based on the expression + * provided to the ngHide attribute. The element is shown or hidden by removing or adding + * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined + * in AngularJS and sets the display style to none (using an !important flag). + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}). + * + *
+ * 
+ * 
+ * + * + *
+ *
+ * + * When the ngHide expression evaluates to true then the .ng-hide CSS class is added to the class attribute + * on the element causing it to become hidden. When false, the ng-hide CSS class is removed + * from the element causing the element not to appear hidden. + * + * ## Why is !important used? + * + * You may be wondering why !important is used for the .ng-hide CSS class. This is because the `.ng-hide` selector + * can be easily overridden by heavier selectors. For example, something as simple + * as changing the display style on a HTML list item would make hidden elements appear visible. + * This also becomes a bigger issue when dealing with CSS frameworks. + * + * By using !important, the show and hide behavior will work as expected despite any clash between CSS selector + * specificity (when !important isn't used with any conflicting styles). If a developer chooses to override the + * styling to change how to hide an element then it is just a matter of using !important in their own CSS code. + * + * ### Overriding .ng-hide + * + * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by + * restating the styles for the .ng-hide class in CSS: + *
+ * .ng-hide {
+ *   //!annotate CSS Specificity|Not to worry, this will override the AngularJS default...
+ *   display:block!important;
+ *
+ *   //this is just another form of hiding an element
+ *   position:absolute;
+ *   top:-9999px;
+ *   left:-9999px;
+ * }
+ * 
+ * + * Just remember to include the important flag so the CSS override will function. + * + * ## A note about animations with ngHide + * + * Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression + * is true and false. This system works like the animation system present with ngClass, except that + * you must also include the !important flag to override the display property so + * that you can perform an animation when the element is hidden during the time of the animation. + * + *
+ * //
+ * //a working example can be found at the bottom of this page
+ * //
+ * .my-element.ng-hide-add, .my-element.ng-hide-remove {
+ *   transition:0.5s linear all;
+ *   display:block!important;
+ * }
+ *
+ * .my-element.ng-hide-add { ... }
+ * .my-element.ng-hide-add.ng-hide-add-active { ... }
+ * .my-element.ng-hide-remove { ... }
+ * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
+ * 
+ * + * @animations + * removeClass: .ng-hide - happens after the ngHide expression evaluates to a truthy value and just before the contents are set to hidden + * addClass: .ng-hide - happens after the ngHide expression evaluates to a non truthy value and just before the contents are set to visible + * + * @element ANY + * @param {expression} ngHide If the {@link guide/expression expression} is truthy then + * the element is shown or hidden respectively. + * + * @example + + + Click me:
+
+ Show: +
+ I show up when your checkbox is checked. +
+
+
+ Hide: +
+ I hide when your checkbox is checked. +
+
+
+ + .animate-hide { + -webkit-transition:all linear 0.5s; + transition:all linear 0.5s; + line-height:20px; + opacity:1; + padding:10px; + border:1px solid black; + background:white; + } + + .animate-hide.ng-hide-add, + .animate-hide.ng-hide-remove { + display:block!important; + } + + .animate-hide.ng-hide { + line-height:0; + opacity:0; + padding:0 10px; + } + + .check-element { + padding:10px; + border:1px solid black; + background:white; + } + + + it('should check ng-show / ng-hide', function() { + expect(element('.doc-example-live .check-element:first:hidden').count()).toEqual(1); + expect(element('.doc-example-live .check-element:last:visible').count()).toEqual(1); + + input('checked').check(); + + expect(element('.doc-example-live .check-element:first:visible').count()).toEqual(1); + expect(element('.doc-example-live .check-element:last:hidden').count()).toEqual(1); + }); + +
+ */ +var ngHideDirective = ['$animate', function($animate) { + return function(scope, element, attr) { + scope.$watch(attr.ngHide, function ngHideWatchAction(value){ + $animate[toBoolean(value) ? 'addClass' : 'removeClass'](element, 'ng-hide'); + }); + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngStyle + * @restrict AC + * + * @description + * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally. + * + * @element ANY + * @param {expression} ngStyle {@link guide/expression Expression} which evals to an + * object whose keys are CSS style names and values are corresponding values for those CSS + * keys. + * + * @example + + + + +
+ Sample Text +
myStyle={{myStyle}}
+
+ + span { + color: black; + } + + + it('should check ng-style', function() { + expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)'); + element('.doc-example-live :button[value=set]').click(); + expect(element('.doc-example-live span').css('color')).toBe('rgb(255, 0, 0)'); + element('.doc-example-live :button[value=clear]').click(); + expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)'); + }); + +
+ */ +var ngStyleDirective = ngDirective(function(scope, element, attr) { + scope.$watch(attr.ngStyle, function ngStyleWatchAction(newStyles, oldStyles) { + if (oldStyles && (newStyles !== oldStyles)) { + forEach(oldStyles, function(val, style) { element.css(style, '');}); + } + if (newStyles) element.css(newStyles); + }, true); +}); + +/** + * @ngdoc directive + * @name ng.directive:ngSwitch + * @restrict EA + * + * @description + * The ngSwitch directive is used to conditionally swap DOM structure on your template based on a scope expression. + * Elements within ngSwitch but without ngSwitchWhen or ngSwitchDefault directives will be preserved at the location + * as specified in the template. + * + * The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it + * from the template cache), ngSwitch simply choses one of the nested elements and makes it visible based on which element + * matches the value obtained from the evaluated expression. In other words, you define a container element + * (where you place the directive), place an expression on the **on="..." attribute** + * (or the **ng-switch="..." attribute**), define any inner elements inside of the directive and place + * a when attribute per element. The when attribute is used to inform ngSwitch which element to display when the on + * expression is evaluated. If a matching expression is not found via a when attribute then an element with the default + * attribute is displayed. + * + * @animations + * enter - happens after the ngSwitch contents change and the matched child element is placed inside the container + * leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM + * + * @usage + * + * ... + * ... + * ... + * + * + * @scope + * @priority 800 + * @param {*} ngSwitch|on expression to match against ng-switch-when. + * @paramDescription + * On child elements add: + * + * * `ngSwitchWhen`: the case statement to match against. If match then this + * case will be displayed. If the same match appears multiple times, all the + * elements will be displayed. + * * `ngSwitchDefault`: the default case when no other case match. If there + * are multiple default cases, all of them will be displayed when no other + * case match. + * + * + * @example + + +
+ + selection={{selection}} +
+
+
Settings Div
+
Home Span
+
default
+
+
+
+ + function Ctrl($scope) { + $scope.items = ['settings', 'home', 'other']; + $scope.selection = $scope.items[0]; + } + + + .animate-switch-container { + position:relative; + background:white; + border:1px solid black; + height:40px; + overflow:hidden; + } + + .animate-switch { + padding:10px; + } + + .animate-switch.ng-animate { + -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; + + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + } + + .animate-switch.ng-leave.ng-leave-active, + .animate-switch.ng-enter { + top:-50px; + } + .animate-switch.ng-leave, + .animate-switch.ng-enter.ng-enter-active { + top:0; + } + + + it('should start in settings', function() { + expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Settings Div/); + }); + it('should change to home', function() { + select('selection').option('home'); + expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Home Span/); + }); + it('should select default', function() { + select('selection').option('other'); + expect(element('.doc-example-live [ng-switch]').text()).toMatch(/default/); + }); + +
+ */ +var ngSwitchDirective = ['$animate', function($animate) { + return { + restrict: 'EA', + require: 'ngSwitch', + + // asks for $scope to fool the BC controller module + controller: ['$scope', function ngSwitchController() { + this.cases = {}; + }], + link: function(scope, element, attr, ngSwitchController) { + var watchExpr = attr.ngSwitch || attr.on, + selectedTranscludes, + selectedElements, + selectedScopes = []; + + scope.$watch(watchExpr, function ngSwitchWatchAction(value) { + for (var i= 0, ii=selectedScopes.length; i + + +
+
+
+ {{text}} +
+
+ + it('should have transcluded', function() { + input('title').enter('TITLE'); + input('text').enter('TEXT'); + expect(binding('title')).toEqual('TITLE'); + expect(binding('text')).toEqual('TEXT'); + }); + + + * + */ +var ngTranscludeDirective = ngDirective({ + controller: ['$element', '$transclude', function($element, $transclude) { + if (!$transclude) { + throw minErr('ngTransclude')('orphan', + 'Illegal use of ngTransclude directive in the template! ' + + 'No parent directive that requires a transclusion found. ' + + 'Element: {0}', + startingTag($element)); + } + + // remember the transclusion fn but call it during linking so that we don't process transclusion before directives on + // the parent element even when the transclusion replaces the current element. (we can't use priority here because + // that applies only to compile fns and not controllers + this.$transclude = $transclude; + }], + + link: function($scope, $element, $attrs, controller) { + controller.$transclude(function(clone) { + $element.html(''); + $element.append(clone); + }); + } +}); + +/** + * @ngdoc directive + * @name ng.directive:script + * @restrict E + * + * @description + * Load content of a script tag, with type `text/ng-template`, into `$templateCache`, so that the + * template can be used by `ngInclude`, `ngView` or directive templates. + * + * @param {'text/ng-template'} type must be set to `'text/ng-template'` + * + * @example + + + + + Load inlined template +
+
+ + it('should load template defined inside script tag', function() { + element('#tpl-link').click(); + expect(element('#tpl-content').text()).toMatch(/Content of the template/); + }); + +
+ */ +var scriptDirective = ['$templateCache', function($templateCache) { + return { + restrict: 'E', + terminal: true, + compile: function(element, attr) { + if (attr.type == 'text/ng-template') { + var templateUrl = attr.id, + // IE is not consistent, in scripts we have to read .text but in other nodes we have to read .textContent + text = element[0].text; + + $templateCache.put(templateUrl, text); + } + } + }; +}]; + +var ngOptionsMinErr = minErr('ngOptions'); +/** + * @ngdoc directive + * @name ng.directive:select + * @restrict E + * + * @description + * HTML `SELECT` element with angular data-binding. + * + * # `ngOptions` + * + * The `ngOptions` attribute can be used to dynamically generate a list of `` + * DOM element. + * * `trackexpr`: Used when working with an array of objects. The result of this expression will be + * used to identify the objects in the array. The `trackexpr` will most likely refer to the + * `value` variable (e.g. `value.propertyName`). + * + * @example + + + +
+
    +
  • + Name: + [X] +
  • +
  • + [add] +
  • +
+
+ Color (null not allowed): +
+ + Color (null allowed): + + +
+ + Color grouped by shade: +
+ + + Select bogus.
+
+ Currently selected: {{ {selected_color:color} }} +
+
+
+
+ + it('should check ng-options', function() { + expect(binding('{selected_color:color}')).toMatch('red'); + select('color').option('0'); + expect(binding('{selected_color:color}')).toMatch('black'); + using('.nullable').select('color').option(''); + expect(binding('{selected_color:color}')).toMatch('null'); + }); + +
+ */ + +var ngOptionsDirective = valueFn({ terminal: true }); +// jshint maxlen: false +var selectDirective = ['$compile', '$parse', function($compile, $parse) { + //0000111110000000000022220000000000000000000000333300000000000000444444444444444000000000555555555555555000000066666666666666600000000000000007777000000000000000000088888 + var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/, + nullModelCtrl = {$setViewValue: noop}; +// jshint maxlen: 100 + + return { + restrict: 'E', + require: ['select', '?ngModel'], + controller: ['$element', '$scope', '$attrs', function($element, $scope, $attrs) { + var self = this, + optionsMap = {}, + ngModelCtrl = nullModelCtrl, + nullOption, + unknownOption; + + + self.databound = $attrs.ngModel; + + + self.init = function(ngModelCtrl_, nullOption_, unknownOption_) { + ngModelCtrl = ngModelCtrl_; + nullOption = nullOption_; + unknownOption = unknownOption_; + }; + + + self.addOption = function(value) { + assertNotHasOwnProperty(value, '"option value"'); + optionsMap[value] = true; + + if (ngModelCtrl.$viewValue == value) { + $element.val(value); + if (unknownOption.parent()) unknownOption.remove(); + } + }; + + + self.removeOption = function(value) { + if (this.hasOption(value)) { + delete optionsMap[value]; + if (ngModelCtrl.$viewValue == value) { + this.renderUnknownOption(value); + } + } + }; + + + self.renderUnknownOption = function(val) { + var unknownVal = '? ' + hashKey(val) + ' ?'; + unknownOption.val(unknownVal); + $element.prepend(unknownOption); + $element.val(unknownVal); + unknownOption.prop('selected', true); // needed for IE + }; + + + self.hasOption = function(value) { + return optionsMap.hasOwnProperty(value); + }; + + $scope.$on('$destroy', function() { + // disable unknown option so that we don't do work when the whole select is being destroyed + self.renderUnknownOption = noop; + }); + }], + + link: function(scope, element, attr, ctrls) { + // if ngModel is not defined, we don't need to do anything + if (!ctrls[1]) return; + + var selectCtrl = ctrls[0], + ngModelCtrl = ctrls[1], + multiple = attr.multiple, + optionsExp = attr.ngOptions, + nullOption = false, // if false, user will not be able to select it (used by ngOptions) + emptyOption, + // we can't just jqLite('",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
a",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="
t
",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t +}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X
","
"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle); +u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("

+YFG4Kq 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±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