Full Code of zhukov/webogram for AI

master 928731935f36 cached
1045 files
13.0 MB
3.5M tokens
7092 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (13,803K chars total). Download the full file to get everything.
Repository: zhukov/webogram
Branch: master
Commit: 928731935f36
Files: 1045
Total size: 13.0 MB

Directory structure:
gitextract_xpysw2_p/

├── .dockerignore
├── .gitignore
├── .tx/
│   └── config
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── app/
│   ├── badbrowser.html
│   ├── index.html
│   ├── js/
│   │   ├── app.js
│   │   ├── background.js
│   │   ├── controllers.js
│   │   ├── directives.js
│   │   ├── directives_mobile.js
│   │   ├── filters.js
│   │   ├── init.js
│   │   ├── lib/
│   │   │   ├── bin_utils.js
│   │   │   ├── config.js
│   │   │   ├── crypto_worker.js
│   │   │   ├── i18n.js
│   │   │   ├── mtproto.js
│   │   │   ├── mtproto_wrapper.js
│   │   │   ├── ng_utils.js
│   │   │   ├── polyfill.js
│   │   │   ├── push_worker.js
│   │   │   ├── schema.tl
│   │   │   ├── tl_utils.js
│   │   │   └── utils.js
│   │   ├── locales/
│   │   │   ├── README.md
│   │   │   ├── de-de.json
│   │   │   ├── en-us.json
│   │   │   ├── es-es.json
│   │   │   ├── it-it.json
│   │   │   ├── nl-nl.json
│   │   │   ├── pt-br.json
│   │   │   └── ru-ru.json
│   │   ├── message_composer.js
│   │   ├── messages_manager.js
│   │   ├── offline_manager.js
│   │   └── services.js
│   ├── less/
│   │   ├── app.less
│   │   ├── desktop.less
│   │   ├── font.less
│   │   ├── lib/
│   │   │   └── mixins.less
│   │   └── mobile.less
│   ├── manifest.json
│   ├── manifest.webapp
│   ├── manifest.webapp.json
│   ├── nacl/
│   │   ├── Makefile
│   │   ├── aes.h
│   │   ├── aes_core.c
│   │   ├── aes_ige.c
│   │   ├── aes_locl.h
│   │   ├── aes_misc.c
│   │   ├── mtproto_crypto.bc
│   │   ├── mtproto_crypto.cc
│   │   ├── mtproto_crypto.nmf
│   │   └── mtproto_crypto.pexe
│   ├── partials/
│   │   ├── desktop/
│   │   │   ├── audio_player.html
│   │   │   ├── changelog_modal.html
│   │   │   ├── channel_edit_modal.html
│   │   │   ├── channel_modal.html
│   │   │   ├── chat_create_modal.html
│   │   │   ├── chat_edit_modal.html
│   │   │   ├── chat_invite_link_modal.html
│   │   │   ├── chat_modal.html
│   │   │   ├── composer_dropdown.html
│   │   │   ├── confirm_modal.html
│   │   │   ├── contacts_modal.html
│   │   │   ├── country_select_modal.html
│   │   │   ├── dialog.html
│   │   │   ├── document_modal.html
│   │   │   ├── edit_contact_modal.html
│   │   │   ├── embed_modal.html
│   │   │   ├── emoji_btn_tooltip.html
│   │   │   ├── error_modal.html
│   │   │   ├── footer.html
│   │   │   ├── forwarded_messages.html
│   │   │   ├── full_document.html
│   │   │   ├── full_gif.html
│   │   │   ├── full_photo.html
│   │   │   ├── full_round.html
│   │   │   ├── full_video.html
│   │   │   ├── game_modal.html
│   │   │   ├── head.html
│   │   │   ├── im.html
│   │   │   ├── import_contact_modal.html
│   │   │   ├── inactive.html
│   │   │   ├── inline_results.html
│   │   │   ├── lang_footer.html
│   │   │   ├── login.html
│   │   │   ├── media_modal_layout.html
│   │   │   ├── megagroup_edit_modal.html
│   │   │   ├── message.html
│   │   │   ├── message_attach_contact.html
│   │   │   ├── message_attach_document.html
│   │   │   ├── message_attach_game.html
│   │   │   ├── message_attach_geo.html
│   │   │   ├── message_attach_pending.html
│   │   │   ├── message_attach_photo.html
│   │   │   ├── message_attach_venue.html
│   │   │   ├── message_attach_webpage.html
│   │   │   ├── message_media.html
│   │   │   ├── message_service.html
│   │   │   ├── password_recovery_modal.html
│   │   │   ├── password_update_modal.html
│   │   │   ├── peer_pinned_message_bar.html
│   │   │   ├── peer_select.html
│   │   │   ├── photo_modal.html
│   │   │   ├── pinned_message.html
│   │   │   ├── profile_edit_modal.html
│   │   │   ├── reply_markup.html
│   │   │   ├── reply_message.html
│   │   │   ├── report_msgs_modal.html
│   │   │   ├── send_form.html
│   │   │   ├── sessions_list_modal.html
│   │   │   ├── settings_modal.html
│   │   │   ├── short_message.html
│   │   │   ├── slider.html
│   │   │   ├── stickerset_modal.html
│   │   │   ├── user_modal.html
│   │   │   ├── username_edit_modal.html
│   │   │   └── video_modal.html
│   │   └── mobile/
│   │       ├── audio_player.html
│   │       ├── changelog_modal.html
│   │       ├── channel_modal.html
│   │       ├── chat_create_modal.html
│   │       ├── chat_edit_modal.html
│   │       ├── chat_modal.html
│   │       ├── contacts_modal.html
│   │       ├── country_select_modal.html
│   │       ├── dialog.html
│   │       ├── edit_contact_modal.html
│   │       ├── full_gif.html
│   │       ├── full_photo.html
│   │       ├── full_video.html
│   │       ├── game_modal.html
│   │       ├── head.html
│   │       ├── im.html
│   │       ├── import_contact_modal.html
│   │       ├── login.html
│   │       ├── message.html
│   │       ├── message_actions_modal.html
│   │       ├── message_attach_contact.html
│   │       ├── message_attach_document.html
│   │       ├── message_attach_geo.html
│   │       ├── message_attach_pending.html
│   │       ├── message_attach_photo.html
│   │       ├── message_attach_venue.html
│   │       ├── message_attach_webpage.html
│   │       ├── message_service.html
│   │       ├── password_recovery_modal.html
│   │       ├── password_update_modal.html
│   │       ├── peer_select.html
│   │       ├── phonebook_modal.html
│   │       ├── photo_modal.html
│   │       ├── profile_edit_modal.html
│   │       ├── send_form.html
│   │       ├── sessions_list_modal.html
│   │       ├── settings_modal.html
│   │       ├── stickerset_modal.html
│   │       ├── user_modal.html
│   │       ├── username_edit_modal.html
│   │       └── video_modal.html
│   ├── service_worker.js
│   ├── vendor/
│   │   ├── README.md
│   │   ├── angular/
│   │   │   ├── angular-animate.js
│   │   │   ├── angular-aria.js
│   │   │   ├── angular-cookies.js
│   │   │   ├── angular-csp.css
│   │   │   ├── angular-loader.js
│   │   │   ├── angular-message-format.js
│   │   │   ├── angular-messages.js
│   │   │   ├── angular-mocks.js
│   │   │   ├── angular-parse-ext.js
│   │   │   ├── angular-resource.js
│   │   │   ├── angular-route.js
│   │   │   ├── angular-sanitize.js
│   │   │   ├── angular-touch.js
│   │   │   ├── angular.js
│   │   │   ├── errors.json
│   │   │   ├── i18n/
│   │   │   │   ├── angular-locale_af-na.js
│   │   │   │   ├── angular-locale_af-za.js
│   │   │   │   ├── angular-locale_af.js
│   │   │   │   ├── angular-locale_agq-cm.js
│   │   │   │   ├── angular-locale_agq.js
│   │   │   │   ├── angular-locale_ak-gh.js
│   │   │   │   ├── angular-locale_ak.js
│   │   │   │   ├── angular-locale_am-et.js
│   │   │   │   ├── angular-locale_am.js
│   │   │   │   ├── angular-locale_ar-001.js
│   │   │   │   ├── angular-locale_ar-ae.js
│   │   │   │   ├── angular-locale_ar-bh.js
│   │   │   │   ├── angular-locale_ar-dj.js
│   │   │   │   ├── angular-locale_ar-dz.js
│   │   │   │   ├── angular-locale_ar-eg.js
│   │   │   │   ├── angular-locale_ar-eh.js
│   │   │   │   ├── angular-locale_ar-er.js
│   │   │   │   ├── angular-locale_ar-il.js
│   │   │   │   ├── angular-locale_ar-iq.js
│   │   │   │   ├── angular-locale_ar-jo.js
│   │   │   │   ├── angular-locale_ar-km.js
│   │   │   │   ├── angular-locale_ar-kw.js
│   │   │   │   ├── angular-locale_ar-lb.js
│   │   │   │   ├── angular-locale_ar-ly.js
│   │   │   │   ├── angular-locale_ar-ma.js
│   │   │   │   ├── angular-locale_ar-mr.js
│   │   │   │   ├── angular-locale_ar-om.js
│   │   │   │   ├── angular-locale_ar-ps.js
│   │   │   │   ├── angular-locale_ar-qa.js
│   │   │   │   ├── angular-locale_ar-sa.js
│   │   │   │   ├── angular-locale_ar-sd.js
│   │   │   │   ├── angular-locale_ar-so.js
│   │   │   │   ├── angular-locale_ar-ss.js
│   │   │   │   ├── angular-locale_ar-sy.js
│   │   │   │   ├── angular-locale_ar-td.js
│   │   │   │   ├── angular-locale_ar-tn.js
│   │   │   │   ├── angular-locale_ar-xb.js
│   │   │   │   ├── angular-locale_ar-ye.js
│   │   │   │   ├── angular-locale_ar.js
│   │   │   │   ├── angular-locale_as-in.js
│   │   │   │   ├── angular-locale_as.js
│   │   │   │   ├── angular-locale_asa-tz.js
│   │   │   │   ├── angular-locale_asa.js
│   │   │   │   ├── angular-locale_ast-es.js
│   │   │   │   ├── angular-locale_ast.js
│   │   │   │   ├── angular-locale_az-cyrl-az.js
│   │   │   │   ├── angular-locale_az-cyrl.js
│   │   │   │   ├── angular-locale_az-latn-az.js
│   │   │   │   ├── angular-locale_az-latn.js
│   │   │   │   ├── angular-locale_az.js
│   │   │   │   ├── angular-locale_bas-cm.js
│   │   │   │   ├── angular-locale_bas.js
│   │   │   │   ├── angular-locale_be-by.js
│   │   │   │   ├── angular-locale_be.js
│   │   │   │   ├── angular-locale_bem-zm.js
│   │   │   │   ├── angular-locale_bem.js
│   │   │   │   ├── angular-locale_bez-tz.js
│   │   │   │   ├── angular-locale_bez.js
│   │   │   │   ├── angular-locale_bg-bg.js
│   │   │   │   ├── angular-locale_bg.js
│   │   │   │   ├── angular-locale_bm-ml.js
│   │   │   │   ├── angular-locale_bm.js
│   │   │   │   ├── angular-locale_bn-bd.js
│   │   │   │   ├── angular-locale_bn-in.js
│   │   │   │   ├── angular-locale_bn.js
│   │   │   │   ├── angular-locale_bo-cn.js
│   │   │   │   ├── angular-locale_bo-in.js
│   │   │   │   ├── angular-locale_bo.js
│   │   │   │   ├── angular-locale_br-fr.js
│   │   │   │   ├── angular-locale_br.js
│   │   │   │   ├── angular-locale_brx-in.js
│   │   │   │   ├── angular-locale_brx.js
│   │   │   │   ├── angular-locale_bs-cyrl-ba.js
│   │   │   │   ├── angular-locale_bs-cyrl.js
│   │   │   │   ├── angular-locale_bs-latn-ba.js
│   │   │   │   ├── angular-locale_bs-latn.js
│   │   │   │   ├── angular-locale_bs.js
│   │   │   │   ├── angular-locale_ca-ad.js
│   │   │   │   ├── angular-locale_ca-es-valencia.js
│   │   │   │   ├── angular-locale_ca-es.js
│   │   │   │   ├── angular-locale_ca-fr.js
│   │   │   │   ├── angular-locale_ca-it.js
│   │   │   │   ├── angular-locale_ca.js
│   │   │   │   ├── angular-locale_ce-ru.js
│   │   │   │   ├── angular-locale_ce.js
│   │   │   │   ├── angular-locale_cgg-ug.js
│   │   │   │   ├── angular-locale_cgg.js
│   │   │   │   ├── angular-locale_chr-us.js
│   │   │   │   ├── angular-locale_chr.js
│   │   │   │   ├── angular-locale_ckb-arab-iq.js
│   │   │   │   ├── angular-locale_ckb-arab-ir.js
│   │   │   │   ├── angular-locale_ckb-arab.js
│   │   │   │   ├── angular-locale_ckb-iq.js
│   │   │   │   ├── angular-locale_ckb-ir.js
│   │   │   │   ├── angular-locale_ckb-latn-iq.js
│   │   │   │   ├── angular-locale_ckb-latn.js
│   │   │   │   ├── angular-locale_ckb.js
│   │   │   │   ├── angular-locale_cs-cz.js
│   │   │   │   ├── angular-locale_cs.js
│   │   │   │   ├── angular-locale_cu-ru.js
│   │   │   │   ├── angular-locale_cu.js
│   │   │   │   ├── angular-locale_cy-gb.js
│   │   │   │   ├── angular-locale_cy.js
│   │   │   │   ├── angular-locale_da-dk.js
│   │   │   │   ├── angular-locale_da-gl.js
│   │   │   │   ├── angular-locale_da.js
│   │   │   │   ├── angular-locale_dav-ke.js
│   │   │   │   ├── angular-locale_dav.js
│   │   │   │   ├── angular-locale_de-at.js
│   │   │   │   ├── angular-locale_de-be.js
│   │   │   │   ├── angular-locale_de-ch.js
│   │   │   │   ├── angular-locale_de-de.js
│   │   │   │   ├── angular-locale_de-it.js
│   │   │   │   ├── angular-locale_de-li.js
│   │   │   │   ├── angular-locale_de-lu.js
│   │   │   │   ├── angular-locale_de.js
│   │   │   │   ├── angular-locale_dje-ne.js
│   │   │   │   ├── angular-locale_dje.js
│   │   │   │   ├── angular-locale_dsb-de.js
│   │   │   │   ├── angular-locale_dsb.js
│   │   │   │   ├── angular-locale_dua-cm.js
│   │   │   │   ├── angular-locale_dua.js
│   │   │   │   ├── angular-locale_dyo-sn.js
│   │   │   │   ├── angular-locale_dyo.js
│   │   │   │   ├── angular-locale_dz-bt.js
│   │   │   │   ├── angular-locale_dz.js
│   │   │   │   ├── angular-locale_ebu-ke.js
│   │   │   │   ├── angular-locale_ebu.js
│   │   │   │   ├── angular-locale_ee-gh.js
│   │   │   │   ├── angular-locale_ee-tg.js
│   │   │   │   ├── angular-locale_ee.js
│   │   │   │   ├── angular-locale_el-cy.js
│   │   │   │   ├── angular-locale_el-gr.js
│   │   │   │   ├── angular-locale_el.js
│   │   │   │   ├── angular-locale_en-001.js
│   │   │   │   ├── angular-locale_en-150.js
│   │   │   │   ├── angular-locale_en-ag.js
│   │   │   │   ├── angular-locale_en-ai.js
│   │   │   │   ├── angular-locale_en-as.js
│   │   │   │   ├── angular-locale_en-at.js
│   │   │   │   ├── angular-locale_en-au.js
│   │   │   │   ├── angular-locale_en-bb.js
│   │   │   │   ├── angular-locale_en-be.js
│   │   │   │   ├── angular-locale_en-bi.js
│   │   │   │   ├── angular-locale_en-bm.js
│   │   │   │   ├── angular-locale_en-bs.js
│   │   │   │   ├── angular-locale_en-bw.js
│   │   │   │   ├── angular-locale_en-bz.js
│   │   │   │   ├── angular-locale_en-ca.js
│   │   │   │   ├── angular-locale_en-cc.js
│   │   │   │   ├── angular-locale_en-ch.js
│   │   │   │   ├── angular-locale_en-ck.js
│   │   │   │   ├── angular-locale_en-cm.js
│   │   │   │   ├── angular-locale_en-cx.js
│   │   │   │   ├── angular-locale_en-cy.js
│   │   │   │   ├── angular-locale_en-de.js
│   │   │   │   ├── angular-locale_en-dg.js
│   │   │   │   ├── angular-locale_en-dk.js
│   │   │   │   ├── angular-locale_en-dm.js
│   │   │   │   ├── angular-locale_en-er.js
│   │   │   │   ├── angular-locale_en-fi.js
│   │   │   │   ├── angular-locale_en-fj.js
│   │   │   │   ├── angular-locale_en-fk.js
│   │   │   │   ├── angular-locale_en-fm.js
│   │   │   │   ├── angular-locale_en-gb.js
│   │   │   │   ├── angular-locale_en-gd.js
│   │   │   │   ├── angular-locale_en-gg.js
│   │   │   │   ├── angular-locale_en-gh.js
│   │   │   │   ├── angular-locale_en-gi.js
│   │   │   │   ├── angular-locale_en-gm.js
│   │   │   │   ├── angular-locale_en-gu.js
│   │   │   │   ├── angular-locale_en-gy.js
│   │   │   │   ├── angular-locale_en-hk.js
│   │   │   │   ├── angular-locale_en-ie.js
│   │   │   │   ├── angular-locale_en-il.js
│   │   │   │   ├── angular-locale_en-im.js
│   │   │   │   ├── angular-locale_en-in.js
│   │   │   │   ├── angular-locale_en-io.js
│   │   │   │   ├── angular-locale_en-iso.js
│   │   │   │   ├── angular-locale_en-je.js
│   │   │   │   ├── angular-locale_en-jm.js
│   │   │   │   ├── angular-locale_en-ke.js
│   │   │   │   ├── angular-locale_en-ki.js
│   │   │   │   ├── angular-locale_en-kn.js
│   │   │   │   ├── angular-locale_en-ky.js
│   │   │   │   ├── angular-locale_en-lc.js
│   │   │   │   ├── angular-locale_en-lr.js
│   │   │   │   ├── angular-locale_en-ls.js
│   │   │   │   ├── angular-locale_en-mg.js
│   │   │   │   ├── angular-locale_en-mh.js
│   │   │   │   ├── angular-locale_en-mo.js
│   │   │   │   ├── angular-locale_en-mp.js
│   │   │   │   ├── angular-locale_en-ms.js
│   │   │   │   ├── angular-locale_en-mt.js
│   │   │   │   ├── angular-locale_en-mu.js
│   │   │   │   ├── angular-locale_en-mw.js
│   │   │   │   ├── angular-locale_en-my.js
│   │   │   │   ├── angular-locale_en-na.js
│   │   │   │   ├── angular-locale_en-nf.js
│   │   │   │   ├── angular-locale_en-ng.js
│   │   │   │   ├── angular-locale_en-nl.js
│   │   │   │   ├── angular-locale_en-nr.js
│   │   │   │   ├── angular-locale_en-nu.js
│   │   │   │   ├── angular-locale_en-nz.js
│   │   │   │   ├── angular-locale_en-pg.js
│   │   │   │   ├── angular-locale_en-ph.js
│   │   │   │   ├── angular-locale_en-pk.js
│   │   │   │   ├── angular-locale_en-pn.js
│   │   │   │   ├── angular-locale_en-pr.js
│   │   │   │   ├── angular-locale_en-pw.js
│   │   │   │   ├── angular-locale_en-rw.js
│   │   │   │   ├── angular-locale_en-sb.js
│   │   │   │   ├── angular-locale_en-sc.js
│   │   │   │   ├── angular-locale_en-sd.js
│   │   │   │   ├── angular-locale_en-se.js
│   │   │   │   ├── angular-locale_en-sg.js
│   │   │   │   ├── angular-locale_en-sh.js
│   │   │   │   ├── angular-locale_en-si.js
│   │   │   │   ├── angular-locale_en-sl.js
│   │   │   │   ├── angular-locale_en-ss.js
│   │   │   │   ├── angular-locale_en-sx.js
│   │   │   │   ├── angular-locale_en-sz.js
│   │   │   │   ├── angular-locale_en-tc.js
│   │   │   │   ├── angular-locale_en-tk.js
│   │   │   │   ├── angular-locale_en-to.js
│   │   │   │   ├── angular-locale_en-tt.js
│   │   │   │   ├── angular-locale_en-tv.js
│   │   │   │   ├── angular-locale_en-tz.js
│   │   │   │   ├── angular-locale_en-ug.js
│   │   │   │   ├── angular-locale_en-um.js
│   │   │   │   ├── angular-locale_en-us-posix.js
│   │   │   │   ├── angular-locale_en-us.js
│   │   │   │   ├── angular-locale_en-vc.js
│   │   │   │   ├── angular-locale_en-vg.js
│   │   │   │   ├── angular-locale_en-vi.js
│   │   │   │   ├── angular-locale_en-vu.js
│   │   │   │   ├── angular-locale_en-ws.js
│   │   │   │   ├── angular-locale_en-xa.js
│   │   │   │   ├── angular-locale_en-za.js
│   │   │   │   ├── angular-locale_en-zm.js
│   │   │   │   ├── angular-locale_en-zw.js
│   │   │   │   ├── angular-locale_en.js
│   │   │   │   ├── angular-locale_eo-001.js
│   │   │   │   ├── angular-locale_eo.js
│   │   │   │   ├── angular-locale_es-419.js
│   │   │   │   ├── angular-locale_es-ar.js
│   │   │   │   ├── angular-locale_es-bo.js
│   │   │   │   ├── angular-locale_es-br.js
│   │   │   │   ├── angular-locale_es-bz.js
│   │   │   │   ├── angular-locale_es-cl.js
│   │   │   │   ├── angular-locale_es-co.js
│   │   │   │   ├── angular-locale_es-cr.js
│   │   │   │   ├── angular-locale_es-cu.js
│   │   │   │   ├── angular-locale_es-do.js
│   │   │   │   ├── angular-locale_es-ea.js
│   │   │   │   ├── angular-locale_es-ec.js
│   │   │   │   ├── angular-locale_es-es.js
│   │   │   │   ├── angular-locale_es-gq.js
│   │   │   │   ├── angular-locale_es-gt.js
│   │   │   │   ├── angular-locale_es-hn.js
│   │   │   │   ├── angular-locale_es-ic.js
│   │   │   │   ├── angular-locale_es-mx.js
│   │   │   │   ├── angular-locale_es-ni.js
│   │   │   │   ├── angular-locale_es-pa.js
│   │   │   │   ├── angular-locale_es-pe.js
│   │   │   │   ├── angular-locale_es-ph.js
│   │   │   │   ├── angular-locale_es-pr.js
│   │   │   │   ├── angular-locale_es-py.js
│   │   │   │   ├── angular-locale_es-sv.js
│   │   │   │   ├── angular-locale_es-us.js
│   │   │   │   ├── angular-locale_es-uy.js
│   │   │   │   ├── angular-locale_es-ve.js
│   │   │   │   ├── angular-locale_es.js
│   │   │   │   ├── angular-locale_et-ee.js
│   │   │   │   ├── angular-locale_et.js
│   │   │   │   ├── angular-locale_eu-es.js
│   │   │   │   ├── angular-locale_eu.js
│   │   │   │   ├── angular-locale_ewo-cm.js
│   │   │   │   ├── angular-locale_ewo.js
│   │   │   │   ├── angular-locale_fa-af.js
│   │   │   │   ├── angular-locale_fa-ir.js
│   │   │   │   ├── angular-locale_fa.js
│   │   │   │   ├── angular-locale_ff-cm.js
│   │   │   │   ├── angular-locale_ff-gn.js
│   │   │   │   ├── angular-locale_ff-mr.js
│   │   │   │   ├── angular-locale_ff-sn.js
│   │   │   │   ├── angular-locale_ff.js
│   │   │   │   ├── angular-locale_fi-fi.js
│   │   │   │   ├── angular-locale_fi.js
│   │   │   │   ├── angular-locale_fil-ph.js
│   │   │   │   ├── angular-locale_fil.js
│   │   │   │   ├── angular-locale_fo-dk.js
│   │   │   │   ├── angular-locale_fo-fo.js
│   │   │   │   ├── angular-locale_fo.js
│   │   │   │   ├── angular-locale_fr-be.js
│   │   │   │   ├── angular-locale_fr-bf.js
│   │   │   │   ├── angular-locale_fr-bi.js
│   │   │   │   ├── angular-locale_fr-bj.js
│   │   │   │   ├── angular-locale_fr-bl.js
│   │   │   │   ├── angular-locale_fr-ca.js
│   │   │   │   ├── angular-locale_fr-cd.js
│   │   │   │   ├── angular-locale_fr-cf.js
│   │   │   │   ├── angular-locale_fr-cg.js
│   │   │   │   ├── angular-locale_fr-ch.js
│   │   │   │   ├── angular-locale_fr-ci.js
│   │   │   │   ├── angular-locale_fr-cm.js
│   │   │   │   ├── angular-locale_fr-dj.js
│   │   │   │   ├── angular-locale_fr-dz.js
│   │   │   │   ├── angular-locale_fr-fr.js
│   │   │   │   ├── angular-locale_fr-ga.js
│   │   │   │   ├── angular-locale_fr-gf.js
│   │   │   │   ├── angular-locale_fr-gn.js
│   │   │   │   ├── angular-locale_fr-gp.js
│   │   │   │   ├── angular-locale_fr-gq.js
│   │   │   │   ├── angular-locale_fr-ht.js
│   │   │   │   ├── angular-locale_fr-km.js
│   │   │   │   ├── angular-locale_fr-lu.js
│   │   │   │   ├── angular-locale_fr-ma.js
│   │   │   │   ├── angular-locale_fr-mc.js
│   │   │   │   ├── angular-locale_fr-mf.js
│   │   │   │   ├── angular-locale_fr-mg.js
│   │   │   │   ├── angular-locale_fr-ml.js
│   │   │   │   ├── angular-locale_fr-mq.js
│   │   │   │   ├── angular-locale_fr-mr.js
│   │   │   │   ├── angular-locale_fr-mu.js
│   │   │   │   ├── angular-locale_fr-nc.js
│   │   │   │   ├── angular-locale_fr-ne.js
│   │   │   │   ├── angular-locale_fr-pf.js
│   │   │   │   ├── angular-locale_fr-pm.js
│   │   │   │   ├── angular-locale_fr-re.js
│   │   │   │   ├── angular-locale_fr-rw.js
│   │   │   │   ├── angular-locale_fr-sc.js
│   │   │   │   ├── angular-locale_fr-sn.js
│   │   │   │   ├── angular-locale_fr-sy.js
│   │   │   │   ├── angular-locale_fr-td.js
│   │   │   │   ├── angular-locale_fr-tg.js
│   │   │   │   ├── angular-locale_fr-tn.js
│   │   │   │   ├── angular-locale_fr-vu.js
│   │   │   │   ├── angular-locale_fr-wf.js
│   │   │   │   ├── angular-locale_fr-yt.js
│   │   │   │   ├── angular-locale_fr.js
│   │   │   │   ├── angular-locale_fur-it.js
│   │   │   │   ├── angular-locale_fur.js
│   │   │   │   ├── angular-locale_fy-nl.js
│   │   │   │   ├── angular-locale_fy.js
│   │   │   │   ├── angular-locale_ga-ie.js
│   │   │   │   ├── angular-locale_ga.js
│   │   │   │   ├── angular-locale_gd-gb.js
│   │   │   │   ├── angular-locale_gd.js
│   │   │   │   ├── angular-locale_gl-es.js
│   │   │   │   ├── angular-locale_gl.js
│   │   │   │   ├── angular-locale_gsw-ch.js
│   │   │   │   ├── angular-locale_gsw-fr.js
│   │   │   │   ├── angular-locale_gsw-li.js
│   │   │   │   ├── angular-locale_gsw.js
│   │   │   │   ├── angular-locale_gu-in.js
│   │   │   │   ├── angular-locale_gu.js
│   │   │   │   ├── angular-locale_guz-ke.js
│   │   │   │   ├── angular-locale_guz.js
│   │   │   │   ├── angular-locale_gv-im.js
│   │   │   │   ├── angular-locale_gv.js
│   │   │   │   ├── angular-locale_ha-gh.js
│   │   │   │   ├── angular-locale_ha-ne.js
│   │   │   │   ├── angular-locale_ha-ng.js
│   │   │   │   ├── angular-locale_ha.js
│   │   │   │   ├── angular-locale_haw-us.js
│   │   │   │   ├── angular-locale_haw.js
│   │   │   │   ├── angular-locale_he-il.js
│   │   │   │   ├── angular-locale_he.js
│   │   │   │   ├── angular-locale_hi-in.js
│   │   │   │   ├── angular-locale_hi.js
│   │   │   │   ├── angular-locale_hr-ba.js
│   │   │   │   ├── angular-locale_hr-hr.js
│   │   │   │   ├── angular-locale_hr.js
│   │   │   │   ├── angular-locale_hsb-de.js
│   │   │   │   ├── angular-locale_hsb.js
│   │   │   │   ├── angular-locale_hu-hu.js
│   │   │   │   ├── angular-locale_hu.js
│   │   │   │   ├── angular-locale_hy-am.js
│   │   │   │   ├── angular-locale_hy.js
│   │   │   │   ├── angular-locale_id-id.js
│   │   │   │   ├── angular-locale_id.js
│   │   │   │   ├── angular-locale_ig-ng.js
│   │   │   │   ├── angular-locale_ig.js
│   │   │   │   ├── angular-locale_ii-cn.js
│   │   │   │   ├── angular-locale_ii.js
│   │   │   │   ├── angular-locale_in.js
│   │   │   │   ├── angular-locale_is-is.js
│   │   │   │   ├── angular-locale_is.js
│   │   │   │   ├── angular-locale_it-ch.js
│   │   │   │   ├── angular-locale_it-it.js
│   │   │   │   ├── angular-locale_it-sm.js
│   │   │   │   ├── angular-locale_it-va.js
│   │   │   │   ├── angular-locale_it.js
│   │   │   │   ├── angular-locale_iw.js
│   │   │   │   ├── angular-locale_ja-jp.js
│   │   │   │   ├── angular-locale_ja.js
│   │   │   │   ├── angular-locale_jgo-cm.js
│   │   │   │   ├── angular-locale_jgo.js
│   │   │   │   ├── angular-locale_jmc-tz.js
│   │   │   │   ├── angular-locale_jmc.js
│   │   │   │   ├── angular-locale_ka-ge.js
│   │   │   │   ├── angular-locale_ka.js
│   │   │   │   ├── angular-locale_kab-dz.js
│   │   │   │   ├── angular-locale_kab.js
│   │   │   │   ├── angular-locale_kam-ke.js
│   │   │   │   ├── angular-locale_kam.js
│   │   │   │   ├── angular-locale_kde-tz.js
│   │   │   │   ├── angular-locale_kde.js
│   │   │   │   ├── angular-locale_kea-cv.js
│   │   │   │   ├── angular-locale_kea.js
│   │   │   │   ├── angular-locale_khq-ml.js
│   │   │   │   ├── angular-locale_khq.js
│   │   │   │   ├── angular-locale_ki-ke.js
│   │   │   │   ├── angular-locale_ki.js
│   │   │   │   ├── angular-locale_kk-kz.js
│   │   │   │   ├── angular-locale_kk.js
│   │   │   │   ├── angular-locale_kkj-cm.js
│   │   │   │   ├── angular-locale_kkj.js
│   │   │   │   ├── angular-locale_kl-gl.js
│   │   │   │   ├── angular-locale_kl.js
│   │   │   │   ├── angular-locale_kln-ke.js
│   │   │   │   ├── angular-locale_kln.js
│   │   │   │   ├── angular-locale_km-kh.js
│   │   │   │   ├── angular-locale_km.js
│   │   │   │   ├── angular-locale_kn-in.js
│   │   │   │   ├── angular-locale_kn.js
│   │   │   │   ├── angular-locale_ko-kp.js
│   │   │   │   ├── angular-locale_ko-kr.js
│   │   │   │   ├── angular-locale_ko.js
│   │   │   │   ├── angular-locale_kok-in.js
│   │   │   │   ├── angular-locale_kok.js
│   │   │   │   ├── angular-locale_ks-in.js
│   │   │   │   ├── angular-locale_ks.js
│   │   │   │   ├── angular-locale_ksb-tz.js
│   │   │   │   ├── angular-locale_ksb.js
│   │   │   │   ├── angular-locale_ksf-cm.js
│   │   │   │   ├── angular-locale_ksf.js
│   │   │   │   ├── angular-locale_ksh-de.js
│   │   │   │   ├── angular-locale_ksh.js
│   │   │   │   ├── angular-locale_kw-gb.js
│   │   │   │   ├── angular-locale_kw.js
│   │   │   │   ├── angular-locale_ky-kg.js
│   │   │   │   ├── angular-locale_ky.js
│   │   │   │   ├── angular-locale_lag-tz.js
│   │   │   │   ├── angular-locale_lag.js
│   │   │   │   ├── angular-locale_lb-lu.js
│   │   │   │   ├── angular-locale_lb.js
│   │   │   │   ├── angular-locale_lg-ug.js
│   │   │   │   ├── angular-locale_lg.js
│   │   │   │   ├── angular-locale_lkt-us.js
│   │   │   │   ├── angular-locale_lkt.js
│   │   │   │   ├── angular-locale_ln-ao.js
│   │   │   │   ├── angular-locale_ln-cd.js
│   │   │   │   ├── angular-locale_ln-cf.js
│   │   │   │   ├── angular-locale_ln-cg.js
│   │   │   │   ├── angular-locale_ln.js
│   │   │   │   ├── angular-locale_lo-la.js
│   │   │   │   ├── angular-locale_lo.js
│   │   │   │   ├── angular-locale_lrc-iq.js
│   │   │   │   ├── angular-locale_lrc-ir.js
│   │   │   │   ├── angular-locale_lrc.js
│   │   │   │   ├── angular-locale_lt-lt.js
│   │   │   │   ├── angular-locale_lt.js
│   │   │   │   ├── angular-locale_lu-cd.js
│   │   │   │   ├── angular-locale_lu.js
│   │   │   │   ├── angular-locale_luo-ke.js
│   │   │   │   ├── angular-locale_luo.js
│   │   │   │   ├── angular-locale_luy-ke.js
│   │   │   │   ├── angular-locale_luy.js
│   │   │   │   ├── angular-locale_lv-lv.js
│   │   │   │   ├── angular-locale_lv.js
│   │   │   │   ├── angular-locale_mas-ke.js
│   │   │   │   ├── angular-locale_mas-tz.js
│   │   │   │   ├── angular-locale_mas.js
│   │   │   │   ├── angular-locale_mer-ke.js
│   │   │   │   ├── angular-locale_mer.js
│   │   │   │   ├── angular-locale_mfe-mu.js
│   │   │   │   ├── angular-locale_mfe.js
│   │   │   │   ├── angular-locale_mg-mg.js
│   │   │   │   ├── angular-locale_mg.js
│   │   │   │   ├── angular-locale_mgh-mz.js
│   │   │   │   ├── angular-locale_mgh.js
│   │   │   │   ├── angular-locale_mgo-cm.js
│   │   │   │   ├── angular-locale_mgo.js
│   │   │   │   ├── angular-locale_mk-mk.js
│   │   │   │   ├── angular-locale_mk.js
│   │   │   │   ├── angular-locale_ml-in.js
│   │   │   │   ├── angular-locale_ml.js
│   │   │   │   ├── angular-locale_mn-mn.js
│   │   │   │   ├── angular-locale_mn.js
│   │   │   │   ├── angular-locale_mo.js
│   │   │   │   ├── angular-locale_mr-in.js
│   │   │   │   ├── angular-locale_mr.js
│   │   │   │   ├── angular-locale_ms-bn.js
│   │   │   │   ├── angular-locale_ms-my.js
│   │   │   │   ├── angular-locale_ms-sg.js
│   │   │   │   ├── angular-locale_ms.js
│   │   │   │   ├── angular-locale_mt-mt.js
│   │   │   │   ├── angular-locale_mt.js
│   │   │   │   ├── angular-locale_mua-cm.js
│   │   │   │   ├── angular-locale_mua.js
│   │   │   │   ├── angular-locale_my-mm.js
│   │   │   │   ├── angular-locale_my.js
│   │   │   │   ├── angular-locale_mzn-ir.js
│   │   │   │   ├── angular-locale_mzn.js
│   │   │   │   ├── angular-locale_naq-na.js
│   │   │   │   ├── angular-locale_naq.js
│   │   │   │   ├── angular-locale_nb-no.js
│   │   │   │   ├── angular-locale_nb-sj.js
│   │   │   │   ├── angular-locale_nb.js
│   │   │   │   ├── angular-locale_nd-zw.js
│   │   │   │   ├── angular-locale_nd.js
│   │   │   │   ├── angular-locale_nds-de.js
│   │   │   │   ├── angular-locale_nds-nl.js
│   │   │   │   ├── angular-locale_nds.js
│   │   │   │   ├── angular-locale_ne-in.js
│   │   │   │   ├── angular-locale_ne-np.js
│   │   │   │   ├── angular-locale_ne.js
│   │   │   │   ├── angular-locale_nl-aw.js
│   │   │   │   ├── angular-locale_nl-be.js
│   │   │   │   ├── angular-locale_nl-bq.js
│   │   │   │   ├── angular-locale_nl-cw.js
│   │   │   │   ├── angular-locale_nl-nl.js
│   │   │   │   ├── angular-locale_nl-sr.js
│   │   │   │   ├── angular-locale_nl-sx.js
│   │   │   │   ├── angular-locale_nl.js
│   │   │   │   ├── angular-locale_nmg-cm.js
│   │   │   │   ├── angular-locale_nmg.js
│   │   │   │   ├── angular-locale_nn-no.js
│   │   │   │   ├── angular-locale_nn.js
│   │   │   │   ├── angular-locale_nnh-cm.js
│   │   │   │   ├── angular-locale_nnh.js
│   │   │   │   ├── angular-locale_no-no.js
│   │   │   │   ├── angular-locale_no.js
│   │   │   │   ├── angular-locale_nus-ss.js
│   │   │   │   ├── angular-locale_nus.js
│   │   │   │   ├── angular-locale_nyn-ug.js
│   │   │   │   ├── angular-locale_nyn.js
│   │   │   │   ├── angular-locale_om-et.js
│   │   │   │   ├── angular-locale_om-ke.js
│   │   │   │   ├── angular-locale_om.js
│   │   │   │   ├── angular-locale_or-in.js
│   │   │   │   ├── angular-locale_or.js
│   │   │   │   ├── angular-locale_os-ge.js
│   │   │   │   ├── angular-locale_os-ru.js
│   │   │   │   ├── angular-locale_os.js
│   │   │   │   ├── angular-locale_pa-arab-pk.js
│   │   │   │   ├── angular-locale_pa-arab.js
│   │   │   │   ├── angular-locale_pa-guru-in.js
│   │   │   │   ├── angular-locale_pa-guru.js
│   │   │   │   ├── angular-locale_pa.js
│   │   │   │   ├── angular-locale_pl-pl.js
│   │   │   │   ├── angular-locale_pl.js
│   │   │   │   ├── angular-locale_prg-001.js
│   │   │   │   ├── angular-locale_prg.js
│   │   │   │   ├── angular-locale_ps-af.js
│   │   │   │   ├── angular-locale_ps.js
│   │   │   │   ├── angular-locale_pt-ao.js
│   │   │   │   ├── angular-locale_pt-br.js
│   │   │   │   ├── angular-locale_pt-ch.js
│   │   │   │   ├── angular-locale_pt-cv.js
│   │   │   │   ├── angular-locale_pt-gq.js
│   │   │   │   ├── angular-locale_pt-gw.js
│   │   │   │   ├── angular-locale_pt-lu.js
│   │   │   │   ├── angular-locale_pt-mo.js
│   │   │   │   ├── angular-locale_pt-mz.js
│   │   │   │   ├── angular-locale_pt-pt.js
│   │   │   │   ├── angular-locale_pt-st.js
│   │   │   │   ├── angular-locale_pt-tl.js
│   │   │   │   ├── angular-locale_pt.js
│   │   │   │   ├── angular-locale_qu-bo.js
│   │   │   │   ├── angular-locale_qu-ec.js
│   │   │   │   ├── angular-locale_qu-pe.js
│   │   │   │   ├── angular-locale_qu.js
│   │   │   │   ├── angular-locale_rm-ch.js
│   │   │   │   ├── angular-locale_rm.js
│   │   │   │   ├── angular-locale_rn-bi.js
│   │   │   │   ├── angular-locale_rn.js
│   │   │   │   ├── angular-locale_ro-md.js
│   │   │   │   ├── angular-locale_ro-ro.js
│   │   │   │   ├── angular-locale_ro.js
│   │   │   │   ├── angular-locale_rof-tz.js
│   │   │   │   ├── angular-locale_rof.js
│   │   │   │   ├── angular-locale_ru-by.js
│   │   │   │   ├── angular-locale_ru-kg.js
│   │   │   │   ├── angular-locale_ru-kz.js
│   │   │   │   ├── angular-locale_ru-md.js
│   │   │   │   ├── angular-locale_ru-ru.js
│   │   │   │   ├── angular-locale_ru-ua.js
│   │   │   │   ├── angular-locale_ru.js
│   │   │   │   ├── angular-locale_rw-rw.js
│   │   │   │   ├── angular-locale_rw.js
│   │   │   │   ├── angular-locale_rwk-tz.js
│   │   │   │   ├── angular-locale_rwk.js
│   │   │   │   ├── angular-locale_sah-ru.js
│   │   │   │   ├── angular-locale_sah.js
│   │   │   │   ├── angular-locale_saq-ke.js
│   │   │   │   ├── angular-locale_saq.js
│   │   │   │   ├── angular-locale_sbp-tz.js
│   │   │   │   ├── angular-locale_sbp.js
│   │   │   │   ├── angular-locale_se-fi.js
│   │   │   │   ├── angular-locale_se-no.js
│   │   │   │   ├── angular-locale_se-se.js
│   │   │   │   ├── angular-locale_se.js
│   │   │   │   ├── angular-locale_seh-mz.js
│   │   │   │   ├── angular-locale_seh.js
│   │   │   │   ├── angular-locale_ses-ml.js
│   │   │   │   ├── angular-locale_ses.js
│   │   │   │   ├── angular-locale_sg-cf.js
│   │   │   │   ├── angular-locale_sg.js
│   │   │   │   ├── angular-locale_sh.js
│   │   │   │   ├── angular-locale_shi-latn-ma.js
│   │   │   │   ├── angular-locale_shi-latn.js
│   │   │   │   ├── angular-locale_shi-tfng-ma.js
│   │   │   │   ├── angular-locale_shi-tfng.js
│   │   │   │   ├── angular-locale_shi.js
│   │   │   │   ├── angular-locale_si-lk.js
│   │   │   │   ├── angular-locale_si.js
│   │   │   │   ├── angular-locale_sk-sk.js
│   │   │   │   ├── angular-locale_sk.js
│   │   │   │   ├── angular-locale_sl-si.js
│   │   │   │   ├── angular-locale_sl.js
│   │   │   │   ├── angular-locale_smn-fi.js
│   │   │   │   ├── angular-locale_smn.js
│   │   │   │   ├── angular-locale_sn-zw.js
│   │   │   │   ├── angular-locale_sn.js
│   │   │   │   ├── angular-locale_so-dj.js
│   │   │   │   ├── angular-locale_so-et.js
│   │   │   │   ├── angular-locale_so-ke.js
│   │   │   │   ├── angular-locale_so-so.js
│   │   │   │   ├── angular-locale_so.js
│   │   │   │   ├── angular-locale_sq-al.js
│   │   │   │   ├── angular-locale_sq-mk.js
│   │   │   │   ├── angular-locale_sq-xk.js
│   │   │   │   ├── angular-locale_sq.js
│   │   │   │   ├── angular-locale_sr-cyrl-ba.js
│   │   │   │   ├── angular-locale_sr-cyrl-me.js
│   │   │   │   ├── angular-locale_sr-cyrl-rs.js
│   │   │   │   ├── angular-locale_sr-cyrl-xk.js
│   │   │   │   ├── angular-locale_sr-cyrl.js
│   │   │   │   ├── angular-locale_sr-latn-ba.js
│   │   │   │   ├── angular-locale_sr-latn-me.js
│   │   │   │   ├── angular-locale_sr-latn-rs.js
│   │   │   │   ├── angular-locale_sr-latn-xk.js
│   │   │   │   ├── angular-locale_sr-latn.js
│   │   │   │   ├── angular-locale_sr.js
│   │   │   │   ├── angular-locale_sv-ax.js
│   │   │   │   ├── angular-locale_sv-fi.js
│   │   │   │   ├── angular-locale_sv-se.js
│   │   │   │   ├── angular-locale_sv.js
│   │   │   │   ├── angular-locale_sw-cd.js
│   │   │   │   ├── angular-locale_sw-ke.js
│   │   │   │   ├── angular-locale_sw-tz.js
│   │   │   │   ├── angular-locale_sw-ug.js
│   │   │   │   ├── angular-locale_sw.js
│   │   │   │   ├── angular-locale_ta-in.js
│   │   │   │   ├── angular-locale_ta-lk.js
│   │   │   │   ├── angular-locale_ta-my.js
│   │   │   │   ├── angular-locale_ta-sg.js
│   │   │   │   ├── angular-locale_ta.js
│   │   │   │   ├── angular-locale_te-in.js
│   │   │   │   ├── angular-locale_te.js
│   │   │   │   ├── angular-locale_teo-ke.js
│   │   │   │   ├── angular-locale_teo-ug.js
│   │   │   │   ├── angular-locale_teo.js
│   │   │   │   ├── angular-locale_th-th.js
│   │   │   │   ├── angular-locale_th.js
│   │   │   │   ├── angular-locale_ti-er.js
│   │   │   │   ├── angular-locale_ti-et.js
│   │   │   │   ├── angular-locale_ti.js
│   │   │   │   ├── angular-locale_tk-tm.js
│   │   │   │   ├── angular-locale_tk.js
│   │   │   │   ├── angular-locale_tl.js
│   │   │   │   ├── angular-locale_to-to.js
│   │   │   │   ├── angular-locale_to.js
│   │   │   │   ├── angular-locale_tr-cy.js
│   │   │   │   ├── angular-locale_tr-tr.js
│   │   │   │   ├── angular-locale_tr.js
│   │   │   │   ├── angular-locale_twq-ne.js
│   │   │   │   ├── angular-locale_twq.js
│   │   │   │   ├── angular-locale_tzm-ma.js
│   │   │   │   ├── angular-locale_tzm.js
│   │   │   │   ├── angular-locale_ug-cn.js
│   │   │   │   ├── angular-locale_ug.js
│   │   │   │   ├── angular-locale_uk-ua.js
│   │   │   │   ├── angular-locale_uk.js
│   │   │   │   ├── angular-locale_ur-in.js
│   │   │   │   ├── angular-locale_ur-pk.js
│   │   │   │   ├── angular-locale_ur.js
│   │   │   │   ├── angular-locale_uz-arab-af.js
│   │   │   │   ├── angular-locale_uz-arab.js
│   │   │   │   ├── angular-locale_uz-cyrl-uz.js
│   │   │   │   ├── angular-locale_uz-cyrl.js
│   │   │   │   ├── angular-locale_uz-latn-uz.js
│   │   │   │   ├── angular-locale_uz-latn.js
│   │   │   │   ├── angular-locale_uz.js
│   │   │   │   ├── angular-locale_vai-latn-lr.js
│   │   │   │   ├── angular-locale_vai-latn.js
│   │   │   │   ├── angular-locale_vai-vaii-lr.js
│   │   │   │   ├── angular-locale_vai-vaii.js
│   │   │   │   ├── angular-locale_vai.js
│   │   │   │   ├── angular-locale_vi-vn.js
│   │   │   │   ├── angular-locale_vi.js
│   │   │   │   ├── angular-locale_vo-001.js
│   │   │   │   ├── angular-locale_vo.js
│   │   │   │   ├── angular-locale_vun-tz.js
│   │   │   │   ├── angular-locale_vun.js
│   │   │   │   ├── angular-locale_wae-ch.js
│   │   │   │   ├── angular-locale_wae.js
│   │   │   │   ├── angular-locale_xog-ug.js
│   │   │   │   ├── angular-locale_xog.js
│   │   │   │   ├── angular-locale_yav-cm.js
│   │   │   │   ├── angular-locale_yav.js
│   │   │   │   ├── angular-locale_yi-001.js
│   │   │   │   ├── angular-locale_yi.js
│   │   │   │   ├── angular-locale_yo-bj.js
│   │   │   │   ├── angular-locale_yo-ng.js
│   │   │   │   ├── angular-locale_yo.js
│   │   │   │   ├── angular-locale_yue-hk.js
│   │   │   │   ├── angular-locale_yue.js
│   │   │   │   ├── angular-locale_zgh-ma.js
│   │   │   │   ├── angular-locale_zgh.js
│   │   │   │   ├── angular-locale_zh-cn.js
│   │   │   │   ├── angular-locale_zh-hans-cn.js
│   │   │   │   ├── angular-locale_zh-hans-hk.js
│   │   │   │   ├── angular-locale_zh-hans-mo.js
│   │   │   │   ├── angular-locale_zh-hans-sg.js
│   │   │   │   ├── angular-locale_zh-hans.js
│   │   │   │   ├── angular-locale_zh-hant-hk.js
│   │   │   │   ├── angular-locale_zh-hant-mo.js
│   │   │   │   ├── angular-locale_zh-hant-tw.js
│   │   │   │   ├── angular-locale_zh-hant.js
│   │   │   │   ├── angular-locale_zh-hk.js
│   │   │   │   ├── angular-locale_zh-tw.js
│   │   │   │   ├── angular-locale_zh.js
│   │   │   │   ├── angular-locale_zu-za.js
│   │   │   │   └── angular-locale_zu.js
│   │   │   ├── sitemap.xml
│   │   │   ├── test-bundles/
│   │   │   │   ├── angular-aria.js
│   │   │   │   ├── angular-cookies.js
│   │   │   │   ├── angular-message-format.js
│   │   │   │   ├── angular-messages.js
│   │   │   │   ├── angular-resource.js
│   │   │   │   ├── angular-route.js
│   │   │   │   ├── angular-sanitize.js
│   │   │   │   └── angular-touch.js
│   │   │   ├── version.json
│   │   │   └── version.txt
│   │   ├── angular-media-player/
│   │   │   └── angular-media-player.js
│   │   ├── angularjs-toaster/
│   │   │   ├── toaster.css
│   │   │   └── toaster.js
│   │   ├── bootstrap/
│   │   │   ├── config.json
│   │   │   ├── css/
│   │   │   │   ├── bootstrap-theme.css
│   │   │   │   └── bootstrap.css
│   │   │   └── js/
│   │   │       └── bootstrap.js
│   │   ├── clipboard/
│   │   │   └── clipboard.js
│   │   ├── closure/
│   │   │   └── long.js
│   │   ├── console-polyfill/
│   │   │   └── console-polyfill.js
│   │   ├── cryptoJS/
│   │   │   ├── THIRDPARTY_LICENSE
│   │   │   └── crypto.js
│   │   ├── jquery/
│   │   │   └── jquery.js
│   │   ├── jquery.emojiarea/
│   │   │   ├── jquery.emojiarea-orig.js
│   │   │   └── jquery.emojiarea.js
│   │   ├── jquery.nanoscroller/
│   │   │   ├── nanoscroller.css
│   │   │   └── nanoscroller.js
│   │   ├── jsbn/
│   │   │   ├── THIRDPARTY_LICENSE
│   │   │   └── jsbn_combined.js
│   │   ├── leemon_bigint/
│   │   │   └── bigint.js
│   │   ├── libwebpjs/
│   │   │   ├── libwebp-0.1.13.js
│   │   │   └── libwebp-0.2.0.js
│   │   ├── ogv.js/
│   │   │   ├── COPYING
│   │   │   ├── COPYING-ogg.txt
│   │   │   ├── COPYING-opus.txt
│   │   │   ├── COPYING-theora.txt
│   │   │   ├── COPYING-vorbis.txt
│   │   │   ├── LICENSE-nestegg.txt
│   │   │   ├── LICENSE-vpx.txt
│   │   │   ├── PATENTS-vpx.txt
│   │   │   ├── README.md
│   │   │   ├── dynamicaudio.swf
│   │   │   ├── ogv-decoder-audio-opus-wasm.js
│   │   │   ├── ogv-decoder-audio-opus-wasm.wasm
│   │   │   ├── ogv-decoder-audio-opus.js
│   │   │   ├── ogv-decoder-audio-vorbis-wasm.js
│   │   │   ├── ogv-decoder-audio-vorbis-wasm.wasm
│   │   │   ├── ogv-decoder-audio-vorbis.js
│   │   │   ├── ogv-decoder-video-theora-wasm.js
│   │   │   ├── ogv-decoder-video-theora-wasm.wasm
│   │   │   ├── ogv-decoder-video-theora.js
│   │   │   ├── ogv-decoder-video-vp8-mt.js
│   │   │   ├── ogv-decoder-video-vp8-wasm.js
│   │   │   ├── ogv-decoder-video-vp8-wasm.wasm
│   │   │   ├── ogv-decoder-video-vp8.js
│   │   │   ├── ogv-decoder-video-vp9-mt.js
│   │   │   ├── ogv-decoder-video-vp9-wasm.js
│   │   │   ├── ogv-decoder-video-vp9-wasm.wasm
│   │   │   ├── ogv-decoder-video-vp9.js
│   │   │   ├── ogv-demuxer-ogg-wasm.js
│   │   │   ├── ogv-demuxer-ogg-wasm.wasm
│   │   │   ├── ogv-demuxer-ogg.js
│   │   │   ├── ogv-demuxer-webm-wasm.js
│   │   │   ├── ogv-demuxer-webm-wasm.wasm
│   │   │   ├── ogv-demuxer-webm.js
│   │   │   ├── ogv-support.js
│   │   │   ├── ogv-version.js
│   │   │   ├── ogv-worker-audio.js
│   │   │   ├── ogv-worker-video.js
│   │   │   ├── ogv.js
│   │   │   └── pthread-main.js
│   │   ├── recorderjs/
│   │   │   ├── encoder_worker.js
│   │   │   └── recorder.js
│   │   ├── rusha/
│   │   │   └── rusha.js
│   │   ├── ui-bootstrap/
│   │   │   ├── THIRDPARTY_LICENSE
│   │   │   └── ui-bootstrap-custom-tpls-0.12.0.js
│   │   └── zlib/
│   │       └── THIRDPARTY_LICENSE
│   └── webogram.appcache
├── gulpfile.js
├── karma.conf.js
├── package.json
├── scripts/
│   ├── cldr_localize.js
│   ├── emoji_data/
│   │   ├── build.php
│   │   └── emoji.json
│   ├── google_fonts_download.sh
│   └── ua_handler.js
├── test/
│   ├── test-init.js
│   └── unit/
│       ├── controllers/
│       │   ├── AppFooterControllerSpec.js
│       │   ├── AppImPanelControllerSpec.js
│       │   ├── AppLangSelectControllerSpec.js
│       │   ├── AppWelcomeControllerSpec.js
│       │   ├── ChangelogModalControlelerSpec.js
│       │   ├── CountrySelectModalControllerSpec.js
│       │   ├── DocumentModalControllerSpec.js
│       │   ├── EmbedModalController.js
│       │   ├── ImportContactModalControllerSpec.js
│       │   ├── PasswordRecoveryModalControllerSpec.js
│       │   ├── PeerSelectControllerSpec.js
│       │   ├── ProfileEditModalControllerSpec.js
│       │   ├── UsernameEditModalControllerSpec.js
│       │   └── VideoModalControllerSpec.js
│       ├── directives/
│       │   ├── myHeadDirective.js
│       │   └── myLangFooterDirective.js
│       ├── filters/
│       │   ├── chatTitleFilterSpec.js
│       │   ├── dateOrTimeFilterSpec.js
│       │   ├── durationFilterSpec.js
│       │   ├── durationRemainsFilterSpec.js
│       │   ├── formatShortNumberFilterSpec.js
│       │   ├── formatSizeFilterSpec.js
│       │   ├── formatSizeProgressFilterSpec.js
│       │   ├── myDateFilterSpec.js
│       │   ├── nl2brFilterSpec.js
│       │   ├── phoneNumberFilterSpec.js
│       │   ├── realtiveTimeFilterSpec.js
│       │   ├── richTextFilterSpec.js
│       │   ├── shortUrlFilterSpec.js
│       │   ├── timeFilterSpec.js
│       │   ├── userFirstNameFilterSpec.js
│       │   ├── userNameFilterSpec.js
│       │   └── userStatusFilterSpec.js
│       └── services/
│           └── PhonebookContactsServiceSpec.js
├── update-angular.sh
└── webogram.sublime-project

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
.git


================================================
FILE: .gitignore
================================================
.DS_Store
.idea
.publish
*.sublime-workspace
*.*~
*.swp

# Node.js package manager
node_modules
npm-debug.log
dist
dist_package
releases
webogram*.zip
app/js/templates.js
app/css
cldr
coverage/


================================================
FILE: .tx/config
================================================
[main]
host = https://www.transifex.com

[telegram-web.en-usjson]
file_filter = app/js/locales/<lang>.json
lang_map = de:de-de, es:es-es, it:it-it, ru:ru-ru, nl:nl-nl, pt_BR:pt-br
source_file = app/js/locales/en-us.json
source_lang = en_US
type = KEYVALUEJSON



================================================
FILE: CHANGELOG.md
================================================
### 0.7
* Improved chats search
* Pinned messages in supergroups and channels
* Saved messages
* Improved chat history filters: added audio, links and mentions. Click on message date opens found message in context.
* Added ability to clean history in private supergroups
* Supported unread status for video messages
* Admin badges in supergroups
* Improved PUSH handling in Chrome
* [Safari] Voice record is now available
* [Safari] Improved downloads (files now have names and download automatically)


### 0.6.1
* Fixed networking problems
* Supported [MTProto v2](https://core.telegram.org/mtproto)

### 0.6.0
* Voice messages record button
* Added support for voice messages playback in Safari

### 0.5.7
* Video messages and Telescope
* Notifications about new logins
* Changelog is now received as a message

### 0.5.6
* Edit the text of your messages after sending them. This works across all Telegram chats, including groups and one-on-one conversations. Select a message and click 'Edit' or just press the up arrow button to edit your last message.
* Unsend Messages: retract any messages within 48 hours of sending them. Check out the [Telegram Blog](https://telegram.org/blog/unsend-and-usage) for more info.
* Pinned chats. Check out the [Telegram Blog](https://telegram.org/blog/pin-and-ifttt) for more info.
* Sticker suggestions by emoji.
* Search for messages in specific chats.
* Background notifications in Chrome and Firefox (can be disabled in Settings)

### 0.5.5
* Introducing Drafts: Seamless syncing for unsent messages on all your devices. Drafts are now visible in your chats list.
* Mention people in groups by typing @ and selecting them from the list — even if they don't have a username.
* Share links to specific posts in channels via quick forwarding menu (click on the date in a message to try this out).

### 0.5.4
* Introducing Bot API 2.0, the biggest update to our bot platform since June 2015.
* New inline keyboards with callback, 'open URL' or 'switch to inline mode' buttons help create seamless interfaces.
* Bots can now update existing messages on the fly as you interact with them.
* Prepare for the rise of location-based bots: all bots can now ask users to share their location.
* Inline bots can now send all attachments supported in Telegram (videos, music, stickers, files, etc.).
* Try out these sample bots to see what's coming your way soon: @music, @sticker, @youtube, @foursquare
* Check out the [Telegram Blog](https://telegram.org/blog/bots-2-0) for more info.
* New quick forwarding in channels (click on the date in a message to try this out).
* Improved performance.

### 0.5.3
* Inline bots: A new way to add bot content to any chat. Type a bot's username and your query in the text field to get instant results and send them to your chat partner. Try typing `@gif dog` in your next chat. Sample bots: @gif, @wiki, @bing, @vid, @bold.
* Check out the [Telegram Blog](https://telegram.org/blog/inline-bots) for more info.
* Improved GIFs: 20x faster sending and downloading, nice animated progress
* Click on message date to reply (or to forward from channels).
* Preview images before sending when pasting from clipboard.
* Improved formatting for copy-pasted history fragments (date, time and sender names inserted automatically).

### 0.5.2
* Unread counters for muted chats now colored in gray.
* Improved previews for sticker sets: Click on a sticker to view the whole set, click on stickers in a set to send right away, added a 'Share' button.
* Improved performance.

### 0.5.1
* Groups that have reached their capacity of 200 users can be upgraded to supergroups of up to 1,000 members.
* Check out the [Telegram Blog](https://telegram.org/blog/supergroups) for more info

### 0.5.0
* Removed annoying "multiple tabs open" error.
* Improved message forwarding.
* Added view counter to messages from channels.
* Improved image loading in Safari and Firefox.

### 0.4.9
* New emoji and sticker menu, tabs for sticker packs.

### 0.4.8
* Introducing Channels – a great new way to broadcast your messages to unlimited audiences.
* Check out the [Telegram Blog](https://telegram.org/blog/channels) for more info
* Improved performance in Safari on OS X El Capitan.
* Added formatting for fixed-width code, surround text with `single backticks` for inline text and ```triple backticks``` for blocks of pre-formatted text.

### 0.4.7
* New bot API, free for everyone. If you're an engineer, create your own bots for games, services or integrations.
            
* Check out [Telegram Blog](https://telegram.org/blog/bot-revolution) for more info
* Improved Stickers support: now stickers are loading much faster.
* Click on any custom stickers in chats to view and add sticker sets.
* [Mobile] Reply to a message easily: tap on any message and select "Reply".

### 0.4.6
* Install and share custom sticker sets like this one: telegram.me/addstickers/Animals
* If you're an artist, create custom sticker sets using our @Stickers bot.
* Check out [Telegram Blog](https://telegram.org/blog/stickers-revolution) for more info

### 0.4.5
* Invite links for group chats:
  Check out [Telegram Blog](https://telegram.org/blog/invite-links) for more info            
* Smart notifications
* 'Listened' status for voice messages
* Places in locations (venues, landmarks)

### 0.4.4
* Link Previews:
Get rich link summaries for tweets, YouTube videos, Instagram photos and other content.
* Check out [Telegram Blog](https://telegram.org/blog/link-preview) for more info.

### 0.4.3
* Sessions List:
View your active Telegram sessions (on desktop, tablet and mobile devices) and close specific sessions remotely.

* Two-step verification:
  Set up an additional password that will be required to log into your Telegram account.
* Check out [Telegram Blog](https://telegram.org/blog/sessions-and-2-step-verification) for more info.

### 0.4.2
* Optimization for screens with smaller Y-resolutions.
* Supported Spotify URL embeds.
* Mentions of the current user in group chats are now highlighted.

### 0.4.1
* Reply to specific messages in groups.
* Mention @usernames in groups to notify multiple users.
* Revised notifications in groups: mentioned users and people you reply to will be notified (private chat notification settings apply in this case instead of group settings). Check out <a href="https://telegram.org/blog/replies-mentions-hashtags" target="_blank">Telegram Blog</a> for more info.
* Setting to disable message preview

### 0.4.0
* Full stickers support
* Multisearch box: instantly find chats, usernames and messages
* Emoji autocomplete: e.g., type **:kiss<** in the message field to see the list. [Full cheat sheet](http://www.emoji-cheat-sheet.com/)
* Added 'typing' notification in chats list
* Online members counter in group headers

### 0.3.9
* [Desktop] Material design completed

### 0.3.8
* Telegram.me links open right in Telegram Web when authorized
* @username mentions in messages are clickable and open a conversation with the user

### 0.3.7
* [Desktop] New material design for modal windows
* [Desktop] Forward messages to multiple recipients

### 0.3.6
* New viewer for photos, videos, documents.
* [FirefoxOS] Improved media downloads.

### 0.3.5
* Added embedded Soundcloud tracks and playlists.
* Added global user search to contacts list.
* Added switch to mobile version on window resize.
* Migrate to HTTPS notification
* Bugfixes.

### 0.3.4
* Added embedded Facebook posts and Vimeo videos.
* Improved IE10+ support: downloading files and style fixes.
* Added unsupported media playback warning.
* Bugfixes.

### 0.3.3
* Added Native Client module: dramatically improved encryption speed; Download and upload speed is now as high as in native applications.
* HTTPS. We recommend you to use https://web.telegram.org.
* Added multiple open tabs warning. Please note, that only one tab with Telegram Web will work.
* Added embedded Instagram, Twitter, Vine, YouTube links.
* Jump to selected spot when playing back audio.
* Bugfixes

### 0.3.2
* Usernames support.
* Search can now find public users by username.
* Most popular emoticons shown in 'recent' when empty
* [ChromeApp] Added saving window position and size
* Bugfixes

### 0.3.1
* New languages: Spanish, German and Italian are now available 
* New custom-made audio player
* Bad browser page for IE 6-9
* Perfomance improvements and bugfixes

### 0.3.0
* Log in codes may be received in other Telegram apps
* Partner's online status updates automatically
* Added support for non-english hashtags in messages
* Fixed invalid scrollbar width bug
* [Desktop] Added automatic country code detection
* [FirefoxOS] Improved PUSH-notifications for <= 1.1
* [FirefoxOS] Fixed emoji in notifications
* [FirefoxOS] Fixed attachment bug for <= 1.1
* [FirefoxOS] Added phonebook permissions handling
* [FirefoxOS] Added ability to share Gallery photos in Telegram


================================================
FILE: CONTRIBUTING.md
================================================
## Contribute

You can help this project by reporting problems, suggestions, localizing it or contributing to the code.

### Report a problem or suggestion

Go to our [issue tracker](https://github.com/zhukov/webogram/issues) and check if your problem/suggestion is already reported. If not, create a new issue with a descriptive title and detail your suggestion or steps to reproduce the problem.

### Localization

If you don't see your native language available for Webogram and you can help with translation, please consult the [Telegram Translations Manual](https://core.telegram.org/translating_telegram).

To test your translation live, use [Localization guide](/app/js/locales/README.md).

### Contribute to the code

If you know how to code, we welcome you to send fixes and new features, but in order to be efficient we ask you to follow the following procedure:

* Fork this repo using the button at the top.
* Clone your forked repo locally.

``$ git clone git@github.com:yourname/webogram.git``

* Don't modify or work on the master branch, we'll use it to always be in sync with webogram upstream.

```
$ git remote add upstream git@github.com:zhukov/webogram.git
$ git fetch upstream
```

* Always create a new issue when you plan to work on a bug or new feature and wait for other devs input before start coding.
* Once the new feature is approved or the problem confirmed, go to your local copy and create a new branch to work on it. Use a descriptive name for it, include the issue number for reference.

``$ git checkout -b improve-contacts-99``

* Do your coding and push it to your fork. Include as few commits as possible (one should be enough) and a good description. Always include a reference to the issue with "Fix #number".

```
$ git add .
$ git commit -m "Improved contact list. Fix #99"
$ git push origin improve-contacts-99
```

* Do a new pull request from your "improve-contacts-99" branch to webogram "master".

#### How to implement changes suggested on a pull request

Sometimes when you submit a PR, you will be asked to correct some code. You can make the changes on your work branch and commit normally and the PR will be automatically updated.

``$ git commit -am "Ops, fixing typo"``

Once everything is OK, you will be asked to merge all commit messages into one to keep history clean.

``$ git rebase -i master``

Edit the file and mark as fixup (f) all commits you want to merge with the first one:

```
pick 1c85e07 Improved contact list. Fix #99
f c595f79 Ops, fixing typo
```

Once rebased you can force a push to your fork branch and the PR will be automatically updated.

``$ git push origin improve-contacts-99 --force``

#### How to keep your local branches updated

To keep your local master branch updated with upstream master, regularly do:

```
$ git fetch upstream
$ git checkout master
$ git pull --rebase upstream master
```

To update the branch you are coding in:

```
$ git checkout improve-contacts-99
$ git rebase master
```


================================================
FILE: Dockerfile
================================================
FROM node

ADD . /opt/webogram
WORKDIR /opt/webogram

RUN npm install -g gulp && npm install

EXPOSE 8000

CMD ["gulp", "watch"]


================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    {one line to give the program's name and a brief idea of what it does.}
    Copyright (C) {year}  {name of author}

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    {project}  Copyright (C) {year}  {fullname}
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.


================================================
FILE: Makefile
================================================
package:
	rm -rf dist_package
	./node_modules/gulp/bin/gulp.js clean
	./node_modules/gulp/bin/gulp.js package
	cp -r dist dist_package
	find dist_package | grep "\.git\|DS_Store\|.swp" | xargs rm -rf
	cd dist_package && zip -r ../releases/webogram_v$(version).zip .

ghdist:
	rm -rf dist
	mkdir dist
	cp -r .git dist/
	cd dist && git checkout gh-pages

publish:
		./node_modules/gulp/bin/gulp.js clean
		cd dist && git pull origin gh-pages
		./node_modules/gulp/bin/gulp.js publish
		echo -n "Please open http://localhost:8000/dist/index.html and check if everything works fine." && read -e
		cd dist && git add --all . && git commit -am "merged with master" && git push origin gh-pages

bump:
	./node_modules/gulp/bin/gulp.js bump

txinstall:
	curl -O https://raw.githubusercontent.com/pypa/pip/master/contrib/get-pip.py
	sudo python get-pip.py
	sudo pip install transifex-client

txupdate:
	tx pull -f

txupload:
	tx pull -f
	tx push -s


================================================
FILE: README.md
================================================
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)

## Project is DEPRECATED

The project was superseeded by 2 new official Telegram Web Apps:

* https://github.com/morethanwords/tweb - Telegram Web K, based on source code of Webogram, rewritten in TypeScript.
* https://github.com/Ajaxy/telegram-tt - Telegram Web Z, based on its own Teact framework (which re-implements React paradigm), uses a custom version of GramJS as an MTProto implementation. Written also in Typescript.


## [Webogram](https://web.telegram.org) — Telegram Web App

Telegram offers great [apps for mobile communication](https://www.telegram.org). It is based on the [MTProto protocol](https://core.telegram.org/mtproto) and has an [Open API](https://core.telegram.org/api). I personally like Telegram for its speed and cloud-support (that makes a web app possible, unlike in the case of WA and others).

MTProto data can be carried over HTTP (SSL is also supported), so this project is my take at creating one.

That said, I'm using this app myself and I'd like to share its sources, so anyone can contribute to the development. Any help is welcome!


### Interface


Here are some screenshots of the interface:


![Sample screenshot 1](/app/img/screenshot1.png)
![Mobile screenshot 2](/app/img/screenshot2.png)
![Mobile screenshot 3](/app/img/screenshot3.png)


### Unsupported at the moment

* Secret chats
* Black list
* ...


### Maintained locations


| Description        | URL           | Type  |
| ------------- |-------------| -----:|
| Online Web-version (hosted on Telegram servers)      | https://web.telegram.org/ | hosted
| Online Web-version (hosted on GitHub pages)      | https://zhukov.github.io/webogram | hosted
| Chrome Web Store      | [https://chrome.google.com/webstore/detail/telegram/ clhhggbfdinjmjhajaheehoeibfljjno](https://chrome.google.com/webstore/detail/telegram/clhhggbfdinjmjhajaheehoeibfljjno) |   packed
| Firefox & FirefoxOS Marketplace | https://marketplace.firefox.com/app/telegram |    packed



**Hosted version**: the app is downloaded via HTTPS as a usual website. Will be available offline due to application cache.

**Packed version**: the app is downloaded at once in a package via HTTPS. The package is updated less frequently than the Web-version.

All of the apps above are submitted and maintained by [@zhukov](https://github.com/zhukov), so feel free to use them and report bugs [here](https://github.com/zhukov/webogram/issues). Please do not report bugs which are only reproducible in different locations.


## Technical details

The app is based on the AngularJS JavaScript framework, and written in pure JavaScript. jQuery is used for DOM manipulations, and Bootstrap as the CSS-framework.


### Running locally


The project repository is based on angularjs-seed and includes gulp tasks, so it's easy to launch the app locally on your desktop.
Install [node.js](http://nodejs.org/).

Install dependencies with:

```lang=bash
npm install
```

Optionally, run the following commands in the project directory to install gulp globally:

```lang=bash
sudo npm install -g gulp
```

This will install all the needed dependencies.


#### Running web-server


Just run `npm start` (`gulp watch`) to start the web server and the livereload task.
Open http://localhost:8000/app/index.html in your browser.



#### Running as Chrome Packaged App

To run this application in Google Chrome as a packaged app, open this URL (in Chrome): `chrome://extensions/`, then tick "Developer mode" and press "Load unpacked extension...". Select the downloaded `app` folder and Webogram should appear in the list.

Run `npm start` (`gulp watch`) to watch for file changes and automatically rebuild the app.


#### Running as Firefox OS App

To run this application in Firefox as a packaged app, open "Menu" -> "Developer" -> "WebIDE" (or hit `Shift + F8`). Choose "Open packaged app" from the Project menu and select the `app` folder.

Run `npm start` (`gulp watch`) to watch for file changes and automatically rebuild the app.

#### Running in production

Run `npm run clean` (`gulp clean`), then `npm run build` (`gulp publish`) to build the minimized production version of the app. Copy `dist` folder contents to your web server. Don't forget to set `X-Frame-Options SAMEORIGIN` header ([docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options)).


### Third party libraries

Besides the frameworks mentioned above, other libraries are used for protocol and UI needs. Here is the short list:

* [JSBN](http://www-cs-students.stanford.edu/~tjw/jsbn/)
* [CryptoJS](https://code.google.com/p/crypto-js/)
* [zlib.js](https://github.com/imaya/zlib.js)
* [UI Bootstrap](http://angular-ui.github.io/bootstrap/)
* [jQuery Emojiarea](https://github.com/diy/jquery-emojiarea)
* [nanoScrollerJS](https://github.com/jamesflorentino/nanoScrollerJS)
* [gemoji](https://github.com/github/gemoji)
* [emoji-data](https://github.com/iamcal/emoji-data)

Many thanks to all these libraries' authors and contributors. A detailed list with descriptions and licenses is available [here](/app/vendor).


### Licensing

The source code is licensed under GPL v3. License is available [here](/LICENSE).


### [Contribute](CONTRIBUTING.md)


================================================
FILE: app/badbrowser.html
================================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" style="display:block; overflow: auto; background: #f8f8f8;">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>Telegram Web</title>

  <!-- build:css css/badbrowser.css -->
  <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.css"/>
  <link rel="stylesheet" href="css/app.css"/>
  <!-- endbuild -->

  <link rel="icon" href="favicon.ico" type="image/x-icon" />

</head>
<body class="non_osx is_1x">

  <div class="welcome_form" style="padding-bottom: 50px; clear: both;">

    <div class="bad_browser_wrap">

      <h2>Your browser is outdated!</h2>

      <div class="bad_browser_text">
        <p>
          Don't take this personally, but your browser is too old to run <strong>Telegram Web</strong>.<br/>
          We require HTML5 support for the MTProto secure messaging protocol to work.
        </p>
        <p>
          Unfortunately, your current browser doesn't support HTML5.<br/>
          Please download a modern browser or update to latest version and come back soon!
        </p>
      </div>


      <a class="btn btn-primary btn-lg pull-right" href="//firefox.com" target="_blank">Download Mozilla Firefox</a>
      <a class="btn btn-primary btn-lg" href="//google.com/chrome" target="_blank">Download Google Chrome</a>

    </div>

  </div>

</body>
</html>

================================================
FILE: app/index.html
================================================
<!doctype html>
<html lang="en" manifest="webogram.appcache" ng-csp="" xmlns:ng="http://angularjs.org" id="ng-app" style="display: none;">
<head>
  <!--[if lte IE 9]>
  <meta HTTP-EQUIV="REFRESH" content="0; url=badbrowser.html">
  <![endif]-->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>Telegram Web</title>

  <!-- build:css css/app.css -->
  <link rel="stylesheet" href="vendor/angular/angular-csp.css"/>
  <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.css"/>
  <link rel="stylesheet" href="vendor/angularjs-toaster/toaster.css"/>
  <link rel="stylesheet" href="css/app.css"/>
  <!-- endbuild -->

  <link rel="manifest" href="manifest.webapp.json"/>

  <!-- <link rel="stylesheet" href="css/font.css"/> -->
  <!-- <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&amp;subset=cyrillic,cyrillic-ext,latin,latin-ext" rel="stylesheet" type="text/css"> -->

  <link rel="icon" href="favicon.ico" type="image/x-icon" />

  <link rel="apple-touch-icon" href="img/iphone_home120.png">
  <link rel="apple-touch-icon" sizes="120x120" href="img/iphone_home120.png">
  <link rel="apple-touch-startup-image" media="(device-width: 320px)" href="img/iphone_startup.png">

  <meta name="apple-mobile-web-app-title" content="Telegram Web">
  <meta name="mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta name="theme-color" content="#497495">
  <meta name="google" content="notranslate">

  <meta property="og:title" content="Telegram Web">
  <meta property="og:url" content="https://web.telegram.org/">
  <meta property="og:image:width" content="236">
  <meta property="og:image:height" content="236">
  <meta property="og:image" content="https://web.telegram.org/img/logo_share.png">
  <meta property="og:site_name" content="Telegram Web">
  <meta property="description" content="Welcome to the Web application of Telegram messenger. See https://github.com/zhukov/webogram for more info.">
  <meta property="og:description" content="Welcome to the Web application of Telegram messenger. See https://github.com/zhukov/webogram for more info.">
</head>
<body>

  <div class="page_wrap" ng-view></div>

  <div id="notify_sound"></div>

  <!-- build:js js/app.js -->
  <script type="text/javascript" src="js/lib/polyfill.js"></script>
  <script type="text/javascript" src="vendor/jquery/jquery.min.js"></script>
  <script type="text/javascript" src="js/lib/config.js"></script>
  <script type="text/javascript" src="js/init.js"></script>
  <script type="text/javascript" src="js/offline_manager.js"></script>

  <script type="text/javascript" src="vendor/jquery.nanoscroller/nanoscroller.js"></script>
  <script type="text/javascript" src="vendor/angular/angular.js"></script>
  <script type="text/javascript" src="vendor/angular/angular-route.js"></script>
  <script type="text/javascript" src="vendor/angular/angular-animate.js"></script>
  <script type="text/javascript" src="vendor/angular/angular-sanitize.js"></script>
  <script type="text/javascript" src="vendor/angular/angular-touch.js"></script>
  <script type="text/javascript" src="vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.js"></script>
  <script type="text/javascript" src="vendor/angular-media-player/angular-media-player.js"></script>

  <script type="text/javascript" src="vendor/jsbn/jsbn_combined.js"></script>
  <script type="text/javascript" src="vendor/cryptoJS/crypto.js"></script>
  <script type="text/javascript" src="vendor/rusha/rusha.js"></script>
  <script type="text/javascript" src="vendor/zlib/gunzip.min.js"></script>
  <script type="text/javascript" src="vendor/closure/long.js"></script>
  <script type="text/javascript" src="vendor/leemon_bigint/bigint.js"></script>
  <script type="text/javascript" src="vendor/libwebpjs/libwebp-0.2.0.js"></script>
  <script type="text/javascript" src="vendor/angularjs-toaster/toaster.js"></script>
  <script type="text/javascript" src="vendor/clipboard/clipboard.js"></script>

  <script type="text/javascript" src="vendor/ogv.js/ogv.js"></script>
  <script type="text/javascript" src="vendor/ogv.js/ogv-demuxer-ogg.js"></script>
  <script type="text/javascript" src="vendor/ogv.js/ogv-decoder-audio-opus.js"></script>
  <script type="text/javascript" src="vendor/ogv.js/ogv-decoder-audio-vorbis.js"></script>
  <script type="text/javascript" src="vendor/ogv.js/ogv-support.js"></script>

  <script type="text/javascript" src="vendor/recorderjs/recorder.min.js"></script>

  <script type="text/javascript" src="js/lib/utils.js"></script>
  <script type="text/javascript" src="js/lib/bin_utils.js"></script>
  <script type="text/javascript" src="js/lib/tl_utils.js"></script>
  <script type="text/javascript" src="js/lib/ng_utils.js"></script>
  <script type="text/javascript" src="js/lib/i18n.js"></script>
  <script type="text/javascript" src="js/lib/mtproto.js"></script>
  <script type="text/javascript" src="js/lib/mtproto_wrapper.js"></script>

  <script type="text/javascript" src="js/app.js"></script>
  <script type="text/javascript" src="js/services.js"></script>
  <script type="text/javascript" src="js/controllers.js"></script>
  <script type="text/javascript" src="js/filters.js"></script>
  <script type="text/javascript" src="js/messages_manager.js"></script>

  <!--PRODUCTION_ONLY_BEGIN
    <script type="text/javascript" src="js/templates.js"></script>
  PRODUCTION_ONLY_END-->

  <script type="text/javascript" src="js/message_composer.js"></script>
  <script type="text/javascript" src="js/directives.js"></script>
  <script type="text/javascript" src="js/directives_mobile.js"></script>
  <!-- endbuild -->

</body>
</html>


================================================
FILE: app/js/app.js
================================================
/*!
 * Webogram v0.7.0 - messaging web application for MTProto
 * https://github.com/zhukov/webogram
 * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
 * https://github.com/zhukov/webogram/blob/master/LICENSE
 */

'use strict'
/* global Config, templateUrl */

var extraModules = []
if (Config.Modes.animations) {
  extraModules.push('ngAnimate')
}

// Declare app level module which depends on filters, and services
angular.module('myApp', [
  'ngRoute',
  'ngSanitize',
  'ngTouch',
  'ui.bootstrap',
  'mediaPlayer',
  'toaster',
  'izhukov.utils',
  'izhukov.mtproto',
  'izhukov.mtproto.wrapper',
  'myApp.filters',
  'myApp.services',
  /*PRODUCTION_ONLY_BEGIN
  'myApp.templates',
  PRODUCTION_ONLY_END*/
  'myApp.directives',
  'myApp.controllers'
].concat(extraModules)).config(['$locationProvider', '$routeProvider', '$compileProvider', 'StorageProvider', function ($locationProvider, $routeProvider, $compileProvider, StorageProvider) {
  $locationProvider.hashPrefix('');
  $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|blob|filesystem|chrome-extension|app):|data:image\//)
  $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|file|tg|mailto|blob|filesystem|chrome-extension|app):|data:/)

  /*PRODUCTION_ONLY_BEGIN
  $compileProvider.debugInfoEnabled(false)
  PRODUCTION_ONLY_END*/

  if (Config.Modes.test) {
    StorageProvider.setPrefix('t_')
  }

  $routeProvider.when('/', {template: '', controller: 'AppWelcomeController'})
  $routeProvider.when('/login', {templateUrl: templateUrl('login'), controller: 'AppLoginController'})
  $routeProvider.when('/im', {templateUrl: templateUrl('im'), controller: 'AppIMController', reloadOnSearch: false})
  $routeProvider.otherwise({redirectTo: '/'})
}])


================================================
FILE: app/js/background.js
================================================
/*!
 * Webogram v0.7.0 - messaging web application for MTProto
 * https://github.com/zhukov/webogram
 * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
 * https://github.com/zhukov/webogram/blob/master/LICENSE
 */

chrome.app.runtime.onLaunched.addListener(function (launchData) {
  var isWindows = typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.match(/windows/i) ? true : false
  chrome.app.window.create('../index.html', {
    id: 'webogram-chat',
    innerBounds: {
      width: 1000,
      height: 700
    },
    minWidth: 320,
    minHeight: 400,
    frame: isWindows ? { color: '#5682a3' } : 'chrome'
  })
})


================================================
FILE: app/js/controllers.js
================================================
/*!
 * Webogram v0.7.0 - messaging web application for MTProto
 * https://github.com/zhukov/webogram
 * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
 * https://github.com/zhukov/webogram/blob/master/LICENSE
 */

'use strict'
/* global Config, location, templateUrl, onContentLoaded, tsNow, cancelEvent, safeReplaceObject, dT, SearchIndexManager, setZeroTimeout, versionCompare, calcImageInBox, getSelectedText, SVGElement, hasOnclick  */

/* Controllers */

angular.module('myApp.controllers', ['myApp.i18n'])

  .controller('AppWelcomeController', function ($scope, $location, MtpApiManager, ChangelogNotifyService, LayoutSwitchService) {
    MtpApiManager.getUserID().then(function (id) {
      if (id) {
        $location.url('/im')
        return
      }
      if (location.protocol == 'http:' &&
        !Config.Modes.http &&
        Config.App.domains.indexOf(location.hostname) != -1) {
        location.href = location.href.replace(/^http:/, 'https:')
        return
      }
      $location.url('/login')
    })

    ChangelogNotifyService.checkUpdate()
    LayoutSwitchService.start()
  })

  .controller('AppLoginController', function ($scope, $rootScope, $location, $timeout, $modal, $modalStack, MtpApiManager, ErrorService, NotificationsManager, PasswordManager, ChangelogNotifyService, IdleManager, LayoutSwitchService, WebPushApiManager, TelegramMeWebService, _) {
    $modalStack.dismissAll()
    IdleManager.start()

    MtpApiManager.getUserID().then(function (id) {
      if (id) {
        $location.url('/im')
        return
      }
      if (location.protocol == 'http:' &&
        !Config.Modes.http &&
        Config.App.domains.indexOf(location.hostname) != -1) {
        location.href = location.href.replace(/^http:/, 'https:')
        return
      }
      TelegramMeWebService.setAuthorized(false)
      WebPushApiManager.forceUnsubscribe()
    })

    var options = {dcID: 2, createNetworker: true}
    var countryChanged = false
    var selectedCountry = false

    $scope.credentials = {phone_country: '', phone_country_name: '', phone_number: '', phone_full: ''}
    $scope.progress = {}
    $scope.nextPending = {}
    $scope.about = {}

    $scope.chooseCountry = function () {
      var modal = $modal.open({
        templateUrl: templateUrl('country_select_modal'),
        controller: 'CountrySelectModalController',
        windowClass: 'countries_modal_window mobile_modal',
        backdrop: 'single'
      })

      modal.result.then(selectCountry)
    }

    function initPhoneCountry () {
      var langCode = (navigator.language || '').toLowerCase()
      var countryIso2 = Config.LangCountries[langCode]
      var shouldPregenerate = !Config.Navigator.mobile

      if (['en', 'en-us', 'en-uk'].indexOf(langCode) == -1) {
        if (countryIso2 !== undefined) {
          selectPhoneCountryByIso2(countryIso2)
        } else if (langCode.indexOf('-') > 0) {
          selectPhoneCountryByIso2(langCode.split('-')[1].toUpperCase())
        } else {
          selectPhoneCountryByIso2('US')
        }
      } else {
        selectPhoneCountryByIso2('US')
      }

      if (!shouldPregenerate) {
        return
      }
      var wasCountry = $scope.credentials.phone_country
      MtpApiManager.invokeApi('help.getNearestDc', {}, {dcID: 2, createNetworker: true}).then(function (nearestDcResult) {
        if (wasCountry == $scope.credentials.phone_country) {
          selectPhoneCountryByIso2(nearestDcResult.country)
        }
        if (nearestDcResult.nearest_dc != nearestDcResult.this_dc) {
          MtpApiManager.getNetworker(nearestDcResult.nearest_dc, {createNetworker: true})
        }
      })
    }

    function selectPhoneCountryByIso2 (countryIso2) {
      if (countryIso2) {
        var i, country
        for (i = 0; i < Config.CountryCodes.length; i++) {
          country = Config.CountryCodes[i]
          if (country[0] == countryIso2) {
            return selectCountry({name: _(country[1] + '_raw'), code: country[2]})
          }
        }
      }
      return selectCountry({name: _('country_select_modal_country_us_raw'), code: '+1'})
    }

    function selectCountry (country) {
      selectedCountry = country
      if ($scope.credentials.phone_country != country.code) {
        $scope.credentials.phone_country = country.code
      } else {
        updateCountry()
      }
      $scope.$broadcast('country_selected')
      $scope.$broadcast('value_updated')
    }

    function updateCountry () {
      var phoneNumber = (
        ($scope.credentials.phone_country || '') +
        ($scope.credentials.phone_number || '')
          ).replace(/\D+/g, '')
      var i, j, code
      var maxLength = 0
      var maxName = false

      if (phoneNumber.length) {
        if (selectedCountry && !phoneNumber.indexOf(selectedCountry.code.replace(/\D+/g, ''))) {
          maxName = selectedCountry.name
        } else {
          for (i = 0; i < Config.CountryCodes.length; i++) {
            for (j = 2; j < Config.CountryCodes[i].length; j++) {
              code = Config.CountryCodes[i][j].replace(/\D+/g, '')
              if (code.length > maxLength && !phoneNumber.indexOf(code)) {
                maxLength = code.length
                maxName = _(Config.CountryCodes[i][1] + '_raw')
              }
            }
          }
        }
      }

      $scope.credentials.phone_full = phoneNumber
      $scope.credentials.phone_country_name = maxName || _('login_controller_unknown_country_raw')
    }

    $scope.$watch('credentials.phone_country', updateCountry)
    $scope.$watch('credentials.phone_number', updateCountry)
    initPhoneCountry()

    var nextTimeout
    var updatePasswordTimeout = false

    $scope.try_desktop = {
      shown: false,
      domain: Config.Navigator.osX ? 'macos.telegram.org' : 'desktop.telegram.org'
    }
    $scope.closeTryDesktop = function() {
      $scope.try_desktop.shown = false;
      ConfigStorage.set({try_desktop_hidden: 1})
    };
    ConfigStorage.get('try_desktop_hidden', function (td_hidden) {
      $scope.try_desktop.shown = !Config.Navigator.mobile && !td_hidden;
    })

    function saveAuth (result) {
      MtpApiManager.setUserAuth(options.dcID, {
        id: result.user.id
      })
      $timeout.cancel(nextTimeout)

      $location.url('/im')
    }

    $scope.sendCode = function () {
      $timeout.cancel(nextTimeout)

      var fullPhone = ($scope.credentials.phone_country || '') + ($scope.credentials.phone_number || '')
      var badPhone = !fullPhone.match(/^[\d\-+\s]+$/)
      if (!badPhone) {
        fullPhone = fullPhone.replace(/\D/g, '')
        if (fullPhone.length < 7 || fullPhone.length > 25) {
          badPhone = true
        }
      }
      if (badPhone) {
        $scope.progress.enabled = false
        $scope.error = {field: 'phone'}
        return
      }

      ErrorService.confirm({
        type: 'LOGIN_PHONE_CORRECT',
        country_code: $scope.credentials.phone_country,
        phone_number: $scope.credentials.phone_number
      }).then(function () {
        $scope.progress.enabled = true

        onContentLoaded(function () {
          $scope.$broadcast('ui_height')
        })

        var authKeyStarted = tsNow()
        MtpApiManager.invokeApi('auth.sendCode', {
          flags: 0,
          phone_number: $scope.credentials.phone_full,
          api_id: Config.App.id,
          api_hash: Config.App.hash,
          lang_code: navigator.language || 'en'
        }, options).then(function (sentCode) {
          $scope.progress.enabled = false

          $scope.error = {}
          $scope.about = {}
          $scope.credentials.phone_code_hash = sentCode.phone_code_hash
          applySentCode(sentCode)
        }, function (error) {
          $scope.progress.enabled = false
          console.log('sendCode error', error)
          switch (error.type) {
            case 'PHONE_NUMBER_INVALID':
              $scope.error = {field: 'phone'}
              error.handled = true
              break

            case 'PHONE_NUMBER_APP_SIGNUP_FORBIDDEN':
              $scope.error = {field: 'phone'}
              break
          }
        })['finally'](function () {
          if ($rootScope.idle.isIDLE || tsNow() - authKeyStarted > 60000) {
            NotificationsManager.notify({
              title: 'Telegram',
              message: 'Your authorization key was successfully generated! Open the app to log in.',
              tag: 'auth_key'
            })
          }
        })
      })
    }

    function applySentCode (sentCode) {
      $scope.credentials.type = sentCode.type
      $scope.nextPending.type = sentCode.next_type || false
      $scope.nextPending.remaining = sentCode.timeout || false
      delete $scope.nextPending.progress

      nextTimeoutCheck()

      onContentLoaded(function () {
        $scope.$broadcast('ui_height')
      })
    }

    $scope.sendNext = function () {
      if (!$scope.nextPending.type ||
        $scope.nextPending.remaining > 0) {
        return
      }
      $scope.nextPending.progress = true
      MtpApiManager.invokeApi('auth.resendCode', {
        phone_number: $scope.credentials.phone_full,
        phone_code_hash: $scope.credentials.phone_code_hash
      }, options).then(applySentCode)
    }

    function nextTimeoutCheck () {
      $timeout.cancel(nextTimeout)
      if (!$scope.nextPending.type ||
        $scope.nextPending.remaining === false) {
        return
      }
      if ((--$scope.nextPending.remaining) > 0) {
        nextTimeout = $timeout(nextTimeoutCheck, 1000)
      }
    }

    $scope.editPhone = function () {
      $timeout.cancel(nextTimeout)

      if ($scope.credentials.phone_full &&
        $scope.credentials.phone_code_hash) {
        MtpApiManager.invokeApi('auth.cancelCode', {
          phone_number: $scope.credentials.phone_full,
          phone_code_hash: $scope.credentials.phone_code_hash
        }, options)
      }

      delete $scope.credentials.phone_code_hash
      delete $scope.credentials.phone_unoccupied
      delete $scope.credentials.phone_code_valid
      delete $scope.nextPending.remaining
    }

    $scope.$watch('credentials.phone_code', function (newVal) {
      if (newVal &&
        newVal.match(/^\d+$/) &&
        $scope.credentials.type &&
        $scope.credentials.type.length &&
        newVal.length == $scope.credentials.type.length) {
        $scope.logIn()
      }
    })

    $scope.logIn = function (forceSignUp) {
      if ($scope.progress.enabled &&
          $scope.progress.forceSignUp == forceSignUp) {
        return
      }
      var method = 'auth.signIn'
      var params = {
        phone_number: $scope.credentials.phone_full,
        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 || ''
        })
      }

      $scope.progress.forceSignUp = forceSignUp
      $scope.progress.enabled = true
      MtpApiManager.invokeApi(method, params, options).then(saveAuth, function (error) {
        $scope.progress.enabled = false
        if (error.code == 400 && error.type == 'PHONE_NUMBER_UNOCCUPIED') {
          error.handled = true
          $scope.credentials.phone_code_valid = true
          $scope.credentials.phone_unoccupied = true
          $scope.about = {}
          return
        } else if (error.code == 400 && error.type == 'PHONE_NUMBER_OCCUPIED') {
          error.handled = true
          return $scope.logIn(false)
        } else if (error.code == 401 && error.type == 'SESSION_PASSWORD_NEEDED') {
          $scope.progress.enabled = true
          updatePasswordState().then(function () {
            $scope.progress.enabled = false
            $scope.credentials.phone_code_valid = true
            $scope.credentials.password_needed = true
            $scope.about = {}
          })
          error.handled = true
          return
        }

        switch (error.type) {
          case 'FIRSTNAME_INVALID':
            $scope.error = {field: 'first_name'}
            error.handled = true
            break
          case 'LASTNAME_INVALID':
            $scope.error = {field: 'last_name'}
            error.handled = true
            break
          case 'PHONE_CODE_INVALID':
            $scope.error = {field: 'phone_code'}
            delete $scope.credentials.phone_code_valid
            error.handled = true
            break
          case 'PHONE_CODE_EXPIRED':
            $scope.editPhone()
            error.handled = true
            break
        }
      })
    }

    $scope.checkPassword = function () {
      $scope.progress.enabled = true
      return PasswordManager.check($scope.password, $scope.credentials.password, options).then(saveAuth, function (error) {
        $scope.progress.enabled = false
        switch (error.type) {
          case 'PASSWORD_HASH_INVALID':
            $scope.error = {field: 'password'}
            error.handled = true
            break
        }
      })
    }

    $scope.forgotPassword = function (event) {
      PasswordManager.requestRecovery($scope.password, options).then(function (emailRecovery) {
        var scope = $rootScope.$new()
        scope.recovery = emailRecovery
        scope.options = options
        var modal = $modal.open({
          scope: scope,
          templateUrl: templateUrl('password_recovery_modal'),
          controller: 'PasswordRecoveryModalController',
          windowClass: 'md_simple_modal_window mobile_modal'
        })

        modal.result.then(function (result) {
          if (result && result.user) {
            saveAuth(result)
          } else {
            $scope.canReset = true
          }
        })
      }, function (error) {
        switch (error.type) {
          case 'PASSWORD_EMPTY':
            $scope.logIn()
            error.handled = true
            break
          case 'PASSWORD_RECOVERY_NA':
            $timeout(function () {
              $scope.canReset = true
            }, 1000)
            error.handled = true
            break
        }
      })

      return cancelEvent(event)
    }

    $scope.resetAccount = function () {
      ErrorService.confirm({
        type: 'RESET_ACCOUNT'
      }).then(function () {
        $scope.progress.enabled = true
        MtpApiManager.invokeApi('account.deleteAccount', {
          reason: 'Forgot password'
        }, options).then(function () {
          delete $scope.progress.enabled
          delete $scope.credentials.password_needed
          $scope.credentials.phone_unoccupied = true
        }, function (error) {
          if (error.type &&
                   error.type.substr(0, 17) == '2FA_CONFIRM_WAIT_') {
            error.waitTime = error.type.substr(17)
            error.type = '2FA_CONFIRM_WAIT_TIME'
          }

          delete $scope.progress.enabled
        })
      })
    }

    function updatePasswordState () {
      // $timeout.cancel(updatePasswordTimeout)
      // updatePasswordTimeout = false
      return PasswordManager.getState(options).then(function (result) {
        return $scope.password = result
      // if (result._ == 'account.noPassword' && result.email_unconfirmed_pattern) {
      //   updatePasswordTimeout = $timeout(updatePasswordState, 5000)
      // }
      })
    }

    ChangelogNotifyService.checkUpdate()
    LayoutSwitchService.start()
  })

  .controller('AppIMController', function ($q, qSync, $scope, $location, $routeParams, $modal, $rootScope, $modalStack, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, ContactsSelectService, ChangelogNotifyService, ErrorService, AppRuntimeManager, HttpsMigrateService, LayoutSwitchService, LocationParamsService, AppStickersManager) {
    $scope.$on('$routeUpdate', updateCurDialog)

    var pendingParams = false
    var pendingAttachment = false
    $scope.$on('history_focus', function (e, peerData) {
      if (peerData.peerString == $scope.curDialog.peer &&
          (peerData.messageID ? peerData.messageID == $scope.curDialog.messageID : !$scope.curDialog.messageID) &&
          !peerData.startParam &&
          !peerData.attachment) {
        if (peerData.messageID) {
          $scope.$broadcast('ui_history_change_scroll', true)
        } else {
          $scope.$broadcast('ui_history_focus')
        }
        $modalStack.dismissAll()
      } else {
        var peerID = AppPeersManager.getPeerID(peerData.peerString)
        var username = AppPeersManager.getPeer(peerID).username
        var peer = username ? '@' + username : peerData.peerString
        if (peerData.messageID || peerData.startParam) {
          pendingParams = {
            messageID: peerData.messageID,
            startParam: peerData.startParam
          }
        } else {
          pendingParams = false
        }
        if (peerData.attachment) {
          pendingAttachment = peerData.attachment
        }
        if ($routeParams.p != peer) {
          $location.url('/im?p=' + peer)
        } else {
          updateCurDialog()
        }
      }
    })

    $scope.$on('esc_no_more', function () {
      $rootScope.$apply(function () {
        $location.url('/im')
      })
    })

    $scope.isLoggedIn = true
    $scope.isEmpty = {}
    $scope.search = {}
    $scope.historyFilter = {mediaType: false}
    $scope.historyPeer = {}
    $scope.historyState = {
      selectActions: false,
      botActions: false,
      channelActions: false,
      canReply: false,
      canDelete: false,
      canEdit: false,
      canReport: false,
      actions: function () {
        return $scope.historyState.selectActions ? 'selected' : ($scope.historyState.botActions ? 'bot' : ($scope.historyState.channelActions ? 'channel' : false))
      },
      typing: [],
      missedCount: 0,
      skipped: false
    }

    $scope.try_desktop = {
      shown: false,
      domain: Config.Navigator.osX ? 'macos.telegram.org' : 'desktop.telegram.org'
    }
    $scope.closeTryDesktop = function() {
      $scope.try_desktop.shown = false;
      onContentLoaded(function () {
        $scope.$broadcast('ui_dialogs_update');
        $scope.$broadcast('ui_panel_update');
      })
      ConfigStorage.set({try_desktop_hidden: 1})
    };
    ConfigStorage.get('try_desktop_hidden', function (td_hidden) {
      $scope.try_desktop.shown = !Config.Navigator.mobile && !td_hidden;
    })

    $scope.openSettings = function () {
      $modal.open({
        templateUrl: templateUrl('settings_modal'),
        controller: 'SettingsModalController',
        windowClass: 'settings_modal_window mobile_modal',
        backdrop: 'single'
      })
    }

    $scope.isHistoryPeerGroup = function () {
      return $scope.historyPeer.id < 0 && !AppPeersManager.isBroadcast($scope.historyPeer.id)
    }

    // setTimeout($scope.openSettings, 1000)

    $scope.openFaq = function () {
      var url = 'https://telegram.org/faq'
      switch (Config.I18n.locale) {
        case 'es-es':
          url += '/es'
          break
        case 'it-it':
          url += '/it'
          break
        case 'de-de':
          url += '/de'
          break
        case 'ko-ko':
          url += '/ko'
          break
        case 'pt-br':
          url += '/br'
          break
      }
      var popup = window.open(url, '_blank')
      try {
        popup.opener = null;
      } catch (e) {}
    }

    $scope.openContacts = function () {
      ContactsSelectService.selectContact().then(function (userID) {
        $scope.dialogSelect(AppUsersManager.getUserString(userID))
      })
    }

    $scope.openGroup = function () {
      ContactsSelectService.selectContacts({action: 'new_group'}).then(function (userIDs) {
        if (userIDs && 
            userIDs.length) {
          var scope = $rootScope.$new()
          scope.userIDs = userIDs

          $modal.open({
            templateUrl: templateUrl('chat_create_modal'),
            controller: 'ChatCreateModalController',
            scope: scope,
            windowClass: 'md_simple_modal_window mobile_modal',
            backdrop: 'single'
          })
        }
      })
    }

    $scope.importContact = function () {
      AppUsersManager.openImportContact().then(function (foundContact) {
        if (foundContact) {
          $rootScope.$broadcast('history_focus', {
            peerString: AppUsersManager.getUserString(foundContact)
          })
        }
      })
    }

    $scope.searchClear = function () {
      $scope.search.query = ''
      $scope.$broadcast('search_clear')
    }

    $scope.dialogSelect = function (peerString, messageID) {
      var params = {peerString: peerString}
      if (messageID) {
        params.messageID = messageID
      } else if ($scope.search.query) {
        $scope.searchClear()
      }
      var peerID = AppPeersManager.getPeerID(peerString)
      var converted = AppMessagesManager.convertMigratedPeer(peerID)
      if (converted) {
        params.peerString = AppPeersManager.getPeerString(converted)
      }
      $rootScope.$broadcast('history_focus', params)
    }

    $scope.logOut = function () {
      ErrorService.confirm({type: 'LOGOUT'}).then(function () {
        MtpApiManager.logOut().then(function () {
          location.hash = '/login'
          AppRuntimeManager.reload()
        })
      })
    }

    $scope.openChangelog = function () {
      ChangelogNotifyService.showChangelog(false)
    }

    $scope.showPeerInfo = function () {
      if ($scope.curDialog.peerID > 0) {
        AppUsersManager.openUser($scope.curDialog.peerID)
      } else if ($scope.curDialog.peerID < 0) {
        AppChatsManager.openChat(-$scope.curDialog.peerID)
      }
    }

    $scope.toggleEdit = function () {
      $scope.$broadcast('history_edit_toggle')
    }
    $scope.selectedFlush = function () {
      $scope.$broadcast('history_edit_flush')
    }
    $scope.toggleMedia = function (mediaType) {
      $scope.$broadcast('history_media_toggle', mediaType)
    }
    $scope.returnToRecent = function () {
      $scope.$broadcast('history_return_recent')
    }
    $scope.toggleSearch = function () {
      $scope.$broadcast('dialogs_search_toggle')
    }

    updateCurDialog()

    function updateCurDialog () {
      $modalStack.dismissAll()
      var addParams = pendingParams || {}
      pendingParams = false
      addParams.messageID = parseInt(addParams.messageID) || false
      addParams.startParam = addParams.startParam

      var peerStringPromise
      if ($routeParams.p && $routeParams.p.charAt(0) == '@') {
        if ($scope.curDialog === undefined) {
          $scope.curDialog = {
            peer: '',
            peerID: 0
          }
        }
        peerStringPromise = AppPeersManager.resolveUsername($routeParams.p.substr(1)).then(function (peerID) {
          return qSync.when(AppPeersManager.getPeerString(peerID))
        })
      } else {
        peerStringPromise = qSync.when($routeParams.p)
      }
      peerStringPromise.then(function (peerString) {
        $scope.curDialog = angular.extend({
          peer: peerString,
          peerID: AppPeersManager.getPeerID(peerString || '')
        }, addParams)
        if (pendingAttachment) {
          $scope.$broadcast('peer_draft_attachment', pendingAttachment)
          pendingAttachment = false
        }
      })
    }

    ChangelogNotifyService.checkUpdate()
    HttpsMigrateService.start()
    LayoutSwitchService.start()
    LocationParamsService.start()
    AppStickersManager.start()
  })

  .controller('AppImDialogsController', function ($scope, $location, $q, $timeout, $routeParams, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppProfileManager, AppPeersManager, PhonebookContactsService, ErrorService, AppRuntimeManager) {
    $scope.dialogs = []
    $scope.myResults = []
    $scope.foundPeers = []
    $scope.foundMessages = []

    if ($scope.search === undefined) {
      $scope.search = {}
    }
    if ($scope.isEmpty === undefined) {
      $scope.isEmpty = {}
    }
    $scope.phonebookAvailable = PhonebookContactsService.isAvailable()

    var searchMessages = false
    var offsetIndex = 0
    var maxID = 0
    var hasMore = false
    var jump = 0
    var contactsJump = 0
    var peersInDialogs = {}
    var typingTimeouts = {}
    var contactsShown

    $scope.$on('dialogs_need_more', function () {
      // console.log('on need more')
      showMoreDialogs()
    })

    $scope.$on('dialog_unread', function (e, dialog) {
      angular.forEach($scope.dialogs, function (curDialog) {
        if (curDialog.peerID == dialog.peerID) {
          curDialog.unreadCount = dialog.count
        }
      })
    })

    $scope.$on('history_search', function (e, peerID) {
      $scope.setSearchPeer(peerID)
    })

    $scope.$on('esc_no_more', function () {
      $scope.setSearchPeer(false)
    })

    $scope.$on('dialogs_multiupdate', function (e, dialogsUpdated) {
      if (searchMessages) {
        return false
      }
      if ($scope.search.query !== undefined &&
          $scope.search.query.length) {
        return false
      }

      var i
      var dialog
      var newPeer = false
      var len = $scope.dialogs.length
      for (i = 0; i < len; i++) {
        dialog = $scope.dialogs[i]
        if (dialogsUpdated[dialog.peerID]) {
          $scope.dialogs.splice(i, 1)
          i--
          len--
          AppMessagesManager.clearDialogCache(dialog.mid)
        }
      }

      angular.forEach(dialogsUpdated, function (dialog, peerID) {
        if ($scope.noUsers && peerID > 0) {
          return
        }
        if (!peersInDialogs[peerID]) {
          peersInDialogs[peerID] = true
          newPeer = true
        }
        $scope.dialogs.unshift(
          AppMessagesManager.wrapForDialog(dialog.top_message, dialog)
        )
      })

      sortDialogs()

      if (newPeer) {
        delete $scope.isEmpty.dialogs
        if (contactsShown) {
          showMoreConversations()
        }
      }
    })

    function deleteDialog (peerID) {
      for (var i = 0; i < $scope.dialogs.length; i++) {
        if ($scope.dialogs[i].peerID == peerID) {
          $scope.dialogs.splice(i, 1)
          break
        }
      }
    }

    function sortDialogs () {
      var myID = false
      if ($scope.forPeerSelect) {
        myID = AppUsersManager.getSelf().id
      }
      $scope.dialogs.sort(function (d1, d2) {
        if (d1.peerID == myID) {
          return -1
        }
        else if (d2.peerID == myID) {
          return 1
        }
        return d2.index - d1.index
      })
    }

    $scope.$on('dialog_top', function (e, dialog) {
      var curDialog, i, wrappedDialog
      var len = $scope.dialogs.length
      for (i = 0; i < len; i++) {
        curDialog = $scope.dialogs[i]
        if (curDialog.peerID == dialog.peerID) {
          wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, dialog)
          $scope.dialogs.splice(i, 1, wrappedDialog)
          break
        }
      }
      sortDialogs()
      if (wrappedDialog == $scope.dialogs[len - 1]) {
        $scope.dialogs.splice(len - 1, 1)
      }
    })
    $scope.$on('dialog_flush', function (e, update) {
      var curDialog, i
      for (i = 0; i < $scope.dialogs.length; i++) {
        curDialog = $scope.dialogs[i]
        if (curDialog.peerID == update.peerID) {
          curDialog.deleted = true
          break
        }
      }
    })
    $scope.$on('dialog_drop', function (e, dialog) {
      deleteDialog(dialog.peerID)
    })

    $scope.$on('dialog_draft', function (e, draftUpdate) {
      var curDialog, i
      for (i = 0; i < $scope.dialogs.length; i++) {
        curDialog = $scope.dialogs[i]
        if (curDialog.peerID == draftUpdate.peerID) {
          curDialog.draft = draftUpdate.draft
          if (draftUpdate.index) {
            curDialog.index = draftUpdate.index
          }
          sortDialogs()
          break
        }
      }
    })

    $scope.$on('history_delete', function (e, historyUpdate) {
      for (var i = 0; i < $scope.dialogs.length; i++) {
        if ($scope.dialogs[i].peerID == historyUpdate.peerID) {
          if (historyUpdate.msgs[$scope.dialogs[i].mid]) {
            $scope.dialogs[i].deleted = true
          }
          break
        }
      }
    })

    $scope.$on('apiUpdate', function (e, update) {
      switch (update._) {
        case 'updateUserTyping':
        case 'updateChatUserTyping':
          if (!AppUsersManager.hasUser(update.user_id)) {
            if (update.chat_id &&
              AppChatsManager.hasChat(update.chat_id) &&
              !AppChatsManager.isChannel(update.chat_id)) {
              AppProfileManager.getChatFull(update.chat_id)
            }
            return
          }
          var peerID = update._ == 'updateUserTyping' ? update.user_id : -update.chat_id
          AppUsersManager.forceUserOnline(update.user_id)
          for (var i = 0; i < $scope.dialogs.length; i++) {
            if ($scope.dialogs[i].peerID == peerID) {
              $scope.dialogs[i].typing = update.user_id
              $timeout.cancel(typingTimeouts[peerID])

              typingTimeouts[peerID] = $timeout(function () {
                for (var i = 0; i < $scope.dialogs.length; i++) {
                  if ($scope.dialogs[i].peerID == peerID) {
                    if ($scope.dialogs[i].typing == update.user_id) {
                      delete $scope.dialogs[i].typing
                    }
                  }
                }
              }, 6000)
              break
            }
          }
          break
      }
    })

    $scope.$watchCollection('search', function () {
      $scope.dialogs = []
      $scope.foundMessages = []
      searchMessages = !!$scope.searchPeer
      contactsJump++
      loadDialogs()
    })

    if (Config.Mobile) {
      $scope.$watch('curDialog.peer', function () {
        $scope.$broadcast('ui_dialogs_update')
      })
    }

    $scope.importPhonebook = function () {
      PhonebookContactsService.openPhonebookImport()
    }

    $scope.setSearchPeer = function (peerID) {
      $scope.searchPeer = peerID || false
      $scope.searchClear()
      if (peerID) {
        $scope.dialogs = []
        $scope.foundPeers = []
        searchMessages = true
        $scope.toggleSearch()
      } else {
        searchMessages = false
      }
      loadDialogs(true)
    }

    $scope.$on('contacts_update', function () {
      if (contactsShown) {
        showMoreConversations()
      }
    })

    $scope.$on('ui_dialogs_search_clear', $scope.searchClear)

    if (!$scope.noMessages) {
      $scope.$on('dialogs_search', function (e, data) {
        $scope.search.query = data.query || ''
        $scope.toggleSearch()
      })
    }

    var searchTimeoutPromise
    function getDialogs (force) {
      var curJump = ++jump

      if (searchTimeoutPromise) {
        $timeout.cancel(searchTimeoutPromise)
      }

      if (searchMessages) {
        searchTimeoutPromise = (force || maxID) ? $q.when() : $timeout(angular.noop, 500)
        return searchTimeoutPromise.then(function () {
          searchTimeoutPromise = false;
          var searchPeerID = $scope.searchPeer || false
          return AppMessagesManager.getSearch(searchPeerID, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID).then(function (result) {
            if (curJump != jump) {
              return $q.reject()
            }
            var dialogs = []
            angular.forEach(result.history, function (messageID) {
              var message = AppMessagesManager.getMessage(messageID)
              var peerID = AppMessagesManager.getMessagePeer(message)

              dialogs.push({
                peerID: peerID,
                top_message: messageID,
                unread_count: -1
              })
            })

            return {
              dialogs: dialogs
            }
          })
        })
      }

      var query = $scope.search.query || ''
      if ($scope.noUsers) {
        query = '%pg ' + query
      }
      return AppMessagesManager.getConversations(query, offsetIndex).then(function (result) {
        if (curJump != jump) {
          return $q.reject()
        }
        if (!query && !offsetIndex && $scope.forPeerSelect) {
          var myID = AppUsersManager.getSelf().id
          return AppMessagesManager.getConversation(myID).then(function (dialog) {
            result.dialogs.unshift(dialog)
            return result
          })
        }
        return result
      })
    }

    function loadDialogs (force) {
      offsetIndex = 0
      maxID = 0
      hasMore = false
      if (!searchMessages) {
        peersInDialogs = {}
        contactsShown = false
      }

      getDialogs(force).then(function (dialogsResult) {
        if (!searchMessages) {
          $scope.dialogs = []
          $scope.myResults = []
          $scope.foundPeers = []
        }
        $scope.foundMessages = []

        var dialogsList = searchMessages ? $scope.foundMessages : $scope.dialogs

        if (dialogsResult.dialogs.length) {
          angular.forEach(dialogsResult.dialogs, function (dialog) {
            if ($scope.canSend &&
                AppPeersManager.isChannel(dialog.peerID) &&
                !AppChatsManager.hasRights(-dialog.peerID, 'send')) {
              return
            }
            var wrapDialog = searchMessages ? undefined : dialog
            var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, wrapDialog)

            if (searchMessages &&
                $scope.searchPeer) {
              var message = AppMessagesManager.getMessage(dialog.top_message)
              if (message.fromID > 0) {
                wrappedDialog.peerID = message.fromID
                wrappedDialog.foundInHistory = true
              }
            }

            if (searchMessages) {
              wrappedDialog.unreadCount = -1
            } else {
              if (peersInDialogs[dialog.peerID]) {
                return
              } else {
                peersInDialogs[dialog.peerID] = true
              }
            }
            dialogsList.push(wrappedDialog)
          })

          if (searchMessages) {
            maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message
          } else {
            offsetIndex = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].index
            delete $scope.isEmpty.dialogs
          }
          hasMore = true
        } else {
          hasMore = false
        }

        $scope.$broadcast('ui_dialogs_change')

        if (!$scope.search.query) {
          AppMessagesManager.getConversations('', offsetIndex, 100)
          if (!dialogsResult.dialogs.length) {
            $scope.isEmpty.dialogs = true
            showMoreDialogs()
          }
        } else {
          showMoreDialogs()
        }
      })
    }

    function showMoreDialogs () {
      if (contactsShown && (!hasMore || (!offsetIndex && !maxID))) {
        return
      }

      if (!hasMore &&
        !searchMessages &&
        !$scope.noUsers &&
        ($scope.search.query || !$scope.dialogs.length)) {
        showMoreConversations()
        return
      }

      getDialogs().then(function (dialogsResult) {
        if (dialogsResult.dialogs.length) {
          var dialogsList = searchMessages ? $scope.foundMessages : $scope.dialogs

          angular.forEach(dialogsResult.dialogs, function (dialog) {
            if ($scope.canSend &&
                AppPeersManager.isChannel(dialog.peerID) &&
                !AppChatsManager.hasRights(-dialog.peerID, 'send')) {
              return
            }
            var wrapDialog = searchMessages ? undefined : dialog
            var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, wrapDialog)

            if (searchMessages &&
                $scope.searchPeer) {
              var message = AppMessagesManager.getMessage(dialog.top_message)
              if (message.fromID > 0) {
                wrappedDialog.peerID = message.fromID
                wrappedDialog.foundInHistory = true
              }
            }

            if (searchMessages) {
              wrappedDialog.unreadCount = -1
            } else {
              if (peersInDialogs[dialog.peerID]) {
                return
              } else {
                peersInDialogs[dialog.peerID] = true
              }
            }

            if (searchMessages &&
                $scope.searchPeer) {
              var message = AppMessagesManager.getMessage(dialog.top_message)
              if (message.fromID > 0) {
                wrappedDialog.peerID = message.fromID
              }
            }

            dialogsList.push(wrappedDialog)
          })

          if (searchMessages) {
            maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message
          } else {
            offsetIndex = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].index
          }

          $scope.$broadcast('ui_dialogs_append')

          hasMore = true
        } else {
          hasMore = false
        }
      })
    }

    function showMoreConversations () {
      contactsShown = true

      var curJump = ++contactsJump
      AppUsersManager.getContacts($scope.search.query).then(function (contactsList) {
        if (curJump != contactsJump) return
        $scope.myResults = []
        angular.forEach(contactsList, function (userID) {
          if (peersInDialogs[userID] === undefined) {
            $scope.myResults.push({
              id: userID,
              peerString: AppUsersManager.getUserString(userID)
            })
          }
        })

        if (contactsList.length) {
          delete $scope.isEmpty.contacts
        } else if (!$scope.search.query) {
          $scope.isEmpty.contacts = true
        }
        $scope.$broadcast('ui_dialogs_append')
      })

      if ($scope.search.query && $scope.search.query.length >= 2) {
        $timeout(function () {
          if (curJump != contactsJump) return
          MtpApiManager.invokeApi('contacts.search', {q: $scope.search.query, limit: 10}).then(function (result) {
            AppUsersManager.saveApiUsers(result.users)
            AppChatsManager.saveApiChats(result.chats)
            if (curJump != contactsJump) return
            var alreadyPeers = []
            angular.forEach($scope.myResults, function (peerFound) {
              alreadyPeers.push(peerFound.id)
            })
            angular.forEach(result.my_results, function (peerFound) {
              var peerID = AppPeersManager.getPeerID(peerFound)
              if (peersInDialogs[peerID] === undefined &&
                  alreadyPeers.indexOf(peerID) == -1) {
                alreadyPeers.push(peerID)
                if ($scope.canSend &&
                  AppPeersManager.isChannel(peerID) &&
                  !AppChatsManager.hasRights(-peerID, 'send')) {
                  return
                }
                $scope.myResults.push({
                  id: peerID,
                  peerString: AppPeersManager.getPeerString(peerID)
                })
              }
            })

            $scope.foundPeers = []
            angular.forEach(result.results, function (peerFound) {
              var peerID = AppPeersManager.getPeerID(peerFound)
              if (peersInDialogs[peerID] === undefined &&
                  alreadyPeers.indexOf(peerID) == -1) {
                if ($scope.canSend &&
                  AppPeersManager.isChannel(peerID) &&
                  !AppChatsManager.hasRights(-peerID, 'send')) {
                  return
                }
                alreadyPeers.push(peerID)
                $scope.foundPeers.push({
                  id: peerID,
                  username: AppPeersManager.getPeer(peerID).username,
                  peerString: AppUsersManager.getUserString(peerID)
                })
              }
            })
          }, function (error) {
            if (error.code == 400) {
              error.handled = true
            }
          })
        }, 500)
      }

      if ($scope.search.query && !$scope.noMessages) {
        searchMessages = true
        loadDialogs()
      }
    }
  })

  .controller('AppImHistoryController', function ($scope, $location, $timeout, $modal, $rootScope, toaster, _, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, PeersSelectService, IdleManager, StatusManager, NotificationsManager, ErrorService, GeoLocationManager) {
    $scope.$watchCollection('curDialog', applyDialogSelect)

    ApiUpdatesManager.attach()
    IdleManager.start()
    StatusManager.start()

    $scope.peerHistories = []
    $scope.selectedMsgs = {}
    $scope.selectedCount = 0
    $scope.historyState.selectActions = false
    $scope.historyState.botActions = false
    $scope.historyState.channelActions = false
    $scope.historyState.canDelete = false
    $scope.historyState.canReply = false
    $scope.historyState.missedCount = 0
    $scope.historyState.skipped = false
    $scope.state = {}

    $scope.toggleMessage = toggleMessage
    $scope.selectedDelete = selectedDelete
    $scope.selectedForward = selectedForward
    $scope.selectedReply = selectedReply
    $scope.selectedEdit = selectedEdit
    $scope.selectedCancel = selectedCancel
    $scope.selectedFlush = selectedFlush
    $scope.selectedReport = selectedReport
    $scope.selectInlineBot = selectInlineBot

    $scope.startBot = startBot
    $scope.cancelBot = cancelBot
    $scope.joinChannel = joinChannel
    $scope.togglePeerMuted = togglePeerMuted

    $scope.toggleEdit = toggleEdit
    $scope.toggleMedia = toggleMedia
    $scope.returnToRecent = returnToRecent

    $scope.$on('history_edit_toggle', toggleEdit)
    $scope.$on('history_edit_flush', selectedFlush)
    $scope.$on('history_media_toggle', function (e, mediaType) {
      toggleMedia(mediaType)
    })

    $scope.$on('history_return_recent', returnToRecent)

    var peerID
    var peerHistory = false
    var unreadAfterIdle = false
    var hasMore = false
    var hasLess = false
    var maxID = 0
    var minID = 0
    var lastSelectID = false
    var inputMediaFilters = {
      photos: 'inputMessagesFilterPhotos',
      video: 'inputMessagesFilterVideo',
      documents: 'inputMessagesFilterDocument',
      audio: 'inputMessagesFilterVoice',
      round: 'inputMessagesFilterRoundVideo',
      music: 'inputMessagesFilterMusic',
      urls: 'inputMessagesFilterUrl',
      mentions: 'inputMessagesFilterMyMentions'
    }
    var jump = 0
    var moreJump = 0
    var moreActive = false
    var morePending = false
    var lessJump = 0
    var lessActive = false
    var lessPending = false

    function applyDialogSelect (newDialog, oldDialog) {
      peerID = $rootScope.selectedPeerID = newDialog.peerID
      var migratedToPeer = AppPeersManager.getPeerMigratedTo(peerID)
      if (migratedToPeer) {
        $rootScope.$broadcast('history_focus', {
          peerString: AppPeersManager.getPeerString(migratedToPeer)
        })
        return
      }
      $scope.historyFilter.mediaType = false

      AppPeersManager.getInputPeer(newDialog.peer || $scope.curDialog.peer || '')

      updateBotActions()
      selectedCancel(true)

      if (oldDialog.peer &&
          oldDialog.peer == newDialog.peer &&
          newDialog.messageID) {
        messageFocusHistory()
      } else if (peerID) {
        updateHistoryPeer(true)
        loadHistory()
      } else {
        showEmptyHistory()
      }
    }

    function historiesQueuePush (peerID) {
      var pos = -1
      var maxLen = 10
      var i, history, diff

      for (i = 0; i < $scope.peerHistories.length; i++) {
        if ($scope.peerHistories[i].peerID == peerID) {
          pos = i
          break
        }
      }
      if (pos > -1) {
        history = $scope.peerHistories[pos]
        return history
      }
      history = {peerID: peerID, messages: [], ids: []}
      $scope.peerHistories.unshift(history)
      diff = $scope.peerHistories.length - maxLen
      if (diff > 0) {
        $scope.peerHistories.splice(maxLen - 1, diff)
      }

      return history
    }

    function historiesQueueFind (peerID) {
      var i
      for (i = 0; i < $scope.peerHistories.length; i++) {
        if ($scope.peerHistories[i].peerID == peerID) {
          return $scope.peerHistories[i]
        }
      }
      return false
    }

    function historiesQueuePop (peerID) {
      var i
      for (i = 0; i < $scope.peerHistories.length; i++) {
        if ($scope.peerHistories[i].peerID == peerID) {
          $scope.peerHistories.splice(i, 1)
          return true
        }
      }
      return false
    }

    function updateHistoryPeer (preload) {
      var peerData = AppPeersManager.getPeer(peerID)
      // console.log('update', preload, peerData)
      if (!peerData || peerData.deleted) {
        safeReplaceObject($scope.state, {loaded: false})
        return false
      }

      peerHistory = historiesQueuePush(peerID)

      safeReplaceObject($scope.historyPeer, {
        id: peerID,
        data: peerData
      })

      MtpApiManager.getUserID().then(function (myID) {
        $scope.ownID = myID
      })

      if (preload) {
        $scope.historyState.typing.splice(0, $scope.historyState.typing.length)
        $scope.$broadcast('ui_peer_change')
        $scope.$broadcast('ui_history_change')
        safeReplaceObject($scope.state, {loaded: true, empty: !peerHistory.messages.length, mayBeHasMore: true})

        updateBotActions()
        updateChannelActions()
      }
    }

    function updateBotActions () {
      var wasBotActions = $scope.historyState.botActions
      if (!peerID ||
        peerID < 0 ||
        !AppUsersManager.isBot(peerID) ||
        $scope.historyFilter.mediaType ||
        $scope.curDialog.messageID) {
        $scope.historyState.botActions = false
      } else if (
        $scope.state.empty || (
        peerHistory &&
        peerHistory.messages.length == 1 &&
        peerHistory.messages[0].action &&
        peerHistory.messages[0].action._ == 'messageActionBotIntro'
        )
      ) {
        $scope.historyState.botActions = 'start'
      } else if ($scope.curDialog.startParam) {
        $scope.historyState.botActions = 'param'
      } else {
        $scope.historyState.botActions = false
      }
      if (wasBotActions != $scope.historyState.botActions) {
        $scope.$broadcast('ui_panel_update')
      }
    }

    function updateChannelActions () {
      var wasChannelActions = $scope.historyState.channelActions
      var channel
      if (peerID &&
        AppPeersManager.isChannel(peerID) &&
        (channel = AppChatsManager.getChat(-peerID))) {
        var canSend = AppChatsManager.hasRights(-peerID, 'send')
        if (!canSend) {
          if (channel.pFlags.left) {
            $scope.historyState.channelActions = 'join'
          } else {
            if (!$scope.historyState.channelActions) {
              $scope.historyState.channelActions = 'mute'
            }
            NotificationsManager.getPeerMuted(peerID).then(function (muted) {
              $scope.historyState.channelActions = muted ? 'unmute' : 'mute'
            })
          }
        } else {
          $scope.historyState.channelActions = false
        }
        $scope.historyState.canReply = canSend
        $scope.historyState.canDelete = canSend || channel.pFlags.moderator
      } else {
        $scope.historyState.channelActions = false
        $scope.historyState.canReply = true
        $scope.historyState.canDelete = true
      }
      if (wasChannelActions != $scope.historyState.channelActions) {
        $scope.$broadcast('ui_panel_update')
      }
    }

    function messageFocusHistory () {
      var history = historiesQueueFind(peerID)

      if (history &&
        history.ids.indexOf($scope.curDialog.messageID) != -1) {
        $scope.historyUnread = {}
        var focusedMsgID = $scope.curDialog.messageID || 0
        $scope.$broadcast('messages_focus', focusedMsgID)
        $scope.$broadcast('ui_history_change_scroll', true)
      } else {
        loadHistory()
      }
    }

    function showLessHistory () {
      if (!hasLess) {
        return
      }
      if (moreActive) {
        lessPending = true
        return
      }
      lessPending = false
      $scope.state.lessActive = lessActive = true

      var curJump = jump
      var curLessJump = ++lessJump
      var limit = 0
      var backLimit = 20
      AppMessagesManager.getHistory($scope.curDialog.peerID, minID, limit, backLimit).then(function (historyResult) {
        $scope.state.lessActive = lessActive = false
        if (curJump != jump || curLessJump != lessJump) return

        var i, id
        for (i = historyResult.history.length - 1; i >= 0; i--) {
          id = historyResult.history[i]
          if (id > minID) {
            peerHistory.messages.push(AppMessagesManager.wrapForHistory(id))
            peerHistory.ids.push(id)
          }
        }

        if (historyResult.history.length) {
          minID = historyResult.history.length >= backLimit
            ? historyResult.history[0]
            : 0
          if (AppMessagesManager.regroupWrappedHistory(peerHistory.messages, -backLimit)) {
            $scope.$broadcast('messages_regroup')
          }
          delete $scope.state.empty
          $scope.$broadcast('ui_history_append')
        } else {
          minID = 0
        }
        $scope.historyState.skipped = hasLess = minID > 0

        if (morePending) {
          showMoreHistory()
        }
      })
    }

    function showMoreHistory () {
      if (!hasMore) {
        return
      }
      if (lessActive) {
        morePending = true
        return
      }
      morePending = false
      $scope.state.moreActive = moreActive = true

      var curJump = jump
      var curMoreJump = ++moreJump
      var inputMediaFilter = $scope.historyFilter.mediaType && {_: inputMediaFilters[$scope.historyFilter.mediaType]}
      var limit = Config.Mobile ? 20 : 0
      var getMessagesPromise = inputMediaFilter
        ? AppMessagesManager.getSearch($scope.curDialog.peerID, '', inputMediaFilter, maxID, limit)
        : AppMessagesManager.getHistory($scope.curDialog.peerID, maxID, limit)

      getMessagesPromise.then(function (historyResult) {
        $scope.state.moreActive = moreActive = false
        if (curJump != jump || curMoreJump != moreJump) return

        angular.forEach(historyResult.history, function (id) {
          peerHistory.messages.unshift(AppMessagesManager.wrapForHistory(id))
          peerHistory.ids.unshift(id)
        })

        hasMore = historyResult.count === null ||
          (historyResult.history.length && peerHistory.messages.length < historyResult.count)

        if (historyResult.history.length) {
          delete $scope.state.empty
          maxID = historyResult.history[historyResult.history.length - 1]
          $scope.$broadcast('ui_history_prepend')
          if (AppMessagesManager.regroupWrappedHistory(peerHistory.messages, historyResult.history.length + 1)) {
            $scope.$broadcast('messages_regroup')
          }
        }

        if (lessPending) {
          showLessHistory()
        }
      })
    }

    function loadHistory (forceRecent) {
      $scope.historyState.missedCount = 0

      hasMore = false
      $scope.historyState.skipped = hasLess = false
      maxID = 0
      minID = 0
      peerHistory = historiesQueuePush(peerID)

      var limit = 0
      var backLimit = 0

      if ($scope.curDialog.messageID) {
        maxID = parseInt($scope.curDialog.messageID)
        limit = 20
        backLimit = 20
      } else if (forceRecent) {
        limit = 10
      }

      $scope.state.moreActive = moreActive = false
      morePending = false
      $scope.state.lessActive = lessActive = false
      lessPending = false

      var prerenderedLen = peerHistory.messages.length
      if (prerenderedLen && (maxID || backLimit)) {
        prerenderedLen = 0
        peerHistory.messages = []
        peerHistory.ids = []
        $scope.state.empty = true
      }

      var curJump = ++jump
      var inputMediaFilter = $scope.historyFilter.mediaType && {_: inputMediaFilters[$scope.historyFilter.mediaType]}
      var getMessagesPromise = inputMediaFilter
        ? AppMessagesManager.getSearch($scope.curDialog.peerID, '', inputMediaFilter, maxID)
        : AppMessagesManager.getHistory($scope.curDialog.peerID, maxID, limit, backLimit, prerenderedLen)

      $scope.state.mayBeHasMore = true
      // console.log(dT(), 'start load history', $scope.curDialog)
      getMessagesPromise.then(function (historyResult) {
        if (curJump != jump) return
        // console.log(dT(), 'history loaded', angular.copy(historyResult))

        var fetchedLength = historyResult.history.length

        minID = (historyResult.unreadSkip || (maxID && historyResult.history.indexOf(maxID) >= backLimit - 1))
          ? historyResult.history[0]
          : 0
        maxID = historyResult.history[historyResult.history.length - 1]

        $scope.historyState.skipped = hasLess = minID > 0
        hasMore = historyResult.count === null ||
          (fetchedLength && fetchedLength < historyResult.count)

        updateHistoryPeer()
        safeReplaceObject($scope.state, {loaded: true, empty: !fetchedLength})

        peerHistory.messages = []
        peerHistory.ids = []
        angular.forEach(historyResult.history, function (id) {
          var message = AppMessagesManager.wrapForHistory(id)
          if ($scope.historyState.skipped) {
            delete message.pFlags.unread
          }
          if (historyResult.unreadOffset) {
            message.unreadAfter = true
          }
          peerHistory.messages.push(message)
          peerHistory.ids.push(id)
        })
        peerHistory.messages.reverse()
        peerHistory.ids.reverse()

        if (AppMessagesManager.regroupWrappedHistory(peerHistory.messages)) {
          $scope.$broadcast('messages_regroup')
        }

        if (historyResult.unreadOffset) {
          $scope.historyUnreadAfter = historyResult.history[historyResult.unreadOffset - 1]
        } else if ($scope.historyUnreadAfter) {
          delete $scope.historyUnreadAfter
        }
        $scope.$broadcast('messages_unread_after')
        var focusedMsgID = $scope.curDialog.messageID || 0
        onContentLoaded(function () {
          $scope.$broadcast('messages_focus', focusedMsgID)
        })
        $scope.$broadcast('ui_history_change')

        if (!$rootScope.idle.isIDLE) {
          AppMessagesManager.readHistory($scope.curDialog.peerID)
        }

        updateBotActions()
        updateChannelActions()
      }, function () {
        safeReplaceObject($scope.state, {error: true, loaded: true})
      })
    }

    function showEmptyHistory () {
      jump++
      safeReplaceObject($scope.historyPeer, {})
      safeReplaceObject($scope.state, {notSelected: true})
      peerHistory = false
      hasMore = false

      $scope.$broadcast('ui_history_change')
    }

    function startBot () {
      AppMessagesManager.startBot(peerID, 0, $scope.curDialog.startParam)
      $scope.curDialog.startParam = false
    }

    function cancelBot () {
      delete $scope.curDialog.startParam
    }

    function joinChannel () {
      MtpApiManager.invokeApi('channels.joinChannel', {
        channel: AppChatsManager.getChannelInput(-peerID)
      }).then(function (result) {
        ApiUpdatesManager.processUpdateMessage(result)
      })
    }

    function togglePeerMuted (muted) {
      NotificationsManager.getPeerSettings(peerID).then(function (settings) {
        settings.mute_until = !muted ? 0 : 2000000000
        NotificationsManager.updatePeerSettings(peerID, settings)
      })
    }

    function toggleMessage (messageID, $event) {
      if ($scope.historyState.botActions ||
        $rootScope.idle.afterFocus) {
        return false
      }
      var message = AppMessagesManager.getMessage(messageID)
      if (message._ == 'messageService') {
        return false
      }

      if (!$scope.historyState.selectActions) {
        if (getSelectedText()) {
          return false
        }

        var target = $event.target
        while (target) {
          if (target instanceof SVGElement) {
            target = target.parentNode
            continue
          }
          if (target.className && target.className.indexOf('im_message_outer_wrap') != -1) {
            if (Config.Mobile) {
              return false
            }
            break
          }
          if (target.className &&
            target.className.indexOf('im_message_date') != -1) {
            if ($scope.historyFilter.mediaType) {
              $rootScope.$broadcast('history_focus', {
                peerString: $scope.curDialog.peer,
                messageID: messageID
              })
              return
            }
            if (AppPeersManager.isBroadcast(peerID)) {
              quickForward(messageID)
            } else {
              selectedReply(messageID)
            }
            return false
          }
          if (Config.Mobile &&
            target.className &&
            target.className.indexOf('im_message_body') != -1) {
            break
          }
          if (target.tagName == 'A' || hasOnclick(target)) {
            return false
          }
          target = target.parentNode
        }

        if (Config.Mobile) {
          $scope.historyState.canEdit = AppMessagesManager.canEditMessage(messageID)
          $scope.historyState.canReport = AppMessagesManager.canReportMessage(messageID)

          $modal.open({
            templateUrl: templateUrl('message_actions_modal'),
            windowClass: 'message_actions_modal_window',
            scope: $scope.$new()
          }).result.then(function (action) {
            switch (action) {
              case 'reply':
                selectedReply(messageID)
                break

              case 'edit':
                selectedEdit(messageID)
                break

              case 'delete':
                selectedDelete(messageID)
                break

              case 'forward':
                selectedForward(messageID)
                break

              case 'report':
                selectedReport(messageID)
                break

              case 'select':
                $scope.historyState.selectActions = 'selected'
                $scope.$broadcast('ui_panel_update')
                toggleMessage(messageID)
                break
            }
          })
          return false
        }
      }

      var shiftClick = $event && $event.shiftKey
      if (shiftClick) {
        $scope.$broadcast('ui_selection_clear')
      }

      if ($scope.selectedMsgs[messageID]) {
        lastSelectID = false
        delete $scope.selectedMsgs[messageID]
        $scope.selectedCount--
        if (!$scope.selectedCount) {
          $scope.historyState.selectActions = false
          $scope.$broadcast('ui_panel_update')
        }
      } else {
        if (!shiftClick) {
          lastSelectID = messageID
        } else if (lastSelectID != messageID) {
          var dir = lastSelectID > messageID
          var i, startPos, curMessageID

          for (i = 0; i < peerHistory.messages.length; i++) {
            if (peerHistory.messages[i].mid == lastSelectID) {
              startPos = i
              break
            }
          }

          i = startPos
          while (peerHistory.messages[i] &&
            (curMessageID = peerHistory.messages[i].mid) != messageID) {
            if (!$scope.selectedMsgs[curMessageID]) {
              $scope.selectedMsgs[curMessageID] = true
              $scope.selectedCount++
            }
            i += dir ? -1 : +1
          }
        }

        $scope.selectedMsgs[messageID] = true
        $scope.selectedCount++
        if (!$scope.historyState.selectActions) {
          $scope.historyState.selectActions = 'selected'
          $scope.$broadcast('ui_panel_update')
        }
      }
      if ($scope.selectedCount == 1) {
        angular.forEach($scope.selectedMsgs, function (t, messageID) {
          $scope.historyState.canEdit = AppMessagesManager.canEditMessage(messageID)
          $scope.historyState.canReport = AppMessagesManager.canReportMessage(messageID)
        })
      } else {
        $scope.historyState.canEdit = false
        $scope.historyState.canReport = false
        angular.forEach($scope.selectedMsgs, function (t, messageID) {
          if (AppMessagesManager.canReportMessage(messageID)) {
            $scope.historyState.canReport = true
          }
        })
      }
      $scope.$broadcast('messages_select')
    }

    function selectInlineBot (botID, $event) {
      if ($scope.historyState.canReply) {
        $scope.$broadcast('inline_bot_select', botID)
      }
      return cancelEvent($event)
    }

    function selectedCancel (noBroadcast) {
      $scope.selectedMsgs = {}
      $scope.selectedCount = 0
      $scope.historyState.selectActions = false
      lastSelectID = false
      if (!noBroadcast) {
        $scope.$broadcast('ui_panel_update')
      }
      $scope.$broadcast('messages_select')
    }

    function selectedFlush () {
      ErrorService.confirm({type: 'HISTORY_FLUSH'}).then(function () {
        AppMessagesManager.flushHistory($scope.curDialog.peerID, true).then(function () {
          selectedCancel()
        })
      })
    }

    function selectedDelete (selectedMessageID) {
      var selectedMessageIDs = []
      if (selectedMessageID) {
        selectedMessageIDs.push(selectedMessageID)
      } else if ($scope.selectedCount > 0) {
        angular.forEach($scope.selectedMsgs, function (t, messageID) {
          selectedMessageIDs.push(messageID)
        })
      }
      if (selectedMessageIDs.length) {
        var peerID = $scope.curDialog.peerID
        var isUser = peerID > 0
        var isChannel = AppPeersManager.isChannel(peerID)
        var isBroadcast = AppPeersManager.isBroadcast(peerID)
        var isMegagroup = AppPeersManager.isMegagroup(peerID)
        var isUsualGroup = !isChannel && !isUser
        var isSavedMessages = peerID == AppUsersManager.getSelf().id

        var revocable = !isChannel
        for (var i = 0; revocable && i < selectedMessageIDs.length; i++) {
          var messageID = selectedMessageIDs[i]
          if (!AppMessagesManager.canRevokeMessage(messageID)) {
            revocable = false
          }
        }

        ErrorService.confirm({
          type: 'MESSAGES_DELETE',
          count: selectedMessageIDs.length,
          revocable: revocable,
          isUser: isUser,
          peerID: peerID,
          isSavedMessages: isSavedMessages,
          isChannel: isBroadcast,
          isSupergroup: isMegagroup,
          isUsualGroup: isUsualGroup
        }, {}, { revoke: false }).then(function (data) {
          AppMessagesManager.deleteMessages(selectedMessageIDs, data.revoke).then(function () {
            selectedCancel()
          })
        })
      }
    }

    function quickForward (msgID) {
      PeersSelectService.selectPeers({
        canSend: true,
        confirm_type: 'FORWARD_PEER',
        shareLinkPromise: AppMessagesManager.getMessageShareLink(msgID)
      }).then(function (peerStrings) {
        angular.forEach(peerStrings, function (peerString) {
          var peerID = AppPeersManager.getPeerID(peerString)
          AppMessagesManager.forwardMessages(peerID, [msgID])
        })
        var toastData = toaster.pop({
          type: 'info',
          body: _('confirm_modal_forward_to_peer_success'),
          bodyOutputType: 'trustedHtml',
          clickHandler: function () {
            $rootScope.$broadcast('history_focus', {
              peerString: peerStrings[0]
            })
            toaster.clear(toastData)
          },
          showCloseButton: false
        })
      })
    }

    function selectedForward (selectedMessageID) {
      var selectedMessageIDs = []
      if (selectedMessageID) {
        selectedMessageIDs.push(selectedMessageID)
      } else if ($scope.selectedCount > 0) {
        angular.forEach($scope.selectedMsgs, function (t, messageID) {
          selectedMessageIDs.push(messageID)
        })
      }
      if (selectedMessageIDs.length) {
        PeersSelectService.selectPeer({canSend: true}).then(function (peerStrings) {
          selectedCancel()
          if (Array.isArray(peerStrings) && peerStrings.length > 1) {
            angular.forEach(peerStrings, function (peerString) {
              var peerID = AppPeersManager.getPeerID(peerString)
              AppMessagesManager.forwardMessages(peerID, selectedMessageIDs)
            })
            var toastData = toaster.pop({
              type: 'info',
              body: _('confirm_modal_forward_to_peer_success'),
              bodyOutputType: 'trustedHtml',
              clickHandler: function () {
                $rootScope.$broadcast('history_focus', {
                  peerString: peerStrings[0]
                })
                toaster.clear(toastData)
              },
              showCloseButton: false
            })
          } else {            
            $rootScope.$broadcast('history_focus', {
              peerString: peerStrings,
              attachment: {
                _: 'fwd_messages',
                id: selectedMessageIDs
              }
            })
          }    
        })
      }
    }

    function selectedReport (selectedMessageID) {
      var selectedMessageIDs = []
      if (selectedMessageID) {
        selectedMessageIDs.push(selectedMessageID)
      } else if ($scope.selectedCount > 0) {
        angular.forEach($scope.selectedMsgs, function (t, messageID) {
          selectedMessageIDs.push(messageID)
        })
      }
      if (selectedMessageIDs.length) {
        $modal.open({
          templateUrl: templateUrl('report_msgs_modal'),
          controller: 'ReportMessagesModalController',
          windowClass: 'md_simple_modal_window mobile_modal',
          scope: $scope.$new()
        }).result.then(function (inputReason) {
          selectedCancel()
          AppMessagesManager.reportMessages(selectedMessageIDs, inputReason).then(function () {
            var toastData = toaster.pop({
              type: 'info',
              body: _('confirm_modal_report_success'),
              bodyOutputType: 'trustedHtml',
              clickHandler: function () {
                toaster.clear(toastData)
              },
              showCloseButton: false
            })
          })
        })
      }
    }

    function selectedReply (selectedMessageID) {
      if (!selectedMessageID && $scope.selectedCount == 1) {
        angular.forEach($scope.selectedMsgs, function (t, messageID) {
          selectedMessageID = messageID
        })
      }
      if (selectedMessageID) {
        selectedCancel()
        $scope.$broadcast('reply_selected', selectedMessageID)
      }
    }

    function selectedEdit (selectedMessageID) {
      if (!selectedMessageID && $scope.selectedCount == 1) {
        angular.forEach($scope.selectedMsgs, function (t, messageID) {
          selectedMessageID = messageID
        })
      }
      if (selectedMessageID) {
        selectedCancel()
        $scope.$broadcast('edit_selected', selectedMessageID)
      }
    }

    function toggleEdit () {
      if ($scope.historyState.selectActions) {
        selectedCancel()
      } else {
        $scope.historyState.selectActions = 'selected'
        $scope.$broadcast('ui_panel_update')
      }
    }

    function toggleMedia (mediaType) {
      if (mediaType == 'search') {
        $rootScope.$broadcast('history_search', $scope.curDialog.peerID)
        return
      }
      $scope.historyFilter.mediaType = mediaType || false
      if (mediaType) {
        $scope.curDialog.messageID = false
      }
      peerHistory.messages = []
      peerHistory.ids = []
      $scope.state.empty = true
      loadHistory()
    }

    function returnToRecent () {
      if ($scope.historyFilter.mediaType) {
        toggleMedia()
      } else {
        if ($scope.curDialog.messageID) {
          $rootScope.$broadcast('history_focus', {peerString: $scope.curDialog.peer})
        } else {
          loadHistory(true)
        }
      }
    }

    $scope.$on('history_update', angular.noop)

    var loadAfterSync = false
    $scope.$on('stateSynchronized', function () {
      if (!loadAfterSync) {
        return
      }
      if (loadAfterSync == $scope.curDialog.peerID) {
        loadHistory()
      }
      loadAfterSync = false
    })

    $scope.$on('reply_button_press', function (e, button) {
      var replyKeyboard = $scope.historyState.replyKeyboard
      if (!replyKeyboard) {
        return
      }
      var sendOptions = {
        replyToMsgID: peerID < 0 && replyKeyboard.mid
      }
      switch (button._) {
        case 'keyboardButtonRequestPhone':
          ErrorService.confirm({type: 'BOT_ACCESS_PHONE'}).then(function () {
            var user = AppUsersManager.getSelf()
            AppMessagesManager.sendOther(peerID, {
              _: 'inputMediaContact',
              phone_number: user.phone,
              first_name: user.first_name,
              last_name: user.last_name
            }, sendOptions)
          })
          break

        case 'keyboardButtonRequestGeoLocation':
          ErrorService.confirm({type: 'BOT_ACCESS_GEO'}).then(function () {
            return GeoLocationManager.getPosition().then(function (coords) {
              AppMessagesManager.sendOther(peerID, {
                _: 'inputMediaGeoPoint',
                geo_point: {
                  _: 'inputGeoPoint',
                  'lat': coords['lat'],
                  'long': coords['long']
                }
              }, sendOptions)
            }, function (error) {
              ErrorService.alert(
                _('error_modal_bad_request_title_raw'),
                _('error_modal_gelocation_na_raw')
              )
            })
          })
          break

        default:
          AppMessagesManager.sendText(peerID, button.text, sendOptions)
      }
    })

    $scope.$on('history_reload', function (e, updPeerID) {
      if (updPeerID == $scope.curDialog.peerID) {
        loadHistory()
      }
    })

    $scope.$on('history_forbidden', function (e, updPeerID) {
      if (updPeerID == $scope.curDialog.peerID) {
        $location.url('/im')
      }
      historiesQueuePop(updPeerID)
    })

    $scope.$on('dialog_migrate', function (e, data) {
      if (data.migrateFrom == $scope.curDialog.peerID) {
        var peerString = AppPeersManager.getPeerString(data.migrateTo)
        $rootScope.$broadcast('history_focus', {peerString: peerString})
      }
      historiesQueuePop(data.migrateFrom)
    })

    $scope.$on('notify_settings', function (e, data) {
      if (data.peerID == $scope.curDialog.peerID) {
        updateChannelActions()
      }
    })

    $scope.$on('channel_settings', function (e, data) {
      if (data.channelID == -$scope.curDialog.peerID) {
        updateChannelActions()
      }
    })

    var typingTimeouts = {}
    $scope.$on('history_append', function (e, addedMessage) {
      var history = historiesQueueFind(addedMessage.peerID)
      if (!history) {
        return
      }
      var curPeer = addedMessage.peerID == $scope.curDialog.peerID
      if (curPeer) {
        if ($scope.historyFilter.mediaType ||
          $scope.historyState.skipped) {
          if (addedMessage.my) {
            returnToRecent()
          } else {
            $scope.historyState.missedCount++
          }
          return
        }
        if ($scope.curDialog.messageID && addedMessage.my) {
          returnToRecent()
        }
        delete $scope.state.empty
      }
      // console.log('append', addedMessage)
      // console.trace()
      var historyMessage = AppMessagesManager.wrapForHistory(addedMessage.messageID)
      history.messages.push(historyMessage)
      history.ids.push(addedMessage.messageID)
      if (AppMessagesManager.regroupWrappedHistory(history.messages, -3)) {
        $scope.$broadcast('messages_regroup')
      }

      if (curPeer) {
        $scope.historyState.typing.splice(0, $scope.historyState.typing.length)
        $scope.$broadcast('ui_history_append_new', {
          my: addedMessage.my,
          idleScroll: unreadAfterIdle && !historyMessage.pFlags.out && $rootScope.idle.isIDLE
        })
        if (addedMessage.my && $scope.historyUnreadAfter) {
          delete $scope.historyUnreadAfter
          $scope.$broadcast('messages_unread_after')
        }

        // console.log('append check', $rootScope.idle.isIDLE, addedMessage.peerID, $scope.curDialog.peerID, historyMessage, history.messages[history.messages.length - 2])
        if ($rootScope.idle.isIDLE) {
          if (historyMessage.pFlags.unread &&
            !historyMessage.pFlags.out &&
            !(history.messages[history.messages.length - 2] || {}).pFlags.unread) {
            $scope.historyUnreadAfter = historyMessage.mid
            unreadAfterIdle = true
            $scope.$broadcast('messages_unread_after')
          }
        } else {
          $timeout(function () {
            AppMessagesManager.readHistory($scope.curDialog.peerID)
          })
        }

        updateBotActions()
        updateChannelActions()
      }
    })

    $scope.$on('history_multiappend', function (e, historyMultiAdded) {
      // console.log(dT(), 'multiappend', angular.copy(historyMultiAdded))
      var regroupped = false
      var unreadAfterChanged = false
      var isIDLE = $rootScope.idle.isIDLE
      angular.forEach(historyMultiAdded, function (msgs, peerID) {
        var history = historiesQueueFind(peerID)
        // var history = historiesQueuePush(peerID)
        if (!history) {
          return
        }
        var curPeer = peerID == $scope.curDialog.peerID
        var exlen = history.messages.length
        var len = msgs.length

        if (curPeer) {
          if ($scope.historyFilter.mediaType ||
            $scope.historyState.skipped) {
            $scope.historyState.missedCount += len
            return
          }
          delete $scope.state.empty
        }

        if ((!curPeer || isIDLE) &&
          exlen > (len > 10 ? 10 : 100)) {
          console.warn(dT(), 'Drop too many messages', len, exlen, isIDLE, curPeer, peerID)
          if (curPeer) {
            minID = history.messages[exlen - 1].mid
            $scope.historyState.skipped = hasLess = minID > 0
            if (hasLess) {
              loadAfterSync = peerID
              $scope.$broadcast('ui_history_append')
            }
          } else {
            historiesQueuePop(peerID)
          }
          return
        }

        var messageID, i
        var hasOut = false
        var unreadAfterNew = false
        var historyMessage = history.messages[history.messages.length - 1]
        var lastIsRead = !historyMessage || !historyMessage.pFlags.unread
        for (i = 0; i < len; i++) {
          messageID = msgs[i]
          if (messageID > 0 && messageID < maxID ||
              history.ids.indexOf(messageID) !== -1) {
            continue
          }
          historyMessage = AppMessagesManager.wrapForHistory(messageID)
          history.messages.push(historyMessage)
          history.ids.push(messageID)
          if (!unreadAfterNew && isIDLE) {
            if (historyMessage.pFlags.unread &&
              !historyMessage.pFlags.out &&
              lastIsRead) {
              unreadAfterNew = messageID
            } else {
              lastIsRead = !historyMessage.pFlags.unread
            }
          }
          if (!hasOut && historyMessage.pFlags.out) {
            hasOut = true
          }
        }
        // console.log('after append', angular.copy(history.messages), angular.copy(history.ids))

        if (AppMessagesManager.regroupWrappedHistory(history.messages, -len - 2)) {
          regroupped = true
        }

        if (curPeer) {
          if ($scope.historyState.typing.length) {
            $scope.historyState.typing.splice(0, $scope.historyState.typing.length)
          }
          $scope.$broadcast('ui_history_append_new', {
            idleScroll: unreadAfterIdle && !hasOut && isIDLE
          })

          if (isIDLE) {
            if (unreadAfterNew) {
              $scope.historyUnreadAfter = unreadAfterNew
              unreadAfterIdle = true
              unreadAfterChanged = true
            }
          } else {
            $timeout(function () {
              AppMessagesManager.readHistory($scope.curDialog.peerID)
            })
          }

          updateBotActions()
          updateChannelActions()
        }
      })

      if (regroupped) {
        $scope.$broadcast('messages_regroup')
      }
      if (unreadAfterChanged) {
        $scope.$broadcast('messages_unread_after')
      }
    })

    $scope.$on('history_delete', function (e, historyUpdate) {
      var history = historiesQueueFind(historyUpdate.peerID)
      if (!history) {
        return
      }
      var newMessages = []
      var i

      for (i = 0; i < history.messages.length; i++) {
        if (!historyUpdate.msgs[history.messages[i].mid]) {
          newMessages.push(history.messages[i])
        }
      }
      history.messages = newMessages
      AppMessagesManager.regroupWrappedHistory(history.messages)
      $scope.$broadcast('messages_regroup')
      if (historyUpdate.peerID == $scope.curDialog.peerID) {
        $scope.state.empty = !newMessages.length
        updateBotActions()
      }
    })

    $scope.$on('dialog_flush', function (e, dialog) {
      var history = historiesQueueFind(dialog.peerID)
      if (history) {
        history.messages = []
        history.ids = []
        if (dialog.peerID == $scope.curDialog.peerID) {
          $scope.state.empty = true
          updateBotActions()
        }
      }
    })

    $scope.$on('history_focus', function (e, peerData) {
      if ($scope.historyFilter.mediaType) {
        toggleMedia()
      }
    })

    $scope.$on('apiUpdate', function (e, update) {
      switch (update._) {
        case 'updateUserTyping':
        case 'updateChatUserTyping':
          AppUsersManager.forceUserOnline(update.user_id)
          if (AppUsersManager.hasUser(update.user_id) &&
            $scope.curDialog.peerID == (update._ == 'updateUserTyping'
              ? update.user_id
              : -update.chat_id
            )) {
            if ($scope.historyState.typing.indexOf(update.user_id) == -1) {
              $scope.historyState.typing.push(update.user_id)
            }
            $timeout.cancel(typingTimeouts[update.user_id])

            typingTimeouts[update.user_id] = $timeout(function () {
              var pos = $scope.historyState.typing.indexOf(update.user_id)
              if (pos !== -1) {
                $scope.historyState.typing.splice(pos, 1)
              }
            }, 6000)
          }
          break
      }
    })

    $scope.$on('history_need_less', showLessHistory)
    $scope.$on('history_need_more', showMoreHistory)

    $rootScope.$watch('idle.isIDLE', function (newVal) {
      if (!newVal &&
          $scope.curDialog &&
          $scope.curDialog.peerID &&
          !$scope.historyFilter.mediaType &&
          !$scope.historyState.skipped) {
        AppMessagesManager.readHistory($scope.curDialog.peerID)
      }
      if (!newVal) {
        unreadAfterIdle = false
        if (loadAfterSync &&
          loadAfterSync == $scope.curDialog.peerID) {
          loadHistory()
          loadAfterSync = false
        }
      }
    })
  })

  .controller('AppImPanelController', function ($scope) {
    $scope.$on('user_update', angular.noop)
  })

  .controller('AppImSendController', function ($rootScope, $q, $scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppStickersManager, AppMessagesManager, AppInlineBotsManager, MtpApiFileManager, DraftsManager, RichTextProcessor) {
    $scope.$watch('curDialog.peer', resetDraft)
    $scope.$on('user_update', angular.noop)
    $scope.$on('peer_draft_attachment', applyDraftAttachment)
    $scope.$on('reply_selected', function (e, messageID) {
      replySelect(messageID, true)
    })
    $scope.$on('edit_selected', function (e, messageID) {
      setEditDraft(messageID, true)
    })

    $scope.$on('ui_typing', onTyping)

    $scope.draftMessage = {
      text: '',
      send: submitMessage,
      replyClear: replyClear,
      fwdsClear: fwdsClear,
      toggleSlash: toggleSlash,
      replyKeyboardToggle: replyKeyboardToggle,
      type: 'new'
    }
    $scope.mentions = {}
    $scope.commands = {}
    $scope.$watch('draftMessage.text', onMessageChange)
    $scope.$watch('draftMessage.files', onFilesSelected)
    $scope.$watch('draftMessage.sticker', onStickerSelected)
    $scope.$watch('draftMessage.command', onCommandSelected)
    $scope.$watch('draftMessage.inlineResultID', onInlineResultSelected)

    $scope.$on('history_reply_markup', function (e, peerData) {
      if (peerData.peerID == $scope.curDialog.peerID) {
        updateReplyKeyboard()
      }
    })

    $scope.$on('inline_bot_select', function (e, botID) {
      var bot = AppUsersManager.getUser(botID)
      $scope.draftMessage.text = '@' + bot.username + ' '
      $scope.$broadcast('ui_peer_draft', {focus: true})
    })

    $scope.$on('inline_bots_popular', updateMentions)

    $scope.$on('last_message_edit', setEditLastMessage)

    $rootScope.$watch('idle.isIDLE', function (newVal) {
      if ($rootScope.idle.initial) {
        return
      }
      if (newVal && $scope.curDialog.peerID) {
        $scope.$broadcast('ui_message_before_send')
        $timeout(function () {
          DraftsManager.syncDraft($scope.curDialog.peerID)
        })
      }
    })

    $scope.$on('draft_updated', function (e, draftUpdate) {
      if (draftUpdate.peerID == $scope.curDialog.peerID &&
          !draftUpdate.local &&
          (!$scope.draftMessage.text || $rootScope.idle.isIDLE)) {
        getDraft()
      }
    })

    var replyToMarkup = false
    var forceDraft = false
    var editMessageID = false

    function submitMessage (e) {
      $scope.$broadcast('ui_message_before_send')

      $timeout(function () {
        if (editMessageID) {
          editMessage()
        } else {
          sendMessage()
        }
      })

      return cancelEvent(e)
    }

    function sendMessage () {
      var text = $scope.draftMessage.text

      if (angular.isString(text) && text.length > 0) {
        text = RichTextProcessor.parseEmojis(text)

        var options = {
          replyToMsgID: $scope.draftMessage.replyToMsgID,
          clearDraft: true
        }
        do {
          AppMessagesManager.sendText($scope.curDialog.peerID, text.substr(0, 4096), options)
          text = text.substr(4096)
          options = angular.copy(options)
          delete options.clearDraft
        } while (text.length)
      }
      fwdsSend()

      if (forceDraft == $scope.curDialog.peer) {
        forceDraft = false
      }

      resetDraft()
      $scope.$broadcast('ui_message_send')
    }

    function editMessage () {
      var text = $scope.draftMessage.text
      text = RichTextProcessor.parseEmojis(text)

      AppMessagesManager.editMessage(editMessageID, text).then(function () {
        editMessageID = false

        resetDraft()
        $scope.$broadcast('ui_message_send')
        $timeout(function () {
          $scope.$broadcast('ui_peer_reply')
        })
      })
    }

    function updateMentions () {
      var peerID = $scope.curDialog.peerID

      if (!peerID) {
        safeReplaceObject($scope.mentions, {})
        $scope.$broadcast('mentions_update')
        return
      }

      var mentionUsers = []
      var mentionIndex = SearchIndexManager.createIndex()

      var inlineBotsPromise = AppInlineBotsManager.getPopularBots().then(function (inlineBots) {
        var ids = []
        angular.forEach(inlineBots, function (bot) {
          ids.push(bot.id)
        })
        return ids
      })
      var chatParticipantsPromise
      if (peerID < 0 && !AppPeersManager.isBroadcast(peerID)) {
        if (AppPeersManager.isChannel(peerID)) {
          chatParticipantsPromise = AppProfileManager.getChannelParticipants(-peerID)
        } else {
          chatParticipantsPromise = AppProfileManager.getChatFull(-peerID).then(function (chatFull) {
            return (chatFull.participants || {}).participants || []
          })
        }
        chatParticipantsPromise = chatParticipantsPromise.then(function (participantsVector) {
          var ids = []
          angular.forEach(participantsVector, function (participant) {
            ids.push(participant.user_id)
          })
          return ids
        })
      } else {
        chatParticipantsPromise = $q.when([])
      }

      $q.all({pop: inlineBotsPromise, chat: chatParticipantsPromise}).then(function (result) {
        var done = {}
        var ids = result.pop.concat(result.chat)
        angular.forEach(ids, function (userID) {
          if (done[userID]) {
            return
          }
          done[userID] = true
          mentionUsers.push(AppUsersManager.getUser(userID))
          SearchIndexManager.indexObject(userID, AppUsersManager.getUserSearchText(userID), mentionIndex)
        })

        safeReplaceObject($scope.mentions, {
          users: mentionUsers,
          index: mentionIndex
        })
        $scope.$broadcast('mentions_update')
      })
    }

    function updateCommands () {
      var peerID = $scope.curDialog.peerID
      if (!peerID) {
        safeReplaceObject($scope.commands, {})
        $scope.$broadcast('mentions_update')
        return
      }

      AppProfileManager.getPeerBots(peerID).then(function (peerBots) {
        if (!peerBots.length) {
          safeReplaceObject($scope.commands, {})
          $scope.$broadcast('mentions_update')
          return
        }

        var needMentions = peerID < 0
        var commandsList = []
        var commandsIndex = SearchIndexManager.createIndex()

        angular.forEach(peerBots, function (peerBot) {
          var mention = ''
          if (needMentions) {
            var bot = AppUsersManager.getUser(peerBot.id)
            if (bot && bot.username) {
              mention += '@' + bot.username
            }
          }
          var botSearchText = AppUsersManager.getUserSearchText(peerBot.id)
          angular.forEach(peerBot.commands, function (description, command) {
            var value = '/' + command + mention
            commandsList.push({
              botID: peerBot.id,
              value: value,
              rDescription: RichTextProcessor.wrapRichText(description, {noLinks: true, noLineBreaks: true})
            })
            SearchIndexManager.indexObject(value, botSearchText + ' ' + command + ' ' + description, commandsIndex)
          })
        })

        safeReplaceObject($scope.commands, {
          list: commandsList,
          index: commandsIndex
        })
        $scope.$broadcast('mentions_update')
      })
    }

    function resetDraft (newPeer, prevPeer) {
      var prevPeerID = prevPeer ? AppPeersManager.getPeerID(prevPeer) : 0
      if (newPeer != prevPeer && prevPeerID) {
        $scope.$broadcast('ui_message_before_send')
        $timeout(function () {
          DraftsManager.syncDraft(prevPeerID)
          resetDraft()
        })
        return
      }

      editMessageID = false

      updateMentions()
      updateCommands()
      replyClear()
      updateReplyKeyboard()

      delete $scope.draftMessage.inlineProgress
      $scope.$broadcast('inline_results', false)

      // console.log(dT(), 'reset draft', $scope.curDialog.peer, forceDraft)
      if (forceDraft) {
        if (forceDraft == $scope.curDialog.peer) {
          $scope.draftMessage.isBroadcast = AppPeersManager.isBroadcast($scope.curDialog.peerID)
          $scope.$broadcast('ui_peer_draft')
          return
        } else {
          forceDraft = false
        }
      }

      fwdsClear()
      getDraft()
    }

    function getDraft () {
      if ($scope.curDialog.peerID) {
        var draftDataPromise
        if (editMessageID) {
          draftDataPromise = AppMessagesManager.getMessageEditData(editMessageID).then(function (draftData) {
            draftData.replyToMsgID = editMessageID
            return draftData
          }, function (error) {
            console.warn(error)
            editMessageID = false
            getDraft()
            return $q.reject()
          })
        } else {
          draftDataPromise = DraftsManager.getDraft($scope.curDialog.peerID)
        }
        draftDataPromise.then(function (draftData) {
          $scope.draftMessage.type = editMessageID ? 'edit' : 'new'
          $scope.draftMessage.text = draftData ? draftData.text : ''
          $scope.draftMessage.isBroadcast = AppPeersManager.isBroadcast($scope.curDialog.peerID)
          if (draftData.replyToMsgID) {
            var replyToMsgID = draftData.replyToMsgID
            replySelect(replyToMsgID)
          } else {
            replyClear()
          }
          $scope.$broadcast('ui_peer_draft')
        })
      } else {
        // console.log('Reset peer')
        $scope.draftMessage.text = ''
        $scope.$broadcast('ui_peer_draft')
      }
    }

    function applyDraftAttachment (e, attachment) {
      console.log(dT(), 'apply draft attach', attachment)
      if (!attachment || !attachment._) {
        return
      }

      if (attachment._ == 'share_url') {
        var url = attachment.url
        var text = attachment.text || ' '
        forceDraft = $scope.curDialog.peer

        $timeout(function () {
          $scope.draftMessage.text = url + '\n' + text
          $scope.$broadcast('ui_peer_draft', {
            customSelection: [
              url + '\n',
              text,
              ''
            ]
          })
        }, 1000)
      } else if (attachment._ == 'fwd_messages') {
        forceDraft = $scope.curDialog.peer
        $timeout(function () {
          $scope.draftMessage.fwdMessages = attachment.id
          $scope.$broadcast('ui_peer_reply')
        }, 100)
      } else if (attachment._ == 'inline_query') {
        var mention = attachment.mention
        var query = attachment.query
        forceDraft = $scope.curDialog.peer

        $timeout(function () {
          $scope.draftMessage.text = mention + ' ' + query
          $scope.$broadcast('ui_peer_draft', {
            customSelection: [
              mention + ' ' + query,
              '',
              ''
            ]
          })
        }, 1000)
      }
    }

    function replySelect (messageID, byUser) {
      if (editMessageID && byUser) {
        replyClear()
        return
      }
      $scope.draftMessage.replyToMsgID = messageID
      $scope.$broadcast('ui_peer_reply')
      replyToMarkup = false

      if (byUser && !editMessageID) {
        DraftsManager.changeDraft($scope.curDialog.peerID, {
          text: $scope.draftMessage.text,
          replyToMsgID: messageID
        })
      }
    }

    function setEditDraft (messageID) {
      editMessageID = messageID
      getDraft()
    }

    function setEditLastMessage () {
      if (editMessageID ||
          !$scope.curDialog.peerID) {
        return false
      }
      AppMessagesManager.getHistory($scope.curDialog.peerID).then(function (historyResult) {
        for (var i = 0, messageID; i < historyResult.history.length; i++) {
          messageID = historyResult.history[i]
          if (AppMessagesManager.canEditMessage(messageID)) {
            setEditDraft(messageID)
            break
          }
        }
      })
    }

    function replyClear (byUser) {
      if (editMessageID) {
        editMessageID = false
        getDraft()
        return
      }
      var mid = $scope.draftMessage.replyToMsgID
      if (mid &&
        $scope.historyState.replyKeyboard &&
        $scope.historyState.replyKeyboard.mid == mid &&
        !$scope.historyState.replyKeyboard.pFlags.hidden) {
        $scope.historyState.replyKeyboard.pFlags.hidden = true
        $scope.$broadcast('ui_keyboard_update')
      }
      delete $scope.draftMessage.replyToMsgID
      $scope.$broadcast('ui_peer_reply')

      if (byUser) {
        DraftsManager.changeDraft($scope.curDialog.peerID, {
          text: $scope.draftMessage.text
        })
      }
    }

    function fwdsClear () {
      if ($scope.draftMessage.fwdMessages &&
        $scope.draftMessage.fwdMessages.length) {
        delete $scope.draftMessage.fwdMessages
        $scope.$broadcast('ui_peer_reply')

        if (forceDraft == $scope.curDialog.peer) {
          forceDraft = false
        }
      }
    }

    function fwdsSend () {
      if ($scope.draftMessage.fwdMessages &&
        $scope.draftMessage.fwdMessages.length) {
        var ids = $scope.draftMessage.fwdMessages.slice()
        fwdsClear()
        setZeroTimeout(function () {
          AppMessagesManager.forwardMessages($scope.curDialog.peerID, ids)
        })
      }
    }

    function toggleSlash ($event) {
      if ($scope.draftMessage.text &&
        $scope.draftMessage.text.charAt(0) == '/') {
        $scope.draftMessage.text = ''
      } else {
        $scope.draftMessage.text = '/'
      }
      $scope.$broadcast('ui_peer_draft', {focus: true})
      return cancelEvent($event)
    }

    function updateReplyKeyboard () {
      var peerID = $scope.curDialog.peerID
      var replyKeyboard = AppMessagesManager.getReplyKeyboard(peerID)
      if (replyKeyboard) {
        replyKeyboard = AppMessagesManager.wrapReplyMarkup(replyKeyboard)
      }
      // console.log('update reply markup', peerID, replyKeyboard)
      $scope.historyState.replyKeyboard = replyKeyboard

      var addReplyMessage =
      replyKeyboard &&
        !replyKeyboard.pFlags.hidden &&
        (replyKeyboard._ == 'replyKeyboardForceReply' ||
        (replyKeyboard._ == 'replyKeyboardMarkup' && peerID < 0))

      if (addReplyMessage) {
        replySelect(replyKeyboard.mid)
        replyToMarkup = true
      } else if (replyToMarkup) {
        replyClear()
      }
      var enabled = replyKeyboard &&
        !replyKeyboard.pFlags.hidden &&
        replyKeyboard._ == 'replyKeyboardMarkup'
      $scope.$broadcast('ui_keyboard_update', {enabled: enabled})
      $scope.$emit('ui_panel_update', {blur: enabled})
    }

    function replyKeyboardToggle ($event) {
      var replyKeyboard = $scope.historyState.replyKeyboard
      if (replyKeyboard) {
        replyKeyboard.pFlags.hidden = !replyKeyboard.pFlags.hidden
        updateReplyKeyboard()
      }
      return cancelEvent($event)
    }

    function onMessageChange (newVal, prevVal, a) {
      // console.log('ctrl text changed', newVal, prevVal);
      if (newVal === '' && prevVal === '') {
        return
      }

      if (newVal && newVal.length) {
        if (!$scope.historyFilter.mediaType && !$scope.historyState.skipped) {
          AppMessagesManager.readHistory($scope.curDialog.peerID)
        }
      }
      if ($scope.curDialog.peerID) {
        if (!editMessageID) {
          var replyToMsgID = $scope.draftMessage.replyToMsgID
          if (replyToMsgID &&
              $scope.historyState.replyKeyboard &&
              $scope.historyState.replyKeyboard.mid == replyToMsgID) {
            replyToMsgID = 0
          }
          DraftsManager.changeDraft($scope.curDialog.peerID, {
            text: newVal,
            replyToMsgID: replyToMsgID
          })
        }
        checkInlinePattern(newVal)
      }
    }

    var inlineUsernameRegex = /^@([a-zA-Z\d_]{1,32})( | )([\s\S]*)$/
    var inlineStickersEmojiRegex = /^\s*:(\S+):\s*$/
    var getInlineResultsTO = false
    var lastInlineBot = false
    var jump = 0

    function checkInlinePattern (message) {
      if (getInlineResultsTO) {
        $timeout.cancel(getInlineResultsTO)
      }
      var curJump = ++jump
      if (!message || !message.length) {
        delete $scope.draftMessage.inlineProgress
        $scope.$broadcast('inline_results', false)
        return
      }
      var matches = message.match(inlineUsernameRegex)
      if (!matches) {
        matches = message.match(inlineStickersEmojiRegex)
        if (matches) {
          var emojiCode = EmojiHelper.shortcuts[matches[1]]
          if (emojiCode) {
            $scope.draftMessage.inlineProgress = true
            AppStickersManager.searchStickers(emojiCode).then(function (docs) {
              var inlineResults = []
              angular.forEach(docs, function (doc) {
                inlineResults.push({
                  _: 'botInlineMediaResult',
                  qID: '_sticker_' + doc.id,
                  pFlags: {sticker: true},
                  id: doc.id,
                  type: 'sticker',
                  document: doc,
                  send_message: {_: 'botInlineMessageMediaAuto'}
                })
              })
              var botResults = {
                pFlags: {gallery: true},
                query_id: 0,
                results: inlineResults
              }
              botResults.text = message
              $scope.$broadcast('inline_results', botResults)
              delete $scope.draftMessage.inlineProgress
            })
          } else {
            delete $scope.draftMessage.inlineProgress
            $scope.$broadcast('inline_results', false)
            return
          }
        }
        delete $scope.draftMessage.inlineProgress
        $scope.$broadcast('inline_results', false)
        return
      }
      var username = matches[1]
      var inlineBotPromise
      $scope.draftMessage.inlineProgress = true
      if (lastInlineBot && lastInlineBot.username == username) {
        inlineBotPromise = $q.when(lastInlineBot)
      } else {
        inlineBotPromise = AppInlineBotsManager.resolveInlineMention(username)
      }
      inlineBotPromise.then(function (inlineBot) {
        if (curJump != jump) {
          return
        }
        lastInlineBot = inlineBot
        $scope.$broadcast('inline_placeholder', {
          prefix: '@' + username + matches[2],
          placeholder: inlineBot.placeholder
        })
        if (getInlineResultsTO) {
          $timeout.cancel(getInlineResultsTO)
        }
        getInlineResultsTO = $timeout(function () {
          var query = RichTextProcessor.parseEmojis(matches[3])
          AppInlineBotsManager.getInlineResults($scope.curDialog.peerID, inlineBot.id, query, inlineBot.geo, '').then(function (botResults) {
            getInlineResultsTO = false
            if (curJump != jump) {
              return
            }
            botResults.text = message
            $scope.$broadcast('inline_results', botResults)
            delete $scope.draftMessage.inlineProgress
          }, function () {
            $scope.$broadcast('inline_results', false)
            delete $scope.draftMessage.inlineProgress
          })
        }, 500)
      }, function (error) {
        $scope.$broadcast('inline_results', false)
        delete $scope.draftMessage.inlineProgress
      })
    }

    function onTyping () {
      if (AppPeersManager.isBroadcast($scope.curDialog.peerID)) {
        return false
      }
      MtpApiManager.invokeApi('messages.setTyping', {
        peer: AppPeersManager.getInputPeerByID($scope.curDialog.peerID),
        action: {_: 'sendMessageTypingAction'}
      })['catch'](function (error) {
        error.handled = true
      })
    }

    function onFilesSelected (newVal) {
      if (!angular.isArray(newVal) || !newVal.length) {
        return
      }
      var options = {
        replyToMsgID: $scope.draftMessage.replyToMsgID,
        isMedia: $scope.draftMessage.isMedia
      }

      delete $scope.draftMessage.replyToMsgID

      if (newVal[0].lastModified) {
        newVal.sort(function (file1, file2) {
          return file1.lastModified - file2.lastModified
        })
      }

      for (var i = 0; i < newVal.length; i++) {
        AppMessagesManager.sendFile($scope.curDialog.peerID, newVal[i], options)
        $scope.$broadcast('ui_message_send')
      }
      fwdsSend()
    }

    function onStickerSelected (newVal) {
      if (!newVal) {
        return
      }

      var doc = AppDocsManager.getDoc(newVal)
      if (doc.id && doc.access_hash) {
        var inputMedia = {
          _: 'inputMediaDocument',
          id: {
            _: 'inputDocument',
            id: doc.id,
            access_hash: doc.access_hash
          }
        }
        var options = {
          replyToMsgID: $scope.draftMessage.replyToMsgID
        }
        AppMessagesManager.sendOther($scope.curDialog.peerID, inputMedia, options)
        $scope.$broadcast('ui_message_send')

        fwdsSend()
        replyClear(true)
      }
      delete $scope.draftMessage.sticker
    }

    function onCommandSelected (command) {
      if (!command) {
        return
      }
      AppMessagesManager.sendText($scope.curDialog.peerID, command, {
        clearDraft: true
      })

      if (forceDraft == $scope.curDialog.peer) {
        forceDraft = false
      }

      fwdsSend()
      resetDraft()
      delete $scope.draftMessage.sticker
      delete $scope.draftMessage.text
      delete $scope.draftMessage.command
      delete $scope.draftMessage.inlineResultID
      $scope.$broadcast('ui_message_send')
      $scope.$broadcast('ui_peer_draft')
    }

    function onInlineResultSelected (qID) {
      if (!qID) {
        return
      }

      if (qID.substr(0, 11) == '_switch_pm_') {
        var botID = lastInlineBot.id
        var startParam = qID.substr(11)
        return AppInlineBotsManager.switchToPM($scope.curDialog.peerID, botID, startParam)
      }

      var options = {
        replyToMsgID: $scope.draftMessage.replyToMsgID,
        clearDraft: true
      }

      if (qID.substr(0, 9) == '_sticker_') {
        var docID = qID.substr(9)
        var doc = AppDocsManager.getDoc(docID)
        if (doc.id && doc.access_hash) {
          var inputMedia = {
            _: 'inputMediaDocument',
            id: {
              _: 'inputDocument',
              id: doc.id,
              access_hash: doc.access_hash
            }
          }
          AppMessagesManager.sendOther($scope.curDialog.peerID, inputMedia, options)
        }
      }
      else {
        AppInlineBotsManager.sendInlineResult($scope.curDialog.peerID, qID, options)
      }


      if (forceDraft == $scope.curDialog.peer) {
        forceDraft = false
      }

      fwdsSend()
      resetDraft()
      delete $scope.draftMessage.sticker
      delete $scope.draftMessage.text
      delete $scope.draftMessage.command
      delete $scope.draftMessage.inlineResultID
      $scope.$broadcast('ui_message_send')
      $scope.$broadcast('ui_peer_draft')
    }
  })

  .controller('AppLangSelectController', function ($scope, _, Storage, ErrorService, AppRuntimeManager) {
    $scope.supportedLocales = Config.I18n.supported
    $scope.langNames = Config.I18n.languages
    $scope.curLocale = Config.I18n.locale
    $scope.form = {locale: Config.I18n.locale}

    $scope.localeSelect = function localeSelect (newLocale) {
      newLocale = newLocale || $scope.form.locale
      if ($scope.curLocale !== newLocale) {
        ErrorService.confirm({type: 'APPLY_LANG_WITH_RELOAD'}).then(function () {
          Storage.set({i18n_locale: newLocale}).then(function () {
            AppRuntimeManager.reload()
          })
        }, function () {
          $scope.form.locale = $scope.curLocale
        })
      }
    }
  })

  .controller('AppFooterController', function ($scope, LayoutSwitchService) {
    $scope.switchLayout = function (mobile) {
      LayoutSwitchService.switchLayout(mobile)
    }
  })

  .controller('PhotoModalController', function ($q, $scope, $rootScope, $modalInstance, AppPhotosManager, AppMessagesManager, AppPeersManager, AppWebPagesManager, PeersSelectService, ErrorService) {
    $scope.photo = AppPhotosManager.wrapForFull($scope.photoID)
    $scope.nav = {}

    $scope.download = function () {
      AppPhotosManager.downloadPhoto($scope.photoID)
    }

    if (!$scope.messageID) {
      return
    }

    $scope.forward = function () {
      var messageID = $scope.messageID

      PeersSelectService.selectPeer({canSend: true}).then(function (peerString) {
        $rootScope.$broadcast('history_focus', {
          peerString: peerString,
          attachment: {
            _: 'fwd_messages',
            id: [messageID]
          }
        })
      })
    }

    $scope.goToMessage = function () {
      var messageID = $scope.messageID
      var peerID = AppMessagesManager.getMessagePeer(AppMessagesManager.getMessage(messageID))
      var peerString = AppPeersManager.getPeerString(peerID)
      $modalInstance.dismiss()
      $rootScope.$broadcast('history_focus', {peerString: peerString, messageID: messageID})
    }

    $scope['delete'] = function () {
      var messageID = $scope.messageID
      ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () {
        AppMessagesManager.deleteMessages([messageID])
      })
    }

    var peerID = AppMessagesManager.getMessagePeer(AppMessagesManager.getMessage($scope.messageID))
    var inputPeer = AppPeersManager.getInputPeerByID(peerID)
    var inputQuery = ''
    var inputFilter = {_: 'inputMessagesFilterPhotos'}
    var list = [$scope.messageID]
    var preloaded = {}
    var maxID = $scope.messageID
    var hasMore = true

    preloaded[$scope.messageID] = true

    updatePrevNext()

    function preloadPhotos (sign) {
      // var preloadOffsets = sign < 0 ? [-1,-2,1,-3,2] : [1,2,-1,3,-2]
      var preloadOffsets = sign < 0 ? [-1, -2] : [1, 2]
      var index = list.indexOf($scope.messageID)
      angular.forEach(preloadOffsets, function (offset) {
        var messageID = list[index + offset]
        if (messageID !== undefined && preloaded[messageID] === undefined) {
          preloaded[messageID] = true
          var message = AppMessagesManager.getMessage(messageID)
          var photoID = message.media.photo.id
          AppPhotosManager.preloadPhoto(photoID)
        }
      })
    }

    function updatePrevNext (count) {
      var index = list.indexOf($scope.messageID)
      if (hasMore) {
        if (count) {
          $scope.count = Math.max(count, list.length)
        }
      } else {
        $scope.count = list.length
      }
      $scope.pos = $scope.count - index
      $scope.nav.hasNext = index > 0
      $scope.nav.hasPrev = hasMore || index < list.length - 1
      $scope.canForward = $scope.canDelete = $scope.messageID > 0
    }

    $scope.nav.next = function () {
      if (!$scope.nav.hasNext) {
        return false
      }

      movePosition(-1)
    }

    $scope.nav.prev = function () {
      if (!$scope.nav.hasPrev) {
        return false
      }
      movePosition(+1)
    }

    $scope.$on('history_delete', function (e, historyUpdate) {
      if (historyUpdate.peerID == peerID) {
        if (historyUpdate.msgs[$scope.messageID]) {
          if ($scope.nav.hasNext) {
            $scope.nav.next()
          } else if ($scope.nav.hasPrev) {
            $scope.nav.prev()
          } else {
            return $modalInstance.dismiss()
          }
        }
        var newList = []
        for (var i = 0; i < list.length; i++) {
          if (!historyUpdate.msgs[list[i]]) {
            newList.push(list[i])
          }
        }
        list = newList
      }
    })

    if ($scope.webpageID) {
      $scope.webpage = AppWebPagesManager.wrapForHistory($scope.webpageID)
      return
    }

    AppMessagesManager.getSearch(peerID, inputQuery, inputFilter, 0, 1000).then(function (searchCachedResult) {
      if (searchCachedResult.history.indexOf($scope.messageID) >= 0) {
        list = searchCachedResult.history
        maxID = list[list.length - 1]

        updatePrevNext()
        preloadPhotos(+1)
      }
      loadMore()
    }, loadMore)

    var jump = 0
    function movePosition (sign) {
      var curIndex = list.indexOf($scope.messageID)
      var index = curIndex >= 0 ? curIndex + sign : 0
      var curJump = ++jump

      var promise = index >= list.length ? loadMore() : $q.when()
      promise.then(function () {
        if (curJump != jump) {
          return
        }

        var messageID = list[index]
        var message = AppMessagesManager.getMessage(messageID)
        var photoID = message && message.media &&
          ((message.media.photo && message.media.photo.id) ||
            (message.media.webpage && message.media.webpage.photo && message.media.webpage.photo.id))
        if (!photoID) {
          console.error('Invalid photo message', index, list, messageID, message)
          return
        }

        $scope.messageID = messageID
        $scope.photoID = photoID
        $scope.photo = AppPhotosManager.wrapForFull($scope.photoID)

        preloaded[$scope.messageID] = true

        updatePrevNext()

        if (sign > 0 && hasMore && list.indexOf(messageID) + 1 >= list.length) {
          loadMore()
        } else {
          preloadPhotos(sign)
        }
      })
    }

    var loadingPromise = false
    function loadMore () {
      if (loadingPromise) return loadingPromise

      return loadingPromise = AppMessagesManager.getSearch(peerID, inputQuery, inputFilter, maxID).then(function (searchResult) {
        if (searchResult.history.length) {
          maxID = searchResult.history[searchResult.history.length - 1]
          list = list.concat(searchResult.history)
          hasMore = list.length < searchResult.count
        } else {
          hasMore = false
        }

        updatePrevNext(searchResult.count)
        loadingPromise = false

        if (searchResult.history.length) {
          return $q.reject()
        }

        preloadPhotos(+1)
      })
    }
  })

  .controller('UserpicModalController', function ($q, $scope, $rootScope, $modalInstance, MtpApiManager, AppPhotosManager, AppUsersManager, AppPeersManager, AppMessagesManager, ApiUpdatesManager, PeersSelectService, ErrorService) {
    $scope.photo = AppPhotosManager.wrapForFull($scope.photoID)
    $scope.photo.thumb = {
      location: AppPhotosManager.choosePhotoSize($scope.photo, 0, 0).location
    }

    $scope.nav = {}
    $scope.canForward = true

    var list = [$scope.photoID]
    var maxID = $scope.photoID
    var preloaded = {}
    var myID = 0
    var hasMore = true

    updatePrevNext()

    AppPhotosManager.getUserPhotos($scope.userID, 0, 1000).then(function (userpicCachedResult) {
      if (userpicCachedResult.photos.indexOf($scope.photoID) >= 0) {
        list = userpicCachedResult.photos
        maxID = list[list.length - 1]
      }
      hasMore = list.length < userpicCachedResult.count
      updatePrevNext()
    })

    MtpApiManager.getUserID().then(function (id) {
      myID = id
      $scope.canDelete = $scope.photo.user_id == myID
    })

    var jump = 0
    function movePosition (sign, deleteCurrent) {
      var curIndex = list.indexOf($scope.photoID)
      var index = curIndex >= 0 ? curIndex + sign : 0
      var curJump = ++jump

      var promise = index >= list.length ? loadMore() : $q.when()
      promise.then(function () {
        if (curJump != jump) {
          return
        }

        $scope.photoID = list[index]
        $scope.photo = AppPhotosManager.wrapForFull($scope.photoID)
        $scope.photo.thumb = {
          location: AppPhotosManager.choosePhotoSize($scope.photo, 0, 0).location
        }

        var newCount
        if (deleteCurrent) {
          list.splice(curIndex, 1)
          newCount = $scope.count - 1
        }

        updatePrevNext(newCount)

        preloaded[$scope.photoID] = true

        updatePrevNext()

        if (sign > 0 && hasMore && list.indexOf($scope.photoID) + 1 >= list.length) {
          loadMore()
        } else {
          preloadPhotos(sign)
        }
      })
    }

    function preloadPhotos (sign) {
      var preloadOffsets = sign < 0 ? [-1, -2] : [1, 2]
      var index = list.indexOf($scope.photoID)
      angular.forEach(preloadOffsets, function (offset) {
        var photoID = list[index + offset]
        if (photoID !== undefined && preloaded[photoID] === undefined) {
          preloaded[photoID] = true
          AppPhotosManager.preloadPhoto(photoID)
        }
      })
    }

    var loadingPromise = false
    function loadMore () {
      if (loadingPromise) return loadingPromise

      return loadingPromise = AppPhotosManager.getUserPhotos($scope.userID, maxID).then(function (userpicResult) {
        if (userpicResult.photos.length) {
          maxID = userpicResult.photos[userpicResult.photos.length - 1]
          list = list.concat(userpicResult.photos)

          hasMore = list.length < userpicResult.count
        } else {
          hasMore = false
        }

        updatePrevNext(userpicResult.count)
        loadingPromise = false

        if (userpicResult.photos.length) {
          return $q.reject()
        }

        preloadPhotos(+1)
      })
    }

    function updatePrevNext (count) {
      var index = list.indexOf($scope.photoID)
      if (hasMore) {
        if (count) {
          $scope.count = Math.max(count, list.length)
        }
      } else {
        $scope.count = list.length
      }
      $scope.pos = $scope.count - index
      $scope.nav.hasNext = index > 0
      $scope.nav.hasPrev = hasMore || index < list.length - 1
      $scope.canDelete = $scope.photo.user_id == myID
    }

    $scope.nav.next = function () {
      if (!$scope.nav.hasNext) {
        return false
      }

      movePosition(-1)
    }

    $scope.nav.prev = function () {
      if (!$scope.nav.hasPrev) {
        return false
      }
      movePosition(+1)
    }

    $scope.forward = function () {
      PeersSelectService.selectPeer({confirm_type: 'FORWARD_PEER', canSend: true}).then(function (peerString) {
        var peerID = AppPeersManager.getPeerID(peerString)
        AppMessagesManager.sendOther(peerID, {
          _: 'inputMediaPhoto',
          id: {
            _: 'inputPhoto',
            id: $scope.photoID,
            access_hash: $scope.photo.access_hash
          }
        })
        $rootScope.$broadcast('history_focus', {peerString: peerString})
      })
    }

    $scope['delete'] = function () {
      var photoID = $scope.photoID
      var myUser = AppUsersManager.getUser(myID)
      var onDeleted = function () {
        if (!$scope.nav.hasNext && !$scope.nav.hasPrev) {
          return $modalInstance.dismiss()
        }
        movePosition($scope.nav.hasNext ? -1 : +1, true)
      }

      ErrorService.confirm({type: 'PHOTO_DELETE'}).then(function () {
        if (myUser && myUser.photo && myUser.photo.photo_id == photoID) {
          MtpApiManager.invokeApi('photos.updateProfilePhoto', {
            id: {_: 'inputPhotoEmpty'}
          }).then(function (updateResult) {
            ApiUpdatesManager.processUpdateMessage({
              _: 'updateShort',
              update: {
                _: 'updateUserPhoto',
                user_id: myID,
                date: tsNow(true),
                photo: updateResult,
                previous: true
              }
            })
            onDeleted()
          })
        } else {
          MtpApiManager.invokeApi('photos.deletePhotos', {
            id: [{_: 'inputPhoto', id: photoID, access_hash: 0}]
          }).then(onDeleted)
        }
      })
    }

    $scope.download = function () {
      AppPhotosManager.downloadPhoto($scope.photoID)
    }
  })

  .controller('ChatpicModalController', function ($q, $scope, $rootScope, $modalInstance, MtpApiManager, AppPhotosManager, AppChatsManager, AppPeersManager, AppMessagesManager, ApiUpdatesManager, PeersSelectService, ErrorService) {
    $scope.photo = AppPhotosManager.wrapForFull($scope.photoID)
    $scope.photo.thumb = {
      location: AppPhotosManager.choosePhotoSize($scope.photo, 0, 0).location
    }

    var chat = AppChatsManager.getChat($scope.chatID)
    var isChannel = AppChatsManager.isChannel($scope.chatID)

    $scope.canForward = true
    $scope.canDelete = isChannel ? chat.pFlags.creator : true

    $scope.forward = function () {
      PeersSelectService.selectPeer({confirm_type: 'FORWARD_PEER', canSend: true}).then(function (peerString) {
        var peerID = AppPeersManager.getPeerID(peerString)
        AppMessagesManager.sendOther(peerID, {
          _: 'inputMediaPhoto',
          id: {
            _: 'inputPhoto',
            id: $scope.photoID,
            access_hash: $scope.photo.access_hash
          }
        })
        $rootScope.$broadcast('history_focus', {peerString: peerString})
      })
    }

    $scope['delete'] = function () {
      ErrorService.confirm({type: 'PHOTO_DELETE'}).then(function () {
        $scope.photo.updating = true
        var apiPromise
        if (AppChatsManager.isChannel($scope.chatID)) {
          apiPromise = MtpApiManager.invokeApi('channels.editPhoto', {
            channel: AppChatsManager.getChannelInput($scope.chatID),
            photo: {_: 'inputChatPhotoEmpty'}
          })
        } else {
          apiPromise = MtpApiManager.invokeApi('messages.editChatPhoto', {
            chat_id: AppChatsManager.getChatInput($scope.chatID),
            photo: {_: 'inputChatPhotoEmpty'}
          })
        }
        apiPromise.then(function (updates) {
          ApiUpdatesManager.processUpdateMessage(updates)
          $modalInstance.dismiss()
          $rootScope.$broadcast('history_focus', {peerString: AppChatsManager.getChatString($scope.chatID)})
        })['finally'](function () {
          $scope.photo.updating = false
        })
      })
    }

    $scope.download = function () {
      AppPhotosManager.downloadPhoto($scope.photoID)
    }
  })

  .controller('VideoModalController', function ($scope, $rootScope, $modalInstance, PeersSelectService, AppMessagesManager, AppDocsManager, AppPeersManager, ErrorService) {
    $scope.video = AppDocsManager.wrapVideoForFull($scope.docID)

    $scope.progress = {enabled: false}
    $scope.player = {}

    $scope.forward = function () {
      var messageID = $scope.messageID
      PeersSelectService.selectPeer({canSend: true}).then(function (peerString) {
        $rootScope.$broadcast('history_focus', {
          peerString: peerString,
          attachment: {
            _: 'fwd_messages',
            id: [messageID]
          }
        })
      })
    }

    $scope['delete'] = function () {
      var messageID = $scope.messageID
      ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () {
        AppMessagesManager.deleteMessages([messageID])
      })
    }

    $scope.download = function () {
      AppDocsManager.saveDocFile($scope.docID)
    }

    $scope.$on('history_delete', function (e, historyUpdate) {
      if (historyUpdate && historyUpdate.msgs && historyUpdate.msgs[$scope.messageID]) {
        $modalInstance.dismiss()
      }
    })
  })

  .controller('DocumentModalController', function ($scope, $rootScope, $modalInstance, PeersSelectService, AppMessagesManager, AppDocsManager, AppPeersManager, ErrorService) {
    $scope.document = AppDocsManager.wrapForHistory($scope.docID)

    $scope.forward = function () {
      var messageID = $scope.messageID
      PeersSelectService.selectPeer({canSend: true}).then(function (peerString) {
        $rootScope.$broadcast('history_focus', {
          peerString: peerString,
          attachment: {
            _: 'fwd_messages',
            id: [messageID]
          }
        })
      })
    }

    $scope['delete'] = function () {
      var messageID = $scope.messageID
      ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () {
        AppMessagesManager.deleteMessages([messageID])
      })
    }

    $scope.download = function () {
      AppDocsManager.saveDocFile($scope.docID)
    }

    $scope.$on('history_delete', function (e, historyUpdate) {
      if (historyUpdate && historyUpdate.msgs && historyUpdate.msgs[$scope.messageID]) {
        $modalInstance.dismiss()
      }
    })
  })

  .controller('EmbedModalController', function ($q, $scope, $rootScope, $modalInstance, AppPhotosManager, AppMessagesManager, AppPeersManager, AppWebPagesManager, PeersSelectService, ErrorService) {
    $scope.webpage = AppWebPagesManager.wrapForFull($scope.webpageID)

    $scope.nav = {}

    $scope.forward = function () {
      var messageID = $scope.messageID
      PeersSelectService.selectPeer({canSend: true}).then(function (peerString) {
        $rootScope.$broadcast('history_focus', {
          peerString: peerString,
          attachment: {
            _: 'fwd_messages',
            id: [messageID]
          }
        })
      })
    }

    $scope['delete'] = function () {
      var messageID = $scope.messageID
      ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () {
        AppMessagesManager.deleteMessages([messageID])
      })
    }
  })

  .controller('GameModalController', function ($q, $scope, $rootScope, $modalInstance, AppPhotosManager, AppMessagesManager, AppPeersManager, AppGamesManager, PeersSelectService, ErrorService) {
    $scope.game = AppGamesManager.wrapForFull($scope.gameID, $scope.messageID, $scope.embedUrl)
    var messageID = $scope.messageID

    var message = AppMessagesManager.getMessage(messageID)
    $scope.botID = message.viaBotID || message.fromID

    $scope.nav = {}

    $scope.forward = function (withMyScore) {
      PeersSelectService.selectPeer({canSend: true, confirm_type: 'INVITE_TO_GAME'}).then(function (peerString) {
        var peerID = AppPeersManager.getPeerID(peerString)
        AppMessagesManager.forwardMessages(peerID, [messageID], {
          withMyScore: withMyScore
        }).then(function () {
          $rootScope.$broadcast('history_focus', {
            peerString: peerString
          })
        })
      })
    }

    $scope.$on('game_frame_event', function (e, eventData) {
      if (eventData.eventType == 'share_score') {
        $scope.forward(true)
      }
    })
  })

  .controller('UserModalController', function ($scope, $location, $rootScope, $modalInstance, AppProfileManager, $modal, AppUsersManager, MtpApiManager, NotificationsManager, AppPhotosManager, AppMessagesManager, AppPeersManager, PeersSelectService, ErrorService) {
    var peerString = AppUsersManager.getUserString($scope.userID)

    $scope.user = AppUsersManager.getUser($scope.userID)
    $scope.blocked = false

    $scope.settings = {notifications: true}

    var profilePromise = AppProfileManager.getProfile($scope.userID, $scope.override)

    profilePromise.then(function (userFull) {
      $scope.blocked = userFull.pFlags.blocked
      $scope.bot_info = userFull.bot_info
      $scope.rAbout = userFull.rAbout

      NotificationsManager.getPeerMuted($scope.userID).then(function (muted) {
        $scope.settings.notifications = !muted

        $scope.$watch('settings.notifications', function (newValue, oldValue) {
          if (newValue === oldValue) {
            return false
          }
          NotificationsManager.getPeerSettings($scope.userID).then(function (settings) {
            settings.mute_until = newValue ? 0 : 2000000000
            NotificationsManager.updatePeerSettings($scope.userID, settings)
          })
        })
      })
    })

    $scope.goToHistory = function () {
      $rootScope.$broadcast('history_focus', {peerString: peerString})
    }

    $scope.openUserPic = function () {
      profilePromise.then(function () {
        $scope.openPhoto($scope.user.photo.photo_id, {p: $scope.userID})
      })
    }

    $scope.flushHistory = function (justClear) {
      ErrorService.confirm({type: justClear ? 'HISTORY_FLUSH' : 'HISTORY_FLUSH_AND_DELETE'}).then(function () {
        AppMessagesManager.flushHistory($scope.userID, justClear).then(function () {
          if (justClear) {
            $scope.goToHistory()
          } else {
            $modalInstance.close()
            $location.url('/im')
          }
        })
      })
    }

    $scope.importContact = function (edit) {
      var scope = $rootScope.$new()
      scope.importContact = {
        phone: $scope.user.phone,
        first_name: $scope.user.first_name,
        last_name: $scope.user.last_name
      }

      $modal.open({
        templateUrl: templateUrl(edit ? 'edit_contact_modal' : 'import_contact_modal'),
        controller: 'ImportContactModalController',
        windowClass: 'md_simple_modal_window mobile_modal',
        scope: scope
      }).result.then(function (foundUserID) {
        if ($scope.userID == foundUserID) {
          $scope.user = AppUsersManager.getUser($scope.userID)
        }
      })
    }

    $scope.deleteContact = function () {
      AppUsersManager.deleteContacts([$scope.userID]).then(function () {
        $scope.user = AppUsersManager.getUser($scope.userID)
      })
    }

    $scope.inviteToGroup = function () {
      PeersSelectService.selectPeer({
        confirm_type: 'INVITE_TO_GROUP',
        noUsers: true
      }).then(function (peerString) {
        var peerID = AppPeersManager.getPeerID(peerString)
        var chatID = peerID < 0 ? -peerID : 0
        AppMessagesManager.startBot($scope.user.id, chatID).then(function () {
          $rootScope.$broadcast('history_focus', {peerString: peerString})
        })
      })
    }

    $scope.sendCommand = function (command) {
      AppMessagesManager.sendText($scope.userID, '/' + command)
      $rootScope.$broadcast('history_focus', {
        peerString: peerString
      })
    }

    $scope.toggleBlock = function (block) {
      MtpApiManager.invokeApi(block ? 'contacts.block' : 'contacts.unblock', {
        id: AppUsersManager.getUserInput($scope.userID)
      }).then(function () {
        $scope.blocked = block
      })
    }

    $scope.shareContact = function () {
      PeersSelectService.selectPeer({confirm_type: 'SHARE_CONTACT_PEER', canSend: true}).then(function (peerString) {
        var peerID = AppPeersManager.getPeerID(peerString)
        AppMessagesManager.sendOther(peerID, {
          _: 'inputMediaContact',
          phone_number: $scope.user.phone,
          first_name: $scope.user.first_name,
          last_name: $scope.user.last_name,
          user_id: $scope.user.id
        })
        $rootScope.$broadcast('history_focus', {peerString: peerString})
      })
    }
  })

  .controller('ChatModalController', function ($scope, $modalInstance, $location, $timeout, $rootScope, $modal, AppUsersManager, AppChatsManager, AppProfileManager, AppPhotosManager, MtpApiManager, MtpApiFileManager, NotificationsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, ContactsSelectService, ErrorService) {
    $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, {})
    $scope.settings = {notifications: true}

    $scope.maxParticipants = 200

    AppProfileManager.getChatFull($scope.chatID).then(function (chatFull) {
      $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, chatFull)
      $scope.$broadcast('ui_height')

      $scope.needMigrate = $scope.chatFull &&
        $scope.chatFull.participants &&
        $scope.chatFull.participants.participants &&
        $scope.chatFull.participants.participants.length >= 200

      if (Config.Modes.test || Config.Modes.debug) {
        $scope.needMigrate = true
      }

      NotificationsManager.getPeerMuted(-$scope.chatID).then(function (muted) {
        $scope.settings.notifications = !muted

        $scope.$watch('settings.notifications', function (newValue, oldValue) {
          if (newValue === oldValue) {
            return false
          }
          NotificationsManager.getPeerSettings(-$scope.chatID).then(function (settings) {
            if (newValue) {
              settings.mute_until = 0
            } else {
              settings.mute_until = 2000000000
            }
            NotificationsManager.updatePeerSettings(-$scope.chatID, settings)
          })
        })
      })
    })

    function onChatUpdated (updates) {
      ApiUpdatesManager.processUpdateMessage(updates)
      $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString})
    }

    $scope.leaveGroup = function () {
      ErrorService.confirm({type: 'HISTORY_LEAVE_AND_FLUSH'}).then(function () {
        MtpApiManager.invokeApi('messages.deleteChatUser', {
          chat_id: AppChatsManager.getChatInput($scope.chatID),
          user_id: {_: 'inputUserSelf'}
        }).then(function (updates) {
          ApiUpdatesManager.processUpdateMessage(updates)
          AppMessagesManager.flushHistory(-$scope.chatID).then(function () {
            $modalInstance.close()
            $location.url('/im')
          })
        })
      })
    }

    $scope.inviteToGroup = function () {
      var disabled = []
      angular.forEach($scope.chatFull.participants.participants, function (participant) {
        disabled.push(participant.user_id)
      })

      ContactsSelectService.selectContacts({disabled: disabled}).then(function (userIDs) {
        angular.forEach(userIDs, function (userID) {
          MtpApiManager.invokeApi('messages.addChatUser', {
            chat_id: AppChatsManager.getChatInput($scope.chatID),
            user_id: AppUsersManager.getUserInput(userID),
            fwd_limit: 100
          }).then(function (updates) {
            ApiUpdatesManager.processUpdateMessage(updates)
          })
        })

        $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString})
      })
    }

    $scope.migrateToSuperGroup = function () {
      ErrorService.confirm({type: 'SUPERGROUP_MIGRATE'}).then(function () {
        MtpApiManager.invokeApi('messages.migrateChat', {
          chat_id: AppChatsManager.getChatInput($scope.chatID)
        }).then(onChatUpdated)
      })
    }

    $scope.kickFromGroup = function (userID) {
      MtpApiManager.invokeApi('messages.deleteChatUser', {
        chat_id: AppChatsManager.getChatInput($scope.chatID),
        user_id: AppUsersManager.getUserInput(userID)
      }).then(onChatUpdated)
    }

    $scope.flushHistory = function (justClear) {
      ErrorService.confirm({type: justClear ? 'HISTORY_FLUSH' : 'HISTORY_FLUSH_AND_DELETE'}).then(function () {
        AppMessagesManager.flushHistory(-$scope.chatID, justClear).then(function () {
          if (justClear) {
            $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString})
          } else {
            $modalInstance.close()
            $location.url('/im')
          }
        })
      })
    }

    $scope.inviteViaLink = function () {
      var scope = $rootScope.$new()
      scope.chatID = $scope.chatID

      $modal.open({
        templateUrl: templateUrl('chat_invite_link_modal'),
        controller: 'ChatInviteLinkModalController',
        scope: scope,
        windowClass: 'md_simple_modal_window'
      })
    }

    $scope.photo = {}

    $scope.$watch('photo.file', onPhotoSelected)

    function onPhotoSelected (photo) {
      if (!photo || !photo.type || photo.type.indexOf('image') !== 0) {
        return
      }
      $scope.photo.updating = true
      MtpApiFileManager.uploadFile(photo).then(function (inputFile) {
        return MtpApiManager.invokeApi('messages.editChatPhoto', {
          chat_id: AppChatsManager.getChatInput($scope.chatID),
          photo: {
            _: 'inputChatUploadedPhoto',
            file: inputFile
          }
        }).then(onChatUpdated)
      })['finally'](function () {
        $scope.photo.updating = false
      })
    }

    $scope.deletePhoto = function () {
      $scope.photo.updating = true
      MtpApiManager.invokeApi('messages.editChatPhoto', {
        chat_id: AppChatsManager.getChatInput($scope.chatID),
        photo: {_: 'inputChatPhotoEmpty'}
      }).then(onChatUpdated)['finally'](function () {
        $scope.photo.updating = false
      })
    }

    $scope.editTitle = function () {
      var scope = $rootScope.$new()
      scope.chatID = $scope.chatID

      $modal.open({
        templateUrl: templateUrl('chat_edit_modal'),
        controller: 'ChatEditModalController',
        scope: scope,
        windowClass: 'md_simple_modal_window mobile_modal'
      })
    }

    $scope.hasRights = function (action) {
      return AppChatsManager.hasRights($scope.chatID, action)
    }
  })

  .controller('ChannelModalController', function ($scope, $timeout, $rootScope, $modal, AppUsersManager, AppChatsManager, AppProfileManager, AppPhotosManager, MtpApiManager, MtpApiFileManager, NotificationsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, ContactsSelectService, ErrorService) {
    $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, {})
    $scope.settings = {notifications: true}
    $scope.isMegagroup = AppChatsManager.isMegagroup($scope.chatID)

    AppProfileManager.getChannelFull($scope.chatID, true).then(function (chatFull) {
      $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, chatFull)
      $scope.$broadcast('ui_height')

      NotificationsManager.getPeerMuted(-$scope.chatID).then(function (muted) {
        $scope.settings.notifications = !muted

        $scope.$watch('settings.notifications', function (newValue, oldValue) {
          if (newValue === oldValue) {
            return false
          }
          NotificationsManager.getPeerSettings(-$scope.chatID).then(function (settings) {
            if (newValue) {
              settings.mute_until = 0
            } else {
              settings.mute_until = 2000000000
            }
            NotificationsManager.updatePeerSettings(-$scope.chatID, settings)
          })
        })
      })

      if ($scope.chatFull.chat &&
        $scope.chatFull.chat.pFlags.creator &&
        $scope.chatFull.exported_invite &&
        $scope.chatFull.exported_invite._ == 'chatInviteEmpty') {
        AppProfileManager.getChatInviteLink($scope.chatID, true).then(function (link) {
          $scope.chatFull.exported_invite = {_: 'chatInviteExported', link: link}
        })
      }
    })

    AppProfileManager.getChannelParticipants($scope.chatID).then(function (participants) {
      $scope.participants = AppChatsManager.wrapParticipants($scope.chatID, participants)
      $scope.$broadcast('ui_height')
 
Download .txt
gitextract_xpysw2_p/

├── .dockerignore
├── .gitignore
├── .tx/
│   └── config
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── app/
│   ├── badbrowser.html
│   ├── index.html
│   ├── js/
│   │   ├── app.js
│   │   ├── background.js
│   │   ├── controllers.js
│   │   ├── directives.js
│   │   ├── directives_mobile.js
│   │   ├── filters.js
│   │   ├── init.js
│   │   ├── lib/
│   │   │   ├── bin_utils.js
│   │   │   ├── config.js
│   │   │   ├── crypto_worker.js
│   │   │   ├── i18n.js
│   │   │   ├── mtproto.js
│   │   │   ├── mtproto_wrapper.js
│   │   │   ├── ng_utils.js
│   │   │   ├── polyfill.js
│   │   │   ├── push_worker.js
│   │   │   ├── schema.tl
│   │   │   ├── tl_utils.js
│   │   │   └── utils.js
│   │   ├── locales/
│   │   │   ├── README.md
│   │   │   ├── de-de.json
│   │   │   ├── en-us.json
│   │   │   ├── es-es.json
│   │   │   ├── it-it.json
│   │   │   ├── nl-nl.json
│   │   │   ├── pt-br.json
│   │   │   └── ru-ru.json
│   │   ├── message_composer.js
│   │   ├── messages_manager.js
│   │   ├── offline_manager.js
│   │   └── services.js
│   ├── less/
│   │   ├── app.less
│   │   ├── desktop.less
│   │   ├── font.less
│   │   ├── lib/
│   │   │   └── mixins.less
│   │   └── mobile.less
│   ├── manifest.json
│   ├── manifest.webapp
│   ├── manifest.webapp.json
│   ├── nacl/
│   │   ├── Makefile
│   │   ├── aes.h
│   │   ├── aes_core.c
│   │   ├── aes_ige.c
│   │   ├── aes_locl.h
│   │   ├── aes_misc.c
│   │   ├── mtproto_crypto.bc
│   │   ├── mtproto_crypto.cc
│   │   ├── mtproto_crypto.nmf
│   │   └── mtproto_crypto.pexe
│   ├── partials/
│   │   ├── desktop/
│   │   │   ├── audio_player.html
│   │   │   ├── changelog_modal.html
│   │   │   ├── channel_edit_modal.html
│   │   │   ├── channel_modal.html
│   │   │   ├── chat_create_modal.html
│   │   │   ├── chat_edit_modal.html
│   │   │   ├── chat_invite_link_modal.html
│   │   │   ├── chat_modal.html
│   │   │   ├── composer_dropdown.html
│   │   │   ├── confirm_modal.html
│   │   │   ├── contacts_modal.html
│   │   │   ├── country_select_modal.html
│   │   │   ├── dialog.html
│   │   │   ├── document_modal.html
│   │   │   ├── edit_contact_modal.html
│   │   │   ├── embed_modal.html
│   │   │   ├── emoji_btn_tooltip.html
│   │   │   ├── error_modal.html
│   │   │   ├── footer.html
│   │   │   ├── forwarded_messages.html
│   │   │   ├── full_document.html
│   │   │   ├── full_gif.html
│   │   │   ├── full_photo.html
│   │   │   ├── full_round.html
│   │   │   ├── full_video.html
│   │   │   ├── game_modal.html
│   │   │   ├── head.html
│   │   │   ├── im.html
│   │   │   ├── import_contact_modal.html
│   │   │   ├── inactive.html
│   │   │   ├── inline_results.html
│   │   │   ├── lang_footer.html
│   │   │   ├── login.html
│   │   │   ├── media_modal_layout.html
│   │   │   ├── megagroup_edit_modal.html
│   │   │   ├── message.html
│   │   │   ├── message_attach_contact.html
│   │   │   ├── message_attach_document.html
│   │   │   ├── message_attach_game.html
│   │   │   ├── message_attach_geo.html
│   │   │   ├── message_attach_pending.html
│   │   │   ├── message_attach_photo.html
│   │   │   ├── message_attach_venue.html
│   │   │   ├── message_attach_webpage.html
│   │   │   ├── message_media.html
│   │   │   ├── message_service.html
│   │   │   ├── password_recovery_modal.html
│   │   │   ├── password_update_modal.html
│   │   │   ├── peer_pinned_message_bar.html
│   │   │   ├── peer_select.html
│   │   │   ├── photo_modal.html
│   │   │   ├── pinned_message.html
│   │   │   ├── profile_edit_modal.html
│   │   │   ├── reply_markup.html
│   │   │   ├── reply_message.html
│   │   │   ├── report_msgs_modal.html
│   │   │   ├── send_form.html
│   │   │   ├── sessions_list_modal.html
│   │   │   ├── settings_modal.html
│   │   │   ├── short_message.html
│   │   │   ├── slider.html
│   │   │   ├── stickerset_modal.html
│   │   │   ├── user_modal.html
│   │   │   ├── username_edit_modal.html
│   │   │   └── video_modal.html
│   │   └── mobile/
│   │       ├── audio_player.html
│   │       ├── changelog_modal.html
│   │       ├── channel_modal.html
│   │       ├── chat_create_modal.html
│   │       ├── chat_edit_modal.html
│   │       ├── chat_modal.html
│   │       ├── contacts_modal.html
│   │       ├── country_select_modal.html
│   │       ├── dialog.html
│   │       ├── edit_contact_modal.html
│   │       ├── full_gif.html
│   │       ├── full_photo.html
│   │       ├── full_video.html
│   │       ├── game_modal.html
│   │       ├── head.html
│   │       ├── im.html
│   │       ├── import_contact_modal.html
│   │       ├── login.html
│   │       ├── message.html
│   │       ├── message_actions_modal.html
│   │       ├── message_attach_contact.html
│   │       ├── message_attach_document.html
│   │       ├── message_attach_geo.html
│   │       ├── message_attach_pending.html
│   │       ├── message_attach_photo.html
│   │       ├── message_attach_venue.html
│   │       ├── message_attach_webpage.html
│   │       ├── message_service.html
│   │       ├── password_recovery_modal.html
│   │       ├── password_update_modal.html
│   │       ├── peer_select.html
│   │       ├── phonebook_modal.html
│   │       ├── photo_modal.html
│   │       ├── profile_edit_modal.html
│   │       ├── send_form.html
│   │       ├── sessions_list_modal.html
│   │       ├── settings_modal.html
│   │       ├── stickerset_modal.html
│   │       ├── user_modal.html
│   │       ├── username_edit_modal.html
│   │       └── video_modal.html
│   ├── service_worker.js
│   ├── vendor/
│   │   ├── README.md
│   │   ├── angular/
│   │   │   ├── angular-animate.js
│   │   │   ├── angular-aria.js
│   │   │   ├── angular-cookies.js
│   │   │   ├── angular-csp.css
│   │   │   ├── angular-loader.js
│   │   │   ├── angular-message-format.js
│   │   │   ├── angular-messages.js
│   │   │   ├── angular-mocks.js
│   │   │   ├── angular-parse-ext.js
│   │   │   ├── angular-resource.js
│   │   │   ├── angular-route.js
│   │   │   ├── angular-sanitize.js
│   │   │   ├── angular-touch.js
│   │   │   ├── angular.js
│   │   │   ├── errors.json
│   │   │   ├── i18n/
│   │   │   │   ├── angular-locale_af-na.js
│   │   │   │   ├── angular-locale_af-za.js
│   │   │   │   ├── angular-locale_af.js
│   │   │   │   ├── angular-locale_agq-cm.js
│   │   │   │   ├── angular-locale_agq.js
│   │   │   │   ├── angular-locale_ak-gh.js
│   │   │   │   ├── angular-locale_ak.js
│   │   │   │   ├── angular-locale_am-et.js
│   │   │   │   ├── angular-locale_am.js
│   │   │   │   ├── angular-locale_ar-001.js
│   │   │   │   ├── angular-locale_ar-ae.js
│   │   │   │   ├── angular-locale_ar-bh.js
│   │   │   │   ├── angular-locale_ar-dj.js
│   │   │   │   ├── angular-locale_ar-dz.js
│   │   │   │   ├── angular-locale_ar-eg.js
│   │   │   │   ├── angular-locale_ar-eh.js
│   │   │   │   ├── angular-locale_ar-er.js
│   │   │   │   ├── angular-locale_ar-il.js
│   │   │   │   ├── angular-locale_ar-iq.js
│   │   │   │   ├── angular-locale_ar-jo.js
│   │   │   │   ├── angular-locale_ar-km.js
│   │   │   │   ├── angular-locale_ar-kw.js
│   │   │   │   ├── angular-locale_ar-lb.js
│   │   │   │   ├── angular-locale_ar-ly.js
│   │   │   │   ├── angular-locale_ar-ma.js
│   │   │   │   ├── angular-locale_ar-mr.js
│   │   │   │   ├── angular-locale_ar-om.js
│   │   │   │   ├── angular-locale_ar-ps.js
│   │   │   │   ├── angular-locale_ar-qa.js
│   │   │   │   ├── angular-locale_ar-sa.js
│   │   │   │   ├── angular-locale_ar-sd.js
│   │   │   │   ├── angular-locale_ar-so.js
│   │   │   │   ├── angular-locale_ar-ss.js
│   │   │   │   ├── angular-locale_ar-sy.js
│   │   │   │   ├── angular-locale_ar-td.js
│   │   │   │   ├── angular-locale_ar-tn.js
│   │   │   │   ├── angular-locale_ar-xb.js
│   │   │   │   ├── angular-locale_ar-ye.js
│   │   │   │   ├── angular-locale_ar.js
│   │   │   │   ├── angular-locale_as-in.js
│   │   │   │   ├── angular-locale_as.js
│   │   │   │   ├── angular-locale_asa-tz.js
│   │   │   │   ├── angular-locale_asa.js
│   │   │   │   ├── angular-locale_ast-es.js
│   │   │   │   ├── angular-locale_ast.js
│   │   │   │   ├── angular-locale_az-cyrl-az.js
│   │   │   │   ├── angular-locale_az-cyrl.js
│   │   │   │   ├── angular-locale_az-latn-az.js
│   │   │   │   ├── angular-locale_az-latn.js
│   │   │   │   ├── angular-locale_az.js
│   │   │   │   ├── angular-locale_bas-cm.js
│   │   │   │   ├── angular-locale_bas.js
│   │   │   │   ├── angular-locale_be-by.js
│   │   │   │   ├── angular-locale_be.js
│   │   │   │   ├── angular-locale_bem-zm.js
│   │   │   │   ├── angular-locale_bem.js
│   │   │   │   ├── angular-locale_bez-tz.js
│   │   │   │   ├── angular-locale_bez.js
│   │   │   │   ├── angular-locale_bg-bg.js
│   │   │   │   ├── angular-locale_bg.js
│   │   │   │   ├── angular-locale_bm-ml.js
│   │   │   │   ├── angular-locale_bm.js
│   │   │   │   ├── angular-locale_bn-bd.js
│   │   │   │   ├── angular-locale_bn-in.js
│   │   │   │   ├── angular-locale_bn.js
│   │   │   │   ├── angular-locale_bo-cn.js
│   │   │   │   ├── angular-locale_bo-in.js
│   │   │   │   ├── angular-locale_bo.js
│   │   │   │   ├── angular-locale_br-fr.js
│   │   │   │   ├── angular-locale_br.js
│   │   │   │   ├── angular-locale_brx-in.js
│   │   │   │   ├── angular-locale_brx.js
│   │   │   │   ├── angular-locale_bs-cyrl-ba.js
│   │   │   │   ├── angular-locale_bs-cyrl.js
│   │   │   │   ├── angular-locale_bs-latn-ba.js
│   │   │   │   ├── angular-locale_bs-latn.js
│   │   │   │   ├── angular-locale_bs.js
│   │   │   │   ├── angular-locale_ca-ad.js
│   │   │   │   ├── angular-locale_ca-es-valencia.js
│   │   │   │   ├── angular-locale_ca-es.js
│   │   │   │   ├── angular-locale_ca-fr.js
│   │   │   │   ├── angular-locale_ca-it.js
│   │   │   │   ├── angular-locale_ca.js
│   │   │   │   ├── angular-locale_ce-ru.js
│   │   │   │   ├── angular-locale_ce.js
│   │   │   │   ├── angular-locale_cgg-ug.js
│   │   │   │   ├── angular-locale_cgg.js
│   │   │   │   ├── angular-locale_chr-us.js
│   │   │   │   ├── angular-locale_chr.js
│   │   │   │   ├── angular-locale_ckb-arab-iq.js
│   │   │   │   ├── angular-locale_ckb-arab-ir.js
│   │   │   │   ├── angular-locale_ckb-arab.js
│   │   │   │   ├── angular-locale_ckb-iq.js
│   │   │   │   ├── angular-locale_ckb-ir.js
│   │   │   │   ├── angular-locale_ckb-latn-iq.js
│   │   │   │   ├── angular-locale_ckb-latn.js
│   │   │   │   ├── angular-locale_ckb.js
│   │   │   │   ├── angular-locale_cs-cz.js
│   │   │   │   ├── angular-locale_cs.js
│   │   │   │   ├── angular-locale_cu-ru.js
│   │   │   │   ├── angular-locale_cu.js
│   │   │   │   ├── angular-locale_cy-gb.js
│   │   │   │   ├── angular-locale_cy.js
│   │   │   │   ├── angular-locale_da-dk.js
│   │   │   │   ├── angular-locale_da-gl.js
│   │   │   │   ├── angular-locale_da.js
│   │   │   │   ├── angular-locale_dav-ke.js
│   │   │   │   ├── angular-locale_dav.js
│   │   │   │   ├── angular-locale_de-at.js
│   │   │   │   ├── angular-locale_de-be.js
│   │   │   │   ├── angular-locale_de-ch.js
│   │   │   │   ├── angular-locale_de-de.js
│   │   │   │   ├── angular-locale_de-it.js
│   │   │   │   ├── angular-locale_de-li.js
│   │   │   │   ├── angular-locale_de-lu.js
│   │   │   │   ├── angular-locale_de.js
│   │   │   │   ├── angular-locale_dje-ne.js
│   │   │   │   ├── angular-locale_dje.js
│   │   │   │   ├── angular-locale_dsb-de.js
│   │   │   │   ├── angular-locale_dsb.js
│   │   │   │   ├── angular-locale_dua-cm.js
│   │   │   │   ├── angular-locale_dua.js
│   │   │   │   ├── angular-locale_dyo-sn.js
│   │   │   │   ├── angular-locale_dyo.js
│   │   │   │   ├── angular-locale_dz-bt.js
│   │   │   │   ├── angular-locale_dz.js
│   │   │   │   ├── angular-locale_ebu-ke.js
│   │   │   │   ├── angular-locale_ebu.js
│   │   │   │   ├── angular-locale_ee-gh.js
│   │   │   │   ├── angular-locale_ee-tg.js
│   │   │   │   ├── angular-locale_ee.js
│   │   │   │   ├── angular-locale_el-cy.js
│   │   │   │   ├── angular-locale_el-gr.js
│   │   │   │   ├── angular-locale_el.js
│   │   │   │   ├── angular-locale_en-001.js
│   │   │   │   ├── angular-locale_en-150.js
│   │   │   │   ├── angular-locale_en-ag.js
│   │   │   │   ├── angular-locale_en-ai.js
│   │   │   │   ├── angular-locale_en-as.js
│   │   │   │   ├── angular-locale_en-at.js
│   │   │   │   ├── angular-locale_en-au.js
│   │   │   │   ├── angular-locale_en-bb.js
│   │   │   │   ├── angular-locale_en-be.js
│   │   │   │   ├── angular-locale_en-bi.js
│   │   │   │   ├── angular-locale_en-bm.js
│   │   │   │   ├── angular-locale_en-bs.js
│   │   │   │   ├── angular-locale_en-bw.js
│   │   │   │   ├── angular-locale_en-bz.js
│   │   │   │   ├── angular-locale_en-ca.js
│   │   │   │   ├── angular-locale_en-cc.js
│   │   │   │   ├── angular-locale_en-ch.js
│   │   │   │   ├── angular-locale_en-ck.js
│   │   │   │   ├── angular-locale_en-cm.js
│   │   │   │   ├── angular-locale_en-cx.js
│   │   │   │   ├── angular-locale_en-cy.js
│   │   │   │   ├── angular-locale_en-de.js
│   │   │   │   ├── angular-locale_en-dg.js
│   │   │   │   ├── angular-locale_en-dk.js
│   │   │   │   ├── angular-locale_en-dm.js
│   │   │   │   ├── angular-locale_en-er.js
│   │   │   │   ├── angular-locale_en-fi.js
│   │   │   │   ├── angular-locale_en-fj.js
│   │   │   │   ├── angular-locale_en-fk.js
│   │   │   │   ├── angular-locale_en-fm.js
│   │   │   │   ├── angular-locale_en-gb.js
│   │   │   │   ├── angular-locale_en-gd.js
│   │   │   │   ├── angular-locale_en-gg.js
│   │   │   │   ├── angular-locale_en-gh.js
│   │   │   │   ├── angular-locale_en-gi.js
│   │   │   │   ├── angular-locale_en-gm.js
│   │   │   │   ├── angular-locale_en-gu.js
│   │   │   │   ├── angular-locale_en-gy.js
│   │   │   │   ├── angular-locale_en-hk.js
│   │   │   │   ├── angular-locale_en-ie.js
│   │   │   │   ├── angular-locale_en-il.js
│   │   │   │   ├── angular-locale_en-im.js
│   │   │   │   ├── angular-locale_en-in.js
│   │   │   │   ├── angular-locale_en-io.js
│   │   │   │   ├── angular-locale_en-iso.js
│   │   │   │   ├── angular-locale_en-je.js
│   │   │   │   ├── angular-locale_en-jm.js
│   │   │   │   ├── angular-locale_en-ke.js
│   │   │   │   ├── angular-locale_en-ki.js
│   │   │   │   ├── angular-locale_en-kn.js
│   │   │   │   ├── angular-locale_en-ky.js
│   │   │   │   ├── angular-locale_en-lc.js
│   │   │   │   ├── angular-locale_en-lr.js
│   │   │   │   ├── angular-locale_en-ls.js
│   │   │   │   ├── angular-locale_en-mg.js
│   │   │   │   ├── angular-locale_en-mh.js
│   │   │   │   ├── angular-locale_en-mo.js
│   │   │   │   ├── angular-locale_en-mp.js
│   │   │   │   ├── angular-locale_en-ms.js
│   │   │   │   ├── angular-locale_en-mt.js
│   │   │   │   ├── angular-locale_en-mu.js
│   │   │   │   ├── angular-locale_en-mw.js
│   │   │   │   ├── angular-locale_en-my.js
│   │   │   │   ├── angular-locale_en-na.js
│   │   │   │   ├── angular-locale_en-nf.js
│   │   │   │   ├── angular-locale_en-ng.js
│   │   │   │   ├── angular-locale_en-nl.js
│   │   │   │   ├── angular-locale_en-nr.js
│   │   │   │   ├── angular-locale_en-nu.js
│   │   │   │   ├── angular-locale_en-nz.js
│   │   │   │   ├── angular-locale_en-pg.js
│   │   │   │   ├── angular-locale_en-ph.js
│   │   │   │   ├── angular-locale_en-pk.js
│   │   │   │   ├── angular-locale_en-pn.js
│   │   │   │   ├── angular-locale_en-pr.js
│   │   │   │   ├── angular-locale_en-pw.js
│   │   │   │   ├── angular-locale_en-rw.js
│   │   │   │   ├── angular-locale_en-sb.js
│   │   │   │   ├── angular-locale_en-sc.js
│   │   │   │   ├── angular-locale_en-sd.js
│   │   │   │   ├── angular-locale_en-se.js
│   │   │   │   ├── angular-locale_en-sg.js
│   │   │   │   ├── angular-locale_en-sh.js
│   │   │   │   ├── angular-locale_en-si.js
│   │   │   │   ├── angular-locale_en-sl.js
│   │   │   │   ├── angular-locale_en-ss.js
│   │   │   │   ├── angular-locale_en-sx.js
│   │   │   │   ├── angular-locale_en-sz.js
│   │   │   │   ├── angular-locale_en-tc.js
│   │   │   │   ├── angular-locale_en-tk.js
│   │   │   │   ├── angular-locale_en-to.js
│   │   │   │   ├── angular-locale_en-tt.js
│   │   │   │   ├── angular-locale_en-tv.js
│   │   │   │   ├── angular-locale_en-tz.js
│   │   │   │   ├── angular-locale_en-ug.js
│   │   │   │   ├── angular-locale_en-um.js
│   │   │   │   ├── angular-locale_en-us-posix.js
│   │   │   │   ├── angular-locale_en-us.js
│   │   │   │   ├── angular-locale_en-vc.js
│   │   │   │   ├── angular-locale_en-vg.js
│   │   │   │   ├── angular-locale_en-vi.js
│   │   │   │   ├── angular-locale_en-vu.js
│   │   │   │   ├── angular-locale_en-ws.js
│   │   │   │   ├── angular-locale_en-xa.js
│   │   │   │   ├── angular-locale_en-za.js
│   │   │   │   ├── angular-locale_en-zm.js
│   │   │   │   ├── angular-locale_en-zw.js
│   │   │   │   ├── angular-locale_en.js
│   │   │   │   ├── angular-locale_eo-001.js
│   │   │   │   ├── angular-locale_eo.js
│   │   │   │   ├── angular-locale_es-419.js
│   │   │   │   ├── angular-locale_es-ar.js
│   │   │   │   ├── angular-locale_es-bo.js
│   │   │   │   ├── angular-locale_es-br.js
│   │   │   │   ├── angular-locale_es-bz.js
│   │   │   │   ├── angular-locale_es-cl.js
│   │   │   │   ├── angular-locale_es-co.js
│   │   │   │   ├── angular-locale_es-cr.js
│   │   │   │   ├── angular-locale_es-cu.js
│   │   │   │   ├── angular-locale_es-do.js
│   │   │   │   ├── angular-locale_es-ea.js
│   │   │   │   ├── angular-locale_es-ec.js
│   │   │   │   ├── angular-locale_es-es.js
│   │   │   │   ├── angular-locale_es-gq.js
│   │   │   │   ├── angular-locale_es-gt.js
│   │   │   │   ├── angular-locale_es-hn.js
│   │   │   │   ├── angular-locale_es-ic.js
│   │   │   │   ├── angular-locale_es-mx.js
│   │   │   │   ├── angular-locale_es-ni.js
│   │   │   │   ├── angular-locale_es-pa.js
│   │   │   │   ├── angular-locale_es-pe.js
│   │   │   │   ├── angular-locale_es-ph.js
│   │   │   │   ├── angular-locale_es-pr.js
│   │   │   │   ├── angular-locale_es-py.js
│   │   │   │   ├── angular-locale_es-sv.js
│   │   │   │   ├── angular-locale_es-us.js
│   │   │   │   ├── angular-locale_es-uy.js
│   │   │   │   ├── angular-locale_es-ve.js
│   │   │   │   ├── angular-locale_es.js
│   │   │   │   ├── angular-locale_et-ee.js
│   │   │   │   ├── angular-locale_et.js
│   │   │   │   ├── angular-locale_eu-es.js
│   │   │   │   ├── angular-locale_eu.js
│   │   │   │   ├── angular-locale_ewo-cm.js
│   │   │   │   ├── angular-locale_ewo.js
│   │   │   │   ├── angular-locale_fa-af.js
│   │   │   │   ├── angular-locale_fa-ir.js
│   │   │   │   ├── angular-locale_fa.js
│   │   │   │   ├── angular-locale_ff-cm.js
│   │   │   │   ├── angular-locale_ff-gn.js
│   │   │   │   ├── angular-locale_ff-mr.js
│   │   │   │   ├── angular-locale_ff-sn.js
│   │   │   │   ├── angular-locale_ff.js
│   │   │   │   ├── angular-locale_fi-fi.js
│   │   │   │   ├── angular-locale_fi.js
│   │   │   │   ├── angular-locale_fil-ph.js
│   │   │   │   ├── angular-locale_fil.js
│   │   │   │   ├── angular-locale_fo-dk.js
│   │   │   │   ├── angular-locale_fo-fo.js
│   │   │   │   ├── angular-locale_fo.js
│   │   │   │   ├── angular-locale_fr-be.js
│   │   │   │   ├── angular-locale_fr-bf.js
│   │   │   │   ├── angular-locale_fr-bi.js
│   │   │   │   ├── angular-locale_fr-bj.js
│   │   │   │   ├── angular-locale_fr-bl.js
│   │   │   │   ├── angular-locale_fr-ca.js
│   │   │   │   ├── angular-locale_fr-cd.js
│   │   │   │   ├── angular-locale_fr-cf.js
│   │   │   │   ├── angular-locale_fr-cg.js
│   │   │   │   ├── angular-locale_fr-ch.js
│   │   │   │   ├── angular-locale_fr-ci.js
│   │   │   │   ├── angular-locale_fr-cm.js
│   │   │   │   ├── angular-locale_fr-dj.js
│   │   │   │   ├── angular-locale_fr-dz.js
│   │   │   │   ├── angular-locale_fr-fr.js
│   │   │   │   ├── angular-locale_fr-ga.js
│   │   │   │   ├── angular-locale_fr-gf.js
│   │   │   │   ├── angular-locale_fr-gn.js
│   │   │   │   ├── angular-locale_fr-gp.js
│   │   │   │   ├── angular-locale_fr-gq.js
│   │   │   │   ├── angular-locale_fr-ht.js
│   │   │   │   ├── angular-locale_fr-km.js
│   │   │   │   ├── angular-locale_fr-lu.js
│   │   │   │   ├── angular-locale_fr-ma.js
│   │   │   │   ├── angular-locale_fr-mc.js
│   │   │   │   ├── angular-locale_fr-mf.js
│   │   │   │   ├── angular-locale_fr-mg.js
│   │   │   │   ├── angular-locale_fr-ml.js
│   │   │   │   ├── angular-locale_fr-mq.js
│   │   │   │   ├── angular-locale_fr-mr.js
│   │   │   │   ├── angular-locale_fr-mu.js
│   │   │   │   ├── angular-locale_fr-nc.js
│   │   │   │   ├── angular-locale_fr-ne.js
│   │   │   │   ├── angular-locale_fr-pf.js
│   │   │   │   ├── angular-locale_fr-pm.js
│   │   │   │   ├── angular-locale_fr-re.js
│   │   │   │   ├── angular-locale_fr-rw.js
│   │   │   │   ├── angular-locale_fr-sc.js
│   │   │   │   ├── angular-locale_fr-sn.js
│   │   │   │   ├── angular-locale_fr-sy.js
│   │   │   │   ├── angular-locale_fr-td.js
│   │   │   │   ├── angular-locale_fr-tg.js
│   │   │   │   ├── angular-locale_fr-tn.js
│   │   │   │   ├── angular-locale_fr-vu.js
│   │   │   │   ├── angular-locale_fr-wf.js
│   │   │   │   ├── angular-locale_fr-yt.js
│   │   │   │   ├── angular-locale_fr.js
│   │   │   │   ├── angular-locale_fur-it.js
│   │   │   │   ├── angular-locale_fur.js
│   │   │   │   ├── angular-locale_fy-nl.js
│   │   │   │   ├── angular-locale_fy.js
│   │   │   │   ├── angular-locale_ga-ie.js
│   │   │   │   ├── angular-locale_ga.js
│   │   │   │   ├── angular-locale_gd-gb.js
│   │   │   │   ├── angular-locale_gd.js
│   │   │   │   ├── angular-locale_gl-es.js
│   │   │   │   ├── angular-locale_gl.js
│   │   │   │   ├── angular-locale_gsw-ch.js
│   │   │   │   ├── angular-locale_gsw-fr.js
│   │   │   │   ├── angular-locale_gsw-li.js
│   │   │   │   ├── angular-locale_gsw.js
│   │   │   │   ├── angular-locale_gu-in.js
│   │   │   │   ├── angular-locale_gu.js
│   │   │   │   ├── angular-locale_guz-ke.js
│   │   │   │   ├── angular-locale_guz.js
│   │   │   │   ├── angular-locale_gv-im.js
│   │   │   │   ├── angular-locale_gv.js
│   │   │   │   ├── angular-locale_ha-gh.js
│   │   │   │   ├── angular-locale_ha-ne.js
│   │   │   │   ├── angular-locale_ha-ng.js
│   │   │   │   ├── angular-locale_ha.js
│   │   │   │   ├── angular-locale_haw-us.js
│   │   │   │   ├── angular-locale_haw.js
│   │   │   │   ├── angular-locale_he-il.js
│   │   │   │   ├── angular-locale_he.js
│   │   │   │   ├── angular-locale_hi-in.js
│   │   │   │   ├── angular-locale_hi.js
│   │   │   │   ├── angular-locale_hr-ba.js
│   │   │   │   ├── angular-locale_hr-hr.js
│   │   │   │   ├── angular-locale_hr.js
│   │   │   │   ├── angular-locale_hsb-de.js
│   │   │   │   ├── angular-locale_hsb.js
│   │   │   │   ├── angular-locale_hu-hu.js
│   │   │   │   ├── angular-locale_hu.js
│   │   │   │   ├── angular-locale_hy-am.js
│   │   │   │   ├── angular-locale_hy.js
│   │   │   │   ├── angular-locale_id-id.js
│   │   │   │   ├── angular-locale_id.js
│   │   │   │   ├── angular-locale_ig-ng.js
│   │   │   │   ├── angular-locale_ig.js
│   │   │   │   ├── angular-locale_ii-cn.js
│   │   │   │   ├── angular-locale_ii.js
│   │   │   │   ├── angular-locale_in.js
│   │   │   │   ├── angular-locale_is-is.js
│   │   │   │   ├── angular-locale_is.js
│   │   │   │   ├── angular-locale_it-ch.js
│   │   │   │   ├── angular-locale_it-it.js
│   │   │   │   ├── angular-locale_it-sm.js
│   │   │   │   ├── angular-locale_it-va.js
│   │   │   │   ├── angular-locale_it.js
│   │   │   │   ├── angular-locale_iw.js
│   │   │   │   ├── angular-locale_ja-jp.js
│   │   │   │   ├── angular-locale_ja.js
│   │   │   │   ├── angular-locale_jgo-cm.js
│   │   │   │   ├── angular-locale_jgo.js
│   │   │   │   ├── angular-locale_jmc-tz.js
│   │   │   │   ├── angular-locale_jmc.js
│   │   │   │   ├── angular-locale_ka-ge.js
│   │   │   │   ├── angular-locale_ka.js
│   │   │   │   ├── angular-locale_kab-dz.js
│   │   │   │   ├── angular-locale_kab.js
│   │   │   │   ├── angular-locale_kam-ke.js
│   │   │   │   ├── angular-locale_kam.js
│   │   │   │   ├── angular-locale_kde-tz.js
│   │   │   │   ├── angular-locale_kde.js
│   │   │   │   ├── angular-locale_kea-cv.js
│   │   │   │   ├── angular-locale_kea.js
│   │   │   │   ├── angular-locale_khq-ml.js
│   │   │   │   ├── angular-locale_khq.js
│   │   │   │   ├── angular-locale_ki-ke.js
│   │   │   │   ├── angular-locale_ki.js
│   │   │   │   ├── angular-locale_kk-kz.js
│   │   │   │   ├── angular-locale_kk.js
│   │   │   │   ├── angular-locale_kkj-cm.js
│   │   │   │   ├── angular-locale_kkj.js
│   │   │   │   ├── angular-locale_kl-gl.js
│   │   │   │   ├── angular-locale_kl.js
│   │   │   │   ├── angular-locale_kln-ke.js
│   │   │   │   ├── angular-locale_kln.js
│   │   │   │   ├── angular-locale_km-kh.js
│   │   │   │   ├── angular-locale_km.js
│   │   │   │   ├── angular-locale_kn-in.js
│   │   │   │   ├── angular-locale_kn.js
│   │   │   │   ├── angular-locale_ko-kp.js
│   │   │   │   ├── angular-locale_ko-kr.js
│   │   │   │   ├── angular-locale_ko.js
│   │   │   │   ├── angular-locale_kok-in.js
│   │   │   │   ├── angular-locale_kok.js
│   │   │   │   ├── angular-locale_ks-in.js
│   │   │   │   ├── angular-locale_ks.js
│   │   │   │   ├── angular-locale_ksb-tz.js
│   │   │   │   ├── angular-locale_ksb.js
│   │   │   │   ├── angular-locale_ksf-cm.js
│   │   │   │   ├── angular-locale_ksf.js
│   │   │   │   ├── angular-locale_ksh-de.js
│   │   │   │   ├── angular-locale_ksh.js
│   │   │   │   ├── angular-locale_kw-gb.js
│   │   │   │   ├── angular-locale_kw.js
│   │   │   │   ├── angular-locale_ky-kg.js
│   │   │   │   ├── angular-locale_ky.js
│   │   │   │   ├── angular-locale_lag-tz.js
│   │   │   │   ├── angular-locale_lag.js
│   │   │   │   ├── angular-locale_lb-lu.js
│   │   │   │   ├── angular-locale_lb.js
│   │   │   │   ├── angular-locale_lg-ug.js
│   │   │   │   ├── angular-locale_lg.js
│   │   │   │   ├── angular-locale_lkt-us.js
│   │   │   │   ├── angular-locale_lkt.js
│   │   │   │   ├── angular-locale_ln-ao.js
│   │   │   │   ├── angular-locale_ln-cd.js
│   │   │   │   ├── angular-locale_ln-cf.js
│   │   │   │   ├── angular-locale_ln-cg.js
│   │   │   │   ├── angular-locale_ln.js
│   │   │   │   ├── angular-locale_lo-la.js
│   │   │   │   ├── angular-locale_lo.js
│   │   │   │   ├── angular-locale_lrc-iq.js
│   │   │   │   ├── angular-locale_lrc-ir.js
│   │   │   │   ├── angular-locale_lrc.js
│   │   │   │   ├── angular-locale_lt-lt.js
│   │   │   │   ├── angular-locale_lt.js
│   │   │   │   ├── angular-locale_lu-cd.js
│   │   │   │   ├── angular-locale_lu.js
│   │   │   │   ├── angular-locale_luo-ke.js
│   │   │   │   ├── angular-locale_luo.js
│   │   │   │   ├── angular-locale_luy-ke.js
│   │   │   │   ├── angular-locale_luy.js
│   │   │   │   ├── angular-locale_lv-lv.js
│   │   │   │   ├── angular-locale_lv.js
│   │   │   │   ├── angular-locale_mas-ke.js
│   │   │   │   ├── angular-locale_mas-tz.js
│   │   │   │   ├── angular-locale_mas.js
│   │   │   │   ├── angular-locale_mer-ke.js
│   │   │   │   ├── angular-locale_mer.js
│   │   │   │   ├── angular-locale_mfe-mu.js
│   │   │   │   ├── angular-locale_mfe.js
│   │   │   │   ├── angular-locale_mg-mg.js
│   │   │   │   ├── angular-locale_mg.js
│   │   │   │   ├── angular-locale_mgh-mz.js
│   │   │   │   ├── angular-locale_mgh.js
│   │   │   │   ├── angular-locale_mgo-cm.js
│   │   │   │   ├── angular-locale_mgo.js
│   │   │   │   ├── angular-locale_mk-mk.js
│   │   │   │   ├── angular-locale_mk.js
│   │   │   │   ├── angular-locale_ml-in.js
│   │   │   │   ├── angular-locale_ml.js
│   │   │   │   ├── angular-locale_mn-mn.js
│   │   │   │   ├── angular-locale_mn.js
│   │   │   │   ├── angular-locale_mo.js
│   │   │   │   ├── angular-locale_mr-in.js
│   │   │   │   ├── angular-locale_mr.js
│   │   │   │   ├── angular-locale_ms-bn.js
│   │   │   │   ├── angular-locale_ms-my.js
│   │   │   │   ├── angular-locale_ms-sg.js
│   │   │   │   ├── angular-locale_ms.js
│   │   │   │   ├── angular-locale_mt-mt.js
│   │   │   │   ├── angular-locale_mt.js
│   │   │   │   ├── angular-locale_mua-cm.js
│   │   │   │   ├── angular-locale_mua.js
│   │   │   │   ├── angular-locale_my-mm.js
│   │   │   │   ├── angular-locale_my.js
│   │   │   │   ├── angular-locale_mzn-ir.js
│   │   │   │   ├── angular-locale_mzn.js
│   │   │   │   ├── angular-locale_naq-na.js
│   │   │   │   ├── angular-locale_naq.js
│   │   │   │   ├── angular-locale_nb-no.js
│   │   │   │   ├── angular-locale_nb-sj.js
│   │   │   │   ├── angular-locale_nb.js
│   │   │   │   ├── angular-locale_nd-zw.js
│   │   │   │   ├── angular-locale_nd.js
│   │   │   │   ├── angular-locale_nds-de.js
│   │   │   │   ├── angular-locale_nds-nl.js
│   │   │   │   ├── angular-locale_nds.js
│   │   │   │   ├── angular-locale_ne-in.js
│   │   │   │   ├── angular-locale_ne-np.js
│   │   │   │   ├── angular-locale_ne.js
│   │   │   │   ├── angular-locale_nl-aw.js
│   │   │   │   ├── angular-locale_nl-be.js
│   │   │   │   ├── angular-locale_nl-bq.js
│   │   │   │   ├── angular-locale_nl-cw.js
│   │   │   │   ├── angular-locale_nl-nl.js
│   │   │   │   ├── angular-locale_nl-sr.js
│   │   │   │   ├── angular-locale_nl-sx.js
│   │   │   │   ├── angular-locale_nl.js
│   │   │   │   ├── angular-locale_nmg-cm.js
│   │   │   │   ├── angular-locale_nmg.js
│   │   │   │   ├── angular-locale_nn-no.js
│   │   │   │   ├── angular-locale_nn.js
│   │   │   │   ├── angular-locale_nnh-cm.js
│   │   │   │   ├── angular-locale_nnh.js
│   │   │   │   ├── angular-locale_no-no.js
│   │   │   │   ├── angular-locale_no.js
│   │   │   │   ├── angular-locale_nus-ss.js
│   │   │   │   ├── angular-locale_nus.js
│   │   │   │   ├── angular-locale_nyn-ug.js
│   │   │   │   ├── angular-locale_nyn.js
│   │   │   │   ├── angular-locale_om-et.js
│   │   │   │   ├── angular-locale_om-ke.js
│   │   │   │   ├── angular-locale_om.js
│   │   │   │   ├── angular-locale_or-in.js
│   │   │   │   ├── angular-locale_or.js
│   │   │   │   ├── angular-locale_os-ge.js
│   │   │   │   ├── angular-locale_os-ru.js
│   │   │   │   ├── angular-locale_os.js
│   │   │   │   ├── angular-locale_pa-arab-pk.js
│   │   │   │   ├── angular-locale_pa-arab.js
│   │   │   │   ├── angular-locale_pa-guru-in.js
│   │   │   │   ├── angular-locale_pa-guru.js
│   │   │   │   ├── angular-locale_pa.js
│   │   │   │   ├── angular-locale_pl-pl.js
│   │   │   │   ├── angular-locale_pl.js
│   │   │   │   ├── angular-locale_prg-001.js
│   │   │   │   ├── angular-locale_prg.js
│   │   │   │   ├── angular-locale_ps-af.js
│   │   │   │   ├── angular-locale_ps.js
│   │   │   │   ├── angular-locale_pt-ao.js
│   │   │   │   ├── angular-locale_pt-br.js
│   │   │   │   ├── angular-locale_pt-ch.js
│   │   │   │   ├── angular-locale_pt-cv.js
│   │   │   │   ├── angular-locale_pt-gq.js
│   │   │   │   ├── angular-locale_pt-gw.js
│   │   │   │   ├── angular-locale_pt-lu.js
│   │   │   │   ├── angular-locale_pt-mo.js
│   │   │   │   ├── angular-locale_pt-mz.js
│   │   │   │   ├── angular-locale_pt-pt.js
│   │   │   │   ├── angular-locale_pt-st.js
│   │   │   │   ├── angular-locale_pt-tl.js
│   │   │   │   ├── angular-locale_pt.js
│   │   │   │   ├── angular-locale_qu-bo.js
│   │   │   │   ├── angular-locale_qu-ec.js
│   │   │   │   ├── angular-locale_qu-pe.js
│   │   │   │   ├── angular-locale_qu.js
│   │   │   │   ├── angular-locale_rm-ch.js
│   │   │   │   ├── angular-locale_rm.js
│   │   │   │   ├── angular-locale_rn-bi.js
│   │   │   │   ├── angular-locale_rn.js
│   │   │   │   ├── angular-locale_ro-md.js
│   │   │   │   ├── angular-locale_ro-ro.js
│   │   │   │   ├── angular-locale_ro.js
│   │   │   │   ├── angular-locale_rof-tz.js
│   │   │   │   ├── angular-locale_rof.js
│   │   │   │   ├── angular-locale_ru-by.js
│   │   │   │   ├── angular-locale_ru-kg.js
│   │   │   │   ├── angular-locale_ru-kz.js
│   │   │   │   ├── angular-locale_ru-md.js
│   │   │   │   ├── angular-locale_ru-ru.js
│   │   │   │   ├── angular-locale_ru-ua.js
│   │   │   │   ├── angular-locale_ru.js
│   │   │   │   ├── angular-locale_rw-rw.js
│   │   │   │   ├── angular-locale_rw.js
│   │   │   │   ├── angular-locale_rwk-tz.js
│   │   │   │   ├── angular-locale_rwk.js
│   │   │   │   ├── angular-locale_sah-ru.js
│   │   │   │   ├── angular-locale_sah.js
│   │   │   │   ├── angular-locale_saq-ke.js
│   │   │   │   ├── angular-locale_saq.js
│   │   │   │   ├── angular-locale_sbp-tz.js
│   │   │   │   ├── angular-locale_sbp.js
│   │   │   │   ├── angular-locale_se-fi.js
│   │   │   │   ├── angular-locale_se-no.js
│   │   │   │   ├── angular-locale_se-se.js
│   │   │   │   ├── angular-locale_se.js
│   │   │   │   ├── angular-locale_seh-mz.js
│   │   │   │   ├── angular-locale_seh.js
│   │   │   │   ├── angular-locale_ses-ml.js
│   │   │   │   ├── angular-locale_ses.js
│   │   │   │   ├── angular-locale_sg-cf.js
│   │   │   │   ├── angular-locale_sg.js
│   │   │   │   ├── angular-locale_sh.js
│   │   │   │   ├── angular-locale_shi-latn-ma.js
│   │   │   │   ├── angular-locale_shi-latn.js
│   │   │   │   ├── angular-locale_shi-tfng-ma.js
│   │   │   │   ├── angular-locale_shi-tfng.js
│   │   │   │   ├── angular-locale_shi.js
│   │   │   │   ├── angular-locale_si-lk.js
│   │   │   │   ├── angular-locale_si.js
│   │   │   │   ├── angular-locale_sk-sk.js
│   │   │   │   ├── angular-locale_sk.js
│   │   │   │   ├── angular-locale_sl-si.js
│   │   │   │   ├── angular-locale_sl.js
│   │   │   │   ├── angular-locale_smn-fi.js
│   │   │   │   ├── angular-locale_smn.js
│   │   │   │   ├── angular-locale_sn-zw.js
│   │   │   │   ├── angular-locale_sn.js
│   │   │   │   ├── angular-locale_so-dj.js
│   │   │   │   ├── angular-locale_so-et.js
│   │   │   │   ├── angular-locale_so-ke.js
│   │   │   │   ├── angular-locale_so-so.js
│   │   │   │   ├── angular-locale_so.js
│   │   │   │   ├── angular-locale_sq-al.js
│   │   │   │   ├── angular-locale_sq-mk.js
│   │   │   │   ├── angular-locale_sq-xk.js
│   │   │   │   ├── angular-locale_sq.js
│   │   │   │   ├── angular-locale_sr-cyrl-ba.js
│   │   │   │   ├── angular-locale_sr-cyrl-me.js
│   │   │   │   ├── angular-locale_sr-cyrl-rs.js
│   │   │   │   ├── angular-locale_sr-cyrl-xk.js
│   │   │   │   ├── angular-locale_sr-cyrl.js
│   │   │   │   ├── angular-locale_sr-latn-ba.js
│   │   │   │   ├── angular-locale_sr-latn-me.js
│   │   │   │   ├── angular-locale_sr-latn-rs.js
│   │   │   │   ├── angular-locale_sr-latn-xk.js
│   │   │   │   ├── angular-locale_sr-latn.js
│   │   │   │   ├── angular-locale_sr.js
│   │   │   │   ├── angular-locale_sv-ax.js
│   │   │   │   ├── angular-locale_sv-fi.js
│   │   │   │   ├── angular-locale_sv-se.js
│   │   │   │   ├── angular-locale_sv.js
│   │   │   │   ├── angular-locale_sw-cd.js
│   │   │   │   ├── angular-locale_sw-ke.js
│   │   │   │   ├── angular-locale_sw-tz.js
│   │   │   │   ├── angular-locale_sw-ug.js
│   │   │   │   ├── angular-locale_sw.js
│   │   │   │   ├── angular-locale_ta-in.js
│   │   │   │   ├── angular-locale_ta-lk.js
│   │   │   │   ├── angular-locale_ta-my.js
│   │   │   │   ├── angular-locale_ta-sg.js
│   │   │   │   ├── angular-locale_ta.js
│   │   │   │   ├── angular-locale_te-in.js
│   │   │   │   ├── angular-locale_te.js
│   │   │   │   ├── angular-locale_teo-ke.js
│   │   │   │   ├── angular-locale_teo-ug.js
│   │   │   │   ├── angular-locale_teo.js
│   │   │   │   ├── angular-locale_th-th.js
│   │   │   │   ├── angular-locale_th.js
│   │   │   │   ├── angular-locale_ti-er.js
│   │   │   │   ├── angular-locale_ti-et.js
│   │   │   │   ├── angular-locale_ti.js
│   │   │   │   ├── angular-locale_tk-tm.js
│   │   │   │   ├── angular-locale_tk.js
│   │   │   │   ├── angular-locale_tl.js
│   │   │   │   ├── angular-locale_to-to.js
│   │   │   │   ├── angular-locale_to.js
│   │   │   │   ├── angular-locale_tr-cy.js
│   │   │   │   ├── angular-locale_tr-tr.js
│   │   │   │   ├── angular-locale_tr.js
│   │   │   │   ├── angular-locale_twq-ne.js
│   │   │   │   ├── angular-locale_twq.js
│   │   │   │   ├── angular-locale_tzm-ma.js
│   │   │   │   ├── angular-locale_tzm.js
│   │   │   │   ├── angular-locale_ug-cn.js
│   │   │   │   ├── angular-locale_ug.js
│   │   │   │   ├── angular-locale_uk-ua.js
│   │   │   │   ├── angular-locale_uk.js
│   │   │   │   ├── angular-locale_ur-in.js
│   │   │   │   ├── angular-locale_ur-pk.js
│   │   │   │   ├── angular-locale_ur.js
│   │   │   │   ├── angular-locale_uz-arab-af.js
│   │   │   │   ├── angular-locale_uz-arab.js
│   │   │   │   ├── angular-locale_uz-cyrl-uz.js
│   │   │   │   ├── angular-locale_uz-cyrl.js
│   │   │   │   ├── angular-locale_uz-latn-uz.js
│   │   │   │   ├── angular-locale_uz-latn.js
│   │   │   │   ├── angular-locale_uz.js
│   │   │   │   ├── angular-locale_vai-latn-lr.js
│   │   │   │   ├── angular-locale_vai-latn.js
│   │   │   │   ├── angular-locale_vai-vaii-lr.js
│   │   │   │   ├── angular-locale_vai-vaii.js
│   │   │   │   ├── angular-locale_vai.js
│   │   │   │   ├── angular-locale_vi-vn.js
│   │   │   │   ├── angular-locale_vi.js
│   │   │   │   ├── angular-locale_vo-001.js
│   │   │   │   ├── angular-locale_vo.js
│   │   │   │   ├── angular-locale_vun-tz.js
│   │   │   │   ├── angular-locale_vun.js
│   │   │   │   ├── angular-locale_wae-ch.js
│   │   │   │   ├── angular-locale_wae.js
│   │   │   │   ├── angular-locale_xog-ug.js
│   │   │   │   ├── angular-locale_xog.js
│   │   │   │   ├── angular-locale_yav-cm.js
│   │   │   │   ├── angular-locale_yav.js
│   │   │   │   ├── angular-locale_yi-001.js
│   │   │   │   ├── angular-locale_yi.js
│   │   │   │   ├── angular-locale_yo-bj.js
│   │   │   │   ├── angular-locale_yo-ng.js
│   │   │   │   ├── angular-locale_yo.js
│   │   │   │   ├── angular-locale_yue-hk.js
│   │   │   │   ├── angular-locale_yue.js
│   │   │   │   ├── angular-locale_zgh-ma.js
│   │   │   │   ├── angular-locale_zgh.js
│   │   │   │   ├── angular-locale_zh-cn.js
│   │   │   │   ├── angular-locale_zh-hans-cn.js
│   │   │   │   ├── angular-locale_zh-hans-hk.js
│   │   │   │   ├── angular-locale_zh-hans-mo.js
│   │   │   │   ├── angular-locale_zh-hans-sg.js
│   │   │   │   ├── angular-locale_zh-hans.js
│   │   │   │   ├── angular-locale_zh-hant-hk.js
│   │   │   │   ├── angular-locale_zh-hant-mo.js
│   │   │   │   ├── angular-locale_zh-hant-tw.js
│   │   │   │   ├── angular-locale_zh-hant.js
│   │   │   │   ├── angular-locale_zh-hk.js
│   │   │   │   ├── angular-locale_zh-tw.js
│   │   │   │   ├── angular-locale_zh.js
│   │   │   │   ├── angular-locale_zu-za.js
│   │   │   │   └── angular-locale_zu.js
│   │   │   ├── sitemap.xml
│   │   │   ├── test-bundles/
│   │   │   │   ├── angular-aria.js
│   │   │   │   ├── angular-cookies.js
│   │   │   │   ├── angular-message-format.js
│   │   │   │   ├── angular-messages.js
│   │   │   │   ├── angular-resource.js
│   │   │   │   ├── angular-route.js
│   │   │   │   ├── angular-sanitize.js
│   │   │   │   └── angular-touch.js
│   │   │   ├── version.json
│   │   │   └── version.txt
│   │   ├── angular-media-player/
│   │   │   └── angular-media-player.js
│   │   ├── angularjs-toaster/
│   │   │   ├── toaster.css
│   │   │   └── toaster.js
│   │   ├── bootstrap/
│   │   │   ├── config.json
│   │   │   ├── css/
│   │   │   │   ├── bootstrap-theme.css
│   │   │   │   └── bootstrap.css
│   │   │   └── js/
│   │   │       └── bootstrap.js
│   │   ├── clipboard/
│   │   │   └── clipboard.js
│   │   ├── closure/
│   │   │   └── long.js
│   │   ├── console-polyfill/
│   │   │   └── console-polyfill.js
│   │   ├── cryptoJS/
│   │   │   ├── THIRDPARTY_LICENSE
│   │   │   └── crypto.js
│   │   ├── jquery/
│   │   │   └── jquery.js
│   │   ├── jquery.emojiarea/
│   │   │   ├── jquery.emojiarea-orig.js
│   │   │   └── jquery.emojiarea.js
│   │   ├── jquery.nanoscroller/
│   │   │   ├── nanoscroller.css
│   │   │   └── nanoscroller.js
│   │   ├── jsbn/
│   │   │   ├── THIRDPARTY_LICENSE
│   │   │   └── jsbn_combined.js
│   │   ├── leemon_bigint/
│   │   │   └── bigint.js
│   │   ├── libwebpjs/
│   │   │   ├── libwebp-0.1.13.js
│   │   │   └── libwebp-0.2.0.js
│   │   ├── ogv.js/
│   │   │   ├── COPYING
│   │   │   ├── COPYING-ogg.txt
│   │   │   ├── COPYING-opus.txt
│   │   │   ├── COPYING-theora.txt
│   │   │   ├── COPYING-vorbis.txt
│   │   │   ├── LICENSE-nestegg.txt
│   │   │   ├── LICENSE-vpx.txt
│   │   │   ├── PATENTS-vpx.txt
│   │   │   ├── README.md
│   │   │   ├── dynamicaudio.swf
│   │   │   ├── ogv-decoder-audio-opus-wasm.js
│   │   │   ├── ogv-decoder-audio-opus-wasm.wasm
│   │   │   ├── ogv-decoder-audio-opus.js
│   │   │   ├── ogv-decoder-audio-vorbis-wasm.js
│   │   │   ├── ogv-decoder-audio-vorbis-wasm.wasm
│   │   │   ├── ogv-decoder-audio-vorbis.js
│   │   │   ├── ogv-decoder-video-theora-wasm.js
│   │   │   ├── ogv-decoder-video-theora-wasm.wasm
│   │   │   ├── ogv-decoder-video-theora.js
│   │   │   ├── ogv-decoder-video-vp8-mt.js
│   │   │   ├── ogv-decoder-video-vp8-wasm.js
│   │   │   ├── ogv-decoder-video-vp8-wasm.wasm
│   │   │   ├── ogv-decoder-video-vp8.js
│   │   │   ├── ogv-decoder-video-vp9-mt.js
│   │   │   ├── ogv-decoder-video-vp9-wasm.js
│   │   │   ├── ogv-decoder-video-vp9-wasm.wasm
│   │   │   ├── ogv-decoder-video-vp9.js
│   │   │   ├── ogv-demuxer-ogg-wasm.js
│   │   │   ├── ogv-demuxer-ogg-wasm.wasm
│   │   │   ├── ogv-demuxer-ogg.js
│   │   │   ├── ogv-demuxer-webm-wasm.js
│   │   │   ├── ogv-demuxer-webm-wasm.wasm
│   │   │   ├── ogv-demuxer-webm.js
│   │   │   ├── ogv-support.js
│   │   │   ├── ogv-version.js
│   │   │   ├── ogv-worker-audio.js
│   │   │   ├── ogv-worker-video.js
│   │   │   ├── ogv.js
│   │   │   └── pthread-main.js
│   │   ├── recorderjs/
│   │   │   ├── encoder_worker.js
│   │   │   └── recorder.js
│   │   ├── rusha/
│   │   │   └── rusha.js
│   │   ├── ui-bootstrap/
│   │   │   ├── THIRDPARTY_LICENSE
│   │   │   └── ui-bootstrap-custom-tpls-0.12.0.js
│   │   └── zlib/
│   │       └── THIRDPARTY_LICENSE
│   └── webogram.appcache
├── gulpfile.js
├── karma.conf.js
├── package.json
├── scripts/
│   ├── cldr_localize.js
│   ├── emoji_data/
│   │   ├── build.php
│   │   └── emoji.json
│   ├── google_fonts_download.sh
│   └── ua_handler.js
├── test/
│   ├── test-init.js
│   └── unit/
│       ├── controllers/
│       │   ├── AppFooterControllerSpec.js
│       │   ├── AppImPanelControllerSpec.js
│       │   ├── AppLangSelectControllerSpec.js
│       │   ├── AppWelcomeControllerSpec.js
│       │   ├── ChangelogModalControlelerSpec.js
│       │   ├── CountrySelectModalControllerSpec.js
│       │   ├── DocumentModalControllerSpec.js
│       │   ├── EmbedModalController.js
│       │   ├── ImportContactModalControllerSpec.js
│       │   ├── PasswordRecoveryModalControllerSpec.js
│       │   ├── PeerSelectControllerSpec.js
│       │   ├── ProfileEditModalControllerSpec.js
│       │   ├── UsernameEditModalControllerSpec.js
│       │   └── VideoModalControllerSpec.js
│       ├── directives/
│       │   ├── myHeadDirective.js
│       │   └── myLangFooterDirective.js
│       ├── filters/
│       │   ├── chatTitleFilterSpec.js
│       │   ├── dateOrTimeFilterSpec.js
│       │   ├── durationFilterSpec.js
│       │   ├── durationRemainsFilterSpec.js
│       │   ├── formatShortNumberFilterSpec.js
│       │   ├── formatSizeFilterSpec.js
│       │   ├── formatSizeProgressFilterSpec.js
│       │   ├── myDateFilterSpec.js
│       │   ├── nl2brFilterSpec.js
│       │   ├── phoneNumberFilterSpec.js
│       │   ├── realtiveTimeFilterSpec.js
│       │   ├── richTextFilterSpec.js
│       │   ├── shortUrlFilterSpec.js
│       │   ├── timeFilterSpec.js
│       │   ├── userFirstNameFilterSpec.js
│       │   ├── userNameFilterSpec.js
│       │   └── userStatusFilterSpec.js
│       └── services/
│           └── PhonebookContactsServiceSpec.js
├── update-angular.sh
└── webogram.sublime-project
Download .txt
Showing preview only (652K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (7092 symbols across 563 files)

FILE: app/js/controllers.js
  function initPhoneCountry (line 73) | function initPhoneCountry () {
  function selectPhoneCountryByIso2 (line 104) | function selectPhoneCountryByIso2 (countryIso2) {
  function selectCountry (line 117) | function selectCountry (country) {
  function updateCountry (line 128) | function updateCountry () {
  function saveAuth (line 176) | function saveAuth (result) {
  function applySentCode (line 252) | function applySentCode (sentCode) {
  function nextTimeoutCheck (line 277) | function nextTimeoutCheck () {
  function updatePasswordState (line 454) | function updatePasswordState () {
  function updateCurDialog (line 684) | function updateCurDialog () {
  function deleteDialog (line 815) | function deleteDialog (peerID) {
  function sortDialogs (line 824) | function sortDialogs () {
  function getDialogs (line 979) | function getDialogs (force) {
  function loadDialogs (line 1033) | function loadDialogs (force) {
  function showMoreDialogs (line 1108) | function showMoreDialogs () {
  function showMoreConversations (line 1179) | function showMoreConversations () {
  function applyDialogSelect (line 1336) | function applyDialogSelect (newDialog, oldDialog) {
  function historiesQueuePush (line 1364) | function historiesQueuePush (peerID) {
  function historiesQueueFind (line 1389) | function historiesQueueFind (peerID) {
  function historiesQueuePop (line 1399) | function historiesQueuePop (peerID) {
  function updateHistoryPeer (line 1410) | function updateHistoryPeer (preload) {
  function updateBotActions (line 1440) | function updateBotActions () {
  function updateChannelActions (line 1467) | function updateChannelActions () {
  function messageFocusHistory (line 1500) | function messageFocusHistory () {
  function showLessHistory (line 1514) | function showLessHistory () {
  function showMoreHistory (line 1562) | function showMoreHistory () {
  function loadHistory (line 1608) | function loadHistory (forceRecent) {
  function showEmptyHistory (line 1710) | function showEmptyHistory () {
  function startBot (line 1720) | function startBot () {
  function cancelBot (line 1725) | function cancelBot () {
  function joinChannel (line 1729) | function joinChannel () {
  function togglePeerMuted (line 1737) | function togglePeerMuted (muted) {
  function toggleMessage (line 1744) | function toggleMessage (messageID, $event) {
  function selectInlineBot (line 1901) | function selectInlineBot (botID, $event) {
  function selectedCancel (line 1908) | function selectedCancel (noBroadcast) {
  function selectedFlush (line 1919) | function selectedFlush () {
  function selectedDelete (line 1927) | function selectedDelete (selectedMessageID) {
  function quickForward (line 1971) | function quickForward (msgID) {
  function selectedForward (line 1996) | function selectedForward (selectedMessageID) {
  function selectedReport (line 2038) | function selectedReport (selectedMessageID) {
  function selectedReply (line 2070) | function selectedReply (selectedMessageID) {
  function selectedEdit (line 2082) | function selectedEdit (selectedMessageID) {
  function toggleEdit (line 2094) | function toggleEdit () {
  function toggleMedia (line 2103) | function toggleMedia (mediaType) {
  function returnToRecent (line 2118) | function returnToRecent () {
  function submitMessage (line 2552) | function submitMessage (e) {
  function sendMessage (line 2566) | function sendMessage () {
  function editMessage (line 2593) | function editMessage () {
  function updateMentions (line 2608) | function updateMentions () {
  function updateCommands (line 2667) | function updateCommands () {
  function resetDraft (line 2714) | function resetDraft (newPeer, prevPeer) {
  function getDraft (line 2750) | function getDraft () {
  function applyDraftAttachment (line 2785) | function applyDraftAttachment (e, attachment) {
  function replySelect (line 2830) | function replySelect (messageID, byUser) {
  function setEditDraft (line 2847) | function setEditDraft (messageID) {
  function setEditLastMessage (line 2852) | function setEditLastMessage () {
  function replyClear (line 2868) | function replyClear (byUser) {
  function fwdsClear (line 2892) | function fwdsClear () {
  function fwdsSend (line 2904) | function fwdsSend () {
  function toggleSlash (line 2915) | function toggleSlash ($event) {
  function updateReplyKeyboard (line 2926) | function updateReplyKeyboard () {
  function replyKeyboardToggle (line 2954) | function replyKeyboardToggle ($event) {
  function onMessageChange (line 2963) | function onMessageChange (newVal, prevVal, a) {
  function checkInlinePattern (line 2997) | function checkInlinePattern (message) {
  function onTyping (line 3087) | function onTyping () {
  function onFilesSelected (line 3099) | function onFilesSelected (newVal) {
  function onStickerSelected (line 3123) | function onStickerSelected (newVal) {
  function onCommandSelected (line 3150) | function onCommandSelected (command) {
  function onInlineResultSelected (line 3172) | function onInlineResultSelected (qID) {
  function preloadPhotos (line 3303) | function preloadPhotos (sign) {
  function updatePrevNext (line 3318) | function updatePrevNext (count) {
  function movePosition (line 3386) | function movePosition (sign) {
  function loadMore (line 3424) | function loadMore () {
  function movePosition (line 3480) | function movePosition (sign, deleteCurrent) {
  function preloadPhotos (line 3517) | function preloadPhotos (sign) {
  function loadMore (line 3530) | function loadMore () {
  function updatePrevNext (line 3554) | function updatePrevNext (count) {
  function onChatUpdated (line 3982) | function onChatUpdated (updates) {
  function onPhotoSelected (line 4067) | function onPhotoSelected (photo) {
  function onChatUpdated (line 4155) | function onChatUpdated (updates) {
  function onPhotoSelected (line 4240) | function onPhotoSelected (photo) {
  function updatePasswordState (line 4372) | function updatePasswordState () {
  function onPhotoSelected (line 4388) | function onPhotoSelected (photo) {
  function updateSessions (line 4753) | function updateSessions () {
  function resetSelected (line 4963) | function resetSelected () {
  function updateContacts (line 4968) | function updateContacts (query) {
  function editTitle (line 5270) | function editTitle () {
  function editAbout (line 5279) | function editAbout () {
  function selectLink (line 5293) | function selectLink () {
  function updateLink (line 5299) | function updateLink (force) {
  function updateList (line 5433) | function updateList () {

FILE: app/js/directives.js
  function link (line 60) | function link ($scope, element, attrs) {
  function updateMessageText (line 189) | function updateMessageText ($scope, element, message) {
  function updateMessageMedia (line 200) | function updateMessageMedia ($scope, element, message) {
  function updateMessageSignature (line 214) | function updateMessageSignature ($scope, element, message) {
  function updateMessageKeyboard (line 225) | function updateMessageKeyboard ($scope, element, message) {
  function updateMessageBody (line 254) | function updateMessageBody ($scope, element, message) {
  function link (line 261) | function link ($scope, element, attrs) {
  function updateHtml (line 296) | function updateHtml (views, element) {
  function link (line 300) | function link ($scope, element, attrs) {
  function link (line 324) | function link ($scope, element, attrs) {
  function updateMessageText (line 470) | function updateMessageText (argument) {
  function link (line 501) | function link ($scope, element, attrs) {
  function link (line 528) | function link ($scope, element, attrs) {
  function link (line 544) | function link ($scope, element, attrs) {
  function link (line 574) | function link ($scope, element, attrs) {
  function checkMessage (line 587) | function checkMessage ($scope, element, mid, isEdit) {
  function updateMessage (line 604) | function updateMessage ($scope, element) {
  function link (line 634) | function link ($scope, element, attrs) {
  function updateMessage (line 650) | function updateMessage ($scope, element) {
  function updatePeerID (line 680) | function updatePeerID(peerID, $scope, force) {
  function link (line 699) | function link ($scope, element, attrs) {
  function link (line 735) | function link ($scope, element, attrs) {
  function updateMessages (line 745) | function updateMessages ($scope, element) {
  function link (line 783) | function link ($scope, element, attrs) {
  function checkEdited (line 795) | function checkEdited ($scope, element, messageID) {
  function link (line 824) | function link($scope, element, attrs) {
  function link (line 859) | function link ($scope, element, attrs) {
  function link (line 1040) | function link ($scope, element, attrs) {
  function link (line 1150) | function link ($scope, element, attrs) {
  function link (line 1182) | function link ($scope, element, attrs) {
  function link (line 1214) | function link ($scope, element, attrs) {
  function link (line 1239) | function link ($scope, element, attrs) {
  function link (line 1264) | function link ($scope, element, attrs) {
  function link (line 1665) | function link ($scope, element, attrs) {
  function link (line 2193) | function link ($scope, element, attrs) {
  function link (line 2272) | function link ($scope, element, attrs) {
  function link (line 2351) | function link ($scope, element, attrs) {
  function checkPlayer (line 2420) | function checkPlayer(newPlayer, newScope) {
  function toggleVideoPlayer (line 2433) | function toggleVideoPlayer ($scope, element) {
  function link (line 2456) | function link ($scope, element, attrs) {
  function checkPlayer (line 2540) | function checkPlayer(newPlayer, newScope) {
  function readVideoMessage (line 2553) | function readVideoMessage($scope) {
  function toggleVideoPlayer (line 2561) | function toggleVideoPlayer ($scope, element) {
  function link (line 2587) | function link ($scope, element, attrs) {
  function link (line 2672) | function link ($scope, element, attrs) {
  function updateModalWidth (line 2763) | function updateModalWidth (element, width) {
  function link (line 2772) | function link ($scope, element, attrs) {
  function link (line 2865) | function link ($scope, element, attrs) {
  function link (line 2896) | function link ($scope, element, attrs) {
  function isAnimationSupported (line 2904) | function isAnimationSupported (el) {
  function link (line 2956) | function link ($scope, element, attrs) {
  function link (line 2976) | function link ($scope, element, attrs) {
  function link (line 2988) | function link ($scope, element, attrs) {
  function link (line 3024) | function link ($scope, element, attrs) {
  function link (line 3039) | function link ($scope, element, attrs) {
  function link (line 3066) | function link ($scope, element, attrs) {
  function link (line 3109) | function link ($scope, element, attrs) {
  function updateAll (line 3160) | function updateAll () {
  function link (line 3166) | function link ($scope, element, attrs) {
  function updateAll (line 3218) | function updateAll () {
  function link (line 3224) | function link ($scope, element, attrs) {
  function link (line 3320) | function link ($scope, element, attrs) {
  function updateClass (line 3333) | function updateClass (peerID, element, className) {
  function link (line 3345) | function link ($scope, element, attrs) {
  function link (line 3439) | function link ($scope, element, attrs) {
  function checkAudioPlayer (line 3598) | function checkAudioPlayer (newPlayerScope) {
  function link (line 3612) | function link ($scope, element, attrs) {
  function link (line 3710) | function link ($scope, element, attrs) {
  function link (line 3825) | function link ($scope, element, attrs) {
  function link (line 3870) | function link ($scope, element, attrs) {
  function link (line 3897) | function link ($scope, element, attrs) {
  function link (line 3945) | function link ($scope, element, attrs) {
  function updateProgress (line 3968) | function updateProgress (bar, progress, fullLen) {
  function link (line 4135) | function link ($scope, element, attrs) {
  function link (line 4170) | function link ($scope, element, attrs) {
  function link (line 4189) | function link ($scope, element, attrs) {

FILE: app/js/directives_mobile.js
  function link (line 19) | function link ($scope, element, attrs) {
  function link (line 100) | function link ($scope, element, attrs) {
  function link (line 344) | function link ($scope, element, attrs) {
  function link (line 370) | function link ($scope, element, attrs) {
  function link (line 394) | function link ($scope, element, attrs) {

FILE: app/js/lib/bin_utils.js
  function bigint (line 8) | function bigint (num) {
  function bigStringInt (line 12) | function bigStringInt (strNum) {
  function dHexDump (line 16) | function dHexDump (bytes) {
  function bytesToHex (line 34) | function bytesToHex (bytes) {
  function bytesFromHex (line 43) | function bytesFromHex (hexString) {
  function bytesToBase64 (line 61) | function bytesToBase64 (bytes) {
  function uint6ToBase64 (line 82) | function uint6ToBase64 (nUint6) {
  function base64ToBlob (line 96) | function base64ToBlob (base64str, mimeType) {
  function dataUrlToBlob (line 117) | function dataUrlToBlob (url) {
  function blobConstruct (line 128) | function blobConstruct (blobParts, mimeType) {
  function blobSafeMimeType (line 143) | function blobSafeMimeType(mimeType) {
  function bytesCmp (line 162) | function bytesCmp (bytes1, bytes2) {
  function bytesXor (line 176) | function bytesXor (bytes1, bytes2) {
  function bytesToWords (line 187) | function bytesToWords (bytes) {
  function bytesFromWords (line 201) | function bytesFromWords (wordArray) {
  function bytesFromBigInt (line 213) | function bytesFromBigInt (bigInt, len) {
  function bytesFromLeemonBigInt (line 235) | function bytesFromLeemonBigInt (bigInt, len) {
  function bytesToArrayBuffer (line 240) | function bytesToArrayBuffer (b) {
  function convertToArrayBuffer (line 244) | function convertToArrayBuffer (bytes) {
  function convertToUint8Array (line 256) | function convertToUint8Array (bytes) {
  function convertToByteArray (line 263) | function convertToByteArray (bytes) {
  function bytesFromArrayBuffer (line 275) | function bytesFromArrayBuffer (buffer) {
  function bufferConcat (line 287) | function bufferConcat (buffer1, buffer2) {
  function longToInts (line 297) | function longToInts (sLong) {
  function longToBytes (line 303) | function longToBytes (sLong) {
  function longFromInts (line 307) | function longFromInts (high, low) {
  function intToUint (line 311) | function intToUint (val) {
  function uintToInt (line 319) | function uintToInt (val) {
  function sha1HashSync (line 326) | function sha1HashSync (bytes) {
  function sha1BytesSync (line 336) | function sha1BytesSync (bytes) {
  function sha256HashSync (line 340) | function sha256HashSync (bytes) {
  function rsaEncrypt (line 350) | function rsaEncrypt (publicKey, bytes) {
  function addPadding (line 364) | function addPadding (bytes, blockSize, zeroes) {
  function aesEncryptSync (line 388) | function aesEncryptSync (bytes, keyBytes, ivBytes) {
  function aesDecryptSync (line 406) | function aesDecryptSync (encryptedBytes, keyBytes, ivBytes) {
  function gzipUncompress (line 421) | function gzipUncompress (bytes) {
  function nextRandomInt (line 428) | function nextRandomInt (maxValue) {
  function pqPrimeFactorization (line 432) | function pqPrimeFactorization (pqBytes) {
  function pqPrimeBigInteger (line 466) | function pqPrimeBigInteger (what) {
  function gcdLong (line 523) | function gcdLong (a, b) {
  function pqPrimeLong (line 540) | function pqPrimeLong (what) {
  function pqPrimeLeemon (line 597) | function pqPrimeLeemon (what) {
  function bytesModPow (line 675) | function bytesModPow (x, y, m) {

FILE: app/js/lib/config.js
  function storageSetPrefix (line 133) | function storageSetPrefix (newPrefix) {
  function storageSetNoPrefix (line 137) | function storageSetNoPrefix () {
  function storageGetPrefix (line 141) | function storageGetPrefix () {
  function storageGetValue (line 149) | function storageGetValue (keys, callback) {
  function storageSetValue (line 205) | function storageSetValue (obj, callback) {
  function storageRemoveValue (line 238) | function storageRemoveValue (keys, callback) {
  function storageClear (line 267) | function storageClear (callback) {

FILE: app/js/lib/i18n.js
  function insertParams (line 10) | function insertParams (msgstr, params) {
  function parseMarkdownString (line 24) | function parseMarkdownString (msgstr, msgid) {
  function _ (line 32) | function _ (msgid, params) {

FILE: app/js/lib/mtproto.js
  function chooseServer (line 29) | function chooseServer (dcID, upload) {
  function prepareRsaKeys (line 144) | function prepareRsaKeys () {
  function selectRsaKeyByFingerPrint (line 170) | function selectRsaKeyByFingerPrint (fingerprints) {
  function generateMessageID (line 205) | function generateMessageID () {
  function applyServerTime (line 224) | function applyServerTime (serverTime, localTime) {
  function mtpSendPlainRequest (line 250) | function mtpSendPlainRequest (dcID, requestBuffer) {
  function mtpSendReqPQ (line 307) | function mtpSendReqPQ (auth) {
  function mtpSendReqDhParams (line 358) | function mtpSendReqDhParams (auth) {
  function mtpDecryptServerDhDataAnswer (line 429) | function mtpDecryptServerDhDataAnswer (auth, encryptedAnswer) {
  function mtpVerifyDhParams (line 474) | function mtpVerifyDhParams(g, dhPrime, gA) {
  function mtpSendSetClientDhParams (line 512) | function mtpSendSetClientDhParams (auth) {
  function mtpAuth (line 616) | function mtpAuth (dcID) {
  function MtpNetworker (line 671) | function MtpNetworker (dcID, authKey, serverSalt, options) {
  function startAll (line 1682) | function startAll () {
  function stopAll (line 1689) | function stopAll () {

FILE: app/js/lib/mtproto_wrapper.js
  function telegramMeNotify (line 26) | function telegramMeNotify (newValue) {
  function mtpSetUserAuth (line 33) | function mtpSetUserAuth (dcID, userAuth) {
  function mtpLogOut (line 45) | function mtpLogOut () {
  function mtpClearStorage (line 74) | function mtpClearStorage () {
  function mtpGetNetworker (line 96) | function mtpGetNetworker (dcID, options) {
  function mtpInvokeApi (line 149) | function mtpInvokeApi (method, params, options) {
  function mtpGetUserID (line 290) | function mtpGetUserID () {
  function getBaseDcID (line 297) | function getBaseDcID () {
  function downloadRequest (line 321) | function downloadRequest (dcID, cb, activeDelta) {
  function downloadCheck (line 338) | function downloadCheck (dcID) {
  function getFileName (line 366) | function getFileName (location) {
  function getTempFileName (line 389) | function getTempFileName (file) {
  function getCachedFile (line 395) | function getCachedFile (location) {
  function getFileStorage (line 404) | function getFileStorage () {
  function saveSmallFile (line 416) | function saveSmallFile (location, bytes) {
  function downloadSmallFile (line 430) | function downloadSmallFile (location) {
  function getDownloadedFile (line 484) | function getDownloadedFile (location, size) {
  function downloadFile (line 491) | function downloadFile (dcID, location, size, options) {
  function uploadFile (line 639) | function uploadFile (file) {
  function start (line 754) | function start () {
  function clearInstance (line 770) | function clearInstance () {
  function deactivateInstance (line 777) | function deactivateInstance () {
  function checkInstance (line 805) | function checkInstance () {

FILE: app/js/lib/ng_utils.js
  function isBlobAvailable (line 72) | function isBlobAvailable () {
  function fileCopyTo (line 76) | function fileCopyTo (fromFileEntry, toFileEntry) {
  function fileWriteData (line 89) | function fileWriteData (fileWriter, bytes) {
  function chooseSaveFile (line 120) | function chooseSaveFile (fileName, ext, mimeType) {
  function getFileWriter (line 140) | function getFileWriter (fileEntry) {
  function getFakeFileWriter (line 152) | function getFakeFileWriter (mimeType, saveFileCallback) {
  function getUrl (line 184) | function getUrl (fileData, mimeType) {
  function getByteArray (line 196) | function getByteArray (fileData) {
  function getDataUrl (line 230) | function getDataUrl (blob) {
  function getFileCorrectUrl (line 247) | function getFileCorrectUrl (blob, mimeType) {
  function downloadFile (line 257) | function downloadFile (blob, mimeType, fileName) {
  function isAvailable (line 369) | function isAvailable () {
  function openDatabase (line 373) | function openDatabase () {
  function saveFile (line 433) | function saveFile (fileName, blob) {
  function saveFileBase64 (line 469) | function saveFileBase64 (db, fileName, blob) {
  function storagePutB64String (line 512) | function storagePutB64String (db, fileName, b64string) {
  function getBlobSize (line 534) | function getBlobSize (blob) {
  function getFile (line 538) | function getFile (fileName) {
  function getFileWriter (line 564) | function getFileWriter (fileName, mimeType) {
  function requestFS (line 589) | function requestFS () {
  function isAvailable (line 611) | function isAvailable () {
  function getFile (line 615) | function getFile (fileName, size) {
  function saveFile (line 639) | function saveFile (fileName, blob) {
  function getFileWriter (line 647) | function getFileWriter (fileName) {
  function isAvailable (line 684) | function isAvailable () {
  function getFile (line 688) | function getFile (fileName, size) {
  function saveFile (line 695) | function saveFile (fileName, blob) {
  function getFileWriter (line 699) | function getFileWriter (fileName, mimeType) {
  function getCanvasFromWebp (line 730) | function getCanvasFromWebp (data) {
  function getPngBlobFromWebp (line 805) | function getPngBlobFromWebp (data) {
  function performTaskWorker (line 876) | function performTaskWorker (task, params, embed) {
  function downloadByURL (line 987) | function downloadByURL (url) {
  function start (line 1040) | function start () {
  function onEvent (line 1051) | function onEvent (e) {
  function isAvailable (line 1106) | function isAvailable () {
  function getPosition (line 1110) | function getPosition (force) {
  function getEmojiSpritesheetCoords (line 1278) | function getEmojiSpritesheetCoords (emojiCode) {
  function parseEntities (line 1295) | function parseEntities (text, options) {
  function parseEmojis (line 1404) | function parseEmojis (text) {
  function parseMarkdown (line 1414) | function parseMarkdown (text, entities, noTrim) {
  function mergeEntities (line 1482) | function mergeEntities (currentEntities, newEntities, fromApi) {
  function wrapRichNestedText (line 1546) | function wrapRichNestedText (text, nested, options) {
  function wrapRichText (line 1555) | function wrapRichText (text, options) {
  function wrapDraftText (line 1781) | function wrapDraftText (text, options) {
  function checkBrackets (line 1863) | function checkBrackets (url) {
  function replaceUrlEncodings (line 1880) | function replaceUrlEncodings(urlWithEncoded) {
  function wrapPlainText (line 1890) | function wrapPlainText (text, options) {
  function wrapUrl (line 1927) | function wrapUrl (url, unsafe) {
  function start (line 2028) | function start() {
  function setLocalNotificationsDisabled (line 2036) | function setLocalNotificationsDisabled() {
  function getSubscription (line 2040) | function getSubscription() {
  function subscribe (line 2055) | function subscribe() {
  function unsubscribe (line 2079) | function unsubscribe() {
  function forceUnsubscribe (line 2106) | function forceUnsubscribe() {
  function isAliveNotify (line 2129) | function isAliveNotify() {
  function setSettings (line 2158) | function setSettings(newSettings) {
  function hidePushNotifications (line 2164) | function hidePushNotifications() {
  function setUpServiceWorkerChannel (line 2174) | function setUpServiceWorkerChannel() {
  function pushSubscriptionNotify (line 2192) | function pushSubscriptionNotify(event, subscription) {

FILE: app/js/lib/polyfill.js
  function setZeroTimeout (line 115) | function setZeroTimeout (fn) {
  function clearZeroTimeout (line 122) | function clearZeroTimeout(timeoutId) {
  function handleMessage (line 134) | function handleMessage (event) {

FILE: app/js/lib/push_worker.js
  function fireNotification (line 114) | function fireNotification(obj, settings, lang) {
  function pushToNotifications (line 169) | function pushToNotifications(notification) {
  function onCloseNotification (line 176) | function onCloseNotification(event) {
  function removeFromNotifications (line 180) | function removeFromNotifications(notification) {
  function closeAllNotifications (line 187) | function closeAllNotifications() {
  function isAvailable (line 270) | function isAvailable () {
  function openDatabase (line 274) | function openDatabase () {
  function setItem (line 333) | function setItem (key, value) {
  function getItem (line 355) | function getItem (key) {
  function getMuteUntil (line 391) | function getMuteUntil() {
  function getLastAliveTime (line 403) | function getLastAliveTime() {
  function getLang (line 415) | function getLang() {
  function getSettings (line 427) | function getSettings() {
  function userInvisibleIsSupported (line 439) | function userInvisibleIsSupported() {

FILE: app/js/lib/tl_utils.js
  function TLSerialization (line 8) | function TLSerialization (options) {
  function TLDeserialization (line 348) | function TLDeserialization (buffer, options) {

FILE: app/js/lib/utils.js
  function dT (line 9) | function dT () {
  function checkClick (line 13) | function checkClick (e, noprevent) {
  function isInDOM (line 25) | function isInDOM (element, parentNode) {
  function checkDragEvent (line 36) | function checkDragEvent (e) {
  function cancelEvent (line 51) | function cancelEvent (event) {
  function hasOnclick (line 65) | function hasOnclick (element) {
  function getScrollWidth (line 77) | function getScrollWidth () {
  function onCtrlEnter (line 92) | function onCtrlEnter (textarea, cb) {
  function setFieldSelection (line 101) | function setFieldSelection (field, from, to) {
  function getFieldSelection (line 124) | function getFieldSelection (field) {
  function getRichValue (line 155) | function getRichValue (field) {
  function getRichValueWithCaret (line 173) | function getRichValueWithCaret (field) {
  function getRichElementValue (line 209) | function getRichElementValue (node, lines, line, selNode, selOffset) {
  function setRichFocus (line 251) | function setRichFocus (field, selectNode, noCollapse) {
  function getSelectedText (line 285) | function getSelectedText () {
  function scrollToNode (line 295) | function scrollToNode (scrollable, node, scroller) {
  function onContentLoaded (line 324) | function onContentLoaded (cb) {
  function tsNow (line 329) | function tsNow (seconds) {
  function safeReplaceObject (line 334) | function safeReplaceObject (wasObject, newObject) {
  function listMergeSorted (line 347) | function listMergeSorted (list1, list2) {
  function listUniqSorted (line 363) | function listUniqSorted (list) {
  function templateUrl (line 377) | function templateUrl (tplName) {
  function encodeEntities (line 404) | function encodeEntities (value) {
  function calcImageInBox (line 414) | function calcImageInBox (imageW, imageH, boxW, boxH, noZooom) {
  function versionCompare (line 441) | function versionCompare (ver1, ver2) {
  function createIndex (line 471) | function createIndex () {
  function cleanSearchText (line 478) | function cleanSearchText (text) {
  function cleanUsername (line 493) | function cleanUsername (username) {
  function indexObject (line 497) | function indexObject (id, searchText, searchIndex) {
  function search (line 526) | function search (query, searchIndex) {

FILE: app/js/message_composer.js
  function getPopularEmoji (line 48) | function getPopularEmoji (callback) {
  function pushPopularEmoji (line 81) | function pushPopularEmoji (code) {
  function indexEmojis (line 107) | function indexEmojis () {
  function searchEmojis (line 119) | function searchEmojis (q) {
  function EmojiTooltip (line 144) | function EmojiTooltip (btnEl, options) {
  function EmojiPanel (line 641) | function EmojiPanel (containerEl, options) {
  function MessageComposer (line 697) | function MessageComposer (textarea, options) {
  function Scroller (line 1616) | function Scroller (content, options) {

FILE: app/js/messages_manager.js
  function getConversations (line 61) | function getConversations (query, offsetIndex, limit) {
  function getConversation (line 120) | function getConversation(peerID) {
  function getDialogByPeerID (line 133) | function getDialogByPeerID (peerID) {
  function saveConversation (line 143) | function saveConversation (dialog) {
  function getTopMessages (line 251) | function getTopMessages (limit) {
  function generateDialogPinnedDate (line 314) | function generateDialogPinnedDate() {
  function generateDialogIndex (line 318) | function generateDialogIndex (date) {
  function pushDialogToStorage (line 325) | function pushDialogToStorage (dialog, offsetDate) {
  function requestHistory (line 361) | function requestHistory (peerID, maxID, limit, offset) {
  function fillHistoryStorage (line 443) | function fillHistoryStorage (peerID, maxID, fullLimit, historyStorage) {
  function wrapHistoryResult (line 504) | function wrapHistoryResult (peerID, result) {
  function migrateChecks (line 520) | function migrateChecks (migrateFrom, migrateTo) {
  function convertMigratedPeer (line 543) | function convertMigratedPeer (peerID) {
  function getHistory (line 549) | function getHistory (peerID, maxID, limit, backLimit, prerendered) {
  function getReplyKeyboard (line 692) | function getReplyKeyboard (peerID) {
  function mergeReplyKeyboard (line 696) | function mergeReplyKeyboard (historyStorage, message) {
  function getSearch (line 769) | function getSearch (peerID, query, inputFilter, maxID, limit) {
  function getMessage (line 965) | function getMessage (messageID) {
  function canMessageBeEdited (line 973) | function canMessageBeEdited(message) {
  function canEditMessage (line 997) | function canEditMessage(messageID) {
  function canReportMessage (line 1016) | function canReportMessage(messageID) {
  function getMessageEditData (line 1029) | function getMessageEditData(messageID) {
  function canRevokeMessage (line 1057) | function canRevokeMessage(messageID) {
  function deleteMessages (line 1086) | function deleteMessages (messageIDs, revoke) {
  function getMessageShareLink (line 1149) | function getMessageShareLink (fullMsgID) {
  function readHistory (line 1172) | function readHistory (peerID) {
  function readMessages (line 1265) | function readMessages (messageIDs) {
  function doFlushHistory (line 1302) | function doFlushHistory (inputPeer, justClear) {
  function flushHistory (line 1327) | function flushHistory (peerID, justClear) {
  function saveMessages (line 1362) | function saveMessages (apiMessages, options) {
  function sendText (line 1564) | function sendText (peerID, text, options) {
  function sendFile (line 1756) | function sendFile (peerID, file, options) {
  function sendOther (line 1941) | function sendOther (peerID, inputMedia, options) {
  function forwardMessages (line 2144) | function forwardMessages (peerID, mids, options) {
  function reportMessages (line 2193) | function reportMessages (mids, reason) {
  function startBot (line 2212) | function startBot (botID, chatID, startParam) {
  function shareGame (line 2262) | function shareGame (botID, peerID, inputGame) {
  function cancelPendingMessage (line 2277) | function cancelPendingMessage (randomID) {
  function finalizePendingMessage (line 2309) | function finalizePendingMessage (randomID, finalMessage) {
  function finalizePendingMessageCallbacks (line 2354) | function finalizePendingMessageCallbacks(tempID, mid) {
  function getInputEntities (line 2365) | function getInputEntities(entities) {
  function editMessage (line 2376) | function editMessage(messageID, text) {
  function getMessagePeer (line 2425) | function getMessagePeer (message) {
  function wrapForDialog (line 2436) | function wrapForDialog (msgID, dialog) {
  function wrapSingleMessage (line 2487) | function wrapSingleMessage (msgID) {
  function clearDialogCache (line 2500) | function clearDialogCache (msgID) {
  function wrapForHistory (line 2504) | function wrapForHistory (msgID) {
  function wrapReplyMarkup (line 2605) | function wrapReplyMarkup (replyMarkup, fromID) {
  function wrapMessageText (line 2635) | function wrapMessageText(msgID) {
  function fetchSingleMessages (line 2660) | function fetchSingleMessages () {
  function incrementMessageViews (line 2695) | function incrementMessageViews () {
  function regroupWrappedHistory (line 2736) | function regroupWrappedHistory (history, limit) {
  function getMessageThumb (line 2843) | function getMessageThumb (message, thumbWidth, thumbHeight) {
  function incrementMaxSeenID (line 2880) | function incrementMaxSeenID (maxID) {
  function notifyAboutMessage (line 2892) | function notifyAboutMessage (message, options) {
  function handleNewMessages (line 3111) | function handleNewMessages () {
  function handleNewDialogs (line 3118) | function handleNewDialogs () {
  function handleNotifications (line 3140) | function handleNotifications () {
  function handleUpdate (line 3165) | function handleUpdate(update) {
  function reloadConversation (line 3764) | function reloadConversation (peerID) {
  function applyConversations (line 3772) | function applyConversations(dialogsResult) {
  function getFullMessageID (line 3919) | function getFullMessageID (msgID, channelID) {
  function getMessageIDInfo (line 3934) | function getMessageIDInfo (fullMsgID) {
  function getMessageLocalID (line 3944) | function getMessageLocalID (fullMsgID) {
  function splitMessageIDsByChannels (line 3951) | function splitMessageIDsByChannels (mids) {

FILE: app/js/offline_manager.js
  function updateFound (line 30) | function updateFound () {

FILE: app/js/services.js
  function fillContacts (line 28) | function fillContacts () {
  function getUserSearchText (line 50) | function getUserSearchText (id) {
  function getContacts (line 67) | function getContacts (query) {
  function resolveUsername (line 94) | function resolveUsername (username) {
  function saveApiUsers (line 98) | function saveApiUsers (apiUsers) {
  function saveApiUser (line 102) | function saveApiUser (apiUser, noReplace) {
  function saveUserAccess (line 174) | function saveUserAccess (id, accessHash) {
  function getUserStatusForSort (line 178) | function getUserStatusForSort (status) {
  function getUser (line 198) | function getUser (id) {
  function getSelf (line 205) | function getSelf () {
  function isBot (line 209) | function isBot (id) {
  function hasUser (line 213) | function hasUser (id, allowMin) {
  function getUserPhoto (line 218) | function getUserPhoto (id) {
  function getUserString (line 238) | function getUserString (id) {
  function getUserInput (line 243) | function getUserInput (id) {
  function updateUsersStatuses (line 255) | function updateUsersStatuses () {
  function forceUserOnline (line 269) | function forceUserOnline (id) {
  function wrapForFull (line 293) | function wrapForFull (id) {
  function openUser (line 299) | function openUser (userID, override) {
  function importContact (line 313) | function importContact (phone, firstName, lastName) {
  function importContacts (line 335) | function importContacts (contacts) {
  function deleteContacts (line 368) | function deleteContacts (userIDs) {
  function onContactUpdated (line 382) | function onContactUpdated (userID, isContact) {
  function openImportContact (line 400) | function openImportContact () {
  function setUserStatus (line 413) | function setUserStatus (userID, offline) {
  function isAvailable (line 519) | function isAvailable () {
  function openPhonebookImport (line 531) | function openPhonebookImport () {
  function getPhonebookContacts (line 539) | function getPhonebookContacts () {
  function saveApiChats (line 602) | function saveApiChats (apiChats) {
  function saveApiChat (line 606) | function saveApiChat (apiChat) {
  function getChat (line 652) | function getChat (id) {
  function hasRights (line 656) | function hasRights (id, action) {
  function resolveUsername (line 703) | function resolveUsername (username) {
  function saveChannelAccess (line 707) | function saveChannelAccess (id, accessHash) {
  function saveIsMegagroup (line 711) | function saveIsMegagroup (id) {
  function isChannel (line 715) | function isChannel (id) {
  function isMegagroup (line 724) | function isMegagroup (id) {
  function isBroadcast (line 735) | function isBroadcast (id) {
  function getChatInput (line 739) | function getChatInput (id) {
  function getChannelInput (line 743) | function getChannelInput (id) {
  function hasChat (line 754) | function hasChat (id, allowMin) {
  function getChatPhoto (line 759) | function getChatPhoto (id) {
  function getChatString (line 772) | function getChatString (id) {
  function wrapForFull (line 780) | function wrapForFull (id, fullChat) {
  function wrapParticipants (line 803) | function wrapParticipants(id, participants) {
  function openChat (line 831) | function openChat (chatID, accessHash) {
  function getInputPeer (line 885) | function getInputPeer (peerString) {
  function getInputPeerByID (line 915) | function getInputPeerByID (peerID) {
  function getPeerSearchText (line 941) | function getPeerSearchText (peerID) {
  function getPeerString (line 952) | function getPeerString (peerID) {
  function getOutputPeer (line 959) | function getOutputPeer (peerID) {
  function resolveUsername (line 970) | function resolveUsername (username) {
  function getPeerID (line 998) | function getPeerID (peerString) {
  function getPeer (line 1010) | function getPeer (peerID) {
  function getPeerPhoto (line 1016) | function getPeerPhoto (peerID) {
  function getPeerMigratedTo (line 1022) | function getPeerMigratedTo(peerID) {
  function isChannel (line 1033) | function isChannel (peerID) {
  function isMegagroup (line 1037) | function isMegagroup (peerID) {
  function isAnyGroup (line 1041) | function isAnyGroup (peerID) {
  function isBroadcast (line 1045) | function isBroadcast (id) {
  function isBot (line 1049) | function isBot (peerID) {
  function saveBotInfo (line 1078) | function saveBotInfo (botInfo) {
  function getProfile (line 1096) | function getProfile (id, override) {
  function getPeerBots (line 1131) | function getPeerBots (peerID) {
  function getChatFull (line 1155) | function getChatFull (id) {
  function getChatInviteLink (line 1188) | function getChatInviteLink (id, force) {
  function getChannelParticipants (line 1214) | function getChannelParticipants (id, filter, limit, offset) {
  function getChannelFull (line 1306) | function getChannelFull (id, force) {
  function invalidateChannelParticipants (line 1355) | function invalidateChannelParticipants(id) {
  function getChannelPinnedMessage (line 1366) | function getChannelPinnedMessage(id) {
  function hideChannelPinnedMessage (line 1381) | function hideChannelPinnedMessage(id, pinnedMessageID) {
  function savePhoto (line 1488) | function savePhoto (apiPhoto, context) {
  function choosePhotoSize (line 1506) | function choosePhotoSize (photo, width, height) {
  function getUserPhotos (line 1527) | function getUserPhotos (userID, maxID, limit) {
  function preloadPhoto (line 1550) | function preloadPhoto (photoID) {
  function getPhoto (line 1578) | function getPhoto (photoID) {
  function wrapForHistory (line 1582) | function wrapForHistory (photoID, options) {
  function wrapForFull (line 1616) | function wrapForFull (photoID) {
  function openPhoto (line 1647) | function openPhoto (photoID, list) {
  function downloadPhoto (line 1681) | function downloadPhoto (photoID) {
  function saveWebPage (line 1743) | function saveWebPage (apiWebPage, messageID, mediaContext) {
  function openEmbed (line 1823) | function openEmbed (webpageID, messageID) {
  function wrapForHistory (line 1838) | function wrapForHistory (webPageID) {
  function wrapForFull (line 1851) | function wrapForFull (webPageID) {
  function saveGame (line 1910) | function saveGame (apiGame, messageID, mediaContext) {
  function openGame (line 1934) | function openGame (gameID, messageID, embedUrl) {
  function wrapForHistory (line 1950) | function wrapForHistory (gameID) {
  function wrapForFull (line 1963) | function wrapForFull (gameID, msgID, embedUrl) {
  function saveDoc (line 2005) | function saveDoc (apiDoc, context) {
  function getDoc (line 2110) | function getDoc (docID) {
  function hasDoc (line 2114) | function hasDoc (docID) {
  function getFileName (line 2118) | function getFileName (doc) {
  function wrapForHistory (line 2129) | function wrapForHistory (docID) {
  function updateDocDownloaded (line 2195) | function updateDocDownloaded (docID) {
  function downloadDoc (line 2215) | function downloadDoc (docID, toFileEntry) {
  function openDoc (line 2274) | function openDoc (docID, messageID) {
  function saveDocFile (line 2288) | function saveDocFile (docID) {
  function wrapVideoForFull (line 2306) | function wrapVideoForFull (docID) {
  function openVideo (line 2332) | function openVideo (docID, messageID) {
  function start (line 2444) | function start () {
  function getStickers (line 2451) | function getStickers (force) {
  function processRawStickers (line 2487) | function processRawStickers (stickers) {
  function indexStickerSetEmoticons (line 2537) | function indexStickerSetEmoticons(fullSet) {
  function searchStickers (line 2564) | function searchStickers(emojiCode) {
  function getStickerSets (line 2595) | function getStickerSets (allStickers, prevCachedSets) {
  function getPopularStickers (line 2622) | function getPopularStickers () {
  function pushPopularSticker (line 2639) | function pushPopularSticker (id) {
  function getStickerset (line 2665) | function getStickerset (inputStickerset) {
  function installStickerset (line 2676) | function installStickerset (fullSet, uninstall) {
  function openStickersetLink (line 2702) | function openStickersetLink (shortName) {
  function openStickerset (line 2709) | function openStickerset (inputStickerset) {
  function getStickerSetsHash (line 2720) | function getStickerSetsHash (stickerSets) {
  function getPopularBots (line 2750) | function getPopularBots () {
  function pushPopularBot (line 2772) | function pushPopularBot (id) {
  function resolveInlineMention (line 2802) | function resolveInlineMention (username) {
  function getInlineResults (line 2833) | function getInlineResults (peerID, botID, query, geo, offset) {
  function regroupWrappedResults (line 2873) | function regroupWrappedResults (results, rowW, rowH) {
  function switchToPM (line 2948) | function switchToPM (fromPeerID, botID, startParam) {
  function checkSwitchReturn (line 2957) | function checkSwitchReturn (botID) {
  function switchInlineQuery (line 2974) | function switchInlineQuery (botID, toPeerString, query) {
  function switchInlineButtonClick (line 2985) | function switchInlineButtonClick (id, button) {
  function callbackButtonClick (line 3006) | function callbackButtonClick (id, button) {
  function gameButtonClick (line 3028) | function gameButtonClick (id) {
  function showCallbackMessage (line 3047) | function showCallbackMessage(message, isAlert) {
  function sendInlineResult (line 3068) | function sendInlineResult (peerID, qID, options) {
  function checkGeoLocationAccess (line 3161) | function checkGeoLocationAccess (botID) {
  function popPendingSeqUpdate (line 3198) | function popPendingSeqUpdate () {
  function popPendingPtsUpdate (line 3231) | function popPendingPtsUpdate (channelID) {
  function forceGetDifference (line 3279) | function forceGetDifference () {
  function processUpdateMessage (line 3285) | function processUpdateMessage (updateMessage, fromMTProto) {
  function getDifference (line 3346) | function getDifference () {
  function getChannelDifference (line 3418) | function getChannelDifference (channelID) {
  function addChannelState (line 3487) | function addChannelState (channelID, pts) {
  function getChannelState (line 3503) | function getChannelState (channelID, pts) {
  function processUpdate (line 3510) | function processUpdate (update, options) {
  function saveUpdate (line 3656) | function saveUpdate (update) {
  function attach (line 3660) | function attach () {
  function start (line 3706) | function start () {
  function sendUpdateStatusReq (line 3714) | function sendUpdateStatusReq (offline) {
  function checkIDLE (line 3728) | function checkIDLE () {
  function isOtherDeviceActive (line 3740) | function isOtherDeviceActive () {
  function updateNotifySettings (line 3924) | function updateNotifySettings () {
  function getNotifySettings (line 3951) | function getNotifySettings () {
  function getPeerSettings (line 3955) | function getPeerSettings (peerID) {
  function setFavicon (line 3968) | function setFavicon (href) {
  function savePeerSettings (line 3983) | function savePeerSettings (peerID, settings) {
  function updatePeerSettings (line 3989) | function updatePeerSettings (peerID, settings) {
  function getPeerMuted (line 4004) | function getPeerMuted (peerID) {
  function start (line 4011) | function start () {
  function stop (line 4031) | function stop () {
  function requestPermission (line 4038) | function requestPermission () {
  function notify (line 4043) | function notify (data) {
  function playSound (line 4164) | function playSound (volume) {
  function notificationCancel (line 4179) | function notificationCancel (key) {
  function notificationHide (line 4199) | function notificationHide (key) {
  function notificationSoundReset (line 4212) | function notificationSoundReset (tag) {
  function notificationsClear (line 4216) | function notificationsClear () {
  function registerDevice (line 4234) | function registerDevice (tokenData) {
  function unregisterDevice (line 4250) | function unregisterDevice (tokenData) {
  function getVibrateSupport (line 4265) | function getVibrateSupport () {
  function getState (line 4279) | function getState (options) {
  function updateSettings (line 4285) | function updateSettings (state, settings) {
  function check (line 4332) | function check (state, password, options) {
  function requestRecovery (line 4340) | function requestRecovery (state, options) {
  function recover (line 4344) | function recover (code, options) {
  function makePasswordHash (line 4350) | function makePasswordHash (salt, password) {
  function show (line 4368) | function show (params, options) {
  function alert (line 4392) | function alert (title, description) {
  function confirm (line 4399) | function confirm (params, options, data) {
  function selectPeer (line 4434) | function selectPeer (options) {
  function selectPeers (line 4452) | function selectPeers (options) {
  function select (line 4483) | function select (multiSelect, options) {
  function checkUpdate (line 4516) | function checkUpdate () {
  function showChangelog (line 4549) | function showChangelog (lastVersion) {
  function check (line 4570) | function check () {
  function start (line 4590) | function start () {
  function switchLayout (line 4611) | function switchLayout (mobile) {
  function layoutCheck (line 4621) | function layoutCheck (e) {
  function start (line 4651) | function start () {
  function sendAsyncRequest (line 4672) | function sendAsyncRequest (canRedirect) {
  function checkLocationTgAddr (line 4708) | function checkLocationTgAddr () {
  function handleTgProtoAddr (line 4723) | function handleTgProtoAddr (url, inner) {
  function handleActivityMessage (line 4839) | function handleActivityMessage (name, data) {
  function start (line 4891) | function start () {
  function openUrl (line 4937) | function openUrl(url) {
  function shareUrl (line 4951) | function shareUrl (url, text, shareLink) {
  function openChatInviteLink (line 4968) | function openChatInviteLink (hash) {
  function getDraft (line 5041) | function getDraft (peerID, unsyncOnly) {
  function getServerDraft (line 5068) | function getServerDraft (peerID) {
  function saveDraft (line 5076) | function saveDraft (peerID, apiDraft, options) {
  function changeDraft (line 5094) | function changeDraft (peerID, draft) {
  function clearDraft (line 5124) | function clearDraft (peerID, alsoSync) {
  function draftsAreEqual (line 5140) | function draftsAreEqual (draft1, draft2) {
  function isEmptyDraft (line 5158) | function isEmptyDraft (draft) {
  function processApiDraft (line 5171) | function processApiDraft (draft) {
  function syncDraft (line 5191) | function syncDraft (peerID) {

FILE: app/nacl/aes.h
  type aes_key_st (line 76) | struct aes_key_st {
  type AES_KEY (line 84) | typedef struct aes_key_st AES_KEY;

FILE: app/nacl/aes_core.c
  function private_AES_set_encrypt_key (line 628) | int private_AES_set_encrypt_key(const unsigned char *userKey, const int ...
  function private_AES_set_decrypt_key (line 729) | int private_AES_set_decrypt_key(const unsigned char *userKey, const int ...
  function AES_encrypt (line 781) | void AES_encrypt(const unsigned char *in, unsigned char *out,
  function AES_decrypt (line 972) | void AES_decrypt(const unsigned char *in, unsigned char *out,
  function private_AES_set_encrypt_key (line 1204) | int private_AES_set_encrypt_key(const unsigned char *userKey, const int ...
  function private_AES_set_decrypt_key (line 1304) | int private_AES_set_decrypt_key(const unsigned char *userKey, const int ...

FILE: app/nacl/aes_ige.c
  type aes_block_t (line 60) | typedef struct {
  function AES_ige_encrypt (line 81) | void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
  function AES_bi_ige_encrypt (line 215) | void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,

FILE: app/nacl/aes_locl.h
  type u32 (line 75) | typedef unsigned long u32;
  type u32 (line 77) | typedef unsigned int u32;
  type u16 (line 79) | typedef unsigned short u16;
  type u8 (line 80) | typedef unsigned char u8;

FILE: app/nacl/aes_misc.c
  function AES_set_encrypt_key (line 69) | int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
  function AES_set_decrypt_key (line 78) | int AES_set_decrypt_key(const unsigned char *userKey, const int bits,

FILE: app/nacl/mtproto_crypto.cc
  function gcd (line 37) | uint64_t gcd(uint64_t a, uint64_t b) {
  class MtprotoCryptoInstance (line 63) | class MtprotoCryptoInstance : public pp::Instance {
    method MtprotoCryptoInstance (line 67) | explicit MtprotoCryptoInstance(PP_Instance instance) : pp::Instance(in...
    method HandleMessage (line 76) | virtual void HandleMessage(const pp::Var& var_message) {
  class MtprotoCryptoModule (line 245) | class MtprotoCryptoModule : public pp::Module {
    method MtprotoCryptoModule (line 247) | MtprotoCryptoModule() : pp::Module() {}
  type pp (line 258) | namespace pp {
    function Module (line 264) | Module* CreateModule() {

FILE: app/vendor/angular-media-player/angular-media-player.js
  function playlistWatch (line 355) | function playlistWatch(player) {

FILE: app/vendor/angular/angular-animate.js
  function assertArg (line 64) | function assertArg(arg, name, reason) {
  function mergeClasses (line 71) | function mergeClasses(a,b) {
  function packageStyles (line 80) | function packageStyles(options) {
  function pendClasses (line 89) | function pendClasses(classes, fix, isPrefix) {
  function removeFromArray (line 106) | function removeFromArray(arr, val) {
  function stripCommentsFromElement (line 113) | function stripCommentsFromElement(element) {
  function extractElementNode (line 138) | function extractElementNode(element) {
  function $$addClass (line 148) | function $$addClass($$jqLite, element, className) {
  function $$removeClass (line 154) | function $$removeClass($$jqLite, element, className) {
  function applyAnimationClassesFactory (line 160) | function applyAnimationClassesFactory($$jqLite) {
  function prepareAnimationOptions (line 173) | function prepareAnimationOptions(options) {
  function applyAnimationStyles (line 187) | function applyAnimationStyles(element, options) {
  function applyAnimationFromStyles (line 192) | function applyAnimationFromStyles(element, options) {
  function applyAnimationToStyles (line 199) | function applyAnimationToStyles(element, options) {
  function mergeAnimationDetails (line 206) | function mergeAnimationDetails(element, oldAnimation, newAnimation) {
  function resolveElementClasses (line 247) | function resolveElementClasses(existing, toAdd, toRemove) {
  function getDomNode (line 305) | function getDomNode(element) {
  function applyGeneratedPreparationClasses (line 309) | function applyGeneratedPreparationClasses($$jqLite, element, event, opti...
  function clearGeneratedClasses (line 326) | function clearGeneratedClasses(element, options) {
  function blockKeyframeAnimations (line 337) | function blockKeyframeAnimations(node, applyBlock) {
  function applyInlineStyle (line 344) | function applyInlineStyle(node, styleTuple) {
  function concatWithSpace (line 350) | function concatWithSpace(a,b) {
  function scheduler (line 370) | function scheduler(tasks) {
  function nextTick (line 400) | function nextTick() {
  function setData (line 507) | function setData(value) {
  function getCssKeyframeDurationStyle (line 754) | function getCssKeyframeDurationStyle(duration) {
  function getCssDelayStyle (line 758) | function getCssDelayStyle(delay, isKeyframeAnimation) {
  function computeCssStyles (line 763) | function computeCssStyles($window, element, properties) {
  function parseMaxTime (line 789) | function parseMaxTime(str) {
  function truthyTimingValue (line 804) | function truthyTimingValue(val) {
  function getCssTransitionDurationStyle (line 808) | function getCssTransitionDurationStyle(duration, applyOnlyDuration) {
  function registerRestorableStyles (line 828) | function registerRestorableStyles(backup, node, properties) {
  function computeCachedCssStyles (line 845) | function computeCachedCssStyles(node, className, cacheKey, allowNoDurati...
  function computeCachedCssStaggerStyles (line 866) | function computeCachedCssStaggerStyles(node, className, cacheKey, proper...
  function waitUntilQuiet (line 897) | function waitUntilQuiet(callback) {
  function computeTimings (line 915) | function computeTimings(node, className, cacheKey, allowNoDuration) {
  function endFn (line 1190) | function endFn() {
  function cancelFn (line 1194) | function cancelFn() {
  function close (line 1198) | function close(rejected) {
  function applyBlocking (line 1263) | function applyBlocking(duration) {
  function closeAndReturnNoopAnimator (line 1273) | function closeAndReturnNoopAnimator() {
  function onAnimationProgress (line 1292) | function onAnimationProgress(event) {
  function start (line 1325) | function start() {
  function isDocumentFragment (line 1513) | function isDocumentFragment(node) {
  function filterCssClasses (line 1542) | function filterCssClasses(classes) {
  function getUniqueValues (line 1547) | function getUniqueValues(a, b) {
  function prepareAnchoredAnimation (line 1555) | function prepareAnchoredAnimation(classes, outAnchor, inAnchor) {
  function prepareFromToAnchorAnimation (line 1682) | function prepareFromToAnchorAnimation(from, to, classes, anchors) {
  function prepareRegularAnimation (line 1735) | function prepareRegularAnimation(animationDetails) {
  function applyOptions (line 1830) | function applyOptions() {
  function close (line 1835) | function close() {
  function onComplete (line 1897) | function onComplete(success) {
  function endAnimations (line 1902) | function endAnimations(cancelled) {
  function executeAnimationFn (line 1911) | function executeAnimationFn(fn, element, event, options, onDone) {
  function groupEventedAnimations (line 1954) | function groupEventedAnimations(element, event, options, animations, fnN...
  function packageAnimations (line 1995) | function packageAnimations(element, event, options, animations, fnName) {
  function lookupAnimations (line 2045) | function lookupAnimations(classes) {
  function endFnFactory (line 2091) | function endFnFactory() {
  function done (line 2100) | function done(status) {
  function prepareAnimation (line 2110) | function prepareAnimation(animationDetails) {
  function getEventData (line 2134) | function getEventData(options) {
  function makeTruthyCssClassMap (line 2143) | function makeTruthyCssClassMap(classString) {
  function hasMatchingClasses (line 2157) | function hasMatchingClasses(newClassString, currentClassString) {
  function isAllowed (line 2166) | function isAllowed(ruleType, currentAnimation, previousAnimation) {
  function hasAnimationClasses (line 2172) | function hasAnimationClasses(animation, and) {
  function removeFromDisabledElementsLookup (line 2241) | function removeFromDisabledElementsLookup(evt) {
  function postDigestTaskFactory (line 2245) | function postDigestTaskFactory() {
  function normalizeAnimationDetails (line 2308) | function normalizeAnimationDetails(element, animation) {
  function findCallbacks (line 2318) | function findCallbacks(targetParentNode, targetNode, event) {
  function filterFromRegistry (line 2334) | function filterFromRegistry(list, matchContainer, matchCallback) {
  function cleanupEventListeners (line 2343) | function cleanupEventListeners(phase, node) {
  function queueAnimation (line 2444) | function queueAnimation(originalElement, event, initialOptions) {
  function closeChildAnimations (line 2726) | function closeChildAnimations(node) {
  function clearElementAnimationState (line 2744) | function clearElementAnimationState(node) {
  function areAnimationsAllowed (line 2756) | function areAnimationsAllowed(node, parentNode, event) {
  function markElementAnimationState (line 2841) | function markElementAnimationState(node, state, details) {
  function setRunner (line 2922) | function setRunner(element, runner) {
  function removeRunner (line 2926) | function removeRunner(element) {
  function getRunner (line 2930) | function getRunner(element) {
  function sortAnimations (line 2940) | function sortAnimations(animations) {
  function getAnchorNodes (line 3179) | function getAnchorNodes(node) {
  function groupAnimations (line 3194) | function groupAnimations(animations) {
  function cssClassesIntersection (line 3277) | function cssClassesIntersection(a,b) {
  function invokeFirstDriver (line 3297) | function invokeFirstDriver(animationDetails) {
  function beforeStart (line 3310) | function beforeStart() {
  function updateAnimationRunners (line 3321) | function updateAnimationRunners(animation, newRunner) {
  function handleDestroyedElement (line 3335) | function handleDestroyedElement() {
  function close (line 3342) | function close(rejected) {

FILE: app/vendor/angular/angular-aria.js
  function $AriaProvider (line 101) | function $AriaProvider() {
  function shouldAttachAttr (line 239) | function shouldAttachAttr(attr, normalizedAttr, elem, allowBlacklistEls) {
  function shouldAttachRole (line 246) | function shouldAttachRole(role, elem) {
  function getShape (line 253) | function getShape(attr, elem) {
  function ngAriaWatchModelValue (line 275) | function ngAriaWatchModelValue() {
  function getRadioReaction (line 279) | function getRadioReaction(newVal) {
  function getCheckboxReaction (line 286) | function getCheckboxReaction() {
  function callback (line 406) | function callback() {

FILE: app/vendor/angular/angular-cookies.js
  function calcOptions (line 67) | function calcOptions(options) {
  function $$CookieWriter (line 203) | function $$CookieWriter($document, $log, $browser) {

FILE: app/vendor/angular/angular-loader.js
  function isFunction (line 12) | function isFunction(value) {return typeof value === 'function';}
  function isDefined (line 13) | function isDefined(value) {return typeof value !== 'undefined';}
  function isNumber (line 14) | function isNumber(value) {return typeof value === 'number';}
  function isObject (line 15) | function isObject(value) {return value !== null && typeof value === 'obj...
  function isScope (line 16) | function isScope(obj) {return obj && obj.$evalAsync && obj.$watch;}
  function isUndefined (line 17) | function isUndefined(value) {return typeof value === 'undefined';}
  function isWindow (line 18) | function isWindow(obj) {return obj && obj.window === obj;}
  function sliceArgs (line 19) | function sliceArgs(args, startIndex) {return Array.prototype.slice.call(...
  function toJsonReplacer (line 20) | function toJsonReplacer(key, value) {
  function serializeObject (line 38) | function serializeObject(obj, maxDepth) {
  function toDebugString (line 61) | function toDebugString(obj, maxDepth) {
  function errorHandlingConfig (line 110) | function errorHandlingConfig(config) {
  function isValidObjectMaxDepth (line 128) | function isValidObjectMaxDepth(maxDepth) {
  function minErr (line 163) | function minErr(module, ErrorConstructor) {
  function setupModuleLoader (line 215) | function setupModuleLoader(window) {

FILE: app/vendor/angular/angular-message-format.js
  function indexToLineAndColumn (line 20) | function indexToLineAndColumn(text, index) {
  function parseTextLiteral (line 33) | function parseTextLiteral(text) {
  function subtractOffset (line 54) | function subtractOffset(expressionFn, offset) {
  function MessageSelectorBase (line 87) | function MessageSelectorBase(expressionFn, choices) {
  function MessageSelectorWatchers (line 119) | function MessageSelectorWatchers(msgSelector, scope, listener, objectEqu...
  function SelectMessage (line 154) | function SelectMessage(expressionFn, choices) {
  function SelectMessageProto (line 158) | function SelectMessageProto() {}
  function PluralMessage (line 171) | function PluralMessage(expressionFn, choices, offset, pluralCat) {
  function PluralMessageProto (line 177) | function PluralMessageProto() {}
  function InterpolationParts (line 205) | function InterpolationParts(trustedContext, allOrNothing) {
  function InterpolationPartsWatcher (line 301) | function InterpolationPartsWatcher(interpolationParts, scope, listener, ...
  function copyNestedParserState (line 338) | function copyNestedParserState(src, dst) {
  function NestedParserState (line 350) | function NestedParserState(parser) {
  function MessageFormatParser (line 358) | function MessageFormatParser(text, startIndex, $parse, pluralCat, string...
  function getEndOperator (line 745) | function getEndOperator(opBegin) {
  function getBeginOperator (line 754) | function getBeginOperator(opEnd) {
  function getStringifier (line 1018) | function getStringifier(trustedContext, allOrNothing, text) {
  function interpolate (line 1029) | function interpolate(text, mustHaveExpression, trustedContext, allOrNoth...

FILE: app/vendor/angular/angular-messages.js
  function findPreviousMessage (line 503) | function findPreviousMessage(parent, comment) {
  function insertMessageNode (line 527) | function insertMessageNode(parent, comment, key) {
  function removeMessageNode (line 543) | function removeMessageNode(parent, comment, key) {
  function isAttrTruthy (line 559) | function isAttrTruthy(scope, attr) {
  function truthy (line 564) | function truthy(val) {
  function replaceElementWithMarker (line 625) | function replaceElementWithMarker(element, src) {
  function ngMessageDirectiveFactory (line 736) | function ngMessageDirectiveFactory(isDefault) {

FILE: app/vendor/angular/angular-mocks.js
  function routeToRegExp (line 24) | function routeToRegExp(path, opts) {
  function concat (line 482) | function concat(array1, array2, index) {
  function jsonStringToDate (line 734) | function jsonStringToDate(string) {
  function toInt (line 758) | function toInt(str) {
  function padNumberInMock (line 762) | function padNumberInMock(num, digits, trim) {
  function reflowFn (line 959) | function reflowFn() {
  method reflows (line 1037) | get reflows() {
  function serialize (line 1129) | function serialize(object) {
  function serializeScope (line 1162) | function serializeScope(scope, offset) {
  function createHttpBackendMock (line 1497) | function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
  function assertArgDefined (line 2149) | function assertArgDefined(args, index, name) {
  function stripQueryAndHash (line 2155) | function stripQueryAndHash(url) {
  function MockHttpExpectation (line 2159) | function MockHttpExpectation(expectedMethod, expectedUrl, expectedData, ...
  function createMockXhr (line 2275) | function createMockXhr() {
  function MockXhr (line 2279) | function MockXhr() {
  function createControllerDecorator (line 2546) | function createControllerDecorator() {
  function countChildScopes (line 3046) | function countChildScopes() {
  function countWatchers (line 3078) | function countWatchers() {
  function workFn (line 3143) | function workFn() {
  function WorkFn (line 3431) | function WorkFn() {
  function workFn (line 3477) | function workFn() {
  function InjectorState (line 3488) | function InjectorState() {
  function pressed (line 3593) | function pressed(key) {
  function supportsTouchEvents (line 3675) | function supportsTouchEvents() {
  function createTouchEvent (line 3693) | function createTouchEvent(element, eventType, x, y) {
  function supportsEventBubblingInDetachedTree (line 3706) | function supportsEventBubblingInDetachedTree() {
  function triggerForPath (line 3726) | function triggerForPath(element, evnt) {
  function patchEventTargetForBubbling (line 3741) | function patchEventTargetForBubbling(event, target) {
  function isAttachedToDocument (line 3746) | function isAttachedToDocument(element) {

FILE: app/vendor/angular/angular-parse-ext.js
  function IDS_Y (line 13) | function IDS_Y(cp) {
  function IDC_Y (line 571) | function IDC_Y(cp) {
  function isValidIdentifierStart (line 1254) | function isValidIdentifierStart(ch, cp) {
  function isValidIdentifierContinue (line 1260) | function isValidIdentifierContinue(ch, cp) {

FILE: app/vendor/angular/angular-resource.js
  function isValidDottedPath (line 15) | function isValidDottedPath(path) {
  function lookupDottedPath (line 20) | function lookupDottedPath(obj, path) {
  function shallowClearAndCopy (line 35) | function shallowClearAndCopy(src, dst) {
  function Route (line 601) | function Route(template, defaults) {
  function resourceFactory (line 681) | function resourceFactory(url, paramDefaults, actions, options) {

FILE: app/vendor/angular/angular-route.js
  function shallowCopy (line 15) | function shallowCopy(src, dst) {
  function routeToRegExp (line 49) | function routeToRegExp(path, opts) {
  function $RouteProvider (line 129) | function $RouteProvider() {
  function instantiateRoute (line 934) | function instantiateRoute($injector) {
  function $RouteParamsProvider (line 978) | function $RouteParamsProvider() {
  function ngViewFactory (line 1160) | function ngViewFactory($route, $anchorScroll, $animate) {
  function ngViewFillContentFactory (line 1237) | function ngViewFillContentFactory($compile, $controller, $route) {

FILE: app/vendor/angular/angular-sanitize.js
  function $SanitizeProvider (line 152) | function $SanitizeProvider() {
  function sanitizeText (line 703) | function sanitizeText(chars) {
  function addText (line 883) | function addText(text) {
  function addLink (line 890) | function addLink(url, text) {

FILE: app/vendor/angular/angular-touch.js
  function nodeName_ (line 34) | function nodeName_(element) {
  function getCoordinates (line 87) | function getCoordinates(event) {
  function getEvents (line 98) | function getEvents(pointerTypes, eventType) {
  function makeSwipeDirective (line 304) | function makeSwipeDirective(directiveName, direction, eventName) {

FILE: app/vendor/angular/angular.js
  function errorHandlingConfig (line 46) | function errorHandlingConfig(config) {
  function isValidObjectMaxDepth (line 64) | function isValidObjectMaxDepth(maxDepth) {
  function minErr (line 99) | function minErr(module, ErrorConstructor) {
  function isArrayLike (line 318) | function isArrayLike(obj) {
  function forEach (line 374) | function forEach(obj, iterator, context) {
  function forEachSorted (line 416) | function forEachSorted(obj, iterator, context) {
  function reverseParams (line 430) | function reverseParams(iteratorFn) {
  function nextUid (line 444) | function nextUid() {
  function setHashKey (line 454) | function setHashKey(obj, h) {
  function baseExtend (line 463) | function baseExtend(dst, objs, deep) {
  function extend (line 515) | function extend(dst) {
  function merge (line 554) | function merge(dst) {
  function toInt (line 560) | function toInt(str) {
  function inherit (line 570) | function inherit(parent, extra) {
  function noop (line 590) | function noop() {}
  function identity (line 622) | function identity($) {return $;}
  function valueFn (line 626) | function valueFn(value) {return function valueRef() {return value;};}
  function hasCustomToString (line 628) | function hasCustomToString(obj) {
  function isUndefined (line 645) | function isUndefined(value) {return typeof value === 'undefined';}
  function isDefined (line 660) | function isDefined(value) {return typeof value !== 'undefined';}
  function isObject (line 676) | function isObject(value) {
  function isBlankObject (line 687) | function isBlankObject(value) {
  function isString (line 704) | function isString(value) {return typeof value === 'string';}
  function isNumber (line 725) | function isNumber(value) {return typeof value === 'number';}
  function isDate (line 740) | function isDate(value) {
  function isArray (line 757) | function isArray(arr) {
  function isError (line 769) | function isError(value) {
  function isFunction (line 791) | function isFunction(value) {return typeof value === 'function';}
  function isRegExp (line 801) | function isRegExp(value) {
  function isWindow (line 813) | function isWindow(obj) {
  function isScope (line 818) | function isScope(obj) {
  function isFile (line 823) | function isFile(obj) {
  function isFormData (line 828) | function isFormData(obj) {
  function isBlob (line 833) | function isBlob(obj) {
  function isBoolean (line 838) | function isBoolean(value) {
  function isPromiseLike (line 843) | function isPromiseLike(obj) {
  function isTypedArray (line 849) | function isTypedArray(value) {
  function isArrayBuffer (line 853) | function isArrayBuffer(obj) {
  function isElement (line 885) | function isElement(node) {
  function makeMap (line 895) | function makeMap(str) {
  function nodeName_ (line 904) | function nodeName_(element) {
  function includes (line 908) | function includes(array, obj) {
  function arrayRemove (line 912) | function arrayRemove(array, value) {
  function copy (line 1007) | function copy(source, destination, maxDepth) {
  function simpleCompare (line 1154) | function simpleCompare(a, b) { return a === b || (a !== a && b !== b); }
  function equals (line 1220) | function equals(o1, o2) {
  function noUnsafeEval (line 1286) | function noUnsafeEval() {
  function concat (line 1351) | function concat(array1, array2, index) {
  function sliceArgs (line 1355) | function sliceArgs(args, startIndex) {
  function bind (line 1377) | function bind(self, fn) {
  function toJsonReplacer (line 1398) | function toJsonReplacer(key, value) {
  function toJson (line 1451) | function toJson(obj, pretty) {
  function fromJson (line 1472) | function fromJson(json) {
  function timezoneToOffset (line 1480) | function timezoneToOffset(timezone, fallback) {
  function addDateMinutes (line 1489) | function addDateMinutes(date, minutes) {
  function convertTimezoneToLocal (line 1496) | function convertTimezoneToLocal(date, timezone, reverse) {
  function startingTag (line 1507) | function startingTag(element) {
  function tryDecodeURIComponent (line 1532) | function tryDecodeURIComponent(value) {
  function parseKeyValue (line 1545) | function parseKeyValue(/**string*/keyValue) {
  function toKeyValue (line 1572) | function toKeyValue(obj) {
  function encodeUriSegment (line 1600) | function encodeUriSegment(val) {
  function encodeUriQuery (line 1619) | function encodeUriQuery(val, pctEncodeSpaces) {
  function getNgAttribute (line 1631) | function getNgAttribute(element, ngAttr) {
  function allowAutoBootstrap (line 1642) | function allowAutoBootstrap(document) {
  function angularInit (line 1836) | function angularInit(element, bootstrap) {
  function bootstrap (line 1929) | function bootstrap(element, modules, config) {
  function reloadWithDebugInfo (line 2007) | function reloadWithDebugInfo() {
  function getTestability (line 2020) | function getTestability(rootElement) {
  function snake_case (line 2030) | function snake_case(name, separator) {
  function bindJQuery (line 2038) | function bindJQuery() {
  function assertArg (line 2092) | function assertArg(arg, name, reason) {
  function assertArgFn (line 2099) | function assertArgFn(arg, name, acceptArrayAnnotation) {
  function assertNotHasOwnProperty (line 2114) | function assertNotHasOwnProperty(name, context) {
  function getter (line 2128) | function getter(obj, path, bindFnToScope) {
  function getBlockNodes (line 2152) | function getBlockNodes(nodes) {
  function createMap (line 2182) | function createMap() {
  function stringify (line 2186) | function stringify(value) {
  function setupModuleLoader (line 2223) | function setupModuleLoader(window) {
  function shallowCopy (line 2633) | function shallowCopy(src, dst) {
  function serializeObject (line 2655) | function serializeObject(obj, maxDepth) {
  function toDebugString (line 2678) | function toDebugString(obj, maxDepth) {
  function publishExternalAPI (line 2816) | function publishExternalAPI(angular) {
  function jqNextId (line 3099) | function jqNextId() { return ++jqId; }
  function cssKebabToCamel (line 3112) | function cssKebabToCamel(name) {
  function fnCamelCaseReplace (line 3116) | function fnCamelCaseReplace(all, letter) {
  function kebabToCamel (line 3124) | function kebabToCamel(name) {
  function jqLiteIsTextNode (line 3149) | function jqLiteIsTextNode(html) {
  function jqLiteAcceptsData (line 3153) | function jqLiteAcceptsData(node) {
  function jqLiteHasData (line 3160) | function jqLiteHasData(node) {
  function jqLiteBuildFragment (line 3167) | function jqLiteBuildFragment(html, context) {
  function jqLiteParseHTML (line 3204) | function jqLiteParseHTML(html, context) {
  function jqLiteWrapNode (line 3219) | function jqLiteWrapNode(node, wrapper) {
  function JQLite (line 3237) | function JQLite(element) {
  function jqLiteClone (line 3264) | function jqLiteClone(element) {
  function jqLiteDealoc (line 3268) | function jqLiteDealoc(element, onlyDescendants) {
  function isEmptyObject (line 3276) | function isEmptyObject(obj) {
  function removeIfEmptyData (line 3285) | function removeIfEmptyData(element) {
  function jqLiteOff (line 3298) | function jqLiteOff(element, type, fn, unsupported) {
  function jqLiteRemoveData (line 3338) | function jqLiteRemoveData(element, name) {
  function jqLiteExpandoStore (line 3354) | function jqLiteExpandoStore(element, createIfNecessary) {
  function jqLiteData (line 3367) | function jqLiteData(element, key, value) {
  function jqLiteHasClass (line 3396) | function jqLiteHasClass(element, selector) {
  function jqLiteRemoveClass (line 3402) | function jqLiteRemoveClass(element, cssClasses) {
  function jqLiteAddClass (line 3419) | function jqLiteAddClass(element, cssClasses) {
  function jqLiteAddNodes (line 3439) | function jqLiteAddNodes(root, elements) {
  function jqLiteController (line 3465) | function jqLiteController(element, name) {
  function jqLiteInheritedData (line 3469) | function jqLiteInheritedData(element, name, value) {
  function jqLiteEmpty (line 3489) | function jqLiteEmpty(element) {
  function jqLiteRemove (line 3496) | function jqLiteRemove(element, keepData) {
  function jqLiteDocumentLoaded (line 3503) | function jqLiteDocumentLoaded(action, win) {
  function jqLiteReady (line 3516) | function jqLiteReady(fn) {
  function getBooleanAttrName (line 3580) | function getBooleanAttrName(element, name) {
  function getAliasedAttrName (line 3588) | function getAliasedAttrName(name) {
  function getText (line 3686) | function getText(element, value) {
  function createEventHandler (line 3771) | function createEventHandler(element, events) {
  function defaultHandlerWrapper (line 3823) | function defaultHandlerWrapper(element, event, handler) {
  function specialMouseHandlerWrapper (line 3827) | function specialMouseHandlerWrapper(target, event, handler) {
  function $$jqLiteProvider (line 4078) | function $$jqLiteProvider() {
  function hashKey (line 4109) | function hashKey(obj, nextUidFn) {
  function NgMapShim (line 4134) | function NgMapShim() {
  function stringifyFn (line 4270) | function stringifyFn(fn) {
  function extractArgs (line 4274) | function extractArgs(fn) {
  function anonFn (line 4280) | function anonFn(fn) {
  function annotate (line 4290) | function annotate(fn, strictDi, name) {
  function createInjector (line 4903) | function createInjector(modulesToLoad, strictDi) {
  function $AnchorScrollProvider (line 5183) | function $AnchorScrollProvider() {
  function mergeClasses (line 5451) | function mergeClasses(a,b) {
  function extractElementNode (line 5460) | function extractElementNode(element) {
  function splitClasses (line 5469) | function splitClasses(classes) {
  function prepareAnimateOptions (line 5494) | function prepareAnimateOptions(options) {
  function updateData (line 5545) | function updateData(data, classes, value) {
  function handleCSSClassChanges (line 5560) | function handleCSSClassChanges() {
  function addRemoveClassesPostDigest (line 5593) | function addRemoveClassesPostDigest(element, add, remove) {
  function domInsert (line 5759) | function domInsert(element, parentElement, afterElement) {
  function waitForTick (line 6246) | function waitForTick(fn) {
  function next (line 6285) | function next() {
  function onProgress (line 6309) | function onProgress(response) {
  function AnimateRunner (line 6317) | function AnimateRunner(host) {
  function run (line 6475) | function run() {
  function applyAnimationContents (line 6486) | function applyAnimationContents() {
  function getHash (line 6506) | function getHash(url) {
  function trimEmptyHash (line 6511) | function trimEmptyHash(url) {
  function Browser (line 6536) | function Browser(window, document, $log, $sniffer, $$taskTrackerFactory) {
  function $BrowserProvider (line 6844) | function $BrowserProvider() {
  function $CacheFactoryProvider (line 6933) | function $CacheFactoryProvider() {
  function $TemplateCacheProvider (line 7252) | function $TemplateCacheProvider() {
  function UNINITIALIZED_VALUE (line 8623) | function UNINITIALIZED_VALUE() {}
  function $CompileProvider (line 8634) | function $CompileProvider($provide, $$sanitizeUriProvider) {
  function SimpleChange (line 11452) | function SimpleChange(previous, current) {
  function directiveNormalize (line 11466) | function directiveNormalize(name) {
  function nodesetLinkingFn (line 11519) | function nodesetLinkingFn(
  function directiveLinkingFn (line 11526) | function directiveLinkingFn(
  function tokenDifference (line 11534) | function tokenDifference(str1, str2) {
  function removeComments (line 11550) | function removeComments(jqNodes) {
  function identifierForController (line 11572) | function identifierForController(controller, ident) {
  function $ControllerProvider (line 11593) | function $ControllerProvider() {
  function $DocumentProvider (line 11766) | function $DocumentProvider() {
  function $$IsDocumentHiddenProvider (line 11778) | function $$IsDocumentHiddenProvider() {
  function $ExceptionHandlerProvider (line 11843) | function $ExceptionHandlerProvider() {
  function serializeValue (line 11884) | function serializeValue(v) {
  function $HttpParamSerializerProvider (line 11893) | function $HttpParamSerializerProvider() {
  function $HttpParamSerializerJQLikeProvider (line 11931) | function $HttpParamSerializerJQLikeProvider() {
  function defaultHttpResponseTransform (line 12007) | function defaultHttpResponseTransform(data, headers) {
  function isJsonLike (line 12033) | function isJsonLike(str) {
  function parseHeaders (line 12044) | function parseHeaders(headers) {
  function headersGetter (line 12080) | function headersGetter(headers) {
  function transformData (line 12110) | function transformData(data, headers, status, fns) {
  function isSuccess (line 12123) | function isSuccess(status) {
  function $HttpProvider (line 12136) | function $HttpProvider() {
  function $xhrFactoryProvider (line 13431) | function $xhrFactoryProvider() {
  function $HttpBackendProvider (line 13457) | function $HttpBackendProvider() {
  function createHttpBackend (line 13463) | function createHttpBackend($browser, createXhr, $browserDefer, callbacks...
  function $InterpolateProvider (line 13698) | function $InterpolateProvider() {
  function $IntervalProvider (line 14054) | function $IntervalProvider() {
  function $$IntervalFactoryProvider (line 14232) | function $$IntervalFactoryProvider() {
  function createCallback (line 14292) | function createCallback(callbackId) {
  function encodePath (line 14383) | function encodePath(path) {
  function decodePath (line 14395) | function decodePath(path, html5Mode) {
  function normalizePath (line 14410) | function normalizePath(pathValue, searchValue, hashValue) {
  function parseAbsoluteUrl (line 14418) | function parseAbsoluteUrl(absoluteUrl, locationObj) {
  function parseAppUrl (line 14427) | function parseAppUrl(url, locationObj, html5Mode) {
  function startsWith (line 14449) | function startsWith(str, search) {
  function stripBaseUrl (line 14460) | function stripBaseUrl(base, url) {
  function stripHash (line 14466) | function stripHash(url) {
  function stripFile (line 14471) | function stripFile(url) {
  function serverBase (line 14476) | function serverBase(url) {
  function LocationHtml5Url (line 14490) | function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {
  function LocationHashbangUrl (line 14562) | function LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) {
  function LocationHashbangInHtml5Url (line 14666) | function LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) {
  function locationGetter (line 15042) | function locationGetter(property) {
  function locationGetterSetter (line 15049) | function locationGetterSetter(property, preprocess) {
  function $LocationProvider (line 15097) | function $LocationProvider() {
  function $LogProvider (line 15457) | function $LogProvider() {
  function getStringValue (line 15603) | function getStringValue(name) {
  function ifDefined (line 16180) | function ifDefined(v, d) {
  function plusFn (line 16184) | function plusFn(l, r) {
  function isStateless (line 16190) | function isStateless($filter, filterName) {
  function isPure (line 16199) | function isPure(node, parentIsPure) {
  function findConstantAndWatchExpressions (line 16224) | function findConstantAndWatchExpressions(ast, $filter, parentIsPure) {
  function getInputs (line 16337) | function getInputs(body) {
  function isAssignable (line 16345) | function isAssignable(ast) {
  function assignableAST (line 16349) | function assignableAST(ast) {
  function isLiteral (line 16355) | function isLiteral(ast) {
  function isConstant (line 16363) | function isConstant(ast) {
  function ASTCompiler (line 16367) | function ASTCompiler($filter) {
  function ASTInterpreter (line 16833) | function ASTInterpreter($filter) {
  function Parser (line 17207) | function Parser(lexer, $filter, options) {
  function getValueOf (line 17240) | function getValueOf(value) {
  function $ParseProvider (line 17296) | function $ParseProvider() {
  function $QProvider (line 17813) | function $QProvider() {
  function $$QProvider (line 17845) | function $$QProvider() {
  function qFactory (line 17873) | function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
  function isStateExceptionHandled (line 18265) | function isStateExceptionHandled(state) {
  function markQStateExceptionHandled (line 18268) | function markQStateExceptionHandled(state) {
  function markQExceptionHandled (line 18271) | function markQExceptionHandled(q) {
  function $$RAFProvider (line 18282) | function $$RAFProvider() { //rAF
  function $RootScopeProvider (line 18381) | function $RootScopeProvider() {
  function $$SanitizeUriProvider (line 19831) | function $$SanitizeUriProvider() {
  function snakeToCamel (line 19950) | function snakeToCamel(name) {
  function adjustMatcher (line 19955) | function adjustMatcher(matcher) {
  function adjustMatchers (line 19983) | function adjustMatchers(matchers) {
  function $SceDelegateProvider (line 20084) | function $SceDelegateProvider() {
  function $SceProvider (line 20680) | function $SceProvider() {
  function $SnifferProvider (line 21106) | function $SnifferProvider() {
  function $$TaskTrackerFactoryProvider (line 21187) | function $$TaskTrackerFactoryProvider() {
  function TaskTracker (line 21191) | function TaskTracker(log) {
  function $TemplateRequestProvider (line 21306) | function $TemplateRequestProvider() {
  function $$TestabilityProvider (line 21416) | function $$TestabilityProvider() {
  function $TimeoutProvider (line 21542) | function $TimeoutProvider() {
  function urlResolve (line 21712) | function urlResolve(url) {
  function urlIsSameOrigin (line 21755) | function urlIsSameOrigin(requestUrl) {
  function urlIsSameOriginAsBaseUrl (line 21769) | function urlIsSameOriginAsBaseUrl(requestUrl) {
  function urlIsAllowedOriginFactory (line 21782) | function urlIsAllowedOriginFactory(whitelistedOriginUrls) {
  function urlsAreSameOrigin (line 21811) | function urlsAreSameOrigin(url1, url2) {
  function getBaseUrl (line 21823) | function getBaseUrl() {
  function $WindowProvider (line 21882) | function $WindowProvider() {
  function $$CookieReader (line 21895) | function $$CookieReader($document) {
  function $$CookieReaderProvider (line 21946) | function $$CookieReaderProvider() {
  function $FilterProvider (line 22057) | function $FilterProvider($provide) {
  function filterFilter (line 22257) | function filterFilter() {
  function createPredicateFn (line 22294) | function createPredicateFn(expression, comparator, anyPropertyKey, match...
  function deepCompare (line 22331) | function deepCompare(actual, expected, comparator, anyPropertyKey, match...
  function getTypeForFilter (line 22383) | function getTypeForFilter(val) {
  function currencyFilter (line 22444) | function currencyFilter($locale) {
  function numberFilter (line 22521) | function numberFilter($locale) {
  function parse (line 22546) | function parse(numStr) {
  function roundNumber (line 22601) | function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
  function formatNumber (line 22676) | function formatNumber(number, pattern, groupSep, decimalSep, fractionSiz...
  function padNumber (line 22742) | function padNumber(num, digits, trim, negWrap) {
  function dateGetter (line 22761) | function dateGetter(name, size, offset, trim, negWrap) {
  function dateStrGetter (line 22773) | function dateStrGetter(name, shortForm, standAlone) {
  function timeZoneGetter (line 22783) | function timeZoneGetter(date, formats, offset) {
  function getFirstThursdayOfYear (line 22793) | function getFirstThursdayOfYear(year) {
  function getThursdayThisWeek (line 22801) | function getThursdayThisWeek(datetime) {
  function weekGetter (line 22807) | function weekGetter(size) {
  function ampmGetter (line 22819) | function ampmGetter(date, formats) {
  function eraGetter (line 22823) | function eraGetter(date, formats) {
  function longEraGetter (line 22827) | function longEraGetter(date, formats) {
  function dateFilter (line 22965) | function dateFilter($locale) {
  function jsonFilter (line 23072) | function jsonFilter() {
  function limitToFilter (line 23221) | function limitToFilter() {
  function sliceFn (line 23248) | function sliceFn(input, begin, end) {
  function orderByFilter (line 23814) | function orderByFilter($parse) {
  function ngDirective (line 23960) | function ngDirective(directive) {
  function defaultLinkFn (line 24356) | function defaultLinkFn(scope, element, attr) {
  function nullFormRenameControl (line 24466) | function nullFormRenameControl(control, name) {
  function FormController (line 24520) | function FormController($element, $attrs, $scope, $animate, $interpolate) {
  function getSetter (line 25058) | function getSetter(expression) {
  function setupValidity (line 25074) | function setupValidity(instance) {
  function addSetValidityMethod (line 25078) | function addSetValidityMethod(context) {
  function isObjectEmpty (line 25165) | function isObjectEmpty(obj) {
  function stringBasedInputType (line 26453) | function stringBasedInputType(ctrl) {
  function textInputType (line 26459) | function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  function baseInputType (line 26464) | function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  function weekParser (line 26584) | function weekParser(isoWeek, existingDate) {
  function createDateParser (line 26616) | function createDateParser(regexp, mapping) {
  function createDateInputType (line 26674) | function createDateInputType(type, regexp, parseDate, format) {
  function badInputChecker (line 26795) | function badInputChecker(scope, element, attr, ctrl, parserName) {
  function numberFormatterParser (line 26811) | function numberFormatterParser(ctrl) {
  function parseNumberAttrVal (line 26831) | function parseNumberAttrVal(val) {
  function isNumberInteger (line 26838) | function isNumberInteger(num) {
  function countDecimals (line 26846) | function countDecimals(num) {
  function isValidForStep (line 26866) | function isValidForStep(viewValue, stepBase, step) {
  function numberInputType (line 26897) | function numberInputType(scope, element, attr, ctrl, $sniffer, $browser,...
  function rangeInputType (line 26962) | function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  function urlInputType (line 27108) | function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  function emailInputType (line 27120) | function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  function radioInputType (line 27132) | function radioInputType(scope, element, attr, ctrl) {
  function parseConstantExpr (line 27163) | function parseConstantExpr($parse, context, name, expression, fallback) {
  function checkboxInputType (line 27176) | function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browse...
  function updateElementValue (line 27519) | function updateElementValue(element, attr, value) {
  function classDirective (line 27838) | function classDirective(name, selector) {
  function createEventDirective (line 28939) | function createEventDirective($parse, $rootScope, $exceptionHandler, dir...
  function NgModelController (line 30282) | function NgModelController($scope, $exceptionHandler, $attr, $element, $...
  function processParseErrors (line 30645) | function processParseErrors() {
  function processSyncValidators (line 30667) | function processSyncValidators() {
  function processAsyncValidators (line 30683) | function processAsyncValidators() {
  function setValidity (line 30709) | function setValidity(name, isValid) {
  function validationDone (line 30715) | function validationDone(allValid) {
  function writeToModelIfNeeded (line 30801) | function writeToModelIfNeeded() {
  function setupModelWatcher (line 31103) | function setupModelWatcher(ctrl) {
  function setTouched (line 31393) | function setTouched() {
  function ModelOptions (line 31422) | function ModelOptions(options) {
  function NgModelOptionsController (line 31958) | function NgModelOptionsController($attrs, $scope) {
  function defaults (line 31983) | function defaults(dst, src) {
  function parseOptionsExpression (line 32274) | function parseOptionsExpression(optionsExp, selectElement, scope) {
  function ngOptionsPostLink (line 32437) | function ngOptionsPostLink(scope, selectElement, attr, ctrls) {
  function updateElementText (line 32972) | function updateElementText(newText) {
  function ngTranscludeCloneAttachFn (line 34857) | function ngTranscludeCloneAttachFn(clone, transcludedScope) {
  function useFallbackContent (line 34868) | function useFallbackContent() {
  function notWhitespace (line 34876) | function notWhitespace(nodes) {
  function setOptionSelectedStatus (line 34941) | function setOptionSelectedStatus(optionEl, value) {
  function scheduleRender (line 35291) | function scheduleRender() {
  function scheduleViewValueUpdate (line 35301) | function scheduleViewValueUpdate(renderAfter) {
  function selectPreLink (line 35689) | function selectPreLink(scope, element, attr, ctrls) {
  function selectPostLink (line 35774) | function selectPostLink(scope, element, attrs, ctrls) {
  function parsePatternAttr (line 36251) | function parsePatternAttr(regex, patternExp, elm) {
  function parseLength (line 36267) | function parseLength(val) {
  function getDecimals (line 36288) | function getDecimals(n) {
  function getVF (line 36294) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_agq-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_agq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ak-gh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ak.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_as-in.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_as.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_asa-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_asa.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ast-es.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ast.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bas-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bas.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bem-zm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bem.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bez-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bez.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bm-ml.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bo-cn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bo-in.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_brx-in.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_brx.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bs-cyrl-ba.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bs-cyrl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bs-latn-ba.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bs-latn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_bs.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ca-ad.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ca-es-valencia.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ca-es.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ca-fr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ca-it.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ca.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ce-ru.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ce.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_cgg-ug.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_cgg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ckb-arab-iq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ckb-arab-ir.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ckb-arab.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ckb-iq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ckb-ir.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ckb-latn-iq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ckb-latn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ckb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_cs-cz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_cs.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_cu-ru.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_cu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_da-dk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {
  function getWT (line 22) | function getWT(v, f) {

FILE: app/vendor/angular/i18n/angular-locale_da-gl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {
  function getWT (line 22) | function getWT(v, f) {

FILE: app/vendor/angular/i18n/angular-locale_da.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {
  function getWT (line 22) | function getWT(v, f) {

FILE: app/vendor/angular/i18n/angular-locale_dav-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dav.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_de-at.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_de-be.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_de-ch.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_de-de.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_de-it.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_de-li.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_de-lu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_de.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dje-ne.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dje.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dsb-de.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dsb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dua-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dua.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dyo-sn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dyo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dz-bt.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_dz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ebu-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ebu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ee-gh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ee-tg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ee.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-001.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-150.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ag.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ai.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-as.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-at.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-au.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-bb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-be.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-bi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-bm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-bs.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-bw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-bz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ca.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-cc.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ch.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ck.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-cx.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-cy.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-de.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-dg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-dk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-dm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-er.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-fi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-fj.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-fk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-fm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-gb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-gd.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-gg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-gh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-gi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-gm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-gu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-gy.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-hk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ie.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-il.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-im.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-in.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-io.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-iso.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-je.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-jm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ki.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-kn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ky.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-lc.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-lr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ls.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-mg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-mh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-mo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-mp.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ms.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-mt.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-mu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-mw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-my.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-na.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-nf.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ng.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-nl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-nr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-nu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-nz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-pg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ph.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-pk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-pn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-pr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-pw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-rw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-sb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-sc.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-sd.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-se.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-sg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-sh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-si.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-sl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ss.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-sx.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-sz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-tc.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-tk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-to.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-tt.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-tv.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ug.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-um.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-us-posix.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-us.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-vc.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-vg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-vi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-vu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-ws.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-xa.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-za.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-zm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en-zw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_en.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_eo-001.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_eo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_et-ee.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_et.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ewo-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ewo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ff-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ff-gn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ff-mr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ff-sn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ff.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fi-fi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fil-ph.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fil.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fo-dk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fo-fo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fur-it.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fur.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fy-nl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_fy.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_gd-gb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_gd.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_gl-es.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_gl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_guz-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_guz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_gv-im.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_gv.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ha-gh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ha-ne.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ha-ng.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ha.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_he-il.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_he.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_hr-ba.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_hr-hr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_hr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_hsb-de.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_hsb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ig-ng.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ig.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ii-cn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ii.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_is-is.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {
  function getWT (line 22) | function getWT(v, f) {

FILE: app/vendor/angular/i18n/angular-locale_is.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {
  function getWT (line 22) | function getWT(v, f) {

FILE: app/vendor/angular/i18n/angular-locale_it-ch.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_it-it.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_it-sm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_it-va.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_it.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_iw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_jgo-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_jgo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_jmc-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_jmc.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kab-dz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kab.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kam-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kam.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kde-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kde.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kea-cv.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kea.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_khq-ml.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_khq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ki-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ki.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kkj-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kkj.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kl-gl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kln-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kln.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kok-in.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kok.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ks-in.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ks.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ksb-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ksb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ksf-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ksf.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ksh-de.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ksh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kw-gb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_kw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lag-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lag.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lb-lu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lb.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lg-ug.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lkt-us.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lkt.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lrc-iq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lrc-ir.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lrc.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lt-lt.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lt.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lu-cd.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_luo-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_luo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_luy-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_luy.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lv-lv.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_lv.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mas-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mas-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mas.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mer-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mer.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mfe-mu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mfe.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mg-mg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mgh-mz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mgh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mgo-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mgo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mk-mk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mua-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mua.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mzn-ir.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_mzn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_naq-na.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_naq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nd-zw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nd.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nds-de.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nds-nl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nds.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nl-aw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nl-be.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nl-bq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nl-cw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nl-nl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nl-sr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nl-sx.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nmg-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nmg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nn-no.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nnh-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nnh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nus-ss.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nus.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nyn-ug.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_nyn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_om-et.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_om-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_om.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_os-ge.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_os-ru.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_os.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_pl-pl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_pl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_prg-001.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_prg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ps-af.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ps.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_qu-bo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_qu-ec.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_qu-pe.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_qu.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rm-ch.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rn-bi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ro-md.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ro-ro.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ro.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rof-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rof.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ru-by.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ru-kg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ru-kz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ru-md.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ru-ru.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ru-ua.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ru.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rw-rw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rwk-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_rwk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sah-ru.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sah.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_saq-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_saq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sbp-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sbp.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_se-fi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_se-no.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_se-se.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_se.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_seh-mz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_seh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ses-ml.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ses.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sg-cf.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sg.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_shi-latn-ma.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_shi-latn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_shi-tfng-ma.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_shi-tfng.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_shi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_si-lk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_si.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sk-sk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sl-si.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_smn-fi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_smn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sn-zw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_so-dj.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_so-et.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_so-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_so-so.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_so.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-cyrl-ba.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-cyrl-me.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-cyrl-rs.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-cyrl-xk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-cyrl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-latn-ba.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-latn-me.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-latn-rs.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-latn-xk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr-latn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sv-ax.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sv-fi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sv-se.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sv.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sw-cd.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sw-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sw-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sw-ug.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_sw.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_teo-ke.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_teo-ug.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_teo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ti-er.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ti-et.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ti.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_tk-tm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_tk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_tl.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_to-to.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_to.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_twq-ne.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_twq.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_tzm-ma.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_tzm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ug-cn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ug.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_uk-ua.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_uk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ur-in.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ur-pk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_ur.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vai-latn-lr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vai-latn.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vai-vaii-lr.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vai-vaii.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vai.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vo-001.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vun-tz.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_vun.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_wae-ch.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_wae.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_xog-ug.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_xog.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yav-cm.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yav.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yi-001.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yi.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yo-bj.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yo-ng.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yo.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yue-hk.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_yue.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_zgh-ma.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/i18n/angular-locale_zgh.js
  function getDecimals (line 4) | function getDecimals(n) {
  function getVF (line 10) | function getVF(n, opt_precision) {

FILE: app/vendor/angular/test-bundles/angular-aria.js
  function $AriaProvider (line 101) | function $AriaProvider() {
  function shouldAttachAttr (line 239) | function shouldAttachAttr(attr, normalizedAttr, elem, allowBlacklistEls) {
  function shouldAttachRole (line 246) | function shouldAttachRole(role, elem) {
  function getShape (line 253) | function getShape(attr, elem) {
  function ngAriaWatchModelValue (line 275) | function ngAriaWatchModelValue() {
  function getRadioReaction (line 279) | function getRadioReaction(newVal) {
  function getCheckboxReaction (line 286) | function getCheckboxReaction() {
  function callback (line 406) | function callback() {
  function eventFor (line 1411) | function eventFor(keyCode) {
  function createHTML (line 1491) | function createHTML(type) {
  function compileElement (line 1645) | function compileElement(inputHtml) {
  function configAriaProvider (line 1650) | function configAriaProvider(config) {
  function expectAriaAttrOnEachElement (line 1658) | function expectAriaAttrOnEachElement(elem, ariaAttr, expected) {
  function injectScopeAndCompiler (line 1664) | function injectScopeAndCompiler() {

FILE: app/vendor/angular/test-bundles/angular-cookies.js
  function calcOptions (line 67) | function calcOptions(options) {
  function $$CookieWriter (line 203) | function $$CookieWriter($document, $log, $browser) {
  function deleteAllCookies (line 396) | function deleteAllCookies() {
  function getLastCookieAssignment (line 527) | function getLastCookieAssignment(key) {

FILE: app/vendor/angular/test-bundles/angular-message-format.js
  function indexToLineAndColumn (line 20) | function indexToLineAndColumn(text, index) {
  function parseTextLiteral (line 33) | function parseTextLiteral(text) {
  function subtractOffset (line 54) | function subtractOffset(expressionFn, offset) {
  function MessageSelectorBase (line 87) | function MessageSelectorBase(expressionFn, choices) {
  function MessageSelectorWatchers (line 119) | function MessageSelectorWatchers(msgSelector, scope, listener, objectEqu...
  function SelectMessage (line 154) | function SelectMessage(expressionFn, choices) {
  function SelectMessageProto (line 158) | function SelectMessageProto() {}
  function PluralMessage (line 171) | function PluralMessage(expressionFn, choices, offset, pluralCat) {
  function PluralMessageProto (line 177) | function PluralMessageProto() {}
  function InterpolationParts (line 205) | function InterpolationParts(trustedContext, allOrNothing) {
  function InterpolationPartsWatcher (line 301) | function InterpolationPartsWatcher(interpolationParts, scope, listener, ...
  function copyNestedParserState (line 338) | function copyNestedParserState(src, dst) {
  function NestedParserState (line 350) | function NestedParserState(parser) {
  function MessageFormatParser (line 358) | function MessageFormatParser(text, startIndex, $parse, pluralCat, string...
  function getEndOperator (line 745) | function getEndOperator(opBegin) {
  function getBeginOperator (line 754) | function getBeginOperator(opEnd) {
  function getStringifier (line 1018) | function getStringifier(trustedContext, allOrNothing, text) {
  function interpolate (line 1029) | function interpolate(text, mustHaveExpression, trustedContext, allOrNoth...
  function Person (line 1090) | function Person(name, gender) {
  function initScope (line 1100) | function initScope($scope) {
  function assertMustache (line 1120) | function assertMustache(text, expected) {
  function assertInterpolation (line 1282) | function assertInterpolation(text, expected) {
  function log (line 1584) | function log() {}

FILE: app/vendor/angular/test-bundles/angular-messages.js
  function findPreviousMessage (line 503) | function findPreviousMessage(parent, comment) {
  function insertMessageNode (line 527) | function insertMessageNode(parent, comment, key) {
  function removeMessageNode (line 543) | function removeMessageNode(parent, comment, key) {
  function isAttrTruthy (line 559) | function isAttrTruthy(scope, attr) {
  function truthy (line 564) | function truthy(val) {
  function replaceElementWithMarker (line 625) | function replaceElementWithMarker(element, src) {
  function ngMessageDirectiveFactory (line 736) | function ngMessageDirectiveFactory(isDefault) {
  function messageChildren (line 832) | function messageChildren(element) {
  function s (line 836) | function s(str) {
  function trim (line 840) | function trim(value) {

FILE: app/vendor/angular/test-bundles/angular-resource.js
  function isValidDottedPath (line 15) | function isValidDottedPath(path) {
  function lookupDottedPath (line 20) | function lookupDottedPath(obj, path) {
  function shallowClearAndCopy (line 35) | function shallowClearAndCopy(src, dst) {
  function Route (line 601) | function Route(template, defaults) {
  function resourceFactory (line 681) | function resourceFactory(url, paramDefaults, actions, options) {
  function verifyRequest (line 1032) | function verifyRequest(method, url, data) {
  function Func (line 1122) | function Func() {}
  function test (line 1312) | function test(templateUrl, params, actualUrl) {
  function test (line 1328) | function test(templateUrl, params, actualUrl) {

FILE: app/vendor/angular/test-bundles/angular-route.js
  function assertArg (line 71) | function assertArg(arg, name, reason) {
  function mergeClasses (line 78) | function mergeClasses(a,b) {
  function packageStyles (line 87) | function packageStyles(options) {
  function pendClasses (line 96) | function pendClasses(classes, fix, isPrefix) {
  function removeFromArray (line 113) | function removeFromArray(arr, val) {
  function stripCommentsFromElement (line 120) | function stripCommentsFromElement(element) {
  function extractElementNode (line 145) | function extractElementNode(element) {
  function $$addClass (line 155) | function $$addClass($$jqLite, element, className) {
  function $$removeClass (line 161) | function $$removeClass($$jqLite, element, className) {
  function applyAnimationClassesFactory (line 167) | function applyAnimationClassesFactory($$jqLite) {
  function prepareAnimationOptions (line 180) | function prepareAnimationOptions(options) {
  function applyAnimationStyles (line 194) | function applyAnimationStyles(element, options) {
  function applyAnimationFromStyles (line 199) | function applyAnimationFromStyles(element, options) {
  function applyAnimationToStyles (line 206) | function applyAnimationToStyles(element, options) {
  function mergeAnimationDetails (line 213) | function mergeAnimationDetails(element, oldAnimation, newAnimation) {
  function resolveElementClasses (line 254) | function resolveElementClasses(existing, toAdd, toRemove) {
  function getDomNode (line 312) | function getDomNode(element) {
  function applyGeneratedPreparationClasses (line 316) | function applyGeneratedPreparationClasses($$jqLite, element, event, opti...
  function clearGeneratedClasses (line 333) | function clearGeneratedClasses(element, options) {
  function blockKeyframeAnimations (line 344) | function blockKeyframeAnimations(node, applyBlock) {
  function applyInlineStyle (line 351) | function applyInlineStyle(node, styleTuple) {
  function concatWithSpace (line 357) | function concatWithSpace(a,b) {
  function scheduler (line 377) | function scheduler(tasks) {
  function nextTick (line 407) | function nextTick() {
  function setData (line 514) | function setData(value) {
  function getCssKeyframeDurationStyle (line 761) | function getCssKeyframeDurationStyle(duration) {
  function getCssDelayStyle (line 765) | function getCssDelayStyle(delay, isKeyframeAnimation) {
  function computeCssStyles (line 770) | function computeCssStyles($window, element, properties) {
  function parseMaxTime (line 796) | function parseMaxTime(str) {
  function truthyTimingValue (line 811) | function truthyTimingValue(val) {
  function getCssTransitionDurationStyle (line 815) | function getCssTransitionDurationStyle(duration, applyOnlyDuration) {
  function registerRestorableStyles (line 835) | function registerRestorableStyles(backup, node, properties) {
  function computeCachedCssStyles (line 852) | function computeCachedCssStyles(node, className, cacheKey, allowNoDurati...
  function computeCachedCssStaggerStyles (line 873) | function computeCachedCssStaggerStyles(node, className, cacheKey, proper...
  function waitUntilQuiet (line 904) | function waitUntilQuiet(callback) {
  function computeTimings (line 922) | function computeTimings(node, className, cacheKey, allowNoDuration) {
  function endFn (line 1197) | function endFn() {
  function cancelFn (line 1201) | function cancelFn() {
  function close (line 1205) | function close(rejected) {
  function applyBlocking (line 1270) | function applyBlocking(duration) {
  function closeAndReturnNoopAnimator (line 1280) | function closeAndReturnNoopAnimator() {
  function onAnimationProgress (line 1299) | function onAnimationProgress(event) {
  function start (line 1332) | function start() {
  function isDocumentFragment (line 1520) | function isDocumentFragment(node) {
  function filterCssClasses (line 1549) | function filterCssClasses(classes) {
  function getUniqueValues (line 1554) | function getUniqueValues(a, b) {
  function prepareAnchoredAnimation (line 1562) | function prepareAnchoredAnimation(classes, outAnchor, inAnchor) {
  function prepareFromToAnchorAnimation (line 1689) | function prepareFromToAnchorAnimation(from, to, classes, anchors) {
  function prepareRegularAnimation (line 1742) | function prepareRegularAnimation(animationDetails) {
  function applyOptions (line 1837) | function applyOptions() {
  function close (line 1842) | function close() {
  function onComplete (line 1904) | function onComplete(success) {
  function endAnimations (line 1909) | function endAnimations(cancelled) {
  function executeAnimationFn (line 1918) | function executeAnimationFn(fn, element, event, options, onDone) {
  function groupEventedAnimations (line 1961) | function groupEventedAnimations(element, event, options, animations, fnN...
  function packageAnimations (line 2002) | function packageAnimations(element, event, options, animations, fnName) {
  function lookupAnimations (line 2052) | function lookupAnimations(classes) {
  function endFnFactory (line 2098) | function endFnFactory() {
  function done (line 2107) | function done(status) {
  function prepareAnimation (line 2117) | function prepareAnimation(animationDetails) {
  function getEventData (line 2141) | function getEventData(options) {
  function makeTruthyCssClassMap (line 2150) | function makeTruthyCssClassMap(classString) {
  function hasMatchingClasses (line 2164) | function hasMatchingClasses(newClassString, currentClassString) {
  function isAllowed (line 2173) | function isAllowed(ruleType, currentAnimation, previousAnimation) {
  function hasAnimationClasses (line 2179) | function hasAnimationClasses(animation, and) {
  function removeFromDisabledElementsLookup (line 2248) | function removeFromDisabledElementsLookup(evt) {
  function postDigestTaskFactory (line 2252) | function postDigestTaskFactory() {
  function normalizeAnimationDetails (line 2315) | function normalizeAnimationDetails(element, animation) {
  function findCallbacks (line 2325) | function findCallbacks(targetParentNode, targetNode, event) {
  function filterFromRegistry (line 2341) | function filterFromRegistry(list, matchContainer, matchCallback) {
  function cleanupEventListeners (line 2350) | function cleanupEventListeners(phase, node) {
  function queueAnimation (line 2451) | function queueAnimation(originalElement, event, initialOptions) {
  function closeChildAnimations (line 2733) | function closeChildAnimations(node) {
  function clearElementAnimationState (line 2751) | function clearElementAnimationState(node) {
  function areAnimationsAllowed (line 2763) | function areAnimationsAllowed(node, parentNode, event) {
  function markElementAnimationState (line 2848) | function markElementAnimationState(node, state, details) {
  function setRunner (line 2929) | function setRunner(element, runner) {
  function removeRunner (line 2933) | function removeRunner(element) {
  function getRunner (line 2937) | function getRunner(element) {
  function sortAnimations (line 2947) | function sortAnimations(animations) {
  function getAnchorNodes (line 3186) | function getAnchorNodes(node) {
  function groupAnimations (line 3201) | function groupAnimations(animations) {
  function cssClassesIntersection (line 3284) | function cssClassesIntersection(a,b) {
  function invokeFirstDriver (line 3304) | function invokeFirstDriver(animationDetails) {
  function beforeStart (line 3317) | function beforeStart() {
  function updateAnimationRunners (line 3328) | function updateAnimationRunners(animation, newRunner) {
  function handleDestroyedElement (line 3342) | function handleDestroyedElement() {
  function close (line 3349) | function close(rejected) {
  function shallowCopy (line 4288) | function shallowCopy(src, dst) {
  function routeToRegExp (line 4322) | function routeToRegExp(path, opts) {
  function $RouteProvider (line 4402) | function $RouteProvider() {
  function instantiateRoute (line 5207) | function instantiateRoute($injector) {
  function $RouteParamsProvider (line 5251) | function $RouteParamsProvider() {
  function ngViewFactory (line 5433) | function ngViewFactory($route, $anchorScroll, $animate) {
  function ngViewFillContentFactory (line 5510) | function ngViewFillContentFactory($compile, $controller, $route) {
  function Ctrl (line 5623) | function Ctrl($scope) {
  function ParentCtrl (line 5819) | function ParentCtrl($scope) {
  function logger (line 6009) | function logger(msg) {
  function createController (line 6015) | function createController(name) {
  function MyCtrl (line 6067) | function MyCtrl($scope) {
  function MyCtrl (line 6097) | function MyCtrl($scope) {}
  function html (line 6273) | function html(content) {
  function n (line 6456) | function n(text) {
  function spyOnAnchorScroll (line 6499) | function spyOnAnchorScroll() {
  function spyOnAnimateEnter (line 6510) | function spyOnAnimateEnter() {
  function compileAndLink (line 6516) | function compileAndLink(tpl) {
  function BaseRoute (line 7160) | function BaseRoute() {}
  function NotFoundCtrl (line 7309) | function NotFoundCtrl() {}
  function MySafeResourceUrl (line 7771) | function MySafeResourceUrl(val) {
  function getVal (line 7785) | function getVal(v) { return v.getVal ? v.getVal() : v; }
  function customRedirectFn (line 7929) | function customRedirectFn(routePathParams, path, search) {
  function createSpies (line 8396) | function createSpies() {
  function setupRoutes (line 8410) | function setupRoutes(routeProvider, spies, resolveRedirectToFn) {
  function customTemplateFn (line 8883) | function customTemplateFn(routePathParams) {
  function customTemplateUrlFn (line 8906) | function customTemplateUrlFn(routePathParams) {
  function controller (line 8942) | function controller($log) {
  function addRouteWithAsyncRedirect (line 9296) | function addRouteWithAsyncRedirect(fromPath, toPath) {

FILE: app/vendor/angular/test-bundles/angular-sanitize.js
  function $SanitizeProvider (line 152) | function $SanitizeProvider() {
  function sanitizeText (line 703) | function sanitizeText(chars) {
  function addText (line 883) | function addText(text) {
  function addLink (line 890) | function addLink(url, text) {
  function tag (line 1555) | function tag(name) {

FILE: app/vendor/angular/test-bundles/angular-touch.js
  function nodeName_ (line 34) | function nodeName_(element) {
  function getCoordinates (line 87) | function getCoordinates(event) {
  function getEvents (line 98) | function getEvents(pointerTypes, eventType) {
  function makeSwipeDirective (line 304) | function makeSwipeDirective(directiveName, direction, eventName) {
  function swipeTests (line 685) | function swipeTests(description, restrictBrowsers, startEvent, moveEvent...

FILE: app/vendor/angularjs-toaster/toaster.js
  function createTypeMethod (line 117) | function createTypeMethod(toasterType) {
  function setTimeout (line 282) | function setTimeout(toast, time) {
  function addToast (line 298) | function addToast(toast, toastId) {
  function removeToast (line 396) | function removeToast(toastIndex) {
  function removeAllToasts (line 410) | function removeAllToasts(toastId) {
  function isUndefinedOrNull (line 424) | function isUndefinedOrNull(val) {

FILE: app/vendor/bootstrap/js/bootstrap.js
  function removeElement (line 58) | function removeElement() {
  function Plugin (line 74) | function Plugin(option) {
  function Plugin (line 177) | function Plugin(option) {
  function Plugin (line 382) | function Plugin(option) {
  function clearMenus (line 527) | function clearMenus(e) {
  function getParent (line 540) | function getParent($this) {
  function Plugin (line 557) | function Plugin(option) {
  function Plugin (line 825) | function Plugin(option, _relatedTarget) {
  function complete (line 1157) | function complete() {
  function Plugin (line 1304) | function Plugin(option) {
  function Plugin (line 1418) | function Plugin(option) {
  function next (line 1505) | function next() {
  function Plugin (line 1540) | function Plugin(option) {
  function Plugin (line 1673) | function Plugin(option) {
  function Plugin (line 1837) | function Plugin(option) {
  function ScrollSpy (line 1904) | function ScrollSpy(element, options) {
  function Plugin (line 2022) | function Plugin(option) {
  function transitionEnd (line 2075) | function transitionEnd() {

FILE: app/vendor/clipboard/clipboard.js
  function s (line 7) | function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&re...
  function delegate (line 32) | function delegate(element, selector, type, callback, useCapture) {
  function listener (line 53) | function listener(element, selector, type, callback) {
  function listen (line 129) | function listen(target, type, callback) {
  function listenNode (line 165) | function listenNode(node, type, callback) {
  function listenNodeList (line 184) | function listenNodeList(nodeList, type, callback) {
  function listenSelector (line 207) | function listenSelector(selector, type, callback) {
  function match (line 246) | function match(el, selector) {
  function select (line 255) | function select(element) {
  function E (line 285) | function E () {
  function listener (line 304) | function listener () {
  function _interopRequireDefault (line 370) | function _interopRequireDefault(obj) {
  function _classCallCheck (line 382) | function _classCallCheck(instance, Constructor) {
  function defineProperties (line 389) | function defineProperties(target, props) {
  function ClipboardAction (line 411) | function ClipboardAction(options) {
  function _interopRequireDefault (line 605) | function _interopRequireDefault(obj) {
  function _classCallCheck (line 611) | function _classCallCheck(instance, Constructor) {
  function _possibleConstructorReturn (line 617) | function _possibleConstructorReturn(self, call) {
  function _inherits (line 625) | function _inherits(subClass, superClass) {
  function Clipboard (line 649) | function Clipboard(trigger, options) {
  function getAttributeValue (line 731) | function getAttributeValue(suffix, element) {

FILE: app/vendor/cryptoJS/crypto.js
  function F (line 25) | function F() {}
  function selectCipherStrategy (line 901) | function selectCipherStrategy(key) {
  function xorBlock (line 1064) | function xorBlock(words, offset, blockSize) {
  function xorBlock (line 1180) | function xorBlock(words, block, offset, blockSize) {
  function isPrime (line 1935) | function isPrime(n) {
  function getFractionalBits (line 1946) | function getFractionalBits(n) {

FILE: app/vendor/jquery.nanoscroller/nanoscroller.js
  function NanoScroll (line 351) | function NanoScroll(el, options) {

FILE: app/vendor/jquery/jquery.js
  function isArraylike (line 570) | function isArraylike( obj ) {
  function Sizzle (line 773) | function Sizzle( selector, context, results, seed 
Copy disabled (too large) Download .json
Condensed preview — 1045 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (14,418K chars).
[
  {
    "path": ".dockerignore",
    "chars": 5,
    "preview": ".git\n"
  },
  {
    "path": ".gitignore",
    "chars": 194,
    "preview": ".DS_Store\n.idea\n.publish\n*.sublime-workspace\n*.*~\n*.swp\n\n# Node.js package manager\nnode_modules\nnpm-debug.log\ndist\ndist_"
  },
  {
    "path": ".tx/config",
    "chars": 261,
    "preview": "[main]\nhost = https://www.transifex.com\n\n[telegram-web.en-usjson]\nfile_filter = app/js/locales/<lang>.json\nlang_map = de"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 8907,
    "preview": "### 0.7\n* Improved chats search\n* Pinned messages in supergroups and channels\n* Saved messages\n* Improved chat history f"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2988,
    "preview": "## Contribute\n\nYou can help this project by reporting problems, suggestions, localizing it or contributing to the code.\n"
  },
  {
    "path": "Dockerfile",
    "chars": 129,
    "preview": "FROM node\n\nADD . /opt/webogram\nWORKDIR /opt/webogram\n\nRUN npm install -g gulp && npm install\n\nEXPOSE 8000\n\nCMD [\"gulp\", "
  },
  {
    "path": "LICENSE",
    "chars": 35121,
    "preview": "GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation,"
  },
  {
    "path": "Makefile",
    "chars": 939,
    "preview": "package:\n\trm -rf dist_package\n\t./node_modules/gulp/bin/gulp.js clean\n\t./node_modules/gulp/bin/gulp.js package\n\tcp -r dis"
  },
  {
    "path": "README.md",
    "chars": 5301,
    "preview": "[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)\n\n## P"
  },
  {
    "path": "app/badbrowser.html",
    "chars": 1561,
    "preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmln"
  },
  {
    "path": "app/index.html",
    "chars": 5831,
    "preview": "<!doctype html>\n<html lang=\"en\" manifest=\"webogram.appcache\" ng-csp=\"\" xmlns:ng=\"http://angularjs.org\" id=\"ng-app\" style"
  },
  {
    "path": "app/js/app.js",
    "chars": 1752,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/background.js",
    "chars": 654,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/controllers.js",
    "chars": 180549,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/directives.js",
    "chars": 136990,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/directives_mobile.js",
    "chars": 12784,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/filters.js",
    "chars": 7729,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/init.js",
    "chars": 4170,
    "preview": ";(function initApplication () {\n  // Prevent click-jacking\n  try {\n    if (window == window.top || window.chrome && chro"
  },
  {
    "path": "app/js/lib/bin_utils.js",
    "chars": 15804,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/lib/config.js",
    "chars": 242730,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/lib/crypto_worker.js",
    "chars": 1187,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/lib/i18n.js",
    "chars": 4044,
    "preview": "'use strict'\n\nangular.module('myApp.i18n', ['izhukov.utils'])\n  .factory('_', ['$rootScope', '$locale', function ($rootS"
  },
  {
    "path": "app/js/lib/mtproto.js",
    "chars": 61506,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/lib/mtproto_wrapper.js",
    "chars": 27798,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/lib/ng_utils.js",
    "chars": 67619,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/lib/polyfill.js",
    "chars": 4478,
    "preview": "// Console-polyfill. MIT license.\n// https://github.com/paulmillr/console-polyfill\n// Make it safe to do console.log() a"
  },
  {
    "path": "app/js/lib/push_worker.js",
    "chars": 11737,
    "preview": "console.log('[SW] Push worker started')\n\nvar pendingNotification = false\n\nvar defaultBaseUrl\nswitch (location.hostname) "
  },
  {
    "path": "app/js/lib/schema.tl",
    "chars": 78619,
    "preview": "boolFalse#bc799737 = Bool;\nboolTrue#997275b5 = Bool;\n\ntrue#3fedd339 = True;\n\nvector#1cb5c415 {t:Type} # [ t ] = Vector t"
  },
  {
    "path": "app/js/lib/tl_utils.js",
    "chars": 18587,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/lib/utils.js",
    "chars": 13634,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/locales/README.md",
    "chars": 12001,
    "preview": "# Localization guide for Webogram\n\n## Adding/updating a new locale/language\n\nAdding a new locale is pretty easy, all you"
  },
  {
    "path": "app/js/locales/de-de.json",
    "chars": 53123,
    "preview": "{\n    \"modal_search\": \"Suchen\",\n    \"modal_close\": \"Schließen\",\n    \"modal_edit\": \"Bearbeiten\",\n    \"modal_cancel\": \"Abb"
  },
  {
    "path": "app/js/locales/en-us.json",
    "chars": 48825,
    "preview": "{\n\t\"modal_search\": \"Search\",\n\t\"modal_close\": \"Close\",\n\t\"modal_edit\": \"Edit\",\n\t\"modal_cancel\": \"Cancel\",\n\t\"modal_more\": \""
  },
  {
    "path": "app/js/locales/es-es.json",
    "chars": 53076,
    "preview": "{\n    \"modal_search\": \"Buscar\",\n    \"modal_close\": \"Cerrar\",\n    \"modal_edit\": \"Editar\",\n    \"modal_cancel\": \"Cancelar\","
  },
  {
    "path": "app/js/locales/it-it.json",
    "chars": 53175,
    "preview": "{\n    \"modal_search\": \"Cerca\",\n    \"modal_close\": \"Chiudi\",\n    \"modal_edit\": \"Modifica\",\n    \"modal_cancel\": \"Annulla\","
  },
  {
    "path": "app/js/locales/nl-nl.json",
    "chars": 52725,
    "preview": "{\n    \"modal_search\": \"Zoeken\",\n    \"modal_close\": \"Sluit\",\n    \"modal_edit\": \"Wijzig\",\n    \"modal_cancel\": \"Annuleren\","
  },
  {
    "path": "app/js/locales/pt-br.json",
    "chars": 53124,
    "preview": "{\n    \"modal_search\": \"Buscar\",\n    \"modal_close\": \"Fechar\",\n    \"modal_edit\": \"Editar\",\n    \"modal_cancel\": \"Cancelar\","
  },
  {
    "path": "app/js/locales/ru-ru.json",
    "chars": 52930,
    "preview": "{\n    \"modal_search\": \"Поиск\",\n    \"modal_close\": \"Закрыть\",\n    \"modal_edit\": \"Изменить\",\n    \"modal_cancel\": \"Отмена\","
  },
  {
    "path": "app/js/message_composer.js",
    "chars": 52700,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/messages_manager.js",
    "chars": 134125,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/js/offline_manager.js",
    "chars": 2916,
    "preview": ";(function initAutoUpgrade () {\n  window.safeConfirm = function (params, callback) {\n    if (typeof params === 'string')"
  },
  {
    "path": "app/js/services.js",
    "chars": 163769,
    "preview": "/*!\n * Webogram v0.7.0 - messaging web application for MTProto\n * https://github.com/zhukov/webogram\n * Copyright (C) 20"
  },
  {
    "path": "app/less/app.less",
    "chars": 87521,
    "preview": "@import \"lib/mixins\";\n\n/* app common css */\n\nhtml {\n  background: #e7ebf0;\n  overflow: visible;\n}\n\nbody {\n  color: #000;"
  },
  {
    "path": "app/less/desktop.less",
    "chars": 43861,
    "preview": "@import \"lib/mixins\";\n\n/* app desktop css */\n\n.tg_head {\n  &_split {\n    max-width: 1010px;\n    margin: 0 auto;\n    heig"
  },
  {
    "path": "app/less/font.less",
    "chars": 1942,
    "preview": "/* From http://fonts.googleapis.com/css?family=Open+Sans:400&subset=latin,cyrillic */\n\n/* cyrillic */\n@font-face {\n  fon"
  },
  {
    "path": "app/less/lib/mixins.less",
    "chars": 2958,
    "preview": "@user_colors:   '#8365ab',\n                '#539e4f',\n                '#ae9661',\n                '#4979a3',\n            "
  },
  {
    "path": "app/less/mobile.less",
    "chars": 32299,
    "preview": "@import \"lib/mixins\";\n\n/* app mobile css */\n\nhtml {\n  background: #fff;\n}\n\n.dropdown-menu {\n  border-radius: 0;\n\n  & > l"
  },
  {
    "path": "app/manifest.json",
    "chars": 689,
    "preview": "{\n  \"name\": \"Telegram\",\n  \"description\": \"Telegram Web App.\\nMore info & source code here: https://github.com/zhukov/web"
  },
  {
    "path": "app/manifest.webapp",
    "chars": 2247,
    "preview": "{\n  \"name\": \"Telegram\",\n  \"description\": \"Telegram Web App.\\nMore info & source code here: https://github.com/zhukov/web"
  },
  {
    "path": "app/manifest.webapp.json",
    "chars": 1516,
    "preview": "{\n  \"name\": \"Telegram\",\n  \"description\": \"Telegram Web App.\\nMore info & source code here: https://github.com/zhukov/web"
  },
  {
    "path": "app/nacl/Makefile",
    "chars": 1639,
    "preview": "# Copyright (c) 2013 The Native Client Authors. All rights reserved.\n# Use of this source code is governed by a BSD-styl"
  },
  {
    "path": "app/nacl/aes.h",
    "chars": 5509,
    "preview": "/* crypto/aes/aes.h -*- mode:C; c-file-style: \"eay\" -*- */\n/* =========================================================="
  },
  {
    "path": "app/nacl/aes_core.c",
    "chars": 60175,
    "preview": "/* crypto/aes/aes_core.c -*- mode:C; c-file-style: \"eay\" -*- */\n/**\n * rijndael-alg-fst.c\n *\n * @version 3.0 (December 2"
  },
  {
    "path": "app/nacl/aes_ige.c",
    "chars": 9707,
    "preview": "/* crypto/aes/aes_ige.c -*- mode:C; c-file-style: \"eay\" -*- */\n/* ======================================================"
  },
  {
    "path": "app/nacl/aes_locl.h",
    "chars": 3528,
    "preview": "/* crypto/aes/aes.h -*- mode:C; c-file-style: \"eay\" -*- */\n/* =========================================================="
  },
  {
    "path": "app/nacl/aes_misc.c",
    "chars": 3290,
    "preview": "/* crypto/aes/aes_misc.c -*- mode:C; c-file-style: \"eay\" -*- */\n/* ====================================================="
  },
  {
    "path": "app/nacl/mtproto_crypto.cc",
    "chars": 9334,
    "preview": "// Copyright (c) 2013 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style l"
  },
  {
    "path": "app/nacl/mtproto_crypto.nmf",
    "chars": 144,
    "preview": "{\n  \"program\": {\n    \"portable\": {\n      \"pnacl-translate\": {\n        \"url\": \"mtproto_crypto.pexe?67\",\n        \"optlevel"
  },
  {
    "path": "app/partials/desktop/audio_player.html",
    "chars": 3261,
    "preview": "<div class=\"audio_player_wrap clearfix\">\n\t<a class=\"im_message_file_button\" ng-click=\"togglePlay()\" ng-class=\"{im_messag"
  },
  {
    "path": "app/partials/desktop/changelog_modal.html",
    "chars": 1772,
    "preview": "<div class=\"changelog_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head\">\n    <div class=\"md_mod"
  },
  {
    "path": "app/partials/desktop/channel_edit_modal.html",
    "chars": 1055,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/channel_modal.html",
    "chars": 8250,
    "preview": "<div class=\"chat_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head\">\n    <div class=\"md_modal_ti"
  },
  {
    "path": "app/partials/desktop/chat_create_modal.html",
    "chars": 828,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/chat_edit_modal.html",
    "chars": 820,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/chat_invite_link_modal.html",
    "chars": 1444,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <div class=\"modal_simple"
  },
  {
    "path": "app/partials/desktop/chat_modal.html",
    "chars": 6434,
    "preview": "<div class=\"chat_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head\">\n    <div class=\"md_modal_ti"
  },
  {
    "path": "app/partials/desktop/composer_dropdown.html",
    "chars": 1299,
    "preview": "<div ng-switch=\"type\">\n\n  <ul ng-switch-when=\"mentions\" class=\"composer_dropdown\">\n    <li ng-repeat=\"user in mentionUse"
  },
  {
    "path": "app/partials/desktop/confirm_modal.html",
    "chars": 8787,
    "preview": "<div class=\"confirm_modal_wrap md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <div "
  },
  {
    "path": "app/partials/desktop/contacts_modal.html",
    "chars": 4232,
    "preview": "<div class=\"contacts_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head md_modal_head_simple\">\n  "
  },
  {
    "path": "app/partials/desktop/country_select_modal.html",
    "chars": 1650,
    "preview": "<div class=\"countries_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head md_modal_head_simple\">\n "
  },
  {
    "path": "app/partials/desktop/dialog.html",
    "chars": 3682,
    "preview": "<a class=\"im_dialog\" ng-mousedown=\"dialogSelect(dialogMessage.peerString, dialogMessage.unreadCount == -1 && dialogMessa"
  },
  {
    "path": "app/partials/desktop/document_modal.html",
    "chars": 1892,
    "preview": "<div class=\"modal_close_wrap\" ng-click=\"$close()\">\n  <div class=\"modal_close\"></div>\n</div>\n\n<div class=\"media_modal_bot"
  },
  {
    "path": "app/partials/desktop/edit_contact_modal.html",
    "chars": 1388,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/embed_modal.html",
    "chars": 1338,
    "preview": "<div class=\"modal_close_wrap\" ng-click=\"$close()\">\n  <div class=\"modal_close\"></div>\n</div>\n\n<div class=\"media_modal_bot"
  },
  {
    "path": "app/partials/desktop/emoji_btn_tooltip.html",
    "chars": 992,
    "preview": "<div class=\"composer_emoji_btn_wrap\">\n\n  <div class=\"composer_emoji_tooltip_wrap\">\n    <div class=\"composer_emoji_toolti"
  },
  {
    "path": "app/partials/desktop/error_modal.html",
    "chars": 7035,
    "preview": "<div class=\"error_modal_wrap md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\" ng-class=\"{md"
  },
  {
    "path": "app/partials/desktop/footer.html",
    "chars": 351,
    "preview": "<div class=\"footer_wrap\" ng-controller=\"AppFooterController\">\n\t<a class=\"footer_link\" href=\"https://telegram.org\" target"
  },
  {
    "path": "app/partials/desktop/forwarded_messages.html",
    "chars": 845,
    "preview": "<div class=\"im_message_reply clearfix\" ng-class=\"{im_message_reply_thumbed: thumb !== false}\">\n  <div class=\"im_message_"
  },
  {
    "path": "app/partials/desktop/full_document.html",
    "chars": 930,
    "preview": "<div class=\"document_modal_image_wrap\">\n  <div class=\"img_fullsize_with_progress_wrap document_fullsize_with_progress_wr"
  },
  {
    "path": "app/partials/desktop/full_gif.html",
    "chars": 1284,
    "preview": "<a class=\"img_gif_with_progress_wrap\" ng-click=\"toggle($event)\">\n\n  <div class=\"img_gif_image_wrap\">\n\n    <div class=\"im"
  },
  {
    "path": "app/partials/desktop/full_photo.html",
    "chars": 765,
    "preview": "<div class=\"img_fullsize_with_progress_wrap\">\n  <div class=\"img_fullsize_progress_overlay\" ng-show=\"progress.enabled\">\n "
  },
  {
    "path": "app/partials/desktop/full_round.html",
    "chars": 1355,
    "preview": "<a class=\"img_round_with_progress_wrap\" ng-click=\"toggle($event)\">\n\n  <div class=\"img_round_image_wrap\" ng-style=\"::{wid"
  },
  {
    "path": "app/partials/desktop/full_video.html",
    "chars": 1433,
    "preview": "<div class=\"img_fullsize_with_progress_wrap\" ng-style=\"{width: video.full.width + 'px', height: video.full.height + 'px'"
  },
  {
    "path": "app/partials/desktop/game_modal.html",
    "chars": 1239,
    "preview": "<div class=\"modal_close_wrap\" ng-click=\"$close()\">\n  <div class=\"modal_close\"></div>\n</div>\n\n<div class=\"media_modal_bot"
  },
  {
    "path": "app/partials/desktop/head.html",
    "chars": 6524,
    "preview": "<div class=\"tg_page_head tg_head_wrap noselect clearfix\">\n  <div class=\"tg_try_desktop\" ng-if=\"try_desktop.shown\">\n    <"
  },
  {
    "path": "app/partials/desktop/im.html",
    "chars": 14455,
    "preview": "<div my-head></div>\n\n<div class=\"im_page_wrap clearfix\" ng-class=\"{im_page_peer_not_selected: !curDialog.peer}\">\n\n  <div"
  },
  {
    "path": "app/partials/desktop/import_contact_modal.html",
    "chars": 1795,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/inactive.html",
    "chars": 586,
    "preview": "<div class=\"inactive_page_wrap\">\n  <div class=\"tg_head_split inactive_head\"></div>\n  <div class=\"im_page_wrap\">\n    <div"
  },
  {
    "path": "app/partials/desktop/inline_results.html",
    "chars": 4510,
    "preview": "<a ng-if=\"botResults.switch_pm !== undefined\" class=\"inline_switch_pm\" ng-bind-html=\"botResults.switch_pm.rText\" data-in"
  },
  {
    "path": "app/partials/desktop/lang_footer.html",
    "chars": 392,
    "preview": "<div class=\"footer_wrap\" ng-controller=\"AppLangSelectController\">\n\t<span ng-repeat=\"locale in ::supportedLocales\">\n\t  <a"
  },
  {
    "path": "app/partials/desktop/login.html",
    "chars": 10386,
    "preview": "<div class=\"login_page_wrap\" my-custom-background=\"#e7ebf0\">\n  <div class=\"login_try_desktop\" ng-if=\"try_desktop.shown\">"
  },
  {
    "path": "app/partials/desktop/media_modal_layout.html",
    "chars": 136,
    "preview": "<div tabindex=\"-1\" role=\"dialog\" class=\"modal\" ng-style=\"{'z-index': 1050 + index*10}\" ng-click=\"close($event)\"  modal-t"
  },
  {
    "path": "app/partials/desktop/megagroup_edit_modal.html",
    "chars": 1047,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/message.html",
    "chars": 5590,
    "preview": " <div class=\"im_message_outer_wrap hasselect\" ng-click=\"toggleMessage(historyMessage.mid, $event)\" data-msg-id=\"{{::hist"
  },
  {
    "path": "app/partials/desktop/message_attach_contact.html",
    "chars": 539,
    "preview": "<div class=\"im_message_contact\">\n  <a ng-if=\"::media.user_id > 0\"  class=\"im_message_contact_photo pull-left\" my-peer-ph"
  },
  {
    "path": "app/partials/desktop/message_attach_document.html",
    "chars": 5286,
    "preview": "<div ng-switch=\"::media.document.type\" data-doc-id=\"{{::media.document.id}}\">\n\n  <div ng-switch-when=\"gif\" my-load-gif d"
  },
  {
    "path": "app/partials/desktop/message_attach_game.html",
    "chars": 839,
    "preview": "<div class=\"im_message_game\">\n  <div class=\"im_message_webpage_wrap clearfix\">\n    <div class=\"im_message_webpage_photo\""
  },
  {
    "path": "app/partials/desktop/message_attach_geo.html",
    "chars": 303,
    "preview": "<a ng-href=\"{{::media.mapUrl}}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"im_message_geopoint\">\n  <img\n    class="
  },
  {
    "path": "app/partials/desktop/message_attach_pending.html",
    "chars": 1105,
    "preview": "<div class=\"im_message_document im_message_upload_file\" ng-class=\"::'im_message_upload_' + media.type\">\n  <div class=\"im"
  },
  {
    "path": "app/partials/desktop/message_attach_photo.html",
    "chars": 438,
    "preview": "<a class=\"im_message_photo_thumb\" ng-click=\"openPhoto(media.photo.id, {m: messageId})\" ng-style=\"::{width: media.photo.t"
  },
  {
    "path": "app/partials/desktop/message_attach_venue.html",
    "chars": 704,
    "preview": "<div class=\"im_message_venue clearfix\">\n\n  <a ng-href=\"{{::media.mapUrl}}\" target=\"_blank\" rel=\"noopener noreferrer\" cla"
  },
  {
    "path": "app/partials/desktop/message_attach_webpage.html",
    "chars": 3323,
    "preview": "<div ng-show=\"media.webpage._ == 'webPage'\" class=\"im_message_webpage_wrap clearfix\" ng-switch=\"media.webpage.type\">\n  <"
  },
  {
    "path": "app/partials/desktop/message_media.html",
    "chars": 1302,
    "preview": "<div ng-switch=\"::media._\">\n  <div ng-switch-when=\"messageMediaPhoto\"     my-message-photo=\"media\" message-id=\"messageId"
  },
  {
    "path": "app/partials/desktop/message_service.html",
    "chars": 4425,
    "preview": "<span ng-switch=\"::historyMessage.action._\">\n  <my-i18n>\n    <span ng-switch-when=\"messageActionChatCreate\" my-i18n-form"
  },
  {
    "path": "app/partials/desktop/password_recovery_modal.html",
    "chars": 1310,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/password_update_modal.html",
    "chars": 3084,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/peer_pinned_message_bar.html",
    "chars": 302,
    "preview": "<div class=\"im_history_pinned_wrap\" ng-if=\"pinnedMessageID > 0\">\n  <a class=\"im_history_pinned_hide\" ng-mousedown=\"hideP"
  },
  {
    "path": "app/partials/desktop/peer_select.html",
    "chars": 6148,
    "preview": "<div class=\"peer_select_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head md_modal_head_simple\">"
  },
  {
    "path": "app/partials/desktop/photo_modal.html",
    "chars": 3015,
    "preview": "<div class=\"modal_prev_wrap\" ng-class=\"{modal_prev_active_wrap: nav.hasPrev}\" ng-click=\"nav.prev($event)\">\n  <div class="
  },
  {
    "path": "app/partials/desktop/pinned_message.html",
    "chars": 245,
    "preview": "<span ng-switch=\"pinnedMessage.loading\"><span ng-switch-when=\"true\" my-i18n=\"im_reply_loading\"><my-i18n-param name=\"dots"
  },
  {
    "path": "app/partials/desktop/profile_edit_modal.html",
    "chars": 1182,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/reply_markup.html",
    "chars": 709,
    "preview": "<div class=\"reply_markup_wrap\">\n  <div class=\"reply_markup\" ng-class=\"replyMarkup.splitCount ? 'reply_markup_h' + replyM"
  },
  {
    "path": "app/partials/desktop/reply_message.html",
    "chars": 1007,
    "preview": "<div class=\"im_message_reply clearfix\" ng-class=\"{im_message_reply_thumbed: thumb !== false}\" ng-switch=\"replyMessage.lo"
  },
  {
    "path": "app/partials/desktop/report_msgs_modal.html",
    "chars": 2587,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/send_form.html",
    "chars": 4123,
    "preview": "<form class=\"im_send_form\" ng-class=\"{im_send_form_empty: !draftMessage.text.length, composer_progress_enabled: draftMes"
  },
  {
    "path": "app/partials/desktop/sessions_list_modal.html",
    "chars": 2729,
    "preview": "<div class=\"sessions_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head md_modal_head_simple\">\n  "
  },
  {
    "path": "app/partials/desktop/settings_modal.html",
    "chars": 8185,
    "preview": "<div class=\"settings_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head\">\n    <div class=\"md_moda"
  },
  {
    "path": "app/partials/desktop/short_message.html",
    "chars": 4762,
    "preview": "<span class=\"im_short_message_media\" ng-if=\"message.media\" ng-switch=\"message.media._\">\n  <span ng-switch-when=\"messageM"
  },
  {
    "path": "app/partials/desktop/slider.html",
    "chars": 154,
    "preview": "<div class=\"tg_slider_wrap\">\n\t<div class=\"tg_slider_thumb\"></div>\n\t<div class=\"tg_slider_track\">\n\t\t<div class=\"tg_slider"
  },
  {
    "path": "app/partials/desktop/stickerset_modal.html",
    "chars": 2237,
    "preview": "<div class=\"stickerset_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head md_modal_head_simple\">\n"
  },
  {
    "path": "app/partials/desktop/user_modal.html",
    "chars": 5680,
    "preview": "<div class=\"user_modal_wrap md_modal_wrap\" my-modal-position>\n\n  <div class=\"md_modal_head\">\n    <div class=\"md_modal_ti"
  },
  {
    "path": "app/partials/desktop/username_edit_modal.html",
    "chars": 1094,
    "preview": "<div class=\"md_simple_modal_wrap\" my-modal-position>\n\n  <div class=\"md_simple_modal_body\">\n\n    <form class=\"modal_simpl"
  },
  {
    "path": "app/partials/desktop/video_modal.html",
    "chars": 1951,
    "preview": "<div class=\"modal_close_wrap\" ng-class=\"{modal_close_wrap_wnext: nav.hasNext}\" ng-click=\"$close()\">\n  <div class=\"modal_"
  },
  {
    "path": "app/partials/mobile/audio_player.html",
    "chars": 3261,
    "preview": "<div class=\"audio_player_wrap clearfix\">\n\t<a class=\"im_message_file_button\" ng-click=\"togglePlay()\" ng-class=\"{im_messag"
  },
  {
    "path": "app/partials/mobile/changelog_modal.html",
    "chars": 27450,
    "preview": "<div class=\"changelog_modal_wrap\">\n\n  <a class=\"modal-close-button\" ng-click=\"$close()\"><i></i></a>\n\n  <div class=\"modal"
  },
  {
    "path": "app/partials/mobile/channel_modal.html",
    "chars": 7926,
    "preview": "<div class=\"chat_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top navba"
  },
  {
    "path": "app/partials/mobile/chat_create_modal.html",
    "chars": 1233,
    "preview": "<div class=\"contacts_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top n"
  },
  {
    "path": "app/partials/mobile/chat_edit_modal.html",
    "chars": 1225,
    "preview": "<div class=\"contacts_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top n"
  },
  {
    "path": "app/partials/mobile/chat_modal.html",
    "chars": 5474,
    "preview": "<div class=\"chat_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top navba"
  },
  {
    "path": "app/partials/mobile/contacts_modal.html",
    "chars": 4315,
    "preview": "<div class=\"contacts_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top n"
  },
  {
    "path": "app/partials/mobile/country_select_modal.html",
    "chars": 1803,
    "preview": "<div class=\"countries_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top "
  },
  {
    "path": "app/partials/mobile/dialog.html",
    "chars": 3545,
    "preview": "<a class=\"im_dialog\" ng-mousedown=\"dialogSelect(dialogMessage.peerString, dialogMessage.unreadCount == -1 && dialogMessa"
  },
  {
    "path": "app/partials/mobile/edit_contact_modal.html",
    "chars": 1686,
    "preview": "<div class=\"import_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top nav"
  },
  {
    "path": "app/partials/mobile/full_gif.html",
    "chars": 1222,
    "preview": "<a class=\"img_gif_with_progress_wrap\" ng-click=\"toggle($event)\">\n\n  <div class=\"img_gif_image_wrap\">\n\n    <div class=\"im"
  },
  {
    "path": "app/partials/mobile/full_photo.html",
    "chars": 765,
    "preview": "<div class=\"img_fullsize_with_progress_wrap\">\n  <div class=\"img_fullsize_progress_overlay\" ng-show=\"progress.enabled\">\n "
  },
  {
    "path": "app/partials/mobile/full_video.html",
    "chars": 1433,
    "preview": "<div class=\"img_fullsize_with_progress_wrap\" ng-style=\"{width: video.full.width + 'px', height: video.full.height + 'px'"
  },
  {
    "path": "app/partials/mobile/game_modal.html",
    "chars": 1364,
    "preview": "<div class=\"game_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top navba"
  },
  {
    "path": "app/partials/mobile/head.html",
    "chars": 7421,
    "preview": "<div class=\"tg_page_head\">\n  <div class=\"navbar navbar-static-top  navbar-inverse\" role=\"navigation\" ng-class=\"{navbar_p"
  },
  {
    "path": "app/partials/mobile/im.html",
    "chars": 9233,
    "preview": "<div my-head></div>\n\n<div class=\"im_page_wrap\" ng-class=\"{im_page_peer_not_selected: !curDialog.peer}\">\n\n  <div class=\"i"
  },
  {
    "path": "app/partials/mobile/import_contact_modal.html",
    "chars": 1908,
    "preview": "<div class=\"import_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top nav"
  },
  {
    "path": "app/partials/mobile/login.html",
    "chars": 10196,
    "preview": "<div class=\"tg_page_head\">\n  <div class=\"navbar navbar-static-top navbar-inverse navbar_peer_not_selected\">\n    <div cla"
  },
  {
    "path": "app/partials/mobile/message.html",
    "chars": 4763,
    "preview": "<div class=\"im_message_outer_wrap\" ng-click=\"toggleMessage(historyMessage.mid, $event)\">\n\n\n  <div class=\"im_message_wrap"
  },
  {
    "path": "app/partials/mobile/message_actions_modal.html",
    "chars": 1092,
    "preview": "<div class=\"message_actions_modal_wrap\" my-modal-position>\n\n  <div class=\"message_actions_wrap\">\n    <button ng-if=\"hist"
  },
  {
    "path": "app/partials/mobile/message_attach_contact.html",
    "chars": 539,
    "preview": "<div class=\"im_message_contact\">\n  <a ng-if=\"::media.user_id > 0\"  class=\"im_message_contact_photo pull-left\" my-peer-ph"
  },
  {
    "path": "app/partials/mobile/message_attach_document.html",
    "chars": 3416,
    "preview": "<div ng-switch=\"::media.document.type\">\n\n  <div ng-switch-when=\"gif\" my-load-gif document=\"media.document\"></div>\n  \n  <"
  },
  {
    "path": "app/partials/mobile/message_attach_geo.html",
    "chars": 203,
    "preview": "<a ng-href=\"{{::media.mapUrl}}\" target=\"_blank\" class=\"im_message_geopoint\">\n  <img\n    class=\"im_message_venue_geopoint"
  },
  {
    "path": "app/partials/mobile/message_attach_pending.html",
    "chars": 1071,
    "preview": "<div class=\"im_message_document im_message_upload_file\" ng-class=\"::'im_message_upload_' + media.type\">\n  <div class=\"im"
  },
  {
    "path": "app/partials/mobile/message_attach_photo.html",
    "chars": 424,
    "preview": "<a class=\"im_message_photo_thumb\" ng-click=\"openPhoto(media.photo.id, {m: messageId})\" ng-style=\"::{width: media.photo.t"
  },
  {
    "path": "app/partials/mobile/message_attach_venue.html",
    "chars": 704,
    "preview": "<div class=\"im_message_venue clearfix\">\n\n  <a ng-href=\"{{::media.mapUrl}}\" target=\"_blank\" rel=\"noopener noreferrer\" cla"
  },
  {
    "path": "app/partials/mobile/message_attach_webpage.html",
    "chars": 2613,
    "preview": "<div ng-show=\"webpage._ == 'webPage'\" class=\"im_message_webpage_wrap clearfix\" ng-switch=\"webpage.type\">\n  <div ng-switc"
  },
  {
    "path": "app/partials/mobile/message_service.html",
    "chars": 4388,
    "preview": "<span ng-switch=\"::historyMessage.action._\">\n  <my-i18n>\n    <span ng-switch-when=\"messageActionChatCreate\" my-i18n-form"
  },
  {
    "path": "app/partials/mobile/password_recovery_modal.html",
    "chars": 1729,
    "preview": "<div class=\"username_edit_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-"
  },
  {
    "path": "app/partials/mobile/password_update_modal.html",
    "chars": 3595,
    "preview": "<div class=\"username_edit_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-"
  },
  {
    "path": "app/partials/mobile/peer_select.html",
    "chars": 4059,
    "preview": "<div class=\"peer_select_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-to"
  },
  {
    "path": "app/partials/mobile/phonebook_modal.html",
    "chars": 3407,
    "preview": "<div class=\"contacts_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top n"
  },
  {
    "path": "app/partials/mobile/photo_modal.html",
    "chars": 2386,
    "preview": "<div class=\"media_modal_bottom_panel_wrap\" ng-show=\"!hideToolbars\">\n  <div class=\"media_modal_bottom_panel\">\n    <div cl"
  },
  {
    "path": "app/partials/mobile/profile_edit_modal.html",
    "chars": 1568,
    "preview": "<div class=\"profile_edit_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-t"
  },
  {
    "path": "app/partials/mobile/send_form.html",
    "chars": 3441,
    "preview": "<form class=\"im_send_form\" ng-class=\"{im_send_form_empty: !draftMessage.text.length && draftMessage.type != 'edit', comp"
  },
  {
    "path": "app/partials/mobile/sessions_list_modal.html",
    "chars": 2961,
    "preview": "<div class=\"sessions_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top n"
  },
  {
    "path": "app/partials/mobile/settings_modal.html",
    "chars": 8844,
    "preview": "<div class=\"settings_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top n"
  },
  {
    "path": "app/partials/mobile/stickerset_modal.html",
    "chars": 2191,
    "preview": "<div class=\"stickerset_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-top"
  },
  {
    "path": "app/partials/mobile/user_modal.html",
    "chars": 4804,
    "preview": "<div class=\"mobile_user_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-to"
  },
  {
    "path": "app/partials/mobile/username_edit_modal.html",
    "chars": 1700,
    "preview": "<div class=\"username_edit_modal_wrap\">\n\n  <div class=\"tg_page_head tg_modal_head\">\n    <div class=\"navbar navbar-static-"
  },
  {
    "path": "app/partials/mobile/video_modal.html",
    "chars": 1848,
    "preview": "<div class=\"media_modal_bottom_panel_wrap\">\n  <div class=\"media_modal_bottom_panel\">\n    <div class=\"media_modal_bottom_"
  },
  {
    "path": "app/service_worker.js",
    "chars": 81,
    "preview": "/* global importScripts */\nimportScripts('js/lib/push_worker.js')\n\n// Version 53\n"
  },
  {
    "path": "app/vendor/README.md",
    "chars": 2194,
    "preview": "## Third party libraries\n\n### [AngularJS](http://angularjs.org/)\n\n**Author**: Google, Inc.\n**License**: MIT, https://git"
  },
  {
    "path": "app/vendor/angular/angular-animate.js",
    "chars": 156629,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-aria.js",
    "chars": 16482,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-cookies.js",
    "chars": 8463,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-csp.css",
    "chars": 343,
    "preview": "/* Include this file in your html if you are using the CSP mode. */\n\n@charset \"UTF-8\";\n\n[ng\\:cloak],\n[ng-cloak],\n[data-n"
  },
  {
    "path": "app/vendor/angular/angular-loader.js",
    "chars": 23232,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n\n(function() {'u"
  },
  {
    "path": "app/vendor/angular/angular-message-format.js",
    "chars": 41403,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-messages.js",
    "chars": 31502,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-mocks.js",
    "chars": 135243,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-parse-ext.js",
    "chars": 58506,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-resource.js",
    "chars": 38056,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-route.js",
    "chars": 46917,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-sanitize.js",
    "chars": 34264,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular-touch.js",
    "chars": 12696,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/angular.js",
    "chars": 1371759,
    "preview": "/**\n * @license AngularJS v1.7.8\n * (c) 2010-2018 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window"
  },
  {
    "path": "app/vendor/angular/errors.json",
    "chars": 9599,
    "preview": "{\"id\":\"ng\",\"generated\":\"Tue Mar 12 2019 09:40:19 GMT+0000 (UTC)\",\"errors\":{\"ng\":{\"areq\":\"Argument '{0}' is {1}\",\"cpta\":\""
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_af-na.js",
    "chars": 2350,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_af-za.js",
    "chars": 2350,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_af.js",
    "chars": 2344,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_agq-cm.js",
    "chars": 4028,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_agq.js",
    "chars": 4022,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ak-gh.js",
    "chars": 3179,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ak.js",
    "chars": 3173,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_am-et.js",
    "chars": 3248,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_am.js",
    "chars": 3242,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-001.js",
    "chars": 4165,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-ae.js",
    "chars": 4159,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-bh.js",
    "chars": 4160,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-dj.js",
    "chars": 4160,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-dz.js",
    "chars": 4078,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-eg.js",
    "chars": 4163,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-eh.js",
    "chars": 4149,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-er.js",
    "chars": 4160,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-il.js",
    "chars": 4155,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  },
  {
    "path": "app/vendor/angular/i18n/angular-locale_ar-iq.js",
    "chars": 4406,
    "preview": "'use strict';\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE:"
  }
]

// ... and 845 more files (download for full content)

About this extraction

This page contains the full source code of the zhukov/webogram GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1045 files (13.0 MB), approximately 3.5M tokens, and a symbol index with 7092 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!