Advanced Access Manager - Version 2.0

Version Description

  • New UI
  • Robust and completely new core functionality
  • Over 3 dozen of bug fixed and improvement during 3 alpha & beta versions
Download this release

Release Info

Developer vasyl_m
Plugin Icon 128x128 Advanced Access Manager
Version 2.0
Comparing to
See all releases

Code changes from version 1.0 to 2.0

Files changed (302) hide show
  1. aam.php +1003 -0
  2. active-menu.png +0 -0
  3. application/control/object.php +113 -0
  4. application/control/object/backup.php +111 -0
  5. application/control/object/capability.php +96 -0
  6. application/control/object/configpress.php +197 -0
  7. application/control/object/event.php +71 -0
  8. application/control/object/menu.php +163 -0
  9. application/control/object/metabox.php +1 -0
  10. application/control/object/post.php +263 -0
  11. application/control/object/term.php +216 -0
  12. application/control/subject.php +287 -0
  13. application/control/subject/role.php +197 -0
  14. application/control/subject/user.php +1 -0
  15. application/control/subject/visitor.php +119 -0
  16. application/core/api.php +167 -0
  17. application/core/console.php +28 -0
  18. application/core/extension.php +266 -0
  19. application/core/migrate.php +479 -0
  20. application/core/request.php +109 -0
  21. application/core/update.php +94 -0
  22. application/view/abstract.php +70 -0
  23. application/view/ajax.php +520 -0
  24. application/view/capability.php +219 -0
  25. application/view/configpress.php +28 -0
  26. application/view/event.php +68 -0
  27. application/view/extension.php +125 -0
  28. application/view/manager.php +380 -0
  29. application/view/menu.php +126 -0
  30. application/view/metabox.php +271 -0
  31. application/view/post.php +478 -0
  32. application/view/role.php +111 -0
  33. application/view/tmpl/capability.phtml +76 -0
  34. application/view/tmpl/configpress.phtml +15 -0
  35. application/view/tmpl/event.phtml +108 -0
  36. application/view/tmpl/extension.phtml +88 -0
  37. application/view/tmpl/manager.phtml +98 -0
  38. application/view/tmpl/menu.phtml +75 -0
  39. application/view/tmpl/metabox.phtml +20 -0
  40. application/view/tmpl/post.phtml +233 -0
  41. application/view/tmpl/role.phtml +41 -0
  42. application/view/tmpl/user.phtml +40 -0
  43. application/view/tmpl/visitor.phtml +11 -0
  44. application/view/user.php +107 -0
  45. application/view/visitor.php +28 -0
  46. config.php +92 -0
  47. core/class-mvb_coreplugin.php +0 -62
  48. core/class-mvb_coretemplate.php +0 -121
  49. css/images/info.png +0 -0
  50. css/images/linkedin.png +0 -0
  51. css/images/logo.png +0 -0
  52. css/images/share_facebook.png +0 -0
  53. css/images/share_friend.png +0 -0
  54. css/images/twitter.png +0 -0
  55. css/images/xit.gif +0 -0
  56. css/tooltip/black.png +0 -0
  57. css/tooltip/black_arrow.png +0 -0
  58. css/tooltip/black_arrow_big.png +0 -0
  59. css/tooltip/black_big.png +0 -0
  60. css/tooltip/white.png +0 -0
  61. css/tooltip/white_arrow.png +0 -0
  62. css/tooltip/white_arrow_big.png +0 -0
  63. css/tooltip/white_big.png +0 -0
  64. css/ui/images/pbar-ani.gif +0 -0
  65. css/ui/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  66. css/ui/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  67. css/ui/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  68. css/ui/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  69. css/ui/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  70. css/ui/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  71. css/ui/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  72. css/ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  73. css/ui/images/ui-icons_222222_256x240.png +0 -0
  74. css/ui/images/ui-icons_2e83ff_256x240.png +0 -0
  75. css/ui/images/ui-icons_454545_256x240.png +0 -0
  76. css/ui/images/ui-icons_888888_256x240.png +0 -0
  77. css/ui/images/ui-icons_cd0a0a_256x240.png +0 -0
  78. css/ui/jquery.ui.accordion.css +0 -19
  79. css/ui/jquery.ui.all.css +0 -11
  80. css/ui/jquery.ui.autocomplete.css +0 -53
  81. css/ui/jquery.ui.base.css +0 -6
  82. css/ui/jquery.ui.button.css +0 -38
  83. css/ui/jquery.ui.core.css +0 -41
  84. css/ui/jquery.ui.datepicker.css +0 -68
  85. css/ui/jquery.ui.dialog.css +0 -21
  86. css/ui/jquery.ui.progressbar.css +0 -11
  87. css/ui/jquery.ui.resizable.css +0 -25
  88. css/ui/jquery.ui.selectable.css +0 -10
  89. css/ui/jquery.ui.slider.css +0 -24
  90. css/ui/jquery.ui.tabs.css +0 -18
  91. css/ui/jquery.ui.theme.css +0 -252
  92. css/wpaccess_style.css +0 -326
  93. docs/configpress.pdf +0 -0
  94. extension/AAM_Multisite_Support/extension.php +272 -0
  95. extension/AAM_Multisite_Support/images/add-active.png +0 -0
  96. extension/AAM_Multisite_Support/images/add.png +0 -0
  97. extension/AAM_Multisite_Support/images/edit-active.png +0 -0
  98. extension/AAM_Multisite_Support/images/edit.png +0 -0
  99. extension/AAM_Multisite_Support/images/manage-active.png +0 -0
  100. extension/AAM_Multisite_Support/images/manage.png +0 -0
  101. extension/AAM_Multisite_Support/images/multisite-active.png +0 -0
  102. extension/AAM_Multisite_Support/images/multisite.png +0 -0
  103. extension/AAM_Multisite_Support/images/pin-active.png +0 -0
  104. extension/AAM_Multisite_Support/images/pin.png +0 -0
  105. extension/AAM_Multisite_Support/images/refresh-active.png +0 -0
  106. extension/AAM_Multisite_Support/images/refresh.png +0 -0
  107. extension/AAM_Multisite_Support/images/unpin.png +0 -0
  108. extension/AAM_Multisite_Support/index.php +14 -0
  109. extension/AAM_Multisite_Support/multisite.css +98 -0
  110. extension/AAM_Multisite_Support/multisite.js +228 -0
  111. extension/AAM_Multisite_Support/ui.phtml +31 -0
  112. js/admin-options.js +0 -605
  113. js/jquery.tools.min.js +0 -145
  114. js/ui/jquery-ui.min.js +0 -259
  115. lang/aam-de_DE.mo +0 -0
  116. lang/aam-de_DE.po +336 -0
  117. lang/aam-en_US.mo +0 -0
  118. lang/aam-en_US.po +310 -0
  119. lang/aam-es_ES.mo +0 -0
  120. lang/aam-es_ES.po +998 -0
  121. lang/aam.pot +308 -0
  122. library/Zend/Config.php +485 -0
  123. library/Zend/Config/Exception.php +33 -0
  124. library/Zend/Config/Ini.php +301 -0
  125. library/Zend/Exception.php +101 -0
  126. license.txt +14 -0
  127. media/css/aam.css +1411 -0
  128. media/css/codemirror.css +260 -0
  129. media/css/extension.css +193 -0
  130. media/css/images/animated-overlay.gif +0 -0
  131. media/css/images/capability/add-active.png +0 -0
  132. media/css/images/capability/add.png +0 -0
  133. media/css/images/capability/ajax-loader.gif +0 -0
  134. media/css/images/capability/checked.png +0 -0
  135. media/css/images/capability/copy-active.png +0 -0
  136. media/css/images/capability/copy.png +0 -0
  137. media/css/images/capability/delete-active.png +0 -0
  138. media/css/images/capability/delete.png +0 -0
  139. media/css/images/capability/filter-active.png +0 -0
  140. media/css/images/capability/filter.png +0 -0
  141. media/css/images/capability/restore-active.png +0 -0
  142. media/css/images/capability/restore.png +0 -0
  143. media/css/images/capability/select-active.png +0 -0
  144. media/css/images/capability/select.png +0 -0
  145. media/css/images/capability/unchecked.png +0 -0
  146. media/css/images/cmanager/add-active.png +0 -0
  147. media/css/images/cmanager/add.png +0 -0
  148. media/css/images/cmanager/block-user-active.png +0 -0
  149. media/css/images/cmanager/block-user.png +0 -0
  150. media/css/images/cmanager/delete-active.png +0 -0
  151. media/css/images/cmanager/delete.png +0 -0
  152. media/css/images/cmanager/edit-active.png +0 -0
  153. media/css/images/cmanager/edit-user-active.png +0 -0
  154. media/css/images/cmanager/edit-user.png +0 -0
  155. media/css/images/cmanager/edit.png +0 -0
  156. media/css/images/cmanager/field-loader.gif +0 -0
  157. media/css/images/cmanager/filter-active.png +0 -0
  158. media/css/images/cmanager/filter.png +0 -0
  159. media/css/images/cmanager/multisite-active.png +0 -0
  160. media/css/images/cmanager/multisite.png +0 -0
  161. media/css/images/cmanager/refresh-active.png +0 -0
  162. media/css/images/cmanager/refresh.png +0 -0
  163. media/css/images/cmanager/role-active.png +0 -0
  164. media/css/images/cmanager/role.png +0 -0
  165. media/css/images/cmanager/select-active.png +0 -0
  166. media/css/images/cmanager/select.png +0 -0
  167. media/css/images/cmanager/settings-active.png +0 -0
  168. media/css/images/cmanager/settings.png +0 -0
  169. media/css/images/cmanager/user-active.png +0 -0
  170. media/css/images/cmanager/user.png +0 -0
  171. media/css/images/cmanager/visitor-active.png +0 -0
  172. media/css/images/cmanager/visitor.png +0 -0
  173. media/css/images/configpress/pdf-active.png +0 -0
  174. media/css/images/configpress/pdf.png +0 -0
  175. media/css/images/cpanel/cpanel-loader.gif +0 -0
  176. media/css/images/cpanel/help-forum-active.png +0 -0
  177. media/css/images/cpanel/help-forum.png +0 -0
  178. media/css/images/cpanel/message-active.png +0 -0
  179. media/css/images/cpanel/message.png +0 -0
  180. media/css/images/cpanel/restore-active.png +0 -0
  181. media/css/images/cpanel/restore.png +0 -0
  182. media/css/images/cpanel/save-active.png +0 -0
  183. media/css/images/cpanel/save.png +0 -0
  184. media/css/images/cpanel/star-active.png +0 -0
  185. media/css/images/cpanel/star.png +0 -0
  186. media/css/images/cpanel/twitter-active.png +0 -0
  187. media/css/images/cpanel/twitter.png +0 -0
  188. media/css/images/event/add-active.png +0 -0
  189. media/css/images/event/add.png +0 -0
  190. media/css/images/event/delete-active.png +0 -0
  191. media/css/images/event/delete.png +0 -0
  192. media/css/images/event/edit-active.png +0 -0
  193. media/css/images/event/edit.png +0 -0
  194. media/css/images/extension/download-active.png +0 -0
  195. media/css/images/extension/download.png +0 -0
  196. media/css/images/extension/forum-active.png +0 -0
  197. media/css/images/extension/forum.png +0 -0
  198. media/css/images/extension/link-active.png +0 -0
  199. media/css/images/extension/link.png +0 -0
  200. media/css/images/extension/message-active.png +0 -0
  201. media/css/images/extension/message.png +0 -0
  202. media/css/images/extension/ok-active.png +0 -0
  203. media/css/images/extension/ok.png +0 -0
  204. media/css/images/extension/plus-active.png +0 -0
  205. media/css/images/extension/plus.png +0 -0
  206. media/css/images/extension/purchase-active.png +0 -0
  207. media/css/images/extension/purchase.png +0 -0
  208. media/css/images/extension/twitter-active.png +0 -0
  209. media/css/images/extension/twitter.png +0 -0
  210. media/css/images/extension/youtube-active.png +0 -0
  211. media/css/images/extension/youtube.png +0 -0
  212. media/css/images/feature-active.png +0 -0
  213. media/css/images/feature.png +0 -0
  214. media/css/images/help.png +0 -0
  215. media/css/images/lock.png +0 -0
  216. css/images/ajax-loader.gif → media/css/images/main-loader.gif +0 -0
  217. media/css/images/menu/checked.png +0 -0
  218. media/css/images/menu/sorting-active.png +0 -0
  219. media/css/images/menu/sorting.png +0 -0
  220. media/css/images/menu/unchecked.png +0 -0
  221. media/css/images/menu/visibility-active.png +0 -0
  222. media/css/images/menu/visibility.png +0 -0
  223. media/css/images/metabox-loader.gif +0 -0
  224. media/css/images/metabox/add-active.png +0 -0
  225. media/css/images/metabox/add.png +0 -0
  226. media/css/images/metabox/checked.png +0 -0
  227. media/css/images/metabox/link-active.png +0 -0
  228. media/css/images/metabox/link.png +0 -0
  229. media/css/images/metabox/refresh-active.png +0 -0
  230. media/css/images/metabox/refresh.png +0 -0
  231. media/css/images/metabox/unchecked.png +0 -0
  232. media/css/images/post/checked.png +0 -0
  233. media/css/images/post/edit-active.png +0 -0
  234. media/css/images/post/edit.png +0 -0
  235. media/css/images/post/filter-active.png +0 -0
  236. media/css/images/post/filter.png +0 -0
  237. media/css/images/post/info-active.png +0 -0
  238. media/css/images/post/info.png +0 -0
  239. media/css/images/post/loader.gif +0 -0
  240. media/css/images/post/lock-big.png +0 -0
  241. media/css/images/post/lock.png +0 -0
  242. media/css/images/post/post.png +0 -0
  243. media/css/images/post/refresh-active.png +0 -0
  244. media/css/images/post/refresh.png +0 -0
  245. media/css/images/post/settings-active.png +0 -0
  246. media/css/images/post/settings.png +0 -0
  247. media/css/images/post/unchecked.png +0 -0
  248. media/css/images/search-active.png +0 -0
  249. media/css/images/search.png +0 -0
  250. media/css/images/sort_asc.png +0 -0
  251. media/css/images/sort_asc_disabled.png +0 -0
  252. media/css/images/sort_both.png +0 -0
  253. media/css/images/sort_desc.png +0 -0
  254. media/css/images/sort_desc_disabled.png +0 -0
  255. media/css/images/table-filtered.png +0 -0
  256. media/css/images/treeview/ajax-loader.gif +0 -0
  257. media/css/images/treeview/file.gif +0 -0
  258. media/css/images/treeview/folder-close.png +0 -0
  259. media/css/images/treeview/folder-closed.gif +0 -0
  260. media/css/images/treeview/folder-open.png +0 -0
  261. media/css/images/treeview/folder.gif +0 -0
  262. media/css/images/treeview/minus.gif +0 -0
  263. media/css/images/treeview/plus.gif +0 -0
  264. media/css/images/treeview/treeview-black-line.gif +0 -0
  265. media/css/images/treeview/treeview-black.gif +0 -0
  266. media/css/images/treeview/treeview-default-line.gif +0 -0
  267. media/css/images/treeview/treeview-default.gif +0 -0
  268. media/css/images/treeview/treeview-famfamfam-line.gif +0 -0
  269. media/css/images/treeview/treeview-famfamfam.gif +0 -0
  270. media/css/images/treeview/treeview-gray-line.gif +0 -0
  271. media/css/images/treeview/treeview-gray.gif +0 -0
  272. media/css/images/treeview/treeview-red-line.gif +0 -0
  273. media/css/images/treeview/treeview-red.gif +0 -0
  274. media/css/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  275. media/css/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  276. media/css/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  277. media/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  278. media/css/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  279. media/css/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  280. media/css/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  281. media/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  282. media/css/images/ui-icons_222222_256x240.png +0 -0
  283. media/css/images/ui-icons_2e83ff_256x240.png +0 -0
  284. media/css/images/ui-icons_454545_256x240.png +0 -0
  285. media/css/images/ui-icons_888888_256x240.png +0 -0
  286. media/css/images/ui-icons_cd0a0a_256x240.png +0 -0
  287. media/css/jquery-ui.css +7 -0
  288. media/css/jquery.dt.css +242 -0
  289. media/css/jquery.treeview.css +117 -0
  290. media/css/migrate.css +67 -0
  291. media/css/migrate/completed.png +0 -0
  292. media/css/migrate/failure.png +0 -0
  293. media/css/migrate/pending.png +0 -0
  294. media/css/migrate/wait.png +0 -0
  295. media/js/aam.js +2773 -0
  296. media/js/codemirror.js +5829 -0
  297. media/js/extension.js +185 -0
  298. media/js/jquery.dt.js +155 -0
  299. media/js/jquery.treeview.js +123 -0
  300. media/js/migrate.js +147 -0
  301. media/js/properties.js +64 -0
  302. module/class-module_filtermenu.php +0 -121
aam.php ADDED
@@ -0,0 +1,1003 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ Plugin Name: Advanced Access Manager
5
+ Description: Manage User and Role Access to WordPress Backend and Frontend.
6
+ Version: 2.0
7
+ Author: Vasyl Martyniuk <support@wpaam.com>
8
+ Author URI: http://www.wpaam.com
9
+
10
+ *
11
+ * ======================================================================
12
+ * LICENSE: This file is subject to the terms and conditions defined in *
13
+ * file 'license.txt', which is part of this source code package. *
14
+ * ======================================================================
15
+ */
16
+
17
+ require(dirname(__FILE__) . '/config.php');
18
+
19
+ /**
20
+ * Main Plugin Class
21
+ *
22
+ * Responsible for initialization and handling user requests to Advanced Access
23
+ * Manager
24
+ *
25
+ * @package AAM
26
+ * @author Vasyl Martyniuk <support@wpaam.com>
27
+ * @copyright Copyright C 2013 Vasyl Martyniuk
28
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
29
+ */
30
+ class aam {
31
+
32
+ /**
33
+ * Single instance of itself
34
+ *
35
+ * @var aam
36
+ *
37
+ * @access private
38
+ */
39
+ private static $_aam = null;
40
+
41
+ /**
42
+ * User Subject
43
+ *
44
+ * @var aam_Control_Subject_User
45
+ *
46
+ * @access private
47
+ */
48
+ private $_user = null;
49
+
50
+ /**
51
+ * Initialize the AAM Object
52
+ *
53
+ * @return void
54
+ *
55
+ * @access protected
56
+ */
57
+ protected function __construct() {
58
+ //use some internal hooks to extend functionality
59
+ add_filter('aam_access_objects', array($this, 'internalHooks'), 1, 2);
60
+
61
+ //initialize the user subject
62
+ $this->initializeUser();
63
+
64
+ if (is_admin()) {
65
+ //check if system requires update
66
+ $this->checkUpdate();
67
+
68
+ //print required JS & CSS
69
+ add_action('admin_print_scripts', array($this, 'printScripts'));
70
+ add_action('admin_print_styles', array($this, 'printStyles'));
71
+
72
+ //manager Admin Menu
73
+ if (aam_Core_API::isNetworkPanel()) {
74
+ add_action('network_admin_menu', array($this, 'adminMenu'), 999);
75
+ } else {
76
+ add_action('admin_menu', array($this, 'adminMenu'), 999);
77
+ }
78
+ //manager AAM Features Content rendering
79
+ add_action('admin_action_features', array($this, 'features'));
80
+ //manager AAM Ajax Requests
81
+ add_action('wp_ajax_aam', array($this, 'ajax'));
82
+ //manager WordPress metaboxes
83
+ //add_action("do_meta_boxes", array($this, 'metaboxes'), 1, 3);
84
+ add_action("in_admin_header", array($this, 'metaboxes'), 999);
85
+ //add_action("add_meta_boxes", array($this, 'filterMetaboxes'), 999, 2);
86
+ //add_filter(
87
+ // 'get_user_option_meta-box-order_dashboard',
88
+ // array($this, 'dashboardFilter'), 999, 3
89
+ //);
90
+ //manager user search and authentication control
91
+ add_filter('user_search_columns', array($this, 'searchColumns'));
92
+ //terms & post restriction handlers
93
+ add_filter('get_terms', array($this, 'getBackendTerms'), 10, 3);
94
+ //post restrictions
95
+ add_action('post_updated', array($this, 'postUpdate'), 10, 3);
96
+ add_filter('page_row_actions', array($this, 'postRowActions'), 10, 2);
97
+ add_filter('post_row_actions', array($this, 'postRowActions'), 10, 2);
98
+ add_filter('tag_row_actions', array($this, 'tagRowActions'), 10, 2);
99
+ add_action('admin_action_edit', array($this, 'adminActionEdit'), 10);
100
+ //wp die hook
101
+ add_filter('wp_die_handler', array($this, 'wpDie'), 10);
102
+ } else {
103
+ //control WordPress frontend
104
+ add_action('wp', array($this, 'wp'), 999);
105
+ //filter navigation pages & taxonomies
106
+ add_filter('get_pages', array($this, 'getPages'));
107
+ add_filter('wp_get_nav_menu_items', array($this, 'getNavigationMenu'));
108
+ //widget filters
109
+ add_filter('sidebars_widgets', array($this, 'widgetFilter'), 999);
110
+ //get control over commenting stuff
111
+ add_filter('comments_open', array($this, 'commentOpen'), 10, 2);
112
+ //user login control
113
+ add_filter('wp_authenticate_user', array($this, 'authenticate'), 1, 2);
114
+ //terms & post restriction handlers
115
+ add_filter('get_terms', array($this, 'getFrontendTerms'), 10, 3);
116
+ }
117
+
118
+ //load extensions only when admin
119
+ $this->loadExtensions();
120
+ }
121
+
122
+ /**
123
+ * Check if system requires update
124
+ *
125
+ * @return void
126
+ *
127
+ * @access public
128
+ */
129
+ public function checkUpdate() {
130
+ if (class_exists('aam_Core_Update') && (AAM_APPL_ENV != 'development')) {
131
+ $update = new aam_Core_Update($this);
132
+ $update->run();
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Control Frontend commenting freature
138
+ *
139
+ * @param boolean $open
140
+ * @param int $post_id
141
+ *
142
+ * @return boolean
143
+ *
144
+ * @access public
145
+ */
146
+ public function commentOpen($open, $post_id) {
147
+ $control = $this->getUser()->getObject(
148
+ aam_Control_Object_Post::UID, $post_id
149
+ );
150
+ if ($control->has('frontend', aam_Control_Object_Post::ACTION_COMMENT)) {
151
+ $open = false;
152
+ }
153
+
154
+ return $open;
155
+ }
156
+
157
+ /**
158
+ * Get Post ID
159
+ *
160
+ * Replication of the same mechanism that is in wp-admin/post.php
161
+ *
162
+ * @return WP_Post|null
163
+ *
164
+ * @access public
165
+ */
166
+ public function getPost() {
167
+ if (get_post()) {
168
+ $post = get_post();
169
+ } elseif ($post_id = aam_Core_Request::get('post')) {
170
+ $post = get_post($post_id);
171
+ } elseif ($post_id = aam_Core_Request::get('post_ID')) {
172
+ $post = get_post($post_id);
173
+ } else {
174
+ $post = null;
175
+ }
176
+
177
+ return $post;
178
+ }
179
+
180
+ /**
181
+ * Filter backend term list
182
+ *
183
+ * @param array $terms
184
+ * @param array $taxonomies
185
+ * @param array $args
186
+ *
187
+ * @return array
188
+ *
189
+ * @access public
190
+ */
191
+ public function getBackendTerms($terms, $taxonomies, $args) {
192
+ return $this->getTerms('backend', $terms);
193
+ }
194
+
195
+ /**
196
+ * Filter frontend term list
197
+ *
198
+ * @param array $terms
199
+ * @param array $taxonomies
200
+ * @param array $args
201
+ *
202
+ * @return array
203
+ *
204
+ * @access public
205
+ */
206
+ public function getFrontendTerms($terms, $taxonomies, $args) {
207
+ return $this->getTerms('frontend', $terms);
208
+ }
209
+
210
+ /**
211
+ * Filter terms based on area
212
+ *
213
+ * @param string $area
214
+ * @param array $terms
215
+ *
216
+ * @return array
217
+ *
218
+ * @access public
219
+ */
220
+ public function getTerms($area, $terms) {
221
+ if (is_array($terms)) {
222
+ $object = $this->getUser()->getObject(aam_Control_Object_Term::UID);
223
+ foreach ($terms as $i => $term) {
224
+ if (is_object($term)) {
225
+ $object->init($term->term_id);
226
+ if ($object->has($area, aam_Control_Object_Term::ACTION_LIST)) {
227
+ unset($terms[$i]);
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+ return $terms;
234
+ }
235
+
236
+ /**
237
+ * Filter Pages that should be excluded in frontend
238
+ *
239
+ * @param array $pages
240
+ *
241
+ * @return array
242
+ *
243
+ * @access public
244
+ * @todo Cache this process
245
+ */
246
+ public function getPages($pages){
247
+ $object = $this->getUser()->getObject(aam_Control_Object_Post::UID);
248
+ if (is_array($pages)){
249
+ foreach($pages as $i => $page){
250
+ $object->init($page);
251
+ if ($object->has('frontend', aam_Control_Object_Post::ACTION_EXCLUDE)){
252
+ unset($pages[$i]);
253
+ }
254
+ }
255
+ }
256
+
257
+ return $pages;
258
+ }
259
+
260
+ /**
261
+ * Filter Navigation menu
262
+ *
263
+ * @param array $pages
264
+ *
265
+ * @return array
266
+ *
267
+ * @access public
268
+ */
269
+ public function getNavigationMenu($pages){
270
+ if (is_array($pages)){
271
+ $post = $this->getUser()->getObject(aam_Control_Object_Post::UID);
272
+ $term = $this->getUser()->getObject(aam_Control_Object_Term::UID);
273
+ foreach($pages as $i => $page){
274
+ if ($page->type === 'taxonomy'){
275
+ $object = $term;
276
+ $exclude = aam_Control_Object_Term::ACTION_EXCLUDE;
277
+ } else {
278
+ $object = $post;
279
+ $exclude = aam_Control_Object_Post::ACTION_EXCLUDE;
280
+ }
281
+ $object->init($page->object_id);
282
+
283
+ if ($object->has('frontend', $exclude)){
284
+ unset($pages[$i]);
285
+ }
286
+ }
287
+ }
288
+
289
+ return $pages;
290
+ }
291
+
292
+ /**
293
+ * Filter Frontend widgets
294
+ *
295
+ * @param array $widgets
296
+ *
297
+ * @return array
298
+ *
299
+ * @access public
300
+ */
301
+ public function widgetFilter($widgets) {
302
+ return $this->getUser()->getObject(
303
+ aam_Control_Object_Metabox::UID)->filterFrontend($widgets);
304
+ }
305
+
306
+ /**
307
+ * Control Edit Post/Term
308
+ *
309
+ * Make sure that current user does not have access to edit Post or Term
310
+ *
311
+ * @return void
312
+ *
313
+ * @access public
314
+ */
315
+ public function adminActionEdit() {
316
+ $user = $this->getUser();
317
+ if (aam_Core_Request::request('taxonomy')) {
318
+ $control = $user->getObject(
319
+ aam_Control_Object_Term::UID, aam_Core_Request::request('tag_ID')
320
+ );
321
+ if ($control->has('backend', aam_Control_Object_Post::ACTION_EDIT)) {
322
+ $this->reject();
323
+ }
324
+ } elseif ($post = $this->getPost()) {
325
+ $control = $user->getObject(aam_Control_Object_Post::UID, $post->ID);
326
+ if ($control->has('backend', aam_Control_Object_Post::ACTION_EDIT)) {
327
+ $this->reject();
328
+ }
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Reject the request
334
+ *
335
+ * Redirect or die the execution based on ConfigPress settings
336
+ *
337
+ * @return void
338
+ *
339
+ * @access public
340
+ */
341
+ public function reject() {
342
+ $cpress = $this->getUser()->getObject(aam_Control_Object_ConfigPress::UID);
343
+ if (is_admin()) {
344
+ $redirect = $cpress->getParam('backend.access.deny.redirect');
345
+ $message = $cpress->getParam(
346
+ 'backend.access.deny.message', __('Access denied', 'aam')
347
+ );
348
+ } else {
349
+ $redirect = $cpress->getParam('frontend.access.deny.redirect');
350
+ $message = $cpress->getParam(
351
+ 'frontend.access.deny.message', __('Access denied', 'aam')
352
+ );
353
+ }
354
+
355
+ if (filter_var($redirect, FILTER_VALIDATE_URL)) {
356
+ wp_redirect($redirect);
357
+ exit;
358
+ } elseif (is_int($redirect)) {
359
+ wp_redirect(get_post_permalink($redirect));
360
+ exit;
361
+ } else {
362
+ wp_die($message);
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Take control over wp_die function
368
+ *
369
+ * @param callback $function
370
+ *
371
+ * @return void
372
+ *
373
+ * @access public
374
+ */
375
+ public function wpDie($function) {
376
+ $cpress = $this->getUser()->getObject(aam_Control_Object_ConfigPress::UID);
377
+ $redirect = $cpress->getParam('backend.access.deny.redirect');
378
+ $message = $cpress->getParam(
379
+ 'backend.access.deny.message', __('Access denied', 'aam')
380
+ );
381
+
382
+ if (filter_var($redirect, FILTER_VALIDATE_URL)) {
383
+ wp_redirect($redirect);
384
+ exit;
385
+ } elseif (is_int($redirect)) {
386
+ wp_redirect(get_post_permalink($redirect));
387
+ exit;
388
+ } else {
389
+ call_user_func($function, $message, '', array());
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Term Quick Menu Actions Filtering
395
+ *
396
+ * @param array $actions
397
+ * @param object $term
398
+ *
399
+ * @return array
400
+ *
401
+ * @access public
402
+ */
403
+ public function tagRowActions($actions, $term) {
404
+ $control = $this->getUser()->getObject(
405
+ aam_Control_Object_Term::UID, $term->term_id
406
+ );
407
+ //filter edit menu
408
+ if ($control->has('backend', aam_Control_Object_Post::ACTION_EDIT)) {
409
+ if (isset($actions['edit'])) {
410
+ unset($actions['edit']);
411
+ }
412
+ if (isset($actions['inline hide-if-no-js'])) {
413
+ unset($actions['inline hide-if-no-js']);
414
+ }
415
+ }
416
+
417
+ //filter delete menu
418
+ if ($control->has('backend', aam_Control_Object_Post::ACTION_DELETE)) {
419
+ if (isset($actions['delete'])) {
420
+ unset($actions['delete']);
421
+ }
422
+ }
423
+
424
+ return $actions;
425
+ }
426
+
427
+ /**
428
+ * Post Quick Menu Actions Filtering
429
+ *
430
+ * @param array $actions
431
+ * @param WP_Post $post
432
+ *
433
+ * @return array
434
+ *
435
+ * @access public
436
+ */
437
+ public function postRowActions($actions, $post) {
438
+ $control = $this->getUser()->getObject(
439
+ aam_Control_Object_Post::UID, $post->ID
440
+ );
441
+ //filter edit menu
442
+ if ($control->has('backend', aam_Control_Object_Post::ACTION_EDIT)) {
443
+ if (isset($actions['edit'])) {
444
+ unset($actions['edit']);
445
+ }
446
+ if (isset($actions['inline hide-if-no-js'])) {
447
+ unset($actions['inline hide-if-no-js']);
448
+ }
449
+ }
450
+ //filter trash menu
451
+ if ($control->has('backend', aam_Control_Object_Post::ACTION_TRASH)) {
452
+ if (isset($actions['trash'])) {
453
+ unset($actions['trash']);
454
+ }
455
+ }
456
+
457
+ //filter delete menu
458
+ if ($control->has('backend', aam_Control_Object_Post::ACTION_DELETE)) {
459
+ if (isset($actions['delete'])) {
460
+ unset($actions['delete']);
461
+ }
462
+ }
463
+
464
+ return $actions;
465
+ }
466
+
467
+ /**
468
+ * Main Frontend access control hook
469
+ *
470
+ * @return void
471
+ *
472
+ * @access public
473
+ * @global WP_Query $wp_query
474
+ * @global WP_Post $post
475
+ */
476
+ public function wp() {
477
+ global $wp_query, $post;
478
+
479
+ $user = $this->getUser();
480
+ if (is_category()) {
481
+ $category = $wp_query->get_queried_object();
482
+ if ($user->getObject(aam_Control_Object_Term::UID, $category->term_id
483
+ )->has('frontend', aam_Control_Object_Term::ACTION_BROWSE)) {
484
+ $this->reject();
485
+ }
486
+ } elseif (!$wp_query->is_home() && ($post instanceof WP_Post)) {
487
+ if ($user->getObject(aam_Control_Object_Post::UID, $post->ID
488
+ )->has('frontend', aam_Control_Object_Post::ACTION_READ)) {
489
+ $this->reject();
490
+ }
491
+ }
492
+ }
493
+
494
+ /**
495
+ * Register Internal miscellenious functionality
496
+ *
497
+ * @param array $objects
498
+ * @param aam_Control_Subject $subject
499
+ *
500
+ * @return array
501
+ *
502
+ * @access public
503
+ */
504
+ public function internalHooks($objects, $subject) {
505
+ $objects[aam_Control_Object_Event::UID] = new aam_Control_Object_Event(
506
+ $subject
507
+ );
508
+
509
+ $configPress = new aam_Control_Object_ConfigPress($subject, 1);
510
+ $objects[aam_Control_Object_ConfigPress::UID] = $configPress;
511
+
512
+ return $objects;
513
+ }
514
+
515
+ /**
516
+ * Event Handler
517
+ *
518
+ * @param int $post_ID
519
+ * @param WP_Post $post_after
520
+ * @param WP_Post $post_before
521
+ *
522
+ * @return void
523
+ *
524
+ * @access public
525
+ */
526
+ public function postUpdate($post_ID, $post_after, $post_before = null) {
527
+ $events = $this->getUser()->getObject(
528
+ aam_Control_Object_Event::UID)->getOption();
529
+
530
+ foreach ($events as $event) {
531
+ if ($post_after->post_type == $event['post_type']) {
532
+ if ($event['event'] == 'status_change') {
533
+ if ($event['event_specifier'] == $post_after->post_status) {
534
+ $this->triggerAction(
535
+ $event, $post_ID, $post_after, $post_before
536
+ );
537
+ }
538
+ } elseif ($post_before && $event['event'] == 'content_change') {
539
+ if ($post_before->post_content != $post_after->post_content) {
540
+ $this->triggerAction(
541
+ $event, $post_ID, $post_after, $post_before
542
+ );
543
+ }
544
+ }
545
+ }
546
+ }
547
+ }
548
+
549
+ /**
550
+ * Trigger Action based on settings
551
+ *
552
+ * @param array $event
553
+ * @param int $post_ID
554
+ * @param WP_Post $post_after
555
+ * @param WP_Post $post_before
556
+ *
557
+ * @global wpdb $wpdb
558
+ * @global array $wp_post_types
559
+ *
560
+ * @return void
561
+ *
562
+ * @access public
563
+ */
564
+ public function triggerAction($event, $post_ID, $post_after, $post_before) {
565
+ global $wpdb, $wp_post_types;
566
+
567
+ if ($event['action'] == 'notify') {
568
+ $subject = $wp_post_types[$event['post_type']]->labels->name . ' ';
569
+ $subject .= $post_ID . ' has been changed by ' . get_current_user();
570
+ $subject = apply_filters('aam_notification_subject', $subject);
571
+
572
+ $message = apply_filters(
573
+ 'aam_notification_message', get_edit_post_link($post_ID)
574
+ );
575
+
576
+ wp_mail($event['action_specifier'], $subject, $message);
577
+ } else if ($event['action'] == 'change_status') {
578
+ $wpdb->update(
579
+ $wpdb->posts,
580
+ array('post_status' => $event['action_specifier']),
581
+ array('ID' => $post_ID)
582
+ );
583
+ } else if ($event['action'] == 'custom') {
584
+ if (is_callable($event['callback'])) {
585
+ call_user_func(
586
+ $event['callback'], $post_ID, $post_after, $post_before
587
+ );
588
+ }
589
+ }
590
+ }
591
+
592
+ /**
593
+ * Add extra column to search in for User search
594
+ *
595
+ * @param array $columns
596
+ *
597
+ * @return array
598
+ *
599
+ * @access public
600
+ */
601
+ public function searchColumns($columns) {
602
+ $columns[] = 'display_name';
603
+
604
+ return $columns;
605
+ }
606
+
607
+ /**
608
+ * Control User Block flag
609
+ *
610
+ * @param WP_Error $user
611
+ *
612
+ * @return WP_Error|WP_User
613
+ *
614
+ * @access public
615
+ */
616
+ public function authenticate($user) {
617
+ if ($user->user_status == 1) {
618
+ $user = new WP_Error();
619
+ $user->add(
620
+ 'authentication_failed', '<strong>ERROR</strong>: User is blocked'
621
+ );
622
+ }
623
+
624
+ return $user;
625
+ }
626
+
627
+ /**
628
+ * Make sure that AAM UI Page is used
629
+ *
630
+ * @return boolean
631
+ *
632
+ * @access public
633
+ */
634
+ public function isAAMScreen() {
635
+ return (aam_Core_Request::get('page') == 'aam' ? true : false);
636
+ }
637
+
638
+ /**
639
+ * Make sure that AAM Extension UI Page is used
640
+ *
641
+ * @return boolean
642
+ *
643
+ * @access public
644
+ */
645
+ public function isAAMExtensionScreen() {
646
+ return (aam_Core_Request::get('page') == 'aam-ext' ? true : false);
647
+ }
648
+
649
+ /**
650
+ * Print necessary styles
651
+ *
652
+ * @return void
653
+ *
654
+ * @access public
655
+ */
656
+ public function printStyles() {
657
+ if ($this->isAAMScreen()) {
658
+ wp_enqueue_style('dashboard');
659
+ wp_enqueue_style('global');
660
+ wp_enqueue_style('wp-admin');
661
+ wp_enqueue_style('aam-ui-style', AAM_MEDIA_URL . 'css/jquery-ui.css');
662
+ wp_enqueue_style('aam-style', AAM_MEDIA_URL . 'css/aam.css');
663
+ wp_enqueue_style('aam-datatables', AAM_MEDIA_URL . 'css/jquery.dt.css');
664
+ wp_enqueue_style('aam-codemirror', AAM_MEDIA_URL . 'css/codemirror.css');
665
+ wp_enqueue_style(
666
+ 'aam-treeview', AAM_MEDIA_URL . 'css/jquery.treeview.css'
667
+ );
668
+ } elseif ($this->isAAMExtensionScreen()) {
669
+ wp_enqueue_style('dashboard');
670
+ wp_enqueue_style('global');
671
+ wp_enqueue_style('wp-admin');
672
+ wp_enqueue_style('aam-ui-style', AAM_MEDIA_URL . 'css/jquery-ui.css');
673
+ wp_enqueue_style('aam-style', AAM_MEDIA_URL . 'css/extension.css');
674
+ wp_enqueue_style('aam-datatables', AAM_MEDIA_URL . 'css/jquery.dt.css');
675
+ }
676
+
677
+ //migration functionality. TODO - remove in July 15 2014
678
+ if (class_exists('aam_Core_Migrate')){
679
+ wp_enqueue_style('aam-migrate', AAM_MEDIA_URL . 'css/migrate.css');
680
+ }
681
+ }
682
+
683
+ /**
684
+ * Print necessary scripts
685
+ *
686
+ * @return void
687
+ *
688
+ * @access public
689
+ */
690
+ public function printScripts() {
691
+ if ($this->isAAMScreen()) {
692
+ wp_enqueue_script('postbox');
693
+ wp_enqueue_script('dashboard');
694
+ wp_enqueue_script('aam-admin', AAM_MEDIA_URL . 'js/aam.js');
695
+ wp_enqueue_script('aam-datatables', AAM_MEDIA_URL . 'js/jquery.dt.js');
696
+ wp_enqueue_script('aam-codemirror', AAM_MEDIA_URL . 'js/codemirror.js');
697
+ wp_enqueue_script('aam-cmini', AAM_MEDIA_URL . 'js/properties.js');
698
+ wp_enqueue_script(
699
+ 'aam-treeview', AAM_MEDIA_URL . 'js/jquery.treeview.js'
700
+ );
701
+ wp_enqueue_script('jquery-ui-core');
702
+ wp_enqueue_script('jquery-effects-core');
703
+ wp_enqueue_script('jquery-ui-widget');
704
+ wp_enqueue_script('jquery-ui-tabs');
705
+ wp_enqueue_script('jquery-ui-accordion');
706
+ wp_enqueue_script('jquery-ui-progressbar');
707
+ wp_enqueue_script('jquery-ui-dialog');
708
+ wp_enqueue_script('jquery-ui-button');
709
+ wp_enqueue_script('jquery-ui-sortable');
710
+ wp_enqueue_script('jquery-ui-menu');
711
+ wp_enqueue_script('jquery-effects-highlight');
712
+
713
+ $localization = array(
714
+ 'nonce' => wp_create_nonce('aam_ajax'),
715
+ 'siteURI' => admin_url('index.php'),
716
+ 'ajaxurl' => admin_url('admin-ajax.php'),
717
+ 'addUserURI' => admin_url('user-new.php'),
718
+ 'editUserURI' => admin_url('user-edit.php'),
719
+ 'defaultSegment' => array(
720
+ 'role' => 'administrator',
721
+ 'blog' => get_current_blog_id(),
722
+ 'user' => 0
723
+ ),
724
+ 'labels' => aam_View_Manager::uiLabels()
725
+ );
726
+ wp_localize_script('aam-admin', 'aamLocal', $localization);
727
+ } elseif ($this->isAAMExtensionScreen()) {
728
+ wp_enqueue_script('postbox');
729
+ wp_enqueue_script('dashboard');
730
+ wp_enqueue_script('jquery-ui-core');
731
+ wp_enqueue_script('jquery-effects-core');
732
+ wp_enqueue_script('jquery-ui-widget');
733
+ wp_enqueue_script('jquery-ui-dialog');
734
+ wp_enqueue_script('jquery-ui-button');
735
+ wp_enqueue_script('jquery-effects-highlight');
736
+ wp_enqueue_script('aam-admin', AAM_MEDIA_URL . 'js/extension.js');
737
+ wp_enqueue_script('aam-datatables', AAM_MEDIA_URL . 'js/jquery.dt.js');
738
+
739
+ $localization = array(
740
+ 'nonce' => wp_create_nonce('aam_ajax'),
741
+ 'ajaxurl' => admin_url('admin-ajax.php'),
742
+ 'labels' => aam_View_Manager::uiLabels()
743
+ );
744
+ wp_localize_script('aam-admin', 'aamLocal', $localization);
745
+ }
746
+
747
+ //migration functionality. TODO - remove in July 15 2014
748
+ if (class_exists('aam_Core_Migrate')){
749
+ wp_enqueue_script('aam-migrate', AAM_MEDIA_URL . 'js/migrate.js');
750
+ $localization = array(
751
+ 'nonce' => wp_create_nonce('aam_ajax'),
752
+ 'ajaxurl' => admin_url('admin-ajax.php'),
753
+ );
754
+ wp_localize_script('aam-migrate', 'aamMigrateLocal', $localization);
755
+ }
756
+ }
757
+
758
+ /**
759
+ * Render list of AAM Features
760
+ *
761
+ * Must be separate from Ajax call because WordPress ajax does not load a lot of
762
+ * UI stuff
763
+ *
764
+ * @return void
765
+ *
766
+ * @access public
767
+ */
768
+ public function features() {
769
+ check_ajax_referer('aam_ajax');
770
+
771
+ $model = new aam_View_Manager;
772
+ $model->retrieveFeatures();
773
+ die();
774
+ }
775
+
776
+ /**
777
+ * Handle Ajax calls to AAM
778
+ *
779
+ * @return void
780
+ *
781
+ * @access public
782
+ */
783
+ public function ajax() {
784
+ check_ajax_referer('aam_ajax');
785
+
786
+ //clean buffer to make sure that nothing messing around with system
787
+ while (@ob_end_clean());
788
+
789
+ //process ajax request
790
+ $model = new aam_View_Ajax;
791
+ echo $model->run();
792
+ die();
793
+ }
794
+
795
+ /**
796
+ * Hanlde Metabox initialization process
797
+ *
798
+ * @return void
799
+ *
800
+ * @access public
801
+ */
802
+ public function metaboxes() {
803
+ global $post;
804
+
805
+ $post_type = ($post instanceof WP_Post ? $post->post_type : '');
806
+
807
+ if (aam_Core_Request::get('aam_meta_init')) {
808
+ $model = new aam_View_Metabox;
809
+ $model->run($post_type);
810
+ } else {
811
+ $this->getUser()->getObject(aam_Control_Object_Metabox::UID)
812
+ ->filterBackend($post_type, 'dashboard');
813
+ }
814
+ }
815
+
816
+ /**
817
+ * Filter Dashboard Widgets & Metaboxes
818
+ *
819
+ * @param array $result
820
+ * @param mixed $option
821
+ * @param mixed $user
822
+ *
823
+ * @return void
824
+ *
825
+ * @access public
826
+ * @deprecated since 2.0 Beta 3
827
+ */
828
+ public function dashboardFilter($result, $option, $user) {
829
+ $this->getUser()->getObject(
830
+ aam_Control_Object_Metabox::UID)->filterBackend('dashboard');
831
+ }
832
+
833
+ /**
834
+ * Filter Screen Metaboxes
835
+ *
836
+ * @param string $post_type
837
+ * @param WP_Post $post
838
+ *
839
+ * @return void
840
+ *
841
+ * @access public
842
+ * @deprecated since 2.0 Beta 3
843
+ */
844
+ public function filterMetaboxes($post_type, $post) {
845
+ $this->getUser()->getObject(aam_Control_Object_Metabox::UID)->filterBackend(
846
+ $post_type, $post
847
+ );
848
+ }
849
+
850
+ /**
851
+ * Register Admin Menu
852
+ *
853
+ * @return void
854
+ *
855
+ * @access public
856
+ */
857
+ public function adminMenu() {
858
+ //register the menu
859
+ add_menu_page(
860
+ __('AAM', 'aam'),
861
+ __('AAM', 'aam'),
862
+ 'administrator',
863
+ 'aam',
864
+ array($this, 'content'),
865
+ AAM_BASE_URL . 'active-menu.png'
866
+ );
867
+ //register submenus
868
+ add_submenu_page(
869
+ 'aam',
870
+ __('Access Control', 'aam'),
871
+ __('Access Control', 'aam'),
872
+ 'administrator',
873
+ 'aam',
874
+ array($this, 'content')
875
+ );
876
+ add_submenu_page(
877
+ 'aam',
878
+ __('Extensions', 'aam'),
879
+ __('Extensions', 'aam'),
880
+ 'administrator',
881
+ 'aam-ext',
882
+ array($this, 'extensionContent')
883
+ );
884
+
885
+ //filter admin menu
886
+ $this->getUser()->getObject(aam_Control_Object_Menu::UID)->filter();
887
+ }
888
+
889
+ /**
890
+ * Render Main Content page
891
+ *
892
+ * @return void
893
+ *
894
+ * @access public
895
+ */
896
+ public function content() {
897
+ $manager = new aam_View_Manager();
898
+ echo $manager->run();
899
+ }
900
+
901
+ /**
902
+ * Extension content page
903
+ *
904
+ * @return void
905
+ *
906
+ * @access public
907
+ */
908
+ public function extensionContent() {
909
+ $manager = new aam_View_Extension();
910
+ echo $manager->run();
911
+ }
912
+
913
+ /**
914
+ * Initialize the AAM plugin
915
+ *
916
+ * @return void
917
+ *
918
+ * @access public
919
+ * @static
920
+ */
921
+ public static function initialize() {
922
+ if (is_null(self::$_aam)) {
923
+ self::$_aam = new self;
924
+ }
925
+ }
926
+
927
+ /**
928
+ * Initialize the current user
929
+ *
930
+ * Whether it is logged in user or visitor
931
+ *
932
+ * @return void
933
+ *
934
+ * @access public
935
+ */
936
+ public function initializeUser() {
937
+ if ($user_id = get_current_user_id()) {
938
+ $this->setUser(new aam_Control_Subject_User($user_id));
939
+ } else {
940
+ $this->setUser(new aam_Control_Subject_Visitor(''));
941
+ }
942
+ }
943
+
944
+ /**
945
+ * Uninstall hook
946
+ *
947
+ * Remove all leftovers from AAM execution
948
+ *
949
+ * @return void
950
+ *
951
+ * @access public
952
+ */
953
+ public static function uninstall() {
954
+ global $wp_filesystem;
955
+
956
+ //remove the content directory
957
+ if (!defined(AAM_CONTENT_DIR_FAILURE) && WP_Filesystem()) {
958
+ $wp_filesystem->rmdir(AAM_TEMP_DIR, true);
959
+ }
960
+ }
961
+
962
+ /**
963
+ * Get Current User Subject
964
+ *
965
+ * @return aam_Control_Subject_User
966
+ *
967
+ * @access public
968
+ */
969
+ public function getUser() {
970
+ return $this->_user;
971
+ }
972
+
973
+ /**
974
+ * Set Current User Subject
975
+ *
976
+ * @param aam_Control_Subject $user
977
+ *
978
+ * @return void
979
+ *
980
+ * @access public
981
+ */
982
+ public function setUser(aam_Control_Subject $user) {
983
+ $this->_user = $user;
984
+ }
985
+
986
+ /**
987
+ * Load Installed extensions
988
+ *
989
+ * @return void
990
+ *
991
+ * @access protected
992
+ */
993
+ protected function loadExtensions() {
994
+ $model = new aam_Core_Extension($this);
995
+ $model->load();
996
+ }
997
+
998
+ }
999
+
1000
+ add_action('init', 'aam::initialize');
1001
+
1002
+ //register_activation_hook(__FILE__, array('aam', 'activate'));
1003
+ register_uninstall_hook(__FILE__, array('aam', 'uninstall'));
active-menu.png ADDED
Binary file
application/control/object.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ * Abstract Object Class
11
+ *
12
+ * Object is any part of the WordPress that is controlled by AAM. The example of
13
+ * object is Post, Page, Metabox, Widget etc.
14
+ *
15
+ * @package AAM
16
+ * @author Vasyl Martyniuk <support@wpaam.com>
17
+ * @copyright Copyright C 2013 Vasyl Martyniuk
18
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
19
+ */
20
+ abstract class aam_Control_Object {
21
+
22
+ /**
23
+ * Subject
24
+ *
25
+ * @var aam_Control_Subject
26
+ *
27
+ * @access private
28
+ */
29
+ private $_subject = null;
30
+
31
+ /**
32
+ * Constructor
33
+ *
34
+ * @param aam_Control_Subject $subject
35
+ * @param int $object_id
36
+ *
37
+ * @return void
38
+ *
39
+ * @access public
40
+ */
41
+ public function __construct(aam_Control_Subject $subject, $object_id) {
42
+ $this->setSubject($subject);
43
+ $this->init($object_id);
44
+ }
45
+
46
+ /**
47
+ * Initialize object
48
+ *
49
+ * @param string|int $object_id
50
+ *
51
+ * @return void
52
+ *
53
+ * @access public
54
+ */
55
+ public function init($object_id) {
56
+ //if (empty($this->_option)) {
57
+ $this->setOption(
58
+ $this->getSubject()->readOption($this->getUID(), $object_id)
59
+ );
60
+ //}
61
+ }
62
+
63
+ /**
64
+ * Set current subject
65
+ *
66
+ * Either it is User or Role
67
+ *
68
+ * @param aam_Control_Subject $subject
69
+ *
70
+ * @return void
71
+ *
72
+ * @access public
73
+ */
74
+ public function setSubject(aam_Control_Subject $subject) {
75
+ $this->_subject = $subject;
76
+ }
77
+
78
+ /**
79
+ * Get Subject
80
+ *
81
+ * @return aam_Control_Subject
82
+ *
83
+ * @access public
84
+ */
85
+ public function getSubject() {
86
+ return $this->_subject;
87
+ }
88
+
89
+ /**
90
+ * Get current object UID
91
+ *
92
+ * @return string
93
+ *
94
+ * @access public
95
+ */
96
+ abstract public function getUID();
97
+
98
+ /**
99
+ *
100
+ */
101
+ abstract public function setOption($option);
102
+
103
+ /**
104
+ *
105
+ */
106
+ abstract public function getOption();
107
+
108
+ /**
109
+ *
110
+ */
111
+ abstract public function save($params = array());
112
+
113
+ }
application/control/object/backup.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_Control_Object_Backup extends aam_Control_Object {
17
+
18
+ /**
19
+ *
20
+ */
21
+ const UID = 'backup';
22
+
23
+ /**
24
+ *
25
+ */
26
+ const ROLEBACK_TIMES = 3;
27
+
28
+ /**
29
+ *
30
+ * @var type
31
+ */
32
+ private $_option = null;
33
+
34
+ /**
35
+ *
36
+ * @var type
37
+ */
38
+ private $_roleback = false;
39
+
40
+ /**
41
+ *
42
+ * @param type $backup
43
+ */
44
+ public function save($backup = null) {
45
+ //define the index
46
+ if ($this->_roleback === false) {
47
+ if (count($this->_option) < self::ROLEBACK_TIMES) {
48
+ $index = count($this->_option); //next index in array
49
+ } else { //shift the array and use the last cell
50
+ $original = array_shift($this->_option);
51
+ $this->_option[0] = $original;
52
+ $index = (self::ROLEBACK_TIMES - 1);
53
+ }
54
+
55
+ //save the backup
56
+ $this->_option[$index] = $backup;
57
+ }
58
+
59
+ $this->getSubject()->updateOption($this->_option, self::UID);
60
+ }
61
+
62
+ /**
63
+ *
64
+ * @return type
65
+ */
66
+ public function getUID() {
67
+ return self::UID;
68
+ }
69
+
70
+ /**
71
+ *
72
+ * @param type $option
73
+ */
74
+ public function setOption($option) {
75
+ $this->_option = (is_array($option) ? $option : array());
76
+ }
77
+
78
+ /**
79
+ *
80
+ * @return type
81
+ */
82
+ public function getOption() {
83
+ return $this->_option;
84
+ }
85
+
86
+ /**
87
+ *
88
+ * @return array
89
+ */
90
+ public function roleback() {
91
+ $counter = count($this->_option);
92
+ if ($counter) {
93
+ $this->_roleback = true;
94
+ $option = $this->_option[$counter - 1];
95
+ unset($this->_option[$counter - 1]);
96
+ } else {
97
+ $option = array();
98
+ }
99
+
100
+ return $option;
101
+ }
102
+
103
+ /**
104
+ *
105
+ * @return type
106
+ */
107
+ public function has() {
108
+ return (count($this->_option) ? true : false);
109
+ }
110
+
111
+ }
application/control/object/capability.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_Control_Object_Capability extends aam_Control_Object {
17
+
18
+ /**
19
+ *
20
+ */
21
+ const UID = 'capability';
22
+
23
+ /**
24
+ *
25
+ * @var type
26
+ */
27
+ private $_option = array();
28
+
29
+ /**
30
+ *
31
+ * @param type $capabilities
32
+ */
33
+ public function save($capabilities = null) {
34
+ if (is_array($capabilities)) {
35
+ foreach ($capabilities as $capability => $grant) {
36
+ if (intval($grant)) {
37
+ $this->getSubject()->addCapability($capability);
38
+ } else {
39
+ $this->getSubject()->removeCapability($capability);
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ /**
46
+ *
47
+ * @param type $object_id
48
+ */
49
+ public function init($object_id) {
50
+ if (empty($this->_option)) {
51
+ $this->setOption($this->getSubject()->getCapabilities());
52
+ }
53
+ }
54
+
55
+ /**
56
+ *
57
+ * @return type
58
+ */
59
+ public function backup() {
60
+ return $this->getSubject()->getCapabilities();
61
+ }
62
+
63
+ /**
64
+ *
65
+ * @return type
66
+ */
67
+ public function getUID() {
68
+ return self::UID;
69
+ }
70
+
71
+ /**
72
+ *
73
+ * @param type $option
74
+ */
75
+ public function setOption($option) {
76
+ $this->_option = (is_array($option) ? $option : array());
77
+ }
78
+
79
+ /**
80
+ *
81
+ * @return type
82
+ */
83
+ public function getOption() {
84
+ return $this->_option;
85
+ }
86
+
87
+ /**
88
+ *
89
+ * @param type $capability
90
+ * @return type
91
+ */
92
+ public function has($capability) {
93
+ return $this->getSubject()->hasCapability($capability);
94
+ }
95
+
96
+ }
application/control/object/configpress.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_Control_Object_ConfigPress extends aam_Control_Object {
17
+
18
+ /**
19
+ *
20
+ */
21
+ const UID = 'configpress';
22
+
23
+ /**
24
+ *
25
+ * @var type
26
+ */
27
+ private $_option = '';
28
+
29
+ /**
30
+ *
31
+ * @var type
32
+ */
33
+ private $_config = '';
34
+
35
+ /**
36
+ *
37
+ * @var type
38
+ */
39
+ private $_tree = null;
40
+
41
+ /**
42
+ *
43
+ * @param type $config_press
44
+ * @return boolean
45
+ */
46
+ public function save($config_press = null) {
47
+ if (is_writable(AAM_TEMP_DIR)) {
48
+ $filename = $this->getOption();
49
+ if (!$filename) { //file already was created
50
+ $filename = sha1(uniqid('aam'));
51
+ aam_Core_API::updateBlogOption('aam_' . self::UID, $filename);
52
+ }
53
+ $response = file_put_contents(
54
+ AAM_TEMP_DIR . $filename, stripcslashes($config_press)
55
+ );
56
+ } else {
57
+ $response = false;
58
+ aam_Core_Console::write('Temp directory is not writable');
59
+ }
60
+
61
+ return $response;
62
+ }
63
+
64
+ /**
65
+ *
66
+ * @return type
67
+ */
68
+ public function getUID(){
69
+ return self::UID;
70
+ }
71
+
72
+ /**
73
+ *
74
+ * @param type $object_id
75
+ */
76
+ public function init($object_id) {
77
+ if (empty($this->_option)) {
78
+ $filename = aam_Core_API::getBlogOption('aam_' . self::UID, '');
79
+ if ($filename && file_exists(AAM_TEMP_DIR . $filename)) {
80
+ $this->setOption($filename);
81
+ $this->setConfig(file_get_contents(AAM_TEMP_DIR . $filename));
82
+ $this->parseConfig(AAM_TEMP_DIR . $filename);
83
+ }
84
+ }
85
+ }
86
+
87
+ /**
88
+ *
89
+ * @param type $filename
90
+ */
91
+ protected function parseConfig($filename) {
92
+ //include third party library
93
+ if (!class_exists('Zend_Config')){
94
+ require_once(AAM_LIBRARY_DIR . 'Zend/Exception.php');
95
+ require_once(AAM_LIBRARY_DIR . 'Zend/Config/Exception.php');
96
+ require_once(AAM_LIBRARY_DIR . 'Zend/Config.php');
97
+ require_once(AAM_LIBRARY_DIR . 'Zend/Config/Ini.php');
98
+ }
99
+ //parse ini file
100
+ try {
101
+ $this->setTree(new Zend_Config_Ini($filename));
102
+ } catch (Zend_Config_Exception $e) {
103
+ aam_Core_Console::write($e->getMessage());
104
+ }
105
+ }
106
+
107
+ /**
108
+ *
109
+ * @param type $param
110
+ * @param type $default
111
+ * @return type
112
+ */
113
+ protected function parseParam($param, $default) {
114
+ if (is_object($param) && isset($param->userFunc)) {
115
+ $func = trim($param->userFunc);
116
+ if (is_string($func) && is_callable($func)) {
117
+ $response = call_user_func($func);
118
+ } else {
119
+ aam_Core_Console::write("ConfigPress userFunc {$func} failure");
120
+ $response = $default;
121
+ }
122
+ } else {
123
+ $response = $param;
124
+ }
125
+
126
+ return $response;
127
+ }
128
+
129
+ /**
130
+ *
131
+ * @param type $param
132
+ * @param type $default
133
+ * @return type
134
+ */
135
+ public function getParam($param, $default = NULL) {
136
+ $tree = $this->getTree();
137
+ foreach (explode('.', $param) as $section) {
138
+ if (isset($tree->{$section})) {
139
+ $tree = $tree->{$section};
140
+ } else {
141
+ $tree = $default;
142
+ break;
143
+ }
144
+ }
145
+
146
+ return $this->parseParam($tree, $default);
147
+ }
148
+
149
+ /**
150
+ *
151
+ * @param type $option
152
+ */
153
+ public function setOption($option) {
154
+ $this->_option = $option;
155
+ }
156
+
157
+ /**
158
+ *
159
+ * @return type
160
+ */
161
+ public function getOption() {
162
+ return $this->_option;
163
+ }
164
+
165
+ /**
166
+ *
167
+ * @param type $config
168
+ */
169
+ public function setConfig($config) {
170
+ $this->_config = $config;
171
+ }
172
+
173
+ /**
174
+ *
175
+ * @return type
176
+ */
177
+ public function getConfig() {
178
+ return $this->_config;
179
+ }
180
+
181
+ /**
182
+ *
183
+ * @param type $tree
184
+ */
185
+ public function setTree($tree) {
186
+ $this->_tree = $tree;
187
+ }
188
+
189
+ /**
190
+ *
191
+ * @return type
192
+ */
193
+ public function getTree() {
194
+ return $this->_tree;
195
+ }
196
+
197
+ }
application/control/object/event.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_Control_Object_Event extends aam_Control_Object {
17
+
18
+ /**
19
+ *
20
+ */
21
+ const UID = 'event';
22
+
23
+ /**
24
+ *
25
+ * @var type
26
+ */
27
+ private $_option = array();
28
+
29
+ /**
30
+ *
31
+ * @param type $events
32
+ */
33
+ public function save($events = null) {
34
+ if (is_array($events)) {
35
+ $this->getSubject()->updateOption($events, self::UID);
36
+ }
37
+ }
38
+
39
+ /**
40
+ *
41
+ * @return type
42
+ */
43
+ public function backup() {
44
+ return $this->getSubject()->readOption(self::UID, '', array());
45
+ }
46
+
47
+ /**
48
+ *
49
+ * @return type
50
+ */
51
+ public function getUID() {
52
+ return self::UID;
53
+ }
54
+
55
+ /**
56
+ *
57
+ * @param type $option
58
+ */
59
+ public function setOption($option) {
60
+ $this->_option = (is_array($option) ? $option : array());
61
+ }
62
+
63
+ /**
64
+ *
65
+ * @return type
66
+ */
67
+ public function getOption() {
68
+ return $this->_option;
69
+ }
70
+
71
+ }
application/control/object/menu.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class aam_Control_Object_Menu extends aam_Control_Object {
18
+
19
+ /**
20
+ * Object Unique ID
21
+ */
22
+ const UID = 'menu';
23
+
24
+ /**
25
+ * List of options
26
+ *
27
+ * @var array
28
+ *
29
+ * @access private
30
+ */
31
+ private $_option = array();
32
+
33
+ /**
34
+ * Filter Menu List
35
+ *
36
+ * @global array $menu
37
+ * @global array $submenu
38
+ *
39
+ * @return void
40
+ *
41
+ * @access public
42
+ */
43
+ public function filter() {
44
+ global $menu;
45
+
46
+ //filter menu & submenu first
47
+ $capability = uniqid('aam_'); //random capability means NO access
48
+ //let's go and iterate menu & submenu
49
+ foreach ($menu as $id => $item) {
50
+ if ($this->has($item[2])) {
51
+ $menu[$id][1] = $capability;
52
+ $denied = true;
53
+ } else {
54
+ $denied = false;
55
+ }
56
+ //filter submenu
57
+ $submenu = $this->filterSubmenu($item[2], $denied);
58
+ //a trick to whether remove the Root Menu or replace link with the first
59
+ //available submenu
60
+ if ($denied && $submenu){
61
+ $menu[$id][2] = $submenu[1];
62
+ $menu[$id][1] = $submenu[0];
63
+ } elseif ($denied){ //ok, no available submenus, remove it completely
64
+ unset($menu[$id]);
65
+ }
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Filter submenu
71
+ *
72
+ * @global array $submenu
73
+ *
74
+ * @param array $menu
75
+ * @param boolean $denied
76
+ *
77
+ * @return string|null
78
+ *
79
+ * @access public
80
+ */
81
+ public function filterSubmenu($menu, $denied) {
82
+ global $submenu;
83
+
84
+ //go to submenu
85
+ $available = null;
86
+ if (isset($submenu[$menu])) {
87
+ foreach ($submenu[$menu] as $sid => $sub_item) {
88
+ if ($this->has($sub_item[2])) {
89
+ //weird WordPress behavior, it gets the first submenu link
90
+ //$submenu[$menu][$sid][1] = $capability;
91
+ unset($submenu[$menu][$sid]);
92
+ } elseif (is_null($available)){ //find first available submenu
93
+ $available = array($sub_item[1], $sub_item[2]);
94
+ }
95
+ }
96
+ }
97
+
98
+ //replace submenu with available new if found
99
+ if ($denied && !is_null($available) && ($available[1] != $menu) ){
100
+ $submenu[$available[1]] = $submenu[$menu];
101
+ unset($submenu[$menu]);
102
+ }
103
+
104
+ return $available;
105
+ }
106
+
107
+ /**
108
+ *
109
+ * @param type $menu
110
+ */
111
+ public function save($menu = null) {
112
+ if (is_array($menu)) {
113
+ $this->getSubject()->updateOption($menu, self::UID);
114
+ }
115
+ }
116
+
117
+ /**
118
+ *
119
+ * @return type
120
+ */
121
+ public function backup() {
122
+ return $this->getSubject()->readOption(self::UID, '', array());
123
+ }
124
+
125
+ /**
126
+ *
127
+ * @return type
128
+ */
129
+ public function getUID() {
130
+ return self::UID;
131
+ }
132
+
133
+ /**
134
+ *
135
+ * @param type $option
136
+ */
137
+ public function setOption($option) {
138
+ $this->_option = (is_array($option) ? $option : array());
139
+ }
140
+
141
+ /**
142
+ *
143
+ * @return type
144
+ */
145
+ public function getOption() {
146
+ return $this->_option;
147
+ }
148
+
149
+ /**
150
+ *
151
+ * @param type $menu
152
+ * @return type
153
+ */
154
+ public function has($menu) {
155
+ $response = false;
156
+ if (isset($this->_option[$menu])) {
157
+ $response = (intval($this->_option[$menu]) ? true : false);
158
+ }
159
+
160
+ return $response;
161
+ }
162
+
163
+ }
application/control/object/metabox.php ADDED
@@ -0,0 +1 @@
 
0
  * ======================================================================
1
  * LICENSE: This file is subject to the terms and conditions defined in *
2
  * file 'license.txt', which is part of this source code package. *
3
  * ======================================================================
4
  */
5
  *
6
  * @package AAM
7
  * @author Vasyl Martyniuk <support@wpaam.com>
8
  * @copyright Copyright C 2013 Vasyl Martyniuk
9
  * @license GNU General Public License {@link http://www.gnu.org/licenses/}
10
  */
11
  /**
12
  *
13
  */
14
  const UID = 'metabox';
15
  /**
16
  *
17
  * @var type
18
  */
19
  private $_option = array();
20
  /**
21
  *
22
  * @global type $wp_registered_widgets
23
  * @param type $sidebar_widgets
24
  * @return type
25
  */
26
  public function filterFrontend($sidebar_widgets) {
27
  global $wp_registered_widgets;
28
  if (is_array($wp_registered_widgets)) {
29
  foreach ($wp_registered_widgets as $id => $data) {
30
  if (is_object($data['callback'][0])) {
31
  $callback = get_class($data['callback'][0]);
32
  } elseif (is_string($data['callback'][0])) {
33
  $callback = $data['callback'][0];
34
  }
35
  if ($this->has('widgets', $callback)) {
36
  unregister_widget($callback);
37
  //remove it from registered widget global var!!
38
  //INFORM: Why Unregister Widget does not clear global var?
39
  unset($wp_registered_widgets[$id]);
40
  }
41
  }
42
  }
43
  return $sidebar_widgets;
44
  }
45
  /**
46
  *
47
  * @global type $wp_meta_boxes
48
  * @param type $screen
49
  * @param type $post
50
  */
51
  public function filterBackend($screen, $post = null) {
52
  global $wp_meta_boxes;
53
  if (is_array($wp_meta_boxes)) {
54
  foreach ($wp_meta_boxes as $screen_id => $zones) {
55
  if ($screen == $screen_id) {
56
  foreach ($zones as $zone => $priorities) {
57
  foreach ($priorities as $priority => $metaboxes) {
58
  foreach ($metaboxes as $metabox => $data) {
59
  if ($this->has($screen_id, $metabox)) {
60
  remove_meta_box($metabox, $screen_id, $zone);
61
  }
62
  }
63
  }
64
  }
65
  }
66
  }
67
  }
68
  }
69
  /**
70
  *
71
  * @param type $metaboxes
72
  */
73
  public function save($metaboxes = null) {
74
  if (is_array($metaboxes)) {
75
  $this->getSubject()->updateOption($metaboxes, self::UID);
76
  }
77
  }
78
  /**
79
  *
80
  * @return type
81
  */
82
  public function backup() {
83
  return $this->getSubject()->readOption(self::UID, '', array());
84
  }
85
  /**
86
  *
87
  * @return type
88
  */
89
  public function getUID() {
90
  return self::UID;
91
  }
92
  /**
93
  *
94
  * @param type $option
95
  */
96
  public function setOption($option) {
97
  $this->_option = (is_array($option) ? $option : array());
98
  }
99
  /**
100
  *
101
  * @return type
102
  */
103
  public function getOption() {
104
  return $this->_option;
105
  }
106
  /**
107
  *
108
  * @param type $group
109
  * @param type $metabox
110
  * @return type
111
  */
112
  public function has($group, $metabox) {
113
  $response = false;
114
  if (isset($this->_option[$group][$metabox])) {
115
  $response = (intval($this->_option[$group][$metabox]) ? true : false);
116
  }
117
  return $response;
118
  }
1
+ <?php
2
  * ======================================================================
3
  * LICENSE: This file is subject to the terms and conditions defined in *
4
  * file 'license.txt', which is part of this source code package. *
5
  * ======================================================================
6
  */
7
  *
8
  * @package AAM
9
  * @author Vasyl Martyniuk <support@wpaam.com>
10
  * @copyright Copyright C 2013 Vasyl Martyniuk
11
  * @license GNU General Public License {@link http://www.gnu.org/licenses/}
12
  */
13
  /**
14
  *
15
  */
16
  const UID = 'metabox';
17
  /**
18
  *
19
  * @var type
20
  */
21
  private $_option = array();
22
  /**
23
  *
24
  * @global type $wp_registered_widgets
25
  * @param type $sidebar_widgets
26
  * @return type
27
  */
28
  public function filterFrontend($sidebar_widgets) {
29
  global $wp_registered_widgets;
30
  if (is_array($wp_registered_widgets)) {
31
  foreach ($wp_registered_widgets as $id => $data) {
32
  if (is_object($data['callback'][0])) {
33
  $callback = get_class($data['callback'][0]);
34
  } elseif (is_string($data['callback'][0])) {
35
  $callback = $data['callback'][0];
36
  }
37
  if ($this->has('widgets', $callback)) {
38
  unregister_widget($callback);
39
  //remove it from registered widget global var!!
40
  //INFORM: Why Unregister Widget does not clear global var?
41
  unset($wp_registered_widgets[$id]);
42
  }
43
  }
44
  }
45
  return $sidebar_widgets;
46
  }
47
  /**
48
  *
49
  * @global type $wp_meta_boxes
50
  * @param type $screen
51
  * @param type $post
52
  */
53
  public function filterBackend($screen, $post = null) {
54
  global $wp_meta_boxes;
55
  if (is_array($wp_meta_boxes)) {
56
  foreach ($wp_meta_boxes as $screen_id => $zones) {
57
  if ($screen == $screen_id) {
58
  foreach ($zones as $zone => $priorities) {
59
  foreach ($priorities as $priority => $metaboxes) {
60
  foreach ($metaboxes as $metabox => $data) {
61
  if ($this->has($screen_id, $metabox)) {
62
  remove_meta_box($metabox, $screen_id, $zone);
63
  }
64
  }
65
  }
66
  }
67
  }
68
  }
69
  }
70
  }
71
  /**
72
  *
73
  * @param type $metaboxes
74
  */
75
  public function save($metaboxes = null) {
76
  if (is_array($metaboxes)) {
77
  $this->getSubject()->updateOption($metaboxes, self::UID);
78
  }
79
  }
80
  /**
81
  *
82
  * @return type
83
  */
84
  public function backup() {
85
  return $this->getSubject()->readOption(self::UID, '', array());
86
  }
87
  /**
88
  *
89
  * @return type
90
  */
91
  public function getUID() {
92
  return self::UID;
93
  }
94
  /**
95
  *
96
  * @param type $option
97
  */
98
  public function setOption($option) {
99
  $this->_option = (is_array($option) ? $option : array());
100
  }
101
  /**
102
  *
103
  * @return type
104
  */
105
  public function getOption() {
106
  return $this->_option;
107
  }
108
  /**
109
  *
110
  * @param type $group
111
  * @param type $metabox
112
  * @return type
113
  */
114
  public function has($group, $metabox) {
115
  $response = false;
116
  if (isset($this->_option[$group][$metabox])) {
117
  $response = (intval($this->_option[$group][$metabox]) ? true : false);
118
  }
119
  return $response;
120
  }
application/control/object/post.php ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_Control_Object_Post extends aam_Control_Object {
17
+
18
+ /**
19
+ *
20
+ */
21
+ const UID = 'post';
22
+
23
+ /**
24
+ *
25
+ */
26
+ const ACTION_COMMENT = 'comment';
27
+
28
+ /**
29
+ *
30
+ */
31
+ const ACTION_READ = 'read';
32
+
33
+ /**
34
+ *
35
+ */
36
+ const ACTION_EXCLUDE = 'exclude';
37
+
38
+ /**
39
+ *
40
+ */
41
+ const ACTION_TRASH = 'trash';
42
+
43
+ /**
44
+ *
45
+ */
46
+ const ACTION_DELETE = 'delete';
47
+
48
+ /**
49
+ *
50
+ */
51
+ const ACTION_EDIT = 'edit';
52
+
53
+ /**
54
+ *
55
+ * @var type
56
+ */
57
+ private $_post;
58
+
59
+ /**
60
+ *
61
+ * @var type
62
+ */
63
+ private $_option = array();
64
+
65
+ /**
66
+ *
67
+ * @param type $params
68
+ */
69
+ public function save($params = null) {
70
+ if (is_array($params)) {
71
+ update_post_meta($this->getPost()->ID, $this->getOptionName(), $params);
72
+ }
73
+ }
74
+
75
+ /**
76
+ *
77
+ * @param type $area
78
+ * @return type
79
+ */
80
+ public function getAccessList($area) {
81
+ if ($area == 'frontend') {
82
+ $response = array(
83
+ self::ACTION_READ, self::ACTION_EXCLUDE, self::ACTION_COMMENT
84
+ );
85
+ } elseif ($area == 'backend') {
86
+ $response = array(
87
+ self::ACTION_TRASH, self::ACTION_DELETE, self::ACTION_EDIT
88
+ );
89
+ } else {
90
+ $response = array();
91
+ }
92
+
93
+ return apply_filters('aam_post_access_list', $response, $area);
94
+ }
95
+
96
+ /**
97
+ *
98
+ * @return type
99
+ */
100
+ public function getUID() {
101
+ return self::UID;
102
+ }
103
+
104
+ /**
105
+ *
106
+ * @return type
107
+ */
108
+ protected function getOptionName() {
109
+ $subject = $this->getSubject();
110
+ //prepare option name
111
+ $meta_key = 'aam_' . self::UID . '_access_' . $subject->getUID();
112
+ $meta_key .= ($subject->getId() ? $subject->getId() : '');
113
+
114
+ return $meta_key;
115
+ }
116
+
117
+ /**
118
+ *
119
+ * @param type $object
120
+ */
121
+ public function init($object) {
122
+ //make sure that we are dealing with WP_Post object
123
+ if ($object instanceof WP_Post){
124
+ $this->setPost($object);
125
+ } elseif (intval($object)) {
126
+ $this->setPost(get_post($object));
127
+ }
128
+ //read options
129
+ if ($this->getPost()) {
130
+ $this->read();
131
+ }
132
+ }
133
+
134
+ /**
135
+ *
136
+ */
137
+ public function read() {
138
+ $option = get_post_meta($this->getPost()->ID, $this->getOptionName(), true);
139
+ //try to inherit it from parent category
140
+ if (empty($option)) {
141
+ $terms = $this->retrievePostTerms();
142
+ //use only first term for inheritance
143
+ $term_id = array_shift($terms);
144
+ //try to get any parent access
145
+ $option = $this->inheritAccess($term_id);
146
+ }
147
+
148
+ $this->setOption(
149
+ apply_filters('aam_post_access_option', $option, $this->getSubject())
150
+ );
151
+ }
152
+
153
+ /**
154
+ *
155
+ * @return type
156
+ */
157
+ public function delete() {
158
+ return delete_post_meta($this->getPost()->ID, $this->getOptionName());
159
+ }
160
+
161
+ /**
162
+ *
163
+ * @return array
164
+ */
165
+ private function retrievePostTerms() {
166
+ $taxonomies = get_object_taxonomies($this->getPost());
167
+ if (is_array($taxonomies) && count($taxonomies)) {
168
+ //filter taxonomies to hierarchical only
169
+ $filtered = array();
170
+ foreach ($taxonomies as $taxonomy) {
171
+ if (is_taxonomy_hierarchical($taxonomy)) {
172
+ $filtered[] = $taxonomy;
173
+ }
174
+ }
175
+ $terms = wp_get_object_terms(
176
+ $this->getPost()->ID, $filtered, array('fields' => 'ids')
177
+ );
178
+ } else {
179
+ $terms = array();
180
+ }
181
+
182
+ return $terms;
183
+ }
184
+
185
+ /**
186
+ *
187
+ * @param type $term_id
188
+ * @return array
189
+ */
190
+ private function inheritAccess($term_id) {
191
+ $term = new aam_Control_Object_Term($this->getSubject(), $term_id);
192
+ $access = $term->getOption();
193
+ if (isset($access['post']) && $access['post']) {
194
+ $result = array('post' => $access['post']);
195
+ } elseif (is_object($term->getTerm()) && $term->getTerm()->parent) {
196
+ $result = $this->inheritAccess($term->getTerm()->parent);
197
+ } else {
198
+ $result = array();
199
+ }
200
+
201
+ return $result;
202
+ }
203
+
204
+ /**
205
+ * Set Post. Cover all unexpectd wierd issues with WP Core
206
+ *
207
+ * @param WP_Post $post
208
+ *
209
+ * @return void
210
+ *
211
+ * @access public
212
+ */
213
+ public function setPost($post) {
214
+ if ($post instanceof WP_Post){
215
+ $this->_post = $post;
216
+ } else {
217
+ $this->_post = (object) array('ID' => 0);
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Get Post
223
+ *
224
+ * @return WP_Post|stdClass
225
+ *
226
+ * @access public
227
+ */
228
+ public function getPost() {
229
+ return $this->_post;
230
+ }
231
+
232
+ /**
233
+ *
234
+ * @param type $option
235
+ */
236
+ public function setOption($option) {
237
+ $this->_option = (is_array($option) ? $option : array());
238
+ }
239
+
240
+ /**
241
+ *
242
+ * @return type
243
+ */
244
+ public function getOption() {
245
+ return $this->_option;
246
+ }
247
+
248
+ /**
249
+ *
250
+ * @param type $area
251
+ * @param type $action
252
+ * @return type
253
+ */
254
+ public function has($area, $action) {
255
+ $response = false;
256
+ if (isset($this->_option['post'][$area][$action])) {
257
+ $response = (intval($this->_option['post'][$area][$action]) ? true : false);
258
+ }
259
+
260
+ return $response;
261
+ }
262
+
263
+ }
application/control/object/term.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class aam_Control_Object_Term extends aam_Control_Object {
18
+
19
+ /**
20
+ *
21
+ */
22
+ const UID = 'term';
23
+
24
+ /**
25
+ *
26
+ */
27
+ const ACTION_BROWSE = 'browse';
28
+
29
+ /**
30
+ *
31
+ */
32
+ const ACTION_EXCLUDE = 'exclude';
33
+
34
+ /**
35
+ *
36
+ */
37
+ const ACTION_EDIT = 'edit';
38
+
39
+ /**
40
+ *
41
+ */
42
+ const ACTION_LIST = 'list';
43
+
44
+ /**
45
+ *
46
+ * @var type
47
+ */
48
+ private $_term = null;
49
+
50
+ /**
51
+ *
52
+ * @var type
53
+ */
54
+ private $_option = array();
55
+
56
+ /**
57
+ *
58
+ * @param type $params
59
+ */
60
+ public function save($params = null) {
61
+ if (is_array($params)) {
62
+ $this->getSubject()->updateOption(
63
+ $params, self::UID, $this->getTerm()->term_id
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param type $area
71
+ * @return type
72
+ */
73
+ public function getAccessList($area) {
74
+ if ($area == 'frontend') {
75
+ $response = array(
76
+ self::ACTION_BROWSE, self::ACTION_EXCLUDE, self::ACTION_LIST
77
+ );
78
+ } elseif ($area == 'backend') {
79
+ $response = array(
80
+ self::ACTION_BROWSE, self::ACTION_EDIT, self::ACTION_LIST
81
+ );
82
+ } else {
83
+ $response = array();
84
+ }
85
+
86
+ return apply_filters('aam_term_access_list', $response, $area);
87
+ }
88
+
89
+ /**
90
+ *
91
+ * @return type
92
+ */
93
+ public function getUID() {
94
+ return self::UID;
95
+ }
96
+
97
+ /**
98
+ *
99
+ * @param type $object_id
100
+ */
101
+ public function init($object_id) {
102
+ if ($object_id) {
103
+ //initialize term first
104
+ $this->setTerm(get_term($object_id, $this->getTaxonomy($object_id)));
105
+ if ($this->getTerm()) {
106
+ $access = $this->getSubject()->readOption(
107
+ self::UID, $this->getTerm()->term_id
108
+ );
109
+ if (empty($access)) {
110
+ //try to get any parent restriction
111
+ $access = $this->inheritAccess($this->getTerm()->parent);
112
+ }
113
+
114
+ $this->setOption(
115
+ apply_filters('aam_term_access_option', $access, $this->getSubject())
116
+ );
117
+ } else {
118
+ aam_Core_Console::write("Term {$object_id} does not exist");
119
+ }
120
+ }
121
+ }
122
+
123
+ /**
124
+ *
125
+ * @return type
126
+ */
127
+ public function delete() {
128
+ return $this->getSubject()->deleteOption(
129
+ self::UID, $this->getTerm()->term_id
130
+ );
131
+ }
132
+
133
+ /**
134
+ *
135
+ * @param type $term_id
136
+ * @return array
137
+ */
138
+ private function inheritAccess($term_id) {
139
+ $term = new aam_Control_Object_Term($this->getSubject(), $term_id);
140
+ if ($term->getTerm()) {
141
+ $access = $term->getOption();
142
+ if (empty($access) && $term->getTerm()->parent) {
143
+ $this->inheritAccess($term->getTerm()->parent);
144
+ } elseif (!empty($access)) {
145
+ $access['inherited'] = true;
146
+ }
147
+ } else {
148
+ $access = array();
149
+ }
150
+
151
+ return $access;
152
+ }
153
+
154
+ /**
155
+ *
156
+ * @global type $wpdb
157
+ * @param type $object_id
158
+ * @return type
159
+ */
160
+ private function getTaxonomy($object_id) {
161
+ global $wpdb;
162
+
163
+ $query = "SELECT taxonomy FROM {$wpdb->term_taxonomy} ";
164
+ $query .= "WHERE term_id = {$object_id}";
165
+
166
+ return $wpdb->get_var($query);
167
+ }
168
+
169
+ /**
170
+ *
171
+ * @param type $term
172
+ */
173
+ public function setTerm($term) {
174
+ $this->_term = $term;
175
+ }
176
+
177
+ /**
178
+ *
179
+ * @return type
180
+ */
181
+ public function getTerm() {
182
+ return $this->_term;
183
+ }
184
+
185
+ /**
186
+ *
187
+ * @param type $option
188
+ */
189
+ public function setOption($option) {
190
+ $this->_option = (is_array($option) ? $option : array());
191
+ }
192
+
193
+ /**
194
+ *
195
+ * @return type
196
+ */
197
+ public function getOption() {
198
+ return $this->_option;
199
+ }
200
+
201
+ /**
202
+ *
203
+ * @param type $area
204
+ * @param type $action
205
+ * @return type
206
+ */
207
+ public function has($area, $action) {
208
+ $response = false;
209
+ if (isset($this->_option['term'][$area][$action])) {
210
+ $response = (intval($this->_option['term'][$area][$action]) ? true : false);
211
+ }
212
+
213
+ return $response;
214
+ }
215
+
216
+ }
application/control/subject.php ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ abstract class aam_Control_Subject {
18
+
19
+ /**
20
+ * Subject ID
21
+ *
22
+ * Whether it is User ID or Role ID
23
+ *
24
+ * @var string|int
25
+ *
26
+ * @access private
27
+ */
28
+ private $_id;
29
+
30
+ /**
31
+ * Subject itself
32
+ *
33
+ * It can be WP_User or WP_Role, based on what class has been used
34
+ *
35
+ * @var WP_Role|WP_User
36
+ *
37
+ * @access private
38
+ */
39
+ private $_subject;
40
+
41
+ /**
42
+ * List of Objects to be access controled for current subject
43
+ *
44
+ * All access control objects like Admin Menu, Metaboxes, Posts etc
45
+ *
46
+ * @var array
47
+ *
48
+ * @access private
49
+ */
50
+ private $_objects = array();
51
+
52
+ /**
53
+ * Constructor
54
+ *
55
+ * @param string|int $id
56
+ *
57
+ * @return void
58
+ *
59
+ * @access public
60
+ */
61
+ public function __construct($id) {
62
+ //set subject
63
+ $this->setId($id);
64
+ //retrieve and set subject itself
65
+ $this->setSubject($this->retrieveSubject());
66
+ }
67
+
68
+ /**
69
+ * Trigger Subject native methods
70
+ *
71
+ * @param string $name
72
+ * @param array $arguments
73
+ *
74
+ * @return mixed
75
+ *
76
+ * @access public
77
+ */
78
+ public function __call($name, $arguments) {
79
+ $subject = $this->getSubject();
80
+ //make sure that method is callable
81
+ if (method_exists($subject, $name)) {
82
+ $response = call_user_func_array(array($subject, $name), $arguments);
83
+ } else {
84
+ aam_Core_Console::write(
85
+ "Method {$name} does not exist in " . get_class($subject)
86
+ );
87
+ $response = null;
88
+ }
89
+
90
+ return $response;
91
+ }
92
+
93
+ /**
94
+ * Get Subject's native properties
95
+ *
96
+ * @param string $name
97
+ *
98
+ * @return mixed
99
+ *
100
+ * @access public
101
+ */
102
+ public function __get($name) {
103
+ $subject = $this->getSubject();
104
+ return $subject->$name;
105
+ }
106
+
107
+ /**
108
+ * Set Subject's native properties
109
+ *
110
+ * @param string $name
111
+ *
112
+ * @return mixed
113
+ *
114
+ * @access public
115
+ */
116
+ public function __set($name, $value) {
117
+ $subject = $this->getSubject();
118
+ $subject->$name = $value;
119
+ }
120
+
121
+ /**
122
+ * Set Subject ID
123
+ *
124
+ * @param string|int
125
+ *
126
+ * @return void
127
+ *
128
+ * @access public
129
+ */
130
+ public function setId($id) {
131
+ $this->_id = $id;
132
+ }
133
+
134
+ /**
135
+ * Get Subject ID
136
+ *
137
+ * @return string|int
138
+ *
139
+ * @access public
140
+ */
141
+ public function getId() {
142
+ return $this->_id;
143
+ }
144
+
145
+ /**
146
+ * Get Subject
147
+ *
148
+ * @return WP_Role|WP_User
149
+ *
150
+ * @access public
151
+ */
152
+ public function getSubject() {
153
+ return $this->_subject;
154
+ }
155
+
156
+ /**
157
+ * Set Subject
158
+ *
159
+ * @param WP_Role|WP_User $subject
160
+ *
161
+ * @return void
162
+ *
163
+ * @access public
164
+ */
165
+ public function setSubject($subject) {
166
+ $this->_subject = $subject;
167
+ }
168
+
169
+ /**
170
+ * Get Access Objects
171
+ *
172
+ * @return array
173
+ *
174
+ * @access public
175
+ */
176
+ public function getObjects() {
177
+ return $this->_objects;
178
+ }
179
+
180
+ /**
181
+ * Get Individual Object
182
+ *
183
+ * @param string $object
184
+ * @param mixed $object_id
185
+ *
186
+ * @return aam_Control_Object
187
+ *
188
+ * @access public
189
+ */
190
+ public function getObject($object, $object_id = 0) {
191
+ if (!isset($this->_objects[$object])) {
192
+ $class_name = 'aam_Control_Object_' . ucfirst($object);
193
+ if (class_exists($class_name)) {
194
+ $this->_objects[$object] = new $class_name($this, $object_id);
195
+ } else {
196
+ $this->_objects[$object] = apply_filters(
197
+ 'aam_object', null, $this, $object_id
198
+ );
199
+ }
200
+ }
201
+
202
+ //make sure that object exists, otherwise log it
203
+ if (is_null($this->_objects[$object])) {
204
+ aam_Core_Console::write("Object {$object} does not exist");
205
+ }
206
+
207
+ return $this->_objects[$object];
208
+ }
209
+
210
+ /**
211
+ * Set Individual Access Object
212
+ *
213
+ * @param aam_Control_Object $object
214
+ * @param string $uid
215
+ *
216
+ * @return void
217
+ *
218
+ * @access public
219
+ */
220
+ public function setObject(aam_Control_Object $object, $uid) {
221
+ $this->_objects[$uid] = $object;
222
+ }
223
+
224
+ /**
225
+ * Get Subject Type
226
+ *
227
+ * @return string
228
+ *
229
+ * @access public
230
+ */
231
+ public function getType() {
232
+ return get_class($this->getSubject());
233
+ }
234
+
235
+ /**
236
+ *
237
+ * @param type $capability
238
+ * @return type
239
+ */
240
+ public function hasCapability($capability) {
241
+ return $this->getSubject()->has_cap($capability);
242
+ }
243
+
244
+ /**
245
+ * Retrieve list of subject's capabilities
246
+ *
247
+ * @return array
248
+ *
249
+ * @access public
250
+ */
251
+ abstract public function getCapabilities();
252
+
253
+ /**
254
+ * Save Access Parameters
255
+ *
256
+ * @param array $params
257
+ *
258
+ * @return boolean
259
+ *
260
+ * @access public
261
+ */
262
+ public function save(array $params) {
263
+ //initialize the backup first
264
+ $backup = array();
265
+
266
+ foreach ($params as $object_id => $dump) {
267
+ if ($object = $this->getObject($object_id)) {
268
+ if (method_exists($object, 'backup')) {
269
+ $backup[$object_id] = $object->backup();
270
+ }
271
+ $object->save($dump);
272
+ }
273
+ }
274
+
275
+ //store backup
276
+ $this->getObject(aam_Control_Object_Backup::UID)->save($backup);
277
+ }
278
+
279
+ /**
280
+ * Retrieve subject based on used class
281
+ *
282
+ * @return void
283
+ *
284
+ * @access protected
285
+ */
286
+ abstract protected function retrieveSubject();
287
+ }
application/control/subject/role.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class aam_Control_Subject_Role extends aam_Control_Subject {
18
+
19
+ /**
20
+ * Subject UID: ROLE
21
+ */
22
+ const UID = 'role';
23
+
24
+ /**
25
+ * Retrieve Role based on ID
26
+ *
27
+ * @return WP_Role|null
28
+ *
29
+ * @access protected
30
+ */
31
+ protected function retrieveSubject() {
32
+ $roles = new WP_Roles;
33
+ $role = $roles->get_role($this->getId());
34
+
35
+ if (is_null($role)) {
36
+ aam_Core_Console::write('Role ' . $this->getId() . ' does not exist');
37
+ } elseif (isset($role->capabilities)){
38
+ //add role capability as role id, weird WordPress behavior
39
+ //example is administrator capability
40
+ $role->capabilities[$this->getId()] = true;
41
+ }
42
+
43
+ return $role;
44
+ }
45
+
46
+ /**
47
+ *
48
+ * @param type $delete_users
49
+ * @return boolean
50
+ */
51
+ public function delete($delete_users = false) {
52
+ $role = new WP_Roles;
53
+
54
+ if ($this->getId() !== 'administrator') {
55
+ if ($delete_users) {
56
+ if (current_user_can('delete_users')) {
57
+ //delete users first
58
+ $users = new WP_User_Query(array(
59
+ 'number' => '',
60
+ 'blog_id' => get_current_blog_id(),
61
+ 'role' => aam_Core_Request::post('role')
62
+ ));
63
+ foreach ($users->get_results() as $user) {
64
+ //user can not delete himself
65
+ if ($user->data->ID !== get_current_user_id()) {
66
+ wp_delete_user($user->data->ID);
67
+ }
68
+ }
69
+ $role->remove_role($this->getId());
70
+ $status = true;
71
+ } else {
72
+ $status = false;
73
+ }
74
+ } else {
75
+ $role->remove_role($this->getId());
76
+ $status = true;
77
+ }
78
+ } else {
79
+ $status = false;
80
+ }
81
+
82
+ return $status;
83
+ }
84
+
85
+ /**
86
+ *
87
+ * @param type $name
88
+ * @return boolean
89
+ */
90
+ public function update($name) {
91
+ $role = new WP_Roles;
92
+ if ($name) {
93
+ $role->roles[$this->getId()]['name'] = $name;
94
+ $status = aam_Core_API::updateBlogOption($role->role_key, $role->roles);
95
+ } else {
96
+ $status = false;
97
+ }
98
+
99
+ return $status;
100
+ }
101
+
102
+ /**
103
+ * Remove Capability
104
+ *
105
+ * @param string $capability
106
+ *
107
+ * @return boolean
108
+ *
109
+ * @access public
110
+ */
111
+ public function removeCapability($capability) {
112
+ return $this->getSubject()->remove_cap($capability);
113
+ }
114
+
115
+ /**
116
+ * Check if Subject has capability
117
+ *
118
+ * Keep compatible with WordPress core
119
+ *
120
+ * @param string $capability
121
+ *
122
+ * @return boolean
123
+ *
124
+ * @access public
125
+ */
126
+ public function addCapability($capability) {
127
+ return $this->getSubject()->add_cap($capability, 1);
128
+ }
129
+
130
+ /**
131
+ *
132
+ * @return type
133
+ */
134
+ public function getCapabilities() {
135
+ return $this->getSubject()->capabilities;
136
+ }
137
+
138
+ /**
139
+ *
140
+ * @param type $value
141
+ * @param type $object
142
+ * @param type $object_id
143
+ * @return type
144
+ */
145
+ public function updateOption($value, $object, $object_id = '') {
146
+ return aam_Core_API::updateBlogOption(
147
+ $this->getOptionName($object, $object_id), $value
148
+ );
149
+ }
150
+
151
+ /**
152
+ *
153
+ * @param type $object
154
+ * @param type $object_id
155
+ * @param type $default
156
+ * @return type
157
+ */
158
+ public function readOption($object, $object_id = '', $default = null) {
159
+ return aam_Core_API::getBlogOption(
160
+ $this->getOptionName($object, $object_id), $default
161
+ );
162
+ }
163
+
164
+ /**
165
+ *
166
+ * @param type $object
167
+ * @param type $object_id
168
+ * @return type
169
+ */
170
+ public function deleteOption($object, $object_id = '') {
171
+ return aam_Core_API::deleteBlogOption(
172
+ $this->getOptionName($object, $object_id)
173
+ );
174
+ }
175
+
176
+ /**
177
+ *
178
+ * @param type $object
179
+ * @param type $object_id
180
+ * @return string
181
+ */
182
+ protected function getOptionName($object, $object_id) {
183
+ $name = "aam_{$object}" . ($object_id ? "_{$object_id}_" : '_');
184
+ $name .= self::UID . '_' . $this->getId();
185
+
186
+ return $name;
187
+ }
188
+
189
+ /**
190
+ *
191
+ * @return type
192
+ */
193
+ public function getUID() {
194
+ return self::UID;
195
+ }
196
+
197
+ }
application/control/subject/user.php ADDED
@@ -0,0 +1 @@
 
0
  * ======================================================================
1
  * LICENSE: This file is subject to the terms and conditions defined in *
2
  * file 'license.txt', which is part of this source code package. *
3
  * ======================================================================
4
  */
5
  *
6
  * @package AAM
7
  * @author Vasyl Martyniuk <support@wpaam.com>
8
  * @copyright Copyright C 2013 Vasyl Martyniuk
9
  * @license GNU General Public License {@link http://www.gnu.org/licenses/}
10
  */
11
  /**
12
  * Subject UID: USER
13
  */
14
  const UID = 'user';
15
 
16
  /**
17
  * AAM Capability Key
18
  *
19
  * WordPress does not allow to have different set of capabilities for one user
20
  * between sites. aam_capability key stores the set of capabilities stored after
21
  * individual user edit and merge them with system capabilities.
22
  * The merging process overwrites allcaps.
23
  *
24
  * @var array
25
  *
26
  * @access private
27
  */
28
  private $_cap_key = '';
29
  /**
30
  *
31
  * @param type $id
32
  */
33
  public function __construct($id) {
34
  parent::__construct($id);
35
 
36
  //initialize list of capabilities
37
  //$this->getObject(aam_Control_Object_Capability::UID);
38
 
39
  //overwrite default set of capabilities if AAM capset is defined
40
  if ($this->isDefaultCapSet() === false){
41
  //make sure that aam_capability is actually array
42
  if (is_array($this->getSubject()->aam_caps)){
43
  $allcaps = array_merge(
44
  $this->getSubject()->allcaps, $this->getSubject()->aam_caps
45
  );
46
  $this->getSubject()->allcaps = $allcaps;
47
  }
48
  }
49
  }
50
  /**
51
  *
52
  * @return type
53
  */
54
  public function delete() {
55
  $response = false;
56
  if (current_user_can('delete_users')
57
  && ($this->getId() !== get_current_user_id())) {
58
  $response = wp_delete_user($this->getId());
59
  }
60
  return $response;
61
  }
62
  /**
63
  *
64
  * @global type $wpdb
65
  * @return boolean
66
  */
67
  public function block() {
68
  global $wpdb;
69
  $response = false;
70
  if (current_user_can('edit_users')
71
  && ($this->getId() != get_current_user_id())) {
72
  $status = ($this->getSubject()->user_status == 0 ? 1 : 0);
73
  if ($wpdb->update(
74
  $wpdb->users,
75
  array('user_status' => $status),
76
  array('ID' => $this->getId())
77
  )) {
78
  $this->getSubject()->user_status = $status;
79
  clean_user_cache($this->getSubject());
80
  $response = true;
81
  }
82
  }
83
  return $response;
84
  }
85
  /**
86
  * Retrieve User based on ID
87
  *
88
  * @return WP_Role|null
89
  *
90
  * @access protected
91
  */
92
  protected function retrieveSubject() {
93
  global $current_user;
94
  if ($current_user instanceof WP_User && $current_user->ID == $this->getId()) {
95
  $subject = $current_user;
96
  } else {
97
  $subject = new WP_User($this->getId());
98
  }
99
 
100
  //retrieve aam capabilities
101
  $this->_cap_key = 'aam_capability';
102
  $subject->aam_caps = get_user_option($this->_cap_key, $this->getId());
103
 
104
  return $subject;
105
  }
106
 
107
  /**
108
  * Check if user has default capability set
109
  *
110
  * @return boolean
111
  *
112
  * @access public
113
  */
114
  public function isDefaultCapSet(){
115
  return empty($this->getSubject()->aam_caps);
116
  }
117
  /**
118
  *
119
  * @return type
120
  */
121
  public function getCapabilities() {
122
  return $this->getSubject()->allcaps;
123
  }
124
  /**
125
  *
126
  * @param type $capability
127
  * @return type
128
  */
129
  public function hasCapability($capability) {
130
  return user_can($this->getSubject(), $capability);
131
  }
132
 
133
  /**
134
  * Check if Subject has capability
135
  *
136
  * Keep compatible with WordPress core
137
  *
138
  * @param string $capability
139
  *
140
  * @return boolean
141
  *
142
  * @access public
143
  */
144
  public function addCapability($capability) {
145
  return $this->updateCapability($capability, true);
146
  }
147
  /**
148
  * Remove Capability
149
  *
150
  * @param string $capability
151
  *
152
  * @return boolean
153
  *
154
  * @access public
155
  */
156
  public function removeCapability($capability) {
157
  return $this->updateCapability($capability, false);
158
  }
159
 
160
  /**
161
  * Reset User Capability
162
  *
163
  * @return array
164
  *
165
  * @access public
166
  */
167
  public function resetCapability(){
168
  return delete_user_option($this->getId(), $this->_cap_key);
169
  }
170
 
171
  /**
172
  * Update User's Capability Set
173
  *
174
  * @param string $capability
175
  * @param boolean $grand
176
  *
177
  * @return boolean
178
  *
179
  * @access public
180
  */
181
  public function updateCapability($capability, $grand){
182
  //make sure that we have right array
183
  if (is_array($this->getSubject()->aam_caps)){
184
  $aam_caps = $this->getSubject()->aam_caps;
185
  } else {
186
  $aam_caps = array();
187
  }
188
 
189
  //add capability
190
  $aam_caps[$capability] = $grand;
191
  //update user data. TODO - Keep eyes on this part
192
  $this->getSubject()->data->aam_caps = $aam_caps;
193
  //save and return the result of operation
194
  return update_user_option($this->getId(), $this->_cap_key, $aam_caps);
195
  }
196
  /**
197
  *
198
  * @param type $value
199
  * @param type $object
200
  * @param type $object_id
201
  * @return type
202
  */
203
  public function updateOption($value, $object, $object_id = '') {
204
  return update_user_option(
205
  $this->getId(), $this->getOptionName($object, $object_id), $value
206
  );
207
  }
208
  /**
209
  *
210
  * @param type $object
211
  * @param type $object_id
212
  * @return type
213
  */
214
  public function readOption($object, $object_id = '') {
215
  $option = get_user_option(
216
  $this->getOptionName($object, $object_id), $this->getId()
217
  );
218
  if (empty($option)) {
219
  //try to get this option from the User's Role
220
  $roles = $this->getSubject()->roles;
221
  //first user role is counted only. AAM does not support multi-roles
222
  $subject_role = array_shift($roles);
223
  //in case of multisite & current user does not belong to the site
224
  if ($subject_role){
225
  $role = new aam_Control_Subject_Role($subject_role);
226
  $option = $role->getObject($object, $object_id)->getOption();
227
  }
228
  }
229
  return $option;
230
  }
231
  /**
232
  *
233
  * @param type $object
234
  * @param type $object_id
235
  * @return type
236
  */
237
  public function deleteOption($object, $object_id = '') {
238
  return delete_user_option(
239
  $this->getId(), $this->getOptionName($object, $object_id)
240
  );
241
  }
242
  /**
243
  *
244
  * @param type $object
245
  * @param type $object_id
246
  * @return type
247
  */
248
  protected function getOptionName($object, $object_id) {
249
  return "aam_{$object}" . ($object_id ? "_{$object_id}" : '');
250
  }
251
  /**
252
  *
253
  * @return type
254
  */
255
  public function getUID() {
256
  return self::UID;
257
  }
1
+ <?php
2
  * ======================================================================
3
  * LICENSE: This file is subject to the terms and conditions defined in *
4
  * file 'license.txt', which is part of this source code package. *
5
  * ======================================================================
6
  */
7
  *
8
  * @package AAM
9
  * @author Vasyl Martyniuk <support@wpaam.com>
10
  * @copyright Copyright C 2013 Vasyl Martyniuk
11
  * @license GNU General Public License {@link http://www.gnu.org/licenses/}
12
  */
13
  /**
14
  * Subject UID: USER
15
  */
16
  const UID = 'user';
17
 
18
  /**
19
  * AAM Capability Key
20
  *
21
  * WordPress does not allow to have different set of capabilities for one user
22
  * between sites. aam_capability key stores the set of capabilities stored after
23
  * individual user edit and merge them with system capabilities.
24
  * The merging process overwrites allcaps.
25
  *
26
  * @var array
27
  *
28
  * @access private
29
  */
30
  private $_cap_key = '';
31
  /**
32
  *
33
  * @param type $id
34
  */
35
  public function __construct($id) {
36
  parent::__construct($id);
37
 
38
  //initialize list of capabilities
39
  //$this->getObject(aam_Control_Object_Capability::UID);
40
 
41
  //overwrite default set of capabilities if AAM capset is defined
42
  if ($this->isDefaultCapSet() === false){
43
  //make sure that aam_capability is actually array
44
  if (is_array($this->getSubject()->aam_caps)){
45
  $allcaps = array_merge(
46
  $this->getSubject()->allcaps, $this->getSubject()->aam_caps
47
  );
48
  $this->getSubject()->allcaps = $allcaps;
49
  }
50
  }
51
  }
52
  /**
53
  *
54
  * @return type
55
  */
56
  public function delete() {
57
  $response = false;
58
  if (current_user_can('delete_users')
59
  && ($this->getId() !== get_current_user_id())) {
60
  $response = wp_delete_user($this->getId());
61
  }
62
  return $response;
63
  }
64
  /**
65
  *
66
  * @global type $wpdb
67
  * @return boolean
68
  */
69
  public function block() {
70
  global $wpdb;
71
  $response = false;
72
  if (current_user_can('edit_users')
73
  && ($this->getId() != get_current_user_id())) {
74
  $status = ($this->getSubject()->user_status == 0 ? 1 : 0);
75
  if ($wpdb->update(
76
  $wpdb->users,
77
  array('user_status' => $status),
78
  array('ID' => $this->getId())
79
  )) {
80
  $this->getSubject()->user_status = $status;
81
  clean_user_cache($this->getSubject());
82
  $response = true;
83
  }
84
  }
85
  return $response;
86
  }
87
  /**
88
  * Retrieve User based on ID
89
  *
90
  * @return WP_Role|null
91
  *
92
  * @access protected
93
  */
94
  protected function retrieveSubject() {
95
  global $current_user;
96
  if ($current_user instanceof WP_User && $current_user->ID == $this->getId()) {
97
  $subject = $current_user;
98
  } else {
99
  $subject = new WP_User($this->getId());
100
  }
101
 
102
  //retrieve aam capabilities
103
  $this->_cap_key = 'aam_capability';
104
  $subject->aam_caps = get_user_option($this->_cap_key, $this->getId());
105
 
106
  return $subject;
107
  }
108
 
109
  /**
110
  * Check if user has default capability set
111
  *
112
  * @return boolean
113
  *
114
  * @access public
115
  */
116
  public function isDefaultCapSet(){
117
  return empty($this->getSubject()->aam_caps);
118
  }
119
  /**
120
  *
121
  * @return type
122
  */
123
  public function getCapabilities() {
124
  return $this->getSubject()->allcaps;
125
  }
126
  /**
127
  *
128
  * @param type $capability
129
  * @return type
130
  */
131
  public function hasCapability($capability) {
132
  return user_can($this->getSubject(), $capability);
133
  }
134
 
135
  /**
136
  * Check if Subject has capability
137
  *
138
  * Keep compatible with WordPress core
139
  *
140
  * @param string $capability
141
  *
142
  * @return boolean
143
  *
144
  * @access public
145
  */
146
  public function addCapability($capability) {
147
  return $this->updateCapability($capability, true);
148
  }
149
  /**
150
  * Remove Capability
151
  *
152
  * @param string $capability
153
  *
154
  * @return boolean
155
  *
156
  * @access public
157
  */
158
  public function removeCapability($capability) {
159
  return $this->updateCapability($capability, false);
160
  }
161
 
162
  /**
163
  * Reset User Capability
164
  *
165
  * @return array
166
  *
167
  * @access public
168
  */
169
  public function resetCapability(){
170
  return delete_user_option($this->getId(), $this->_cap_key);
171
  }
172
 
173
  /**
174
  * Update User's Capability Set
175
  *
176
  * @param string $capability
177
  * @param boolean $grand
178
  *
179
  * @return boolean
180
  *
181
  * @access public
182
  */
183
  public function updateCapability($capability, $grand){
184
  //make sure that we have right array
185
  if (is_array($this->getSubject()->aam_caps)){
186
  $aam_caps = $this->getSubject()->aam_caps;
187
  } else {
188
  $aam_caps = array();
189
  }
190
 
191
  //add capability
192
  $aam_caps[$capability] = $grand;
193
  //update user data. TODO - Keep eyes on this part
194
  $this->getSubject()->data->aam_caps = $aam_caps;
195
  //save and return the result of operation
196
  return update_user_option($this->getId(), $this->_cap_key, $aam_caps);
197
  }
198
  /**
199
  *
200
  * @param type $value
201
  * @param type $object
202
  * @param type $object_id
203
  * @return type
204
  */
205
  public function updateOption($value, $object, $object_id = '') {
206
  return update_user_option(
207
  $this->getId(), $this->getOptionName($object, $object_id), $value
208
  );
209
  }
210
  /**
211
  *
212
  * @param type $object
213
  * @param type $object_id
214
  * @return type
215
  */
216
  public function readOption($object, $object_id = '') {
217
  $option = get_user_option(
218
  $this->getOptionName($object, $object_id), $this->getId()
219
  );
220
  if (empty($option)) {
221
  //try to get this option from the User's Role
222
  $roles = $this->getSubject()->roles;
223
  //first user role is counted only. AAM does not support multi-roles
224
  $subject_role = array_shift($roles);
225
  //in case of multisite & current user does not belong to the site
226
  if ($subject_role){
227
  $role = new aam_Control_Subject_Role($subject_role);
228
  $option = $role->getObject($object, $object_id)->getOption();
229
  }
230
  }
231
  return $option;
232
  }
233
  /**
234
  *
235
  * @param type $object
236
  * @param type $object_id
237
  * @return type
238
  */
239
  public function deleteOption($object, $object_id = '') {
240
  return delete_user_option(
241
  $this->getId(), $this->getOptionName($object, $object_id)
242
  );
243
  }
244
  /**
245
  *
246
  * @param type $object
247
  * @param type $object_id
248
  * @return type
249
  */
250
  protected function getOptionName($object, $object_id) {
251
  return "aam_{$object}" . ($object_id ? "_{$object_id}" : '');
252
  }
253
  /**
254
  *
255
  * @return type
256
  */
257
  public function getUID() {
258
  return self::UID;
259
  }
application/control/subject/visitor.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_Control_Subject_Visitor extends aam_Control_Subject
17
+ {
18
+
19
+ /**
20
+ * Subject UID: VISITOR
21
+ */
22
+ const UID = 'visitor';
23
+
24
+ /**
25
+ * Constructor
26
+ *
27
+ * @param string|int $id
28
+ *
29
+ * @return void
30
+ *
31
+ * @access public
32
+ */
33
+ public function __construct($id) {
34
+ //run parent constructor
35
+ parent::__construct('');
36
+ }
37
+
38
+ /**
39
+ * Retrieve Visitor Subject
40
+ *
41
+ * @return stdClass
42
+ *
43
+ * @access protected
44
+ */
45
+ protected function retrieveSubject()
46
+ {
47
+ return new stdClass();
48
+ }
49
+
50
+ /**
51
+ *
52
+ * @return type
53
+ */
54
+ public function getCapabilities()
55
+ {
56
+ return array();
57
+ }
58
+
59
+ /**
60
+ *
61
+ * @param type $value
62
+ * @param type $object
63
+ * @param type $object_id
64
+ * @return type
65
+ */
66
+ public function updateOption($value, $object, $object_id = '')
67
+ {
68
+ return aam_Core_API::updateBlogOption(
69
+ $this->getOptionName($object, $object_id), $value
70
+ );
71
+ }
72
+
73
+ /**
74
+ *
75
+ * @param type $object
76
+ * @param type $object_id
77
+ * @return type
78
+ */
79
+ public function readOption($object, $object_id = '')
80
+ {
81
+ return aam_Core_API::getBlogOption(
82
+ $this->getOptionName($object, $object_id)
83
+ );
84
+ }
85
+
86
+ /**
87
+ *
88
+ * @param type $object
89
+ * @param type $object_id
90
+ * @return type
91
+ */
92
+ public function deleteOption($object, $object_id = '')
93
+ {
94
+ return aam_Core_API::deleteBlogOption(
95
+ $this->getOptionName($object, $object_id)
96
+ );
97
+ }
98
+
99
+ /**
100
+ *
101
+ * @param type $object
102
+ * @param type $object_id
103
+ * @return type
104
+ */
105
+ protected function getOptionName($object, $object_id)
106
+ {
107
+ return 'aam_' . self::UID . "_{$object}" . ($object_id ? "_{$object_id}" : '');
108
+ }
109
+
110
+ /**
111
+ *
112
+ * @return type
113
+ */
114
+ public function getUID()
115
+ {
116
+ return self::UID;
117
+ }
118
+
119
+ }
application/core/api.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ final class aam_Core_API {
18
+
19
+ /**
20
+ * Get current blog's option
21
+ *
22
+ * @param string $option
23
+ * @param mixed $default
24
+ * @param int $blog_id;
25
+ *
26
+ * @return mixed
27
+ *
28
+ * @access public
29
+ * @static
30
+ */
31
+ public static function getBlogOption($option, $default = FALSE, $blog_id = null) {
32
+ if (is_multisite()) {
33
+ $blog = (is_null($blog_id) ? get_current_blog_id() : $blog_id);
34
+ $response = get_blog_option($blog, $option, $default);
35
+ } else {
36
+ $response = get_option($option, $default);
37
+ }
38
+
39
+ return $response;
40
+ }
41
+
42
+ /**
43
+ * Update Blog Option
44
+ *
45
+ * @param string $option
46
+ * @param mixed $data
47
+ * @param int $blog_id
48
+ *
49
+ * @return bool
50
+ *
51
+ * @access public
52
+ * @static
53
+ */
54
+ public static function updateBlogOption($option, $data, $blog_id = null) {
55
+ if (is_multisite()) {
56
+ $blog = (is_null($blog_id) ? get_current_blog_id() : $blog_id);
57
+ $response = update_blog_option($blog, $option, $data);
58
+ } else {
59
+ $response = update_option($option, $data);
60
+ }
61
+
62
+ return $response;
63
+ }
64
+
65
+ /**
66
+ * Delete Blog Option
67
+ *
68
+ * @param string $option
69
+ * @param int $blog_id
70
+ *
71
+ * @return bool
72
+ *
73
+ * @access public
74
+ * @static
75
+ */
76
+ public static function deleteBlogOption($option, $blog_id = null) {
77
+ if (is_multisite()) {
78
+ $blog = (is_null($blog_id) ? get_current_blog_id() : $blog_id);
79
+ $response = delete_blog_option($blog, $option);
80
+ } else {
81
+ $response = delete_option($option);
82
+ }
83
+
84
+ return $response;
85
+ }
86
+
87
+ /**
88
+ * Initiate HTTP request
89
+ *
90
+ * @param string $url Requested URL
91
+ * @param bool $send_cookies Wheather send cookies or not
92
+ * @param bool $return_content Return content or not
93
+ * @return bool Always return TRUE
94
+ */
95
+ public static function cURL($url, $send_cookies = TRUE, $return_content = FALSE) {
96
+ $header = array(
97
+ 'User-Agent' => aam_Core_Request::server('HTTP_USER_AGENT')
98
+ );
99
+
100
+ $cookies = array();
101
+ if (is_array($_COOKIE) && $send_cookies) {
102
+ foreach ($_COOKIE as $key => $value) {
103
+ //SKIP PHPSESSID - some servers does not like it for security reason
104
+ if ($key !== 'PHPSESSID') {
105
+ $cookies[] = new WP_Http_Cookie(array(
106
+ 'name' => $key,
107
+ 'value' => $value
108
+ ));
109
+ }
110
+ }
111
+ }
112
+
113
+ $res = wp_remote_request($url, array(
114
+ 'headers' => $header,
115
+ 'cookies' => $cookies,
116
+ 'timeout' => 5)
117
+ );
118
+
119
+ if (is_wp_error($res)) {
120
+ $result = array(
121
+ 'status' => 'error',
122
+ 'url' => $url
123
+ );
124
+ } else {
125
+ $result = array('status' => 'success');
126
+ if ($return_content) {
127
+ $result['content'] = $res['body'];
128
+ }
129
+ }
130
+
131
+ return $result;
132
+ }
133
+
134
+ /**
135
+ * Check whether it is Multisite Network panel
136
+ *
137
+ * @return boolean
138
+ *
139
+ * @access public
140
+ */
141
+ public static function isNetworkPanel() {
142
+ return (is_multisite() && is_network_admin() ? TRUE : FALSE);
143
+ }
144
+
145
+ /**
146
+ * Check if SSL is used
147
+ *
148
+ * @return boolean
149
+ *
150
+ * @access public
151
+ * @static
152
+ */
153
+ public static function isSSL(){
154
+ if (force_ssl_admin()){
155
+ $response = true;
156
+ } elseif (aam_Core_Request::server('HTTPS')){
157
+ $response = true;
158
+ } elseif (aam_Core_Request::server('REQUEST_SCHEME') == 'https'){
159
+ $response = true;
160
+ } else {
161
+ $response = false;
162
+ }
163
+
164
+ return $response;
165
+ }
166
+
167
+ }
application/core/console.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_Core_Console {
17
+
18
+ /**
19
+ *
20
+ * @param type $message
21
+ */
22
+ public static function write($message) {
23
+ file_put_contents(
24
+ AAM_TEMP_DIR . '/console.log', $message . "\n", FILE_APPEND
25
+ );
26
+ }
27
+
28
+ }
application/core/extension.php ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class aam_Core_Extension {
18
+
19
+ /**
20
+ * Extensions download Failed
21
+ */
22
+ const STATUS_FAILED = 'failed';
23
+
24
+ /**
25
+ * Extensions status pending
26
+ */
27
+ const STATUS_PENDING = 'pending';
28
+
29
+ /**
30
+ * Extensions installed successfully
31
+ */
32
+ const STATUS_INSTALLED = 'installed';
33
+
34
+ /**
35
+ * Basedir to Extentions repository
36
+ *
37
+ * @var string
38
+ *
39
+ * @access private
40
+ */
41
+ private $_basedir = '';
42
+
43
+ /**
44
+ *
45
+ * @var type
46
+ */
47
+ private $_cache = array();
48
+
49
+ /**
50
+ * Main AAM class
51
+ *
52
+ * @var aam
53
+ *
54
+ * @access private
55
+ */
56
+ private $_parent;
57
+
58
+ /**
59
+ * Consturctor
60
+ *
61
+ * @return void
62
+ *
63
+ * @access public
64
+ */
65
+ public function __construct(aam $parent = null) {
66
+ $this->setParent($parent);
67
+ $this->_basedir = AAM_BASE_DIR . 'extension';
68
+ }
69
+
70
+ /**
71
+ * Load active extensions
72
+ *
73
+ * @return void
74
+ *
75
+ * @access public
76
+ */
77
+ public function load() {
78
+
79
+ //iterate through each active extension and load it
80
+ foreach (scandir($this->_basedir) as $module) {
81
+ if (!in_array($module, array('.', '..'))) {
82
+ $this->bootstrapExtension($module);
83
+ }
84
+ }
85
+ }
86
+
87
+ /**
88
+ *
89
+ */
90
+ public function download() {
91
+ $this->initFilesystem();
92
+ $repository = aam_Core_API::getBlogOption('aam_extensions', array(), 1);
93
+
94
+ if (is_array($repository)) {
95
+ //get the list of extensions
96
+ foreach ($repository as $extension => $data) {
97
+ if ($this->retrieve($data->license)) {
98
+ $repository[$extension]->status = self::STATUS_INSTALLED;
99
+ } else {
100
+ $repository[$extension]->status = self::STATUS_FAILED;
101
+ }
102
+ }
103
+ aam_Core_API::updateBlogOption('aam_extensions', $repository, 1);
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Add new extension to repository
109
+ *
110
+ * @param string $extension
111
+ * @param string $license
112
+ *
113
+ * @return boolean
114
+ *
115
+ * @access public
116
+ */
117
+ public function add($extension, $license){
118
+ $this->initFilesystem();
119
+ $repository = aam_Core_API::getBlogOption('aam_extensions', array(), 1);
120
+
121
+ if ($this->retrieve($license)){
122
+ $repository[$extension] = (object) array(
123
+ 'status' => self::STATUS_INSTALLED,
124
+ 'license' => $license,
125
+ //ugly way but quick
126
+ 'basedir' => $this->_basedir . '/' . str_replace(' ', '_', $extension)
127
+ );
128
+ aam_Core_API::updateBlogOption('aam_extensions', $repository, 1);
129
+ $response = true;
130
+ } else {
131
+ $response = false;
132
+ }
133
+
134
+ return $response;
135
+ }
136
+
137
+ /**
138
+ * Remove Extension from the repository
139
+ *
140
+ * @param string $extension
141
+ * @param string $license
142
+ *
143
+ * @return boolean
144
+ *
145
+ * @access public
146
+ */
147
+ public function remove($extension, $license){
148
+ global $wp_filesystem;
149
+
150
+ $this->initFilesystem();
151
+ $repository = aam_Core_API::getBlogOption('aam_extensions', array(), 1);
152
+ $response = false;
153
+
154
+ if (isset($repository[$extension])){
155
+ $basedir = $repository[$extension]->basedir;
156
+ if ($wp_filesystem->rmdir($basedir, true)){
157
+ $response = true;
158
+ unset($repository[$extension]);
159
+ aam_Core_API::updateBlogOption('aam_extensions', $repository, 1);
160
+ }
161
+ }
162
+
163
+ return $response;
164
+ }
165
+
166
+ /**
167
+ * Initialize WordPress filesystem
168
+ *
169
+ * @return void
170
+ *
171
+ * @access protected
172
+ */
173
+ protected function initFilesystem(){
174
+ require_once ABSPATH . 'wp-admin/includes/file.php';
175
+
176
+ //initialize Filesystem
177
+ WP_Filesystem();
178
+ }
179
+
180
+ /**
181
+ * Retrieve extension based on license key
182
+ *
183
+ * @global WP_Filesystem $wp_filesystem
184
+ * @param string $license
185
+ *
186
+ * @return boolean
187
+ *
188
+ * @access protected
189
+ */
190
+ protected function retrieve($license) {
191
+ global $wp_filesystem;
192
+
193
+ $url = WPAAM_REST_API . '?method=extension&license=' . $license;
194
+ $res = wp_remote_request($url, array('timeout' => 10));
195
+ $response = false;
196
+ if (!is_wp_error($res)) {
197
+ //write zip archive to the filesystem first
198
+ $zip = AAM_TEMP_DIR . '/' . uniqid();
199
+ $content = base64_decode($res['body']);
200
+ if ($content && $wp_filesystem->put_contents($zip, $content)) {
201
+ $response = $this->insert($zip);
202
+ $wp_filesystem->delete($zip);
203
+ }
204
+ }
205
+
206
+ return $response;
207
+ }
208
+
209
+ /**
210
+ *
211
+ * @param type $zip
212
+ * @return boolean
213
+ */
214
+ protected function insert($zip) {
215
+ $response = true;
216
+ if (is_wp_error(unzip_file($zip, $this->_basedir))) {
217
+ aam_Core_Console::write('Failed to insert extension');
218
+ $response = false;
219
+ }
220
+
221
+ return $response;
222
+ }
223
+
224
+ /**
225
+ * Bootstrap the Extension
226
+ *
227
+ * In case of any errors, the output can be found in console
228
+ *
229
+ * @param string $extension
230
+ *
231
+ * @return void
232
+ *
233
+ * @access protected
234
+ */
235
+ protected function bootstrapExtension($extension) {
236
+ $bootstrap = $this->_basedir . "/{$extension}/index.php";
237
+ if (file_exists($bootstrap) && !isset($this->_cache[$extension])) {
238
+ $this->_cache[$extension] = require_once($bootstrap);
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Set Parent class
244
+ *
245
+ * @param aam $parent
246
+ *
247
+ * @return void
248
+ *
249
+ * @access public
250
+ */
251
+ public function setParent($parent){
252
+ $this->_parent = $parent;
253
+ }
254
+
255
+ /**
256
+ * Get Parent class
257
+ *
258
+ * @return aam
259
+ *
260
+ * @access public
261
+ */
262
+ public function getParent(){
263
+ return $this->_parent;
264
+ }
265
+
266
+ }
application/core/migrate.php ADDED
@@ -0,0 +1,479 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ * Migrate the setting to 2.x version
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <support@wpaam.com>
15
+ * @copyright Copyright C 2013 Vasyl Martyniuk
16
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
17
+ */
18
+ final class aam_Core_Migrate {
19
+
20
+ /**
21
+ * Run the migration process
22
+ *
23
+ * @return string
24
+ *
25
+ * @access public
26
+ */
27
+ public function run() {
28
+ @set_time_limit(300);
29
+
30
+ ob_start(); //prevent from any kind of notice, warning printout
31
+ switch (aam_Core_Request::post('step')) {
32
+ case 'collect':
33
+ $response = $this->collect();
34
+ break;
35
+
36
+ case 'migrate':
37
+ $response = $this->migrate();
38
+ break;
39
+
40
+ case 'cleanup':
41
+ $response = $this->cleanup();
42
+ break;
43
+
44
+ case 'complete':
45
+ $response = $this->complete();
46
+ break;
47
+
48
+ default:
49
+ $response = array('status' => 'failure');
50
+ break;
51
+ }
52
+ ob_end_clean();
53
+
54
+ return json_encode($response);
55
+ }
56
+
57
+ /**
58
+ * Collect the list of all setting for migration
59
+ *
60
+ * @global type $wpdb
61
+ * @return string
62
+ */
63
+ protected function collect() {
64
+ global $wpdb;
65
+
66
+ $collection = array(
67
+ 'users' => array(),
68
+ 'roles' => array()
69
+ );
70
+ aam_Core_API::deleteBlogOption('aam_migration_cache');
71
+
72
+ //====== collect all user individual settings ======
73
+ $query = 'SELECT * FROM ' . $wpdb->usermeta;
74
+ $query .= ' WHERE meta_key = "wpaccess_config"';
75
+ $user_list = $wpdb->get_results($query);
76
+ if (count($user_list)) {
77
+ foreach ($user_list as $user) {
78
+ $collection['users'][$user->user_id] = $user->meta_value;
79
+ }
80
+ }
81
+
82
+ //====== collect all roles settings =======
83
+ if (is_multisite()) {
84
+ //get all sites first and iterate through each
85
+ $query = 'SELECT blog_id FROM ' . $wpdb->blogs;
86
+ $blog_list = $wpdb->get_results($query);
87
+ if (is_array($blog_list)) {
88
+ foreach ($blog_list as $blog) {
89
+ $collection['roles'][$blog->blog_id] = $this->getRoleSet(
90
+ $blog->blog_id
91
+ );
92
+ }
93
+ }
94
+ } else {
95
+ $collection['roles'] = $this->getRoleSet();
96
+ }
97
+
98
+ //save the cache for wether migration process
99
+ if (aam_Core_API::updateBlogOption('aam_migration_cache', $collection, 1)) {
100
+ $response = array('status' => 'success', 'stop' => 1);
101
+ } else {
102
+ $response = array('status' => 'failure');
103
+ }
104
+
105
+ return $response;
106
+ }
107
+
108
+ protected function getRoleSet($blog_id = 1) {
109
+ global $wpdb;
110
+
111
+ $role_set = array();
112
+ $blog_prefix = $wpdb->get_blog_prefix($blog_id);
113
+ //get list of roles for current blog
114
+ $query = 'SELECT * FROM ' . $blog_prefix . 'options ';
115
+ $query .= 'WHERE option_name = "' . $blog_prefix . 'user_roles"';
116
+ if ($row = $wpdb->get_row($query)) {
117
+ $user_roles = unserialize($row->option_value);
118
+ if (is_array($user_roles)) {
119
+ foreach ($user_roles as $role => $data) {
120
+ $query = 'SELECT option_value FROM ' . $blog_prefix . 'options ';
121
+ $query .= 'WHERE option_name = "' . $blog_prefix . 'wpaccess_config_' . $role . '"';
122
+ $role_set[$role] = $wpdb->get_var($query);
123
+ }
124
+ }
125
+ }
126
+
127
+ return $role_set;
128
+ }
129
+
130
+ protected function migrate() {
131
+ $response = array('status' => 'success', 'stop' => 1);
132
+ //get the settings
133
+ $collection = aam_Core_API::getBlogOption('aam_migration_cache', 1);
134
+
135
+ if (is_array($collection)) {
136
+ if (isset($collection['users'])) {
137
+ $this->migrateUsers($collection);
138
+ }
139
+
140
+ if (isset($collection['roles'])) {
141
+ $this->migrateRoles($collection);
142
+ }
143
+ }
144
+
145
+ return $response;
146
+ }
147
+
148
+ protected function migrateSettings($settings) {
149
+ $migrated = array();
150
+ $legacy = unserialize($settings);
151
+ if ($legacy instanceof stdClass) {
152
+ if (isset($legacy->menu)) {
153
+ $migrated['menu'] = $this->migrateMenu($legacy->menu);
154
+ }
155
+ if (isset($legacy->metaboxes)) {
156
+ $migrated['metabox'] = $this->migrateMetaboxes(
157
+ $legacy->metaboxes
158
+ );
159
+ }
160
+ if (isset($legacy->capabilities)) {
161
+ $migrated['capability'] = $this->migrateCapabilities(
162
+ $legacy->capabilities
163
+ );
164
+ }
165
+ if (isset($legacy->restrictions)) {
166
+ $migrated['restrictions'] = $this->migrateRestrictions(
167
+ $legacy->restrictions
168
+ );
169
+ }
170
+ if (isset($legacy->events)) {
171
+ $migrated['events'] = $this->migrateEvents($legacy->events);
172
+ }
173
+ }
174
+
175
+ return $migrated;
176
+ }
177
+
178
+ protected function migrateMenu($legacy) {
179
+ $menu = array();
180
+
181
+ if (is_array($legacy)) {
182
+ foreach ($legacy as $id => $data) {
183
+ if (isset($data['whole']) && intval($data['whole'])) {
184
+ $menu[$id] = 1;
185
+ }
186
+ if (isset($data['sub']) && is_array($data['sub'])) {
187
+ foreach ($data['sub'] as $sub_id => $sub_data) {
188
+ if (intval($sub_data)) {
189
+ $menu[$sub_id] = 1;
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
195
+
196
+ return $menu;
197
+ }
198
+
199
+ protected function migrateMetaboxes($legacy) {
200
+ $metaboxes = array();
201
+ if (is_array($legacy)) {
202
+ foreach ($legacy as $id => $checked) {
203
+ if (intval($checked)) {
204
+ $chunks = explode('-', $id);
205
+ if (count($chunks) == 1) { //widgets
206
+ if (!isset($metaboxes['widgets'])) {
207
+ $metaboxes['widgets'] = array();
208
+ }
209
+ $metaboxes['widgets'][$chunks[0]] = 1;
210
+ } elseif (count($chunks) == 2) {
211
+ if (!isset($metaboxes[$chunks[0]])) {
212
+ $metaboxes[$chunks[0]] = array();
213
+ }
214
+ $metaboxes[$chunks[0]][$chunks[1]] = 1;
215
+ }
216
+ }
217
+ }
218
+ }
219
+
220
+ return $metaboxes;
221
+ }
222
+
223
+ protected function migrateCapabilities($capabilities) {
224
+ return (is_array($capabilities) && count($capabilities) ? $capabilities : array());
225
+ }
226
+
227
+ protected function migrateRestrictions($legacy) {
228
+ $access = array(
229
+ 'post' => array(),
230
+ 'taxonomy' => array()
231
+ );
232
+ if (is_array($legacy)) {
233
+ foreach ($legacy as $type => $records) {
234
+ if (is_array($records)) {
235
+ foreach ($records as $id => $restrictions) {
236
+ $access[$type][$id] = array(
237
+ 'frontend' => array(),
238
+ 'backend' => array()
239
+ );
240
+ foreach ($restrictions as $restriction => $checked) {
241
+ if (intval($checked)) {
242
+ $chunks = explode('_', $restriction);
243
+ if ($type == 'taxonomy') {
244
+ $access[$type][$id][$chunks[0]][$chunks[1]] = 1;
245
+ } elseif ($type == 'post') {
246
+ $access[$type][$id][$chunks[0]][$chunks[2]] = 1;
247
+ }
248
+ }
249
+ }
250
+ }
251
+ }
252
+ }
253
+ }
254
+
255
+ return $access;
256
+ }
257
+
258
+ protected function migrateEvents($legacy) {
259
+ $events = array();
260
+
261
+ if (is_array($legacy)) {
262
+ foreach ($legacy as $event_id => $data) {
263
+ $events[$event_id] = array();
264
+ if (isset($data['eventType'])) {
265
+ $events[$event_id]['event'] = $data['eventType'];
266
+ }
267
+ if (isset($data['statusChange'])) {
268
+ $events[$event_id]['event_specifier'] = $data['statusChange'];
269
+ }
270
+ if (isset($data['postType'])) {
271
+ $events[$event_id]['post_type'] = $data['postType'];
272
+ }
273
+ if (isset($data['eventAction'])) {
274
+ //fix type from previos version
275
+ if ($data['eventAction'] === 'change_satus') {
276
+ $action = 'change_status';
277
+ } else {
278
+ $action = $data['eventAction'];
279
+ }
280
+ $events[$event_id]['action'] = $action;
281
+ }
282
+ if (!empty($data['eventEmail'])) {
283
+ $events[$event_id]['action_specifier'] = $data['eventEmail'];
284
+ } elseif (!empty($data['statusChangeTo'])) {
285
+ $events[$event_id]['action_specifier'] = $data['statusChangeTo'];
286
+ } elseif (!empty($data['callback'])) {
287
+ $events[$event_id]['action_specifier'] = $data['callback'];
288
+ }
289
+ }
290
+ }
291
+
292
+ return $events;
293
+ }
294
+
295
+ protected function migrateUsers(&$collection) {
296
+ if (is_array($collection['users'])) {
297
+ foreach ($collection['users'] as $id => $data) {
298
+ $migrated = $this->migrateSettings($data);
299
+ //unset restrictions, bad implementation in AAM 1.x
300
+ if (isset($migrated['restrictions'])) {
301
+ unset($migrated['restrictions']);
302
+ }
303
+
304
+ $this->saveSettings('User', $id, $migrated);
305
+ }
306
+ }
307
+
308
+ return 'success';
309
+ }
310
+
311
+ protected function migrateRoles(&$collection) {
312
+ global $wpdb, $wp_user_roles, $blog_id;
313
+
314
+ if (is_multisite()) {
315
+ foreach ($collection['roles'] as $blog_id => $roles) {
316
+ //reset roles & blog id
317
+ $wp_user_roles = null;
318
+ $wpdb->set_blog_id($blog_id);
319
+ foreach ($roles as $role => $data) {
320
+ $this->migrateRole($role, $data, $blog_id);
321
+ }
322
+ }
323
+ } else {
324
+ foreach ($collection['roles'] as $role => $data) {
325
+ $this->migrateRole($role, $data);
326
+ }
327
+ }
328
+ }
329
+
330
+ protected function migrateRole($role, $data) {
331
+ if ($role !== 'administrator'){ //skip admin role. We do not have super admin anymore
332
+ $settings = $this->migrateSettings($data);
333
+ } elseif (isset($data['events'])) { //transfer only events
334
+ $settings = array('events' => $data['events']);
335
+ } else {
336
+ $settings = array();
337
+ }
338
+
339
+ return $this->saveSettings('Role', $role, $settings);
340
+ }
341
+
342
+ protected function saveSettings($type, $id, $settings) {
343
+ if (is_array($settings) && count($settings)) {
344
+ $subject_class = 'aam_Control_Subject_' . $type;
345
+ $subject = new $subject_class($id);
346
+ //set new settings
347
+ //Dashboard Menu settings
348
+ if (isset($settings['menu']) && count($settings['menu'])) {
349
+ $subject->getObject(aam_Control_Object_Menu::UID)->save(
350
+ $settings['menu']
351
+ );
352
+ }
353
+ //Dashboard Metaboxes & Widgets
354
+ if (isset($settings['metabox']) && count($settings['metabox'])) {
355
+ $subject->getObject(aam_Control_Object_Metabox::UID)->save(
356
+ $settings['metabox']
357
+ );
358
+ }
359
+ //Capability list
360
+ if (isset($settings['capability']) && count($settings['capability'])) {
361
+ foreach ($settings['capability'] as $capability => $grand) {
362
+ if (intval($grand)) {
363
+ $subject->addCapability($capability);
364
+ } else {
365
+ $subject->removeCapability($capability);
366
+ }
367
+ }
368
+ }
369
+ //Posts & Categories
370
+ if (isset($settings['restrictions']) && count($settings['restrictions'])) {
371
+ if (count($settings['restrictions']['post'])) {
372
+ $post = $subject->getObject(aam_Control_Object_Post::UID);
373
+ foreach ($settings['restrictions']['post'] as $post_id => $data) {
374
+ $post->setOption(null); //clean up for next iteration
375
+ $post->init($post_id);
376
+ if (@$post->getPost()->ID) {
377
+ $post->save(array('post' => $data));
378
+ }
379
+ }
380
+ }
381
+
382
+ if (count($settings['restrictions']['taxonomy'])) {
383
+ $term = $subject->getObject(aam_Control_Object_Term::UID);
384
+ foreach ($settings['restrictions']['taxonomy'] as $term_id => $data) {
385
+ $term->setOption(null);
386
+ $term->init($term_id);
387
+ if (@$term->getTerm()->term_id) {
388
+ $term->save(array('term' => $data));
389
+ }
390
+ }
391
+ }
392
+ }
393
+
394
+ //Events
395
+ if (isset($settings['events']) && count($settings['events'])) {
396
+ $subject->getObject(aam_Control_Object_Event::UID)->save(
397
+ $settings['events']
398
+ );
399
+ }
400
+ }
401
+ }
402
+
403
+ protected function cleanup() {
404
+ $this->removeSuperAdmin();
405
+
406
+ //remove migration cache
407
+ aam_Core_API::deleteBlogOption('aam_migration_cache', 1);
408
+
409
+ return array('status' => 'success', 'stop' => 1);
410
+ }
411
+
412
+ protected function removeSuperAdmin() {
413
+ global $wp_user_roles, $wpdb;
414
+
415
+ if (is_multisite()) {
416
+ //get all sites first and iterate through each
417
+ $query = 'SELECT blog_id FROM ' . $wpdb->blogs;
418
+ $blog_list = $wpdb->get_results($query);
419
+ if (is_array($blog_list)) {
420
+ foreach ($blog_list as $blog) {
421
+ //reset roles & blog id
422
+ $wp_user_roles = null;
423
+ $wpdb->set_blog_id($blog_id);
424
+ $this->removeSuperAdminRole();
425
+ }
426
+ }
427
+ } else {
428
+ $this->removeSuperAdminRole();
429
+ }
430
+ //remove all super_admin capabilities from usermeta
431
+ $list = $wpdb->get_results(
432
+ 'SELECT * FROM ' . $wpdb->usermeta . ' WHERE meta_key LIKE "%_capabilities"'
433
+ );
434
+ if (is_array($list)) {
435
+ foreach ($list as $metadata) {
436
+ $caps = unserialize($metadata->meta_value);
437
+ if (isset($caps['super_admin'])) {
438
+ unset($caps['super_admin']);
439
+ $caps['administrator'] = 1;
440
+ $wpdb->update(
441
+ $wpdb->usermeta,
442
+ array('meta_value' => serialize($caps)),
443
+ array('umeta_id' => $metadata->umeta_id)
444
+ );
445
+ }
446
+ }
447
+ }
448
+ }
449
+
450
+ protected function removeSuperAdminRole() {
451
+ //update the role capabilities and remove super admin role
452
+ $roles = new WP_Roles();
453
+ //get all capabilities first and merge them in one array
454
+ $capabilities = array();
455
+ foreach ($roles->role_objects as $role) {
456
+ $capabilities = array_merge($capabilities, $role->capabilities);
457
+ }
458
+
459
+ if (count($capabilities)) {
460
+ //update administrator capability role
461
+ if ($admin = $roles->get_role('administrator')) {
462
+ foreach ($capabilities as $capability => $grand) {
463
+ $admin->add_cap($capability);
464
+ }
465
+ } else {
466
+ $roles->add_role('administrator', 'Administrator', $capabilities);
467
+ }
468
+ //remove Super Admin Role
469
+ $roles->remove_role('super_admin');
470
+ }
471
+ }
472
+
473
+ protected function complete() {
474
+ aam_Core_API::updateBlogOption('aam_migrated', 1, 1);
475
+
476
+ return array('status' => 'success', 'stop' => 1);
477
+ }
478
+
479
+ }
application/core/request.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_Core_Request {
17
+
18
+ /**
19
+ * Get parameter from global _GET array
20
+ *
21
+ * @param string $param GET Parameter
22
+ * @param mixed $default Default value
23
+ *
24
+ * @return mixed
25
+ *
26
+ * @access public
27
+ */
28
+ public static function get($param = null, $default = null) {
29
+ return self::readArray($_GET, $param, $default);
30
+ }
31
+
32
+ /**
33
+ * Get parameter from global _POST array
34
+ *
35
+ * @param string $param POST Parameter
36
+ * @param mixed $default Default value
37
+ *
38
+ * @return mixed
39
+ *
40
+ * @access public
41
+ */
42
+ public static function post($param = null, $default = null) {
43
+ return self::readArray($_POST, $param, $default);
44
+ }
45
+
46
+ /**
47
+ * Get parameter from global _REQUEST array
48
+ *
49
+ * @param string $param REQUEST Parameter
50
+ * @param mixed $default Default value
51
+ *
52
+ * @return mixed
53
+ *
54
+ * @access public
55
+ * @static
56
+ */
57
+ public static function request($param = null, $default = null) {
58
+ return self::readArray($_REQUEST, $param, $default);
59
+ }
60
+
61
+ /**
62
+ * Get parameter from global _SERVER array
63
+ *
64
+ * @param string $param SERVER Parameter
65
+ * @param mixed $default Default value
66
+ *
67
+ * @return mixed
68
+ *
69
+ * @access public
70
+ * @static
71
+ */
72
+ public static function server($param = null, $default = null) {
73
+ return self::readArray($_SERVER, $param, $default);
74
+ }
75
+
76
+ /**
77
+ * Check array for specified parameter and return the it's value or
78
+ * default one
79
+ *
80
+ * @param array &$array Global array _GET, _POST etc
81
+ * @param string $param Array Parameter
82
+ * @param mixed $default Default value
83
+ *
84
+ * @return mixed
85
+ *
86
+ * @access protected
87
+ * @static
88
+ */
89
+ protected static function readArray(&$array, $param, $default) {
90
+ $value = $default;
91
+ if (is_null($param)) {
92
+ $value = $array;
93
+ } else {
94
+ $chunks = explode('.', $param);
95
+ $value = $array;
96
+ foreach ($chunks as $chunk) {
97
+ if (isset($value[$chunk])) {
98
+ $value = $value[$chunk];
99
+ } else {
100
+ $value = $default;
101
+ break;
102
+ }
103
+ }
104
+ }
105
+
106
+ return $value;
107
+ }
108
+
109
+ }
application/core/update.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ final class aam_Core_Update {
18
+
19
+ /**
20
+ * List of stages
21
+ *
22
+ * @var array
23
+ *
24
+ * @access private
25
+ */
26
+ private $_stages = array();
27
+
28
+ /**
29
+ * Constructoor
30
+ *
31
+ * @return void
32
+ *
33
+ * @access public
34
+ */
35
+ public function __construct() {
36
+ //register update stages
37
+ $this->_stages = apply_filters('aam_update_stages', array(
38
+ array($this, 'downloadRepository'),
39
+ array($this, 'removeUpdate')
40
+ ));
41
+ }
42
+
43
+ /**
44
+ * Run the update if necessary
45
+ *
46
+ * @return void
47
+ *
48
+ * @access public
49
+ */
50
+ public function run() {
51
+ foreach ($this->_stages as $stage) {
52
+ //break the change if any stage failed
53
+ if (call_user_func($stage) === false) {
54
+ break;
55
+ }
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Download the Extension Repository
61
+ *
62
+ * This forces the system to retrieve the new set of extensions based on
63
+ * license key
64
+ *
65
+ * @return boolean
66
+ *
67
+ * @access public
68
+ */
69
+ public function downloadRepository() {
70
+ $response = true;
71
+ if ($extensions = aam_Core_API::getBlogOption('aam_extensions')) {
72
+ if (is_array($extensions)){
73
+ $extension = new aam_Core_Extension();
74
+ $extension->download();
75
+ }
76
+ }
77
+
78
+ return $response;
79
+ }
80
+
81
+ /**
82
+ * Remove the update file
83
+ *
84
+ * This will stop to run the update again
85
+ *
86
+ * @return boolean
87
+ *
88
+ * @access public
89
+ */
90
+ public function removeUpdate() {
91
+ return rename(__FILE__, dirname(__FILE__) . '/__' . basename(__FILE__));
92
+ }
93
+
94
+ }
application/view/abstract.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ abstract class aam_View_Abstract {
17
+
18
+ /**
19
+ *
20
+ * @var type
21
+ */
22
+ static private $_subject = null;
23
+
24
+ /**
25
+ *
26
+ */
27
+ public function __construct() {
28
+ if (is_null(self::$_subject)) {
29
+ $subject_class = 'aam_Control_Subject_' . ucfirst(
30
+ trim(aam_Core_Request::request('subject'), '')
31
+ );
32
+ if (class_exists($subject_class)){
33
+ $this->setSubject(new $subject_class(
34
+ aam_Core_Request::request('subject_id')
35
+ ));
36
+ }
37
+ }
38
+ }
39
+
40
+ /**
41
+ *
42
+ * @return type
43
+ */
44
+ public function getSubject() {
45
+ return self::$_subject;
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param aam_Control_Subject $subject
51
+ */
52
+ public function setSubject(aam_Control_Subject $subject) {
53
+ self::$_subject = $subject;
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @param type $tmpl_path
59
+ * @return type
60
+ */
61
+ public function loadTemplate($tmpl_path) {
62
+ ob_start();
63
+ require_once($tmpl_path);
64
+ $content = ob_get_contents();
65
+ ob_end_clean();
66
+
67
+ return $content;
68
+ }
69
+
70
+ }
application/view/ajax.php ADDED
@@ -0,0 +1,520 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ * Ajax Call router
11
+ *
12
+ * Based on sub_action prepare and runs proper model
13
+ *
14
+ * @package AAM
15
+ * @author Vasyl Martyniuk <support@wpaam.com>
16
+ * @copyright Copyright C 2013 Vasyl Martyniuk
17
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
18
+ */
19
+ class aam_View_Ajax extends aam_View_Abstract{
20
+
21
+ /**
22
+ * Process the ajax call
23
+ *
24
+ * @return string
25
+ *
26
+ * @access public
27
+ */
28
+ public function run() {
29
+ switch (aam_Core_Request::request('sub_action')) {
30
+ case 'role_list':
31
+ $response = $this->retrieveRoleList();
32
+ break;
33
+
34
+ case 'user_list':
35
+ $response = $this->retrieveUserList();
36
+ break;
37
+
38
+ case 'add_role':
39
+ $response = $this->addRole();
40
+ break;
41
+
42
+ case 'edit_role':
43
+ $response = $this->editRole();
44
+ break;
45
+
46
+ case 'delete_role':
47
+ $response = $this->deleteRole();
48
+ break;
49
+
50
+ case 'block_user':
51
+ $response = $this->blockUser();
52
+ break;
53
+
54
+ case 'delete_user':
55
+ $response = $this->deleteUser();
56
+ break;
57
+
58
+ case 'load_metaboxes':
59
+ $response = $this->loadMetaboxes();
60
+ break;
61
+
62
+ case 'init_link':
63
+ $response = $this->initLink();
64
+ break;
65
+
66
+ case 'load_capabilities':
67
+ $response = $this->loadCapabilities();
68
+ break;
69
+
70
+ case 'role_capabilities':
71
+ $response = $this->getRoleCapabilities();
72
+ break;
73
+
74
+ case 'add_capability':
75
+ $response = $this->addCapability();
76
+ break;
77
+
78
+ case 'delete_capability':
79
+ $response = $this->deleteCapability();
80
+ break;
81
+
82
+ case 'restore_capability':
83
+ $response = $this->restoreCapability();
84
+ break;
85
+
86
+ case 'post_type_list':
87
+ $response = $this->getPostTypeList();
88
+ break;
89
+
90
+ case 'post_list':
91
+ $response = $this->getPostList();
92
+ break;
93
+
94
+ case 'post_tree':
95
+ $response = $this->getPostTree();
96
+ break;
97
+
98
+ case 'post_breadcrumb':
99
+ $response = $this->generatePostBreadcrumb();
100
+ break;
101
+
102
+ case 'save_access':
103
+ $response = $this->saveAccess();
104
+ break;
105
+
106
+ case 'get_access':
107
+ $response = $this->getAccess();
108
+ break;
109
+
110
+ case 'clear_access':
111
+ $response = $this->clearAccess();
112
+ break;
113
+
114
+ case 'event_list':
115
+ $response = $this->getEventList();
116
+ break;
117
+
118
+ case 'save':
119
+ $response = $this->save();
120
+ break;
121
+
122
+ case 'check_roleback':
123
+ $response = $this->checkRoleback();
124
+ break;
125
+
126
+ case 'roleback':
127
+ $response = $this->roleback();
128
+ break;
129
+
130
+ case 'install_extension':
131
+ $response = $this->installExtension();
132
+ break;
133
+
134
+ case 'remove_extension':
135
+ $response = $this->removeExtension();
136
+ break;
137
+
138
+ //TODO - Remove in 07/15/2014
139
+ case 'migrate':
140
+ $response = $this->migrate();
141
+ break;
142
+
143
+ default:
144
+ $response = apply_filters(
145
+ 'aam_ajax_call', -1, $this->getSubject()
146
+ );
147
+ break;
148
+ }
149
+
150
+ return $response;
151
+ }
152
+
153
+ /**
154
+ * Retrieve Available for Editing Role List
155
+ *
156
+ * @return string
157
+ *
158
+ * @access protected
159
+ */
160
+ protected function retrieveRoleList() {
161
+ $model = new aam_View_Role;
162
+
163
+ return $model->retrieveList();
164
+ }
165
+
166
+ /**
167
+ * Retrieve Available User List
168
+ *
169
+ * @return string
170
+ *
171
+ * @access protected
172
+ */
173
+ protected function retrieveUserList() {
174
+ $model = new aam_View_User;
175
+
176
+ return $model->retrieveList();
177
+ }
178
+
179
+ /**
180
+ * Add New Role
181
+ *
182
+ * @return string
183
+ *
184
+ * @access protected
185
+ */
186
+ protected function addRole() {
187
+ $model = new aam_View_Role;
188
+
189
+ return $model->add();
190
+ }
191
+
192
+ /**
193
+ * Edit Existing Role
194
+ *
195
+ * @return string
196
+ *
197
+ * @access protected
198
+ */
199
+ protected function editRole() {
200
+ $model = new aam_View_Role;
201
+
202
+ return $model->edit();
203
+ }
204
+
205
+ /**
206
+ * Delete Existing Role
207
+ *
208
+ * @return string
209
+ *
210
+ * @access protected
211
+ */
212
+ protected function deleteRole() {
213
+ $model = new aam_View_Role;
214
+
215
+ return $model->delete();
216
+ }
217
+
218
+ /**
219
+ * Block Selected User
220
+ *
221
+ * @return string
222
+ *
223
+ * @access protected
224
+ */
225
+ protected function blockUser() {
226
+ $model = new aam_View_User;
227
+
228
+ return $model->block();
229
+ }
230
+
231
+ /**
232
+ * Delete Selected User
233
+ *
234
+ * @return string
235
+ *
236
+ * @access protected
237
+ */
238
+ protected function deleteUser() {
239
+ $model = new aam_View_User;
240
+
241
+ return $model->delete();
242
+ }
243
+
244
+ /**
245
+ * Load List of Metaboxes
246
+ *
247
+ * @return string
248
+ *
249
+ * @access protected
250
+ */
251
+ protected function loadMetaboxes() {
252
+ $model = new aam_View_Metabox;
253
+
254
+ return $model->retrieveList();
255
+ }
256
+
257
+ /**
258
+ * Initialize list of metaboxes from individual link
259
+ *
260
+ * @return string
261
+ *
262
+ * @access protected
263
+ */
264
+ protected function initLink() {
265
+ $model = new aam_View_Metabox;
266
+
267
+ return $model->initLink();
268
+ }
269
+
270
+ /**
271
+ * Load list of capabilities
272
+ *
273
+ * @return string
274
+ *
275
+ * @access protected
276
+ */
277
+ protected function loadCapabilities() {
278
+ $model = new aam_View_Capability;
279
+
280
+ return $model->retrieveList();
281
+ }
282
+
283
+ /**
284
+ * Get list of Capabilities by selected Role
285
+ *
286
+ * @return string
287
+ *
288
+ * @access protected
289
+ */
290
+ protected function getRoleCapabilities() {
291
+ $model = new aam_View_Capability;
292
+
293
+ return $model->retrieveRoleCapabilities();
294
+ }
295
+
296
+ /**
297
+ * Add New Capability
298
+ *
299
+ * @return string
300
+ *
301
+ * @access protected
302
+ */
303
+ protected function addCapability() {
304
+ $model = new aam_View_Capability;
305
+
306
+ return $model->addCapability();
307
+ }
308
+
309
+ /**
310
+ * Delete Capability
311
+ *
312
+ * @return string
313
+ *
314
+ * @access protected
315
+ */
316
+ protected function deleteCapability() {
317
+ $model = new aam_View_Capability;
318
+
319
+ return $model->deleteCapability();
320
+ }
321
+
322
+ /**
323
+ * Restore Capabilities
324
+ *
325
+ * @return string
326
+ *
327
+ * @access protected
328
+ */
329
+ protected function restoreCapability() {
330
+ $model = new aam_View_Capability;
331
+
332
+ return $model->restoreCapability();
333
+ }
334
+
335
+ /**
336
+ * Get the list of Post Types
337
+ *
338
+ * This is used for Post & Term Access Feature
339
+ *
340
+ * @return string
341
+ *
342
+ * @access protected
343
+ */
344
+ protected function getPostTypeList() {
345
+ $model = new aam_View_Post;
346
+
347
+ return $model->retrievePostTypeList();
348
+ }
349
+
350
+ /**
351
+ * Get the List of Posts
352
+ *
353
+ * @return string
354
+ *
355
+ * @access protected
356
+ */
357
+ protected function getPostList() {
358
+ $model = new aam_View_Post;
359
+
360
+ return $model->retrievePostList();
361
+ }
362
+
363
+ /**
364
+ * Get Post Tree
365
+ *
366
+ * @return string
367
+ *
368
+ * @access protected
369
+ */
370
+ protected function getPostTree() {
371
+ $model = new aam_View_Post;
372
+
373
+ return $model->getPostTree();
374
+ }
375
+
376
+ /**
377
+ * Save Access settings for Post or Term
378
+ *
379
+ * @return string
380
+ *
381
+ * @access protected
382
+ */
383
+ protected function saveAccess() {
384
+ $model = new aam_View_Post();
385
+
386
+ return $model->saveAccess();
387
+ }
388
+
389
+ /**
390
+ * Get Access settings for Post or Term
391
+ *
392
+ * @return string
393
+ *
394
+ * @access protected
395
+ */
396
+ protected function getAccess() {
397
+ $model = new aam_View_Post();
398
+
399
+ return $model->getAccess();
400
+ }
401
+
402
+ /**
403
+ * Restore default access level for Post or Term
404
+ *
405
+ * @return string
406
+ *
407
+ * @access protected
408
+ */
409
+ protected function clearAccess() {
410
+ $model = new aam_View_Post();
411
+
412
+ return $model->clearAccess();
413
+ }
414
+
415
+ /**
416
+ * Prepare and generate the post breadcrumb
417
+ *
418
+ * @return string
419
+ *
420
+ * @access protected
421
+ */
422
+ protected function generatePostBreadcrumb() {
423
+ $model = new aam_View_Post;
424
+
425
+ return $model->getPostBreadcrumb();
426
+ }
427
+
428
+ /**
429
+ * Get Event List
430
+ *
431
+ * @return string
432
+ *
433
+ * @access protected
434
+ */
435
+ protected function getEventList() {
436
+ $model = new aam_View_Event;
437
+
438
+ return $model->retrieveEventList();
439
+ }
440
+
441
+ /**
442
+ * Save AAM settings
443
+ *
444
+ * @return string
445
+ *
446
+ * @access protected
447
+ */
448
+ protected function save() {
449
+ $model = new aam_View_Manager;
450
+
451
+ return $model->save();
452
+ }
453
+
454
+ /**
455
+ * Roleback the changes
456
+ *
457
+ * @return string
458
+ *
459
+ * @access protected
460
+ */
461
+ protected function roleback() {
462
+ $model = new aam_View_Manager;
463
+
464
+ return $model->roleback();
465
+ }
466
+
467
+ /**
468
+ * Check whether roleback action can be performed
469
+ *
470
+ * @return string
471
+ *
472
+ * @access protected
473
+ */
474
+ protected function checkRoleback() {
475
+ $model = new aam_View_Manager;
476
+
477
+ return $model->checkRoleback();
478
+ }
479
+
480
+ /**
481
+ * Install extension
482
+ *
483
+ * @return string
484
+ *
485
+ * @access protected
486
+ */
487
+ protected function installExtension() {
488
+ $model = new aam_View_Extension();
489
+
490
+ return $model->install();
491
+ }
492
+
493
+ /**
494
+ * Remove extension
495
+ *
496
+ * @return string
497
+ *
498
+ * @access protected
499
+ */
500
+ protected function removeExtension() {
501
+ $model = new aam_View_Extension();
502
+
503
+ return $model->remove();
504
+ }
505
+
506
+ /**
507
+ * Migrate
508
+ *
509
+ * @return string
510
+ *
511
+ * @access protected
512
+ * @todo Remove in 07/15/2014
513
+ */
514
+ protected function migrate() {
515
+ $model = new aam_Core_Migrate();
516
+
517
+ return $model->run();
518
+ }
519
+
520
+ }
application/view/capability.php ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_View_Capability extends aam_View_Abstract {
17
+
18
+ /**
19
+ *
20
+ * @var type
21
+ */
22
+ private $_groups = array(
23
+ 'system' => array(
24
+ 'level_0', 'level_1', 'level_2', 'level_3', 'level_4', 'level_5',
25
+ 'level_6', 'level_7', 'level_8', 'level_9', 'level_10'
26
+ ),
27
+ 'post' => array(
28
+ 'delete_others_pages', 'delete_others_posts', 'delete_pages',
29
+ 'delete_posts', 'delete_private_pages', 'delete_private_posts',
30
+ 'delete_published_pages', 'delete_published_posts', 'edit_others_pages',
31
+ 'edit_others_posts', 'edit_pages', 'edit_private_posts',
32
+ 'edit_private_pages', 'edit_posts', 'edit_published_pages',
33
+ 'edit_published_posts', 'publish_pages', 'publish_posts', 'read',
34
+ 'read_private_pages', 'read_private_posts', 'edit_permalink'
35
+ ),
36
+ 'backend' => array(
37
+ 'aam_manage', 'activate_plugins', 'add_users', 'create_users',
38
+ 'delete_users', 'delete_themes', 'edit_dashboard', 'edit_files',
39
+ 'edit_plugins', 'edit_theme_options', 'edit_themes', 'edit_users',
40
+ 'export', 'import', 'install_plugins', 'install_themes', 'list_users',
41
+ 'manage_options', 'manage_links', 'manage_categories', 'promote_users',
42
+ 'unfiltered_html', 'unfiltered_upload', 'update_themes', 'update_plugins',
43
+ 'update_core', 'upload_files', 'delete_plugins', 'remove_users',
44
+ 'switch_themes'
45
+ )
46
+ );
47
+
48
+ /**
49
+ *
50
+ * @return type
51
+ */
52
+ public function retrieveList() {
53
+ $response = array(
54
+ 'aaData' => array(),
55
+ 'aaDefault' => 1 //Default set of Capabilities indicator
56
+ );
57
+
58
+ $subject = $this->getSubject();
59
+ $roles = new WP_Roles();
60
+ if ($subject->getUID() === aam_Control_Subject_Role::UID) {
61
+ //prepare list of all capabilities
62
+ $caps = array();
63
+ foreach ($roles->role_objects as $role) {
64
+ $caps = array_merge($caps, $role->capabilities);
65
+ }
66
+ //init all caps
67
+ foreach ($caps as $capability => $grant) {
68
+ $response['aaData'][] = array(
69
+ $capability,
70
+ ($subject->hasCapability($capability) ? 1 : 0),
71
+ $this->getGroup($capability),
72
+ $this->getHumanText($capability),
73
+ ''
74
+ );
75
+ }
76
+ } else {
77
+ $role_list = $subject->roles;
78
+ $role = $roles->get_role(array_shift($role_list));
79
+ foreach ($role->capabilities as $capability => $grant) {
80
+ $response['aaData'][] = array(
81
+ $capability,
82
+ ($subject->hasCapability($capability) ? 1 : 0),
83
+ $this->getGroup($capability),
84
+ $this->getHumanText($capability),
85
+ ''
86
+ );
87
+ $response['aaDefault'] = ($subject->isDefaultCapSet() ? 1 : 0);
88
+ }
89
+ }
90
+
91
+ return json_encode($response);
92
+ }
93
+
94
+ /**
95
+ *
96
+ * @return type
97
+ */
98
+ public function getGroupList(){
99
+ return apply_filters('aam_capability_groups', array(
100
+ __('System', 'aam'),
101
+ __('Post & Page', 'aam'),
102
+ __('Backend Interface', 'aam'),
103
+ __('Miscellaneous', 'aam')
104
+ ));
105
+ }
106
+
107
+ /**
108
+ *
109
+ * @return type
110
+ */
111
+ public function retrieveRoleCapabilities() {
112
+ return json_encode(array(
113
+ 'status' => 'success',
114
+ 'capabilities' => $this->getSubject()->getCapabilities()
115
+ ));
116
+ }
117
+
118
+ /**
119
+ *
120
+ * @return type
121
+ */
122
+ public function addCapability() {
123
+ $roles = new WP_Roles();
124
+ $capability = trim(aam_Core_Request::post('capability'));
125
+
126
+ if ($capability) {
127
+ $normalized = str_replace(' ', '_', strtolower($capability));
128
+ //add the capability to administrator's role as default behavior
129
+ $roles->add_cap('administrator', $normalized);
130
+ $response = array('status' => 'success', 'capability' => $normalized);
131
+ } else {
132
+ $response = array('status' => 'failure');
133
+ }
134
+
135
+ return json_encode($response);
136
+ }
137
+
138
+ /**
139
+ *
140
+ * @return type
141
+ */
142
+ public function deleteCapability() {
143
+ $roles = new WP_Roles();
144
+ $capability = trim(aam_Core_Request::post('capability'));
145
+
146
+ if ($capability) {
147
+ foreach ($roles->role_objects as $role) {
148
+ $role->remove_cap($capability);
149
+ }
150
+ $response = array('status' => 'success');
151
+ } else {
152
+ $response = array('status' => 'failure');
153
+ }
154
+
155
+ return json_encode($response);
156
+ }
157
+
158
+ /**
159
+ * Restore default user capabilities
160
+ *
161
+ * @return string
162
+ *
163
+ * @access public
164
+ */
165
+ public function restoreCapability(){
166
+ $subject = $this->getSubject();
167
+ $response = array('status' => 'failure');
168
+ if (($subject->getUID() == aam_Control_Subject_User::UID)
169
+ && $subject->resetCapability()){
170
+ $response['status'] = 'success';
171
+ }
172
+
173
+ return json_encode($response);
174
+ }
175
+
176
+ /**
177
+ *
178
+ * @param type $text
179
+ * @return type
180
+ */
181
+ protected function getHumanText($text) {
182
+ $parts = preg_split('/_/', $text);
183
+ if (is_array($parts)) {
184
+ foreach ($parts as &$part) {
185
+ $part = ucfirst($part);
186
+ }
187
+ }
188
+
189
+ return implode(' ', $parts);
190
+ }
191
+
192
+ /**
193
+ *
194
+ * @param type $capability
195
+ * @return type
196
+ */
197
+ protected function getGroup($capability) {
198
+ if (in_array($capability, $this->_groups['system'])) {
199
+ $response = __('System', 'aam');
200
+ } elseif (in_array($capability, $this->_groups['post'])) {
201
+ $response = __('Post & Page', 'aam');
202
+ } elseif (in_array($capability, $this->_groups['backend'])) {
203
+ $response = __('Backend Interface', 'aam');
204
+ } else {
205
+ $response = __('Miscellaneous', 'aam');
206
+ }
207
+
208
+ return apply_filters('aam_capability_group', $response, $capability);
209
+ }
210
+
211
+ /**
212
+ *
213
+ * @return type
214
+ */
215
+ public function content() {
216
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/capability.phtml');
217
+ }
218
+
219
+ }
application/view/configpress.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_View_ConfigPress extends aam_View_Abstract
17
+ {
18
+
19
+ /**
20
+ *
21
+ * @return type
22
+ */
23
+ public function content()
24
+ {
25
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/configpress.phtml');
26
+ }
27
+
28
+ }
application/view/event.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_View_Event extends aam_View_Abstract {
17
+
18
+ /**
19
+ *
20
+ * @return type
21
+ */
22
+ public function retrieveEventList() {
23
+ $response = array('aaData' => array());
24
+ foreach ($this->getSubject()->getObject(aam_Control_Object_Event::UID)->getOption() as $event) {
25
+ $response['aaData'][] = array(
26
+ $event['event'],
27
+ $event['event_specifier'],
28
+ $event['post_type'],
29
+ $event['action'],
30
+ $event['action_specifier'],
31
+ ''
32
+ );
33
+ }
34
+
35
+ return json_encode($response);
36
+ }
37
+
38
+ /**
39
+ *
40
+ * @global type $wp_post_statuses
41
+ * @return type
42
+ */
43
+ public function getPostStatuses() {
44
+ global $wp_post_statuses;
45
+
46
+ return $wp_post_statuses;
47
+ }
48
+
49
+ /**
50
+ *
51
+ * @global type $wp_post_types
52
+ * @return type
53
+ */
54
+ public function getPostTypes() {
55
+ global $wp_post_types;
56
+
57
+ return $wp_post_types;
58
+ }
59
+
60
+ /**
61
+ *
62
+ * @return type
63
+ */
64
+ public function content() {
65
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/event.phtml');
66
+ }
67
+
68
+ }
application/view/extension.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_View_Extension extends aam_View_Abstract {
17
+
18
+ /**
19
+ * Extensions Repository
20
+ *
21
+ * @var array
22
+ *
23
+ * @access private
24
+ */
25
+ private $_repository = array();
26
+
27
+ /**
28
+ * Constructor
29
+ *
30
+ * The filter "aam_cpanel" can be used to control the Control Panel items.
31
+ *
32
+ * @return void
33
+ *
34
+ * @access public
35
+ */
36
+ public function __construct() {
37
+ parent::__construct();
38
+
39
+ //get repository
40
+ $repository = aam_Core_API::getBlogOption('aam_extensions', array(), 1);
41
+ if (is_array($repository)){
42
+ $this->_repository = $repository;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Install extension
48
+ *
49
+ * @return string
50
+ *
51
+ * @access public
52
+ */
53
+ public function install(){
54
+ $extension = new aam_Core_Extension;
55
+ $license = aam_Core_Request::post('license');
56
+ $ext = aam_Core_Request::post('extension');
57
+
58
+ if ($license && $extension->add($ext, $license)){
59
+ $response = array('status' => 'success');
60
+ } else {
61
+ $response = array('status' => 'failure');
62
+ }
63
+
64
+ return json_encode($response);
65
+ }
66
+
67
+ /**
68
+ * Remove extension
69
+ *
70
+ * @return string
71
+ *
72
+ * @access public
73
+ */
74
+ public function remove(){
75
+ $extension = new aam_Core_Extension;
76
+ $license = aam_Core_Request::post('license');
77
+ $ext = aam_Core_Request::post('extension');
78
+
79
+ if ($extension && $extension->remove($ext, $license)){
80
+ $response = array('status' => 'success');
81
+ } else {
82
+ $response = array('status' => 'failure');
83
+ }
84
+
85
+ return json_encode($response);
86
+ }
87
+
88
+ /**
89
+ * Run the Manager
90
+ *
91
+ * @return string
92
+ *
93
+ * @access public
94
+ */
95
+ public function run() {
96
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/extension.phtml');
97
+ }
98
+
99
+ /**
100
+ * Check if extensions exists
101
+ *
102
+ * @param string $extension
103
+ *
104
+ * @return boolean
105
+ *
106
+ * @access public
107
+ */
108
+ public function hasExtension($extension){
109
+ return (isset($this->_repository[$extension]) ? true : false);
110
+ }
111
+
112
+ /**
113
+ * Get Extension
114
+ *
115
+ * @param string $extension
116
+ *
117
+ * @return stdClass
118
+ *
119
+ * @access public
120
+ */
121
+ public function getExtension($extension){
122
+ return ($this->hasExtension($extension) ? $this->_repository[$extension] : new stdClass);
123
+ }
124
+
125
+ }
application/view/manager.php ADDED
@@ -0,0 +1,380 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_View_Manager extends aam_View_Abstract {
17
+
18
+ /**
19
+ *
20
+ * @var type
21
+ */
22
+ private $_cmanager = array();
23
+
24
+ /**
25
+ *
26
+ * @var type
27
+ */
28
+ private $_features = array();
29
+
30
+ /**
31
+ * Constructor
32
+ *
33
+ * The filter "aam_cpanel" can be used to control the Control Panel items.
34
+ *
35
+ * @return void
36
+ *
37
+ * @access public
38
+ */
39
+ public function __construct() {
40
+ parent::__construct();
41
+
42
+ $this->setCManager(
43
+ apply_filters('aam_ui_subjects', $this->getDefaultSubjects())
44
+ );
45
+ $this->setFeatures(
46
+ apply_filters('aam_ui_features', $this->getDefaultFeatures())
47
+ );
48
+ }
49
+
50
+ /**
51
+ *
52
+ * @return type
53
+ */
54
+ protected function getDefaultSubjects() {
55
+ return array(
56
+ 'roles' => array(
57
+ 'position' => 5,
58
+ 'segment' => 'role',
59
+ 'label' => __('Roles', 'aam'),
60
+ 'title' => __('Role Manager', 'aam'),
61
+ 'class' => 'manager-item manager-item-role',
62
+ 'id' => 'aam_role',
63
+ 'content' => array(new aam_View_Role(), 'content')
64
+ ),
65
+ 'users' => array(
66
+ 'position' => 10,
67
+ 'segment' => 'user',
68
+ 'label' => __('Users', 'aam'),
69
+ 'title' => __('User Manager', 'aam'),
70
+ 'class' => 'manager-item manager-item-user',
71
+ 'id' => 'aam_user',
72
+ 'content' => array(new aam_View_User(), 'content')
73
+ ),
74
+ 'visitor' => array(
75
+ 'position' => 15,
76
+ 'segment' => 'visitor',
77
+ 'label' => __('Visitor', 'aam'),
78
+ 'title' => __('Visitor Manager', 'aam'),
79
+ 'class' => 'manager-item manager-item-visitor',
80
+ 'id' => 'aam_visitor',
81
+ 'content' => array(new aam_View_Visitor(), 'content')
82
+ )
83
+ );
84
+ }
85
+
86
+ /**
87
+ *
88
+ * @return type
89
+ */
90
+ protected function getDefaultFeatures() {
91
+ return array(
92
+ 'admin_menu' => array(
93
+ 'id' => 'admin_menu',
94
+ 'position' => 5,
95
+ 'title' => __('Admin Menu', 'aam'),
96
+ 'anonimus' => false,
97
+ 'content' => array(new aam_View_Menu(), 'content'),
98
+ 'help' => __('Control Access to Admin Menu. Restrict access to entire Menu or Submenu. <b>Notice</b>, the menu is rendered based on Role\'s or User\'s capabilities.', 'aam')
99
+ ),
100
+ 'metabox' => array(
101
+ 'id' => 'metabox',
102
+ 'position' => 10,
103
+ 'title' => __('Metabox & Widget', 'aam'),
104
+ 'anonimus' => true,
105
+ 'content' => array(new aam_View_Metabox(), 'content'),
106
+ 'help' => __('Filter the list of Metaboxes or Widgets for selected Role or User. If metabox or widget is not listed, try to click <b>Refresh the List</b> button or Copy & Paste direct link to page where specific metabox or widget is shown and hit <b>Retrieve Metaboxes from Link</b> button.', 'aam')
107
+ ),
108
+ 'capability' => array(
109
+ 'id' => 'capability',
110
+ 'position' => 15,
111
+ 'title' => __('Capability', 'aam'),
112
+ 'anonimus' => false,
113
+ 'content' => array(new aam_View_Capability(), 'content'),
114
+ 'help' => __('Manage the list of Capabilities for selected User or Role. <b>Notice</b>, list of user\'s capabilities are inherited from user\'s Role.<br/><b>Warning!</b> Be very careful with capabilities. Deleting or unchecking any capability may cause temporary or permanent constrol lost over some features or WordPress dashboard.', 'aam')
115
+ ),
116
+ 'post_access' => array(
117
+ 'id' => 'post_access',
118
+ 'position' => 20,
119
+ 'title' => __('Posts & Categories', 'aam'),
120
+ 'anonimus' => true,
121
+ 'content' => array(new aam_View_Post(), 'content'),
122
+ 'help' => __('Manage access to individual <b>Post</b> or <b>Term</b>. Notice, under <b>Post</b>, we assume any post, page or custom post type. And under <b>Term</b> - any term like Post Categories.', 'aam')
123
+ ),
124
+ 'event_manager' => array(
125
+ 'id' => 'event_manager',
126
+ 'position' => 25,
127
+ 'title' => __('Event Manager', 'aam'),
128
+ 'anonimus' => false,
129
+ 'content' => array(new aam_View_Event(), 'content'),
130
+ 'help' => __('Define your own action when some event appeared in your WordPress blog. This sections allows you to trigger an action on event like post content change, or page status update. You can setup to send email notification, change the post status or write your own custom event handler.', 'aam')
131
+ ),
132
+ 'config_press' => array(
133
+ 'id' => 'configpress',
134
+ 'position' => 30,
135
+ 'title' => __('ConfigPress', 'aam'),
136
+ 'anonimus' => true,
137
+ 'content' => array(new aam_View_ConfigPress(), 'content'),
138
+ 'help' => __('Control <b>AAM</b> behavior with ConfigPress. For more details please check <b>ConfigPress tutorial</b>.', 'aam')
139
+ )
140
+ );
141
+ }
142
+
143
+ /**
144
+ * Set Control Panel items
145
+ *
146
+ * @param array $cpanel
147
+ *
148
+ * @return void
149
+ *
150
+ * @access public
151
+ */
152
+ public function setCManager(array $cmanager) {
153
+ $final = array();
154
+ foreach ($cmanager as $item) {
155
+ if (!isset($final[$item['position']])) {
156
+ $final[$item['position']] = $item;
157
+ } else {
158
+ aam_Extension_Console::log(
159
+ "Control Manager position {$item['position']} reserved already"
160
+ );
161
+ }
162
+ }
163
+ ksort($final);
164
+
165
+ $this->_cmanager = $final;
166
+ }
167
+
168
+ /**
169
+ * Get Control Panel items
170
+ *
171
+ * @return array
172
+ *
173
+ * @access public
174
+ */
175
+ public function getCManager() {
176
+ return $this->_cmanager;
177
+ }
178
+
179
+ /**
180
+ *
181
+ * @param type $list
182
+ */
183
+ public function setFeatures($list) {
184
+ $final = array();
185
+ foreach ($list as $item) {
186
+ if (!isset($final[$item['position']])) {
187
+ $final[$item['position']] = $item;
188
+ } else {
189
+ aam_Extension_Console::log(
190
+ "Feature position {$item['position']} reserved already"
191
+ );
192
+ }
193
+ }
194
+ ksort($final);
195
+
196
+ $this->_features = $final;
197
+ }
198
+
199
+ /**
200
+ *
201
+ * @return type
202
+ */
203
+ public function getFeatures() {
204
+ return $this->_features;
205
+ }
206
+
207
+ /**
208
+ * Run the Manager
209
+ *
210
+ * @return string
211
+ *
212
+ * @access public
213
+ */
214
+ public function run() {
215
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/manager.phtml');
216
+ }
217
+
218
+ /**
219
+ *
220
+ * @return type
221
+ */
222
+ public function isVisitor() {
223
+ return ($this->getSubject()->getUID() === 'visitor' ? true : false);
224
+ }
225
+
226
+ /**
227
+ *
228
+ */
229
+ public function retrieveFeatures() {
230
+ ?>
231
+ <div class="aam-help">
232
+ <?php
233
+ foreach ($this->getFeatures() as $feature) {
234
+ if (!$this->isVisitor() || $feature['anonimus']) {
235
+ echo '<span id="feature_help_' . $feature['id'] . '">', $feature['help'], '</span>';
236
+ }
237
+ }
238
+ ?>
239
+ </div>
240
+ <div class="feature-list">
241
+ <?php
242
+ foreach ($this->getFeatures() as $feature) {
243
+ if (!$this->isVisitor() || $feature['anonimus']) {
244
+ echo '<div class="feature-item" feature="' . $feature['id'] . '">';
245
+ echo '<span>' . $feature['title'] . '</span></div>';
246
+ }
247
+ }
248
+ ?>
249
+ </div>
250
+ <div class="feature-content">
251
+ <?php
252
+ foreach ($this->getFeatures() as $feature) {
253
+ if (!$this->isVisitor() || $feature['anonimus']) {
254
+ echo call_user_func($feature['content']);
255
+ }
256
+ }
257
+ ?>
258
+ </div>
259
+ <br class="clear" />
260
+ <?php
261
+ do_action('aam_retrieve_features');
262
+ }
263
+
264
+ /**
265
+ *
266
+ * @return type
267
+ */
268
+ public function save() {
269
+ $this->getSubject()->save(
270
+ $this->prepareSaveOptions(aam_Core_Request::post('aam'))
271
+ );
272
+ return json_encode(array('status' => 'success'));
273
+ }
274
+
275
+ /**
276
+ *
277
+ * @param type $options
278
+ * @return type
279
+ */
280
+ protected function prepareSaveOptions($options) {
281
+ //make sure that some parts are always in place
282
+ if (!isset($options[aam_Control_Object_Menu::UID])) {
283
+ $options[aam_Control_Object_Menu::UID] = array();
284
+ }
285
+ if (!isset($options[aam_Control_Object_Metabox::UID])) {
286
+ $options[aam_Control_Object_Metabox::UID] = array();
287
+ }
288
+ if (!isset($options[aam_Control_Object_Event::UID])) {
289
+ $options[aam_Control_Object_Event::UID] = array();
290
+ }
291
+
292
+ return apply_filters('aam_prepare_option_list', $options);
293
+ }
294
+
295
+ /**
296
+ *
297
+ * @return type
298
+ */
299
+ public function roleback() {
300
+ $params = $this->getSubject()->getObject(
301
+ aam_Control_Object_Backup::UID)->roleback();
302
+
303
+ $this->getSubject()->save($this->prepareSaveOptions($params));
304
+
305
+ return json_encode(
306
+ array(
307
+ 'status' => 'success',
308
+ 'more' => intval(
309
+ $this->getSubject()->getObject(
310
+ aam_Control_Object_Backup::UID)->has()
311
+ )
312
+ )
313
+ );
314
+ }
315
+
316
+ /**
317
+ *
318
+ * @return type
319
+ */
320
+ public function checkRoleback() {
321
+ return json_encode(
322
+ array(
323
+ 'status' => intval($this->getSubject()->getObject(
324
+ aam_Control_Object_Backup::UID)->has()
325
+ )
326
+ )
327
+ );
328
+ }
329
+
330
+ /**
331
+ *
332
+ * @return type
333
+ */
334
+ public static function uiLabels(){
335
+ return apply_filters('aam_localization_labels', array(
336
+ 'Rollback Settings' => __('Rollback Settings', 'aam'),
337
+ 'Cancel' => __('Cancel', 'aam'),
338
+ 'Send E-mail' => __('Send E-mail', 'aam'),
339
+ 'Add New Role' => __('Add New Role', 'aam'),
340
+ 'Manage' => __('Manage', 'aam'),
341
+ 'Edit' => __('Edit', 'aam'),
342
+ 'Delete' => __('Delete', 'aam'),
343
+ 'Filtered' => __('Filtered', 'aam'),
344
+ 'Clear' => __('Clear', 'aam'),
345
+ 'Add New Role' => __('Add New Role', 'aam'),
346
+ 'Save Changes' => __('Save Changes', 'aam'),
347
+ 'Delete Role with Users Message' => __('System detected %d user(s) with this role. All Users with Role <b>%s</b> will be deleted automatically!', 'aam'),
348
+ 'Delete Role Message' => __('Are you sure that you want to delete role <b>%s</b>?', 'aam'),
349
+ 'Delete Role' => __('Delete Role', 'aam'),
350
+ 'Add User' => __('Add User', 'aam'),
351
+ 'Filter Users' => __('Filter Users', 'aam'),
352
+ 'Refresh List' => __('Refresh List', 'aam'),
353
+ 'Block' => __('Block', 'aam'),
354
+ 'Delete User Message' => __('Are you sure you want to delete user <b>%s</b>?', 'aam'),
355
+ 'Filter Capabilities by Category' => __('Filter Capabilities by Category', 'aam'),
356
+ 'Inherit Capabilities' => __('Inherit Capabilities', 'aam'),
357
+ 'Add New Capability' => __('Add New Capability', 'aam'),
358
+ 'Delete Capability Message' => __('Are you sure that you want to delete capability <b>%s</b>?', 'aam'),
359
+ 'Delete Capability' => __('Delete Capability', 'aam'),
360
+ 'Select Role' => __('Select Role', 'aam'),
361
+ 'Add Capability' => __('Add Capability', 'aam'),
362
+ 'Add Event' => __('Add Event', 'aam'),
363
+ 'Edit Event' => __('Edit Event', 'aam'),
364
+ 'Delete Event' => __('Delete Event', 'aam'),
365
+ 'Save Event' => __('Save Event', 'aam'),
366
+ 'Delete Event' => __('Delete Event', 'aam'),
367
+ 'Filter Posts by Post Type' => __('Filter Posts by Post Type', 'aam'),
368
+ 'Refresh List' => __('Refresh List', 'aam'),
369
+ 'Restore Default' => __('Restore Default', 'aam'),
370
+ 'Apply' => __('Apply', 'aam'),
371
+ 'Edit Term' => __('Edit Term', 'aam'),
372
+ 'Manager Access' => __('Manager Access', 'aam'),
373
+ 'Unlock Default Accesss Control' => __('Unlock Default Accesss Control', 'aam'),
374
+ 'Close' => __('Close', 'aam'),
375
+ 'Edit Role' => __('Edit Role', 'aam'),
376
+ 'Restore Default Capabilities' => __('Restore Default Capabilities', 'aam')
377
+ ));
378
+ }
379
+
380
+ }
application/view/menu.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_View_Menu extends aam_View_Abstract {
17
+
18
+ /**
19
+ *
20
+ * @return type
21
+ */
22
+ public function content() {
23
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/menu.phtml');
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @global type $menu
29
+ * @global type $submenu
30
+ * @return type
31
+ */
32
+ public function getMenu() {
33
+ global $menu;
34
+
35
+ $response = array();
36
+
37
+ //let's create menu list with submenus
38
+ foreach ($menu as $menu_item) {
39
+ if (!preg_match('/^separator/', $menu_item[2])) {
40
+ $submenu = $this->getSubmenu($menu_item[2]);
41
+ $remove = !$this->getSubject()->hasCapability($menu_item[1]);
42
+ if (($remove === false) || (count($submenu) !== 0)) {
43
+ $item = array(
44
+ 'name' => $this->removeHTML($menu_item[0]),
45
+ 'id' => $menu_item[2],
46
+ 'submenu' => $submenu
47
+ );
48
+ $response[] = $item;
49
+ }
50
+ }
51
+ }
52
+
53
+ return $response;
54
+ }
55
+
56
+ /**
57
+ * Prepare filtered submenu
58
+ *
59
+ * @global array $submenu
60
+ * @param string $menu
61
+ *
62
+ * @return array
63
+ *
64
+ * @access public
65
+ */
66
+ public function getSubmenu($menu) {
67
+ global $submenu;
68
+
69
+ $filtered_submenu = array();
70
+ if (isset($submenu[$menu])) {
71
+ foreach ($submenu[$menu] as $submenu_item) {
72
+ if ($this->getSubject()->hasCapability($submenu_item[1]) !== false) {
73
+ //prepare title
74
+ $submenu_title = $this->removeHTML($submenu_item[0]);
75
+ if (strlen($submenu_title) > 18) {
76
+ $submenu_short = substr($submenu_title, 0, 15) . '..';
77
+ } else {
78
+ $submenu_short = $submenu_title;
79
+ }
80
+
81
+ $filtered_submenu[] = array(
82
+ 'name' => $submenu_title,
83
+ 'short' => $submenu_short,
84
+ 'id' => $submenu_item[2]
85
+ );
86
+ }
87
+ }
88
+ }
89
+
90
+ return $filtered_submenu;
91
+ }
92
+
93
+ /**
94
+ * Check if the entire branch is restricted
95
+ *
96
+ * @param array $menu
97
+ *
98
+ * @return boolean
99
+ *
100
+ * @access public
101
+ */
102
+ public function hasRestrictedAll($menu){
103
+ $menuControl = $this->getSubject()->getObject(aam_Control_Object_Menu::UID);
104
+ $response = $menuControl->has($menu['id']);
105
+
106
+ foreach($menu['submenu'] as $submenu){
107
+ if ($menuControl->has($submenu['id']) === false){
108
+ $response = false;
109
+ break;
110
+ }
111
+ }
112
+
113
+ return $response;
114
+ }
115
+
116
+ /**
117
+ *
118
+ * @param type $text
119
+ * @return type
120
+ */
121
+ public function removeHTML($text) {
122
+ // Return clean content
123
+ return strip_tags($text);
124
+ }
125
+
126
+ }
application/view/metabox.php ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class aam_View_Metabox extends aam_View_Abstract {
18
+
19
+ /**
20
+ * Metabox Group - WIDGETS
21
+ *
22
+ * Is used to retrieve the list of all wigets on the frontend
23
+ */
24
+ const GROUP_WIDGETS = 'widgets';
25
+
26
+ /**
27
+ *
28
+ * @var type
29
+ */
30
+ private $_cache = array();
31
+
32
+ /**
33
+ *
34
+ * @global type $wp_meta_boxes
35
+ * @param type $post_type
36
+ */
37
+ public function run($post_type) {
38
+ $this->_cache = aam_Core_API::getBlogOption(
39
+ 'aam_metabox_cache', array()
40
+ );
41
+
42
+ if ($post_type === '') {
43
+ $this->collectWidgets();
44
+ } else {
45
+ $this->collectMetaboxes($post_type);
46
+ }
47
+ aam_Core_API::updateBlogOption('aam_metabox_cache', $this->_cache);
48
+ }
49
+
50
+ /**
51
+ *
52
+ * @global type $wp_registered_widgets
53
+ */
54
+ protected function collectWidgets() {
55
+ global $wp_registered_widgets;
56
+
57
+ if (!isset($this->_cache['widgets'])) {
58
+ $this->_cache['widgets'] = array();
59
+ }
60
+
61
+ //get frontend widgets
62
+ if (is_array($wp_registered_widgets)) {
63
+ foreach ($wp_registered_widgets as $id => $data) {
64
+ if (is_object($data['callback'][0])) {
65
+ $callback = get_class($data['callback'][0]);
66
+ } elseif (is_string($data['callback'][0])) {
67
+ $callback = $data['callback'][0];
68
+ } else {
69
+ $callback = null;
70
+ }
71
+
72
+ if (!is_null($callback)) { //exclude any junk
73
+ $this->_cache['widgets'][$callback] = array(
74
+ 'title' => $this->removeHTML($data['name']),
75
+ 'id' => $callback
76
+ );
77
+ }
78
+ }
79
+ }
80
+
81
+ //now collect Admin Dashboard Widgets
82
+ $this->collectMetaboxes('dashboard');
83
+ }
84
+
85
+ protected function collectMetaboxes($post_type) {
86
+ global $wp_meta_boxes;
87
+
88
+ if (!isset($this->_cache[$post_type])) {
89
+ $this->_cache[$post_type] = array();
90
+ }
91
+
92
+ if (isset($wp_meta_boxes[$post_type]) && is_array($wp_meta_boxes[$post_type])) {
93
+ foreach ($wp_meta_boxes[$post_type] as $levels) {
94
+ if (is_array($levels)) {
95
+ foreach ($levels as $boxes) {
96
+ if (is_array($boxes)) {
97
+ foreach ($boxes as $data) {
98
+ if (trim($data['id'])) { //exclude any junk
99
+ $this->_cache[$post_type][$data['id']] = array(
100
+ 'id' => $data['id'],
101
+ 'title' => $this->removeHTML($data['title'])
102
+ );
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ /**
113
+ *
114
+ * @return type
115
+ */
116
+ public function initLink() {
117
+ $link = filter_var(aam_Core_Request::post('link'), FILTER_VALIDATE_URL);
118
+ if ($link) {
119
+ $url = add_query_arg('aam_meta_init', 1, $link);
120
+ aam_Core_API::cURL($url);
121
+ $response = array('status' => 'success');
122
+ } else {
123
+ $response = array('status' => 'failure');
124
+ }
125
+
126
+ return json_encode($response);
127
+ }
128
+
129
+ /**
130
+ *
131
+ * @global type $wp_post_types
132
+ * @return type
133
+ */
134
+ public function retrieveList() {
135
+ global $wp_post_types;
136
+
137
+ if (aam_Core_Request::post('refresh') == 1) {
138
+ aam_Core_API::deleteBlogOption('aam_metabox_cache');
139
+ $type_list = array_keys($wp_post_types);
140
+ array_unshift($type_list, self::GROUP_WIDGETS);
141
+
142
+ foreach ($type_list as $type) {
143
+ if ($type == 'widgets') {
144
+ $url = add_query_arg(
145
+ 'aam_meta_init',
146
+ 1,
147
+ admin_url('index.php')
148
+ );
149
+ } else {
150
+ $url = add_query_arg(
151
+ 'aam_meta_init',
152
+ 1,
153
+ admin_url('post-new.php?post_type=' . $type)
154
+ );
155
+ }
156
+ //grab metaboxes
157
+ aam_Core_API::cURL($url);
158
+ }
159
+ }
160
+
161
+ return $this->buildMetaboxList();
162
+ }
163
+
164
+ /**
165
+ *
166
+ * @global type $wp_post_types
167
+ * @return type
168
+ */
169
+ protected function buildMetaboxList() {
170
+ global $wp_post_types;
171
+
172
+ $cache = aam_Core_API::getBlogOption('aam_metabox_cache', array());
173
+ if ($this->getSubject()->getUID() == 'visitor') {
174
+ $list = array(
175
+ 'widgets' => (isset($cache['widgets']) ? $cache['widgets'] : array())
176
+ );
177
+ } else {
178
+ $list = $cache;
179
+ }
180
+ $content = '<div id="metabox_list">';
181
+ foreach ($list as $screen => $metaboxes) {
182
+ $content .= '<div class="group">';
183
+ switch ($screen) {
184
+ case 'dashboard':
185
+ $content .= '<h4>' . __('Dashboard Widgets', 'aam') . '</h4>';
186
+ break;
187
+
188
+ case 'widgets':
189
+ $content .= '<h4>' . __('Frontend Widgets', 'aam') . '</h4>';
190
+ break;
191
+
192
+ default:
193
+ $content .= '<h4>' . $wp_post_types[$screen]->labels->name;
194
+ $content .= '</h4>';
195
+ break;
196
+ }
197
+ $content .= '<div>';
198
+ $content .= '<div class="metabox-group">';
199
+ $i = 1;
200
+ $metaboxControl = $this->getSubject()->getObject(
201
+ aam_Control_Object_Metabox::UID
202
+ );
203
+ foreach ($metaboxes as $metabox) {
204
+ if ($i++ == 1) {
205
+ $content .= '<div class=metabox-row>';
206
+ }
207
+ //prepare title
208
+ if (strlen($metabox['title']) > 18) {
209
+ $title = substr($metabox['title'], 0, 15) . '...';
210
+ } else {
211
+ $title = $metabox['title'];
212
+ }
213
+ //prepare selected
214
+ if ($metaboxControl->has($screen, $metabox['id'])) {
215
+ $checked = 'checked="checked"';
216
+ } else {
217
+ $checked = '';
218
+ }
219
+
220
+ $metabox_id = "metabox_{$screen}_{$metabox['id']}";
221
+
222
+ $content .= '<div class="metabox-item">';
223
+ $content .= sprintf(
224
+ '<label for="%s" tooltip="%s">%s</label>',
225
+ $metabox_id,
226
+ esc_js($metabox['title']),
227
+ $title
228
+ );
229
+ $content .= sprintf(
230
+ '<input type="checkbox" id="%s" name="aam[%s][%s][%s]" %s />',
231
+ $metabox_id,
232
+ aam_Control_Object_Metabox::UID,
233
+ $screen,
234
+ $metabox['id'],
235
+ $checked
236
+ );
237
+ $content .= '<label for="' . $metabox_id . '"><span></span></label>';
238
+ $content .= '</div>';
239
+ if ($i > 3) {
240
+ $content .= '</div>';
241
+ $i = 1;
242
+ }
243
+ }
244
+ if ($i != 1) {
245
+ $content .= '</div>';
246
+ }
247
+ $content .= '</div></div></div>';
248
+ }
249
+ $content .= '</div>';
250
+
251
+ return json_encode(array('content' => $content));
252
+ }
253
+
254
+ /**
255
+ *
256
+ * @param type $text
257
+ * @return type
258
+ */
259
+ public function removeHTML($text) {
260
+ return strip_tags($text);
261
+ }
262
+
263
+ /**
264
+ *
265
+ * @return type
266
+ */
267
+ public function content() {
268
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/metabox.phtml');
269
+ }
270
+
271
+ }
application/view/post.php ADDED
@@ -0,0 +1,478 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class aam_View_Post extends aam_View_Abstract {
18
+
19
+ /**
20
+ *
21
+ * @var type
22
+ */
23
+ private $_post_type = 'post';
24
+
25
+ /**
26
+ *
27
+ * @var type
28
+ */
29
+ private $_term = 0;
30
+
31
+ /**
32
+ *
33
+ */
34
+ public function __construct() {
35
+ parent::__construct();
36
+ $this->_post_type = aam_Core_Request::request('post_type');
37
+ $this->_term = intval(aam_Core_Request::request('term'));
38
+ }
39
+
40
+ /**
41
+ *
42
+ * @global type $wp_post_types
43
+ * @return type
44
+ */
45
+ public function retrievePostTypeList() {
46
+ global $wp_post_types;
47
+
48
+ $response = array(
49
+ 'aaData' => array()
50
+ );
51
+
52
+ if (is_array($wp_post_types)) {
53
+ foreach ($wp_post_types as $post_type => $data) {
54
+ //show only list of post type which have User Interface
55
+ if ($data->show_ui) {
56
+ $response['aaData'][] = array(
57
+ $post_type,
58
+ $data->label,
59
+ ''
60
+ );
61
+ }
62
+ }
63
+ }
64
+
65
+ return json_encode($response);
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @global type $wp_post_statuses
71
+ * @global type $wp_post_types
72
+ * @return type
73
+ */
74
+ public function retrievePostList() {
75
+ global $wp_post_statuses, $wp_post_types;
76
+
77
+ $term = trim(aam_Core_Request::request('term'));
78
+
79
+ if (empty($term)) {
80
+ $post_type = 'post';
81
+ } elseif (isset($wp_post_types[$term])) {
82
+ $post_type = $term;
83
+ $term = '';
84
+ } else {
85
+ $post_type = '';
86
+ }
87
+
88
+ $args = array(
89
+ 'numberposts' => aam_Core_Request::request('iDisplayLength'),
90
+ 'offset' => aam_Core_Request::request('iDisplayStart'),
91
+ 'category' => $term,
92
+ 'post_type' => $post_type,
93
+ 's' => aam_Core_Request::request('sSearch'),
94
+ 'post_status' => array()
95
+ );
96
+
97
+ $argsAll = array(
98
+ 'numberposts' => '999999',
99
+ 'fields' => 'ids',
100
+ 'category' => $term,
101
+ 'post_type' => $post_type,
102
+ 's' => aam_Core_Request::request('sSearch'),
103
+ 'post_status' => array()
104
+ );
105
+
106
+ foreach ($wp_post_statuses as $status => $data) {
107
+ if ($data->show_in_admin_status_list) {
108
+ $args['post_status'][] = $status;
109
+ $argsAll['post_status'][] = $status;
110
+ }
111
+ }
112
+
113
+ $total = 0;
114
+ foreach (wp_count_posts($post_type) as $status => $number) {
115
+ if ($wp_post_statuses[$status]->show_in_admin_status_list) {
116
+ $total += $number;
117
+ }
118
+ }
119
+
120
+ //get displayed total
121
+ $displayTotal = count(get_posts($argsAll));
122
+
123
+ $response = array(
124
+ 'iTotalRecords' => $total,
125
+ 'iTotalDisplayRecords' => $displayTotal,
126
+ 'sEcho' => aam_Core_Request::request('sEcho'),
127
+ 'aaData' => array(),
128
+ );
129
+
130
+ foreach (get_posts($args) as $post) {
131
+ $response['aaData'][] = array(
132
+ $post->ID,
133
+ $post->post_status,
134
+ get_edit_post_link($post->ID),
135
+ $post->post_title,
136
+ $wp_post_statuses[$post->post_status]->label,
137
+ ''
138
+ );
139
+ }
140
+
141
+ return json_encode($response);
142
+ }
143
+
144
+ /**
145
+ *
146
+ * @global type $wp_post_types
147
+ * @return type
148
+ */
149
+ public function getPostTree() {
150
+ global $wp_post_types;
151
+
152
+ $type = $_REQUEST['root'];
153
+ $tree = array();
154
+
155
+ if ($type == "source") {
156
+ if (is_array($wp_post_types)) {
157
+ foreach ($wp_post_types as $post_type => $data) {
158
+ //show only list of post type which have User Interface
159
+ if ($data->show_ui) {
160
+ $tree[] = (object) array(
161
+ 'text' => $data->label,
162
+ 'expanded' => FALSE,
163
+ 'hasChildren' => TRUE,
164
+ 'id' => $post_type,
165
+ 'classes' => 'important',
166
+ );
167
+ }
168
+ }
169
+ }
170
+ } else {
171
+ if (preg_match('/^[\d]+$/', $type)) {
172
+ $taxonomy = $this->getTaxonomyByTerm($type);
173
+ $tree = $this->buildBranch(NULL, $taxonomy, $type);
174
+ } else {
175
+ $tree = $this->buildBranch($type);
176
+ }
177
+ }
178
+
179
+ if (!count($tree)) {
180
+ $tree[] = (object) array(
181
+ 'text' => '<i>' . __('[empty]', 'aam') . '</i>',
182
+ 'hasChildren' => FALSE,
183
+ 'classes' => 'post-ontree',
184
+ 'id' => 'empty-' . uniqid()
185
+ );
186
+ }
187
+
188
+ return json_encode($tree);
189
+ }
190
+
191
+ /**
192
+ *
193
+ * @global type $wpdb
194
+ * @param type $term_id
195
+ * @return boolean
196
+ */
197
+ protected function getTaxonomyByTerm($term_id) {
198
+ global $wpdb;
199
+
200
+ if ($term_id) {
201
+ $query = "SELECT taxonomy FROM {$wpdb->term_taxonomy} ";
202
+ $query .= "WHERE term_id = {$term_id}";
203
+ $result = $wpdb->get_var($query);
204
+ } else {
205
+ $result = FALSE;
206
+ }
207
+
208
+ return $result;
209
+ }
210
+
211
+ /**
212
+ *
213
+ * @param type $post_type
214
+ * @param type $taxonomy
215
+ * @param type $parent
216
+ * @return type
217
+ */
218
+ private function buildBranch($post_type, $taxonomy = FALSE, $parent = 0) {
219
+ $tree = array();
220
+ if (!$parent && !$taxonomy) { //root of a branch
221
+ $tree = $this->buildCategories($post_type);
222
+ } elseif ($taxonomy) { //build sub categories
223
+ $tree = $this->buildCategories('', $taxonomy, $parent);
224
+ }
225
+
226
+ return $tree;
227
+ }
228
+
229
+ /**
230
+ *
231
+ * @param type $post_type
232
+ * @param type $taxonomy
233
+ * @param type $parent
234
+ * @return type
235
+ */
236
+ private function buildCategories($post_type, $taxonomy = FALSE, $parent = 0) {
237
+
238
+ $tree = array();
239
+
240
+ if ($parent) {
241
+ //$taxonomy = $this->get_taxonomy_get_term($parent);
242
+ //firstly render the list of sub categories
243
+ $cat_list = get_terms(
244
+ $taxonomy, array(
245
+ 'get' => 'all',
246
+ 'parent' => $parent,
247
+ 'hide_empty' => FALSE
248
+ )
249
+ );
250
+ if (is_array($cat_list)) {
251
+ foreach ($cat_list as $category) {
252
+ $tree[] = $this->buildCategory($category);
253
+ }
254
+ }
255
+ } else {
256
+ $taxonomies = get_object_taxonomies($post_type);
257
+ foreach ($taxonomies as $taxonomy) {
258
+ if (is_taxonomy_hierarchical($taxonomy)) {
259
+ $term_list = get_terms($taxonomy, array(
260
+ 'parent' => $parent,
261
+ 'hide_empty' => FALSE
262
+ ));
263
+ if (is_array($term_list)) {
264
+ foreach ($term_list as $term) {
265
+ $tree[] = $this->buildCategory($term);
266
+ }
267
+ }
268
+ }
269
+ }
270
+ }
271
+
272
+ return $tree;
273
+ }
274
+
275
+ /**
276
+ *
277
+ * @param type $category
278
+ * @return type
279
+ */
280
+ private function buildCategory($category) {
281
+ $branch = (object) array(
282
+ 'text' => $category->name,
283
+ 'expanded' => FALSE,
284
+ 'classes' => 'important folder',
285
+ );
286
+ if ($this->hasCategoryChilds($category)) {
287
+ $branch->hasChildren = TRUE;
288
+ } else {
289
+ $branch->hasChildren = FALSE;
290
+ }
291
+ $branch->id = $category->term_id;
292
+
293
+ return $branch;
294
+ }
295
+
296
+ /**
297
+ * Check if category has children
298
+ *
299
+ * @param int category ID
300
+ * @return bool TRUE if has
301
+ */
302
+ protected function hasCategoryChilds($cat) {
303
+ global $wpdb;
304
+
305
+ //get number of categories
306
+ $query = "SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE parent={$cat->term_id}";
307
+ $counter = $wpdb->get_var($query);
308
+
309
+ return ($counter ? TRUE : FALSE);
310
+ }
311
+
312
+ /**
313
+ *
314
+ * @global type $wp_post_types
315
+ * @global type $wp_taxonomies
316
+ * @return type
317
+ */
318
+ public function getPostBreadcrumb() {
319
+ global $wp_post_types, $wp_taxonomies;
320
+
321
+ $id = aam_Core_Request::post('id');
322
+ $response = array();
323
+ if (preg_match('/^[\d]+$/', $id)) {
324
+ $taxonomy = $this->getTaxonomyByTerm($id);
325
+ //get post type
326
+ if (isset($wp_taxonomies[$taxonomy])) {
327
+ $post_type = $wp_taxonomies[$taxonomy]->object_type[0];
328
+ if (isset($wp_post_types[$post_type])) {
329
+ $response['post_type'] = $post_type;
330
+ $response['term'] = $id;
331
+ $response['link'] = get_edit_term_link($id, $taxonomy);
332
+ $term = get_term($id, $taxonomy);
333
+ $tree = $this->renderBreadcrumbTree($term, array());
334
+ $tree[] = array($post_type, $wp_post_types[$post_type]->label);
335
+ $response['breadcrumb'] = array_reverse($tree);
336
+ }
337
+ }
338
+ } else {
339
+ if (isset($wp_post_types[$id])) {
340
+ $response = array(
341
+ 'post_type' => $id,
342
+ 'term' => 0,
343
+ 'breadcrumb' => array(
344
+ array($id, $wp_post_types[$id]->label),
345
+ array('#', __('All', 'aam'))
346
+ )
347
+ );
348
+ } else {
349
+ $response = array(
350
+ 'term' => '',
351
+ 'breadcrumb' => array(
352
+ array('post', $wp_post_types['post']->label),
353
+ array('#', __('All', 'aam'))
354
+ )
355
+ );
356
+ }
357
+ }
358
+
359
+ return json_encode($response);
360
+ }
361
+
362
+ /**
363
+ *
364
+ * @param type $term
365
+ * @param type $tree
366
+ * @return type
367
+ */
368
+ protected function renderBreadcrumbTree($term, $tree) {
369
+ $tree[] = array($term->term_id, $term->name);
370
+ if ($term->parent) {
371
+ $tree = $this->renderBreadcrumbTree(
372
+ get_term($term->parent, $term->taxonomy), $tree
373
+ );
374
+ }
375
+
376
+ return $tree;
377
+ }
378
+
379
+ /**
380
+ *
381
+ * @return type
382
+ */
383
+ public function content() {
384
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/post.phtml');
385
+ }
386
+
387
+ /**
388
+ *
389
+ * @return type
390
+ */
391
+ public function saveAccess() {
392
+ $object_id = aam_Core_Request::post('id');
393
+
394
+ $limit_counter = apply_filters(
395
+ 'wpaccess_restrict_limit',
396
+ aam_Core_API::getBlogOption('aam_access_limit', 0)
397
+ );
398
+
399
+ if ($limit_counter == -1 || $limit_counter <= 5) {
400
+ $access = aam_Core_Request::post('access');
401
+ if (aam_Core_Request::post('type') == 'term') {
402
+ $object = $this->getSubject()->getObject(
403
+ aam_Control_Object_Term::UID, $object_id
404
+ );
405
+ if ($limit_counter !== -1 && isset($access['post'])){
406
+ unset($access['post']);
407
+ }
408
+ } else {
409
+ $object = $this->getSubject()->getObject(
410
+ aam_Control_Object_Post::UID, $object_id
411
+ );
412
+ }
413
+ $object->save($access);
414
+ aam_Core_API::updateBlogOption('aam_access_limit', $limit_counter + 1);
415
+
416
+ $response = array('status' => 'success');
417
+ } else {
418
+ $response = array(
419
+ 'status' => 'failure',
420
+ 'reason' => 'limitation',
421
+ 'extension' => 'AAM Unlimited Basic'
422
+ );
423
+ }
424
+
425
+ return json_encode($response);
426
+ }
427
+
428
+ /**
429
+ *
430
+ * @return type
431
+ */
432
+ public function getAccess() {
433
+ $type = aam_Core_Request::post('type');
434
+ $object_id = aam_Core_Request::post('id');
435
+
436
+ if ($type === 'term') {
437
+ $object = $this->getSubject()->getObject(
438
+ aam_Control_Object_Term::UID, $object_id
439
+ );
440
+ } else {
441
+ $object = $this->getSubject()->getObject(
442
+ aam_Control_Object_Post::UID, $object_id
443
+ );
444
+ }
445
+
446
+ return json_encode(array(
447
+ 'settings' => $object->getOption(),
448
+ 'counter' => apply_filters(
449
+ 'wpaccess_restrict_limit',
450
+ aam_Core_API::getBlogOption('aam_access_limit', 0)
451
+ )
452
+ ));
453
+ }
454
+
455
+ /**
456
+ *
457
+ * @return type
458
+ */
459
+ public function clearAccess() {
460
+ $type = aam_Core_Request::post('type');
461
+ $object_id = aam_Core_Request::post('id');
462
+
463
+ if ($type === 'term') {
464
+ $object = $this->getSubject()->getObject(
465
+ aam_Control_Object_Term::UID, $object_id
466
+ );
467
+ } else {
468
+ $object = $this->getSubject()->getObject(
469
+ aam_Control_Object_Post::UID, $object_id
470
+ );
471
+ }
472
+
473
+ return json_encode(array(
474
+ 'status' => ($object->delete() ? 'success' : 'failure')
475
+ ));
476
+ }
477
+
478
+ }
application/view/role.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class aam_View_Role extends aam_View_Abstract {
18
+
19
+ /**
20
+ *
21
+ * @return type
22
+ */
23
+ public function content() {
24
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/role.phtml');
25
+ }
26
+
27
+ /**
28
+ *
29
+ * @return type
30
+ */
31
+ public function retrieveList() {
32
+ //retrieve list of users
33
+ $count = count_users();
34
+ $user_count = $count['avail_roles'];
35
+
36
+ //filter by name
37
+ $search = strtolower(trim(aam_Core_Request::request('sSearch')));
38
+ $filtered = array();
39
+ $roles = get_editable_roles();
40
+ foreach ($roles as $id => $role) {
41
+ if (!$search || preg_match('/^' . $search . '/i', $role['name'])) {
42
+ $filtered[$id] = $role;
43
+ }
44
+ }
45
+
46
+ $response = array(
47
+ 'iTotalRecords' => count($roles),
48
+ 'iTotalDisplayRecords' => count($filtered),
49
+ 'sEcho' => aam_Core_Request::request('sEcho'),
50
+ 'aaData' => array(),
51
+ );
52
+ foreach ($filtered as $role => $data) {
53
+ $users = (isset($user_count[$role]) ? $user_count[$role] : 0);
54
+ $response['aaData'][] = array(
55
+ $role,
56
+ $users,
57
+ $data['name'],
58
+ ''
59
+ );
60
+ }
61
+
62
+ return json_encode($response);
63
+ }
64
+
65
+ /**
66
+ *
67
+ * @return type
68
+ */
69
+ public function add() {
70
+ $name = trim(aam_Core_Request::post('name'));
71
+ $roles = new WP_Roles;
72
+ $role_id = 'aamrole_' . uniqid();
73
+
74
+ if ($roles->add_role($role_id, $name)) {
75
+ $response = array(
76
+ 'status' => 'success',
77
+ 'role' => $role_id
78
+ );
79
+ } else {
80
+ $response = array('status' => 'failure');
81
+ }
82
+
83
+ return json_encode($response);
84
+ }
85
+
86
+ /**
87
+ *
88
+ * @return type
89
+ */
90
+ public function edit() {
91
+ $result = $this->getSubject()->update(trim(aam_Core_Request::post('name')));
92
+ return json_encode(
93
+ array('status' => ($result ? 'success' : 'failure'))
94
+ );
95
+ }
96
+
97
+ /**
98
+ *
99
+ * @return type
100
+ */
101
+ public function delete() {
102
+ if ($this->getSubject()->delete(aam_Core_Request::post('delete_users'))) {
103
+ $status = 'success';
104
+ } else {
105
+ $status = 'failure';
106
+ }
107
+
108
+ return json_encode(array('status' => $status));
109
+ }
110
+
111
+ }
application/view/tmpl/capability.phtml ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div class="feature-content-container" id="capability_content">
10
+ <table id="capability_list">
11
+ <thead>
12
+ <tr>
13
+ <th>Capability ID</th>
14
+ <th>Checked</th>
15
+ <th width="35%"><?php echo __('Category', 'aam'); ?></th>
16
+ <th width="50%"><?php echo __('Capability', 'aam'); ?></th>
17
+ <th><?php echo __('Control', 'aam'); ?></th>
18
+ </tr>
19
+ </thead>
20
+ <tbody></tbody>
21
+ </table>
22
+
23
+ <div id="filter_capability_dialog" class="aam-dialog" title="<?php echo __('Filter Capability List', 'aam'); ?>">
24
+ <table id="capability_group_list">
25
+ <thead>
26
+ <tr>
27
+ <th><?php echo __('Group Name', 'aam'); ?></th>
28
+ <th><?php echo __('Select', 'aam'); ?></th>
29
+ </tr>
30
+ </thead>
31
+ <tbody>
32
+ <?php foreach ($this->getGroupList() as $group) { ?>
33
+ <tr>
34
+ <td><?php echo $group; ?></td>
35
+ <td>
36
+ <div class="capability-actions">
37
+ <a href="#" class="capability-action capability-action-select"></a>
38
+ </div>
39
+ </td>
40
+ </tr>
41
+ <?php } ?>
42
+ </tbody>
43
+ </table>
44
+ </div>
45
+
46
+ <div id="copy_role_dialog" class="aam-dialog" title="<?php echo __('Inherit Capabilities', 'aam'); ?>">
47
+ <table id="copy_role_list">
48
+ <thead>
49
+ <tr>
50
+ <th>Role ID</th>
51
+ <th>User Count</th>
52
+ <th width="80%"><?php echo __('Role Name', 'aam'); ?></th>
53
+ <th><?php echo __('Action', 'aam'); ?></th>
54
+ </tr>
55
+ </thead>
56
+ <tbody></tbody>
57
+ </table>
58
+ <div class="aam-metabox-loader"></div>
59
+ </div>
60
+
61
+ <div id="capability_form_dialog" class="aam-dialog" title="<?php echo __('Add New Capability', 'aam'); ?>">
62
+ <table class="dataTable">
63
+ <tbody>
64
+ <tr>
65
+ <th><?php echo __('Capability Name', 'aam'); ?><span class="aam-asterix">*</span>:</th>
66
+ <td><input type="text" id="capability_name" class="aam-input" /></td>
67
+ </tr>
68
+ </tbody>
69
+ </table>
70
+ <div class="aam-metabox-loader"></div>
71
+ </div>
72
+
73
+ <div id="delete_capability" class="aam-dialog" title="<?php echo __('Delete Capability', 'aam'); ?>">
74
+ <p class="dialog-content"></p>
75
+ </div>
76
+ </div>
application/view/tmpl/configpress.phtml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div class="feature-content-container" id="configpress_content">
10
+ <div class="configpress-top-actions">
11
+ <a href="<?php echo AAM_BASE_URL . '/docs/configpress.pdf' ?>" target="_blank" class="configpress-top-action-item configpress-top-action-tutorial" tooltip="<?php echo __('Download ConfigPress Tutorial', 'aam'); ?>"></a>
12
+ </div>
13
+
14
+ <textarea id="configpress" style="width:100%; height: 400px;"><?php echo $this->getSubject()->getObject(aam_Control_Object_ConfigPress::UID)->getConfig(); ?></textarea>
15
+ </div>
application/view/tmpl/event.phtml ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div class="feature-content-container" id="event_manager_content">
10
+ <table id="event_list">
11
+ <thead>
12
+ <tr>
13
+ <th width="30%"><?php echo __('Event', 'aam'); ?></th>
14
+ <th><?php echo __('Event Specifier', 'aam'); ?></th>
15
+ <th width="25%"><?php echo __('Bind Post Type', 'aam'); ?></th>
16
+ <th width="30%"><?php echo __('Action', 'aam'); ?></th>
17
+ <th><?php echo __('Action Specifier', 'aam'); ?></th>
18
+ <th><?php echo __('Control', 'aam'); ?></th>
19
+ </tr>
20
+ </thead>
21
+ <tbody></tbody>
22
+ </table>
23
+ <div id="manage_event_dialog" class="aam-dialog" title="<?php echo __('Manager Event'); ?>">
24
+ <table class="aam-form-table">
25
+ <tbody>
26
+ <tr>
27
+ <th width="40%"><?php echo __('Event', 'aam'); ?><span class="aam-asterix">*</span>:</th>
28
+ <td>
29
+ <select id="event_event">
30
+ <option value="status_change"><?php echo __('Post Status Change', 'aam'); ?></option>
31
+ <option value="content_change"><?php echo __('Post Content Change', 'aam'); ?></option>
32
+ </select>
33
+ </td>
34
+ </tr>
35
+ <tr id="status_changed" style="display: none;">
36
+ <th><?php echo __('Status Changed To', 'aam'); ?><span class="aam-asterix">*</span>:</th>
37
+ <td>
38
+ <select id="event_specifier">
39
+ <?php
40
+ foreach ($this->getPostStatuses() as $status => $config) {
41
+ if ($config->show_in_admin_status_list) {
42
+ echo '<option value="' . $status . '">';
43
+ echo $config->label . '</option>';
44
+ }
45
+ }
46
+ ?>
47
+ </select>
48
+ </td>
49
+ </tr>
50
+ <tr>
51
+ <th><?php echo __('Bind to Post Type', 'aam'); ?><span class="aam-asterix">*</span>:</th>
52
+ <td>
53
+ <select id="event_bind">
54
+ <?php
55
+ foreach ($this->getPostTypes() as $post => $config) {
56
+ echo '<option value="' . $post . '">';
57
+ echo $config->labels->name . '</option>';
58
+ }
59
+ ?>
60
+ </select>
61
+ </td>
62
+ </tr>
63
+ <tr>
64
+ <th><?php echo __('Action', 'aam'); ?><span class="aam-asterix">*</span>:</th>
65
+ <td>
66
+ <select id="event_action">
67
+ <option value="notify"><?php echo __('Email Notification', 'aam'); ?></option>
68
+ <option value="change_status"><?php echo __('Change Status', 'aam'); ?></option>
69
+ <option value="callback"><?php echo __('Callback', 'aam'); ?></option>
70
+ </select>
71
+ </td>
72
+ </tr>
73
+ <tr id="event_specifier_notify_holder" class="event-specifier">
74
+ <th><?php echo __('Email Address', 'aam'); ?><span class="aam-asterix">*</span>:</th>
75
+ <td>
76
+ <input type="text" id="event_specifier_notify" />
77
+ </td>
78
+ </tr>
79
+ <tr id="event_specifier_change_status_holder" class="event-specifier">
80
+ <th><?php echo __('Change Status To', 'aam'); ?><span class="aam-asterix">*</span>:</th>
81
+ <td>
82
+ <select id="event_specifier_change_status">
83
+ <?php
84
+ foreach ($this->getPostStatuses() as $status => $config) {
85
+ if ($config->show_in_admin_status_list) {
86
+ echo '<option value="' . $status . '">';
87
+ echo $config->label . '</option>';
88
+ }
89
+ }
90
+ ?>
91
+ </select>
92
+ </td>
93
+ </tr>
94
+ <tr id="event_specifier_callback_holder" class="event-specifier">
95
+ <th><?php echo __('Callback Function', 'aam'); ?><span class="aam-asterix">*</span>:</th>
96
+ <td>
97
+ <input type="text" id="event_specifier_callback" />
98
+ </td>
99
+ </tr>
100
+ </tbody>
101
+ </table>
102
+ </div>
103
+
104
+ <div id="delete_event" class="aam-dialog" title="<?php echo __('Delete Event', 'aam'); ?>">
105
+ <p class="dialog-content"><?php echo __('Are you sure you want to delete selected Event?', 'aam'); ?></p>
106
+ </div>
107
+
108
+ </div>
application/view/tmpl/extension.phtml ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap" id="aam">
2
+ <div class="postbox-container" style="width:70%;">
3
+ <div class="metabox-holder">
4
+ <div class="meta-box-sortables">
5
+ <div class="postbox">
6
+ <div class="handlediv" title="<?php echo __('Click to toggle', 'aam'); ?>"></div>
7
+ <h3 class="hndle">
8
+ <span>
9
+ <?php echo __('Extension List', 'aam'); ?>
10
+ </span>
11
+ </h3>
12
+ <div class="inside">
13
+ <table id="extension_list">
14
+ <thead>
15
+ <tr>
16
+ <th width="25%"><?php echo __('Name', 'aam'); ?></th>
17
+ <th width="50%"><?php echo __('Description', 'aam'); ?></th>
18
+ <th width="10%"><?php echo __('Price', 'aam'); ?></th>
19
+ <th><?php echo __('Actions', 'aam'); ?></th>
20
+ </tr>
21
+ </thead>
22
+ <tbody>
23
+ <tr>
24
+ <td>
25
+ <span class="extension-name">AAM Plus Package</span>
26
+ </td>
27
+ <td class="extension-description">
28
+ This Extension extends default AAM basic features and unlock some limitations.
29
+ Add custom taxonomy <b>Page Category</b> to ground pages into categories;
30
+ Unlock the limitation for Post Access control;
31
+ Add additional Capability Group <b>Comments</b> with the set of capabilities to control default comment
32
+ actions like <b>Reply</b>, <b>Mark Spam</b>, <b>Trash</b>, <b>Delete</b> etc;
33
+ Add possibility to setup default post or page access.
34
+ For more details, please visit our forum.
35
+ </td>
36
+ <td class="extension-price payed">$30.00</td>
37
+ <td>
38
+ <div class="extension-actions">
39
+ <a href="http://wpaam.com/support#viewtopic.php?f=7&t=10" target="_blank" class="extension-action extension-action-forum" tooltip="Visit Our Forum"></a>
40
+ <?php if ($this->hasExtension('AAM Plus Package')) { ?>
41
+ <a href="#" extension="AAM Plus Package" license="<?php echo $this->getExtension('AAM Plus Package')->license; ?>" class="extension-action extension-action-ok" tooltip="Installed Successfully"></a>
42
+ <?php } else { ?>
43
+ <a href="#" extension="AAM Plus Package" link="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UEM8U65HFEG4Q" class="extension-action extension-action-purchase" tooltip="Get it Today"></a>
44
+ <?php } ?>
45
+ </div>
46
+ </td>
47
+ </tr>
48
+ </tbody>
49
+ </table>
50
+ <div id="install_extension" class="aam-dialog" title="<?php echo __('Install Extension', 'aam'); ?>">
51
+ <p class="dialog-content">
52
+ <?php echo __('If you already have license key for current extension, please enter it below. Othewise click <b>Purchase</b> button to checkout your order.', 'aam'); ?>
53
+ <input type="text" class="license-input" id="license_key" placeholder="License Key" />
54
+ </p>
55
+ </div>
56
+ <div id="update_extension" class="aam-dialog" title="<?php echo __('Update Extension', 'aam'); ?>">
57
+ <p class="dialog-content" style="text-align: center;">
58
+ <?php echo __('Extension has been installed. Your license key: ', 'aam'); ?><br/>
59
+ <b><span id="installed_license_key"></span></b>
60
+ </p>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ <div class="postbox-container" style="width:25%; margin-left: 2%;">
68
+ <div class="metabox-holder">
69
+ <div class="meta-box-sortables">
70
+ <div class="postbox">
71
+ <div class="handlediv" title="<?php echo __('Click to toggle', 'aam'); ?>"></div>
72
+ <h3 class="hndle">
73
+ <span><?php echo __('Connect with AAM', 'aam'); ?></span>
74
+ </h3>
75
+ <div class="inside">
76
+ <div id="misc-publishing-actions" class="cpanel">
77
+ <a href="https://twitter.com/wpaam" class="cpanel-item cpanel-item-twitter" tooltip="Follow @wpaam" target="_blank">Follow</a>
78
+ <a href="mailto:support@wpaam.com" class="cpanel-item cpanel-item-message" tooltip="Send Us Email">Send Message</a>
79
+ <a href="http://wpaam.com" class="cpanel-item cpanel-item-website" tooltip="Visit Us" target="_blank">Website</a>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+
88
+
application/view/tmpl/manager.phtml ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div class="wrap" id="aam">
10
+ <form action="" method="post" id="aam_form">
11
+ <?php do_action('aam_cmanager_hierarchy'); ?>
12
+ <div class="postbox-container" style="width:70%;">
13
+ <div class="metabox-holder">
14
+ <div class="meta-box-sortables">
15
+ <div class="postbox">
16
+ <div class="handlediv" title="<?php echo __('Click to toggle', 'aam'); ?>"></div>
17
+ <h3 class="hndle">
18
+ <?php if (aam_Core_API::isNetworkPanel()) { ?>
19
+ <span class="current-site"></span>
20
+ <?php } ?>
21
+ <span class="current-subject"></span>
22
+ </h3>
23
+ <div class="inside main-inside">
24
+ <div class="aam-main-loader"></div>
25
+ <div class="aam-main-content"></div>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+
32
+ <div class="postbox-container" style="width:25%; margin-left: 2%;">
33
+ <div class="metabox-holder" id="control_panel">
34
+ <div class="meta-box-sortables">
35
+ <div class="postbox">
36
+ <div class="handlediv" title="<?php echo __('Click to toggle', 'aam'); ?>"></div>
37
+ <h3 class="hndle">
38
+ <span><?php echo __('Control Panel', 'aam'); ?></span>
39
+ </h3>
40
+ <div class="inside">
41
+ <div>
42
+ <div class="cpanel-major">
43
+ <a href="#" class="cpanel-item cpanel-item-restore" id="aam_roleback" tooltip="<?php echo __('Undo Change', 'aam'); ?>"><?php echo __('Undo Change', 'aam'); ?></a>
44
+ <a href="#" class="cpanel-item cpanel-item-save" id="aam_save" ><?php echo __('Save', 'aam'); ?></a>
45
+ </div>
46
+ </div>
47
+ <div class="cpanel-minor">
48
+ <a href="https://twitter.com/wpaam" target="_blank" class="cpanel-item cpanel-item-twitter" id="aam_twitter" tooltip="<?php echo __('Follow @wpaam', 'aam'); ?>"><?php echo __('Follow', 'aam'); ?></a>
49
+ <a href="http://wpaam.com/support" target="_blank" class="cpanel-item cpanel-item-help" id="aam_help" tooltip="<?php echo __('Help Forum', 'aam'); ?>"><?php echo __('Help', 'aam'); ?></a>
50
+ <a href="#" class="cpanel-item cpanel-item-message" id="aam_message" tooltip="<?php echo __('E-mail Us', 'aam'); ?>"><?php echo __('E-mail Us', 'aam'); ?></a>
51
+ <a href="http://wordpress.org/support/view/plugin-reviews/advanced-access-manager" target="_blank" class="cpanel-item cpanel-item-star" tooltip="<?php echo __('Rate AAM', 'aam'); ?>"><?php echo __('Rate Us', 'aam'); ?></a>
52
+ </div>
53
+ <div class="aam-metabox-loader"></div>
54
+ </div>
55
+ <div id="restore_dialog" class="aam-dialog" title="<?php echo __('Undo Change', 'aam'); ?>">
56
+ <p class="dialog-content"><?php echo __('Would your like to role back current settings?', 'aam'); ?></p>
57
+ </div>
58
+ <div id="message_dialog" class="aam-dialog" title="<?php echo __('E-mail Us', 'aam'); ?>">
59
+ <p class="dialog-content"><?php echo __('Our E-mail address is <b>support@wpaam.com</b>', 'aam'); ?></p>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+ <div class="metabox-holder" id="control_manager">
66
+ <div class="meta-box-sortables">
67
+ <div class="postbox">
68
+ <div class="handlediv" title="<?php echo __('Click to toggle', 'aam'); ?>"></div>
69
+ <h3 class="hndle">
70
+ <span><?php echo __('Control Manager', 'aam'); ?></span>
71
+ </h3>
72
+ <div class="inside">
73
+ <div id="minor-publishing">
74
+ <div id="misc-publishing-actions" class="control-manager">
75
+ <?php
76
+ foreach ($this->getCManager() as $item) {
77
+ echo '<a href="#" class="', $item['class'], '" ';
78
+ echo 'id="', $item['id'], '" tooltip="', $item['title'], '" segment="' . $item['segment'] . '">';
79
+ echo $item['label'], '</a>';
80
+ }
81
+ ?>
82
+ </div>
83
+ </div>
84
+ <div class="control-manager-content">
85
+ <?php
86
+ foreach ($this->getCManager() as $item) {
87
+ echo call_user_func($item['content']);
88
+ }
89
+ ?>
90
+ </div>
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ <br class="clear" />
97
+ </form>
98
+ </div>
application/view/tmpl/menu.phtml ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ $menu = $this->getMenu();
9
+ ?>
10
+ <div class="feature-content-container" id="admin_menu_content">
11
+ <?php if (count($menu)) { ?>
12
+ <div class="menu-top-actions">
13
+ <!--
14
+ <div class="menu-top-action-sort-description">
15
+ <span>Drag &amp; Drop the Menu Item to change the order.</span>
16
+ </div>
17
+ <a href="#" class="menu-top-action-item menu-top-action-sort" tooltip="Sort the Admin Menu"></a>
18
+ -->
19
+ </div>
20
+ <?php } ?>
21
+ <div id="main_menu_list">
22
+ <?php
23
+ if (count($menu)) {
24
+ $menuControl = $this->getSubject()->getObject(aam_Control_Object_Menu::UID);
25
+ foreach ($menu as $i => $menu) {
26
+ $menu_id = $i . uniqid();
27
+ ?>
28
+ <div class="group">
29
+ <h4><?php echo $menu['name']; ?></h4>
30
+ <div>
31
+ <div class="whole-menu">
32
+ <label for="m<?php echo $menu_id; ?>"><?php echo __('Restrict All', 'aam'); ?></label>
33
+ <input type="checkbox" id="m<?php echo $menu_id; ?>" name="aam[<?php echo aam_Control_Object_Menu::UID; ?>][<?php echo $menu['id']; ?>]" <?php echo ($this->hasRestrictedAll($menu) ? 'checked="checked"' : ''); ?> class="whole_menu" />
34
+ <label for="m<?php echo $menu_id; ?>"><span></span></label>
35
+ </div>
36
+ <?php if (isset($menu['submenu'])) { ?>
37
+ <div class="menu-submenu-list" id="submenu_m<?php echo $menu_id; ?>">
38
+ <?php
39
+ $c = 1;
40
+ foreach ($menu['submenu'] as $j => $submenu) {
41
+ if ($c++ === 1) {
42
+ echo '<div class="menu-submenu-row">';
43
+ }
44
+ ?>
45
+ <div class="menu-submenu-item">
46
+ <label for="m<?php echo $menu_id . $j; ?>" tooltip="<?php echo $submenu['name']; ?>" ><?php echo $submenu['short']; ?></label>
47
+ <input type="checkbox" id="m<?php echo $menu_id . $j; ?>" name="aam[<?php echo aam_Control_Object_Menu::UID; ?>][<?php echo $submenu['id']; ?>]" <?php echo ($menuControl->has($submenu['id']) ? 'checked="checked"' : ''); ?> />
48
+ <label for="m<?php echo $menu_id . $j; ?>"><span></span></label>
49
+ </div>
50
+ <?php
51
+ if ($c > 3) {
52
+ $c = 1;
53
+ echo '</div>';
54
+ }
55
+ }
56
+ if ($c !== 1) {
57
+ echo '</div>';
58
+ }
59
+ ?>
60
+ </div>
61
+ <?php } ?>
62
+ </div>
63
+ </div>
64
+ <?php
65
+ }
66
+ } else {
67
+ ?>
68
+ <div class="menu-empty-list">
69
+ <span><?php echo __('There is no single menu item allowed for current Role or User', 'aam'); ?></span>
70
+ </div>
71
+ <?php
72
+ }
73
+ ?>
74
+ </div>
75
+ </div>
application/view/tmpl/metabox.phtml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div class="feature-content-container" id="metabox_content">
10
+ <div class="metabox-top-actions">
11
+ <div class="metabox-top-action-link">
12
+ <input type="text" class="link-text" id="metabox_link" />
13
+ </div>
14
+ <a href="#" class="metabox-top-action metabox-top-action-add" tooltip="<?php echo __('Retrieve Metaboxes From Link', 'aam') ;?>"></a>
15
+ <a href="#" class="metabox-top-action metabox-top-action-refresh" tooltip="<?php echo __('Refresh the List', 'aam') ;?>"></a>
16
+ <br class="clear" />
17
+ </div>
18
+ <div class="aam-metabox-loader"></div>
19
+ <div id="metabox_list_container"></div>
20
+ </div>
application/view/tmpl/post.phtml ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div class="feature-content-container" id="post_access_content">
10
+ <table id="post_list">
11
+ <thead>
12
+ <tr>
13
+ <th>Post ID</th>
14
+ <th>Post Status</th>
15
+ <th>Post Link</th>
16
+ <th width="60%"><?php echo __('Name', 'aam'); ?></th>
17
+ <th width="20%"><?php echo __('Status', 'aam'); ?></th>
18
+ <th><?php echo __('Control', 'aam'); ?></th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ </tbody>
23
+ </table>
24
+
25
+ <div id="filter_post_dialog" class="aam-dialog" title="<?php echo __('Filter Posts by Type', 'aam'); ?>">
26
+ <div class="tree-holder postbox">
27
+ <div id="sidetreecontrol">
28
+ <a href="#"><?php echo __('Collapse All', 'aam'); ?></a>&nbsp;|&nbsp;
29
+ <a href="#"><?php echo __('Expand All', 'aam'); ?></a>&nbsp;|&nbsp;
30
+ <span><?php echo __('Refresh', 'aam'); ?></span></div>
31
+ <br class="clear" />
32
+ <ul id="tree" class="filetree"></ul>
33
+ </div>
34
+ <div class="aam-main-loader"></div>
35
+ </div>
36
+
37
+ <div id="access_dialog" class="aam-dialog">
38
+ <div class="aam-lock-message">
39
+ <span><?php echo __('You riched the limit. Get <a href="' . admin_url('admin.php?page=aam-ext') . '" target="_blank">AAM Plus Package</a> to unlock the feature.'); ?></span>
40
+ </div>
41
+ <div class="post-access-inherited"></div>
42
+ <?php if ($this->getSubject()->getUID() != 'visitor') { ?>
43
+ <div class="post-access-area">
44
+ <input type="radio" id="post_area_frontend" value="frontend" checked="checked" name="access_area" /><label for="post_area_frontend"><?php echo __('Frontend', 'aam'); ?></label>
45
+ <input type="radio" id="post_area_backend" value="backend" name="access_area" /><label for="post_area_backend"><?php echo __('Backend', 'aam'); ?></label>
46
+ </div>
47
+ <?php } ?>
48
+
49
+ <div id="access_control_area">
50
+ <div id="term_access">
51
+ <table class="dataTable" id="term_access_frontend">
52
+ <thead>
53
+ <tr>
54
+ <th colspan="2" class="term-access-title"><?php echo __('Term Access', 'aam'); ?></th>
55
+ </tr>
56
+ <tr>
57
+ <th><?php echo __('Capability', 'aam'); ?></th>
58
+ <th><?php echo __('Restrict', 'aam'); ?></th>
59
+ </tr>
60
+ </thead>
61
+ <tbody>
62
+ <?php
63
+ $term = $this->getSubject()->getObject(aam_Control_Object_Term::UID);
64
+ foreach ($term->getAccessList('frontend') as $i => $action) {
65
+ ?>
66
+ <tr class="<?php echo ($i % 2 ? 'event' : 'odd'); ?>">
67
+ <td>
68
+ <div class="post-access">
69
+ <?php echo __($action, 'aam'); ?>
70
+ </div>
71
+ </td>
72
+ <td>
73
+ <div class="post-actions">
74
+ <div class="post-action">
75
+ <input type="checkbox" id="term_frontend_<?php echo $action; ?>" object="term" area="frontend" action="<?php echo $action; ?>" />
76
+ <label for="term_frontend_<?php echo $action; ?>"><span></span></label>
77
+ </div>
78
+ </div>
79
+ </td>
80
+ </tr>
81
+ <?php
82
+ }
83
+ ?>
84
+ </tbody>
85
+ <tfoot>
86
+ <tr>
87
+ <td colspan="2" class="post-access-description">
88
+ <span class="aam-post-access-notice">*</span>
89
+ <?php echo __('Control Frontend Term Access', 'aam'); ?>
90
+ </td>
91
+ </tr>
92
+ </tfoot>
93
+ </table>
94
+ <table class="dataTable" id="term_access_backend">
95
+ <thead>
96
+ <tr>
97
+ <th colspan="2" class="term-access-title"><?php echo __('Term Access', 'aam'); ?></th>
98
+ </tr>
99
+ <tr>
100
+ <th><?php echo __('Capability', 'aam'); ?></th>
101
+ <th><?php echo __('Restrict', 'aam'); ?></th>
102
+ </tr>
103
+ </thead>
104
+ <tbody>
105
+ <?php
106
+ foreach ($term->getAccessList('backend') as $i => $action) {
107
+ ?>
108
+ <tr class="<?php echo ($i % 2 ? 'event' : 'odd'); ?>">
109
+ <td>
110
+ <div class="post-access">
111
+ <?php echo __($action, 'aam'); ?>
112
+ </div>
113
+ </td>
114
+ <td>
115
+ <div class="post-actions">
116
+ <div class="post-action">
117
+ <input type="checkbox" id="term_backend_<?php echo $action ?>" object="term" area="backend" action="<?php echo $action ?>" />
118
+ <label for="term_backend_<?php echo $action ?>"><span></span></label>
119
+ </div>
120
+ </div>
121
+ </td>
122
+ </tr>
123
+ <?php
124
+ }
125
+ ?>
126
+ </tbody>
127
+ <tfoot>
128
+ <tr>
129
+ <td colspan="2" class="post-access-description">
130
+ <span class="aam-post-access-notice">*</span>
131
+ <?php echo __('Control Backend Term Access', 'aam'); ?>
132
+ </td>
133
+ </tr>
134
+ </tfoot>
135
+ </table>
136
+ </div>
137
+
138
+ <div id="post_access" class="post-access-list">
139
+ <table class="dataTable" id="post_access_frontend">
140
+ <thead>
141
+ <tr>
142
+ <th colspan="2" class="post-access-title"><?php echo __('All Posts in Term', 'aam'); ?></th>
143
+ </tr>
144
+ <tr>
145
+ <th><?php echo __('Capability', 'aam'); ?></th>
146
+ <th><?php echo __('Restrict', 'aam'); ?></th>
147
+ </tr>
148
+ </thead>
149
+ <tbody>
150
+ <?php
151
+ $post = $this->getSubject()->getObject(aam_Control_Object_Post::UID);
152
+ foreach ($post->getAccessList('frontend') as $i => $action) {
153
+ ?>
154
+ <tr class="<?php echo ($i % 2 ? 'event' : 'odd'); ?>">
155
+ <td>
156
+ <div class="post-access">
157
+ <?php echo __($action, 'aam'); ?>
158
+ </div>
159
+ </td>
160
+ <td>
161
+ <div class="post-actions">
162
+ <div class="post-action post-action-check">
163
+ <input type="checkbox" id="post_frontend_<?php echo $action ?>" object="post" area="frontend" action="<?php echo $action ?>" />
164
+ <label for="post_frontend_<?php echo $action ?>"><span></span></label>
165
+ </div>
166
+ </div>
167
+ </td>
168
+ </tr>
169
+ <?php
170
+ }
171
+ ?>
172
+ </tbody>
173
+ <tfoot>
174
+ <tr>
175
+ <td colspan="2" class="post-access-description">
176
+ <span class="aam-post-access-notice">*</span>
177
+ <?php echo __('Control Frontend Post Access', 'aam'); ?>
178
+ </td>
179
+ </tr>
180
+ </tfoot>
181
+ </table>
182
+ <table class="dataTable" id="post_access_backend">
183
+ <thead>
184
+ <tr>
185
+ <th colspan="2" class="post-access-title"><?php echo __('All Posts in Term', 'aam'); ?></th>
186
+ </tr>
187
+ <tr>
188
+ <th><?php echo __('Capability', 'aam'); ?></th>
189
+ <th><?php echo __('Restrict', 'aam'); ?></th>
190
+ </tr>
191
+ </thead>
192
+ <tbody>
193
+ <?php
194
+ foreach ($post->getAccessList('backend') as $i => $action) {
195
+ ?>
196
+ <tr class="<?php echo ($i % 2 ? 'event' : 'odd'); ?>">
197
+ <td>
198
+ <div class="post-access">
199
+ <?php echo __($action, 'aam'); ?>
200
+ </div>
201
+ </td>
202
+ <td>
203
+ <div class="post-actions">
204
+ <div class="post-action post-action-check">
205
+ <input type="checkbox" id="post_backend_<?php echo $action ?>" object="post" area="backend" action="<?php echo $action ?>" />
206
+ <label for="post_backend_<?php echo $action ?>"><span></span></label>
207
+ </div>
208
+ </div>
209
+ </td>
210
+ </tr>
211
+ <?php
212
+ }
213
+ ?>
214
+ </tbody>
215
+ <tfoot>
216
+ <tr>
217
+ <td colspan="2" class="post-access-description">
218
+ <span class="aam-post-access-notice">*</span>
219
+ <?php echo __('Control Backend Post Access', 'aam'); ?>
220
+ </td>
221
+ </tr>
222
+ </tfoot>
223
+ </table>
224
+ <div class="post-access-block">
225
+ <a href="#" class="aam-lock-big">
226
+ <span><?php echo __('Get AAM Plus Package', 'aam'); ?></span>
227
+ </a>
228
+ </div>
229
+ </div>
230
+ </div>
231
+ <div class="aam-main-loader"></div>
232
+ </div>
233
+ </div>
application/view/tmpl/role.phtml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div id="role_manager_wrap">
10
+ <table id="role_list">
11
+ <thead>
12
+ <tr>
13
+ <th>Role ID</th>
14
+ <th>User Count</th>
15
+ <th width="60%"><?php echo __('Role', 'aam'); ?></th>
16
+ <th><?php echo __('Action', 'aam'); ?></th>
17
+ </tr>
18
+ </thead>
19
+ <tbody></tbody>
20
+ </table>
21
+
22
+ <div id="manage_role_dialog" class="aam-dialog">
23
+ <table class="dataTable">
24
+ <tbody>
25
+ <tr>
26
+ <th><?php echo __('Role Name', 'aam'); ?><span class="aam-asterix">*</span>:</th>
27
+ <td><input type="text" id="role_name" class="aam-input" /></td>
28
+ </tr>
29
+ </tbody>
30
+ </table>
31
+ </div>
32
+
33
+ <div id="delete_role_dialog" class="aam-dialog" title="<?php echo __('Delete Role', 'aam'); ?>">
34
+ <p class="dialog-content"></p>
35
+ </div>
36
+ <div id="delete_admin_role_dialog" class="aam-dialog" title="<?php echo __('Notice', 'aam'); ?>">
37
+ <p class="dialog-content">
38
+ <?php echo __('You can not delete <b>Administrator</b> Role', 'aam'); ?>
39
+ </p>
40
+ </div>
41
+ </div>
application/view/tmpl/user.phtml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div id="user_manager_wrap">
10
+ <table id="user_list">
11
+ <thead>
12
+ <tr>
13
+ <th>User ID</th>
14
+ <th>User Login</th>
15
+ <th width="60%"><?php echo __('Username', 'aam'); ?></th>
16
+ <th><?php echo __('Action', 'aam'); ?></th>
17
+ <th>Status</th>
18
+ </tr>
19
+ </thead>
20
+ <tbody></tbody>
21
+ </table>
22
+
23
+ <div id="filter_user_dialog" class="aam-dialog" title="<?php echo __('Filter Users by Role', 'aam'); ?>">
24
+ <table id="filter_role_list">
25
+ <thead>
26
+ <tr>
27
+ <th>Role ID</th>
28
+ <th>User Count</th>
29
+ <th width="80%"><?php echo __('Role Name', 'aam'); ?></th>
30
+ <th><?php echo __('Action', 'aam'); ?></th>
31
+ </tr>
32
+ </thead>
33
+ <tbody></tbody>
34
+ </table>
35
+ </div>
36
+
37
+ <div id="delete_user_dialog" class="aam-dialog" title="<?php echo __('Delete User', 'aam'); ?>">
38
+ <span class="dialog-content"></span>
39
+ </div>
40
+ </div>
application/view/tmpl/visitor.phtml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div id="visitor_manager_wrap" class="control-manager-visitor">
10
+ <?php echo __('Control Access to your blog for visitor (any user that is not logged in)', 'aam'); ?>.
11
+ </div>
application/view/user.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class aam_View_User extends aam_View_Abstract {
18
+
19
+ /**
20
+ *
21
+ * @return type
22
+ */
23
+ public function content() {
24
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/user.phtml');
25
+ }
26
+
27
+ /**
28
+ *
29
+ * @return type
30
+ */
31
+ public function retrieveList() {
32
+ //get total number of users
33
+ $total = count_users();
34
+ $result = $this->query();
35
+ $response = array(
36
+ 'iTotalRecords' => $total['total_users'],
37
+ 'iTotalDisplayRecords' => $result->get_total(),
38
+ 'sEcho' => aam_Core_Request::request('sEcho'),
39
+ 'aaData' => array(),
40
+ );
41
+ foreach ($result->get_results() as $user) {
42
+ $response['aaData'][] = array(
43
+ $user->ID,
44
+ $user->user_login,
45
+ ($user->display_name ? $user->display_name : $user->user_nicename),
46
+ '',
47
+ $user->user_status
48
+ );
49
+ }
50
+
51
+ return json_encode($response);
52
+ }
53
+
54
+ /**
55
+ *
56
+ * @return \WP_User_Query
57
+ */
58
+ public function query() {
59
+ if ($search = trim(aam_Core_Request::request('sSearch'))) {
60
+ $search = "{$search}*";
61
+ }
62
+ $args = array(
63
+ 'number' => '',
64
+ 'blog_id' => get_current_blog_id(),
65
+ 'role' => aam_Core_Request::request('role'),
66
+ 'fields' => 'all',
67
+ 'number' => aam_Core_Request::request('iDisplayLength'),
68
+ 'offset' => aam_Core_Request::request('iDisplayStart'),
69
+ 'search' => $search,
70
+ 'search_columns' => array('user_login', 'user_email', 'display_name'),
71
+ 'orderby' => 'user_nicename',
72
+ 'order' => 'ASC'
73
+ );
74
+
75
+ return new WP_User_Query($args);
76
+ }
77
+
78
+ /**
79
+ *
80
+ * @return type
81
+ */
82
+ public function block() {
83
+ if ($this->getSubject()->block()){
84
+ $response = array(
85
+ 'status' => 'success',
86
+ 'user_status' => $this->getSubject()->user_status
87
+ );
88
+ } else{
89
+ $response = array('status' => 'failure');
90
+ }
91
+
92
+ return json_encode($response);
93
+ }
94
+
95
+ /**
96
+ *
97
+ * @return type
98
+ */
99
+ public function delete() {
100
+ return json_encode(
101
+ array(
102
+ 'status' => $this->getSubject()->delete() ? 'success' : 'failure'
103
+ )
104
+ );
105
+ }
106
+
107
+ }
application/view/visitor.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @package AAM
12
+ * @author Vasyl Martyniuk <support@wpaam.com>
13
+ * @copyright Copyright C 2013 Vasyl Martyniuk
14
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
15
+ */
16
+ class aam_View_Visitor extends aam_View_Abstract
17
+ {
18
+
19
+ /**
20
+ *
21
+ * @return type
22
+ */
23
+ public function content()
24
+ {
25
+ return $this->loadTemplate(dirname(__FILE__) . '/tmpl/visitor.phtml');
26
+ }
27
+
28
+ }
config.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+ define('AAM_BASE_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
10
+
11
+ //jean.yves.dumaine@gmail.com feedback - thank you
12
+ $base_url = WP_PLUGIN_URL . '/' . basename(AAM_BASE_DIR) . '/';
13
+ if (force_ssl_admin()) {
14
+ $base_url = str_replace('http', 'https', $base_url);
15
+ }
16
+ define('AAM_BASE_URL', $base_url);
17
+
18
+ define('AAM_TEMPLATE_DIR', AAM_BASE_DIR . 'view/html/');
19
+ define('AAM_LIBRARY_DIR', AAM_BASE_DIR . 'library/');
20
+ define('AAM_TEMP_DIR', WP_CONTENT_DIR . '/aam/');
21
+ define('AAM_MEDIA_URL', AAM_BASE_URL . 'media/');
22
+
23
+ define('AAM_APPL_ENV', (getenv('APPL_ENV') ? getenv('APPL_ENV') : 'production'));
24
+ //Rest API
25
+ if (AAM_APPL_ENV === 'production') {
26
+ define('WPAAM_REST_API', 'http://wpaam.com/rest');
27
+ } else {
28
+ define('WPAAM_REST_API', 'http://wpaam.localhost/rest');
29
+ }
30
+
31
+ /**
32
+ * Autoloader for project Advanced Access Manager
33
+ *
34
+ * Try to load a class if prefix is mvb_
35
+ *
36
+ * @param string $class_name
37
+ */
38
+ function aam_autoload($class_name) {
39
+ $chunks = explode('_', strtolower($class_name));
40
+ $prefix = array_shift($chunks);
41
+
42
+ if ($prefix === 'aam') {
43
+ $base_path = AAM_BASE_DIR . '/application';
44
+ $path = $base_path . '/' . implode('/', $chunks) . '.php';
45
+ if (file_exists($path)) {
46
+ require($path);
47
+ }
48
+ }
49
+ }
50
+
51
+ spl_autoload_register('aam_autoload');
52
+
53
+ function aam_content_folder() {
54
+ echo "<div class='update-nag'>";
55
+ echo __('<b>wp-content</b> folder is not writable or does not exists. ', 'aam');
56
+ echo '<a href="http://wpaam.com/support#viewtopic.php?f=4&t=23" target="_blank">';
57
+ echo __('Read more.', 'aam') . '</a>';
58
+ echo '</div>';
59
+ }
60
+
61
+ //make sure that we have always content dir
62
+ if (!file_exists(AAM_TEMP_DIR)) {
63
+ if (@mkdir(AAM_TEMP_DIR)) {
64
+ //silence the directory
65
+ file_put_contents(AAM_TEMP_DIR . '/index.php', '');
66
+ } else {
67
+ define('AAM_CONTENT_DIR_FAILURE', 1);
68
+ if (is_multisite()) {
69
+ add_action('network_admin_notices', 'aam_content_folder');
70
+ } else {
71
+ add_action('admin_notices', 'aam_content_folder');
72
+ }
73
+ }
74
+ }
75
+
76
+ load_plugin_textdomain('aam', false, basename(AAM_BASE_DIR) . '/lang');
77
+
78
+ //set migration admin notice. TODO - remove in July 15 2014
79
+ function aam_migration_note() {
80
+ if (class_exists('aam_Core_Migrate') && !aam_Core_API::getBlogOption('aam_migrated')) {
81
+ echo "<div class='update-nag'>";
82
+ echo __('Migrate your setting to new AAM platform. ', 'aam');
83
+ echo '<a href="#" id="aam_migrate">' . __('Click to Migrate', 'aam') . '</a>';
84
+ echo '</div>';
85
+ }
86
+ }
87
+
88
+ if (is_multisite()) {
89
+ add_action('network_admin_notices', 'aam_migration_note');
90
+ } else {
91
+ add_action('admin_notices', 'aam_migration_note');
92
+ }
core/class-mvb_coreplugin.php DELETED
@@ -1,62 +0,0 @@
1
- <?php
2
-
3
- /*
4
- Copyright (C) <2011> Vasyl Martyniuk <martyniuk.vasyl@gmail.com>
5
-
6
- This program is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- This program is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU General Public License for more details.
15
-
16
- You should have received a copy of the GNU General Public License
17
- along with this program. If not, see <http://www.gnu.org/licenses/>.
18
-
19
- */
20
-
21
- class mvb_corePlugin {
22
-
23
- function __construct() {
24
-
25
- if (is_admin()) {
26
- $this->scripts();
27
- $this->styles();
28
- }
29
- }
30
-
31
- function styles() {
32
- wp_enqueue_style('dashboard');
33
- wp_enqueue_style('global');
34
- wp_enqueue_style('wp-admin');
35
- }
36
-
37
- function scripts() {
38
- wp_enqueue_script('postbox');
39
- wp_enqueue_script('dashboard');
40
- wp_enqueue_script('thickbox');
41
- wp_enqueue_script('media-upload');
42
- }
43
-
44
- /**
45
- * Create a potbox widget
46
- */
47
- function postbox($id, $title, $content) {
48
- $content = '
49
- <div id="' . $id . '" class="postbox">
50
- <div class="handlediv" title="Click to toggle"><br /></div>
51
- <h3 class="hndle"><span>' . $title . '</span></h3>
52
- <div class="inside">
53
- ' . $content . '
54
- </div>
55
- </div>';
56
-
57
- return $content;
58
- }
59
-
60
- }
61
-
62
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
core/class-mvb_coretemplate.php DELETED
@@ -1,121 +0,0 @@
1
- <?php
2
-
3
- /*
4
- Copyright (C) <2011> Vasyl Martyniuk <martyniuk.vasyl@gmail.com>
5
-
6
- This program is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- This program is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU General Public License for more details.
15
-
16
- You should have received a copy of the GNU General Public License
17
- along with this program. If not, see <http://www.gnu.org/licenses/>.
18
-
19
- */
20
-
21
- /*
22
- * Template worker
23
- *
24
- * This class is helper for working with HTML files
25
- *
26
- * @version 1.0
27
- */
28
- class mvb_coreTemplate {
29
-
30
- /*
31
- * Read template from file
32
- *
33
- * Read file
34
- *
35
- * @param string Absolute path to file with template
36
- * @return mixed Return string on success and False if failed
37
- */
38
-
39
- function readTemplate($path) {
40
- if ($path) {
41
- $handle = fopen($path, "rb");
42
- if ($handle) {
43
- $template = fread($handle, filesize($path));
44
- fclose($handle);
45
- }
46
- }
47
-
48
- return ($template? $template :FALSE);
49
- }
50
- /*
51
- * Get subpart from template
52
- *
53
- * Searching for specified subpart in template and return subpart's content
54
- * if found. Example of subpart -
55
- * <!-- ###HELLO_WORLD### begin-->Some content<!-- ###HELLO_WORLD### end-->
56
- *
57
- * @param string Subpart name
58
- * @param string Template to search in
59
- * @return string
60
- */
61
-
62
- public function retrieveSub($subTemplate, $template) {
63
- $subPart = '';
64
- $regExp = '/<!\-\-[\s]?###' . $subTemplate . '###[\s]?begin\-\->';
65
- $regExp .= '(.*)<!\-\-[\s]?###' . $subTemplate . '###[\s]?end\-\->/si';
66
-
67
- if (preg_match($regExp, $template, $matches)) {
68
- $subPart = $matches[1];
69
- }
70
-
71
- return $subPart;
72
- }
73
-
74
- /*
75
- * Replace subpart with content
76
- *
77
- * Find proper subpart and replace it with content
78
- *
79
- * @param string Subpart name
80
- * @param string HTML content to replace with
81
- * @param string Template to search and replace in
82
- * @return string Template with replaced subpart
83
- */
84
-
85
- public function replaceSub($subTemplate, $content, $template) {
86
- $result = '';
87
-
88
- $regExp = '/<!\-\-[\s]?###' . $subTemplate . '###[\s]?begin\-\->';
89
- $regExp .= '.*<!\-\-[\s]?###' . $subTemplate . '###[\s]?end\-\->/si';
90
-
91
- return $template = preg_replace($regExp, $content, $template);
92
- }
93
-
94
- /*
95
- * Update markers in template
96
- *
97
- * Take array with key => value pair and replace key with value
98
- * Example of a marker - ###hello_world###
99
- *
100
- * @param array key => value pair array
101
- * @param string HTML template
102
- * @return string HTML template with replaced markers
103
- */
104
-
105
- public function updateMarkers($markers, $template) {
106
- if (is_array($markers)) {
107
- foreach($markers as $marker => $content){
108
- $template = str_replace($marker, $content, $template);
109
- }
110
- }
111
-
112
- return $template;
113
- }
114
-
115
- public function clearTemplate($template, $pattern = '/(###[a-z0-9_\-]+###)/si'){
116
-
117
- return preg_replace($pattern, '', $template);
118
- }
119
-
120
- }
121
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/images/info.png DELETED
Binary file
css/images/linkedin.png DELETED
Binary file
css/images/logo.png DELETED
Binary file
css/images/share_facebook.png DELETED
Binary file
css/images/share_friend.png DELETED
Binary file
css/images/twitter.png DELETED
Binary file
css/images/xit.gif DELETED
Binary file
css/tooltip/black.png DELETED
Binary file
css/tooltip/black_arrow.png DELETED
Binary file
css/tooltip/black_arrow_big.png DELETED
Binary file
css/tooltip/black_big.png DELETED
Binary file
css/tooltip/white.png DELETED
Binary file
css/tooltip/white_arrow.png DELETED
Binary file
css/tooltip/white_arrow_big.png DELETED
Binary file
css/tooltip/white_big.png DELETED
Binary file
css/ui/images/pbar-ani.gif DELETED
Binary file
css/ui/images/ui-bg_flat_0_aaaaaa_40x100.png DELETED
Binary file
css/ui/images/ui-bg_flat_75_ffffff_40x100.png DELETED
Binary file
css/ui/images/ui-bg_glass_55_fbf9ee_1x400.png DELETED
Binary file
css/ui/images/ui-bg_glass_65_ffffff_1x400.png DELETED
Binary file
css/ui/images/ui-bg_glass_75_dadada_1x400.png DELETED
Binary file
css/ui/images/ui-bg_glass_75_e6e6e6_1x400.png DELETED
Binary file
css/ui/images/ui-bg_glass_95_fef1ec_1x400.png DELETED
Binary file
css/ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png DELETED
Binary file
css/ui/images/ui-icons_222222_256x240.png DELETED
Binary file
css/ui/images/ui-icons_2e83ff_256x240.png DELETED
Binary file
css/ui/images/ui-icons_454545_256x240.png DELETED
Binary file
css/ui/images/ui-icons_888888_256x240.png DELETED
Binary file
css/ui/images/ui-icons_cd0a0a_256x240.png DELETED
Binary file
css/ui/jquery.ui.accordion.css DELETED
@@ -1,19 +0,0 @@
1
- /*
2
- * jQuery UI Accordion 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Accordion#theming
9
- */
10
- /* IE/Win - Fix animation bug - #4615 */
11
- .ui-accordion { width: 100%; }
12
- .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
13
- .ui-accordion .ui-accordion-li-fix { display: inline; }
14
- .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important;}
15
- .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
16
- .ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
17
- .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
18
- .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
19
- .ui-accordion .ui-accordion-content-active { display: block; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.all.css DELETED
@@ -1,11 +0,0 @@
1
- /*
2
- * jQuery UI CSS Framework 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Theming
9
- */
10
- @import "jquery.ui.base.css";
11
- @import "jquery.ui.theme.css";
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.autocomplete.css DELETED
@@ -1,53 +0,0 @@
1
- /*
2
- * jQuery UI Autocomplete 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Autocomplete#theming
9
- */
10
- .ui-autocomplete { position: absolute; cursor: default; }
11
-
12
- /* workarounds */
13
- * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
14
-
15
- /*
16
- * jQuery UI Menu 1.8.12
17
- *
18
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
19
- * Dual licensed under the MIT or GPL Version 2 licenses.
20
- * http://jquery.org/license
21
- *
22
- * http://docs.jquery.com/UI/Menu#theming
23
- */
24
- .ui-menu {
25
- list-style:none;
26
- padding: 2px;
27
- margin: 0;
28
- display:block;
29
- float: left;
30
- }
31
- .ui-menu .ui-menu {
32
- margin-top: -3px;
33
- }
34
- .ui-menu .ui-menu-item {
35
- margin:0;
36
- padding: 0;
37
- zoom: 1;
38
- float: left;
39
- clear: left;
40
- width: 100%;
41
- }
42
- .ui-menu .ui-menu-item a {
43
- text-decoration:none;
44
- display:block;
45
- padding:.2em .4em;
46
- line-height:1.5;
47
- zoom:1;
48
- }
49
- .ui-menu .ui-menu-item a.ui-state-hover,
50
- .ui-menu .ui-menu-item a.ui-state-active {
51
- font-weight: normal;
52
- margin: -1px;
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.base.css DELETED
@@ -1,6 +0,0 @@
1
- @import url("jquery.ui.core.css");
2
- @import url("jquery.ui.accordion.css");
3
- @import url("jquery.ui.button.css");
4
- @import url("jquery.ui.dialog.css");
5
- @import url("jquery.ui.tabs.css");
6
- @import url("jquery.ui.progressbar.css");
 
 
 
 
 
 
css/ui/jquery.ui.button.css DELETED
@@ -1,38 +0,0 @@
1
- /*
2
- * jQuery UI Button 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Button#theming
9
- */
10
- .ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
11
- .ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
12
- button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
13
- .ui-button-icons-only { width: 3.4em; }
14
- button.ui-button-icons-only { width: 3.7em; }
15
-
16
- /*button text element */
17
- .ui-button .ui-button-text { display: block; line-height: 1.4; }
18
- .ui-button-text-only .ui-button-text { padding: .4em 1em; }
19
- .ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
20
- .ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
21
- .ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
22
- .ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
23
- /* no icon support for input elements, provide padding by default */
24
- input.ui-button { padding: .4em 1em; }
25
-
26
- /*button icon element(s) */
27
- .ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
28
- .ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
29
- .ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
30
- .ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
31
- .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
32
-
33
- /*button sets*/
34
- .ui-buttonset { margin-right: 7px; }
35
- .ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
36
-
37
- /* workarounds */
38
- button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.core.css DELETED
@@ -1,41 +0,0 @@
1
- /*
2
- * jQuery UI CSS Framework 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Theming/API
9
- */
10
-
11
- /* Layout helpers
12
- ----------------------------------*/
13
- .ui-helper-hidden { display: none; }
14
- .ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
15
- .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
16
- .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
17
- .ui-helper-clearfix { display: inline-block; }
18
- /* required comment for clearfix to work in Opera \*/
19
- * html .ui-helper-clearfix { height:1%; }
20
- .ui-helper-clearfix { display:block; }
21
- /* end clearfix */
22
- .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
23
-
24
-
25
- /* Interaction Cues
26
- ----------------------------------*/
27
- .ui-state-disabled { cursor: default !important; }
28
-
29
-
30
- /* Icons
31
- ----------------------------------*/
32
-
33
- /* states and images */
34
- .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
35
-
36
-
37
- /* Misc visuals
38
- ----------------------------------*/
39
-
40
- /* Overlays */
41
- .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.datepicker.css DELETED
@@ -1,68 +0,0 @@
1
- /*
2
- * jQuery UI Datepicker 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Datepicker#theming
9
- */
10
- .ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
11
- .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
12
- .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
13
- .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
14
- .ui-datepicker .ui-datepicker-prev { left:2px; }
15
- .ui-datepicker .ui-datepicker-next { right:2px; }
16
- .ui-datepicker .ui-datepicker-prev-hover { left:1px; }
17
- .ui-datepicker .ui-datepicker-next-hover { right:1px; }
18
- .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
19
- .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
20
- .ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
21
- .ui-datepicker select.ui-datepicker-month-year {width: 100%;}
22
- .ui-datepicker select.ui-datepicker-month,
23
- .ui-datepicker select.ui-datepicker-year { width: 49%;}
24
- .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
25
- .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
26
- .ui-datepicker td { border: 0; padding: 1px; }
27
- .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
28
- .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
29
- .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
30
- .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
31
-
32
- /* with multiple calendars */
33
- .ui-datepicker.ui-datepicker-multi { width:auto; }
34
- .ui-datepicker-multi .ui-datepicker-group { float:left; }
35
- .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
36
- .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
37
- .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
38
- .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
39
- .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
40
- .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
41
- .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
42
- .ui-datepicker-row-break { clear:both; width:100%; }
43
-
44
- /* RTL support */
45
- .ui-datepicker-rtl { direction: rtl; }
46
- .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
47
- .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
48
- .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
49
- .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
50
- .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
51
- .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
52
- .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
53
- .ui-datepicker-rtl .ui-datepicker-group { float:right; }
54
- .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
55
- .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
56
-
57
- /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
58
- .ui-datepicker-cover {
59
- display: none; /*sorry for IE5*/
60
- display/**/: block; /*sorry for IE5*/
61
- position: absolute; /*must have*/
62
- z-index: -1; /*must have*/
63
- filter: mask(); /*must have*/
64
- top: -4px; /*must have*/
65
- left: -4px; /*must have*/
66
- width: 200px; /*must have*/
67
- height: 200px; /*must have*/
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.dialog.css DELETED
@@ -1,21 +0,0 @@
1
- /*
2
- * jQuery UI Dialog 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Dialog#theming
9
- */
10
- .ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
11
- .ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
12
- .ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
13
- .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
14
- .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
15
- .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
16
- .ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
17
- .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
18
- .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
19
- .ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
20
- .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
21
- .ui-draggable .ui-dialog-titlebar { cursor: move; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.progressbar.css DELETED
@@ -1,11 +0,0 @@
1
- /*
2
- * jQuery UI Progressbar 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Progressbar#theming
9
- */
10
- .ui-progressbar { height:2em; text-align: left; }
11
- .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.resizable.css DELETED
@@ -1,25 +0,0 @@
1
- /*
2
- * jQuery UI Resizable 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Resizable#theming
9
- */
10
- .ui-resizable { position: relative;}
11
- .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;
12
- /* http://bugs.jqueryui.com/ticket/7233
13
- - Resizable: resizable handles fail to work in IE if transparent and content overlaps
14
- */
15
- background-image:url(data:);
16
- }
17
- .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
18
- .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
19
- .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
20
- .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
21
- .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
22
- .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
23
- .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
24
- .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
25
- .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.selectable.css DELETED
@@ -1,10 +0,0 @@
1
- /*
2
- * jQuery UI Selectable 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Selectable#theming
9
- */
10
- .ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.slider.css DELETED
@@ -1,24 +0,0 @@
1
- /*
2
- * jQuery UI Slider 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Slider#theming
9
- */
10
- .ui-slider { position: relative; text-align: left; }
11
- .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
12
- .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
13
-
14
- .ui-slider-horizontal { height: .8em; }
15
- .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
16
- .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
17
- .ui-slider-horizontal .ui-slider-range-min { left: 0; }
18
- .ui-slider-horizontal .ui-slider-range-max { right: 0; }
19
-
20
- .ui-slider-vertical { width: .8em; height: 100px; }
21
- .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
22
- .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
23
- .ui-slider-vertical .ui-slider-range-min { bottom: 0; }
24
- .ui-slider-vertical .ui-slider-range-max { top: 0; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.tabs.css DELETED
@@ -1,18 +0,0 @@
1
- /*
2
- * jQuery UI Tabs 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Tabs#theming
9
- */
10
- .ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
11
- .ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
12
- .ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
13
- .ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
14
- .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
15
- .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
16
- .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
17
- .ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
18
- .ui-tabs .ui-tabs-hide { display: none !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/ui/jquery.ui.theme.css DELETED
@@ -1,252 +0,0 @@
1
- /*
2
- * jQuery UI CSS Framework 1.8.12
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Theming/API
9
- *
10
- * To view and modify this theme, visit http://jqueryui.com/themeroller/
11
- */
12
-
13
-
14
- /* Component containers
15
- ----------------------------------*/
16
- .ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; }
17
- .ui-widget .ui-widget { font-size: 1em; }
18
- .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; }
19
- .ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; }
20
- .ui-widget-content a { color: #222222/*{fcContent}*/; }
21
- .ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; }
22
- .ui-widget-header a { color: #222222/*{fcHeader}*/; }
23
-
24
- /* Interaction states
25
- ----------------------------------*/
26
- .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; }
27
- .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; }
28
- .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; }
29
- .ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; }
30
- .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; }
31
- .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; }
32
- .ui-widget :active { outline: none; }
33
-
34
- /* Interaction Cues
35
- ----------------------------------*/
36
- .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; }
37
- .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; }
38
- .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; }
39
- .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; }
40
- .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; }
41
- .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
42
- .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
43
- .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
44
-
45
- /* Icons
46
- ----------------------------------*/
47
-
48
- /* states and images */
49
- .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
50
- .ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
51
- .ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; }
52
- .ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; }
53
- .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; }
54
- .ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; }
55
- .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; }
56
- .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; }
57
-
58
- /* positioning */
59
- .ui-icon-carat-1-n { background-position: 0 0; }
60
- .ui-icon-carat-1-ne { background-position: -16px 0; }
61
- .ui-icon-carat-1-e { background-position: -32px 0; }
62
- .ui-icon-carat-1-se { background-position: -48px 0; }
63
- .ui-icon-carat-1-s { background-position: -64px 0; }
64
- .ui-icon-carat-1-sw { background-position: -80px 0; }
65
- .ui-icon-carat-1-w { background-position: -96px 0; }
66
- .ui-icon-carat-1-nw { background-position: -112px 0; }
67
- .ui-icon-carat-2-n-s { background-position: -128px 0; }
68
- .ui-icon-carat-2-e-w { background-position: -144px 0; }
69
- .ui-icon-triangle-1-n { background-position: 0 -16px; }
70
- .ui-icon-triangle-1-ne { background-position: -16px -16px; }
71
- .ui-icon-triangle-1-e { background-position: -32px -16px; }
72
- .ui-icon-triangle-1-se { background-position: -48px -16px; }
73
- .ui-icon-triangle-1-s { background-position: -64px -16px; }
74
- .ui-icon-triangle-1-sw { background-position: -80px -16px; }
75
- .ui-icon-triangle-1-w { background-position: -96px -16px; }
76
- .ui-icon-triangle-1-nw { background-position: -112px -16px; }
77
- .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
78
- .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
79
- .ui-icon-arrow-1-n { background-position: 0 -32px; }
80
- .ui-icon-arrow-1-ne { background-position: -16px -32px; }
81
- .ui-icon-arrow-1-e { background-position: -32px -32px; }
82
- .ui-icon-arrow-1-se { background-position: -48px -32px; }
83
- .ui-icon-arrow-1-s { background-position: -64px -32px; }
84
- .ui-icon-arrow-1-sw { background-position: -80px -32px; }
85
- .ui-icon-arrow-1-w { background-position: -96px -32px; }
86
- .ui-icon-arrow-1-nw { background-position: -112px -32px; }
87
- .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
88
- .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
89
- .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
90
- .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
91
- .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
92
- .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
93
- .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
94
- .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
95
- .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
96
- .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
97
- .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
98
- .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
99
- .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
100
- .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
101
- .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
102
- .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
103
- .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
104
- .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
105
- .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
106
- .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
107
- .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
108
- .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
109
- .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
110
- .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
111
- .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
112
- .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
113
- .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
114
- .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
115
- .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
116
- .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
117
- .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
118
- .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
119
- .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
120
- .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
121
- .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
122
- .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
123
- .ui-icon-arrow-4 { background-position: 0 -80px; }
124
- .ui-icon-arrow-4-diag { background-position: -16px -80px; }
125
- .ui-icon-extlink { background-position: -32px -80px; }
126
- .ui-icon-newwin { background-position: -48px -80px; }
127
- .ui-icon-refresh { background-position: -64px -80px; }
128
- .ui-icon-shuffle { background-position: -80px -80px; }
129
- .ui-icon-transfer-e-w { background-position: -96px -80px; }
130
- .ui-icon-transferthick-e-w { background-position: -112px -80px; }
131
- .ui-icon-folder-collapsed { background-position: 0 -96px; }
132
- .ui-icon-folder-open { background-position: -16px -96px; }
133
- .ui-icon-document { background-position: -32px -96px; }
134
- .ui-icon-document-b { background-position: -48px -96px; }
135
- .ui-icon-note { background-position: -64px -96px; }
136
- .ui-icon-mail-closed { background-position: -80px -96px; }
137
- .ui-icon-mail-open { background-position: -96px -96px; }
138
- .ui-icon-suitcase { background-position: -112px -96px; }
139
- .ui-icon-comment { background-position: -128px -96px; }
140
- .ui-icon-person { background-position: -144px -96px; }
141
- .ui-icon-print { background-position: -160px -96px; }
142
- .ui-icon-trash { background-position: -176px -96px; }
143
- .ui-icon-locked { background-position: -192px -96px; }
144
- .ui-icon-unlocked { background-position: -208px -96px; }
145
- .ui-icon-bookmark { background-position: -224px -96px; }
146
- .ui-icon-tag { background-position: -240px -96px; }
147
- .ui-icon-home { background-position: 0 -112px; }
148
- .ui-icon-flag { background-position: -16px -112px; }
149
- .ui-icon-calendar { background-position: -32px -112px; }
150
- .ui-icon-cart { background-position: -48px -112px; }
151
- .ui-icon-pencil { background-position: -64px -112px; }
152
- .ui-icon-clock { background-position: -80px -112px; }
153
- .ui-icon-disk { background-position: -96px -112px; }
154
- .ui-icon-calculator { background-position: -112px -112px; }
155
- .ui-icon-zoomin { background-position: -128px -112px; }
156
- .ui-icon-zoomout { background-position: -144px -112px; }
157
- .ui-icon-search { background-position: -160px -112px; }
158
- .ui-icon-wrench { background-position: -176px -112px; }
159
- .ui-icon-gear { background-position: -192px -112px; }
160
- .ui-icon-heart { background-position: -208px -112px; }
161
- .ui-icon-star { background-position: -224px -112px; }
162
- .ui-icon-link { background-position: -240px -112px; }
163
- .ui-icon-cancel { background-position: 0 -128px; }
164
- .ui-icon-plus { background-position: -16px -128px; }
165
- .ui-icon-plusthick { background-position: -32px -128px; }
166
- .ui-icon-minus { background-position: -48px -128px; }
167
- .ui-icon-minusthick { background-position: -64px -128px; }
168
- .ui-icon-close { background-position: -80px -128px; }
169
- .ui-icon-closethick { background-position: -96px -128px; }
170
- .ui-icon-key { background-position: -112px -128px; }
171
- .ui-icon-lightbulb { background-position: -128px -128px; }
172
- .ui-icon-scissors { background-position: -144px -128px; }
173
- .ui-icon-clipboard { background-position: -160px -128px; }
174
- .ui-icon-copy { background-position: -176px -128px; }
175
- .ui-icon-contact { background-position: -192px -128px; }
176
- .ui-icon-image { background-position: -208px -128px; }
177
- .ui-icon-video { background-position: -224px -128px; }
178
- .ui-icon-script { background-position: -240px -128px; }
179
- .ui-icon-alert { background-position: 0 -144px; }
180
- .ui-icon-info { background-position: -16px -144px; }
181
- .ui-icon-notice { background-position: -32px -144px; }
182
- .ui-icon-help { background-position: -48px -144px; }
183
- .ui-icon-check { background-position: -64px -144px; }
184
- .ui-icon-bullet { background-position: -80px -144px; }
185
- .ui-icon-radio-off { background-position: -96px -144px; }
186
- .ui-icon-radio-on { background-position: -112px -144px; }
187
- .ui-icon-pin-w { background-position: -128px -144px; }
188
- .ui-icon-pin-s { background-position: -144px -144px; }
189
- .ui-icon-play { background-position: 0 -160px; }
190
- .ui-icon-pause { background-position: -16px -160px; }
191
- .ui-icon-seek-next { background-position: -32px -160px; }
192
- .ui-icon-seek-prev { background-position: -48px -160px; }
193
- .ui-icon-seek-end { background-position: -64px -160px; }
194
- .ui-icon-seek-start { background-position: -80px -160px; }
195
- /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
196
- .ui-icon-seek-first { background-position: -80px -160px; }
197
- .ui-icon-stop { background-position: -96px -160px; }
198
- .ui-icon-eject { background-position: -112px -160px; }
199
- .ui-icon-volume-off { background-position: -128px -160px; }
200
- .ui-icon-volume-on { background-position: -144px -160px; }
201
- .ui-icon-power { background-position: 0 -176px; }
202
- .ui-icon-signal-diag { background-position: -16px -176px; }
203
- .ui-icon-signal { background-position: -32px -176px; }
204
- .ui-icon-battery-0 { background-position: -48px -176px; }
205
- .ui-icon-battery-1 { background-position: -64px -176px; }
206
- .ui-icon-battery-2 { background-position: -80px -176px; }
207
- .ui-icon-battery-3 { background-position: -96px -176px; }
208
- .ui-icon-circle-plus { background-position: 0 -192px; }
209
- .ui-icon-circle-minus { background-position: -16px -192px; }
210
- .ui-icon-circle-close { background-position: -32px -192px; }
211
- .ui-icon-circle-triangle-e { background-position: -48px -192px; }
212
- .ui-icon-circle-triangle-s { background-position: -64px -192px; }
213
- .ui-icon-circle-triangle-w { background-position: -80px -192px; }
214
- .ui-icon-circle-triangle-n { background-position: -96px -192px; }
215
- .ui-icon-circle-arrow-e { background-position: -112px -192px; }
216
- .ui-icon-circle-arrow-s { background-position: -128px -192px; }
217
- .ui-icon-circle-arrow-w { background-position: -144px -192px; }
218
- .ui-icon-circle-arrow-n { background-position: -160px -192px; }
219
- .ui-icon-circle-zoomin { background-position: -176px -192px; }
220
- .ui-icon-circle-zoomout { background-position: -192px -192px; }
221
- .ui-icon-circle-check { background-position: -208px -192px; }
222
- .ui-icon-circlesmall-plus { background-position: 0 -208px; }
223
- .ui-icon-circlesmall-minus { background-position: -16px -208px; }
224
- .ui-icon-circlesmall-close { background-position: -32px -208px; }
225
- .ui-icon-squaresmall-plus { background-position: -48px -208px; }
226
- .ui-icon-squaresmall-minus { background-position: -64px -208px; }
227
- .ui-icon-squaresmall-close { background-position: -80px -208px; }
228
- .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
229
- .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
230
- .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
231
- .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
232
- .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
233
- .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
234
-
235
-
236
- /* Misc visuals
237
- ----------------------------------*/
238
-
239
- /* Corner radius */
240
- .ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; }
241
- .ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; }
242
- .ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; }
243
- .ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; }
244
- .ui-corner-top { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; }
245
- .ui-corner-bottom { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; }
246
- .ui-corner-right { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; }
247
- .ui-corner-left { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; }
248
- .ui-corner-all { -moz-border-radius: 4px/*{cornerRadius}*/; -webkit-border-radius: 4px/*{cornerRadius}*/; border-radius: 4px/*{cornerRadius}*/; }
249
-
250
- /* Overlays */
251
- .ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; }
252
- .ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/wpaccess_style.css DELETED
@@ -1,326 +0,0 @@
1
- #wp-access{
2
- display:none;
3
- }
4
-
5
- #metabox-list{
6
- margin-top: 20px;
7
- }
8
-
9
- #current-role-display{
10
- font-weight: bold;
11
- }
12
-
13
- .new-capability{
14
- float:left;
15
- }
16
-
17
- .additional-panel{
18
- width: 100%;
19
- margin-top: 10px;
20
- height: auto;
21
- }
22
-
23
- .plugin-logo{
24
- background: url('images/logo.png') no-repeat;
25
- float:left;
26
- margin:10px 0 10px 30px;
27
- width:40px;
28
- height:40px;
29
- }
30
-
31
- .delete-role-table{
32
- width:100%;
33
- }
34
-
35
- .delete-role-table tr:hover{
36
- background-color: #E6E6E6;
37
- cursor: pointer;
38
- }
39
-
40
- .dialog{
41
- display:none;
42
- }
43
-
44
- #new-role-name{
45
- font-size: 10px;
46
- width:150px;
47
- }
48
-
49
- .new-role-name-empty{
50
- position:absolute;
51
- margin: 5px 0 0 7px;
52
- color: #9E9B9B;
53
- font: 11px "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif
54
- }
55
-
56
- .initiate-url-empty{
57
- position:absolute;
58
- margin: 8px 0 0 7px;
59
- color: #9E9B9B;
60
- font: 12px "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif
61
- }
62
-
63
- .delete-role-table td{
64
- font-size: 12px;
65
- padding: 3px 0px;
66
- }
67
-
68
- .message-active{
69
- display:block;
70
- float:left;
71
- width:70%;
72
- margin: 5px 0;
73
- }
74
- .message-passive{
75
- display:none;
76
- }
77
-
78
- .plugin-title{
79
- float:left;
80
- margin:0px 0 0 15px;
81
- }
82
-
83
- .misc-role-section{
84
- margin: 10px 0 0 10px;
85
- }
86
-
87
- .change-role{
88
- font-size: 10px;
89
- }
90
-
91
- .misc-role-section label{
92
- font-size: 11px;
93
- }
94
-
95
- #role-select{
96
- margin-top: 5px;
97
- }
98
-
99
- #new-role-message-ok, #new-role-message-error{
100
- display:none;
101
- }
102
-
103
- .mainmenu-subitem-whole{
104
- width:100%;
105
- margin-bottom: 5px;
106
- }
107
- .mainmenu-subitem{
108
- width: 200px;
109
- float: left;
110
- }
111
-
112
- .capability-item{
113
- width: 200px;
114
- margin-bottom: 5px;
115
- float:left;
116
- font-size: 11px;
117
- }
118
-
119
- #capability-form input{
120
- width: 85%;
121
- }
122
-
123
- .submenu-holder{
124
- padding: 2px 0 5px 3px;
125
- }
126
-
127
- .ajax-loader-big{
128
- background: url('images/ajax-loader.gif') no-repeat;
129
- width:100px;
130
- height:100px;
131
- z-index:1999;
132
- position: absolute;
133
- top:0px;
134
- left:0px;
135
- }
136
-
137
- .loading-new{
138
- opacity : 0.4;
139
- filter: alpha(opacity=40);
140
- }
141
-
142
- .tooltip {
143
- display:none;
144
- background:url(tooltip/black_big.png);
145
- height:163px;
146
- padding:25px 30px 10px 30px;
147
- width:310px;
148
- font-size:11px;
149
- color:#fff;
150
- z-index: 1000;
151
- }
152
- /*
153
- .tooltip {
154
- display:none;
155
- background-color:#ffa;
156
- border:1px solid #cc9;
157
- padding:3px;
158
- font-size:13px;
159
- -moz-box-shadow: 2px 2px 11px #666;
160
- -webkit-box-shadow: 2px 2px 11px #666;
161
- }
162
-
163
- */
164
-
165
- .description-table{
166
- width: 100%;
167
- }
168
-
169
- .description-table td{
170
- font-size:11px;
171
- }
172
-
173
- .tooltip a{
174
- color: #ff853c;
175
- font-weight: bold;
176
- }
177
-
178
- .info{
179
- font-weight: bold;
180
- }
181
-
182
- #progressbar{
183
- height: 22px;
184
- width:98%;
185
- margin-left: auto;
186
- margin-right: auto;
187
- display:none;
188
- }
189
-
190
- .ui-progressbar-value {
191
- background-image: url(ui/images/pbar-ani.gif);
192
- }
193
-
194
- .metaboxlist-holder{
195
- margin-top: 10px;
196
- }
197
-
198
- .metabox-item{
199
- width: 280px;
200
- float:left;
201
- margin-left: 10px;
202
- }
203
-
204
- .metabox-description th{
205
- text-align: right;
206
- font-size: 10px;
207
- padding-top: 5px;
208
- }
209
-
210
- .metabox-description td{
211
- padding: 5px 0 0 15px;
212
- }
213
-
214
- .initiate-url-text{
215
- width:70%;
216
- }
217
-
218
- #metabox-wpaccess-general p{
219
- text-align: justify;
220
- }
221
-
222
- .default-roles{
223
- float:right;
224
- }
225
-
226
- .capability-name{
227
- float:left;
228
- }
229
-
230
- .info{
231
- float: left;
232
- }
233
- .capability-delete{
234
- width: 10px;
235
- height: 10px;
236
- background: url(images/xit.gif) no-repeat;
237
- margin-top:2px;
238
- float: left;
239
- margin-left: 10px;
240
- cursor: pointer;
241
- }
242
-
243
-
244
- .capability-delete:hover{
245
- background: url(images/xit.gif) no-repeat -10px 0;
246
- }
247
-
248
- .capability-description{
249
- width: 10px;
250
- height: 10px;
251
- background: url(images/info.png) no-repeat;
252
- margin-top:2px;
253
- margin-left: 10px;
254
- cursor: pointer;
255
- }
256
-
257
-
258
- .capability-description:hover{
259
- background: url(images/info.png) no-repeat -10px 0;
260
- }
261
-
262
- /* SEXY BOOKMARKS */
263
- div.sexy-bookmarks {
264
- margin:10px 0 0 0;
265
- clear: both;
266
- }
267
-
268
- div.sexy-bookmarks ul.socials {
269
- background:transparent none;
270
- border:0 none;
271
- outline:0 none;
272
- }
273
-
274
- div.sexy-bookmarks ul.socials li {
275
- display:inline;
276
- float:left;
277
- list-style-type:none;
278
- margin:0;
279
- height:29px;
280
- width:55px;
281
- cursor:pointer;
282
- padding:0;
283
- background-color:transparent;
284
- border:0 none;
285
- outline:0 none;
286
- }
287
-
288
- div.sexy-bookmarks ul.socials a {
289
- display:block !important;
290
- width:50px !important;
291
- height:29px !important;
292
- text-indent: -9999px !important;
293
- background-color:transparent !important;
294
- }
295
-
296
- .sexy-mail {
297
- background: url('images/share_friend.png') no-repeat bottom;
298
- }
299
- .sexy-mail:hover {
300
- background: url('images/share_friend.png') no-repeat top;
301
- }
302
-
303
- .sexy-facebook {
304
- background: url('images/share_facebook.png') no-repeat bottom;
305
- }
306
- .sexy-facebook:hover {
307
- background: url('images/share_facebook.png') no-repeat top;
308
- }
309
-
310
- .sexy-twitter {
311
- background: url('images/twitter.png') no-repeat bottom;
312
- }
313
- .sexy-twitter:hover {
314
- background: url('images/twitter.png') no-repeat top;
315
- }
316
-
317
- .sexy-linkedin {
318
- background: url('images/linkedin.png') no-repeat bottom;
319
- }
320
- .sexy-linkedin:hover {
321
- background: url('images/linkedin.png') no-repeat top;
322
- }
323
-
324
- #emergency-curl{
325
- display : none;
326
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/configpress.pdf ADDED
Binary file
extension/AAM_Multisite_Support/extension.php ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ *
12
+ * @package AAM
13
+ * @author Vasyl Martyniuk <support@wpaam.com>
14
+ * @copyright Copyright C 2013 Vasyl Martyniuk
15
+ * @license GNU General Public License {@link http://www.gnu.org/licenses/}
16
+ */
17
+ class AAM_Extension_Multisite {
18
+
19
+ /**
20
+ *
21
+ * @var type
22
+ */
23
+ private $_parent = null;
24
+
25
+ /**
26
+ *
27
+ * @var type
28
+ */
29
+ private $_subject = null;
30
+
31
+ /**
32
+ *
33
+ * @param aam|aam_View_Connector $parent
34
+ */
35
+ public function __construct(aam $parent) {
36
+ $this->setParent($parent);
37
+ if (aam_Core_API::isNetworkPanel()) {
38
+ add_action('admin_print_scripts', array($this, 'printScripts'));
39
+ add_action('admin_print_styles', array($this, 'printStyles'));
40
+ add_action('aam_localization_labels', array($this, 'localizationLabels'));
41
+ add_filter('aam_ui_subjects', array($this, 'addUISubject'), 10, 1);
42
+ add_action('wpmu_new_blog', array($this, 'newBlog'), 10, 6);
43
+ } elseif (is_admin()) {
44
+ add_filter('aam_ajax_call', array($this, 'ajax'), 10, 2);
45
+ }
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param type $blog_id
51
+ * @param type $user_id
52
+ * @param type $domain
53
+ * @param type $path
54
+ * @param type $site_id
55
+ * @param type $meta
56
+ */
57
+ public function newBlog($blog_id, $user_id, $domain, $path, $site_id, $meta) {
58
+ global $wpdb;
59
+
60
+ if ($default_id = aam_Core_API::getBlogOption('aam_default_site', 0, 1)){
61
+ $default_option = $wpdb->get_blog_prefix($default_id) . 'user_roles';
62
+ $roles = aam_Core_API::getBlogOption($default_option, null, $default_id);
63
+ if ($roles){
64
+ aam_Core_API::updateBlogOption(
65
+ $wpdb->get_blog_prefix($blog_id) . 'user_roles',
66
+ $roles, $blog_id
67
+ );
68
+ }
69
+ }
70
+ }
71
+
72
+ /**
73
+ *
74
+ * @return type
75
+ */
76
+ protected function getSiteList() {
77
+ //retrieve site list first
78
+ $blog_list = $this->retrieveSiteList();
79
+
80
+ $response = array(
81
+ 'iTotalRecords' => count($blog_list),
82
+ 'iTotalDisplayRecords' => count($blog_list),
83
+ 'sEcho' => aam_Core_Request::request('sEcho'),
84
+ 'aaData' => array(),
85
+ );
86
+ $default = aam_Core_API::getBlogOption('aam_default_site', 0, 1);
87
+
88
+ foreach ($blog_list as $site) {
89
+ $blog = get_blog_details($site->blog_id);
90
+ $response['aaData'][] = array(
91
+ $site->blog_id,
92
+ get_admin_url($site->blog_id, 'admin.php'),
93
+ get_admin_url($site->blog_id, 'admin-ajax.php'),
94
+ $blog->blogname,
95
+ '',
96
+ ($site->blog_id == $default ? 1 : 0)
97
+ );
98
+ }
99
+
100
+ return json_encode($response);
101
+ }
102
+
103
+ /**
104
+ * Retieve the list of sites
105
+ *
106
+ * @return array
107
+ *
108
+ * @access public
109
+ */
110
+ public function retrieveSiteList(){
111
+ global $wpdb;
112
+
113
+ return $wpdb->get_results('SELECT blog_id FROM ' . $wpdb->blogs);
114
+ }
115
+
116
+ /**
117
+ *
118
+ * @param type $subjects
119
+ * @return type
120
+ */
121
+ public function addUISubject($subjects) {
122
+ $subjects['multisite'] = array(
123
+ 'position' => 1,
124
+ 'segment' => 'multisite',
125
+ 'label' => __('Sites', 'aam'),
126
+ 'title' => __('Site Manager', 'aam'),
127
+ 'class' => 'manager-item manager-item-multisite',
128
+ 'id' => 'aam_multisite',
129
+ 'content' => array($this, 'content')
130
+ );
131
+
132
+ return $subjects;
133
+ }
134
+
135
+ /**
136
+ *
137
+ * @return type
138
+ */
139
+ public function content() {
140
+ ob_start();
141
+ require_once dirname(__FILE__) . '/ui.phtml';
142
+ $content = ob_get_contents();
143
+ ob_clean();
144
+
145
+ return $content;
146
+ }
147
+
148
+ /**
149
+ * Print necessary scripts
150
+ *
151
+ * @return void
152
+ *
153
+ * @access public
154
+ */
155
+ public function printScripts() {
156
+ if ($this->getParent()->isAAMScreen()) {
157
+ wp_enqueue_script(
158
+ 'aam-multisite-admin', AAM_MULTISITE_BASE_URL . '/multisite.js', array('aam-admin')
159
+ );
160
+ $localization = array(
161
+ 'nonce' => wp_create_nonce('aam_ajax'),
162
+ 'addSiteURI' => admin_url('network/site-new.php'),
163
+ 'editSiteURI' => admin_url('network/site-info.php')
164
+ );
165
+
166
+ wp_localize_script(
167
+ 'aam-multisite-admin', 'aamMultisiteLocal', $localization
168
+ );
169
+ }
170
+ }
171
+
172
+ /**
173
+ *
174
+ */
175
+ public function printStyles() {
176
+ if ($this->getParent()->isAAMScreen()) {
177
+ wp_enqueue_style(
178
+ 'aam-multisite-admin', AAM_MULTISITE_BASE_URL . '/multisite.css'
179
+ );
180
+ }
181
+ }
182
+
183
+ /**
184
+ *
185
+ * @param type $labels
186
+ * @return type
187
+ */
188
+ public function localizationLabels($labels) {
189
+ $labels['Set Default'] = __('Set Default', 'aam');
190
+ $labels['Unset Default'] = __('Unset Default', 'aam');
191
+ $labels['Set as Default'] = __('Set as Default', 'aam');
192
+
193
+ return $labels;
194
+ }
195
+
196
+ /**
197
+ *
198
+ * @param type $default
199
+ * @param aam_Control_Subject $subject
200
+ * @return type
201
+ */
202
+ public function ajax($default, aam_Control_Subject $subject = null) {
203
+ $this->setSubject($subject);
204
+
205
+ switch (aam_Core_Request::request('sub_action')) {
206
+ case 'site_list':
207
+ $response = $this->getSiteList();
208
+ break;
209
+
210
+ case 'pin_site':
211
+ $response = $this->pinSite();
212
+ break;
213
+
214
+ case 'unpin_site':
215
+ $response = $this->unpinSite();
216
+ break;
217
+
218
+ default:
219
+ $response = $default;
220
+ break;
221
+ }
222
+
223
+ return $response;
224
+ }
225
+
226
+ protected function pinSite() {
227
+ return json_encode(array(
228
+ 'status' => aam_Core_API::updateBlogOption(
229
+ 'aam_default_site', aam_Core_Request::post('blog'), 1
230
+ ) ? 'success' : 'failure'
231
+ ));
232
+ }
233
+
234
+ protected function unpinSite() {
235
+ return json_encode(array(
236
+ 'status' => aam_Core_API::deleteBlogOption('aam_default_site', 1) ? 'success' : 'failure'
237
+ ));
238
+ }
239
+
240
+ /**
241
+ *
242
+ * @param aam $parent
243
+ */
244
+ public function setParent(aam $parent) {
245
+ $this->_parent = $parent;
246
+ }
247
+
248
+ /**
249
+ *
250
+ * @return aam
251
+ */
252
+ public function getParent() {
253
+ return $this->_parent;
254
+ }
255
+
256
+ /**
257
+ *
258
+ * @param type $subject
259
+ */
260
+ public function setSubject($subject) {
261
+ $this->_subject = $subject;
262
+ }
263
+
264
+ /**
265
+ *
266
+ * @return type
267
+ */
268
+ public function getSubject() {
269
+ return $this->_subject;
270
+ }
271
+
272
+ }
extension/AAM_Multisite_Support/images/add-active.png ADDED
Binary file
extension/AAM_Multisite_Support/images/add.png ADDED
Binary file
extension/AAM_Multisite_Support/images/edit-active.png ADDED
Binary file
extension/AAM_Multisite_Support/images/edit.png ADDED
Binary file
extension/AAM_Multisite_Support/images/manage-active.png ADDED
Binary file
extension/AAM_Multisite_Support/images/manage.png ADDED
Binary file
extension/AAM_Multisite_Support/images/multisite-active.png ADDED
Binary file
extension/AAM_Multisite_Support/images/multisite.png ADDED
Binary file
extension/AAM_Multisite_Support/images/pin-active.png ADDED
Binary file
extension/AAM_Multisite_Support/images/pin.png ADDED
Binary file
extension/AAM_Multisite_Support/images/refresh-active.png ADDED
Binary file
extension/AAM_Multisite_Support/images/refresh.png ADDED
Binary file
extension/AAM_Multisite_Support/images/unpin.png ADDED
Binary file
extension/AAM_Multisite_Support/index.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+
9
+ $dirname = basename(dirname(__FILE__));
10
+ define('AAM_MULTISITE_BASE_URL', AAM_BASE_URL . 'extension/' . $dirname);
11
+
12
+ require_once dirname(__FILE__) . '/extension.php';
13
+
14
+ return new AAM_Extension_Multisite($this->getParent());
extension/AAM_Multisite_Support/multisite.css ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * ======================================================================
3
+ * LICENSE: This file is subject to the terms and conditions defined in *
4
+ * file 'license.txt', which is part of this source code package. *
5
+ * ======================================================================
6
+ */
7
+
8
+ /** CONTROL MANAGER STYLES **/
9
+ .manager-item-multisite{
10
+ background-image: url('images/multisite.png');
11
+ }
12
+
13
+ .manager-item-multisite-active{
14
+ background-image: url('images/multisite-active.png');
15
+ }
16
+
17
+ .multisite-top-actions{
18
+ float: right;
19
+ display: inline-table;
20
+ width: auto;
21
+ text-align: right;
22
+ }
23
+
24
+ .multisite-top-action{
25
+ width: 24px;
26
+ height: 24px;
27
+ display: table-cell;
28
+ text-indent: -9999px;
29
+ padding-right: 10px;
30
+ background-repeat: no-repeat;
31
+ background-position: center;
32
+ }
33
+
34
+ .multisite-top-action-add{
35
+ background-image: url('images/add.png');
36
+ }
37
+
38
+ .multisite-top-action-add:hover{
39
+ background-image: url('images/add-active.png');
40
+ }
41
+
42
+ .multisite-top-action-refresh{
43
+ background-image: url('images/refresh.png');
44
+ }
45
+
46
+ .multisite-top-action-refresh:hover{
47
+ background-image: url('images/refresh-active.png');
48
+ }
49
+
50
+ .multisite-actions{
51
+ width: 100%;
52
+ display: table;
53
+ }
54
+
55
+ .multisite-action{
56
+ width: 16px;
57
+ height: 16px;
58
+ display: table-cell;
59
+ text-indent: -9999px;
60
+ background-repeat: no-repeat;
61
+ background-position: center;
62
+ }
63
+
64
+ .multisite-action-manage{
65
+ background-image: url('images/manage.png');
66
+ }
67
+
68
+ .multisite-action-manage:hover{
69
+ background-image: url('images/manage-active.png');
70
+ }
71
+
72
+ .multisite-action-manage-active{
73
+ background-image: url('images/manage-active.png');
74
+ }
75
+
76
+ .multisite-action-pin{
77
+ background-image: url('images/pin.png');
78
+ }
79
+
80
+ .multisite-action-pin-active{
81
+ background-image: url('images/pin-active.png');
82
+ }
83
+
84
+ .multisite-action-pin:hover{
85
+ background-image: url('images/pin-active.png');
86
+ }
87
+
88
+ .multisite-action-edit{
89
+ background-image: url('images/edit.png');
90
+ }
91
+
92
+ .multisite-action-edit:hover{
93
+ background-image: url('images/edit-active.png');
94
+ }
95
+
96
+ .aam-multisite-bold{
97
+ font-weight: bold;
98
+ }
extension/AAM_Multisite_Support/multisite.js ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * ======================================================================
3
+ * LICENSE: This file is subject to the terms and conditions defined in *
4
+ * file 'license.txt', which is part of this source code package. *
5
+ * ======================================================================
6
+ */
7
+
8
+ AAM.prototype.site_id = 1;
9
+ AAM.prototype.segmentTables.siteList = null;
10
+
11
+ AAM.prototype.reloadSite = function(site_id, siteurl, ajaxurl) {
12
+ var _this = this;
13
+ this.site_id = site_id;
14
+ aamLocal.siteURI = siteurl;
15
+ aamLocal.ajaxurl = ajaxurl;
16
+
17
+ //reset default values for current subjects
18
+ this.setSubject('role', aamLocal.defaultSegment.role);
19
+
20
+ this.retrieveSettings();
21
+
22
+ //highlight the active site
23
+ jQuery('#site_list .aam-multisite-bold').removeClass('aam-multisite-bold');
24
+ jQuery('#site_list .multisite-action-manage-active').each(function() {
25
+ _this.terminate(jQuery(this), 'multisite-action-manage');
26
+ });
27
+ var nRow = jQuery('#site_list tr[site="' + site_id + '"]');
28
+ jQuery('td:eq(0)', nRow).addClass('aam-multisite-bold');
29
+ this.launch(jQuery('.multisite-action-manage', nRow), 'multisite-action-manage');
30
+
31
+ //reload all segmentTables
32
+ for (var i in this.segmentTables) {
33
+ if (this.segmentTables[i] !== null) {
34
+ this.segmentTables[i].fnDraw();
35
+ }
36
+ }
37
+ };
38
+
39
+ AAM.prototype.loadMultisiteSegment = function() {
40
+ var _this = this;
41
+
42
+ if (typeof this.siteList === 'undefined') {
43
+ this.siteList = jQuery('#site_list').dataTable({
44
+ sDom: "<'top'f<'multisite-top-actions'><'clear'>>t<'footer'ip<'clear'>>",
45
+ bServerSide: true,
46
+ sPaginationType: "full_numbers",
47
+ bAutoWidth: false,
48
+ bSort: false,
49
+ sAjaxSource: ajaxurl,
50
+ fnServerParams: function(aoData) {
51
+ aoData.push({
52
+ name: 'action',
53
+ value: 'aam'
54
+ });
55
+ aoData.push({
56
+ name: 'sub_action',
57
+ value: 'site_list'
58
+ });
59
+ aoData.push({
60
+ name: '_ajax_nonce',
61
+ value: aamLocal.nonce
62
+ });
63
+ aoData.push({
64
+ name: 's',
65
+ value: jQuery('#site_list_filter input').val()
66
+ });
67
+ },
68
+ fnInitComplete: function() {
69
+ var add = jQuery('<a/>', {
70
+ 'href': aamMultisiteLocal.addSiteURI,
71
+ 'target': '_blank',
72
+ 'class': 'multisite-top-action multisite-top-action-add',
73
+ 'tooltip': aamLocal.labels['Add New Site']
74
+ });
75
+ jQuery('#site_list_wrapper .multisite-top-actions').append(add);
76
+
77
+ var refresh = jQuery('<a/>', {
78
+ 'href': '#',
79
+ 'class': 'multisite-top-action multisite-top-action-refresh',
80
+ 'tooltip': aamLocal.labels['Refresh']
81
+ }).bind('click', function(event) {
82
+ event.preventDefault();
83
+ _this.siteList.fnDraw();
84
+ });
85
+ jQuery('#site_list_wrapper .multisite-top-actions').append(refresh);
86
+
87
+ _this.initTooltip(jQuery('#site_list_wrapper .site-top-actions'));
88
+ },
89
+ fnDrawCallback: function() {
90
+ jQuery('#multisite_list_wrapper .clear-table-filter').bind('click', function(event) {
91
+ event.preventDefault();
92
+ jQuery('#multisite_list_filter input').val('');
93
+ _this.siteList.fnFilter('');
94
+ });
95
+ },
96
+ oLanguage: {
97
+ sSearch: "",
98
+ oPaginate: {
99
+ sFirst: "&Lt;",
100
+ sLast: "&Gt;",
101
+ sNext: "&gt;",
102
+ sPrevious: "&lt;"
103
+ }
104
+ },
105
+ aoColumnDefs: [
106
+ {
107
+ bVisible: false,
108
+ aTargets: [0, 1, 2, 4]
109
+ }
110
+ ],
111
+ fnRowCallback: function(nRow, aData) { //format data
112
+ jQuery('td:eq(1)', nRow).html(jQuery('<div/>', {
113
+ 'class': 'multisite-actions'
114
+ })); //
115
+ //add role attribute
116
+ jQuery(nRow).attr('site', aData[0]);
117
+
118
+ if (parseInt(aData[0]) === _this.site_id) {
119
+ jQuery('.current-site').html(aData[3] + ':');
120
+ jQuery('td:eq(0)', nRow).addClass('aam-multisite-bold');
121
+ var current = true;
122
+ } else {
123
+ current = false;
124
+ }
125
+
126
+ jQuery('.multisite-actions', nRow).empty();
127
+ jQuery('.multisite-actions', nRow).append(jQuery('<a/>', {
128
+ 'href': '#',
129
+ 'class': 'multisite-action multisite-action-manage' + (current ? '-active' : ''),
130
+ 'tooltip': aamLocal.labels['Manage']
131
+ }).bind('click', function(event) {
132
+ event.preventDefault();
133
+ //change title
134
+ jQuery('.current-site').html(aData[3] + ':');
135
+ _this.reloadSite(aData[0], aData[1], aData[2]);
136
+ }));
137
+
138
+ var def_site = (parseInt(aData[5]) === 1 ? true : false);
139
+
140
+ jQuery('.multisite-actions', nRow).append(jQuery('<a/>', {
141
+ 'href': '#',
142
+ 'class': 'multisite-action multisite-action-pin' + (def_site ? '-active' : ''),
143
+ 'tooltip': (def_site ? aamLocal.labels['Unset Default'] : aamLocal.labels['Set as Default'])
144
+ }).bind('click', function(event) {
145
+ event.preventDefault();
146
+ var button = this;
147
+
148
+ if (def_site) {
149
+ var unpin_data = _this.compileAjaxPackage('unpin_site', false);
150
+ unpin_data.blog = aData[0];
151
+ jQuery.ajax(ajaxurl, {
152
+ type: 'POST',
153
+ dataType: 'json',
154
+ data: unpin_data,
155
+ success: function(response) {
156
+ if (response.status === 'success') {
157
+ _this.siteList.fnDraw();
158
+ }
159
+ _this.highlight('.control-manager-content', response.status);
160
+ },
161
+ error: function() {
162
+ _this.highlight('.control-manager-content', 'failure');
163
+ }
164
+ });
165
+ } else {
166
+ jQuery('#default_site').html(aData[3]);
167
+ var pin_data = _this.compileAjaxPackage('pin_site', false);
168
+ pin_data.blog = aData[0];
169
+
170
+ var buttons = {};
171
+ buttons[aamLocal.labels['Set Default']] = function() {
172
+ jQuery.ajax(ajaxurl, {
173
+ type: 'POST',
174
+ dataType: 'json',
175
+ data: pin_data,
176
+ success: function(response) {
177
+ if (response.status === 'success') {
178
+ _this.siteList.fnDraw();
179
+ }
180
+ _this.highlight('.control-manager-content', response.status);
181
+ },
182
+ error: function() {
183
+ _this.highlight('.control-manager-content', 'failure');
184
+ },
185
+ complete: function() {
186
+ jQuery("#tap_default_site").dialog("close");
187
+ }
188
+ });
189
+ jQuery("#tap_default_site").dialog("close");
190
+ };
191
+ buttons[aamLocal.labels['Cancel']] = function() {
192
+ jQuery("#tap_default_site").dialog("close");
193
+ };
194
+
195
+ jQuery("#tap_default_site").dialog({
196
+ resizable: false,
197
+ height: 'auto',
198
+ modal: true,
199
+ buttons: buttons
200
+ });
201
+ }
202
+ }));
203
+
204
+ jQuery('.multisite-actions', nRow).append(jQuery('<a/>', {
205
+ 'href': aamMultisiteLocal.editSiteURI + '?id=' + aData[0],
206
+ 'class': 'multisite-action multisite-action-edit',
207
+ 'target': '_blank',
208
+ 'tooltip': aamLocal.labels['Edit']
209
+ }));
210
+
211
+ _this.initTooltip(nRow);
212
+ },
213
+ fnInfoCallback: function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
214
+ return (iMax !== iTotal ? _this.clearFilterIndicator() : '');
215
+ }
216
+ });
217
+ }
218
+
219
+ jQuery('#multisite_manager_wrap').show();
220
+ };
221
+
222
+ jQuery(document).ready(function() {
223
+ aamInterface.addAction('aam_load_segment', function() {
224
+ aamInterface.loadMultisiteSegment();
225
+ });
226
+ //by default load the Multisite panel first
227
+ aamInterface.loadSegment('multisite');
228
+ });
extension/AAM_Multisite_Support/ui.phtml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ======================================================================
4
+ * LICENSE: This file is subject to the terms and conditions defined in *
5
+ * file 'license.txt', which is part of this source code package. *
6
+ * ======================================================================
7
+ */
8
+ ?>
9
+ <div id="multisite_manager_wrap">
10
+ <table id="site_list">
11
+ <thead>
12
+ <tr>
13
+ <th>Site ID</th>
14
+ <th>Site URL</th>
15
+ <th>Site Ajax URL</th>
16
+ <th width="65%"><?php echo __('Site', 'aam'); ?></th>
17
+ <th><?php echo __('Action', 'aam'); ?></th>
18
+ <th>Default</th>
19
+ </tr>
20
+ </thead>
21
+ <tbody></tbody>
22
+ </table>
23
+ <div id="tap_default_site" class="aam-dialog" title="<?php echo __('Set Default Site', 'aam'); ?>">
24
+ <p class="dialog-content">
25
+ <?php echo __('Would you like to set the site', 'aam'); ?> <b><span id="default_site"></span></b> <?php echo __('as default?', 'aam'); ?>
26
+ </p>
27
+ <p class="dialog-note">
28
+ <?php echo __('All newly created sites will inherit list of Roles & Capabilities.', 'aam'); ?>
29
+ </p>
30
+ </div>
31
+ </div>
js/admin-options.js DELETED
@@ -1,605 +0,0 @@
1
- /*
2
- Copyright (C) <2011> Vasyl Martyniuk <martyniuk.vasyl@gmail.com>
3
-
4
- This program is free software: you can redistribute it and/or modify
5
- it under the terms of the GNU General Public License as published by
6
- the Free Software Foundation, either version 3 of the License, or
7
- (at your option) any later version.
8
-
9
- This program is distributed in the hope that it will be useful,
10
- but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- GNU General Public License for more details.
13
-
14
- You should have received a copy of the GNU General Public License
15
- along with this program. If not, see <http://www.gnu.org/licenses/>.
16
-
17
- */
18
-
19
- function mvbam_object(){
20
- /*
21
- * Indicates how many changes happend on form
22
- *
23
- * @var int
24
- * @access private
25
- */
26
- this.formChanged = 0;
27
-
28
- /*
29
- * Array of pre-defined capabilities for default WP roles
30
- *
31
- * @var array
32
- * @access private
33
- */
34
- this.roleCapabilities = {
35
- radio2 : ['moderate_comments', 'manage_categories', 'manage_links', 'upload_files',
36
- 'unfiltered_html', 'edit_posts', 'edit_others_posts', 'edit_published_posts',
37
- 'publish_posts', 'edit_pages', 'read', 'level_7', 'level_6', 'level_5', 'level_4',
38
- 'level_3', 'level_2', 'level_1', 'level_0', 'edit_others_pages', 'edit_published_pages',
39
- 'publish_pages', 'delete_pages', 'delete_others_pages', 'delete_published_pages',
40
- 'delete_posts', 'delete_others_posts', 'delete_published_posts', 'delete_private_posts',
41
- 'read_private_posts', 'delete_private_pages', 'edit_private_pages', 'read_private_pages'],
42
- radio3 : ['upload_files', 'edit_posts', 'edit_others_posts', 'edit_published_posts',
43
- 'publish_posts', 'read', 'level_2', 'level_1', 'level_0', 'delete_posts', 'delete_published_posts',],
44
- radio4 : ['edit_posts', 'read', 'level_1', 'level_0', 'delete_posts'],
45
- radio5 : ['read', 'level_0']
46
- }
47
- }
48
-
49
- /*
50
- * **
51
- */
52
- mvbam_object.prototype.addNewRole = function(){
53
- var newRoleTitle = jQuery.trim(jQuery('#new-role-name').val());
54
- if (!newRoleTitle){
55
- jQuery('#new-role-name').effect('highlight',3000);
56
- return;
57
- }
58
- jQuery('#new-role-name').val('');
59
- jQuery('.new-role-name-empty').show();
60
- this.showAjaxLoader('#tabs');
61
- var params = {
62
- 'action' : 'mvbam',
63
- 'sub_action' : 'create_role',
64
- '_ajax_nonce': wpaccessLocal.nonce,
65
- 'role' : newRoleTitle
66
- };
67
- var _this = this;
68
- jQuery.post(ajaxurl, params, function(data){
69
- if (data.result == 'success'){
70
- var nOption = '<option value="'+data.new_role+'">'+newRoleTitle+'</option>';
71
- jQuery('#role option:last').after(nOption);
72
- jQuery('#role').val(data.new_role);
73
- _this.getRoleOptionList(data.new_role);
74
- jQuery('div #new-role-form').hide();
75
- jQuery('.change-role').show();
76
- //jQuery('#new-role-message-error').hide();
77
- jQuery('.delete-role-table tbody').append(data.html);
78
- jQuery('#new-role-message-ok').show().delay(2000).hide('slow');
79
-
80
- }else{
81
- _this.removeAjaxLoader('#tabs');
82
- // jQuery('#new-role-message-ok').hide();
83
- jQuery('#new-role-message-error').show().delay(2000).hide('slow');
84
- }
85
- }, 'json');
86
- }
87
-
88
- mvbam_object.prototype.showAjaxLoader = function(selector){
89
- jQuery(selector).addClass('loading-new');
90
- jQuery(selector).prepend('<div class="ajax-loader-big"></div>');
91
- jQuery('.ajax-loader-big').css({
92
- top: 150,
93
- left: jQuery(selector).width()/2 - 25
94
- });
95
- }
96
-
97
- mvbam_object.prototype.getRoleOptionList = function(currentRoleID){
98
- this.showAjaxLoader('#tabs');
99
-
100
- var params = {
101
- 'action' : 'render_rolelist',
102
- '_ajax_nonce': wpaccessLocal.nonce,
103
- 'role' : currentRoleID
104
- };
105
- jQuery('#current_role').val(currentRoleID);
106
- var _this = this;
107
- jQuery.post(wpaccessLocal.handlerURL, params, function(data){
108
- jQuery('#tabs').tabs('destroy');
109
- jQuery('#tabs').replaceWith(data.html);
110
- _this.configureElements();
111
- jQuery('div #role-select').hide();
112
- jQuery('#current-role-display').html(jQuery('#role option:selected').text());
113
- jQuery('.change-role').show();
114
- //hide or show Restore Default according to server options
115
- if (data.restorable){
116
- //sorry to lazy to create my own style :)
117
- jQuery('#delete-action').show();
118
- }else{
119
- jQuery('#delete-action').hide();
120
- }
121
- }, 'json');
122
- }
123
-
124
- mvbam_object.prototype.configureElements = function(){
125
- this.configureMainMenu();
126
- this.configureMetaboxes();
127
- this.configureCapabilities();
128
- }
129
-
130
- mvbam_object.prototype.configureMainMenu = function(){
131
- jQuery( "#tabs" ).tabs();
132
- this.configureAccordion("#main-menu-options");
133
- jQuery('#main-menu-options > div').each(function(){
134
- jQuery('#whole', this).bind('click',{
135
- _this: this
136
- }, function(event){
137
- var checked = (jQuery(this).attr('checked') ? true : false);
138
- jQuery('input:checkbox', event.data._this).attr('checked', checked);
139
- });
140
- });
141
- }
142
-
143
- mvbam_object.prototype.configureMetaboxes = function(){
144
- this.configureAccordion('#metabox-list');
145
- var _this = this;
146
- jQuery('.initiate-metaboxes').bind('click', function(event){
147
- jQuery('#initiate-message').hide();
148
- jQuery('#progressbar').progressbar({
149
- value: 0
150
- }).show();
151
- _this.initiationChain('');
152
- });
153
-
154
- jQuery('.initiate-url').bind('click', function(event){
155
- var val = jQuery('.initiate-url-text').val();
156
- if (jQuery.trim(val)){
157
- jQuery('#initiate-message').hide();
158
- jQuery('#progressbar').progressbar({
159
- value: 20
160
- }).show();
161
- var params = {
162
- 'action' : 'mvbam',
163
- 'sub_action' : 'initiate_url',
164
- '_ajax_nonce': wpaccessLocal.nonce,
165
- 'url' : val
166
- };
167
- jQuery.post(ajaxurl, params, function(data){
168
- jQuery('.initiate-url-text').val('');
169
- jQuery('.initiate-url-empty').show();
170
- if (data.status == 'success'){
171
- jQuery('#progressbar').progressbar('option', 'value', 100);
172
- _this.grabInitiatedWM();
173
- }else{
174
- _this.emergencyCall(data);
175
- }
176
- }, 'json');
177
- }else{
178
- jQuery('.initiate-url-text').effect('highlight',3000);
179
- }
180
- });
181
-
182
- jQuery('.initiate-url-empty').click(function(){
183
- jQuery('#initiateURL').focus();
184
- });
185
- jQuery('#initiateURL').focus(function(){
186
- jQuery('.initiate-url-empty').hide();
187
- });
188
- jQuery('#initiateURL').blur(function(){
189
- if (!jQuery.trim(jQuery(this).val())){
190
- jQuery('.initiate-url-empty').show();
191
- }
192
- });
193
- }
194
-
195
- mvbam_object.prototype.configureCapabilities = function(){
196
- var _this = this;
197
- jQuery(".capability-description").each(function(){
198
- if(jQuery(this).attr('title')){
199
- jQuery(this).tooltip({
200
- position : 'center right',
201
- events : {
202
- def: "click,mouseout",
203
- input: "focus,blur",
204
- widget: "focus mouseover,blur mouseout",
205
- tooltip: "mouseover,mouseout"
206
- }
207
- });
208
- }else{
209
- jQuery(this).remove();
210
- }
211
- });
212
-
213
- jQuery('.default-roles').buttonset();
214
- jQuery('#new-capability').button({
215
- icons: {
216
- primary: "ui-icon-plus"
217
- }
218
- }).bind('click', function(e){
219
- e.preventDefault();
220
- _this.addNewCapability();
221
- });
222
- }
223
-
224
- mvbam_object.prototype.addNewCapability = function(){
225
- jQuery( "#capability-form #new-cap" ).val('').focus();
226
- jQuery( "#capability-form" ).dialog({
227
- resizable: false,
228
- height:150,
229
- modal: false,
230
- buttons: {
231
- "Add Capability": function() {
232
- var cap = jQuery( "#capability-form #new-cap" ).val();
233
-
234
- if (jQuery.trim(cap)){
235
- jQuery( this ).dialog( "close" );
236
- var params = {
237
- 'action' : 'mvbam',
238
- 'sub_action' : 'add_capability',
239
- '_ajax_nonce': wpaccessLocal.nonce,
240
- 'cap' : cap,
241
- 'role' : jQuery('#role').val()
242
- };
243
- jQuery.post(ajaxurl, params, function(data){
244
- if (data.status == 'success'){
245
- jQuery('.capability-item:last').after(data.html);
246
- jQuery('.capability-item:last .info').remove();
247
- }else{
248
- alert(data.message);
249
- }
250
- }, 'json');
251
- }else{
252
- jQuery( "#capability-form #new-cap" ).effect('highlight', 5000);
253
- }
254
- },
255
- Cancel: function() {
256
- jQuery( this ).dialog( "close" );
257
- }
258
- }
259
- });
260
- }
261
-
262
- mvbam_object.prototype.emergencyCall = function(data){
263
- var _this = this;
264
- jQuery.ajax(data.url, {
265
- success : function(){
266
- if (data.next){
267
- _this.initiationChain(data.next);
268
- }else{
269
- jQuery('#progressbar').progressbar("option", "value", 100);
270
- _this.grabInitiatedWM();
271
- }
272
- },
273
- error : function(jqXHR, textStatus, errorThrown){
274
- if (textStatus != 'timeout'){
275
- if (data.next){
276
- _this.initiationChain(data.next);
277
- }else{
278
- jQuery('#progressbar').progressbar("option", "value", 100);
279
- _this.grabInitiatedWM();
280
- }
281
- }else{
282
- alert('Error Appears during Metabox initialization!');
283
- jQuery('#progressbar').progressbar("option", "value", 100);
284
- _this.grabInitiatedWM();
285
- }
286
- },
287
- timeout : 5000
288
- });
289
-
290
- }
291
-
292
- mvbam_object.prototype.initiationChain = function(next){
293
- //start initiation
294
- var params = {
295
- 'action' : 'mvbam',
296
- 'sub_action' : 'initiate_wm',
297
- '_ajax_nonce': wpaccessLocal.nonce,
298
- 'next' : next
299
- };
300
- var _this = this;
301
- jQuery.post(ajaxurl, params, function(data){
302
- jQuery('#progressbar').progressbar("option", "value", data.value);
303
- if (data.status == 'success'){
304
- if (data.next){
305
- _this.initiationChain(data.next);
306
- }else{
307
- jQuery('#progressbar').progressbar("option", "value", 100);
308
- _this.grabInitiatedWM();
309
- }
310
- }else{
311
- //try directly to go to that page
312
- _this.emergencyCall(data);
313
- }
314
- }, 'json');
315
- }
316
-
317
- mvbam_object.prototype.grabInitiatedWM = function(){
318
- jQuery('#progressbar').progressbar('destroy').hide();
319
- jQuery('#initiate-message').show();
320
- jQuery('#metabox-list').empty().css({
321
- 'height' : '200px',
322
- 'width' : '100%'
323
- });
324
- this.showAjaxLoader('#metabox-list');
325
- var params = {
326
- 'action' : 'mvbam',
327
- 'sub_action' : 'render_metabox_list',
328
- '_ajax_nonce': wpaccessLocal.nonce,
329
- 'role' : jQuery('#current_role').val()
330
- };
331
- var _this = this;
332
- jQuery.post(ajaxurl, params, function(data){
333
- jQuery('#metabox-list').replaceWith(data);
334
- _this.configureAccordion('#metabox-list');
335
- });
336
- }
337
-
338
- mvbam_object.prototype.configureAccordion = function(selector){
339
- var icons = {
340
- header: "ui-icon-circle-arrow-e",
341
- headerSelected: "ui-icon-circle-arrow-s"
342
- };
343
-
344
- jQuery(selector).accordion({
345
- collapsible: true,
346
- header: 'h4',
347
- autoHeight: false,
348
- icons: icons,
349
- active: -1
350
- });
351
- }
352
-
353
- mvbam_object.prototype.deleteRole = function(role){
354
- jQuery('#delete-role-title').html(jQuery('.delete-role-table #dl-row-'+role+' td:first').html());
355
- var _this = this;
356
- jQuery( "#dialog-delete-confirm" ).dialog({
357
- resizable: false,
358
- height:180,
359
- modal: true,
360
- buttons: {
361
- "Delete Role": function() {
362
- var params = {
363
- 'action' : 'mvbam',
364
- 'sub_action' : 'delete_role',
365
- '_ajax_nonce': wpaccessLocal.nonce,
366
- 'role' : role
367
- };
368
- jQuery.post(ajaxurl, params, function(){
369
- jQuery('.delete-role-table #dl-row-' + role).remove();
370
- if (jQuery('#role option[value="'+role+'"]').attr('selected')){
371
- _this.getRoleOptionList(jQuery('#role option:first').val());
372
- }
373
- jQuery('#role option[value="'+role+'"]').remove();
374
- });
375
- jQuery( this ).dialog( "close" );
376
- },
377
- Cancel: function() {
378
- jQuery( this ).dialog( "close" );
379
- }
380
- }
381
- });
382
- }
383
-
384
- mvbam_object.prototype.changeCapabilities = function(type){
385
- switch(type){
386
- case 'radio1': //administrator
387
- jQuery('.capability-item input').attr('checked', true);
388
- break;
389
-
390
- case 'radio2': //editor
391
- case 'radio3': //author
392
- case 'radio4': //contributor
393
- case 'radio5': //subscriber
394
- jQuery('.capability-item input').attr('checked', false);
395
- for (var c in this.roleCapabilities[type]){
396
- jQuery('.capability-item input[name*="['+this.roleCapabilities[type][c]+']"]').attr('checked', true);
397
- }
398
- break;
399
-
400
- case 'radio6': //clear all
401
- jQuery('.capability-item input').attr('checked', false);
402
- break;
403
-
404
- default:
405
- break;
406
- }
407
- }
408
-
409
- mvbam_object.prototype.changeRole = function(){
410
- var currentRoleID = jQuery('#role').val();
411
- this.getRoleOptionList(currentRoleID);
412
- this.formChanged = 0;
413
- }
414
-
415
- mvbam_object.prototype.submitForm = function(){
416
- this.formChanged = -1;
417
- jQuery('#ajax-loading').show();
418
- }
419
-
420
- mvbam_object.prototype.goodbye = function(e){
421
- if (this.formChanged > 0){
422
- if(!e) e = window.event;
423
- //e.cancelBubble is supported by IE - this will kill the bubbling process.
424
- e.cancelBubble = true;
425
- e.returnValue = 'You sure you want to leave?'; //This is displayed on the dialog
426
-
427
- //e.stopPropagation works in Firefox.
428
- if (e.stopPropagation) {
429
- e.stopPropagation();
430
- e.preventDefault();
431
- }
432
- }
433
- }
434
-
435
- mvbam_object.prototype.restoreDefault = function(){
436
- var _this = this;
437
- jQuery( "#dialog-confirm" ).dialog({
438
- resizable: false,
439
- height:180,
440
- modal: true,
441
- buttons: {
442
- "Restore": function() {
443
- var role = jQuery('#current_role').val();
444
- var params = {
445
- 'action' : 'mvbam',
446
- 'sub_action' : 'restore_role',
447
- '_ajax_nonce': wpaccessLocal.nonce,
448
- 'role' : role
449
- };
450
- var _dialog = this;
451
- jQuery.post(ajaxurl, params, function(data){
452
- if (data.status == 'success'){
453
- _this.getRoleOptionList(role);
454
- }else{
455
- //TODO - Implement error
456
- alert('Current Role can not be restored!');
457
- }
458
- jQuery( _dialog ).dialog( "close" );
459
- },'json');
460
- },
461
- Cancel: function() {
462
- jQuery( this ).dialog( "close" );
463
- }
464
- }
465
- });
466
- }
467
-
468
- mvbam_object.prototype.removeAjaxLoader = function(selector){
469
- jQuery(selector).removeClass('loading-new');
470
- jQuery('.ajax-loader-big').remove();
471
- }
472
-
473
- mvbam_object.prototype.deleteCapability = function(cap, label){
474
- jQuery('#delete-capability-title').html(label);
475
- var _this = this;
476
- jQuery( "#dialog-delete-capability" ).dialog({
477
- resizable: false,
478
- height:180,
479
- modal: true,
480
- buttons: {
481
- "Delete Capability": function() {
482
- var params = {
483
- 'action' : 'mvbam',
484
- 'sub_action' : 'delete_capability',
485
- '_ajax_nonce': wpaccessLocal.nonce,
486
- 'cap' : cap
487
- };
488
- jQuery.post(ajaxurl, params, function(data){
489
- if (data.status == 'success'){
490
- jQuery('#cap-' + cap).parent().parent().remove();
491
- }else{
492
- alert(data.message);
493
- }
494
- }, 'json');
495
- jQuery( this ).dialog( "close" );
496
- },
497
- Cancel: function() {
498
- jQuery( this ).dialog( "close" );
499
- }
500
- }
501
- });
502
- }
503
-
504
- //**********************************************
505
-
506
- jQuery(document).ready(function(){
507
-
508
- try{
509
- mObj = new mvbam_object();
510
-
511
- mObj.configureElements();
512
- jQuery('.change-role').bind('click', function(e){
513
- e.preventDefault();
514
- jQuery('div #role-select').show();
515
- jQuery(this).hide();
516
- });
517
-
518
- jQuery('#role-ok').bind('click', function(e){
519
- e.preventDefault();
520
- if (mObj.formChanged > 0){
521
- jQuery( "#leave-confirm" ).dialog({
522
- resizable: false,
523
- height: 180,
524
- modal: true,
525
- buttons: {
526
- "Change Role": function() {
527
- jQuery( this ).dialog( "close" );
528
- mObj.changeRole();
529
- },
530
- Cancel: function() {
531
- jQuery( this ).dialog( "close" );
532
- }
533
- }
534
- });
535
- }else{
536
- mObj.changeRole();
537
- }
538
-
539
- });
540
-
541
-
542
- jQuery('.new-role-name-empty').click(function(e){
543
- e.preventDefault();
544
- jQuery('#new-role-name').focus();
545
- });
546
- jQuery('#new-role-name').focus(function(){
547
- jQuery('.new-role-name-empty').hide();
548
- });
549
- jQuery('#new-role-name').blur(function(){
550
- if (!jQuery.trim(jQuery(this).val())){
551
- jQuery('.new-role-name-empty').show();
552
- }
553
- });
554
- jQuery('#new-role-name').keypress(function(event){
555
- if (event.which == 13){
556
- event.preventDefault();
557
- mObj.addNewRole();
558
- };
559
- });
560
-
561
- jQuery('#wp-access').keypress(function(event){
562
- if (event.which == 13){
563
- event.preventDefault();
564
- };
565
- });
566
-
567
- jQuery('#new-role-ok').bind('click', function(e){
568
- e.preventDefault();
569
- mObj.addNewRole();
570
- });
571
-
572
- jQuery('#role-cancel').bind('click', function(e){
573
- e.preventDefault();
574
- jQuery('div #role-select').hide();
575
- jQuery('.change-role').show();
576
- });
577
- jQuery('#new-role-cancel').bind('click', function(e){
578
- e.preventDefault();
579
- jQuery('div #new-role-form').hide();
580
- jQuery('.change-role').show();
581
- });
582
-
583
- jQuery('#role-tabs').tabs();
584
-
585
- jQuery('.deletion').bind('click', function(e){
586
- e.preventDefault();
587
- mObj.restoreDefault();
588
- });
589
-
590
- jQuery('#wp-access').bind('change', function(e){
591
- mObj.formChanged++;
592
- });
593
- jQuery('#role').bind('change', function(e){
594
- mObj.formChanged -= 1;
595
- });
596
-
597
- jQuery('.message-active').show().delay(5000).hide('slow');
598
-
599
- //window.onbeforeunload = mObj.goodbye;
600
-
601
- jQuery('#wp-access').show();
602
- }catch(err){
603
- jQuery('#wp-access').show();
604
- }
605
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/jquery.tools.min.js DELETED
@@ -1,145 +0,0 @@
1
- /*!
2
- * jQuery Tools v1.2.5 - The missing UI library for the Web
3
- *
4
- * tooltip/tooltip.js
5
- *
6
- * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
7
- *
8
- * http://flowplayer.org/tools/
9
- *
10
- */
11
- (function(a){
12
- a.tools=a.tools||{
13
- version:"v1.2.5"
14
- },a.tools.tooltip={
15
- conf:{
16
- effect:"toggle",
17
- fadeOutSpeed:"fast",
18
- predelay:0,
19
- delay:30,
20
- opacity:1,
21
- tip:0,
22
- position:["top","center"],
23
- offset:[0,0],
24
- relative:!1,
25
- cancelDefault:!0,
26
- events:{
27
- def:"mouseenter,mouseleave",
28
- input:"focus,blur",
29
- widget:"focus mouseenter,blur mouseleave",
30
- tooltip:"mouseenter,mouseleave"
31
- },
32
- layout:"<div/>",
33
- tipClass:"tooltip"
34
- },
35
- addEffect:function(a,c,d){
36
- b[a]=[c,d]
37
- }
38
- };
39
-
40
- var b={
41
- toggle:[function(a){
42
- var b=this.getConf(),c=this.getTip(),d=b.opacity;
43
- d<1&&c.css({
44
- opacity:d
45
- }),c.show(),a.call()
46
- },function(a){
47
- this.getTip().hide(),a.call()
48
- }],
49
- fade:[function(a){
50
- var b=this.getConf();
51
- this.getTip().fadeTo(b.fadeInSpeed,b.opacity,a)
52
- },function(a){
53
- this.getTip().fadeOut(this.getConf().fadeOutSpeed,a)
54
- }]
55
- };
56
-
57
- function c(b,c,d){
58
- var e=d.relative?b.position().top:b.offset().top,f=d.relative?b.position().left:b.offset().left,g=d.position[0];
59
- e-=c.outerHeight()-d.offset[0],f+=b.outerWidth()+d.offset[1],/iPad/i.test(navigator.userAgent)&&(e-=a(window).scrollTop());
60
- var h=c.outerHeight()+b.outerHeight();
61
- g=="center"&&(e+=h/2),g=="bottom"&&(e+=h),g=d.position[1];
62
- var i=c.outerWidth()+b.outerWidth();
63
- g=="center"&&(f-=i/2),g=="left"&&(f-=i);
64
- return{
65
- top:e,
66
- left:f
67
- }
68
- }
69
- function d(d,e){
70
- var f=this,g=d.add(f),h,i=0,j=0,k=d.attr("title"),l=d.attr("data-tooltip"),m=b[e.effect],n,o=d.is(":input"),p=o&&d.is(":checkbox, :radio, select, :button, :submit"),q=d.attr("type"),r=e.events[q]||e.events[o?p?"widget":"input":"def"];
71
- if(!m)throw"Nonexistent effect \""+e.effect+"\"";
72
- r=r.split(/,\s*/);
73
- if(r.length!=2)throw"Tooltip: bad events configuration for "+q;
74
- d.bind(r[0],function(a){
75
- clearTimeout(i),e.predelay?j=setTimeout(function(){
76
- f.show(a)
77
- },e.predelay):f.show(a)
78
- }).bind(r[1],function(a){
79
- clearTimeout(j),e.delay?i=setTimeout(function(){
80
- f.hide(a)
81
- },e.delay):f.hide(a)
82
- }),k&&e.cancelDefault&&(d.removeAttr("title"),d.data("title",k)),a.extend(f,{
83
- show:function(b){
84
- if(!h){
85
- l?h=a(l):e.tip?h=a(e.tip).eq(0):k?h=a(e.layout).addClass(e.tipClass).appendTo(document.body).hide().append(k):(h=d.next(),h.length||(h=d.parent().next()));
86
- if(!h.length)throw"Cannot find tooltip for "+d
87
- }
88
- if(f.isShown())return f;
89
- h.stop(!0,!0);
90
- var o=c(d,h,e);
91
- e.tip&&h.html(d.data("title")),b=b||a.Event(),b.type="onBeforeShow",g.trigger(b,[o]);
92
- if(b.isDefaultPrevented())return f;
93
- o=c(d,h,e),h.css({
94
- position:"absolute",
95
- top:o.top,
96
- left:o.left
97
- }),n=!0,m[0].call(f,function(){
98
- b.type="onShow",n="full",g.trigger(b)
99
- });
100
- var p=e.events.tooltip.split(/,\s*/);
101
- h.data("__set")||(h.bind(p[0],function(){
102
- clearTimeout(i),clearTimeout(j)
103
- }),p[1]&&!d.is("input:not(:checkbox, :radio), textarea")&&h.bind(p[1],function(a){
104
- a.relatedTarget!=d[0]&&d.trigger(r[1].split(" ")[0])
105
- }),h.data("__set",!0));
106
- return f
107
- },
108
- hide:function(c){
109
- if(!h||!f.isShown())return f;
110
- c=c||a.Event(),c.type="onBeforeHide",g.trigger(c);
111
- if(!c.isDefaultPrevented()){
112
- n=!1,b[e.effect][1].call(f,function(){
113
- c.type="onHide",g.trigger(c)
114
- });
115
- return f
116
- }
117
- },
118
- isShown:function(a){
119
- return a?n=="full":n
120
- },
121
- getConf:function(){
122
- return e
123
- },
124
- getTip:function(){
125
- return h
126
- },
127
- getTrigger:function(){
128
- return d
129
- }
130
- }),a.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","),function(b,c){
131
- a.isFunction(e[c])&&a(f).bind(c,e[c]),f[c]=function(b){
132
- b&&a(f).bind(c,b);
133
- return f
134
- }
135
- })
136
- }
137
- a.fn.tooltip=function(b){
138
- var c=this.data("tooltip");
139
- if(c)return c;
140
- b=a.extend(!0,{},a.tools.tooltip.conf,b),typeof b.position=="string"&&(b.position=b.position.split(/,?\s/)),this.each(function(){
141
- c=new d(a(this),b),a(this).data("tooltip",c)
142
- });
143
- return b.api?c:this
144
- }
145
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/ui/jquery-ui.min.js DELETED
@@ -1,259 +0,0 @@
1
- /*!
2
- * jQuery UI 1.8.15
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI
9
- */
10
- (function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.15",
11
- keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=
12
- this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,
13
- "overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":
14
- "mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,
15
- outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a,
16
- "tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&
17
- a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&
18
- c.ui.isOverAxis(b,e,i)}})}})(jQuery);
19
- ;/*!
20
- * jQuery UI Widget 1.8.15
21
- *
22
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
23
- * Dual licensed under the MIT or GPL Version 2 licenses.
24
- * http://jquery.org/license
25
- *
26
- * http://docs.jquery.com/UI/Widget
27
- */
28
- (function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,
29
- a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.charAt(0)==="_")return h;
30
- e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,
31
- this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},
32
- widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},
33
- enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
34
- ;/*!
35
- * jQuery UI Mouse 1.8.15
36
- *
37
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
38
- * Dual licensed under the MIT or GPL Version 2 licenses.
39
- * http://jquery.org/license
40
- *
41
- * http://docs.jquery.com/UI/Mouse
42
- *
43
- * Depends:
44
- * jquery.ui.widget.js
45
- */
46
- (function(b){b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(c){return a._mouseDown(c)}).bind("click."+this.widgetName,function(c){if(true===b.data(c.target,a.widgetName+".preventClickEvent")){b.removeData(c.target,a.widgetName+".preventClickEvent");c.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=
47
- a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var c=this,e=a.which==1,f=typeof this.options.cancel=="string"?b(a.target).closest(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){c.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==
48
- false;if(!this._mouseStarted){a.preventDefault();return true}}true===b.data(a.target,this.widgetName+".preventClickEvent")&&b.removeData(a.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(d){return c._mouseMove(d)};this._mouseUpDelegate=function(d){return c._mouseUp(d)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(b.browser.msie&&
49
- !(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=
50
- false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
51
- ;/*
52
- * jQuery UI Position 1.8.15
53
- *
54
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
55
- * Dual licensed under the MIT or GPL Version 2 licenses.
56
- * http://jquery.org/license
57
- *
58
- * http://docs.jquery.com/UI/Position
59
- */
60
- (function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
61
- left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
62
- k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=
63
- m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=
64
- d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
65
- a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
66
- g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
67
- ;/*
68
- * jQuery UI Accordion 1.8.15
69
- *
70
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
71
- * Dual licensed under the MIT or GPL Version 2 licenses.
72
- * http://jquery.org/license
73
- *
74
- * http://docs.jquery.com/UI/Accordion
75
- *
76
- * Depends:
77
- * jquery.ui.core.js
78
- * jquery.ui.widget.js
79
- */
80
- (function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");
81
- a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
82
- if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",
83
- function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a=
84
- this.options;if(a.icons){c("<span></span>").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex");
85
- this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();
86
- b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target);
87
- a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+
88
- c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options;
89
- if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);
90
- if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(),
91
- e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight||
92
- e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false",
93
- "aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.15",
94
- animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);
95
- f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",
96
- paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
97
- ;/*
98
- * jQuery UI Button 1.8.15
99
- *
100
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
101
- * Dual licensed under the MIT or GPL Version 2 licenses.
102
- * http://jquery.org/license
103
- *
104
- * http://docs.jquery.com/UI/Button
105
- *
106
- * Depends:
107
- * jquery.ui.core.js
108
- * jquery.ui.widget.js
109
- */
110
- (function(b){var h,i,j,g,l=function(){var a=b(this).find(":ui-button");setTimeout(function(){a.button("refresh")},1)},k=function(a){var c=a.name,e=a.form,f=b([]);if(c)f=e?b(e).find("[name='"+c+"']"):b("[name='"+c+"']",a.ownerDocument).filter(function(){return!this.form});return f};b.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",l);if(typeof this.options.disabled!==
111
- "boolean")this.options.disabled=this.element.propAttr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var a=this,c=this.options,e=this.type==="checkbox"||this.type==="radio",f="ui-state-hover"+(!e?" ui-state-active":"");if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!c.disabled){b(this).addClass("ui-state-hover");
112
- this===h&&b(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){c.disabled||b(this).removeClass(f)}).bind("click.button",function(d){if(c.disabled){d.preventDefault();d.stopImmediatePropagation()}});this.element.bind("focus.button",function(){a.buttonElement.addClass("ui-state-focus")}).bind("blur.button",function(){a.buttonElement.removeClass("ui-state-focus")});if(e){this.element.bind("change.button",function(){g||a.refresh()});this.buttonElement.bind("mousedown.button",function(d){if(!c.disabled){g=
113
- false;i=d.pageX;j=d.pageY}}).bind("mouseup.button",function(d){if(!c.disabled)if(i!==d.pageX||j!==d.pageY)g=true})}if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled||g)return false;b(this).toggleClass("ui-state-active");a.buttonElement.attr("aria-pressed",a.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(c.disabled||g)return false;b(this).addClass("ui-state-active");a.buttonElement.attr("aria-pressed","true");
114
- var d=a.element[0];k(d).not(d).map(function(){return b(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")});else{this.buttonElement.bind("mousedown.button",function(){if(c.disabled)return false;b(this).addClass("ui-state-active");h=this;b(document).one("mouseup",function(){h=null})}).bind("mouseup.button",function(){if(c.disabled)return false;b(this).removeClass("ui-state-active")}).bind("keydown.button",function(d){if(c.disabled)return false;if(d.keyCode==b.ui.keyCode.SPACE||
115
- d.keyCode==b.ui.keyCode.ENTER)b(this).addClass("ui-state-active")}).bind("keyup.button",function(){b(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(d){d.keyCode===b.ui.keyCode.SPACE&&b(this).click()})}this._setOption("disabled",c.disabled);this._resetButton()},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type===
116
- "radio"){var a=this.element.parents().filter(":last"),c="label[for="+this.element.attr("id")+"]";this.buttonElement=a.find(c);if(!this.buttonElement.length){a=a.length?a.siblings():this.element.siblings();this.buttonElement=a.filter(c);if(!this.buttonElement.length)this.buttonElement=a.find(c)}this.element.addClass("ui-helper-hidden-accessible");(a=this.element.is(":checked"))&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",a)}else this.buttonElement=this.element},
117
- widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||this.buttonElement.removeAttr("title");
118
- b.Widget.prototype.destroy.call(this)},_setOption:function(a,c){b.Widget.prototype._setOption.apply(this,arguments);if(a==="disabled")c?this.element.propAttr("disabled",true):this.element.propAttr("disabled",false);else this._resetButton()},refresh:function(){var a=this.element.is(":disabled");a!==this.options.disabled&&this._setOption("disabled",a);if(this.type==="radio")k(this.element[0]).each(function(){b(this).is(":checked")?b(this).button("widget").addClass("ui-state-active").attr("aria-pressed",
119
- "true"):b(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false")},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var a=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
120
- c=b("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),e=this.options.icons,f=e.primary&&e.secondary,d=[];if(e.primary||e.secondary){if(this.options.text)d.push("ui-button-text-icon"+(f?"s":e.primary?"-primary":"-secondary"));e.primary&&a.prepend("<span class='ui-button-icon-primary ui-icon "+e.primary+"'></span>");e.secondary&&a.append("<span class='ui-button-icon-secondary ui-icon "+e.secondary+"'></span>");if(!this.options.text){d.push(f?"ui-button-icons-only":
121
- "ui-button-icon-only");this.hasTitle||a.attr("title",c)}}else d.push("ui-button-text-only");a.addClass(d.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){a==="disabled"&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a=this.element.css("direction")===
122
- "ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");
123
- b.Widget.prototype.destroy.call(this)}})})(jQuery);
124
- ;/*
125
- * jQuery UI Dialog 1.8.15
126
- *
127
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
128
- * Dual licensed under the MIT or GPL Version 2 licenses.
129
- * http://jquery.org/license
130
- *
131
- * http://docs.jquery.com/UI/Dialog
132
- *
133
- * Depends:
134
- * jquery.ui.core.js
135
- * jquery.ui.widget.js
136
- * jquery.ui.button.js
137
- * jquery.ui.draggable.js
138
- * jquery.ui.mouse.js
139
- * jquery.ui.position.js
140
- * jquery.ui.resizable.js
141
- */
142
- (function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,
143
- position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||"&#160;",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+
144
- b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),
145
- h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",
146
- e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");
147
- a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==
148
- b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()};c.ui.dialog.maxZ+=1;
149
- d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target===
150
- f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,
151
- function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('<button type="button"></button>').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",
152
- handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,
153
- originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",
154
- f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):
155
- [a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f);
156
- if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):
157
- e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a=
158
- this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height-
159
- b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.15",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),
160
- create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()<c.ui.dialog.overlay.maxZ)return false})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
161
- height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
162
- b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,function(){a=
163
- a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
164
- ;/*
165
- * jQuery UI Tabs 1.8.15
166
- *
167
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
168
- * Dual licensed under the MIT or GPL Version 2 licenses.
169
- * http://jquery.org/license
170
- *
171
- * http://docs.jquery.com/UI/Tabs
172
- *
173
- * Depends:
174
- * jquery.ui.core.js
175
- * jquery.ui.widget.js
176
- */
177
- (function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&&
178
- e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=
179
- d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]||
180
- (q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
181
- this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected=
182
- this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
183
- if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
184
- this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+
185
- g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",
186
- function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};
187
- this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected=
188
- -1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
189
- d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=
190
- d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b,
191
- e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);
192
- j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();
193
- if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=b}),function(h){return h>=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null,
194
- this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this},
195
- load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c,
196
- "cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},
197
- url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.15"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k<a.anchors.length?k:0)},b);j&&j.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(j){j.clientX&&
198
- a.rotate(null)}:function(){t=c.selected;h()});if(b){this.element.bind("tabsshow",h);this.anchors.bind(c.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(c.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
199
- ;/*
200
- * jQuery UI Progressbar 1.8.15
201
- *
202
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
203
- * Dual licensed under the MIT or GPL Version 2 licenses.
204
- * http://jquery.org/license
205
- *
206
- * http://docs.jquery.com/UI/Progressbar
207
- *
208
- * Depends:
209
- * jquery.ui.core.js
210
- * jquery.ui.widget.js
211
- */
212
- (function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
213
- this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*
214
- this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.15"})})(jQuery);
215
- ;/*
216
- * jQuery UI Effects 1.8.15
217
- *
218
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
219
- * Dual licensed under the MIT or GPL Version 2 licenses.
220
- * http://jquery.org/license
221
- *
222
- * http://docs.jquery.com/UI/Effects/
223
- */
224
- jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
225
- 16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
226
- a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
227
- a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
228
- "borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
229
- 0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
230
- 211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,
231
- d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})};
232
- f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this,
233
- [{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.15",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";return a},getBaseline:function(c,a){var b;switch(c[0]){case "top":b=
234
- 0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});
235
- c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);return c},setTransition:function(c,
236
- a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);
237
- a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%",
238
- "pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*
239
- ((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=
240
- e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=
241
- e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/
242
- h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);if(a<1)return-0.5*
243
- h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,a,b,d,e){return d-f.easing.easeOutBounce(c,
244
- e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
245
- ;/*
246
- * jQuery UI Effects Highlight 1.8.15
247
- *
248
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
249
- * Dual licensed under the MIT or GPL Version 2 licenses.
250
- * http://jquery.org/license
251
- *
252
- * http://docs.jquery.com/UI/Effects/Highlight
253
- *
254
- * Depends:
255
- * jquery.effects.core.js
256
- */
257
- (function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&&
258
- this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
259
- ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lang/aam-de_DE.mo ADDED
Binary file
lang/aam-de_DE.po ADDED
@@ -0,0 +1,336 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: AAM\n"
4
+ "POT-Creation-Date: 2013-12-01 14:07-0500\n"
5
+ "PO-Revision-Date: 2014-01-02 21:40-0500\n"
6
+ "Last-Translator: Vasyl Martyniuk <scarab.regit@gmail.com>\n"
7
+ "Language-Team: WPAAM <support@wpaam.com>\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 1.6.3\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "Language: de_DE\n"
14
+
15
+ #: aam.php:243 aam.php:248 aam.php:267
16
+ msgid "Access denied"
17
+ msgstr "Zugriff verweigert"
18
+
19
+ #: aam.php:691 aam.php:692
20
+ msgid "AAM"
21
+ msgstr "AAM"
22
+
23
+ #: aam.php:701 aam.php:702
24
+ msgid "Access Control"
25
+ msgstr "Zugangs Kontrolle"
26
+
27
+ #: aam.php:709 aam.php:710
28
+ msgid "Extensions"
29
+ msgstr "Erweiterungen"
30
+
31
+ #: application/view/capability.php:98 application/view/capability.php:179
32
+ msgid "System"
33
+ msgstr "System"
34
+
35
+ #: application/view/capability.php:99 application/view/capability.php:181
36
+ msgid "Post & Page"
37
+ msgstr "Artikel & Seiten"
38
+
39
+ #: application/view/capability.php:100 application/view/capability.php:183
40
+ msgid "Backend Interface"
41
+ msgstr "Backend Interface"
42
+
43
+ #: application/view/capability.php:101
44
+ msgid "Miscellaneous"
45
+ msgstr "Diverses"
46
+
47
+ #: application/view/capability.php:185
48
+ msgid "Miscelaneous"
49
+ msgstr "Diverses"
50
+
51
+ #: application/view/manager.php:59
52
+ msgid "Roles"
53
+ msgstr "Rollen"
54
+
55
+ #: application/view/manager.php:60
56
+ msgid "Role Manager"
57
+ msgstr "Rollen Manager"
58
+
59
+ #: application/view/manager.php:68
60
+ msgid "Users"
61
+ msgstr "Benutzer"
62
+
63
+ #: application/view/manager.php:69
64
+ msgid "User Manager"
65
+ msgstr "Benutzer Manager"
66
+
67
+ #: application/view/manager.php:77
68
+ msgid "Visitor"
69
+ msgstr "Besucher"
70
+
71
+ #: application/view/manager.php:78
72
+ msgid "Visitor Manager"
73
+ msgstr "Besucher Manager"
74
+
75
+ #: application/view/manager.php:95
76
+ msgid "Admin Menu"
77
+ msgstr "Admin Menü"
78
+
79
+ #: application/view/manager.php:98
80
+ msgid ""
81
+ "Control Access to Admin Menu. Restrict access to entire Menu or Submenu. "
82
+ "<b>Notice</b>, the menu is rendered based on Role's or User's capabilities."
83
+ msgstr ""
84
+ "Zugangskontrolle für das Admin Menü. Zugangs Beschränkung das vollständige "
85
+ "Menü oder Untermenüs . <b>Anmerkung</b>, das Menü wird aufgrund der "
86
+ "Benutzer- oder Rolleneigenschaften erstellt."
87
+
88
+ #: application/view/manager.php:103
89
+ msgid "Metabox & Widget"
90
+ msgstr "Metabox & Widgets"
91
+
92
+ #: application/view/manager.php:106
93
+ msgid ""
94
+ "Filter the list of Metaboxes or Widgets for selected Role or User. If "
95
+ "metabox or widget is not listed, try to click <b>Refresh the List</b> button "
96
+ "or Copy & Paste direct link to page where specific metabox or widget is "
97
+ "shown and hit <b>Retrieve Metaboxes from Link</b> button."
98
+ msgstr ""
99
+ "Sortiere nach den Metaboxen oder Widgets der ausgewählten Rolle oder des "
100
+ "Benutzers. Wenn eine Metabox oder ein Widget nicht angezeigt wird, klicke "
101
+ "auf <b>Refresh the List</b> oder kopiere den direkten Link zu der Site wo "
102
+ "die Metabox oder das Widget angezeigt werden und klicke <b>Retrieve "
103
+ "Metaboxes from Link</b> ."
104
+
105
+ #: application/view/manager.php:111
106
+ msgid "Capability"
107
+ msgstr "Eigenschaft"
108
+
109
+ #: application/view/manager.php:114
110
+ msgid ""
111
+ "Manage the list of Capabilities for selected User or Role. <b>Notice</b>, "
112
+ "list of user's capabilities are inherited from user's Role.<br/><b>Warning!</"
113
+ "b> Be very careful with capabilities. Deleting or unchecking any capability "
114
+ "may cause temporary or permanent constrol lost over some features or "
115
+ "WordPress dashboard."
116
+ msgstr ""
117
+ "Verwalte die Eigenschaften für die ausgewählte Rolle oder den Benutzer. "
118
+ "<b>Anmerkung</b>, die Eigenschafen der Benutzer werden von der Benutzerrolle "
119
+ "vererbt.<br/><b>Achtung!</b>, sei vorsichtig mit den Eigenschaften. Das "
120
+ "Löschen oder das Abwählen von Eigenschaften kann zeitweisen oder dauerhaften "
121
+ "Verlust von Funktionen verursachen."
122
+
123
+ #: application/view/manager.php:119
124
+ msgid "Posts & Categories"
125
+ msgstr "Artikel & Kategorien"
126
+
127
+ #: application/view/manager.php:122
128
+ msgid ""
129
+ "Manage access to individual <b>Post</b> or <b>Term</b>. Notice, under "
130
+ "<b>Post</b>, we assume any post, page or custom post type. And under "
131
+ "<b>Term</b> - any term like Post Categories."
132
+ msgstr ""
133
+ "Verwalte den Zugang zu einzelnen <b>Artikeln</b> oder <b>Ebenen<b/> Unter "
134
+ "<b>Artikeln</b> werden alle Artikel, Seiten oder custom post type und unter "
135
+ "<b>Ebenen<b/> z.B. Kategorien verstanden."
136
+
137
+ #: application/view/manager.php:127
138
+ msgid "Event Manager"
139
+ msgstr "Event Manager"
140
+
141
+ #: application/view/manager.php:130
142
+ msgid ""
143
+ "Define your own action when some event appeared in your WordPress blog. This "
144
+ "sections allows you to trigger an action on event like post content change, "
145
+ "or page status update. You can setup to send email notification, change the "
146
+ "post status or write your own custom event handler."
147
+ msgstr ""
148
+ "Definiere deine eigene Aktion, wenn ein Bestimmtes Ereignis auf deinem Blog "
149
+ "eintritt. Diese Auswahl erlaubt dir automatisch eine Aktion auszulösen, wenn "
150
+ "sich der Inhalt eines Artikels oder der Seitenstatus geändert haben. Du "
151
+ "kannst Email Benachichtugungen senden, den Artikel Status ändern oder eigene "
152
+ "Ereignisse beschreiben."
153
+
154
+ #: application/view/manager.php:135
155
+ msgid "ConfigPress"
156
+ msgstr "ConfigPress"
157
+
158
+ #: application/view/manager.php:138
159
+ msgid ""
160
+ "Control <b>AAM</b> behavior with ConfigPress. For more details please check "
161
+ "<b>ConfigPress tutorial</b>."
162
+ msgstr ""
163
+ "Kontrolliere das Verhalten von <b>AAM</b> mit ConfigPress Für mehr Details "
164
+ "schaue bitte ins <b>ConfigPress Tutorial</b>."
165
+
166
+ #: application/view/manager.php:342
167
+ msgid "Rollback Settings"
168
+ msgstr "Wiederholungseinstellungen"
169
+
170
+ #: application/view/manager.php:343
171
+ msgid "Cancel"
172
+ msgstr "Abbrechen"
173
+
174
+ #: application/view/manager.php:344
175
+ msgid "Send E-mail"
176
+ msgstr "E-Mail senden"
177
+
178
+ #: application/view/manager.php:345 application/view/manager.php:351
179
+ msgid "Add New Role"
180
+ msgstr "Neue Rolle hinzufügen"
181
+
182
+ #: application/view/manager.php:346
183
+ msgid "Manage"
184
+ msgstr "Verwalten"
185
+
186
+ #: application/view/manager.php:347
187
+ msgid "Edit"
188
+ msgstr "Bearbeiten"
189
+
190
+ #: application/view/manager.php:348
191
+ msgid "Delete"
192
+ msgstr "Löschen"
193
+
194
+ #: application/view/manager.php:349
195
+ msgid "Filtered"
196
+ msgstr "Sortieren"
197
+
198
+ #: application/view/manager.php:350
199
+ msgid "Clear"
200
+ msgstr "Leeren"
201
+
202
+ #: application/view/manager.php:352
203
+ msgid "Save Changes"
204
+ msgstr "Änderungen speichern"
205
+
206
+ #: application/view/manager.php:353
207
+ #, php-format
208
+ msgid ""
209
+ "System detected %d user(s) with this role. All Users with Role <b>%s</b> "
210
+ "will be deleted automatically!"
211
+ msgstr ""
212
+ "Das System hat %d Benutzer mit dieser Rolle identifiziert. Alle Benutzer mit "
213
+ "der Rolle <b>%s</b> werden automatisch gelöscht."
214
+
215
+ #: application/view/manager.php:354
216
+ #, php-format
217
+ msgid "Are you sure that you want to delete role <b>%s</b>?"
218
+ msgstr "Bist du sicher, dass du die Rolle <b>%s</b> löschen möchtest?"
219
+
220
+ #: application/view/manager.php:355
221
+ msgid "Delete Role"
222
+ msgstr "Rolle löschen"
223
+
224
+ #: application/view/manager.php:356
225
+ msgid "Add User"
226
+ msgstr "Benutzer hinzufügen"
227
+
228
+ #: application/view/manager.php:357
229
+ msgid "Filter Users"
230
+ msgstr "Benutzer sortieren"
231
+
232
+ #: application/view/manager.php:358 application/view/manager.php:374
233
+ msgid "Refresh List"
234
+ msgstr "Liste aktualisieren"
235
+
236
+ #: application/view/manager.php:359
237
+ msgid "Block"
238
+ msgstr "Block"
239
+
240
+ #: application/view/manager.php:360
241
+ #, php-format
242
+ msgid "Are you sure you want to delete user <b>%s</b>?"
243
+ msgstr "Bist du sicher, dass du den Benutzer <b>%s</b> löschen möchtest?"
244
+
245
+ #: application/view/manager.php:361
246
+ msgid "Filter Capabilities by Category"
247
+ msgstr "Sortiere die Eigenschaften nach der Kategorie"
248
+
249
+ #: application/view/manager.php:362
250
+ msgid "Inherit Capabilities"
251
+ msgstr "Vererbe Eigenschaften"
252
+
253
+ #: application/view/manager.php:363
254
+ msgid "Add New Capability"
255
+ msgstr "Neue Eigenschaft hinzufügen"
256
+
257
+ #: application/view/manager.php:364
258
+ #, php-format
259
+ msgid "Are you sure that you want to delete capability <b>%s</b>?"
260
+ msgstr "Bist du sicher, dass du die Eigenschaft <b>%s</b> löschen möchtest?"
261
+
262
+ #: application/view/manager.php:365
263
+ msgid "Delete Capability"
264
+ msgstr "Eigenschaft löschen"
265
+
266
+ #: application/view/manager.php:366
267
+ msgid "Select Role"
268
+ msgstr "Rolle auswählen"
269
+
270
+ #: application/view/manager.php:367
271
+ msgid "Add Capability"
272
+ msgstr "Eigenschaft hinzufügen"
273
+
274
+ #: application/view/manager.php:368
275
+ msgid "Add Event"
276
+ msgstr "Event hinzufügen"
277
+
278
+ #: application/view/manager.php:369
279
+ msgid "Edit Event"
280
+ msgstr "Event bearbeiten"
281
+
282
+ #: application/view/manager.php:370 application/view/manager.php:372
283
+ msgid "Delete Event"
284
+ msgstr "Event löschen"
285
+
286
+ #: application/view/manager.php:371
287
+ msgid "Save Event"
288
+ msgstr "Event speichern"
289
+
290
+ #: application/view/manager.php:373
291
+ msgid "Filter Posts by Post Type"
292
+ msgstr "Sortiere Artikel nach Artikel Typ"
293
+
294
+ #: application/view/manager.php:375
295
+ msgid "Restore Default"
296
+ msgstr "Standard wiederherstellen"
297
+
298
+ #: application/view/manager.php:376
299
+ msgid "Apply"
300
+ msgstr "Zustimmen"
301
+
302
+ #: application/view/manager.php:377
303
+ msgid "Edit Term"
304
+ msgstr "Ebene bearbeiten"
305
+
306
+ #: application/view/manager.php:378
307
+ msgid "Manager Access"
308
+ msgstr "Zugangs Verwaltung"
309
+
310
+ #: application/view/manager.php:379
311
+ msgid "Unlock Default Accesss Control"
312
+ msgstr "Öffne Standard Zugangs Kontrolle"
313
+
314
+ #: application/view/manager.php:380
315
+ msgid "Close"
316
+ msgstr "Schließen"
317
+
318
+ #: application/view/manager.php:381
319
+ msgid "Edit Role"
320
+ msgstr "Rolle bearbeiten"
321
+
322
+ #: application/view/metabox.php:179
323
+ msgid "Dashboard Widgets"
324
+ msgstr "Dashboard Widgets"
325
+
326
+ #: application/view/metabox.php:183
327
+ msgid "Frontend Widgets"
328
+ msgstr "Frontend Widgets"
329
+
330
+ #: application/view/post.php:181
331
+ msgid "[empty]"
332
+ msgstr "[leer]"
333
+
334
+ #: application/view/post.php:345 application/view/post.php:353
335
+ msgid "All"
336
+ msgstr ""
lang/aam-en_US.mo ADDED
Binary file
lang/aam-en_US.po ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: AAM\n"
4
+ "POT-Creation-Date: 2013-12-01 14:07-0500\n"
5
+ "PO-Revision-Date: 2014-01-02 21:40-0500\n"
6
+ "Last-Translator: Vasyl Martyniuk <scarab.regit@gmail.com>\n"
7
+ "Language-Team: WPAAM <support@wpaam.com>\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "Language: en_US\n"
12
+ "X-Generator: Poedit 1.6.3\n"
13
+
14
+ #: aam.php:243 aam.php:248 aam.php:267
15
+ msgid "Access denied"
16
+ msgstr ""
17
+
18
+ #: aam.php:691 aam.php:692
19
+ msgid "AAM"
20
+ msgstr ""
21
+
22
+ #: aam.php:701 aam.php:702
23
+ msgid "Access Control"
24
+ msgstr ""
25
+
26
+ #: aam.php:709 aam.php:710
27
+ msgid "Extensions"
28
+ msgstr ""
29
+
30
+ #: application/view/capability.php:98 application/view/capability.php:179
31
+ msgid "System"
32
+ msgstr ""
33
+
34
+ #: application/view/capability.php:99 application/view/capability.php:181
35
+ msgid "Post & Page"
36
+ msgstr ""
37
+
38
+ #: application/view/capability.php:100 application/view/capability.php:183
39
+ msgid "Backend Interface"
40
+ msgstr ""
41
+
42
+ #: application/view/capability.php:101
43
+ msgid "Miscellaneous"
44
+ msgstr ""
45
+
46
+ #: application/view/capability.php:185
47
+ msgid "Miscelaneous"
48
+ msgstr ""
49
+
50
+ #: application/view/manager.php:59
51
+ msgid "Roles"
52
+ msgstr ""
53
+
54
+ #: application/view/manager.php:60
55
+ msgid "Role Manager"
56
+ msgstr ""
57
+
58
+ #: application/view/manager.php:68
59
+ msgid "Users"
60
+ msgstr ""
61
+
62
+ #: application/view/manager.php:69
63
+ msgid "User Manager"
64
+ msgstr ""
65
+
66
+ #: application/view/manager.php:77
67
+ msgid "Visitor"
68
+ msgstr ""
69
+
70
+ #: application/view/manager.php:78
71
+ msgid "Visitor Manager"
72
+ msgstr ""
73
+
74
+ #: application/view/manager.php:95
75
+ msgid "Admin Menu"
76
+ msgstr ""
77
+
78
+ #: application/view/manager.php:98
79
+ msgid ""
80
+ "Control Access to Admin Menu. Restrict access to entire Menu or Submenu. "
81
+ "<b>Notice</b>, the menu is rendered based on Role's or User's capabilities."
82
+ msgstr ""
83
+
84
+ #: application/view/manager.php:103
85
+ msgid "Metabox & Widget"
86
+ msgstr ""
87
+
88
+ #: application/view/manager.php:106
89
+ msgid ""
90
+ "Filter the list of Metaboxes or Widgets for selected Role or User. If "
91
+ "metabox or widget is not listed, try to click <b>Refresh the List</b> button "
92
+ "or Copy & Paste direct link to page where specific metabox or widget is "
93
+ "shown and hit <b>Retrieve Metaboxes from Link</b> button."
94
+ msgstr ""
95
+
96
+ #: application/view/manager.php:111
97
+ msgid "Capability"
98
+ msgstr ""
99
+
100
+ #: application/view/manager.php:114
101
+ msgid ""
102
+ "Manage the list of Capabilities for selected User or Role. <b>Notice</b>, "
103
+ "list of user's capabilities are inherited from user's Role.<br/><b>Warning!</"
104
+ "b> Be very careful with capabilities. Deleting or unchecking any capability "
105
+ "may cause temporary or permanent constrol lost over some features or "
106
+ "WordPress dashboard."
107
+ msgstr ""
108
+
109
+ #: application/view/manager.php:119
110
+ msgid "Posts & Categories"
111
+ msgstr ""
112
+
113
+ #: application/view/manager.php:122
114
+ msgid ""
115
+ "Manage access to individual <b>Post</b> or <b>Term</b>. Notice, under "
116
+ "<b>Post</b>, we assume any post, page or custom post type. And under "
117
+ "<b>Term</b> - any term like Post Categories."
118
+ msgstr ""
119
+
120
+ #: application/view/manager.php:127
121
+ msgid "Event Manager"
122
+ msgstr ""
123
+
124
+ #: application/view/manager.php:130
125
+ msgid ""
126
+ "Define your own action when some event appeared in your WordPress blog. This "
127
+ "sections allows you to trigger an action on event like post content change, "
128
+ "or page status update. You can setup to send email notification, change the "
129
+ "post status or write your own custom event handler."
130
+ msgstr ""
131
+
132
+ #: application/view/manager.php:135
133
+ msgid "ConfigPress"
134
+ msgstr ""
135
+
136
+ #: application/view/manager.php:138
137
+ msgid ""
138
+ "Control <b>AAM</b> behavior with ConfigPress. For more details please check "
139
+ "<b>ConfigPress tutorial</b>."
140
+ msgstr ""
141
+
142
+ #: application/view/manager.php:342
143
+ msgid "Rollback Settings"
144
+ msgstr ""
145
+
146
+ #: application/view/manager.php:343
147
+ msgid "Cancel"
148
+ msgstr ""
149
+
150
+ #: application/view/manager.php:344
151
+ msgid "Send E-mail"
152
+ msgstr ""
153
+
154
+ #: application/view/manager.php:345 application/view/manager.php:351
155
+ msgid "Add New Role"
156
+ msgstr ""
157
+
158
+ #: application/view/manager.php:346
159
+ msgid "Manage"
160
+ msgstr ""
161
+
162
+ #: application/view/manager.php:347
163
+ msgid "Edit"
164
+ msgstr ""
165
+
166
+ #: application/view/manager.php:348
167
+ msgid "Delete"
168
+ msgstr ""
169
+
170
+ #: application/view/manager.php:349
171
+ msgid "Filtered"
172
+ msgstr ""
173
+
174
+ #: application/view/manager.php:350
175
+ msgid "Clear"
176
+ msgstr ""
177
+
178
+ #: application/view/manager.php:352
179
+ msgid "Save Changes"
180
+ msgstr ""
181
+
182
+ #: application/view/manager.php:353
183
+ #, php-format
184
+ msgid ""
185
+ "System detected %d user(s) with this role. All Users with Role <b>%s</b> "
186
+ "will be deleted automatically!"
187
+ msgstr ""
188
+
189
+ #: application/view/manager.php:354
190
+ #, php-format
191
+ msgid "Are you sure that you want to delete role <b>%s</b>?"
192
+ msgstr ""
193
+
194
+ #: application/view/manager.php:355
195
+ msgid "Delete Role"
196
+ msgstr ""
197
+
198
+ #: application/view/manager.php:356
199
+ msgid "Add User"
200
+ msgstr ""
201
+
202
+ #: application/view/manager.php:357
203
+ msgid "Filter Users"
204
+ msgstr ""
205
+
206
+ #: application/view/manager.php:358 application/view/manager.php:374
207
+ msgid "Refresh List"
208
+ msgstr ""
209
+
210
+ #: application/view/manager.php:359
211
+ msgid "Block"
212
+ msgstr ""
213
+
214
+ #: application/view/manager.php:360
215
+ #, php-format
216
+ msgid "Are you sure you want to delete user <b>%s</b>?"
217
+ msgstr ""
218
+
219
+ #: application/view/manager.php:361
220
+ msgid "Filter Capabilities by Category"
221
+ msgstr ""
222
+
223
+ #: application/view/manager.php:362
224
+ msgid "Inherit Capabilities"
225
+ msgstr ""
226
+
227
+ #: application/view/manager.php:363
228
+ msgid "Add New Capability"
229
+ msgstr ""
230
+
231
+ #: application/view/manager.php:364
232
+ #, php-format
233
+ msgid "Are you sure that you want to delete capability <b>%s</b>?"
234
+ msgstr ""
235
+
236
+ #: application/view/manager.php:365
237
+ msgid "Delete Capability"
238
+ msgstr ""
239
+
240
+ #: application/view/manager.php:366
241
+ msgid "Select Role"
242
+ msgstr ""
243
+
244
+ #: application/view/manager.php:367
245
+ msgid "Add Capability"
246
+ msgstr ""
247
+
248
+ #: application/view/manager.php:368
249
+ msgid "Add Event"
250
+ msgstr ""
251
+
252
+ #: application/view/manager.php:369
253
+ msgid "Edit Event"
254
+ msgstr ""
255
+
256
+ #: application/view/manager.php:370 application/view/manager.php:372
257
+ msgid "Delete Event"
258
+ msgstr ""
259
+
260
+ #: application/view/manager.php:371
261
+ msgid "Save Event"
262
+ msgstr ""
263
+
264
+ #: application/view/manager.php:373
265
+ msgid "Filter Posts by Post Type"
266
+ msgstr ""
267
+
268
+ #: application/view/manager.php:375
269
+ msgid "Restore Default"
270
+ msgstr ""
271
+
272
+ #: application/view/manager.php:376
273
+ msgid "Apply"
274
+ msgstr ""
275
+
276
+ #: application/view/manager.php:377
277
+ msgid "Edit Term"
278
+ msgstr ""
279
+
280
+ #: application/view/manager.php:378
281
+ msgid "Manager Access"
282
+ msgstr ""
283
+
284
+ #: application/view/manager.php:379
285
+ msgid "Unlock Default Accesss Control"
286
+ msgstr ""
287
+
288
+ #: application/view/manager.php:380
289
+ msgid "Close"
290
+ msgstr ""
291
+
292
+ #: application/view/manager.php:381
293
+ msgid "Edit Role"
294
+ msgstr ""
295
+
296
+ #: application/view/metabox.php:179
297
+ msgid "Dashboard Widgets"
298
+ msgstr ""
299
+
300
+ #: application/view/metabox.php:183
301
+ msgid "Frontend Widgets"
302
+ msgstr ""
303
+
304
+ #: application/view/post.php:181
305
+ msgid "[empty]"
306
+ msgstr ""
307
+
308
+ #: application/view/post.php:345 application/view/post.php:353
309
+ msgid "All"
310
+ msgstr ""
lang/aam-es_ES.mo ADDED
Binary file
lang/aam-es_ES.po ADDED
@@ -0,0 +1,998 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Advanced Access Manager\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2013-12-01 14:07-0500\n"
6
+ "PO-Revision-Date: 2014-01-03 18:30-0300\n"
7
+ "Last-Translator: Esteban Truelsegaard <esteban@netmdp.com>\n"
8
+ "Language-Team: Vasyl Martyniuk <whimba@gmail.com>\n"
9
+ "Language: en\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Poedit-KeywordsList: _;gettext;gettext_noop;__\n"
14
+ "X-Generator: Poedit 1.5.7\n"
15
+ "X-Poedit-SearchPath-0: .\n"
16
+
17
+ #: aam.php:243 aam.php:248 aam.php:267
18
+ msgid "Access denied"
19
+ msgstr "Acceso Denegado"
20
+
21
+ #: aam.php:691 aam.php:692
22
+ msgid "AAM"
23
+ msgstr "Permisos AAM"
24
+
25
+ #: aam.php:701 aam.php:702
26
+ msgid "Access Control"
27
+ msgstr "Control de Accesos"
28
+
29
+ #: aam.php:709 aam.php:710
30
+ msgid "Extensions"
31
+ msgstr "Extensiones"
32
+
33
+ #: application/view/capability.php:98 application/view/capability.php:179
34
+ msgid "System"
35
+ msgstr "Sistema"
36
+
37
+ #: application/view/capability.php:99 application/view/capability.php:181
38
+ msgid "Post & Page"
39
+ msgstr "Entrada & Página"
40
+
41
+ #: application/view/capability.php:100 application/view/capability.php:183
42
+ msgid "Backend Interface"
43
+ msgstr "Backend Interface"
44
+
45
+ #: application/view/capability.php:101
46
+ msgid "Miscellaneous"
47
+ msgstr "Misceláneo"
48
+
49
+ #: application/view/capability.php:185
50
+ msgid "Miscelaneous"
51
+ msgstr "Misceláneo"
52
+
53
+ #: application/view/manager.php:59
54
+ msgid "Roles"
55
+ msgstr "Roles"
56
+
57
+ #: application/view/manager.php:60
58
+ msgid "Role Manager"
59
+ msgstr "Administrar Roles"
60
+
61
+ #: application/view/manager.php:68
62
+ msgid "Users"
63
+ msgstr "Usuarios"
64
+
65
+ #: application/view/manager.php:69
66
+ msgid "User Manager"
67
+ msgstr "Administrar Usuario"
68
+
69
+ #: application/view/manager.php:77
70
+ msgid "Visitor"
71
+ msgstr "Visita"
72
+
73
+ #: application/view/manager.php:78
74
+ msgid "Visitor Manager"
75
+ msgstr "Administrar Visitas"
76
+
77
+ #: application/view/manager.php:95
78
+ msgid "Admin Menu"
79
+ msgstr "Menú principal"
80
+
81
+ #: application/view/manager.php:98
82
+ msgid ""
83
+ "Control Access to Admin Menu. Restrict access to entire Menu or Submenu. "
84
+ "<b>Notice</b>, the menu is rendered based on Role's or User's capabilities."
85
+ msgstr ""
86
+ "Control de Accesos al Menu Admin. Restringe accesos a todo el Menú o por "
87
+ "Submenú. <b>Nota</b>, el menú es mostrado basado en el Rol o capabilities "
88
+ "del Usuario."
89
+
90
+ #: application/view/manager.php:103
91
+ msgid "Metabox & Widget"
92
+ msgstr "Metabox & Widget"
93
+
94
+ #: application/view/manager.php:106
95
+ msgid ""
96
+ "Filter the list of Metaboxes or Widgets for selected Role or User. If "
97
+ "metabox or widget is not listed, try to click <b>Refresh the List</b> button "
98
+ "or Copy & Paste direct link to page where specific metabox or widget is "
99
+ "shown and hit <b>Retrieve Metaboxes from Link</b> button."
100
+ msgstr ""
101
+ "Filtrar lista de Metaboxes o Widgets para el Rol o Usuario seleccionado. Si "
102
+ "el metabox o widget no está listado, intente clickeando el botón "
103
+ "<b>Actualizar Lista</b> o Copie & Pegue el link directo a la página donde se "
104
+ "muestra el metabox o widget y toque el botón <b>Recuperar Metaboxes desde "
105
+ "link</b>."
106
+
107
+ #: application/view/manager.php:111
108
+ msgid "Capability"
109
+ msgstr "Capability"
110
+
111
+ #: application/view/manager.php:114
112
+ msgid ""
113
+ "Manage the list of Capabilities for selected User or Role. <b>Notice</b>, "
114
+ "list of user's capabilities are inherited from user's Role.<br/><b>Warning!</"
115
+ "b> Be very careful with capabilities. Deleting or unchecking any capability "
116
+ "may cause temporary or permanent constrol lost over some features or "
117
+ "WordPress dashboard."
118
+ msgstr ""
119
+ "Administrar lista de Capabilities para el Usuario o Rol seleccionado. "
120
+ "<b>Nota</b>, la lista de capacidades se heredan del Rol de usuario. <br/"
121
+ "><b>Cuidado!</b> Sea cuidadoso con las capacidades. Borrar o desmarcar una "
122
+ "capability puede causar perdida de control temporal o permanente sobre "
123
+ "alguna característica o el panel de Wordpress."
124
+
125
+ #: application/view/manager.php:119
126
+ msgid "Posts & Categories"
127
+ msgstr "Entradas & Taxonomias"
128
+
129
+ #: application/view/manager.php:122
130
+ msgid ""
131
+ "Manage access to individual <b>Post</b> or <b>Term</b>. Notice, under "
132
+ "<b>Post</b>, we assume any post, page or custom post type. And under "
133
+ "<b>Term</b> - any term like Post Categories."
134
+ msgstr ""
135
+ "Administrar acceso sobre <b>Entrada</b> o <b>Taxonomía</b> individual. Nota, "
136
+ "bajo <b>Entrada</b>, se asume cualquier post, página o custom post type. Y "
137
+ "bajo <b>Taxonomía</b>, cualquier término como Categorías de Entradas."
138
+
139
+ #: application/view/manager.php:127
140
+ msgid "Event Manager"
141
+ msgstr "Administrar Eventos"
142
+
143
+ #: application/view/manager.php:130
144
+ msgid ""
145
+ "Define your own action when some event appeared in your WordPress blog. This "
146
+ "sections allows you to trigger an action on event like post content change, "
147
+ "or page status update. You can setup to send email notification, change the "
148
+ "post status or write your own custom event handler."
149
+ msgstr ""
150
+ "Define su propia acción cuando ocurre algún evento en su blog. Esta sección "
151
+ "le permite agregar una acción a un evento como cambio de contenido de una "
152
+ "entrada, o el estado de actualización de una página. Puede enviar una "
153
+ "notificación por e-mail, cambiar el estado de la entrada o escribir su "
154
+ "propio manejador de eventos."
155
+
156
+ #: application/view/manager.php:135
157
+ msgid "ConfigPress"
158
+ msgstr "Configuración"
159
+
160
+ #: application/view/manager.php:138
161
+ msgid ""
162
+ "Control <b>AAM</b> behavior with ConfigPress. For more details please check "
163
+ "<b>ConfigPress tutorial</b>."
164
+ msgstr ""
165
+ "Controle el comportamiento de <b>AAM</b> con ConfigPress. Para mas detalles "
166
+ "mire <b>ConfigPress tutorial</b>."
167
+
168
+ #: application/view/manager.php:342
169
+ msgid "Rollback Settings"
170
+ msgstr "Recuperar Valores"
171
+
172
+ #: application/view/manager.php:343
173
+ msgid "Cancel"
174
+ msgstr "Cancelar"
175
+
176
+ #: application/view/manager.php:344
177
+ msgid "Send E-mail"
178
+ msgstr "Enviar email"
179
+
180
+ #: application/view/manager.php:345 application/view/manager.php:351
181
+ msgid "Add New Role"
182
+ msgstr "Agregar Nuevo Rol"
183
+
184
+ #: application/view/manager.php:346
185
+ msgid "Manage"
186
+ msgstr "Administrar"
187
+
188
+ #: application/view/manager.php:347
189
+ msgid "Edit"
190
+ msgstr "Editor"
191
+
192
+ #: application/view/manager.php:348
193
+ msgid "Delete"
194
+ msgstr "Borrar"
195
+
196
+ #: application/view/manager.php:349
197
+ msgid "Filtered"
198
+ msgstr "Filtrado"
199
+
200
+ #: application/view/manager.php:350
201
+ msgid "Clear"
202
+ msgstr "Limpìar"
203
+
204
+ #: application/view/manager.php:352
205
+ msgid "Save Changes"
206
+ msgstr "Grabar Cambios"
207
+
208
+ #: application/view/manager.php:353
209
+ #, php-format
210
+ msgid ""
211
+ "System detected %d user(s) with this role. All Users with Role <b>%s</b> "
212
+ "will be deleted automatically!"
213
+ msgstr ""
214
+ "El sistema ha detectado %d usuario(s) con este rol. ¡Todos los Usuarios con "
215
+ "Rol <b>%s</b> serán borrados automáticamente!"
216
+
217
+ #: application/view/manager.php:354
218
+ #, php-format
219
+ msgid "Are you sure that you want to delete role <b>%s</b>?"
220
+ msgstr "Está seguro de borrar el rol <b>%s</b>?"
221
+
222
+ #: application/view/manager.php:355
223
+ msgid "Delete Role"
224
+ msgstr "Borrar Rol"
225
+
226
+ #: application/view/manager.php:356
227
+ msgid "Add User"
228
+ msgstr "Agregar Usuario"
229
+
230
+ #: application/view/manager.php:357
231
+ msgid "Filter Users"
232
+ msgstr "Filtrar Usuarios"
233
+
234
+ #: application/view/manager.php:358 application/view/manager.php:374
235
+ msgid "Refresh List"
236
+ msgstr "Refrescar Lista"
237
+
238
+ #: application/view/manager.php:359
239
+ msgid "Block"
240
+ msgstr "Bloquear"
241
+
242
+ #: application/view/manager.php:360
243
+ #, php-format
244
+ msgid "Are you sure you want to delete user <b>%s</b>?"
245
+ msgstr "Está seguro de borrar el usuario <b>%s</b>?"
246
+
247
+ #: application/view/manager.php:361
248
+ msgid "Filter Capabilities by Category"
249
+ msgstr "Filtrar Capabilities por Categoría"
250
+
251
+ #: application/view/manager.php:362
252
+ msgid "Inherit Capabilities"
253
+ msgstr "Inherit Capabilities"
254
+
255
+ #: application/view/manager.php:363
256
+ msgid "Add New Capability"
257
+ msgstr "Agregar nueva Capability"
258
+
259
+ #: application/view/manager.php:364
260
+ #, php-format
261
+ msgid "Are you sure that you want to delete capability <b>%s</b>?"
262
+ msgstr "Por favor confirme el borrado de Capability - <b>%s</b>"
263
+
264
+ #: application/view/manager.php:365
265
+ msgid "Delete Capability"
266
+ msgstr "Borrar Capability"
267
+
268
+ #: application/view/manager.php:366
269
+ msgid "Select Role"
270
+ msgstr "Seleccionar Rol"
271
+
272
+ #: application/view/manager.php:367
273
+ msgid "Add Capability"
274
+ msgstr "Agregar Capability"
275
+
276
+ #: application/view/manager.php:368
277
+ msgid "Add Event"
278
+ msgstr "Agregar Evento"
279
+
280
+ #: application/view/manager.php:369
281
+ msgid "Edit Event"
282
+ msgstr "Editar Evento"
283
+
284
+ #: application/view/manager.php:370 application/view/manager.php:372
285
+ msgid "Delete Event"
286
+ msgstr "Borrar Evento"
287
+
288
+ #: application/view/manager.php:371
289
+ msgid "Save Event"
290
+ msgstr "Salvar Evento"
291
+
292
+ #: application/view/manager.php:373
293
+ msgid "Filter Posts by Post Type"
294
+ msgstr "Filtrar Entradas por Post Type"
295
+
296
+ #: application/view/manager.php:375
297
+ msgid "Restore Default"
298
+ msgstr "Restaurar valores por defecto"
299
+
300
+ #: application/view/manager.php:376
301
+ msgid "Apply"
302
+ msgstr "Aplicar Todo"
303
+
304
+ #: application/view/manager.php:377
305
+ msgid "Edit Term"
306
+ msgstr "Editar Term"
307
+
308
+ #: application/view/manager.php:378
309
+ msgid "Manager Access"
310
+ msgstr "Administrar Accesos"
311
+
312
+ #: application/view/manager.php:379
313
+ msgid "Unlock Default Accesss Control"
314
+ msgstr "Desbloquear Control de Accesos por Defecto"
315
+
316
+ #: application/view/manager.php:380
317
+ msgid "Close"
318
+ msgstr "Cerrar"
319
+
320
+ #: application/view/manager.php:381
321
+ msgid "Edit Role"
322
+ msgstr "Editar Rol"
323
+
324
+ #: application/view/metabox.php:179
325
+ msgid "Dashboard Widgets"
326
+ msgstr "Metaboxes & Widgets"
327
+
328
+ #: application/view/metabox.php:183
329
+ msgid "Frontend Widgets"
330
+ msgstr "Frontend Widgets"
331
+
332
+ #: application/view/post.php:181
333
+ msgid "[empty]"
334
+ msgstr "[vaciar]"
335
+
336
+ #: application/view/post.php:345 application/view/post.php:353
337
+ msgid "All"
338
+ msgstr "Todo"
339
+
340
+ #~ msgid "Password Protected"
341
+ #~ msgstr "Protegido por contraseña"
342
+
343
+ #~ msgid "Public"
344
+ #~ msgstr "Público"
345
+
346
+ #~ msgid "Advanced Access Manager"
347
+ #~ msgstr "Administrador de Accesos"
348
+
349
+ #~ msgid "Alert"
350
+ #~ msgstr "Alerta"
351
+
352
+ #~ msgid "Options updated successfully"
353
+ #~ msgstr "Opciones guardadas"
354
+
355
+ #~ msgid "Drag and Drop Menu in the List and click <b>Save Order</b>"
356
+ #~ msgstr ""
357
+ #~ "Para Reorganizar el menu sólo arrastre y suelte Items en la lista y "
358
+ #~ "clickee <b>Salvar Orden</b>"
359
+
360
+ #~ msgid "Reorganize"
361
+ #~ msgstr "Reorganizar"
362
+
363
+ #~ msgid "Whole Branch"
364
+ #~ msgstr "Toda la Rama"
365
+
366
+ #~ msgid ""
367
+ #~ "To initialize list of metaboxes manually, copy and paste the URL to edit "
368
+ #~ "screen page (e.g. http://localhost/wp-admin/post.php?post=1&action=edit) "
369
+ #~ "into text field and click \"Initiate URL\". List of all new metaboxes "
370
+ #~ "will be added automatically."
371
+ #~ msgstr ""
372
+ #~ "Para inicializar la lista de metaboxes manualmente, copie y pegue la URL "
373
+ #~ "a la pag. admin en este sitio en el campo de texto y clickee \"Iniciar URL"
374
+ #~ "\". La lista de todas las metaboxes nuevas serán agregadas "
375
+ #~ "automaticamente."
376
+
377
+ #~ msgid "Enter Correct URL"
378
+ #~ msgstr "Ingrese URL correcta"
379
+
380
+ #~ msgid "Initialize URL"
381
+ #~ msgstr "Inicializar URL"
382
+
383
+ #~ msgid "ID"
384
+ #~ msgstr "ID"
385
+
386
+ #~ msgid "Priority"
387
+ #~ msgstr "Prioridad"
388
+
389
+ #~ msgid "Position"
390
+ #~ msgstr "Posición"
391
+
392
+ #~ msgid "Restrict"
393
+ #~ msgstr "Restringir"
394
+
395
+ #~ msgid "List of Metaboxes is empty or not initialized."
396
+ #~ msgstr "La lista de metaboxes esta vacía o no inicializada."
397
+
398
+ #~ msgid "Initialize the List"
399
+ #~ msgstr "Inicializar la Lista"
400
+
401
+ #~ msgid "Error"
402
+ #~ msgstr "Error"
403
+
404
+ #~ msgid "Role Administrator's List of Capabilities"
405
+ #~ msgstr "Dar lista de Capabilities de Administrador"
406
+
407
+ #~ msgid "Administrator"
408
+ #~ msgstr "Administrador"
409
+
410
+ #~ msgid "Role Editor's List of Capabilities"
411
+ #~ msgstr "Dar lista de Capabilities de Editor"
412
+
413
+ #~ msgid "Role Author's List of Capabilities"
414
+ #~ msgstr "Dar lista de Capabilities de Autor"
415
+
416
+ #~ msgid "Author"
417
+ #~ msgstr "Autor"
418
+
419
+ #~ msgid "Role Contributor's List of Capabilities"
420
+ #~ msgstr "Dar lista de Capabilities de Contribuidor"
421
+
422
+ #~ msgid "Contributor"
423
+ #~ msgstr "Contribuidor"
424
+
425
+ #~ msgid "Role Subscriber's List of Capabilities"
426
+ #~ msgstr "Dar lista de Capabilities de Suscriptor"
427
+
428
+ #~ msgid "Subscriber"
429
+ #~ msgstr "Suscriptor"
430
+
431
+ #~ msgid "Collapse All"
432
+ #~ msgstr "Colapsar Todo"
433
+
434
+ #~ msgid "Expand All"
435
+ #~ msgstr "Expandir Todo"
436
+
437
+ #~ msgid "Error during saving"
438
+ #~ msgstr "Error mientras guardaba"
439
+
440
+ #~ msgid "Apply Restrictions Only for Current Role or User"
441
+ #~ msgstr "Aplicar Restricciones solo para el Rol o Usuario Actual"
442
+
443
+ #~ msgid "Apply Restrictions for All Roles"
444
+ #~ msgstr "Aplicar valores para TODOS los Roles de Usuario ?"
445
+
446
+ #~ msgid "Apply for All"
447
+ #~ msgstr "Aplicar para Todo"
448
+
449
+ #~ msgid "Select Post, Page or Taxonomy"
450
+ #~ msgstr "Seleccionar Entrada, Página o Taxonomía"
451
+
452
+ #~ msgid "Click to toggle"
453
+ #~ msgstr "Click para intercambiar"
454
+
455
+ #~ msgid "General"
456
+ #~ msgstr "General"
457
+
458
+ #~ msgid "Current Role"
459
+ #~ msgstr "Rol Actual"
460
+
461
+ #~ msgid "OK"
462
+ #~ msgstr "OK"
463
+
464
+ #~ msgid "Saving..."
465
+ #~ msgstr "Salvando..."
466
+
467
+ #~ msgid "Save"
468
+ #~ msgstr "Salvar"
469
+
470
+ #~ msgid "Enter New Role"
471
+ #~ msgstr "Ingrese Nuevo Rol"
472
+
473
+ #~ msgid "Add"
474
+ #~ msgstr "Agregar"
475
+
476
+ #~ msgid "New Role Created successfully"
477
+ #~ msgstr "Nuevo Rol creado"
478
+
479
+ #~ msgid "Role can not be created"
480
+ #~ msgstr "El Rol no puede ser creado"
481
+
482
+ #~ msgid "Delete Role?"
483
+ #~ msgstr "Borrar Rol ?"
484
+
485
+ #~ msgid "Please confirm deleting Role %s"
486
+ #~ msgstr "Por favor confirme el borrado del Rol %s"
487
+
488
+ #~ msgid "Save Menu Order"
489
+ #~ msgstr "Salvar Orden del Menú?"
490
+
491
+ #~ msgid "Save Menu Order <b>ONLY</b> for Role %s?"
492
+ #~ msgstr "Le gustaría salvar el orden del Menú <b>SOLO</b> para el Rol %s?"
493
+
494
+ #~ msgid "Delete Capability?"
495
+ #~ msgstr "Borrar Capability?"
496
+
497
+ #~ msgid "Restore Default Settings?"
498
+ #~ msgstr "Restaurar valores por defecto de Rol?"
499
+
500
+ #~ msgid "All current settings will be lost. Are you sure?"
501
+ #~ msgstr "Todos los valores actuales se perderán. Está seguro?"
502
+
503
+ #~ msgid "Apply Setting for ALL Roles?"
504
+ #~ msgstr "Aplicar valores para TODOS los Roles de Usuario ?"
505
+
506
+ #~ msgid "Do you really want to apply these settings to <b>ALL</b> Roles?"
507
+ #~ msgstr ""
508
+ #~ "Realmente quiere aplicar estos valores para <b>TODOS</b> los Roles de "
509
+ #~ "Usuario ?"
510
+
511
+ #~ msgid "Do not show me this message again"
512
+ #~ msgstr "No mostrarme este mensaje otra vez."
513
+
514
+ #~ msgid "Description"
515
+ #~ msgstr "Posición"
516
+
517
+ #~ msgid "Upgrade functionality"
518
+ #~ msgstr "Actualizar funcionalidad"
519
+
520
+ #~ msgid "Important Message"
521
+ #~ msgstr "Mensaje Importante"
522
+
523
+ #~ msgid "No Description found"
524
+ #~ msgstr "No se encontró descripción"
525
+
526
+ #~ msgid "WARNING"
527
+ #~ msgstr "WARNING"
528
+
529
+ #~ msgid ""
530
+ #~ "Advanced Access Manager requires WordPress 3.2 or newer. <a href=\"http://"
531
+ #~ "codex.wordpress.org/Upgrading_WordPress\">Update now!</a>"
532
+ #~ msgstr ""
533
+ #~ "Advanced Access Manager requiere WordPress 3.1 o mayor. <a href=\"http://"
534
+ #~ "codex.wordpress.org/Upgrading_WordPress\">Update now!</a>"
535
+
536
+ #~ msgid "Advanced Access Manager requires PHP 5.1.2 or newer"
537
+ #~ msgstr "Advanced Access Manager requiere PHP 5.0 o superior"
538
+
539
+ #~ msgid "Empty Capability"
540
+ #~ msgstr "Borrar Capability"
541
+
542
+ #~ msgid "Current Capability can not be deleted"
543
+ #~ msgstr "Capability Actual no puede ser borrada"
544
+
545
+ #~ msgid "Super Admin"
546
+ #~ msgstr "Super Admin"
547
+
548
+ #~ msgid "Unauthorized Action"
549
+ #~ msgstr "Acción no Autorizada"
550
+
551
+ #~ msgid "Options List"
552
+ #~ msgstr "Lista de Opciones"
553
+
554
+ #~ msgid "Yes"
555
+ #~ msgstr "Si"
556
+
557
+ #~ msgid "Error appeared during Metabox initialization!"
558
+ #~ msgstr "Aparece un error durante la inicialización Metabox!"
559
+
560
+ #~ msgid "Restore"
561
+ #~ msgstr "Restaurar"
562
+
563
+ #~ msgid "Current Role can not be restored!"
564
+ #~ msgstr "Rol actual no puede ser restaurado!"
565
+
566
+ #~ msgid "Apply All"
567
+ #~ msgstr "Aplicar Todo"
568
+
569
+ #~ msgid "Error during information grabbing!"
570
+ #~ msgstr "Error during information grabbing!"
571
+
572
+ #~ msgid "Premium"
573
+ #~ msgstr " "
574
+
575
+ #~ msgid "Create"
576
+ #~ msgstr "Crear"
577
+
578
+ #~ msgid "Do not Create"
579
+ #~ msgstr "No Crear"
580
+
581
+ #~ msgid "Change Role"
582
+ #~ msgstr "Cambiar Rol"
583
+
584
+ #~ msgid "Current Site"
585
+ #~ msgstr "Sitio Actual"
586
+
587
+ #~ msgid ""
588
+ #~ "cURL library returned empty result. Contact your system administrator to "
589
+ #~ "fix this issue."
590
+ #~ msgstr ""
591
+ #~ "cURL library returned empty result. Contact your system administrator to "
592
+ #~ "fix this issue."
593
+
594
+ #~ msgid ""
595
+ #~ "You are not an active user for current blog. Please click <a href=\"#\" "
596
+ #~ "id=\"add-user-toblog\">here</a> to add yourself to current blog as "
597
+ #~ "Administrator"
598
+ #~ msgstr ""
599
+ #~ "No es un usuario activo para el blog Actual. Por favor clickea <a href="
600
+ #~ "\"#\" id=\"add-user-toblog\">aquí</a> para agregarte como admin del blog "
601
+ #~ "actual"
602
+
603
+ #~ msgid "Basic"
604
+ #~ msgstr " "
605
+
606
+ #~ msgid "Administrator added Successfully"
607
+ #~ msgstr "Administrador agregado"
608
+
609
+ #~ msgid "Failed to add new Administrator"
610
+ #~ msgstr "Falla al agregar Administrador"
611
+
612
+ #~ msgid "Click for more information"
613
+ #~ msgstr "Click para Tooltip"
614
+
615
+ #~ msgid "Current User"
616
+ #~ msgstr "Usuario Actual"
617
+
618
+ #~ msgid "Delete current capability"
619
+ #~ msgstr "Borrar Capability"
620
+
621
+ #~ msgid "Read more..."
622
+ #~ msgstr "Leer Más..."
623
+
624
+ #~ msgid "Restore Default Settings"
625
+ #~ msgstr "Restaurar valores por defecto de Rol?"
626
+
627
+ #~ msgid ""
628
+ #~ "Check Menu or Submenu to restrict or <b>Whole Branch</b> to restrict "
629
+ #~ "whole menu."
630
+ #~ msgstr ""
631
+ #~ "Marque Menú o Sub-menú para restringir el acceso o <b>Toda la Rama</b> "
632
+ #~ "para restringir el acceso a todo el menú."
633
+
634
+ #~ msgid ""
635
+ #~ "Only Latin letters, numbers and space are allowed. All other symbols will "
636
+ #~ "be filtered.<br/>New Capability will be added to Super Admin and Admin "
637
+ #~ "Roles automatically."
638
+ #~ msgstr ""
639
+ #~ "Sólo se permiten letras, números y espacios. Todo lo demás será filtrado."
640
+ #~ "<br/>La nueva Capability se agregará automáticamente a los roles Super "
641
+ #~ "Admin y Admin."
642
+
643
+ #~ msgid "Enter New Capability"
644
+ #~ msgstr "Agregar nueva Capability"
645
+
646
+ #~ msgid "Would you like to restore default restrictions?"
647
+ #~ msgstr "Quiere restaurar los permisos por defecto ?"
648
+
649
+ #~ msgid "Restore Restrictions"
650
+ #~ msgstr "Restaurar valores por defecto de Rol?"
651
+
652
+ #~ msgid "Posts in %s"
653
+ #~ msgstr "Entradas en %s"
654
+
655
+ #~ msgid "Information"
656
+ #~ msgstr "Información"
657
+
658
+ #~ msgid "Refresh"
659
+ #~ msgstr "Refrescar"
660
+
661
+ #~ msgid "Frontend"
662
+ #~ msgstr "Frontend"
663
+
664
+ #~ msgid "Backend"
665
+ #~ msgstr "Backend"
666
+
667
+ #~ msgid "List"
668
+ #~ msgstr "Lista de Roles"
669
+
670
+ #~ msgid "Exclude"
671
+ #~ msgstr "Excluir Página"
672
+
673
+ #~ msgid "Read"
674
+ #~ msgstr "Leer"
675
+
676
+ #~ msgid "Trash"
677
+ #~ msgstr "Papelera"
678
+
679
+ #~ msgid "Install Plugin"
680
+ #~ msgstr "Instalar Plugin"
681
+
682
+ #~ msgid "Publish"
683
+ #~ msgstr "Público"
684
+
685
+ #~ msgid "Comment"
686
+ #~ msgstr "Comentario"
687
+
688
+ #~ msgid "Browse"
689
+ #~ msgstr "Mostrar"
690
+
691
+ #~ msgid "Worth checking"
692
+ #~ msgstr "Chequeo de errores"
693
+
694
+ #~ msgid "Additional features available"
695
+ #~ msgstr "Características adicionales"
696
+
697
+ #~ msgid "You have a JavaScript Error on a page"
698
+ #~ msgstr "Tiene un error Javascript en una página"
699
+
700
+ #~ msgid "For support send an email to address"
701
+ #~ msgstr "Para soporte envíe un email a"
702
+
703
+ #~ msgid "Add New Cap"
704
+ #~ msgstr "Agregar Cap"
705
+
706
+ #~ msgid "Title"
707
+ #~ msgstr "Título"
708
+
709
+ #~ msgid "This is the title of selected Post or Page"
710
+ #~ msgstr "Este es el título del Post o Página seleccionada"
711
+
712
+ #~ msgid "Selected item's type"
713
+ #~ msgstr "Tipo de Item seleccionado"
714
+
715
+ #~ msgid "Type"
716
+ #~ msgstr "Tipo"
717
+
718
+ #~ msgid "Status"
719
+ #~ msgstr "Status"
720
+
721
+ #~ msgid "Current Post or Page Status"
722
+ #~ msgstr "Estado actual del Post o Página"
723
+
724
+ #~ msgid "Visibility"
725
+ #~ msgstr "Visibilidad"
726
+
727
+ #~ msgid "Visibility of current Post or Page"
728
+ #~ msgstr "Visibilidad del Post o Página Actual"
729
+
730
+ #~ msgid "Restrict Admin"
731
+ #~ msgstr "Restringir Admin"
732
+
733
+ #~ msgid "Restrict access to current Post or Page on BackEnd"
734
+ #~ msgstr "Restringir acceso al Post o Página actual en el BackEnd"
735
+
736
+ #~ msgid "Restrict Front"
737
+ #~ msgstr "Restringir Frente"
738
+
739
+ #~ msgid "Restrict access to current Post or Page on FrontEnd"
740
+ #~ msgstr "Restringir acceso al Post o Página actual en el FrontEnd"
741
+
742
+ #~ msgid "Just Exclude page from navitation but do not restrict access"
743
+ #~ msgstr "Sólo Excluye la página de la navegación pero no restringe el acceso"
744
+
745
+ #~ msgid "Expire"
746
+ #~ msgstr "Expirar"
747
+
748
+ #~ msgid ""
749
+ #~ "If Restric is checked then restrict access to current Post or Page until "
750
+ #~ "the picked date. If Restrict is unchecked then allow access to Page or "
751
+ #~ "Post until the picked date"
752
+ #~ msgstr ""
753
+ #~ "Si Restringir está checkeado entonces restringe acceso al post o página "
754
+ #~ "actual hasta la fecha elegida. Si Restringir no está checkeado entonces "
755
+ #~ "permite acceso al post o página actual hasta la fecha elegida."
756
+
757
+ #~ msgid "Update info only for current role"
758
+ #~ msgstr "Actualizar info sólo para el rol actual"
759
+
760
+ #~ msgid "Update Current"
761
+ #~ msgstr "Actualizar"
762
+
763
+ #~ msgid "Update info for all role"
764
+ #~ msgstr "Actualizar info para todos los roles"
765
+
766
+ #~ msgid "Update All"
767
+ #~ msgstr "Actualziar todo"
768
+
769
+ #~ msgid "Category"
770
+ #~ msgstr "Categoría"
771
+
772
+ #~ msgid "Category title"
773
+ #~ msgstr "Título de categoría"
774
+
775
+ #~ msgid "This is just a type of post's taxonomy. Always Category"
776
+ #~ msgstr "Esto es sólo un tipo de taxonomía de post. Siempre Category"
777
+
778
+ #~ msgid "Posts"
779
+ #~ msgstr "Posts"
780
+
781
+ #~ msgid "Number of posts current category has"
782
+ #~ msgstr "Número de posts que tiene la categoría actual"
783
+
784
+ #~ msgid ""
785
+ #~ "Restrict access to current category and for all Sub Categories on "
786
+ #~ "BackEnd. Also it'll restrict access to all posts under these categories"
787
+ #~ msgstr ""
788
+ #~ "Restringir acceso a la categoría actual y a todas las subcategorías en el "
789
+ #~ "BackEnd. También restringirá acceso a todos los posts bajo estas "
790
+ #~ "categorías"
791
+
792
+ #~ msgid ""
793
+ #~ "Restrict access to current category and for all Sub Categories on "
794
+ #~ "FrontEnd. Also it'll restrict access to all posts under these categories"
795
+ #~ msgstr ""
796
+ #~ "Restringir acceso a la categoría actual y a todas las subcategorías en el "
797
+ #~ "FrontEnd. También restringirá acceso a todos los posts bajo estas "
798
+ #~ "categorías"
799
+
800
+ #~ msgid ""
801
+ #~ "If Restric is checked then restrict access to current Category and all "
802
+ #~ "Sub Categories, and Posts since the picked date. If Restrict is unchecked "
803
+ #~ "then allow access to current Category and all Sub Categories, and Posts "
804
+ #~ "since the picked date"
805
+ #~ msgstr ""
806
+ #~ "Si Restringir está checkeado entonces restringe acceso a la categoría "
807
+ #~ "actual y sus subcategorías, y Posts desde la fecha elegida. Si "
808
+ #~ "Restringir no está checkeado entonces permite acceso a la categoría "
809
+ #~ "actual y sus subcategorías, y Posts hasta la fecha elegida."
810
+
811
+ #~ msgid "Select a proper Page, Post or Category."
812
+ #~ msgstr "Seleccionar una página, Post, o Categoría adecuada."
813
+
814
+ #~ msgid "Restore Default Setting for Current Role"
815
+ #~ msgstr "Restaurar valores por defecto del Rol Actual"
816
+
817
+ #~ msgid "Export Configurations"
818
+ #~ msgstr "Exportar configuraciones"
819
+
820
+ #~ msgid "Import Configurations"
821
+ #~ msgstr "Importar Configuraciones"
822
+
823
+ #~ msgid "Support"
824
+ #~ msgstr "Soporte"
825
+
826
+ #~ msgid "Find on Facebook"
827
+ #~ msgstr "Buscar en Facebook"
828
+
829
+ #~ msgid "Follow on Twitter"
830
+ #~ msgstr "Seguir en Twitter"
831
+
832
+ #~ msgid "LinkedIn"
833
+ #~ msgstr "LinkedIn"
834
+
835
+ #~ msgid "Leave Without Saving?"
836
+ #~ msgstr "Salir Sin Salvar ?"
837
+
838
+ #~ msgid ""
839
+ #~ "Some changed detected. Are you sure that you want to leave without saving"
840
+ #~ msgstr "Detectados algunos cambios. Está seguro de salir sin salvar ?"
841
+
842
+ #~ msgid "Additional Features Available"
843
+ #~ msgstr "Disponibles características adicionales"
844
+
845
+ #~ msgid ""
846
+ #~ "Additional features detected to extend Advanced Access Manager "
847
+ #~ "functionality."
848
+ #~ msgstr ""
849
+ #~ "Características adicionales detectadas para extender la funcionalidad del "
850
+ #~ "Administrador Avanzado de Acceso."
851
+
852
+ #~ msgid ""
853
+ #~ "Do you want to create a <b>Super Admin</b> Role to get access to ALL "
854
+ #~ "features?"
855
+ #~ msgstr ""
856
+ #~ "Quiere crear el Rol <b>Super Admin</b> para acceder a todas las "
857
+ #~ "características ?"
858
+
859
+ #~ msgid ""
860
+ #~ "After importing, ALL current configurations will be lost. If you are "
861
+ #~ "sure, please select proper INI file and click on <i>Import</i> button."
862
+ #~ msgstr ""
863
+ #~ "Despues de importar, TODAS las configuraciones actuales de perderán. Si "
864
+ #~ "está seguro, seleccione el Archivo INI apropiado y haga click en el botón "
865
+ #~ "<i>Importar</i>"
866
+
867
+ #~ msgid "Uploading..."
868
+ #~ msgstr "Actualizando..."
869
+
870
+ #~ msgid "Please wait. Importer is working..."
871
+ #~ msgstr "Espere por favor. Realizando la importación..."
872
+
873
+ #~ msgid "You are not authorized to view this page"
874
+ #~ msgstr "No está autorizado a ver esta página"
875
+
876
+ #~ msgid "Import"
877
+ #~ msgstr "Importar"
878
+
879
+ #~ msgid "Error during importing"
880
+ #~ msgstr "Error durante la Importación"
881
+
882
+ #~ msgid "Apply to ALL Blogs"
883
+ #~ msgstr "Aplicar a TODOS los Blogs"
884
+
885
+ #~ msgid "Action completed successfully"
886
+ #~ msgstr "Acción completada con éxito"
887
+
888
+ #~ msgid "Action failed"
889
+ #~ msgstr "Error en la acción"
890
+
891
+ #~ msgid "Settings applied successfully to ALL Blogs"
892
+ #~ msgstr "Valores aplicados con éxito a todos los Blogs"
893
+
894
+ #~ msgid ""
895
+ #~ "<b>Since 2.0</b><br/>\n"
896
+ #~ " <b>Note:</b> No longer used."
897
+ #~ msgstr ""
898
+ #~ "<b>Since 2.0</b><br/>\n"
899
+ #~ " <b>Nota:</b> No usado mas."
900
+
901
+ #~ msgid "<b>Description does not exist</b>"
902
+ #~ msgstr "<b>Descripción no existe</b>"
903
+
904
+ #~ msgid "<p>You do not have sufficient permissions to perform this action</p>"
905
+ #~ msgstr "<p>No tienes los permisos suficientes para realizar esta acción</p>"
906
+
907
+ #~ msgid ""
908
+ #~ "<p><h3>General Information</h3></p>\n"
909
+ #~ " <p>If you want to filter Admin Menu for some User Roles or just "
910
+ #~ "delete unnecessary dashboard widgets or metaboxes in Edit Post Page, this "
911
+ #~ "plugin is for you.\n"
912
+ #~ " You can do following things with Advanced Access Manager:</p>\n"
913
+ #~ "<ul>\n"
914
+ #~ "<li>Filter Admin Menu for specific User Role</li>\n"
915
+ #~ "<li>Filter Dashboard Widgets for specific User Role</li>\n"
916
+ #~ "<li>Filter List of Metaboxes in Edit Post page for specific User Role</"
917
+ #~ "li>\n"
918
+ #~ "<li>Add new User Capabilities</li>\n"
919
+ #~ "<li>Delete created User Capabilities</li>\n"
920
+ #~ "<li>Create new User Roles</li>\n"
921
+ #~ "<li>Delete any User Role</li>\n"
922
+ #~ "<li>Save current User Roles settings and restore later</li>\n"
923
+ #~ "<li>View the list of Posts Pages and Categories in a nice hierarchical "
924
+ #~ "tree</li>\n"
925
+ #~ "<li>Filter Posts and Post Categories</li>\n"
926
+ #~ "<li>Filter Pages and Sub Pages</li>\n"
927
+ #~ "<li>Set expiration Date for specific Posts, Pages or even Categories</"
928
+ #~ "li>\n"
929
+ #~ "<li>Reorganize Order of Main Menu for specific User Role</li>\n"
930
+ #~ "</ul>\n"
931
+ #~ " <p><h3>Main Menu</h3></p>\n"
932
+ #~ " <p>Under Main Menu Tab there is a list of admin menu and submenus. "
933
+ #~ "You can Restrict access to certain menus of submenus by checking proper "
934
+ #~ "checkbox.\n"
935
+ #~ " Also you can reorganize the menu order by draggin and dropping menus "
936
+ #~ "in order you want.</p>\n"
937
+ #~ " <p><h3>Metabox & Widgets</h3></p>\n"
938
+ #~ " <p>This section allows you to filter the list of metaboxes (sections "
939
+ #~ "to the Write Post, Write Page, and Write Link editing pages) and "
940
+ #~ "dashboard widgets.</p>\n"
941
+ #~ " <p><h3>Capabilities</h3></p>\n"
942
+ #~ " <p>This is more advanced Tab which allows to create different "
943
+ #~ "combinations of Capabilities for current User Role. If you are not "
944
+ #~ "familiar with Capabilities please read <a href=\"http://codex.wordpress."
945
+ #~ "org/Roles_and_Capabilities\" target=\"_blank\">Roles and Capabilities</a>."
946
+ #~ "</p>\n"
947
+ #~ " <p><h3>Posts & Pages</h3></p>\n"
948
+ #~ " <p>Tree View of Posts (grouped into categories) and Pages (organized "
949
+ #~ "hierarchically according to Parent Page parameter) where you can restrict "
950
+ #~ "access to certain page or post or the whole category for current User "
951
+ #~ "Role. There is also possibility to set expiration date to posts or pages."
952
+ #~ "</p>\n"
953
+ #~ msgstr ""
954
+ #~ "<p><h3>Información General</h3></p>\n"
955
+ #~ " <p>Si quiere flitrar el Menú Admin para algunos Roles de usuario o "
956
+ #~ "borrar widgets no necesarios del Escritorio o metaboxes en la Edición de "
957
+ #~ "páginas , Este plugin es para ti.\n"
958
+ #~ " You can do following things with Advanced Access Manager:</p>\n"
959
+ #~ "<ul>\n"
960
+ #~ "<li>Filter Admin Menu for specific User Role</li>\n"
961
+ #~ "<li>Filter Dashboard Widgets for specific User Role</li>\n"
962
+ #~ "<li>Filter List of Metaboxes in Edit Post page for specific User Role</"
963
+ #~ "li>\n"
964
+ #~ "<li>Add new User Capabilities</li>\n"
965
+ #~ "<li>Delete created User Capabilities</li>\n"
966
+ #~ "<li>Create new User Roles</li>\n"
967
+ #~ "<li>Delete any User Role</li>\n"
968
+ #~ "<li>Save current User Roles settings and restore later</li>\n"
969
+ #~ "<li>View the list of Posts Pages and Categories in a nice hierarchical "
970
+ #~ "tree</li>\n"
971
+ #~ "<li>Filter Posts and Post Categories</li>\n"
972
+ #~ "<li>Filter Pages and Sub Pages</li>\n"
973
+ #~ "<li>Set expiration Date for specific Posts, Pages or even Categories</"
974
+ #~ "li>\n"
975
+ #~ "<li>Reorganize Order of Main Menu for specific User Role</li>\n"
976
+ #~ "</ul>\n"
977
+ #~ " <p><h3>Main Menu</h3></p>\n"
978
+ #~ " <p>Under Main Menu Tab there is a list of admin menu and submenus. "
979
+ #~ "You can Restrict access to certain menus of submenus by checking proper "
980
+ #~ "checkbox.\n"
981
+ #~ " Also you can reorganize the menu order by draggin and dropping menus "
982
+ #~ "in order you want.</p>\n"
983
+ #~ " <p><h3>Metabox & Widgets</h3></p>\n"
984
+ #~ " <p>This section allows you to filter the list of metaboxes (sections "
985
+ #~ "to the Write Post, Write Page, and Write Link editing pages) and "
986
+ #~ "dashboard widgets.</p>\n"
987
+ #~ " <p><h3>Capabilities</h3></p>\n"
988
+ #~ " <p>This is more advanced Tab which allows to create different "
989
+ #~ "combinations of Capabilities for current User Role. If you are not "
990
+ #~ "familiar with Capabilities please read <a href=\"http://codex.wordpress."
991
+ #~ "org/Roles_and_Capabilities\" target=\"_blank\">Roles and Capabilities</a>."
992
+ #~ "</p>\n"
993
+ #~ " <p><h3>Posts & Pages</h3></p>\n"
994
+ #~ " <p>Tree View of Posts (grouped into categories) and Pages (organized "
995
+ #~ "hierarchically according to Parent Page parameter) where you can restrict "
996
+ #~ "access to certain page or post or the whole category for current User "
997
+ #~ "Role. There is also possibility to set expiration date to posts or pages."
998
+ #~ "</p>\n"
lang/aam.pot ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: AAM\n"
4
+ "POT-Creation-Date: 2013-12-01 14:07-0500\n"
5
+ "PO-Revision-Date: 2013-12-01 14:08-0500\n"
6
+ "Last-Translator: Vasyl Martyniuk <martyniuk.vasyl@gmail.com>\n"
7
+ "Language-Team: WPAAM <support@wpaam.com>\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+
12
+ #: aam.php:243 aam.php:248 aam.php:267
13
+ msgid "Access denied"
14
+ msgstr ""
15
+
16
+ #: aam.php:691 aam.php:692
17
+ msgid "AAM"
18
+ msgstr ""
19
+
20
+ #: aam.php:701 aam.php:702
21
+ msgid "Access Control"
22
+ msgstr ""
23
+
24
+ #: aam.php:709 aam.php:710
25
+ msgid "Extensions"
26
+ msgstr ""
27
+
28
+ #: application/view/capability.php:98 application/view/capability.php:179
29
+ msgid "System"
30
+ msgstr ""
31
+
32
+ #: application/view/capability.php:99 application/view/capability.php:181
33
+ msgid "Post & Page"
34
+ msgstr ""
35
+
36
+ #: application/view/capability.php:100 application/view/capability.php:183
37
+ msgid "Backend Interface"
38
+ msgstr ""
39
+
40
+ #: application/view/capability.php:101
41
+ msgid "Miscellaneous"
42
+ msgstr ""
43
+
44
+ #: application/view/capability.php:185
45
+ msgid "Miscelaneous"
46
+ msgstr ""
47
+
48
+ #: application/view/manager.php:59
49
+ msgid "Roles"
50
+ msgstr ""
51
+
52
+ #: application/view/manager.php:60
53
+ msgid "Role Manager"
54
+ msgstr ""
55
+
56
+ #: application/view/manager.php:68
57
+ msgid "Users"
58
+ msgstr ""
59
+
60
+ #: application/view/manager.php:69
61
+ msgid "User Manager"
62
+ msgstr ""
63
+
64
+ #: application/view/manager.php:77
65
+ msgid "Visitor"
66
+ msgstr ""
67
+
68
+ #: application/view/manager.php:78
69
+ msgid "Visitor Manager"
70
+ msgstr ""
71
+
72
+ #: application/view/manager.php:95
73
+ msgid "Admin Menu"
74
+ msgstr ""
75
+
76
+ #: application/view/manager.php:98
77
+ msgid ""
78
+ "Control Access to Admin Menu. Restrict access to entire Menu or Submenu. "
79
+ "<b>Notice</b>, the menu is rendered based on Role's or User's capabilities."
80
+ msgstr ""
81
+
82
+ #: application/view/manager.php:103
83
+ msgid "Metabox & Widget"
84
+ msgstr ""
85
+
86
+ #: application/view/manager.php:106
87
+ msgid ""
88
+ "Filter the list of Metaboxes or Widgets for selected Role or User. If "
89
+ "metabox or widget is not listed, try to click <b>Refresh the List</b> button "
90
+ "or Copy & Paste direct link to page where specific metabox or widget is "
91
+ "shown and hit <b>Retrieve Metaboxes from Link</b> button."
92
+ msgstr ""
93
+
94
+ #: application/view/manager.php:111
95
+ msgid "Capability"
96
+ msgstr ""
97
+
98
+ #: application/view/manager.php:114
99
+ msgid ""
100
+ "Manage the list of Capabilities for selected User or Role. <b>Notice</b>, "
101
+ "list of user's capabilities are inherited from user's Role.<br/><b>Warning!</"
102
+ "b> Be very careful with capabilities. Deleting or unchecking any capability "
103
+ "may cause temporary or permanent constrol lost over some features or "
104
+ "WordPress dashboard."
105
+ msgstr ""
106
+
107
+ #: application/view/manager.php:119
108
+ msgid "Posts & Categories"
109
+ msgstr ""
110
+
111
+ #: application/view/manager.php:122
112
+ msgid ""
113
+ "Manage access to individual <b>Post</b> or <b>Term</b>. Notice, under "
114
+ "<b>Post</b>, we assume any post, page or custom post type. And under "
115
+ "<b>Term</b> - any term like Post Categories."
116
+ msgstr ""
117
+
118
+ #: application/view/manager.php:127
119
+ msgid "Event Manager"
120
+ msgstr ""
121
+
122
+ #: application/view/manager.php:130
123
+ msgid ""
124
+ "Define your own action when some event appeared in your WordPress blog. This "
125
+ "sections allows you to trigger an action on event like post content change, "
126
+ "or page status update. You can setup to send email notification, change the "
127
+ "post status or write your own custom event handler."
128
+ msgstr ""
129
+
130
+ #: application/view/manager.php:135
131
+ msgid "ConfigPress"
132
+ msgstr ""
133
+
134
+ #: application/view/manager.php:138
135
+ msgid ""
136
+ "Control <b>AAM</b> behavior with ConfigPress. For more details please check "
137
+ "<b>ConfigPress tutorial</b>."
138
+ msgstr ""
139
+
140
+ #: application/view/manager.php:342
141
+ msgid "Rollback Settings"
142
+ msgstr ""
143
+
144
+ #: application/view/manager.php:343
145
+ msgid "Cancel"
146
+ msgstr ""
147
+
148
+ #: application/view/manager.php:344
149
+ msgid "Send E-mail"
150
+ msgstr ""
151
+
152
+ #: application/view/manager.php:345 application/view/manager.php:351
153
+ msgid "Add New Role"
154
+ msgstr ""
155
+
156
+ #: application/view/manager.php:346
157
+ msgid "Manage"
158
+ msgstr ""
159
+
160
+ #: application/view/manager.php:347
161
+ msgid "Edit"
162
+ msgstr ""
163
+
164
+ #: application/view/manager.php:348
165
+ msgid "Delete"
166
+ msgstr ""
167
+
168
+ #: application/view/manager.php:349
169
+ msgid "Filtered"
170
+ msgstr ""
171
+
172
+ #: application/view/manager.php:350
173
+ msgid "Clear"
174
+ msgstr ""
175
+
176
+ #: application/view/manager.php:352
177
+ msgid "Save Changes"
178
+ msgstr ""
179
+
180
+ #: application/view/manager.php:353
181
+ #, php-format
182
+ msgid ""
183
+ "System detected %d user(s) with this role. All Users with Role <b>%s</b> "
184
+ "will be deleted automatically!"
185
+ msgstr ""
186
+
187
+ #: application/view/manager.php:354
188
+ #, php-format
189
+ msgid "Are you sure that you want to delete role <b>%s</b>?"
190
+ msgstr ""
191
+
192
+ #: application/view/manager.php:355
193
+ msgid "Delete Role"
194
+ msgstr ""
195
+
196
+ #: application/view/manager.php:356
197
+ msgid "Add User"
198
+ msgstr ""
199
+
200
+ #: application/view/manager.php:357
201
+ msgid "Filter Users"
202
+ msgstr ""
203
+
204
+ #: application/view/manager.php:358 application/view/manager.php:374
205
+ msgid "Refresh List"
206
+ msgstr ""
207
+
208
+ #: application/view/manager.php:359
209
+ msgid "Block"
210
+ msgstr ""
211
+
212
+ #: application/view/manager.php:360
213
+ #, php-format
214
+ msgid "Are you sure you want to delete user <b>%s</b>?"
215
+ msgstr ""
216
+
217
+ #: application/view/manager.php:361
218
+ msgid "Filter Capabilities by Category"
219
+ msgstr ""
220
+
221
+ #: application/view/manager.php:362
222
+ msgid "Inherit Capabilities"
223
+ msgstr ""
224
+
225
+ #: application/view/manager.php:363
226
+ msgid "Add New Capability"
227
+ msgstr ""
228
+
229
+ #: application/view/manager.php:364
230
+ #, php-format
231
+ msgid "Are you sure that you want to delete capability <b>%s</b>?"
232
+ msgstr ""
233
+
234
+ #: application/view/manager.php:365
235
+ msgid "Delete Capability"
236
+ msgstr ""
237
+
238
+ #: application/view/manager.php:366
239
+ msgid "Select Role"
240
+ msgstr ""
241
+
242
+ #: application/view/manager.php:367
243
+ msgid "Add Capability"
244
+ msgstr ""
245
+
246
+ #: application/view/manager.php:368
247
+ msgid "Add Event"
248
+ msgstr ""
249
+
250
+ #: application/view/manager.php:369
251
+ msgid "Edit Event"
252
+ msgstr ""
253
+
254
+ #: application/view/manager.php:370 application/view/manager.php:372
255
+ msgid "Delete Event"
256
+ msgstr ""
257
+
258
+ #: application/view/manager.php:371
259
+ msgid "Save Event"
260
+ msgstr ""
261
+
262
+ #: application/view/manager.php:373
263
+ msgid "Filter Posts by Post Type"
264
+ msgstr ""
265
+
266
+ #: application/view/manager.php:375
267
+ msgid "Restore Default"
268
+ msgstr ""
269
+
270
+ #: application/view/manager.php:376
271
+ msgid "Apply"
272
+ msgstr ""
273
+
274
+ #: application/view/manager.php:377
275
+ msgid "Edit Term"
276
+ msgstr ""
277
+
278
+ #: application/view/manager.php:378
279
+ msgid "Manager Access"
280
+ msgstr ""
281
+
282
+ #: application/view/manager.php:379
283
+ msgid "Unlock Default Accesss Control"
284
+ msgstr ""
285
+
286
+ #: application/view/manager.php:380
287
+ msgid "Close"
288
+ msgstr ""
289
+
290
+ #: application/view/manager.php:381
291
+ msgid "Edit Role"
292
+ msgstr ""
293
+
294
+ #: application/view/metabox.php:179
295
+ msgid "Dashboard Widgets"
296
+ msgstr ""
297
+
298
+ #: application/view/metabox.php:183
299
+ msgid "Frontend Widgets"
300
+ msgstr ""
301
+
302
+ #: application/view/post.php:181
303
+ msgid "[empty]"
304
+ msgstr ""
305
+
306
+ #: application/view/post.php:345 application/view/post.php:353
307
+ msgid "All"
308
+ msgstr ""
library/Zend/Config.php ADDED
@@ -0,0 +1,485 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Zend Framework
4
+ *
5
+ * LICENSE
6
+ *
7
+ * This source file is subject to the new BSD license that is bundled
8
+ * with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://framework.zend.com/license/new-bsd
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@zend.com so we can send you a copy immediately.
14
+ *
15
+ * @category Zend
16
+ * @package Zend_Config
17
+ * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
18
+ * @license http://framework.zend.com/license/new-bsd New BSD License
19
+ * @version $Id: Config.php 23775 2011-03-01 17:25:24Z ralph $
20
+ */
21
+
22
+ /**
23
+ * File has been modified by Vasyl Martyniuk <martyniuk.vasyl@gmail.com> to fit the
24
+ * project needs.
25
+ */
26
+
27
+ /**
28
+ * @category Zend
29
+ * @package Zend_Config
30
+ * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
31
+ * @license http://framework.zend.com/license/new-bsd New BSD License
32
+ */
33
+ class Zend_Config implements Countable, Iterator
34
+ {
35
+ /**
36
+ * Whether in-memory modifications to configuration data are allowed
37
+ *
38
+ * @var boolean
39
+ */
40
+ protected $_allowModifications;
41
+
42
+ /**
43
+ * Iteration index
44
+ *
45
+ * @var integer
46
+ */
47
+ protected $_index;
48
+
49
+ /**
50
+ * Number of elements in configuration data
51
+ *
52
+ * @var integer
53
+ */
54
+ protected $_count;
55
+
56
+ /**
57
+ * Contains array of configuration data
58
+ *
59
+ * @var array
60
+ */
61
+ protected $_data;
62
+
63
+ /**
64
+ * Used when unsetting values during iteration to ensure we do not skip
65
+ * the next element
66
+ *
67
+ * @var boolean
68
+ */
69
+ protected $_skipNextIteration;
70
+
71
+ /**
72
+ * Contains which config file sections were loaded. This is null
73
+ * if all sections were loaded, a string name if one section is loaded
74
+ * and an array of string names if multiple sections were loaded.
75
+ *
76
+ * @var mixed
77
+ */
78
+ protected $_loadedSection;
79
+
80
+ /**
81
+ * This is used to track section inheritance. The keys are names of sections that
82
+ * extend other sections, and the values are the extended sections.
83
+ *
84
+ * @var array
85
+ */
86
+ protected $_extends = array();
87
+
88
+ /**
89
+ * Load file error string.
90
+ *
91
+ * Is null if there was no error while file loading
92
+ *
93
+ * @var string
94
+ */
95
+ protected $_loadFileErrorStr = null;
96
+
97
+ /**
98
+ * Zend_Config provides a property based interface to
99
+ * an array. The data are read-only unless $allowModifications
100
+ * is set to true on construction.
101
+ *
102
+ * Zend_Config also implements Countable and Iterator to
103
+ * facilitate easy access to the data.
104
+ *
105
+ * @param array $array
106
+ * @param boolean $allowModifications
107
+ * @return void
108
+ */
109
+ public function __construct(array $array, $allowModifications = false)
110
+ {
111
+ $this->_allowModifications = (boolean) $allowModifications;
112
+ $this->_loadedSection = null;
113
+ $this->_index = 0;
114
+ $this->_data = array();
115
+ foreach ($array as $key => $value) {
116
+ if (is_array($value)) {
117
+ $this->_data[$key] = new self($value, $this->_allowModifications);
118
+ } else {
119
+ $this->_data[$key] = $value;
120
+ }
121
+ }
122
+ $this->_count = count($this->_data);
123
+ }
124
+
125
+ /**
126
+ * Retrieve a value and return $default if there is no element set.
127
+ *
128
+ * @param string $name
129
+ * @param mixed $default
130
+ * @return mixed
131
+ */
132
+ public function get($name, $default = null)
133
+ {
134
+ $result = $default;
135
+ if (array_key_exists($name, $this->_data)) {
136
+ $result = $this->_data[$name];
137
+ }
138
+ return $result;
139
+ }
140
+
141
+ /**
142
+ * Magic function so that $obj->value will work.
143
+ *
144
+ * @param string $name
145
+ * @return mixed
146
+ */
147
+ public function __get($name)
148
+ {
149
+ return $this->get($name);
150
+ }
151
+
152
+ /**
153
+ * Only allow setting of a property if $allowModifications
154
+ * was set to true on construction. Otherwise, throw an exception.
155
+ *
156
+ * @param string $name
157
+ * @param mixed $value
158
+ * @throws Zend_Config_Exception
159
+ * @return void
160
+ */
161
+ public function __set($name, $value)
162
+ {
163
+ if ($this->_allowModifications) {
164
+ if (is_array($value)) {
165
+ $this->_data[$name] = new self($value, true);
166
+ } else {
167
+ $this->_data[$name] = $value;
168
+ }
169
+ $this->_count = count($this->_data);
170
+ } else {
171
+ /** @see Zend_Config_Exception */
172
+ throw new Zend_Config_Exception('Zend_Config is read only');
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Deep clone of this instance to ensure that nested Zend_Configs
178
+ * are also cloned.
179
+ *
180
+ * @return void
181
+ */
182
+ public function __clone()
183
+ {
184
+ $array = array();
185
+ foreach ($this->_data as $key => $value) {
186
+ if ($value instanceof Zend_Config) {
187
+ $array[$key] = clone $value;
188
+ } else {
189
+ $array[$key] = $value;
190
+ }
191
+ }
192
+ $this->_data = $array;
193
+ }
194
+
195
+ /**
196
+ * Return an associative array of the stored data.
197
+ *
198
+ * @return array
199
+ */
200
+ public function toArray()
201
+ {
202
+ $array = array();
203
+ $data = $this->_data;
204
+ foreach ($data as $key => $value) {
205
+ if ($value instanceof Zend_Config) {
206
+ $array[$key] = $value->toArray();
207
+ } else {
208
+ $array[$key] = $value;
209
+ }
210
+ }
211
+ return $array;
212
+ }
213
+
214
+ /**
215
+ * Support isset() overloading on PHP 5.1
216
+ *
217
+ * @param string $name
218
+ * @return boolean
219
+ */
220
+ public function __isset($name)
221
+ {
222
+ return isset($this->_data[$name]);
223
+ }
224
+
225
+ /**
226
+ * Support unset() overloading on PHP 5.1
227
+ *
228
+ * @param string $name
229
+ * @throws Zend_Config_Exception
230
+ * @return void
231
+ */
232
+ public function __unset($name)
233
+ {
234
+ if ($this->_allowModifications) {
235
+ unset($this->_data[$name]);
236
+ $this->_count = count($this->_data);
237
+ $this->_skipNextIteration = true;
238
+ } else {
239
+ /** @see Zend_Config_Exception */
240
+ throw new Zend_Config_Exception('Zend_Config is read only');
241
+ }
242
+
243
+ }
244
+
245
+ /**
246
+ * Defined by Countable interface
247
+ *
248
+ * @return int
249
+ */
250
+ public function count()
251
+ {
252
+ return $this->_count;
253
+ }
254
+
255
+ /**
256
+ * Defined by Iterator interface
257
+ *
258
+ * @return mixed
259
+ */
260
+ public function current()
261
+ {
262
+ $this->_skipNextIteration = false;
263
+ return current($this->_data);
264
+ }
265
+
266
+ /**
267
+ * Defined by Iterator interface
268
+ *
269
+ * @return mixed
270
+ */
271
+ public function key()
272
+ {
273
+ return key($this->_data);
274
+ }
275
+
276
+ /**
277
+ * Defined by Iterator interface
278
+ *
279
+ */
280
+ public function next()
281
+ {
282
+ if ($this->_skipNextIteration) {
283
+ $this->_skipNextIteration = false;
284
+ return;
285
+ }
286
+ next($this->_data);
287
+ $this->_index++;
288
+ }
289
+
290
+ /**
291
+ * Defined by Iterator interface
292
+ *
293
+ */
294
+ public function rewind()
295
+ {
296
+ $this->_skipNextIteration = false;
297
+ reset($this->_data);
298
+ $this->_index = 0;
299
+ }
300
+
301
+ /**
302
+ * Defined by Iterator interface
303
+ *
304
+ * @return boolean
305
+ */
306
+ public function valid()
307
+ {
308
+ return $this->_index < $this->_count;
309
+ }
310
+
311
+ /**
312
+ * Returns the section name(s) loaded.
313
+ *
314
+ * @return mixed
315
+ */
316
+ public function getSectionName()
317
+ {
318
+ if(is_array($this->_loadedSection) && count($this->_loadedSection) == 1) {
319
+ $this->_loadedSection = $this->_loadedSection[0];
320
+ }
321
+ return $this->_loadedSection;
322
+ }
323
+
324
+ /**
325
+ * Returns true if all sections were loaded
326
+ *
327
+ * @return boolean
328
+ */
329
+ public function areAllSectionsLoaded()
330
+ {
331
+ return $this->_loadedSection === null;
332
+ }
333
+
334
+
335
+ /**
336
+ * Merge another Zend_Config with this one. The items
337
+ * in $merge will override the same named items in
338
+ * the current config.
339
+ *
340
+ * @param Zend_Config $merge
341
+ * @return Zend_Config
342
+ */
343
+ public function merge(Zend_Config $merge)
344
+ {
345
+ foreach($merge as $key => $item) {
346
+ if(array_key_exists($key, $this->_data)) {
347
+ if($item instanceof Zend_Config && $this->$key instanceof Zend_Config) {
348
+ $this->$key = $this->$key->merge(new Zend_Config($item->toArray(), !$this->readOnly()));
349
+ } else {
350
+ $this->$key = $item;
351
+ }
352
+ } else {
353
+ if($item instanceof Zend_Config) {
354
+ $this->$key = new Zend_Config($item->toArray(), !$this->readOnly());
355
+ } else {
356
+ $this->$key = $item;
357
+ }
358
+ }
359
+ }
360
+
361
+ return $this;
362
+ }
363
+
364
+ /**
365
+ * Prevent any more modifications being made to this instance. Useful
366
+ * after merge() has been used to merge multiple Zend_Config objects
367
+ * into one object which should then not be modified again.
368
+ *
369
+ */
370
+ public function setReadOnly()
371
+ {
372
+ $this->_allowModifications = false;
373
+ foreach ($this->_data as $key => $value) {
374
+ if ($value instanceof Zend_Config) {
375
+ $value->setReadOnly();
376
+ }
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Returns if this Zend_Config object is read only or not.
382
+ *
383
+ * @return boolean
384
+ */
385
+ public function readOnly()
386
+ {
387
+ return !$this->_allowModifications;
388
+ }
389
+
390
+ /**
391
+ * Get the current extends
392
+ *
393
+ * @return array
394
+ */
395
+ public function getExtends()
396
+ {
397
+ return $this->_extends;
398
+ }
399
+
400
+ /**
401
+ * Set an extend for Zend_Config_Writer
402
+ *
403
+ * @param string $extendingSection
404
+ * @param string $extendedSection
405
+ * @return void
406
+ */
407
+ public function setExtend($extendingSection, $extendedSection = null)
408
+ {
409
+ if ($extendedSection === null && isset($this->_extends[$extendingSection])) {
410
+ unset($this->_extends[$extendingSection]);
411
+ } else if ($extendedSection !== null) {
412
+ $this->_extends[$extendingSection] = $extendedSection;
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Throws an exception if $extendingSection may not extend $extendedSection,
418
+ * and tracks the section extension if it is valid.
419
+ *
420
+ * @param string $extendingSection
421
+ * @param string $extendedSection
422
+ * @throws Zend_Config_Exception
423
+ * @return void
424
+ */
425
+ protected function _assertValidExtend($extendingSection, $extendedSection)
426
+ {
427
+ // detect circular section inheritance
428
+ $extendedSectionCurrent = $extendedSection;
429
+ while (array_key_exists($extendedSectionCurrent, $this->_extends)) {
430
+ if ($this->_extends[$extendedSectionCurrent] == $extendingSection) {
431
+ /** @see Zend_Config_Exception */
432
+ throw new Zend_Config_Exception('Illegal circular inheritance detected');
433
+ }
434
+ $extendedSectionCurrent = $this->_extends[$extendedSectionCurrent];
435
+ }
436
+ // remember that this section extends another section
437
+ $this->_extends[$extendingSection] = $extendedSection;
438
+ }
439
+
440
+ /**
441
+ * Handle any errors from simplexml_load_file or parse_ini_file
442
+ *
443
+ * @param integer $errno
444
+ * @param string $errstr
445
+ * @param string $errfile
446
+ * @param integer $errline
447
+ */
448
+ protected function _loadFileErrorHandler($errno, $errstr, $errfile, $errline)
449
+ {
450
+ if ($this->_loadFileErrorStr === null) {
451
+ $this->_loadFileErrorStr = $errstr;
452
+ } else {
453
+ $this->_loadFileErrorStr .= (PHP_EOL . $errstr);
454
+ }
455
+ }
456
+
457
+ /**
458
+ * Merge two arrays recursively, overwriting keys of the same name
459
+ * in $firstArray with the value in $secondArray.
460
+ *
461
+ * @param mixed $firstArray First array
462
+ * @param mixed $secondArray Second array to merge into first array
463
+ * @return array
464
+ */
465
+ protected function _arrayMergeRecursive($firstArray, $secondArray)
466
+ {
467
+ if (is_array($firstArray) && is_array($secondArray)) {
468
+ foreach ($secondArray as $key => $value) {
469
+ if (isset($firstArray[$key])) {
470
+ $firstArray[$key] = $this->_arrayMergeRecursive($firstArray[$key], $value);
471
+ } else {
472
+ if($key === 0) {
473
+ $firstArray= array(0=>$this->_arrayMergeRecursive($firstArray, $value));
474
+ } else {
475
+ $firstArray[$key] = $value;
476
+ }
477
+ }
478
+ }
479
+ } else {
480
+ $firstArray = $secondArray;
481
+ }
482
+
483
+ return $firstArray;
484
+ }
485
+ }
library/Zend/Config/Exception.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Zend Framework
4
+ *
5
+ * LICENSE
6
+ *
7
+ * This source file is subject to the new BSD license that is bundled
8
+ * with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://framework.zend.com/license/new-bsd
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@zend.com so we can send you a copy immediately.
14
+ *
15
+ * @category Zend
16
+ * @package Zend_Config
17
+ * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
18
+ * @license http://framework.zend.com/license/new-bsd New BSD License
19
+ * @version $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $
20
+ */
21
+
22
+ /**
23
+ * File has been modified by Vasyl Martyniuk <martyniuk.vasyl@gmail.com> to fit the
24
+ * project needs.
25
+ */
26
+
27
+ /**
28
+ * @category Zend
29
+ * @package Zend_Config
30
+ * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
31
+ * @license http://framework.zend.com/license/new-bsd New BSD License
32
+ */
33
+ class Zend_Config_Exception extends Zend_Exception {}
library/Zend/Config/Ini.php ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Zend Framework
4
+ *
5
+ * LICENSE
6
+ *
7
+ * This source file is subject to the new BSD license that is bundled
8
+ * with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://framework.zend.com/license/new-bsd
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@zend.com so we can send you a copy immediately.
14
+ *
15
+ * @category Zend
16
+ * @package Zend_Config
17
+ * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
18
+ * @license http://framework.zend.com/license/new-bsd New BSD License
19
+ * @version $Id: Ini.php 24045 2011-05-23 12:45:11Z rob $
20
+ */
21
+
22
+ /**
23
+ * File has been modified by Vasyl Martyniuk <martyniuk.vasyl@gmail.com> to fit the
24
+ * project needs.
25
+ */
26
+
27
+
28
+ /**
29
+ * @category Zend
30
+ * @package Zend_Config
31
+ * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
32
+ * @license http://framework.zend.com/license/new-bsd New BSD License
33
+ */
34
+ class Zend_Config_Ini extends Zend_Config
35
+ {
36
+ /**
37
+ * String that separates nesting levels of configuration data identifiers
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_nestSeparator = '.';
42
+
43
+ /**
44
+ * String that separates the parent section name
45
+ *
46
+ * @var string
47
+ */
48
+ protected $_sectionSeparator = ':';
49
+
50
+ /**
51
+ * Whether to skip extends or not
52
+ *
53
+ * @var boolean
54
+ */
55
+ protected $_skipExtends = false;
56
+
57
+ /**
58
+ * Loads the section $section from the config file $filename for
59
+ * access facilitated by nested object properties.
60
+ *
61
+ * If the section name contains a ":" then the section name to the right
62
+ * is loaded and included into the properties. Note that the keys in
63
+ * this $section will override any keys of the same
64
+ * name in the sections that have been included via ":".
65
+ *
66
+ * If the $section is null, then all sections in the ini file are loaded.
67
+ *
68
+ * If any key includes a ".", then this will act as a separator to
69
+ * create a sub-property.
70
+ *
71
+ * example ini file:
72
+ * [all]
73
+ * db.connection = database
74
+ * hostname = live
75
+ *
76
+ * [staging : all]
77
+ * hostname = staging
78
+ *
79
+ * after calling $data = new Zend_Config_Ini($file, 'staging'); then
80
+ * $data->hostname === "staging"
81
+ * $data->db->connection === "database"
82
+ *
83
+ * The $options parameter may be provided as either a boolean or an array.
84
+ * If provided as a boolean, this sets the $allowModifications option of
85
+ * Zend_Config. If provided as an array, there are three configuration
86
+ * directives that may be set. For example:
87
+ *
88
+ * $options = array(
89
+ * 'allowModifications' => false,
90
+ * 'nestSeparator' => ':',
91
+ * 'skipExtends' => false,
92
+ * );
93
+ *
94
+ * @param string $filename
95
+ * @param mixed $section
96
+ * @param boolean|array $options
97
+ * @throws Zend_Config_Exception
98
+ * @return void
99
+ */
100
+ public function __construct($filename, $section = null, $options = false)
101
+ {
102
+ if (empty($filename)) {
103
+ /**
104
+ * @see Zend_Config_Exception
105
+ */
106
+ throw new Zend_Config_Exception('Filename is not set');
107
+ }
108
+
109
+ $allowModifications = false;
110
+ if (is_bool($options)) {
111
+ $allowModifications = $options;
112
+ } elseif (is_array($options)) {
113
+ if (isset($options['allowModifications'])) {
114
+ $allowModifications = (bool) $options['allowModifications'];
115
+ }
116
+ if (isset($options['nestSeparator'])) {
117
+ $this->_nestSeparator = (string) $options['nestSeparator'];
118
+ }
119
+ if (isset($options['skipExtends'])) {
120
+ $this->_skipExtends = (bool) $options['skipExtends'];
121
+ }
122
+ }
123
+
124
+ $iniArray = $this->_loadIniFile($filename);
125
+
126
+ if (null === $section) {
127
+ // Load entire file
128
+ $dataArray = array();
129
+ foreach ($iniArray as $sectionName => $sectionData) {
130
+ if(!is_array($sectionData)) {
131
+ $dataArray = $this->_arrayMergeRecursive($dataArray, $this->_processKey(array(), $sectionName, $sectionData));
132
+ } else {
133
+ $dataArray[$sectionName] = $this->_processSection($iniArray, $sectionName);
134
+ }
135
+ }
136
+ parent::__construct($dataArray, $allowModifications);
137
+ } else {
138
+ // Load one or more sections
139
+ if (!is_array($section)) {
140
+ $section = array($section);
141
+ }
142
+ $dataArray = array();
143
+ foreach ($section as $sectionName) {
144
+ if (!isset($iniArray[$sectionName])) {
145
+ /**
146
+ * @see Zend_Config_Exception
147
+ */
148
+ throw new Zend_Config_Exception("Section '$sectionName' cannot be found in $filename");
149
+ }
150
+ $dataArray = $this->_arrayMergeRecursive($this->_processSection($iniArray, $sectionName), $dataArray);
151
+
152
+ }
153
+ parent::__construct($dataArray, $allowModifications);
154
+ }
155
+
156
+ $this->_loadedSection = $section;
157
+ }
158
+
159
+ /**
160
+ * Load the INI file from disk using parse_ini_file(). Use a private error
161
+ * handler to convert any loading errors into a Zend_Config_Exception
162
+ *
163
+ * @param string $filename
164
+ * @throws Zend_Config_Exception
165
+ * @return array
166
+ */
167
+ protected function _parseIniFile($filename)
168
+ {
169
+ set_error_handler(array($this, '_loadFileErrorHandler'));
170
+ $iniArray = parse_ini_file($filename, true); // Warnings and errors are suppressed
171
+ restore_error_handler();
172
+
173
+ // Check if there was a error while loading file
174
+ if ($this->_loadFileErrorStr !== null) {
175
+ /**
176
+ * @see Zend_Config_Exception
177
+ */
178
+ throw new Zend_Config_Exception($this->_loadFileErrorStr);
179
+ }
180
+
181
+ return $iniArray;
182
+ }
183
+
184
+ /**
185
+ * Load the ini file and preprocess the section separator (':' in the
186
+ * section name (that is used for section extension) so that the resultant
187
+ * array has the correct section names and the extension information is
188
+ * stored in a sub-key called ';extends'. We use ';extends' as this can
189
+ * never be a valid key name in an INI file that has been loaded using
190
+ * parse_ini_file().
191
+ *
192
+ * @param string $filename
193
+ * @throws Zend_Config_Exception
194
+ * @return array
195
+ */
196
+ protected function _loadIniFile($filename)
197
+ {
198
+ $loaded = $this->_parseIniFile($filename);
199
+ $iniArray = array();
200
+ foreach ($loaded as $key => $data)
201
+ {
202
+ $pieces = explode($this->_sectionSeparator, $key);
203
+ $thisSection = trim($pieces[0]);
204
+ switch (count($pieces)) {
205
+ case 1:
206
+ $iniArray[$thisSection] = $data;
207
+ break;
208
+
209
+ case 2:
210
+ $extendedSection = trim($pieces[1]);
211
+ $iniArray[$thisSection] = array_merge(array(';extends'=>$extendedSection), $data);
212
+ break;
213
+
214
+ default:
215
+ /**
216
+ * @see Zend_Config_Exception
217
+ */
218
+ throw new Zend_Config_Exception("Section '$thisSection' may not extend multiple sections in $filename");
219
+ }
220
+ }
221
+
222
+ return $iniArray;
223
+ }
224
+
225
+ /**
226
+ * Process each element in the section and handle the ";extends" inheritance
227
+ * key. Passes control to _processKey() to handle the nest separator
228
+ * sub-property syntax that may be used within the key name.
229
+ *
230
+ * @param array $iniArray
231
+ * @param string $section
232
+ * @param array $config
233
+ * @throws Zend_Config_Exception
234
+ * @return array
235
+ */
236
+ protected function _processSection($iniArray, $section, $config = array())
237
+ {
238
+ $thisSection = $iniArray[$section];
239
+
240
+ foreach ($thisSection as $key => $value) {
241
+ if (strtolower($key) == ';extends') {
242
+ if (isset($iniArray[$value])) {
243
+ $this->_assertValidExtend($section, $value);
244
+
245
+ if (!$this->_skipExtends) {
246
+ $config = $this->_processSection($iniArray, $value, $config);
247
+ }
248
+ } else {
249
+ /**
250
+ * @see Zend_Config_Exception
251
+ */
252
+ throw new Zend_Config_Exception("Parent section '$section' cannot be found");
253
+ }
254
+ } else {
255
+ $config = $this->_processKey($config, $key, $value);
256
+ }
257
+ }
258
+ return $config;
259
+ }
260
+
261
+ /**
262
+ * Assign the key's value to the property list. Handles the
263
+ * nest separator for sub-properties.
264
+ *
265
+ * @param array $config
266
+ * @param string $key
267
+ * @param string $value
268
+ * @throws Zend_Config_Exception
269
+ * @return array
270
+ */
271
+ protected function _processKey($config, $key, $value)
272
+ {
273
+ if (strpos($key, $this->_nestSeparator) !== false) {
274
+ $pieces = explode($this->_nestSeparator, $key, 2);
275
+ if (strlen($pieces[0]) && strlen($pieces[1])) {
276
+ if (!isset($config[$pieces[0]])) {
277
+ if ($pieces[0] === '0' && !empty($config)) {
278
+ // convert the current values in $config into an array
279
+ $config = array($pieces[0] => $config);
280
+ } else {
281
+ $config[$pieces[0]] = array();
282
+ }
283
+ } elseif (!is_array($config[$pieces[0]])) {
284
+ /**
285
+ * @see Zend_Config_Exception
286
+ */
287
+ throw new Zend_Config_Exception("Cannot create sub-key for '{$pieces[0]}' as key already exists");
288
+ }
289
+ $config[$pieces[0]] = $this->_processKey($config[$pieces[0]], $pieces[1], $value);
290
+ } else {
291
+ /**
292
+ * @see Zend_Config_Exception
293
+ */
294
+ throw new Zend_Config_Exception("Invalid key '$key'");
295
+ }
296
+ } else {
297
+ $config[$key] = $value;
298
+ }
299
+ return $config;
300
+ }
301
+ }
library/Zend/Exception.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Zend Framework
4
+ *
5
+ * LICENSE
6
+ *
7
+ * This source file is subject to the new BSD license that is bundled
8
+ * with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://framework.zend.com/license/new-bsd
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@zend.com so we can send you a copy immediately.
14
+ *
15
+ * @category Zend
16
+ * @package Zend
17
+ * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
18
+ * @license http://framework.zend.com/license/new-bsd New BSD License
19
+ * @version $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $
20
+ */
21
+
22
+ /**
23
+ * File has been modified by Vasyl Martyniuk <martyniuk.vasyl@gmail.com> to fit the
24
+ * project needs.
25
+ */
26
+
27
+ /**
28
+ * @category Zend
29
+ * @package Zend
30
+ * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
31
+ * @license http://framework.zend.com/license/new-bsd New BSD License
32
+ */
33
+ class Zend_Exception extends Exception
34
+ {
35
+ /**
36
+ * @var null|Exception
37
+ */
38
+ private $_previous = null;
39
+
40
+ /**
41
+ * Construct the exception
42
+ *
43
+ * @param string $msg
44
+ * @param int $code
45
+ * @param Exception $previous
46
+ * @return void
47
+ */
48
+ public function __construct($msg = '', $code = 0, Exception $previous = null)
49
+ {
50
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
51
+ parent::__construct($msg, (int) $code);
52
+ $this->_previous = $previous;
53
+ } else {
54
+ parent::__construct($msg, (int) $code, $previous);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Overloading
60
+ *
61
+ * For PHP < 5.3.0, provides access to the getPrevious() method.
62
+ *
63
+ * @param string $method
64
+ * @param array $args
65
+ * @return mixed
66
+ */
67
+ public function __call($method, array $args)
68
+ {
69
+ if ('getprevious' == strtolower($method)) {
70
+ return $this->_getPrevious();
71
+ }
72
+ return null;
73
+ }
74
+
75
+ /**
76
+ * String representation of the exception
77
+ *
78
+ * @return string
79
+ */
80
+ public function __toString()
81
+ {
82
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
83
+ if (null !== ($e = $this->getPrevious())) {
84
+ return $e->__toString()
85
+ . "\n\nNext "
86
+ . parent::__toString();
87
+ }
88
+ }
89
+ return parent::__toString();
90
+ }
91
+
92
+ /**
93
+ * Returns previous Exception
94
+ *
95
+ * @return Exception|null
96
+ */
97
+ protected function _getPrevious()
98
+ {
99
+ return $this->_previous;
100
+ }
101
+ }
license.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (C) <2013> Vasyl Martyniuk <support@wpaam.com>
2
+
3
+ This program is free software: you can redistribute it and/or modify
4
+ it under the terms of the GNU General Public License as published by
5
+ the Free Software Foundation, either version 3 of the License, or
6
+ (at your option) any later version.
7
+
8
+ This program is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ GNU General Public License for more details.
12
+
13
+ You should have received a copy of the GNU General Public License
14
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
media/css/aam.css ADDED
@@ -0,0 +1,1411 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * ======================================================================
3
+ * LICENSE: This file is subject to the terms and conditions defined in *
4
+ * file 'license.txt', which is part of this source code package. *
5
+ * ======================================================================
6
+ */
7
+
8
+ #aam{
9
+ font-family: "Trebuchet MS", Helvetica, sans-serif;
10
+ }
11
+
12
+ .alpha-notice{
13
+ margin: 15px 10px;
14
+ border: 1px solid #FF8888;
15
+ border-radius: 4px;
16
+ padding: 4px;
17
+ text-align: center;
18
+ font-weight: bold;
19
+ font-size: 1.1em;
20
+ }
21
+
22
+ /** GLOBAL AAM STYLES */
23
+ #aam_form{
24
+ position: relative;
25
+ }
26
+
27
+ .aam-hidden{
28
+ display: none;
29
+ }
30
+
31
+ .aam-dialog{
32
+ display: none;
33
+ }
34
+
35
+ .aam-asterix{
36
+ display: inline-block;
37
+ font-size: 0.9em;
38
+ color: #bf0909;
39
+ margin-left: 3px;
40
+ }
41
+
42
+ .aam-form-table{
43
+ width: 100%;
44
+ }
45
+
46
+ .aam-form-table th{
47
+ text-align: right;
48
+ }
49
+
50
+ .aam-form-table input, .aam-form-table select{
51
+ width: 100%;
52
+ }
53
+
54
+ .dialog-content{
55
+ text-align: center;
56
+ }
57
+
58
+ .dialog-note{
59
+ font-size: 0.8em;
60
+ margin-bottom: 0;
61
+ }
62
+
63
+ .dialog-input{
64
+ width: 55%;
65
+ margin-left: 5%;
66
+ }
67
+
68
+ .aam-input{
69
+ width: 100%;
70
+ }
71
+
72
+ .dialog-input-dynamic{
73
+ width: 55%;
74
+ margin-left: 5%;
75
+ background: transparent url('images/cmanager/field-loader.gif') no-repeat center;
76
+ }
77
+
78
+ .dialog-fieldset{
79
+ width: 100%;
80
+ margin: 10px 0px;
81
+ }
82
+
83
+ .aam-help{
84
+ width: 100%;
85
+ border: 1px solid #CCCCCC;
86
+ border-radius: 5px;
87
+ background: transparent url('images/help.png') no-repeat 10px center;
88
+ height: 40px;
89
+ padding: 5px 0;
90
+ margin-bottom: 10px;
91
+ display: table;
92
+ }
93
+
94
+ .aam-help span{
95
+ display: none;
96
+ vertical-align: middle;
97
+ font-family: 'Lucida Console', Monaco, monospace;
98
+ text-align: justify;
99
+ padding: 0 20px 0 50px;
100
+ }
101
+
102
+ .wrap a{
103
+ outline: 0;
104
+ }
105
+
106
+ .aam-tooltip {
107
+ display:none;
108
+ position:absolute;
109
+ border:1px solid #CCCCCC;
110
+ background-color: #F5F5F5;
111
+ border-radius: 4px;
112
+ box-shadow: 0 0 5px #AAAAAA;
113
+ padding: 5px 10px;
114
+ z-index: 9999;
115
+ color: #333333;
116
+ font-size: 1em;
117
+ max-width: 300px;
118
+ left:0px;
119
+ top: 0px;
120
+ font-weight: bold;
121
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
122
+ }
123
+
124
+
125
+ .clear{
126
+ line-height: 0;
127
+ font-size: 0;
128
+ padding: 0;
129
+ margin: 0;
130
+ clear: both;
131
+ }
132
+
133
+ .main-inside{
134
+ position: relative;
135
+ min-height: 200px;
136
+ }
137
+
138
+ .aam-main-loader{
139
+ position: absolute;
140
+ top: 0px;
141
+ left: 0px;
142
+ width: 100%;
143
+ height: 100%;
144
+ background: transparent url('images/main-loader.gif') no-repeat center;
145
+ }
146
+
147
+ .aam-metabox-loader{
148
+ display: none;
149
+ position: absolute;
150
+ top: 0px;
151
+ left: 0px;
152
+ width: 100%;
153
+ height: 100%;
154
+ background: transparent url('images/metabox-loader.gif') no-repeat center;
155
+ }
156
+
157
+ .aam-bold{
158
+ font-weight: bold;
159
+ }
160
+
161
+ .current-site{
162
+ text-transform: capitalize;
163
+ font-weight: bold;
164
+ color: #257DA6;
165
+ margin-right: 4px;
166
+ }
167
+
168
+
169
+ .current-subject{
170
+ text-transform: capitalize;
171
+ font-weight: bold;
172
+ color: #bf0909;
173
+ }
174
+
175
+ /** FEATURE LIST STYLES */
176
+ .feature-list{
177
+ width: 25%;
178
+ float: left;
179
+ }
180
+
181
+ .feature-item{
182
+ height: 28px;
183
+ width: 100%;
184
+ display: table;
185
+ font-size: 1em;
186
+ border: 1px solid #CCCCCC;
187
+ font-family: "Lucida Console", Monaco, monospace;
188
+ cursor: pointer;
189
+ background: transparent url('images/feature.png') no-repeat 2px 2px;
190
+ }
191
+
192
+ .feature-item:hover{
193
+ border: 1px solid #006400;
194
+ }
195
+
196
+ .feature-item-active{
197
+ border: 1px solid #257DA6;
198
+ background: #257DA6 url('images/feature-active.png') no-repeat 2px 2px;
199
+ }
200
+
201
+ .feature-item span{
202
+ text-transform: uppercase;
203
+ display: table-cell;
204
+ padding-left: 38px;
205
+ vertical-align: middle;
206
+ }
207
+
208
+ .feature-item-active span{
209
+ font-weight: bold;
210
+ color: #FFFFFF;
211
+ }
212
+
213
+ .feature-content{
214
+ float: right;
215
+ width: 72%;
216
+ border-radius: 4px;
217
+ border: 1px solid #CCCCCC;
218
+ padding: 5px;
219
+ }
220
+
221
+ .feature-content-container{
222
+ position: relative;
223
+ }
224
+
225
+ /** CONTROL PANEL STYLES */
226
+ .cpanel-major{
227
+ display: table;
228
+ width: 100%;
229
+ margin-bottom: 5px;
230
+ padding-bottom: 5px;
231
+ border-bottom: 1px solid #CCCCCC;
232
+ }
233
+
234
+ .cpanel-major .cpanel-item{
235
+ height: 64px;
236
+ width: 50%;
237
+ display: table-cell;
238
+ text-align: center;
239
+ vertical-align: bottom;
240
+ text-decoration: none;
241
+ text-transform: uppercase;
242
+ font-size: 10px;
243
+ font-weight: bold;
244
+ color: #333333;
245
+ background-repeat: no-repeat;
246
+ background-position: center top;
247
+ }
248
+
249
+ .cpanel-minor{
250
+ display: table;
251
+ width: 100%;
252
+ margin-top: 10px;
253
+ }
254
+
255
+ .cpanel-minor .cpanel-item{
256
+ height: 40px;
257
+ width: 25%;
258
+ display: table-cell;
259
+ text-align: center;
260
+ vertical-align: bottom;
261
+ text-decoration: none;
262
+ text-transform: uppercase;
263
+ font-size: 9px;
264
+ font-weight: bold;
265
+ color: #333333;
266
+ background-repeat: no-repeat;
267
+ background-position: center top;
268
+ }
269
+
270
+ .cpanel-item-restore{
271
+ background-image: url('images/cpanel/restore.png');
272
+ }
273
+
274
+ .cpanel-item-restore:hover{
275
+ background-image: url('images/cpanel/restore-active.png');
276
+ }
277
+
278
+ .cpanel-item-save{
279
+ background-image: url('images/cpanel/save.png');
280
+ }
281
+
282
+ .cpanel-item-save:hover{
283
+ background-image: url('images/cpanel/save-active.png');
284
+ }
285
+
286
+ .cpanel-item-help{
287
+ background-image: url('images/cpanel/help-forum.png');
288
+ }
289
+
290
+ .cpanel-item-help:hover{
291
+ background-image: url('images/cpanel/help-forum-active.png');
292
+ }
293
+
294
+ .cpanel-item-twitter{
295
+ background-image: url('images/cpanel/twitter.png');
296
+ }
297
+
298
+ .cpanel-item-twitter:hover{
299
+ background-image: url('images/cpanel/twitter-active.png');
300
+ }
301
+
302
+ .cpanel-item-message{
303
+ background-image: url('images/cpanel/message.png');
304
+ }
305
+
306
+ .cpanel-item-message:hover{
307
+ background-image: url('images/cpanel/message-active.png');
308
+ }
309
+
310
+ .cpanel-item-star{
311
+ background-image: url('images/cpanel/star.png');
312
+ }
313
+
314
+ .cpanel-item-star:hover{
315
+ background-image: url('images/cpanel/star-active.png');
316
+ }
317
+
318
+ #major-publishing-actions{
319
+ margin-top: 5px;
320
+ border-top: 1px solid #D5D5D5;
321
+ }
322
+
323
+ /** CONTROL MANAGER STYLES */
324
+ .control-manager{
325
+ display: table;
326
+ width: 100%;
327
+ margin-bottom: 5px;
328
+ }
329
+
330
+ .manager-item{
331
+ height: 50px;
332
+ min-width: 32px;
333
+ display: table-cell;
334
+ text-align: center;
335
+ vertical-align: bottom;
336
+ text-decoration: none;
337
+ text-transform: uppercase;
338
+ font-size: 10px;
339
+ font-weight: bold;
340
+ color: #333333;
341
+ background-repeat: no-repeat;
342
+ background-position: center top;
343
+ }
344
+
345
+ .control-manager-content{
346
+ border-top: 1px solid #F5F5F5;
347
+ }
348
+
349
+ /**
350
+ ================
351
+ ALL OTHER STYLES
352
+ ================
353
+ */
354
+
355
+ /** ROLE MANAGER STYLES */
356
+ .manager-item-role{
357
+ background-image: url('images/cmanager/role.png');
358
+ }
359
+
360
+ .manager-item-role-active{
361
+ background-image: url('images/cmanager/role-active.png');
362
+ }
363
+
364
+ .role-top-actions{
365
+ float: right;
366
+ display: inline-table;
367
+ width: auto;
368
+ text-align: right;
369
+ }
370
+
371
+ .role-top-action{
372
+ width: 24px;
373
+ height: 24px;
374
+ display: table-cell;
375
+ text-indent: -9999px;
376
+ padding-right: 10px;
377
+ background-repeat: no-repeat;
378
+ background-position: center;
379
+ }
380
+
381
+ .role-top-action-add{
382
+ background-image: url('images/cmanager/add.png');
383
+ }
384
+
385
+ .role-top-action-add:hover{
386
+ background-image: url('images/cmanager/add-active.png');
387
+ }
388
+
389
+ .role-top-action-add-active{
390
+ background-image: url('images/cmanager/add-active.png');
391
+ }
392
+
393
+ .role-actions{
394
+ width: 100%;
395
+ display: table;
396
+ }
397
+
398
+ .role-action{
399
+ width: 16px;
400
+ height: 16px;
401
+ display: table-cell;
402
+ text-indent: -9999px;
403
+ background-repeat: no-repeat;
404
+ background-position: center;
405
+ }
406
+
407
+ .role-action-edit{
408
+ background-image: url('images/cmanager/edit.png');
409
+ }
410
+
411
+ .role-action-edit:hover{
412
+ background-image: url('images/cmanager/edit-active.png');
413
+ }
414
+
415
+ .role-action-edit-active{
416
+ background-image: url('images/cmanager/edit-active.png');
417
+ }
418
+
419
+ .role-action-delete{
420
+ background-image: url('images/cmanager/delete.png');
421
+ }
422
+
423
+ .role-action-delete-active{
424
+ background-image: url('images/cmanager/delete-active.png');
425
+ }
426
+
427
+ .role-action-delete:hover{
428
+ background-image: url('images/cmanager/delete-active.png');
429
+ }
430
+
431
+ .role-action-manage{
432
+ background-image: url('images/cmanager/settings.png');
433
+ }
434
+
435
+ .role-action-manage-active{
436
+ background-image: url('images/cmanager/settings-active.png');
437
+ }
438
+
439
+ .role-action-manage:hover{
440
+ background-image: url('images/cmanager/settings-active.png');
441
+ }
442
+
443
+ /** USER MANAGER STYLES */
444
+ .manager-item-user{
445
+ background-image: url('images/cmanager/user.png');
446
+ }
447
+
448
+ .manager-item-user-active{
449
+ background-image: url('images/cmanager/user-active.png');
450
+ }
451
+
452
+ .user-top-actions{
453
+ float: right;
454
+ display: inline-table;
455
+ width: auto;
456
+ text-align: right;
457
+ }
458
+
459
+ .user-top-action{
460
+ width: 24px;
461
+ height: 24px;
462
+ display: table-cell;
463
+ text-indent: -9999px;
464
+ padding-right: 10px;
465
+ background-repeat: no-repeat;
466
+ background-position: center;
467
+ }
468
+
469
+ .user-top-action-add{
470
+ background-image: url('images/cmanager/add.png');
471
+ }
472
+
473
+ .user-top-action-add:hover{
474
+ background-image: url('images/cmanager/add-active.png');
475
+ }
476
+
477
+ .user-top-action-filter{
478
+ background-image: url('images/cmanager/filter.png');
479
+ }
480
+
481
+ .user-top-action-filter:hover{
482
+ background-image: url('images/cmanager/filter-active.png');
483
+ }
484
+
485
+ .user-top-action-filter-active{
486
+ background-image: url('images/cmanager/filter-active.png');
487
+ }
488
+
489
+ .user-top-action-refresh{
490
+ background-image: url('images/cmanager/refresh.png');
491
+ }
492
+
493
+ .user-top-action-refresh:hover{
494
+ background-image: url('images/cmanager/refresh-active.png');
495
+ }
496
+
497
+ .user-actions{
498
+ width: 100%;
499
+ display: table;
500
+ }
501
+
502
+ .user-action{
503
+ width: 16px;
504
+ height: 16px;
505
+ display: table-cell;
506
+ text-indent: -9999px;
507
+ background-repeat: no-repeat;
508
+ background-position: center;
509
+ }
510
+
511
+ .user-action-edit{
512
+ background-image: url('images/cmanager/edit-user.png');
513
+ }
514
+
515
+ .user-action-edit-active{
516
+ background-image: url('images/cmanager/edit-user-active.png');
517
+ }
518
+
519
+ .user-action-edit:hover{
520
+ background-image: url('images/cmanager/edit-user-active.png');
521
+ }
522
+
523
+ .user-action-block{
524
+ background-image: url('images/cmanager/block-user.png');
525
+ }
526
+
527
+ .user-action-block-active{
528
+ background-image: url('images/cmanager/block-user-active.png');
529
+ }
530
+
531
+ .user-action-block:hover{
532
+ background-image: url('images/cmanager/block-user-active.png');
533
+ }
534
+
535
+ .user-action-delete{
536
+ background-image: url('images/cmanager/delete.png');
537
+ }
538
+
539
+ .user-action-delete-active{
540
+ background-image: url('images/cmanager/delete-active.png');
541
+ }
542
+
543
+ .user-action-delete:hover{
544
+ background-image: url('images/cmanager/delete-active.png');
545
+ }
546
+
547
+ .user-action-manage{
548
+ background-image: url('images/cmanager/settings.png');
549
+ }
550
+
551
+ .user-action-manage-active{
552
+ background-image: url('images/cmanager/settings-active.png');
553
+ }
554
+
555
+ .user-action-manage:hover{
556
+ background-image: url('images/cmanager/settings-active.png');
557
+ }
558
+
559
+ .user-action-select{
560
+ background-image: url('images/cmanager/select.png');
561
+ }
562
+
563
+ .user-action-select:hover{
564
+ background-image: url('images/cmanager/select-active.png');
565
+ }
566
+
567
+ .user-settings{
568
+ border: 1px solid #E2E4FF;
569
+ width: 100%;
570
+ }
571
+
572
+ .user-settings td {
573
+ border-bottom: 1px solid #CCCCCC;
574
+ }
575
+
576
+ .user-settings th {
577
+ padding: 2px 10px;
578
+ border-bottom: 1px solid #CCCCCC;
579
+ font-weight: bold;
580
+ text-transform: uppercase;
581
+ cursor: pointer;
582
+ text-align: right;
583
+ background-color: #257da6;
584
+ }
585
+
586
+ .user-settings input, .user-settings select{
587
+ width: 100%;
588
+ border: 0px solid transparent;
589
+ }
590
+
591
+
592
+ /** VISITOR MANAGER STYLES */
593
+ .manager-item-visitor{
594
+ background-image: url('images/cmanager/visitor.png');
595
+ }
596
+
597
+ .manager-item-visitor-active{
598
+ background-image: url('images/cmanager/visitor-active.png');
599
+ }
600
+
601
+ .control-manager-visitor{
602
+ margin-top: 10px;
603
+ width: auto;
604
+ border-top: 4px solid #257DA6;
605
+ border-bottom: 1px solid #CCCCCC;
606
+ border-left: 1px solid #CCCCCC;
607
+ border-right: 1px solid #CCCCCC;
608
+ text-align: justify;
609
+ padding: 10px;
610
+ font-family: 'Lucida Console', Monaco, monospace;
611
+ }
612
+
613
+
614
+ /** ADMIN MENU STYLES */
615
+ .menu-top-actions{
616
+ padding: 2px 0;
617
+ width: 100%;
618
+ margin-bottom: 10px;
619
+ text-align: right;
620
+ position: relative;
621
+ }
622
+
623
+ .menu-top-action-item{
624
+ width:24px;
625
+ height: 24px;
626
+ display: inline-block;
627
+ background-repeat: no-repeat;
628
+ background-position: center;
629
+ text-indent: -9999px;
630
+ text-decoration: none;
631
+ }
632
+
633
+ .menu-top-action-sort-description{
634
+ border: 1px solid #257DA6;
635
+ height: 24px;
636
+ position: absolute;
637
+ left: 0px;
638
+ width: 80%;
639
+ text-align: left;
640
+ padding-left: 10px;
641
+ vertical-align: middle;
642
+ display: inline-table;
643
+ border-radius: 4px;
644
+ font-family: 'Lucida Console', Monaco, monospace;
645
+ visibility: hidden;
646
+ font-weight: bold;
647
+ }
648
+
649
+ .menu-top-action-sort-description span{
650
+ display: table-cell;
651
+ vertical-align: middle;
652
+ }
653
+
654
+ .menu-top-action-sort{
655
+ background-image: url('images/menu/sorting.png');
656
+ }
657
+
658
+ .menu-top-action-sort-active{
659
+ background-image: url('images/menu/sorting-active.png');
660
+ }
661
+
662
+ .menu-item-action{
663
+ background-repeat: no-repeat;
664
+ background-position: center;
665
+ width: 26px;
666
+ height: 26px;
667
+ display: block;
668
+ margin: -10px auto 4px auto;
669
+ text-indent: -9999px;
670
+ text-decoration: none;
671
+ }
672
+
673
+ .menu-item-action-restrict{
674
+ background-image:url(images/menu/visibility.png);
675
+ }
676
+
677
+ .menu-item-action-restrict-active{
678
+ background-image:url(images/menu/visibility-active.png);
679
+ }
680
+
681
+ .whole-menu{
682
+ width: 50%;
683
+ background-color: #F9F9F9;
684
+ border-radius: 5px;
685
+ text-align: center;
686
+ font-family: 'Lucida Console', Monaco, monospace;
687
+ vertical-align: top;
688
+ margin: 0px auto 5px auto;
689
+ padding: 0px 10px;
690
+ }
691
+
692
+ .whole-menu label{
693
+ display: inline-block;
694
+ line-height: 25px;
695
+ height: 23px;
696
+ }
697
+
698
+ .menu-submenu-list{
699
+ border: 1px solid #CCCCCC;
700
+ border-radius: 5px;
701
+ padding: 12px 5px 5px;
702
+ background-color: #F9F9F9;
703
+ width: 95%;
704
+ margin: auto;
705
+ display: table;
706
+ }
707
+
708
+ .menu-submenu-row{
709
+ display: table-row;
710
+ }
711
+
712
+ .menu-submenu-item{
713
+ text-align: right;
714
+ padding-right: 10px;
715
+ font-family: 'Lucida Console', Monaco, monospace;
716
+ vertical-align: top;
717
+ display: table-cell;
718
+ }
719
+
720
+ .menu-submenu-item label{
721
+ display: inline-block;
722
+ line-height: 25px;
723
+ height: 29px;
724
+ font-size: 0.8em;
725
+ }
726
+
727
+ #main_menu_list input[type="checkbox"] {
728
+ display:none;
729
+ }
730
+
731
+ #main_menu_list input[type="checkbox"] + label span {
732
+ display:inline-block;
733
+ width:16px;
734
+ height:16px;
735
+ background:url(images/menu/unchecked.png) no-repeat center;
736
+ cursor:pointer;
737
+ margin-top: 4px;
738
+ }
739
+
740
+ #main_menu_list input[type="checkbox"]:checked + label span {
741
+ background:url(images/menu/checked.png) no-repeat center;
742
+ }
743
+
744
+ .menu-empty-list{
745
+ border: 1px solid #bf0909;
746
+ border-radius: 4px;
747
+ padding: 8px 10px;
748
+ text-align: center;
749
+ font-weight: bold;
750
+ font-size: 1em;
751
+ background-color: #E2E4FF;
752
+ }
753
+
754
+ /** METABOX & WIDGETS STYLES */
755
+ .metabox-top-actions{
756
+ padding: 2px 0;
757
+ width: 100%;
758
+ margin-bottom: 10px;
759
+ }
760
+
761
+ .metabox-top-action-link{
762
+ width: 75%;
763
+ float: left;
764
+ }
765
+
766
+ .metabox-top-action-link input{
767
+ height: 24px;
768
+ width: 100%;
769
+ background-repeat: no-repeat;
770
+ background-position: 5px center;
771
+ background-image: url('images/metabox/link.png');
772
+ padding-left: 24px;
773
+ }
774
+
775
+ .metabox-top-action-link input:focus{
776
+ background-image: url('images/metabox/link-active.png');
777
+ }
778
+
779
+ .metabox-top-action{
780
+ width:24px;
781
+ height: 24px;
782
+ display: block;
783
+ background-repeat: no-repeat;
784
+ background-position: center;
785
+ text-indent: -9999px;
786
+ text-decoration: none;
787
+ }
788
+
789
+ .metabox-top-action-add{
790
+ background-image: url('images/metabox/add.png');
791
+ float: left;
792
+ margin-left: 10px;
793
+ }
794
+
795
+ .metabox-top-action-add:hover{
796
+ background-image: url('images/metabox/add-active.png');
797
+ }
798
+
799
+ .metabox-top-action-add-active{
800
+ background-image: url('images/metabox/add-active.png');
801
+ float: left;
802
+ margin-left: 10px;
803
+ }
804
+
805
+ .metabox-top-action-refresh{
806
+ background-position: right center;
807
+ background-image: url('images/metabox/refresh.png');
808
+ float: right;
809
+ }
810
+
811
+ .metabox-top-action-refresh:hover{
812
+ background-position: right center;
813
+ background-image: url('images/metabox/refresh-active.png');
814
+ }
815
+
816
+ .metabox-group{
817
+ border: 1px solid #CCCCCC;
818
+ border-radius: 5px;
819
+ padding: 12px 5px 5px;
820
+ background-color: #F9F9F9;
821
+ width: 95%;
822
+ margin: auto;
823
+ display: table;
824
+ }
825
+
826
+ .metabox-row{
827
+ display: table-row;
828
+ }
829
+
830
+ .metabox-item{
831
+ text-align: right;
832
+ font-family: 'Lucida Console', Monaco, monospace;
833
+ vertical-align: top;
834
+ display: table-cell;
835
+ }
836
+
837
+ .metabox-item label{
838
+ display: inline-block;
839
+ line-height: 25px;
840
+ height: 29px;
841
+ font-size: 0.8em;
842
+ }
843
+
844
+ .metabox-item input[type="checkbox"] {
845
+ display:none;
846
+ }
847
+
848
+ .metabox-item input[type="checkbox"] + label span {
849
+ display:inline-block;
850
+ width:16px;
851
+ height:16px;
852
+ background:url(images/metabox/unchecked.png) no-repeat center;
853
+ cursor:pointer;
854
+ margin-top: 4px;
855
+ margin-left: 6px;
856
+ }
857
+
858
+ .metabox-item input[type="checkbox"]:checked + label span {
859
+ background:url(images/metabox/checked.png) no-repeat center;
860
+ }
861
+
862
+ #metabox_content{
863
+ min-height: 200px;
864
+ }
865
+
866
+ /** CAPABILITIES STYLES */
867
+ .capability-top-actions{
868
+ float: right;
869
+ display: inline-table;
870
+ width: auto;
871
+ text-align: right;
872
+ }
873
+
874
+ .capability-top-action{
875
+ width: 24px;
876
+ height: 24px;
877
+ display: table-cell;
878
+ text-indent: -9999px;
879
+ padding-right: 10px;
880
+ background-repeat: no-repeat;
881
+ background-position: center;
882
+ }
883
+
884
+ .capability-top-action-add{
885
+ background-image: url('images/capability/add.png');
886
+ }
887
+
888
+ .capability-top-action-add:hover{
889
+ background-image: url('images/capability/add-active.png');
890
+ }
891
+
892
+ .capability-top-action-add-active{
893
+ background-image: url('images/capability/add-active.png');
894
+ }
895
+
896
+ .capability-top-action-copy{
897
+ background-image: url('images/capability/copy.png');
898
+ }
899
+
900
+ .capability-top-action-copy:hover{
901
+ background-image: url('images/capability/copy-active.png');
902
+ }
903
+
904
+ .capability-top-action-copy-active{
905
+ background-image: url('images/capability/copy-active.png');
906
+ }
907
+
908
+ .capability-top-action-filter{
909
+ background-image: url('images/capability/filter.png');
910
+ }
911
+
912
+ .capability-top-action-filter:hover{
913
+ background-image: url('images/capability/filter-active.png');
914
+ }
915
+
916
+ .capability-top-action-filter-active{
917
+ background-image: url('images/capability/filter-active.png');
918
+ }
919
+
920
+ .capability-top-action-restore{
921
+ background-image: url('images/capability/restore.png');
922
+ }
923
+
924
+ .capability-top-action-restore:hover{
925
+ background-image: url('images/capability/restore-active.png');
926
+ }
927
+
928
+ .capability-top-action-restore-running{
929
+ background-image: url('images/capability/ajax-loader.gif');
930
+ }
931
+
932
+ .capability-actions{
933
+ display: table;
934
+ width: 100%;
935
+ }
936
+
937
+ .capability-action{
938
+ width: 16px;
939
+ height: 16px;
940
+ display: table-cell;
941
+ text-align: center;
942
+ vertical-align: middle;
943
+ text-decoration: none;
944
+ outline: 0;
945
+ }
946
+
947
+ a.capability-action{
948
+ outline: 0;
949
+ }
950
+
951
+ .capability-action input[type="checkbox"] {
952
+ display:none;
953
+ }
954
+
955
+ .capability-action input[type="checkbox"] + label span {
956
+ display:inline-block;
957
+ width:16px;
958
+ height:16px;
959
+ background:url(images/capability/unchecked.png) no-repeat center;
960
+ cursor:pointer;
961
+ margin-top: 4px;
962
+ }
963
+
964
+ .capability-action input[type="checkbox"]:checked + label span {
965
+ background:url(images/capability/checked.png) no-repeat center;
966
+ }
967
+
968
+ .capability-action-delete{
969
+ background: transparent url('images/capability/delete.png') no-repeat center;
970
+ }
971
+
972
+ .capability-action-delete:hover{
973
+ background: transparent url('images/capability/delete-active.png') no-repeat center;
974
+ }
975
+
976
+ .capability-action-delete-active{
977
+ background: transparent url('images/capability/delete-active.png') no-repeat center;
978
+ }
979
+
980
+ .capability-action-select{
981
+ background: transparent url('images/capability/select.png') no-repeat center;
982
+ }
983
+ .capability-action-select:hover{
984
+ background: transparent url('images/capability/select-active.png') no-repeat center;
985
+ }
986
+
987
+
988
+ .capability-action-select-active{
989
+ background: transparent url('images/capability/select-active.png') no-repeat center;
990
+ }
991
+
992
+ /** POSTS & CATEGORIES STYLES */
993
+ .post-top-actions{
994
+ float: right;
995
+ display: inline-table;
996
+ width: auto;
997
+ text-align: right;
998
+ }
999
+
1000
+ .post-top-action{
1001
+ width: 24px;
1002
+ height: 24px;
1003
+ display: table-cell;
1004
+ text-indent: -9999px;
1005
+ padding-right: 10px;
1006
+ background-repeat: no-repeat;
1007
+ background-position: center;
1008
+ }
1009
+
1010
+ .post-top-action-filter{
1011
+ background-image: url('images/post/filter.png');
1012
+ }
1013
+
1014
+ .post-top-action-filter:hover{
1015
+ background-image: url('images/post/filter-active.png');
1016
+ }
1017
+
1018
+ .post-top-action-filter-active{
1019
+ background-image: url('images/post/filter-active.png');
1020
+ }
1021
+
1022
+ .post-top-action-refresh{
1023
+ background-image: url('images/post/refresh.png');
1024
+ }
1025
+
1026
+ .post-top-action-refresh:hover{
1027
+ background-image: url('images/post/refresh-active.png');
1028
+ }
1029
+
1030
+ .post-type-post{
1031
+ height: 16px;
1032
+ background: transparent url('images/post/post.png') no-repeat left center;
1033
+ display: inline-block;
1034
+ padding-left: 20px;
1035
+ text-decoration: none;
1036
+ }
1037
+
1038
+ .post-actions{
1039
+ display: table;
1040
+ width: 100%;
1041
+ }
1042
+
1043
+ .post-action{
1044
+ width: 16px;
1045
+ height: 16px;
1046
+ display: table-cell;
1047
+ cursor: pointer;
1048
+ padding: 2px 0;
1049
+ background-repeat: no-repeat;
1050
+ background-position: center;
1051
+ text-align: center;
1052
+ }
1053
+
1054
+ .post-action-manage{
1055
+ background-image: url('images/post/settings.png');
1056
+ }
1057
+
1058
+ .post-action-manage:hover{
1059
+ background-image: url('images/post/settings-active.png');
1060
+ }
1061
+
1062
+ .post-action-manage-active{
1063
+ background-image: url('images/post/settings-active.png');
1064
+ }
1065
+
1066
+ .post-action-edit{
1067
+ background-image: url('images/post/edit.png');
1068
+ }
1069
+
1070
+ .post-action-edit:hover{
1071
+ background-image: url('images/post/edit-active.png');
1072
+ }
1073
+
1074
+ .post-action-edit-active{
1075
+ background-image: url('images/post/edit-active.png');
1076
+ }
1077
+
1078
+ .post-action-lock{
1079
+ background-image: url('images/lock.png');
1080
+ }
1081
+
1082
+ .post-action input[type="checkbox"] {
1083
+ display:none;
1084
+ }
1085
+
1086
+ .post-action input[type="checkbox"] + label span {
1087
+ display:inline-block;
1088
+ width:16px;
1089
+ height:16px;
1090
+ background:url(images/post/unchecked.png) no-repeat center;
1091
+ cursor:pointer;
1092
+ margin-top: 4px;
1093
+ }
1094
+
1095
+ .post-action input[type="checkbox"]:checked + label span {
1096
+ background:url(images/post/checked.png) no-repeat center;
1097
+ }
1098
+
1099
+ .post-access-area{
1100
+ margin: 5px 0;
1101
+ text-align: center;
1102
+ }
1103
+
1104
+ .post-access-area .ui-button-text-only .ui-button-text{
1105
+ padding: 0.1em 1em;
1106
+ }
1107
+
1108
+ .post-category-subposts .ui-button-text-only .ui-button-text{
1109
+ padding: 0.1em 1em;
1110
+ }
1111
+
1112
+ .post-access{
1113
+ display: inline-block;
1114
+ font-size: 14px;
1115
+ font-weight: bold;
1116
+ padding: 2px 0 4px 5px;
1117
+ text-transform: uppercase;
1118
+ }
1119
+
1120
+ .post-access-inherited{
1121
+ border: 1px solid #CCCCCC;
1122
+ border-radius: 3px;
1123
+ color: #FF0000;
1124
+ margin: 5px 0 10px;
1125
+ padding: 2px;
1126
+ text-align: center;
1127
+ display: none;
1128
+ }
1129
+
1130
+ .post-breadcrumb{
1131
+ margin-top: 4px;
1132
+ border: 1px solid #CCCCCC;
1133
+ width: 100%;
1134
+ padding: 4px 0px;
1135
+ font-family: 'Lucida Console', Monaco, monospace;
1136
+ }
1137
+
1138
+ .post-breadcrumb-loading{
1139
+ background: transparent url('images/post/loader.gif') no-repeat center;
1140
+ }
1141
+
1142
+ .post-breadcrumb-line{
1143
+ width: 88%;
1144
+ display: inline-block;
1145
+ vertical-align: middle;
1146
+ }
1147
+
1148
+ .post-breadcrumb-line a{
1149
+ text-decoration: none;
1150
+ font-weight: bold;
1151
+ color: #257DA6;
1152
+ margin-left: 5px;
1153
+ }
1154
+
1155
+ .aam-gt{
1156
+ display: inline-block;
1157
+ margin: 0 2px;
1158
+ }
1159
+
1160
+ .post-breadcrumb-line-actions{
1161
+ width: 10%;
1162
+ display:inline-table;
1163
+ border-left: 1px solid #CCCCCC;
1164
+ vertical-align: middle;
1165
+ }
1166
+
1167
+ .post-breadcrumb-line-action{
1168
+ display: table-cell;
1169
+ width: 16px;
1170
+ height: 16px;
1171
+ background-position: center;
1172
+ background-repeat: no-repeat;
1173
+ }
1174
+
1175
+ .post-breadcrumb-line-action-edit{
1176
+ background-image: url('images/post/edit.png');
1177
+ }
1178
+
1179
+ .post-breadcrumb-line-action-edit:hover{
1180
+ background-image: url('images/post/edit-active.png');
1181
+ }
1182
+
1183
+ .post-breadcrumb-line-action-manage{
1184
+ background-image: url('images/post/settings.png');
1185
+ }
1186
+
1187
+ .post-breadcrumb-line-action-manage:hover{
1188
+ background-image: url('images/post/settings-active.png');
1189
+ }
1190
+
1191
+ .post-breadcrumb-line-action-manage-active{
1192
+ background-image: url('images/post/settings-active.png');
1193
+ }
1194
+
1195
+ .post-breadcrumb-line-action-lock{
1196
+ background-image: url('images/lock.png');
1197
+ }
1198
+
1199
+ #access_dialog{
1200
+ position: relative;
1201
+ }
1202
+
1203
+ .aam-lock-message{
1204
+ margin: 5px 0 10px 0;
1205
+ border: 1px solid #bf0909;
1206
+ border-radius: 4px;
1207
+ background: transparent url('images/lock.png') no-repeat 5px center;
1208
+ display: table;
1209
+ width: 100%;
1210
+ }
1211
+
1212
+ .aam-lock-message span{
1213
+ font-weight: bold;
1214
+ vertical-align: middle;
1215
+ display: table-cell;
1216
+ padding: 5px 2px 5px 28px;
1217
+ }
1218
+
1219
+ .aam-lock-message a{
1220
+ color: #257DA6;
1221
+ outline: 0;
1222
+ }
1223
+
1224
+ .ui-menu {
1225
+ width: 150px;
1226
+ z-index: 9999;
1227
+ }
1228
+
1229
+ .post-term-descend{
1230
+ margin: 5px 0;
1231
+ text-align: left;
1232
+ display: table;
1233
+ vertical-align: middle;
1234
+ }
1235
+
1236
+ .post-term-descend label{
1237
+ display: table-cell;
1238
+ }
1239
+
1240
+ .post-term-descend input[type="checkbox"] {
1241
+ display:none;
1242
+ }
1243
+
1244
+ .post-term-descend input[type="checkbox"] + label span {
1245
+ display:inline-block;
1246
+ width:16px;
1247
+ height:16px;
1248
+ background:url(images/capability/unchecked.png) no-repeat center;
1249
+ cursor:pointer;
1250
+ margin-top: 4px;
1251
+ margin-left: 8px;
1252
+ }
1253
+
1254
+ .post-term-descend input[type="checkbox"]:checked + label span {
1255
+ background:url(images/capability/checked.png) no-repeat center;
1256
+ }
1257
+
1258
+ #access_dialog table.dataTable td{
1259
+ padding: 0px 10px;
1260
+ }
1261
+
1262
+ .dataTable th.term-access-title, .dataTable th.post-access-title{
1263
+ background-color: #CCCCCC;
1264
+ }
1265
+
1266
+ .post-access-list{
1267
+ position: relative;
1268
+ }
1269
+
1270
+ .post-access-list .post-access-block{
1271
+ position: absolute;
1272
+ top: 0;
1273
+ left: 0;
1274
+ width: 100%;
1275
+ height: 100%;
1276
+ background-color: #F5F5F5;
1277
+ opacity: 0.8;
1278
+ }
1279
+
1280
+ .aam-lock-big{
1281
+ display: table;
1282
+ width: 100%;
1283
+ height: 120px;
1284
+ background: transparent url('images/post/lock-big.png') no-repeat center;
1285
+ }
1286
+
1287
+ a.aam-lock-big{
1288
+ text-decoration: none;
1289
+ outline: 0;
1290
+ }
1291
+
1292
+ .aam-lock-big span{
1293
+ display: table-cell;
1294
+ vertical-align: bottom;
1295
+ text-align: center;
1296
+ text-transform: uppercase;
1297
+ font-size: 0.8em;
1298
+ font-weight: bold;
1299
+ }
1300
+
1301
+ .aam-post-access-notice{
1302
+ display: inline-block;
1303
+ margin-right: 2px;
1304
+ color: #257DA6;
1305
+ font-weight: bold;
1306
+ }
1307
+
1308
+ .post-access-description{
1309
+ font-size: 0.75em;
1310
+ }
1311
+
1312
+
1313
+ /** EVENT MANAGER STYLES */
1314
+ .event-top-actions{
1315
+ float: right;
1316
+ display: inline-table;
1317
+ width: auto;
1318
+ text-align: right;
1319
+ }
1320
+
1321
+ .event-top-action{
1322
+ width: 24px;
1323
+ height: 24px;
1324
+ display: table-cell;
1325
+ text-indent: -9999px;
1326
+ padding-right: 10px;
1327
+ background-repeat: no-repeat;
1328
+ background-position: center;
1329
+ }
1330
+
1331
+ .event-top-action-add{
1332
+ background-image: url('images/event/add.png');
1333
+ }
1334
+
1335
+ .event-top-action-add:hover{
1336
+ background-image: url('images/event/add-active.png');
1337
+ }
1338
+
1339
+ .event-top-action-add-active{
1340
+ background-image: url('images/event/add-active.png');
1341
+ }
1342
+
1343
+
1344
+ .event-actions{
1345
+ display: table;
1346
+ width: 100%;
1347
+ }
1348
+
1349
+ .event-action{
1350
+ width: 16px;
1351
+ height: 16px;
1352
+ display: table-cell;
1353
+ padding: 2px 0;
1354
+ background-repeat: no-repeat;
1355
+ background-position: center;
1356
+ }
1357
+
1358
+ .event-action-edit{
1359
+ background-image: url('images/event/edit.png');
1360
+ }
1361
+
1362
+ .event-action-edit:hover{
1363
+ background-image: url('images/event/edit-active.png');
1364
+ }
1365
+
1366
+ .event-action-edit-active{
1367
+ background-image: url('images/event/edit-active.png');
1368
+ }
1369
+
1370
+ .event-action-delete{
1371
+ background-image: url('images/event/delete.png');
1372
+ }
1373
+
1374
+ .event-action-delete:hover{
1375
+ background-image: url('images/event/delete-active.png');
1376
+ }
1377
+
1378
+ .event-action-delete-active{
1379
+ background-image: url('images/event/delete-active.png');
1380
+ }
1381
+
1382
+ .event-specifier{
1383
+ display:none;
1384
+ }
1385
+
1386
+ /** CONFIGPRESS STYLES **/
1387
+ .configpress-top-actions{
1388
+ padding: 2px 0;
1389
+ width: 100%;
1390
+ margin-bottom: 2px;
1391
+ text-align: right;
1392
+ position: relative;
1393
+ }
1394
+
1395
+ .configpress-top-action-item{
1396
+ width:24px;
1397
+ height: 24px;
1398
+ display: inline-block;
1399
+ background-repeat: no-repeat;
1400
+ background-position: center;
1401
+ text-indent: -9999px;
1402
+ text-decoration: none;
1403
+ }
1404
+
1405
+ .configpress-top-action-tutorial{
1406
+ background-image: url('images/configpress/pdf.png');
1407
+ }
1408
+
1409
+ .configpress-top-action-tutorial:hover{
1410
+ background-image: url('images/configpress/pdf-active.png');
1411
+ }
media/css/codemirror.css ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* BASICS */
2
+
3
+ .CodeMirror {
4
+ /* Set height, width, borders, and global font properties here */
5
+ font-family: monospace;
6
+ height: 300px;
7
+ }
8
+ .CodeMirror-scroll {
9
+ /* Set scrolling behaviour here */
10
+ overflow: auto;
11
+ }
12
+
13
+ /* PADDING */
14
+
15
+ .CodeMirror-lines {
16
+ padding: 4px 0; /* Vertical padding around content */
17
+ }
18
+ .CodeMirror pre {
19
+ padding: 0 4px; /* Horizontal padding of content */
20
+ }
21
+
22
+ .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
23
+ background-color: white; /* The little square between H and V scrollbars */
24
+ }
25
+
26
+ /* GUTTER */
27
+
28
+ .CodeMirror-gutters {
29
+ border-right: 1px solid #ddd;
30
+ background-color: #f7f7f7;
31
+ white-space: nowrap;
32
+ }
33
+ .CodeMirror-linenumbers {}
34
+ .CodeMirror-linenumber {
35
+ padding: 0 3px 0 5px;
36
+ min-width: 20px;
37
+ text-align: right;
38
+ color: #999;
39
+ }
40
+
41
+ /* CURSOR */
42
+
43
+ .CodeMirror div.CodeMirror-cursor {
44
+ border-left: 1px solid black;
45
+ z-index: 3;
46
+ }
47
+ /* Shown when moving in bi-directional text */
48
+ .CodeMirror div.CodeMirror-secondarycursor {
49
+ border-left: 1px solid silver;
50
+ }
51
+ .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
52
+ width: auto;
53
+ border: 0;
54
+ background: #7e7;
55
+ z-index: 1;
56
+ }
57
+ /* Can style cursor different in overwrite (non-insert) mode */
58
+ .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
59
+
60
+ .cm-tab { display: inline-block; }
61
+
62
+ /* DEFAULT THEME */
63
+
64
+ .cm-s-default .cm-keyword {color: #708;}
65
+ .cm-s-default .cm-atom {color: #219;}
66
+ .cm-s-default .cm-number {color: #164;}
67
+ .cm-s-default .cm-def {color: #00f;}
68
+ .cm-s-default .cm-variable {color: black;}
69
+ .cm-s-default .cm-variable-2 {color: #05a;}
70
+ .cm-s-default .cm-variable-3 {color: #085;}
71
+ .cm-s-default .cm-property {color: black;}
72
+ .cm-s-default .cm-operator {color: black;}
73
+ .cm-s-default .cm-comment {color: #a50;}
74
+ .cm-s-default .cm-string {color: #a11;}
75
+ .cm-s-default .cm-string-2 {color: #f50;}
76
+ .cm-s-default .cm-meta {color: #555;}
77
+ .cm-s-default .cm-error {color: #f00;}
78
+ .cm-s-default .cm-qualifier {color: #555;}
79
+ .cm-s-default .cm-builtin {color: #30a;}
80
+ .cm-s-default .cm-bracket {color: #997;}
81
+ .cm-s-default .cm-tag {color: #170;}
82
+ .cm-s-default .cm-attribute {color: #00c;}
83
+ .cm-s-default .cm-header {color: blue;}
84
+ .cm-s-default .cm-quote {color: #090;}
85
+ .cm-s-default .cm-hr {color: #999;}
86
+ .cm-s-default .cm-link {color: #00c;}
87
+
88
+ .cm-negative {color: #d44;}
89
+ .cm-positive {color: #292;}
90
+ .cm-header, .cm-strong {font-weight: bold;}
91
+ .cm-em {font-style: italic;}
92
+ .cm-link {text-decoration: underline;}
93
+
94
+ .cm-invalidchar {color: #f00;}
95
+
96
+ div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
97
+ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
98
+ .CodeMirror-activeline-background {background: #e8f2ff;}
99
+
100
+ /* STOP */
101
+
102
+ /* The rest of this file contains styles related to the mechanics of
103
+ the editor. You probably shouldn't touch them. */
104
+
105
+ .CodeMirror {
106
+ line-height: 1;
107
+ position: relative;
108
+ overflow: hidden;
109
+ background: white;
110
+ color: black;
111
+ border-top: 1px solid #BBBBBB;
112
+ }
113
+
114
+ .CodeMirror-scroll {
115
+ /* 30px is the magic margin used to hide the element's real scrollbars */
116
+ /* See overflow: hidden in .CodeMirror */
117
+ background-color: #F9F9F9;
118
+ font-size: 1.1em;
119
+ height: 100%;
120
+ outline: none; /* Prevent dragging from highlighting the element */
121
+ position: relative;
122
+ }
123
+ .CodeMirror-sizer {
124
+ position: relative;
125
+ }
126
+
127
+ /* The fake, visible scrollbars. Used to force redraw during scrolling
128
+ before actuall scrolling happens, thus preventing shaking and
129
+ flickering artifacts. */
130
+ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
131
+ position: absolute;
132
+ z-index: 6;
133
+ display: none;
134
+ }
135
+ .CodeMirror-vscrollbar {
136
+ right: 0; top: 0;
137
+ overflow-x: hidden;
138
+ overflow-y: scroll;
139
+ }
140
+ .CodeMirror-hscrollbar {
141
+ bottom: 0; left: 0;
142
+ overflow-y: hidden;
143
+ overflow-x: scroll;
144
+ }
145
+ .CodeMirror-scrollbar-filler {
146
+ right: 0; bottom: 0;
147
+ }
148
+ .CodeMirror-gutter-filler {
149
+ left: 0; bottom: 0;
150
+ }
151
+
152
+ .CodeMirror-gutters {
153
+ position: absolute; left: 0; top: 0;
154
+ padding-bottom: 30px;
155
+ z-index: 3;
156
+ }
157
+ .CodeMirror-gutter {
158
+ white-space: normal;
159
+ height: 100%;
160
+ padding-bottom: 30px;
161
+ margin-bottom: -32px;
162
+ display: inline-block;
163
+ /* Hack to make IE7 behave */
164
+ *zoom:1;
165
+ *display:inline;
166
+ }
167
+ .CodeMirror-gutter-elt {
168
+ position: absolute;
169
+ cursor: default;
170
+ z-index: 4;
171
+ }
172
+
173
+ .CodeMirror-lines {
174
+ cursor: text;
175
+ }
176
+ .CodeMirror pre {
177
+ /* Reset some styles that the rest of the page might have set */
178
+ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
179
+ border-width: 0;
180
+ background: transparent;
181
+ font-family: inherit;
182
+ font-size: inherit;
183
+ margin: 0;
184
+ white-space: pre;
185
+ word-wrap: normal;
186
+ line-height: inherit;
187
+ color: inherit;
188
+ z-index: 2;
189
+ position: relative;
190
+ overflow: visible;
191
+ }
192
+ .CodeMirror-wrap pre {
193
+ word-wrap: break-word;
194
+ white-space: pre-wrap;
195
+ word-break: normal;
196
+ }
197
+ .CodeMirror-code pre {
198
+ border-right: 30px solid transparent;
199
+ width: -webkit-fit-content;
200
+ width: -moz-fit-content;
201
+ width: fit-content;
202
+ }
203
+ .CodeMirror-wrap .CodeMirror-code pre {
204
+ border-right: none;
205
+ width: auto;
206
+ }
207
+ .CodeMirror-linebackground {
208
+ position: absolute;
209
+ left: 0; right: 0; top: 0; bottom: 0;
210
+ z-index: 0;
211
+ }
212
+
213
+ .CodeMirror-linewidget {
214
+ position: relative;
215
+ z-index: 2;
216
+ overflow: auto;
217
+ }
218
+
219
+ .CodeMirror-widget {
220
+ }
221
+
222
+ .CodeMirror-wrap .CodeMirror-scroll {
223
+ overflow-x: hidden;
224
+ }
225
+
226
+ .CodeMirror-measure {
227
+ position: absolute;
228
+ width: 100%; height: 0px;
229
+ overflow: hidden;
230
+ visibility: hidden;
231
+ }
232
+ .CodeMirror-measure pre { position: static; }
233
+
234
+ .CodeMirror div.CodeMirror-cursor {
235
+ position: absolute;
236
+ visibility: hidden;
237
+ border-right: none;
238
+ width: 0;
239
+ }
240
+ .CodeMirror-focused div.CodeMirror-cursor {
241
+ visibility: visible;
242
+ }
243
+
244
+ .CodeMirror-selected { background: #d9d9d9; }
245
+ .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
246
+
247
+ .cm-searching {
248
+ background: #ffa;
249
+ background: rgba(255, 255, 0, .4);
250
+ }
251
+
252
+ /* IE7 hack to prevent it from returning funny offsetTops on the spans */
253
+ .CodeMirror span { *vertical-align: text-bottom; }
254
+
255
+ @media print {
256
+ /* Hide the cursor when printing */
257
+ .CodeMirror div.CodeMirror-cursor {
258
+ visibility: hidden;
259
+ }
260
+ }
media/css/extension.css ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .cpanel{
2
+ display: table;
3
+ width: 100%;
4
+ }
5
+
6
+ .extension-name{
7
+ font-weight: bold;
8
+ font-family: Tahoma, Geneva, sans-serif;
9
+ }
10
+
11
+ .extension-description{
12
+ text-align: justify;
13
+ }
14
+
15
+ .extension-description a{
16
+ font-weight: bold;
17
+ text-decoration: none;
18
+ }
19
+
20
+ .extension-price{
21
+ text-align: center;
22
+ font-weight: bold;
23
+ font-size: 1.1em;
24
+ }
25
+
26
+ .free{
27
+ color: #006400;
28
+ }
29
+
30
+ .payed{
31
+ color: #212121;
32
+ }
33
+
34
+ .cpanel-item{
35
+ height: 64px;
36
+ min-width: 48px;
37
+ display: table-cell;
38
+ text-align: center;
39
+ vertical-align: bottom;
40
+ text-decoration: none;
41
+ text-transform: uppercase;
42
+ font-size: 10px;
43
+ font-weight: bold;
44
+ color: #333333;
45
+ background-repeat: no-repeat;
46
+ background-position: center top;
47
+ }
48
+
49
+ a.cpanel-item{
50
+ outline: 0;
51
+ }
52
+
53
+ .cpanel-item-twitter{
54
+ background-image: url('images/extension/twitter.png');
55
+ }
56
+
57
+ .cpanel-item-twitter:hover{
58
+ background-image: url('images/extension/twitter-active.png');
59
+ }
60
+
61
+ .cpanel-item-message{
62
+ background-image: url('images/extension/message.png');
63
+ }
64
+
65
+ .cpanel-item-message:hover{
66
+ background-image: url('images/extension/message-active.png');
67
+ }
68
+
69
+ .cpanel-item-website{
70
+ background-image: url('images/extension/link.png');
71
+ }
72
+
73
+ .cpanel-item-website:hover{
74
+ background-image: url('images/extension/link-active.png');
75
+ }
76
+
77
+ .extension-actions{
78
+ display: table;
79
+ width: 100%;
80
+ }
81
+
82
+ .extension-action{
83
+ width: 26px;
84
+ height: 26px;
85
+ display: table-cell;
86
+ text-align: center;
87
+ vertical-align: middle;
88
+ text-decoration: none;
89
+ background-color: transparent;
90
+ background-repeat: no-repeat;
91
+ background-position: center;
92
+ }
93
+
94
+ a.extension-action{
95
+ outline: 0;
96
+ }
97
+
98
+ .extension-action-youtube{
99
+ background-image: url('images/extension/youtube.png');
100
+ }
101
+
102
+ .extension-action-youtube:hover{
103
+ background-image: url('images/extension/youtube-active.png');
104
+ }
105
+
106
+ .extension-action-forum{
107
+ background-image: url('images/extension/forum.png');
108
+ }
109
+
110
+ .extension-action-forum:hover{
111
+ background-image: url('images/extension/forum-active.png');
112
+ }
113
+
114
+ .extension-action-purchase{
115
+ background-image: url('images/extension/plus.png');
116
+ }
117
+
118
+ .extension-action-purchase:hover{
119
+ background-image: url('images/extension/plus-active.png');
120
+ }
121
+
122
+ .extension-action-ok{
123
+ background-image: url('images/extension/ok.png');
124
+ }
125
+
126
+ .extension-action-ok:hover{
127
+ background-image: url('images/extension/ok-active.png');
128
+ }
129
+
130
+ .extension-action-download{
131
+ background-image: url('images/extension/download.png');
132
+ }
133
+
134
+ .extension-action-download:hover{
135
+ background-image: url('images/extension/download-active.png');
136
+ }
137
+
138
+ .aam-tooltip {
139
+ display:none;
140
+ position:absolute;
141
+ border:1px solid #CCCCCC;
142
+ background-color: #F5F5F5;
143
+ border-radius: 4px;
144
+ box-shadow: 0 0 5px #AAAAAA;
145
+ padding: 5px 10px;
146
+ z-index: 9999;
147
+ color: #333333;
148
+ font-size: 1em;
149
+ max-width: 300px;
150
+ left:0px;
151
+ top: 0px;
152
+ font-weight: bold;
153
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
154
+ }
155
+
156
+ .aam-dialog{
157
+ display: none;
158
+ }
159
+
160
+ .dialog-content{
161
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
162
+ }
163
+
164
+ .dialog-content a{
165
+ font-weight: bold;
166
+ text-decoration: none;
167
+ color: #257DA6;
168
+ outline: 0;
169
+ }
170
+
171
+ input.license-input{
172
+ width: 100%;
173
+ border: 1px solid #CCCCCC;
174
+ border-radius: 0px;
175
+ margin-top: 5px;
176
+ padding: 2px;
177
+ font-size: 12px;
178
+ line-height: 16px;
179
+ }
180
+
181
+ #install_extension{
182
+ position: relative;
183
+ }
184
+
185
+ .loading-extension{
186
+ width: 100%;
187
+ height: 100%;
188
+ background: #CCCCCC url('images/main-loader.gif') no-repeat center;
189
+ position: absolute;
190
+ top: 0;
191
+ left: 0;
192
+ opacity: 0.8;
193
+ }
media/css/images/animated-overlay.gif ADDED
Binary file
media/css/images/capability/add-active.png ADDED
Binary file
media/css/images/capability/add.png ADDED
Binary file
media/css/images/capability/ajax-loader.gif ADDED
Binary file
media/css/images/capability/checked.png ADDED
Binary file
media/css/images/capability/copy-active.png ADDED
Binary file
media/css/images/capability/copy.png ADDED
Binary file
media/css/images/capability/delete-active.png ADDED
Binary file
media/css/images/capability/delete.png ADDED
Binary file
media/css/images/capability/filter-active.png ADDED
Binary file
media/css/images/capability/filter.png ADDED
Binary file
media/css/images/capability/restore-active.png ADDED
Binary file
media/css/images/capability/restore.png ADDED
Binary file
media/css/images/capability/select-active.png ADDED
Binary file
media/css/images/capability/select.png ADDED
Binary file
media/css/images/capability/unchecked.png ADDED
Binary file
media/css/images/cmanager/add-active.png ADDED
Binary file
media/css/images/cmanager/add.png ADDED
Binary file
media/css/images/cmanager/block-user-active.png ADDED
Binary file
media/css/images/cmanager/block-user.png ADDED
Binary file
media/css/images/cmanager/delete-active.png ADDED
Binary file
media/css/images/cmanager/delete.png ADDED
Binary file
media/css/images/cmanager/edit-active.png ADDED
Binary file
media/css/images/cmanager/edit-user-active.png ADDED
Binary file
media/css/images/cmanager/edit-user.png ADDED
Binary file
media/css/images/cmanager/edit.png ADDED
Binary file
media/css/images/cmanager/field-loader.gif ADDED
Binary file
media/css/images/cmanager/filter-active.png ADDED
Binary file
media/css/images/cmanager/filter.png ADDED
Binary file
media/css/images/cmanager/multisite-active.png ADDED
Binary file
media/css/images/cmanager/multisite.png ADDED
Binary file
media/css/images/cmanager/refresh-active.png ADDED
Binary file
media/css/images/cmanager/refresh.png ADDED
Binary file
media/css/images/cmanager/role-active.png ADDED
Binary file
media/css/images/cmanager/role.png ADDED
Binary file
media/css/images/cmanager/select-active.png ADDED
Binary file
media/css/images/cmanager/select.png ADDED
Binary file
media/css/images/cmanager/settings-active.png ADDED
Binary file
media/css/images/cmanager/settings.png ADDED
Binary file
media/css/images/cmanager/user-active.png ADDED
Binary file
media/css/images/cmanager/user.png ADDED
Binary file
media/css/images/cmanager/visitor-active.png ADDED
Binary file
media/css/images/cmanager/visitor.png ADDED
Binary file
media/css/images/configpress/pdf-active.png ADDED
Binary file
media/css/images/configpress/pdf.png ADDED
Binary file
media/css/images/cpanel/cpanel-loader.gif ADDED
Binary file
media/css/images/cpanel/help-forum-active.png ADDED
Binary file
media/css/images/cpanel/help-forum.png ADDED
Binary file
media/css/images/cpanel/message-active.png ADDED
Binary file
media/css/images/cpanel/message.png ADDED
Binary file
media/css/images/cpanel/restore-active.png ADDED
Binary file
media/css/images/cpanel/restore.png ADDED
Binary file
media/css/images/cpanel/save-active.png ADDED
Binary file
media/css/images/cpanel/save.png ADDED
Binary file
media/css/images/cpanel/star-active.png ADDED
Binary file
media/css/images/cpanel/star.png ADDED
Binary file
media/css/images/cpanel/twitter-active.png ADDED
Binary file
media/css/images/cpanel/twitter.png ADDED
Binary file
media/css/images/event/add-active.png ADDED
Binary file
media/css/images/event/add.png ADDED
Binary file
media/css/images/event/delete-active.png ADDED
Binary file
media/css/images/event/delete.png ADDED
Binary file
media/css/images/event/edit-active.png ADDED
Binary file
media/css/images/event/edit.png ADDED
Binary file
media/css/images/extension/download-active.png ADDED
Binary file
media/css/images/extension/download.png ADDED
Binary file
media/css/images/extension/forum-active.png ADDED
Binary file
media/css/images/extension/forum.png ADDED
Binary file
media/css/images/extension/link-active.png ADDED
Binary file
media/css/images/extension/link.png ADDED
Binary file
media/css/images/extension/message-active.png ADDED
Binary file
media/css/images/extension/message.png ADDED
Binary file
media/css/images/extension/ok-active.png ADDED
Binary file
media/css/images/extension/ok.png ADDED
Binary file
media/css/images/extension/plus-active.png ADDED
Binary file
media/css/images/extension/plus.png ADDED
Binary file
media/css/images/extension/purchase-active.png ADDED
Binary file
media/css/images/extension/purchase.png ADDED
Binary file
media/css/images/extension/twitter-active.png ADDED
Binary file
media/css/images/extension/twitter.png ADDED
Binary file
media/css/images/extension/youtube-active.png ADDED
Binary file
media/css/images/extension/youtube.png ADDED
Binary file
media/css/images/feature-active.png ADDED
Binary file
media/css/images/feature.png ADDED
Binary file
media/css/images/help.png ADDED
Binary file
media/css/images/lock.png ADDED
Binary file
css/images/ajax-loader.gif → media/css/images/main-loader.gif RENAMED
Binary file
media/css/images/menu/checked.png ADDED
Binary file
media/css/images/menu/sorting-active.png ADDED
Binary file
media/css/images/menu/sorting.png ADDED
Binary file
media/css/images/menu/unchecked.png ADDED
Binary file
media/css/images/menu/visibility-active.png ADDED
Binary file
media/css/images/menu/visibility.png ADDED
Binary file
media/css/images/metabox-loader.gif ADDED
Binary file
media/css/images/metabox/add-active.png ADDED
Binary file
media/css/images/metabox/add.png ADDED
Binary file
media/css/images/metabox/checked.png ADDED
Binary file
media/css/images/metabox/link-active.png ADDED
Binary file
media/css/images/metabox/link.png ADDED
Binary file
media/css/images/metabox/refresh-active.png ADDED
Binary file
media/css/images/metabox/refresh.png ADDED
Binary file
media/css/images/metabox/unchecked.png ADDED
Binary file
media/css/images/post/checked.png ADDED
Binary file
media/css/images/post/edit-active.png ADDED
Binary file
media/css/images/post/edit.png ADDED
Binary file
media/css/images/post/filter-active.png ADDED
Binary file
media/css/images/post/filter.png ADDED
Binary file
media/css/images/post/info-active.png ADDED
Binary file
media/css/images/post/info.png ADDED
Binary file
media/css/images/post/loader.gif ADDED
Binary file
media/css/images/post/lock-big.png ADDED
Binary file
media/css/images/post/lock.png ADDED
Binary file
media/css/images/post/post.png ADDED
Binary file
media/css/images/post/refresh-active.png ADDED
Binary file
media/css/images/post/refresh.png ADDED
Binary file
media/css/images/post/settings-active.png ADDED
Binary file
media/css/images/post/settings.png ADDED
Binary file
media/css/images/post/unchecked.png ADDED
Binary file
media/css/images/search-active.png ADDED
Binary file
media/css/images/search.png ADDED
Binary file
media/css/images/sort_asc.png ADDED
Binary file
media/css/images/sort_asc_disabled.png ADDED
Binary file
media/css/images/sort_both.png ADDED
Binary file
media/css/images/sort_desc.png ADDED
Binary file
media/css/images/sort_desc_disabled.png ADDED
Binary file
media/css/images/table-filtered.png ADDED
Binary file
media/css/images/treeview/ajax-loader.gif ADDED
Binary file
media/css/images/treeview/file.gif ADDED
Binary file
media/css/images/treeview/folder-close.png ADDED
Binary file
media/css/images/treeview/folder-closed.gif ADDED
Binary file
media/css/images/treeview/folder-open.png ADDED
Binary file
media/css/images/treeview/folder.gif ADDED
Binary file
media/css/images/treeview/minus.gif ADDED
Binary file
media/css/images/treeview/plus.gif ADDED
Binary file
media/css/images/treeview/treeview-black-line.gif ADDED
Binary file
media/css/images/treeview/treeview-black.gif ADDED
Binary file
media/css/images/treeview/treeview-default-line.gif ADDED
Binary file
media/css/images/treeview/treeview-default.gif ADDED
Binary file
media/css/images/treeview/treeview-famfamfam-line.gif ADDED
Binary file
media/css/images/treeview/treeview-famfamfam.gif ADDED
Binary file
media/css/images/treeview/treeview-gray-line.gif ADDED
Binary file
media/css/images/treeview/treeview-gray.gif ADDED
Binary file
media/css/images/treeview/treeview-red-line.gif ADDED
Binary file
media/css/images/treeview/treeview-red.gif ADDED
Binary file
media/css/images/ui-bg_flat_0_aaaaaa_40x100.png ADDED
Binary file
media/css/images/ui-bg_flat_75_ffffff_40x100.png ADDED
Binary file
media/css/images/ui-bg_glass_55_fbf9ee_1x400.png ADDED
Binary file
media/css/images/ui-bg_glass_65_ffffff_1x400.png ADDED
Binary file
media/css/images/ui-bg_glass_75_dadada_1x400.png ADDED
Binary file
media/css/images/ui-bg_glass_75_e6e6e6_1x400.png ADDED
Binary file
media/css/images/ui-bg_glass_95_fef1ec_1x400.png ADDED
Binary file
media/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png ADDED
Binary file
media/css/images/ui-icons_222222_256x240.png ADDED
Binary file
media/css/images/ui-icons_2e83ff_256x240.png ADDED
Binary file
media/css/images/ui-icons_454545_256x240.png ADDED
Binary file
media/css/images/ui-icons_888888_256x240.png ADDED
Binary file
media/css/images/ui-icons_cd0a0a_256x240.png ADDED
Binary file
media/css/jquery-ui.css ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*! jQuery UI - v1.10.3 - 2013-09-12
2
+ * http://jqueryui.com
3
+ * Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
4
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
5
+ * Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
6
+
7
+ .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;min-height:0}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:21px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("images/animated-overlay.gif");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
media/css/jquery.dt.css ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .dataTable {
2
+ margin: 10px auto;
3
+ clear: both;
4
+ width: 100%;
5
+ border: 1px solid #CCCCCC;
6
+ }
7
+
8
+ table.dataTable thead th {
9
+ padding: 3px 18px 3px 10px;
10
+ border-bottom: 1px solid #CCCCCC;
11
+ font-weight: bold;
12
+ text-transform: uppercase;
13
+ cursor: pointer;
14
+ background-color: #257da6;
15
+ }
16
+
17
+ table.dataTable tfoot td {
18
+ border-top: 1px solid #CCCCCC;
19
+ }
20
+
21
+ table.dataTable td {
22
+ padding: 3px 10px;
23
+ }
24
+
25
+ table.dataTable td.center,
26
+ table.dataTable td.dataTables_empty {
27
+ text-align: center;
28
+ }
29
+
30
+ table.dataTable tr.odd { background-color: #E2E4FF; }
31
+ table.dataTable tr.even { background-color: white; }
32
+
33
+ table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; }
34
+ table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; }
35
+ table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; }
36
+ table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; }
37
+ table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; }
38
+ table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; }
39
+
40
+
41
+ /*
42
+ * Table wrapper
43
+ */
44
+ .dataTables_wrapper {
45
+ position: relative;
46
+ clear: both;
47
+ }
48
+
49
+
50
+ /*
51
+ * Page length menu
52
+ */
53
+ .dataTables_length {
54
+ float: left;
55
+ margin-right: 5px;
56
+ }
57
+
58
+ /*
59
+ * Filter
60
+ */
61
+ .dataTables_filter {
62
+ text-align: left;
63
+ width: 60%;
64
+ float:left;
65
+ }
66
+
67
+ .dataTables_filter input{
68
+ width: 90%;
69
+ height: 24px;
70
+ padding-left: 24px;
71
+ background: transparent url('images/search.png') no-repeat 5px center;
72
+ }
73
+
74
+ .dataTables_filter input:focus{
75
+ background: transparent url('images/search-active.png') no-repeat 5px center;
76
+ }
77
+
78
+ .table-filtered{
79
+ background: transparent url('images/table-filtered.png') no-repeat 2px center;
80
+ height: 16px;
81
+ display: inline-block;
82
+ padding-left: 20px;
83
+ font-size: 0.8em;
84
+ }
85
+
86
+ a.clear-table-filter{
87
+ text-decoration: none;
88
+ color: #257DA6;
89
+ font-size: 0.9em;
90
+ font-weight: bold;
91
+ }
92
+
93
+ /*
94
+ * Table information
95
+ */
96
+ .dataTables_info {
97
+ clear: both;
98
+ float: left;
99
+ }
100
+
101
+
102
+ /*
103
+ * Pagination
104
+ */
105
+ .dataTables_paginate {
106
+ float: right;
107
+ text-align: right;
108
+ font-size: 0.8em;
109
+ }
110
+
111
+ /* Two button pagination - previous / next */
112
+ .paginate_disabled_previous,
113
+ .paginate_enabled_previous,
114
+ .paginate_disabled_next,
115
+ .paginate_enabled_next {
116
+ height: 19px;
117
+ float: left;
118
+ cursor: pointer;
119
+ *cursor: hand;
120
+ color: #111 !important;
121
+ }
122
+ .paginate_disabled_previous:hover,
123
+ .paginate_enabled_previous:hover,
124
+ .paginate_disabled_next:hover,
125
+ .paginate_enabled_next:hover {
126
+ text-decoration: none !important;
127
+ }
128
+ .paginate_disabled_previous:active,
129
+ .paginate_enabled_previous:active,
130
+ .paginate_disabled_next:active,
131
+ .paginate_enabled_next:active {
132
+ outline: none;
133
+ }
134
+
135
+ .paginate_disabled_previous,
136
+ .paginate_disabled_next {
137
+ color: #666 !important;
138
+ }
139
+ .paginate_disabled_previous,
140
+ .paginate_enabled_previous {
141
+ padding-left: 23px;
142
+ }
143
+ .paginate_disabled_next,
144
+ .paginate_enabled_next {
145
+ padding-right: 23px;
146
+ margin-left: 10px;
147
+ }
148
+
149
+ .paginate_enabled_previous { background: url('images/back_enabled.png') no-repeat top left; }
150
+ .paginate_enabled_previous:hover { background: url('images/back_enabled_hover.png') no-repeat top left; }
151
+ .paginate_disabled_previous { background: url('images/back_disabled.png') no-repeat top left; }
152
+
153
+ .paginate_enabled_next { background: url('images/forward_enabled.png') no-repeat top right; }
154
+ .paginate_enabled_next:hover { background: url('images/forward_enabled_hover.png') no-repeat top right; }
155
+ .paginate_disabled_next { background: url('images/forward_disabled.png') no-repeat top right; }
156
+
157
+ /* Full number pagination */
158
+ .paging_full_numbers {
159
+ height: 22px;
160
+ line-height: 22px;
161
+ }
162
+ .paging_full_numbers a:active {
163
+ outline: none
164
+ }
165
+ .paging_full_numbers a:hover {
166
+ text-decoration: none;
167
+ }
168
+
169
+ .paging_full_numbers a.paginate_button,
170
+ .paging_full_numbers a.paginate_active {
171
+ border: 1px solid #aaa;
172
+ -webkit-border-radius: 5px;
173
+ -moz-border-radius: 5px;
174
+ border-radius: 5px;
175
+ padding: 2px 5px;
176
+ margin: 0 3px;
177
+ cursor: pointer;
178
+ *cursor: hand;
179
+ color: #333 !important;
180
+ }
181
+
182
+ .paging_full_numbers a.paginate_button {
183
+ background-color: #ddd;
184
+ }
185
+
186
+ .paging_full_numbers a.paginate_button:hover {
187
+ background-color: #ccc;
188
+ text-decoration: none !important;
189
+ }
190
+
191
+ .paging_full_numbers a.paginate_active {
192
+ background-color: #99B3FF;
193
+ }
194
+
195
+
196
+ /*
197
+ * Processing indicator
198
+ */
199
+ .dataTables_processing {
200
+ position: absolute;
201
+ top: 50%;
202
+ left: 50%;
203
+ width: 250px;
204
+ height: 30px;
205
+ margin-left: -125px;
206
+ margin-top: -15px;
207
+ padding: 14px 0 2px 0;
208
+ border: 1px solid #ddd;
209
+ text-align: center;
210
+ color: #999;
211
+ font-size: 14px;
212
+ background-color: white;
213
+ }
214
+
215
+
216
+ /*
217
+ * Sorting
218
+ */
219
+ .sorting { background: url('images/sort_both.png') no-repeat center right; }
220
+ .sorting_asc { background: url('images/sort_asc.png') no-repeat center right; }
221
+ .sorting_desc { background: url('images/sort_desc.png') no-repeat center right; }
222
+
223
+ .sorting_asc_disabled { background: url('images/sort_asc_disabled.png') no-repeat center right; }
224
+ .sorting_desc_disabled { background: url('images/sort_desc_disabled.png') no-repeat center right; }
225
+
226
+ table.dataTable thead th:active,
227
+ table.dataTable thead td:active {
228
+ outline: none;
229
+ }
230
+
231
+
232
+ /*
233
+ * Scrolling
234
+ */
235
+ .dataTables_scroll {
236
+ clear: both;
237
+ }
238
+
239
+ .dataTables_scrollBody {
240
+ *margin-top: -1px;
241
+ -webkit-overflow-scrolling: touch;
242
+ }
media/css/jquery.treeview.css ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .treeview, .treeview ul {
2
+ padding: 0;
3
+ margin: 0;
4
+ list-style: none;
5
+ }
6
+
7
+ .treeview ul {
8
+
9
+ margin-top: 4px;
10
+ }
11
+
12
+ .treeview .hitarea {
13
+ background: url(images/treeview/treeview-default.gif) -64px -25px no-repeat;
14
+ height: 16px;
15
+ width: 16px;
16
+ margin-left: -16px;
17
+ float: left;
18
+ cursor: pointer;
19
+ }
20
+ /* fix for IE6 */
21
+ * html .hitarea {
22
+ display: inline;
23
+ float:none;
24
+ }
25
+
26
+ .treeview li {
27
+ margin: 0;
28
+ padding: 3px 0pt 3px 16px;
29
+ }
30
+
31
+ .treeview a.selected {
32
+ background-color: #eee;
33
+ }
34
+
35
+ #treecontrol { margin: 1em 0; display: none; }
36
+
37
+ .treeview .hover { color: red; cursor: pointer; }
38
+
39
+ .treeview li { background: url(images/treeview/treeview-default-line.gif) 0 0 no-repeat; }
40
+ .treeview li.collapsable, .treeview li.expandable { background-position: 0 -176px; }
41
+
42
+ .treeview .expandable-hitarea { background-position: -80px -3px; }
43
+
44
+ .treeview li.last { background-position: 0 -1766px }
45
+ .treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(images/treeview/treeview-default.gif); }
46
+ .treeview li.lastCollapsable { background-position: 0 -111px }
47
+ .treeview li.lastExpandable { background-position: -32px -67px }
48
+
49
+ .treeview div.lastCollapsable-hitarea, .treeview div.lastExpandable-hitarea { background-position: 0; }
50
+
51
+ .treeview-red li { background-image: url(images/treeview/treeview-red-line.gif); }
52
+ .treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(images/treeview-red.gif); }
53
+
54
+ .treeview-black li { background-image: url(images/treeview/treeview-black-line.gif); }
55
+ .treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(images/treeview-black.gif); }
56
+
57
+ .treeview-gray li { background-image: url(images/treeview/treeview-gray-line.gif); }
58
+ .treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(images/treeview-gray.gif); }
59
+
60
+ .treeview-famfamfam li { background-image: url(images/treeview/treeview-famfamfam-line.gif); }
61
+ .treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(images/treeview-famfamfam.gif); }
62
+
63
+ .treeview .placeholder {
64
+ background: url(images/treeview/ajax-loader.gif) 0 0 no-repeat;
65
+ height: 16px;
66
+ width: 16px;
67
+ display: block;
68
+ }
69
+
70
+ .filetree li { padding: 3px 0 2px 16px; }
71
+ .filetree span.folder { padding-left: 18px; display: block; }
72
+ .filetree span.folder { background: url(images/treeview/folder-open.png) 0 0 no-repeat; }
73
+ .filetree li.expandable span.folder { background: url(images/treeview/folder-close.png) 0 0 no-repeat; }
74
+ .filetree span.folder a{
75
+ text-decoration: none;
76
+ }
77
+
78
+ .treeview .important{
79
+ font-weight: bold;
80
+ }
81
+
82
+ .treeview .roots{
83
+ font-weight: bold;
84
+ color: #257DA6;
85
+ }
86
+
87
+ #sidetreecontrol{
88
+ font-size: 12px;
89
+ margin-bottom: 10px;
90
+ float: right;
91
+ padding-bottom: 6px;
92
+ border-bottom: 2px solid #257DA6;
93
+ }
94
+
95
+ #sidetreecontrol span{
96
+ color: #006505;
97
+ text-decoration: underline;
98
+ cursor: pointer;
99
+ }
100
+
101
+ #sidetreecontrol span:hover{
102
+ color: #257da6;
103
+ }
104
+
105
+ .tree-holder{
106
+ width: auto;
107
+ padding: 10px;
108
+ }
109
+
110
+ #sidetreecontrol a{
111
+ color: #006505;
112
+ outline: none;
113
+ }
114
+
115
+ #sidetreecontrol a:hover{
116
+ color: #257da6;
117
+ }
media/css/migrate.css ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .migration-dialog{
2
+ position: fixed;
3
+ width: 30%;
4
+ top: 25%;
5
+ left: 50%;
6
+ margin-left: -12.5%;
7
+ border: 2px solid #CCCCCC;
8
+ background-color: #F5F5F5;
9
+ opacity: 0.9;
10
+ }
11
+
12
+ .migration-header{
13
+ height: 20px;
14
+ width: 100%;
15
+ background-color: #0074a2;
16
+ color: #FFFFFF;
17
+ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
18
+ padding-left: 10px;
19
+ font-size: 12px;
20
+ padding-top: 4px;
21
+ box-sizing: border-box;
22
+ -moz-box-sizing: border-box;
23
+ -webkit-box-sizing: border-box;
24
+ }
25
+
26
+ .migration-notice{
27
+ margin: 5px 10px;
28
+ border: 1px solid #FF6666;
29
+ text-align: center;
30
+ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
31
+ font-size: 12px;
32
+ font-weight: bold;
33
+ }
34
+
35
+ .migration-steps{
36
+ margin: 5px 10px;
37
+ }
38
+
39
+ .migration-step{
40
+ border: 1px solid #CCCCCC;
41
+ margin-top: 2px;
42
+ background-color: #EAEBFF;
43
+ height: 28px;
44
+ font-family: "Trebuchet MS", Helvetica, sans-serif;
45
+ box-sizing: border-box;
46
+ -moz-box-sizing: border-box;
47
+ -webkit-box-sizing: border-box;
48
+ font-size: 14px;
49
+ padding: 3px 0 3px 34px;
50
+ opacity: 0.3;
51
+ }
52
+
53
+ .migration-step-pending{
54
+ background: #EAEBFF url('migrate/pending.png') no-repeat 5px center;
55
+ }
56
+
57
+ .migration-step-running{
58
+ background: #EAEBFF url('migrate/wait.png') no-repeat 5px center;
59
+ }
60
+
61
+ .migration-step-completed{
62
+ background: #EAEBFF url('migrate/completed.png') no-repeat 5px center;
63
+ }
64
+
65
+ .migration-step-failed{
66
+ background: #EAEBFF url('migrate/failure.png') no-repeat 5px center;
67
+ }
media/css/migrate/completed.png ADDED
Binary file
media/css/migrate/failure.png ADDED
Binary file
media/css/migrate/pending.png ADDED
Binary file
media/css/migrate/wait.png ADDED
Binary file
media/js/aam.js ADDED
@@ -0,0 +1,2773 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * ======================================================================
3
+ * LICENSE: This file is subject to the terms and conditions defined in *
4
+ * file 'license.txt', which is part of this source code package. *
5
+ * ======================================================================
6
+ */
7
+
8
+ /**
9
+ * Main AAM UI Class
10
+ *
11
+ * @returns {AAM}
12
+ */
13
+ function AAM() {
14
+
15
+ /**
16
+ * Current Subject
17
+ *
18
+ * @type {Object}
19
+ *
20
+ * @access public
21
+ */
22
+ this.subject = {
23
+ type: 'role',
24
+ id: aamLocal.defaultSegment.role
25
+ };
26
+
27
+ /**
28
+ * Current Post Term
29
+ *
30
+ * @type {Int}
31
+ *
32
+ * @access public
33
+ */
34
+ this.postTerm = '';
35
+
36
+ /**
37
+ * User Role to filter
38
+ *
39
+ * @type String
40
+ *
41
+ * @access public
42
+ */
43
+ this.userRoleFilter = aamLocal.defaultSegment.role;
44
+
45
+ /**
46
+ * ConfigPress editor
47
+ *
48
+ * @type {Object}
49
+ *
50
+ * @access public
51
+ */
52
+ this.editor = null;
53
+
54
+ /**
55
+ * JavaScript Custom Actions
56
+ *
57
+ * @type Array
58
+ */
59
+ this.actions = new Array();
60
+
61
+ //Let's init the UI
62
+ this.initUI();
63
+ }
64
+
65
+ /**
66
+ * List of Blog Tables
67
+ *
68
+ * @type {Object}
69
+ *
70
+ * @access public
71
+ */
72
+ AAM.prototype.blogTables = {
73
+ capabilities: null,
74
+ inheritRole: null,
75
+ postList: null,
76
+ eventList: null,
77
+ filterRoleList: null
78
+ };
79
+
80
+ /**
81
+ * List of Segment Tables
82
+ *
83
+ * @type {Object}
84
+ *
85
+ * @access public
86
+ */
87
+ AAM.prototype.segmentTables = {
88
+ roleList: null,
89
+ userList: null
90
+ };
91
+
92
+ /**
93
+ * Add Custom Action to queue
94
+ *
95
+ * @param {String} action
96
+ * @param {Fuction} callback
97
+ *
98
+ * @returns {void}
99
+ */
100
+ AAM.prototype.addAction = function(action, callback) {
101
+ if (typeof this.actions[action] === 'undefined') {
102
+ this.actions[action] = new Array();
103
+ }
104
+
105
+ this.actions[action].push(callback);
106
+ };
107
+
108
+ /**
109
+ * Do Custom Action queue
110
+ *
111
+ * @param {String} action
112
+ * @param {Object} params
113
+ *
114
+ * @returns {void}
115
+ */
116
+ AAM.prototype.doAction = function(action, params) {
117
+ if (typeof this.actions[action] !== 'undefined') {
118
+ for (var i in this.actions[action]) {
119
+ this.actions[action][i].call(this, params);
120
+ }
121
+ }
122
+ };
123
+
124
+ /**
125
+ * Set Current Subject
126
+ *
127
+ * @param {String} type
128
+ * @param {String} id
129
+ *
130
+ * @returns {void}
131
+ *
132
+ * @access public
133
+ */
134
+ AAM.prototype.setSubject = function(type, id) {
135
+ //reset subject first
136
+ this.subject.type = type;
137
+ this.subject.id = id;
138
+ };
139
+
140
+ /**
141
+ * Get Current Subject
142
+ *
143
+ * @param {String} subject
144
+ *
145
+ * @returns {void}
146
+ *
147
+ * @access public
148
+ */
149
+ AAM.prototype.getSubject = function() {
150
+ return this.subject;
151
+ };
152
+
153
+ /**
154
+ * Initialize the UI
155
+ *
156
+ * @returns {void}
157
+ *
158
+ * @access public
159
+ */
160
+ AAM.prototype.initUI = function() {
161
+ //initialize side blocks - Control Panel & Control Manager
162
+ this.initControlPanel();
163
+ this.initControlManager();
164
+
165
+ //Retrieve settings of default segment
166
+ this.retrieveSettings();
167
+ };
168
+
169
+ /**
170
+ * Initialize tooltip for selected area
171
+ *
172
+ * @param {String} selector
173
+ *
174
+ * @returns {void}
175
+ *
176
+ * @access public
177
+ */
178
+ AAM.prototype.initTooltip = function(selector) {
179
+ jQuery('[tooltip]', selector).hover(function() {
180
+ // Hover over code
181
+ var title = jQuery(this).attr('tooltip');
182
+ jQuery(this).data('tipText', title).removeAttr('tooltip');
183
+ jQuery('<div/>', {
184
+ 'class': 'aam-tooltip'
185
+ }).text(title).appendTo('body').fadeIn('slow');
186
+ }, function() {
187
+ //Hover out code
188
+ jQuery(this).attr('tooltip', jQuery(this).data('tipText'));
189
+ jQuery('.aam-tooltip').remove();
190
+ }).mousemove(function(e) {
191
+ jQuery('.aam-tooltip').css({
192
+ top: e.pageY + 15, //Get Y coordinates
193
+ left: e.pageX + 15 //Get X coordinates
194
+ });
195
+ });
196
+ };
197
+
198
+ /**
199
+ * Show Metabox Loader
200
+ *
201
+ * @param {String} selector
202
+ *
203
+ * @returns {void}
204
+ *
205
+ * @access public
206
+ */
207
+ AAM.prototype.showMetaboxLoader = function(selector) {
208
+ jQuery('.aam-metabox-loader', selector).show();
209
+ };
210
+
211
+ /**
212
+ * Hide Metabox Loader
213
+ *
214
+ * @param {String} selector
215
+ *
216
+ * @returns {void}
217
+ *
218
+ * @access public
219
+ */
220
+ AAM.prototype.hideMetaboxLoader = function(selector) {
221
+ jQuery('.aam-metabox-loader', selector).hide();
222
+ };
223
+
224
+ /**
225
+ * Compile default Ajax POST package
226
+ *
227
+ * @param {String} action
228
+ * @param {Boolean} include_subject
229
+ *
230
+ * @returns {Object}
231
+ *
232
+ * @access public
233
+ */
234
+ AAM.prototype.compileAjaxPackage = function(action, include_subject) {
235
+ var data = {
236
+ action: 'aam',
237
+ sub_action: action,
238
+ _ajax_nonce: aamLocal.nonce
239
+ };
240
+ if (include_subject) {
241
+ data.subject = this.getSubject().type;
242
+ data.subject_id = this.getSubject().id;
243
+ }
244
+
245
+ return data;
246
+ };
247
+
248
+ /**
249
+ * Initialize Control Panel Metabox
250
+ *
251
+ * @returns {void}
252
+ *
253
+ * @access public
254
+ */
255
+ AAM.prototype.initControlPanel = function() {
256
+ var _this = this;
257
+ //Role Back feature
258
+ jQuery('#aam_roleback').bind('click', function(event) {
259
+ event.preventDefault();
260
+ var buttons = {};
261
+ buttons[aamLocal.labels['Rollback Settings']] = function() {
262
+ _this.showMetaboxLoader('#control_panel');
263
+ jQuery.ajax(aamLocal.ajaxurl, {
264
+ type: 'POST',
265
+ dataType: 'json',
266
+ data: _this.compileAjaxPackage('roleback', true),
267
+ success: function(response) {
268
+ if (response.status === 'success') {
269
+ _this.retrieveSettings();
270
+ if (response.more === 1) {
271
+ jQuery('#aam_roleback').show();
272
+ } else {
273
+ jQuery('#aam_roleback').hide();
274
+ }
275
+ }
276
+ _this.highlight('#control_panel .inside', response.status);
277
+ },
278
+ error: function() {
279
+ _this.highlight('#control_panel .inside', 'failure');
280
+ },
281
+ complete: function() {
282
+ _this.hideMetaboxLoader('#control_panel');
283
+ jQuery("#restore_dialog").dialog("close");
284
+ }
285
+ });
286
+ };
287
+ buttons[aamLocal.labels['Cancel']] = function() {
288
+ jQuery("#restore_dialog").dialog("close");
289
+ };
290
+
291
+ jQuery("#restore_dialog").dialog({
292
+ resizable: false,
293
+ height: 180,
294
+ modal: true,
295
+ buttons: buttons
296
+ });
297
+ });
298
+
299
+ //Save the AAM settings
300
+ jQuery('#aam_save').bind('click', function(event) {
301
+ event.preventDefault();
302
+ _this.showMetaboxLoader('#control_panel');
303
+
304
+ //get information from the form
305
+ var data = _this.compileAjaxPackage('save', true);
306
+ //collect data from the form
307
+ //1. Collect Main Menu
308
+ jQuery('input', '#admin_menu_content').each(function() {
309
+ data[jQuery(this).attr('name')] = (jQuery(this).prop('checked') ? 1 : 0);
310
+ });
311
+ //2. Collect Metaboxes & Widgets
312
+ jQuery('input', '#metabox_list').each(function() {
313
+ data[jQuery(this).attr('name')] = (jQuery(this).prop('checked') ? 1 : 0);
314
+ });
315
+ if (_this.getSubject().type !== 'visitor') {
316
+ //3. Collect Capabilities
317
+ var caps = _this.blogTables.capabilities.fnGetData();
318
+ for (var i in caps) {
319
+ data['aam[capability][' + caps[i][0] + ']'] = caps[i][1];
320
+ }
321
+ //4. Collect Events
322
+ var events = _this.blogTables.eventList.fnGetData();
323
+ for (var j in events) {
324
+ data['aam[event][' + j + '][event]'] = events[j][0];
325
+ data['aam[event][' + j + '][event_specifier]'] = events[j][1];
326
+ data['aam[event][' + j + '][post_type]'] = events[j][2];
327
+ data['aam[event][' + j + '][action]'] = events[j][3];
328
+ data['aam[event][' + j + '][action_specifier]'] = events[j][4];
329
+ }
330
+ }
331
+
332
+ //5. Collect ConfigPress
333
+ data['aam[configpress]'] = _this.editor.getValue();
334
+
335
+ //send the Ajax request to save the data
336
+ jQuery.ajax(aamLocal.ajaxurl, {
337
+ type: 'POST',
338
+ dataType: 'json',
339
+ data: data,
340
+ success: function(response) {
341
+ if (response.status === 'success') {
342
+ jQuery('#aam_roleback').show();
343
+ _this.retrieveSettings();
344
+ }
345
+ _this.highlight('#control_panel .inside', response.status);
346
+ },
347
+ error: function() {
348
+ _this.highlight('#control_panel .inside', 'failure');
349
+ },
350
+ complete: function() {
351
+ _this.hideMetaboxLoader('#control_panel');
352
+ }
353
+ });
354
+ });
355
+ //Send Email to Us
356
+ jQuery('#aam_message').bind('click', function(event) {
357
+ event.preventDefault();
358
+ var buttons = {};
359
+ buttons[aamLocal.labels['Send E-mail']] = function() {
360
+ location.href = 'mailto:support@wpaam.com';
361
+ jQuery("#message_dialog").dialog("close");
362
+ };
363
+ jQuery("#message_dialog").dialog({
364
+ resizable: false,
365
+ height: 'auto',
366
+ width: '20%',
367
+ modal: true,
368
+ buttons: buttons
369
+ });
370
+ });
371
+ //Init Tooltip
372
+ this.initTooltip('#control_panel');
373
+ };
374
+
375
+ /**
376
+ * Initialize Control Manager Metabox
377
+ *
378
+ * @returns {void}
379
+ *
380
+ * @access public
381
+ */
382
+ AAM.prototype.initControlManager = function() {
383
+ var _this = this;
384
+ jQuery('.control-manager a').each(function() {
385
+ jQuery(this).bind('click', function(event) {
386
+ event.preventDefault();
387
+ var segment = jQuery(this).attr('segment');
388
+ _this.loadSegment(segment);
389
+ });
390
+ });
391
+
392
+ //by default load the Role Segment
393
+ this.loadSegment('role');
394
+ };
395
+
396
+ /**
397
+ * Initialize & Load the Control Segment
398
+ *
399
+ * Segment is a access control area like Blog, Role or User. It is virtual
400
+ * understanding of what we are managing right now
401
+ *
402
+ * @param {String} segment
403
+ *
404
+ * @returns {void}
405
+ *
406
+ * @access public
407
+ */
408
+ AAM.prototype.loadSegment = function(segment) {
409
+ var _this = this;
410
+ //clear all active segments
411
+ jQuery('.control-manager a').each(function() {
412
+ _this.terminate(this, 'manager-item-' + jQuery(this).attr('segment'));
413
+ });
414
+
415
+ //hide all segment contents from control manager
416
+ jQuery('.control-manager-content > div').hide();
417
+
418
+ switch (segment) {
419
+ case 'role':
420
+ this.loadRoleSegment();
421
+ break;
422
+
423
+ case 'user':
424
+ this.loadUserSegment();
425
+ break;
426
+
427
+ case 'visitor':
428
+ this.loadVisitorSegment();
429
+ break;
430
+
431
+ default:
432
+ this.doAction('aam_load_segment');
433
+ break;
434
+ }
435
+
436
+ //activate segment icon
437
+ this.launch(jQuery('.manager-item-' + segment), 'manager-item-' + segment);
438
+ };
439
+
440
+ /**
441
+ * Initialize & Load Role Segment
442
+ *
443
+ * @returns {void}
444
+ *
445
+ * @access public
446
+ */
447
+ AAM.prototype.loadRoleSegment = function() {
448
+ var _this = this;
449
+
450
+ jQuery('#role_manager_wrap').show();
451
+ if (this.segmentTables.roleList === null) {
452
+ this.segmentTables.roleList = jQuery('#role_list').dataTable({
453
+ sDom: "<'top'f<'role-top-actions'><'clear'>>t<'footer'ip<'clear'>>",
454
+ bServerSide: true,
455
+ sPaginationType: "full_numbers",
456
+ bAutoWidth: false,
457
+ bSort: false,
458
+ fnServerData: function(sSource, aoData, fnCallback, oSettings) {
459
+ oSettings.jqXHR = jQuery.ajax({
460
+ "dataType": 'json',
461
+ "type": "POST",
462
+ "url": aamLocal.ajaxurl,
463
+ "data": aoData,
464
+ "success": fnCallback
465
+ });
466
+ },
467
+ fnServerParams: function(aoData) {
468
+ aoData.push({
469
+ name: 'action',
470
+ value: 'aam'
471
+ });
472
+ aoData.push({
473
+ name: 'sub_action',
474
+ value: 'role_list'
475
+ });
476
+ aoData.push({
477
+ name: '_ajax_nonce',
478
+ value: aamLocal.nonce
479
+ });
480
+ },
481
+ fnInitComplete: function() {
482
+ var add = jQuery('<a/>', {
483
+ 'href': '#',
484
+ 'class': 'role-top-action role-top-action-add',
485
+ 'tooltip': aamLocal.labels['Add New Role']
486
+ }).bind('click', function(event) {
487
+ event.preventDefault();
488
+ _this.launch(jQuery(this), 'role-top-action-add');
489
+ _this.launchAddRoleDialog(this);
490
+ });
491
+ jQuery('#role_list_wrapper .role-top-actions').append(add);
492
+ _this.initTooltip(jQuery('#role_list_wrapper .role-top-actions'));
493
+ },
494
+ fnDrawCallback: function() {
495
+ jQuery('#role_list_wrapper .clear-table-filter').bind('click', function(event) {
496
+ event.preventDefault();
497
+ jQuery('#role_list_filter input').val('');
498
+ _this.segmentTables.roleList.fnFilter('');
499
+ });
500
+ },
501
+ oLanguage: {
502
+ sSearch: "",
503
+ oPaginate: {
504
+ sFirst: "&Lt;",
505
+ sLast: "&Gt;",
506
+ sNext: "&gt;",
507
+ sPrevious: "&lt;"
508
+ }
509
+ },
510
+ aoColumnDefs: [
511
+ {
512
+ bVisible: false,
513
+ aTargets: [0, 1]
514
+ }
515
+ ],
516
+ fnRowCallback: function(nRow, aData) { //format data
517
+ jQuery('td:eq(1)', nRow).html(jQuery('<div/>', {
518
+ 'class': 'role-actions'
519
+ })); //
520
+ //add role attribute
521
+ jQuery(nRow).attr('role', aData[0]);
522
+
523
+ jQuery('.role-actions', nRow).empty();
524
+ jQuery('.role-actions', nRow).append(jQuery('<a/>', {
525
+ 'href': '#',
526
+ 'class': 'role-action role-action-manage',
527
+ 'tooltip': aamLocal.labels['Manage']
528
+ }).bind('click', {
529
+ role: aData[0]
530
+ }, function(event) {
531
+ event.preventDefault();
532
+ _this.setSubject('role', event.data.role);
533
+ _this.userRoleFilter = event.data.role;
534
+ _this.retrieveSettings();
535
+ _this.setCurrent('role', nRow, aData[2]);
536
+ if (_this.segmentTables.userList !== null) {
537
+ _this.segmentTables.userList.fnDraw();
538
+ }
539
+ }));
540
+
541
+ jQuery('.role-actions', nRow).append(jQuery('<a/>', {
542
+ 'href': '#',
543
+ 'class': 'role-action role-action-edit',
544
+ 'tooltip': aamLocal.labels['Edit']
545
+ }).bind('click', function(event) {
546
+ event.preventDefault();
547
+ _this.launch(jQuery(this), 'role-action-edit');
548
+ _this.launchEditRoleDialog(this, aData);
549
+ }));
550
+
551
+ jQuery('.role-actions', nRow).append(jQuery('<a/>', {
552
+ 'href': '#',
553
+ 'class': 'role-action role-action-delete',
554
+ 'tooltip': aamLocal.labels['Delete']
555
+ }).bind('click', function(event) {
556
+ event.preventDefault();
557
+ if ((aData[0] === 'administrator')) {
558
+ //open the dialog
559
+ var buttons = {};
560
+ buttons[aamLocal.labels['Close']] = function() {
561
+ jQuery('#delete_admin_role_dialog').dialog("close");
562
+ };
563
+ jQuery('#delete_admin_role_dialog').dialog({
564
+ resizable: false,
565
+ height: 'auto',
566
+ width: '25%',
567
+ modal: true,
568
+ buttons: buttons
569
+ });
570
+ } else {
571
+ _this.launch(jQuery(this), 'role-action-delete');
572
+ _this.launchDeleteRoleDialog(this, aData);
573
+ }
574
+ }));
575
+
576
+ //set active
577
+ if (_this.getSubject().type === 'role'
578
+ && _this.getSubject().id === aData[0]) {
579
+ _this.setCurrent('role', nRow, aData[2]);
580
+ }
581
+
582
+ _this.initTooltip(nRow);
583
+ },
584
+ fnInfoCallback: function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
585
+ return (iMax !== iTotal ? _this.clearFilterIndicator() : '');
586
+ }
587
+ });
588
+ }
589
+ };
590
+
591
+ /**
592
+ * Highlight current subject
593
+ *
594
+ * @param {String} subject
595
+ * @param {Object} nRow
596
+ * @param {String} name
597
+ *
598
+ * @returns {void}
599
+ *
600
+ * @access public
601
+ */
602
+ AAM.prototype.setCurrent = function(subject, nRow, name) {
603
+ var _this = this;
604
+
605
+ //terminate any active subject
606
+ jQuery('.user-action-manage-active').each(function() {
607
+ _this.terminate(jQuery(this), 'user-action-manage');
608
+ });
609
+ jQuery('.role-action-manage-active').each(function() {
610
+ _this.terminate(jQuery(this), 'role-action-manage');
611
+ });
612
+ jQuery('.aam-bold').each(function() {
613
+ jQuery(this).removeClass('aam-bold');
614
+ });
615
+
616
+ //highlight the row
617
+ jQuery('td:eq(0)', nRow).addClass('aam-bold');
618
+ _this.launch(
619
+ jQuery('.' + subject + '-action-manage', nRow),
620
+ subject + '-action-manage'
621
+ );
622
+ jQuery('.current-subject').html(subject + ' ' + name);
623
+ };
624
+
625
+ /**
626
+ * Generate clear filter indicator for all tables
627
+ *
628
+ * @returns {String}
629
+ *
630
+ * @access public
631
+ */
632
+ AAM.prototype.clearFilterIndicator = function() {
633
+ var info = '<div class="table-filtered">';
634
+ info += aamLocal.labels['Filtered'] + '. ';
635
+ info += '<a href="#" class="clear-table-filter">';
636
+ info += aamLocal.labels['Clear'] + '.</a></div>';
637
+
638
+ return info;
639
+ };
640
+
641
+ /**
642
+ * Launch Add Role Dialog
643
+ *
644
+ * @param {Object} button
645
+ *
646
+ * @returns {void}
647
+ *
648
+ * @access public
649
+ */
650
+ AAM.prototype.launchAddRoleDialog = function(button) {
651
+ var _this = this;
652
+ //clean-up the form first
653
+ jQuery('#role_name').val('');
654
+ //open the dialog
655
+ var buttons = {};
656
+ buttons[aamLocal.labels['Add New Role']] = function() {
657
+ //prepare ajax package
658
+ var data = _this.compileAjaxPackage('add_role');
659
+ data.name = jQuery('#role_name').val();
660
+
661
+ //send the request
662
+ jQuery.ajax(aamLocal.ajaxurl, {
663
+ type: 'POST',
664
+ dataType: 'json',
665
+ data: data,
666
+ success: function(response) {
667
+ if (response.status === 'success') {
668
+ _this.segmentTables.roleList.fnDraw();
669
+ }
670
+ _this.highlight('#control_manager .inside', response.status);
671
+ }
672
+ });
673
+ jQuery('#manage_role_dialog').dialog("close");
674
+ };
675
+ buttons[aamLocal.labels['Cancel']] = function() {
676
+ jQuery('#manage_role_dialog').dialog("close");
677
+ };
678
+
679
+ jQuery('#manage_role_dialog').dialog({
680
+ resizable: false,
681
+ height: 'auto',
682
+ width: '30%',
683
+ modal: true,
684
+ title: aamLocal.labels['Add New Role'],
685
+ buttons: buttons,
686
+ close: function() {
687
+ _this.terminate(jQuery(button), 'role-top-action-add');
688
+ }
689
+ });
690
+ };
691
+
692
+ /**
693
+ * Launch Edit Role Dialog
694
+ *
695
+ * @param {Object} button
696
+ * @param {Object} aData
697
+ *
698
+ * @returns {void}
699
+ *
700
+ * @access public
701
+ */
702
+ AAM.prototype.launchEditRoleDialog = function(button, aData) {
703
+ var _this = this;
704
+ //populate the form with data
705
+ jQuery('#role_name').val(aData[2]);
706
+ //launch the dialog
707
+ var buttons = {};
708
+ buttons[aamLocal.labels['Save Changes']] = function() {
709
+ var data = _this.compileAjaxPackage('edit_role');
710
+ data.subject = 'role';
711
+ data.subject_id = aData[0];
712
+ data.name = jQuery('#role_name').val();
713
+ //save the changes
714
+ jQuery.ajax(aamLocal.ajaxurl, {
715
+ type: 'POST',
716
+ dataType: 'json',
717
+ data: data,
718
+ success: function(response) {
719
+ if (response.status === 'success') {
720
+ _this.segmentTables.roleList.fnDraw();
721
+ }
722
+ _this.highlight('#control_manager .inside', response.status);
723
+ },
724
+ error: function() {
725
+ _this.highlight('#control_manager .inside', 'failure');
726
+ },
727
+ complete: function() {
728
+ jQuery('#manage_role_dialog').dialog("close");
729
+ }
730
+ });
731
+ };
732
+ buttons[aamLocal.labels['Cancel']] = function() {
733
+ jQuery('#manage_role_dialog').dialog("close");
734
+ };
735
+
736
+ jQuery('#manage_role_dialog').dialog({
737
+ resizable: false,
738
+ height: 'auto',
739
+ modal: true,
740
+ width: '30%',
741
+ title: aamLocal.labels['Edit Role'],
742
+ buttons: buttons,
743
+ close: function() {
744
+ _this.terminate(jQuery(button), 'role-action-edit');
745
+ }
746
+ });
747
+ };
748
+
749
+ /**
750
+ * Launch Delete Role Dialog
751
+ *
752
+ * @param {Object} button
753
+ * @param {Object} aData
754
+ *
755
+ * @returns {void}
756
+ *
757
+ * @access public
758
+ */
759
+ AAM.prototype.launchDeleteRoleDialog = function(button, aData) {
760
+ var _this = this;
761
+ //render the message first
762
+ if (aData[1]) {
763
+ var message = aamLocal.labels['Delete Role with Users Message'].replace(
764
+ '%d', aData[1]
765
+ );
766
+ message = message.replace('%s', aData[2]);
767
+ jQuery('#delete_role_dialog .dialog-content').html(message);
768
+ } else {
769
+ message = aamLocal.labels['Delete Role Message'].replace('%s', aData[2]);
770
+ jQuery('#delete_role_dialog .dialog-content').html(message);
771
+ }
772
+
773
+ var buttons = {};
774
+ buttons[aamLocal.labels['Delete Role']] = function() {
775
+ //prepare ajax package
776
+ var data = _this.compileAjaxPackage('delete_role');
777
+ data.subject = 'role';
778
+ data.subject_id = aData[0];
779
+ data.delete_users = aData[1];
780
+ //send the request
781
+ jQuery.ajax(aamLocal.ajaxurl, {
782
+ type: 'POST',
783
+ dataType: 'json',
784
+ data: data,
785
+ success: function(response) {
786
+ if (response.status === 'success') {
787
+ //reset the current role
788
+ var subject = _this.getSubject();
789
+ if (subject.type === 'role' && subject.id === aData[0]) {
790
+ _this.setSubject('role', null);
791
+ }
792
+ _this.segmentTables.roleList.fnDraw();
793
+ }
794
+ _this.highlight('#control_manager .inside', response.status);
795
+ },
796
+ error: function() {
797
+ _this.highlight('#control_manager .inside', 'failure');
798
+ },
799
+ complete: function() {
800
+ jQuery('#delete_role_dialog').dialog("close");
801
+ }
802
+ });
803
+ };
804
+ buttons[aamLocal.labels['Cancel']] = function() {
805
+ jQuery('#delete_role_dialog').dialog("close");
806
+ };
807
+
808
+ //launch the dialog
809
+ jQuery('#delete_role_dialog').dialog({
810
+ resizable: false,
811
+ height: 'auto',
812
+ modal: true,
813
+ title: aamLocal.labels['Delete Role'],
814
+ buttons: buttons,
815
+ close: function() {
816
+ _this.terminate(jQuery(button), 'role-action-delete');
817
+ }
818
+ });
819
+ };
820
+
821
+ /**
822
+ * Initialize & Load User Segment
823
+ *
824
+ * @returns {void}
825
+ *
826
+ * @access public
827
+ */
828
+ AAM.prototype.loadUserSegment = function() {
829
+ var _this = this;
830
+ jQuery('#user_manager_wrap').show();
831
+ if (this.segmentTables.userList === null) {
832
+ this.segmentTables.userList = jQuery('#user_list').dataTable({
833
+ sDom: "<'top'f<'user-top-actions'><'clear'>>t<'footer'ip<'clear'>>",
834
+ bServerSide: true,
835
+ sPaginationType: "full_numbers",
836
+ bAutoWidth: false,
837
+ bSort: false,
838
+ sAjaxSource: true,
839
+ fnServerData: function(sSource, aoData, fnCallback, oSettings) {
840
+ oSettings.jqXHR = jQuery.ajax({
841
+ "dataType": 'json',
842
+ "type": "POST",
843
+ "url": aamLocal.ajaxurl,
844
+ "data": aoData,
845
+ "success": fnCallback
846
+ });
847
+ },
848
+ fnServerParams: function(aoData) {
849
+ aoData.push({
850
+ name: 'action',
851
+ value: 'aam'
852
+ });
853
+ aoData.push({
854
+ name: 'sub_action',
855
+ value: 'user_list'
856
+ });
857
+ aoData.push({
858
+ name: '_ajax_nonce',
859
+ value: aamLocal.nonce
860
+ });
861
+ aoData.push({
862
+ name: 'role',
863
+ value: _this.userRoleFilter
864
+ });
865
+ },
866
+ aoColumnDefs: [
867
+ {
868
+ bVisible: false,
869
+ aTargets: [0, 1, 4]
870
+ }
871
+ ],
872
+ fnInitComplete: function() {
873
+ var add = jQuery('<a/>', {
874
+ 'href': aamLocal.addUserURI,
875
+ 'target': '_blank',
876
+ 'class': 'user-top-action user-top-action-add',
877
+ 'tooltip': aamLocal.labels['Add User']
878
+ });
879
+
880
+ var filter = jQuery('<a/>', {
881
+ 'href': '#',
882
+ 'class': 'user-top-action user-top-action-filter',
883
+ 'tooltip': aamLocal.labels['Filter Users']
884
+ }).bind('click', function(event) {
885
+ event.preventDefault();
886
+ _this.launch(jQuery(this), 'user-top-action-filter');
887
+ _this.launchFilterUserDialog(this);
888
+ });
889
+
890
+ var refresh = jQuery('<a/>', {
891
+ 'href': '#',
892
+ 'class': 'user-top-action user-top-action-refresh',
893
+ 'tooltip': aamLocal.labels['Refresh List']
894
+ }).bind('click', function(event) {
895
+ event.preventDefault();
896
+ _this.segmentTables.userList.fnDraw();
897
+ });
898
+
899
+ jQuery('#user_list_wrapper .user-top-actions').append(filter);
900
+ jQuery('#user_list_wrapper .user-top-actions').append(add);
901
+ jQuery('#user_list_wrapper .user-top-actions').append(refresh);
902
+ _this.initTooltip(jQuery('#user_list_wrapper .user-top-actions'));
903
+ },
904
+ fnDrawCallback: function() {
905
+ jQuery('#user_list_wrapper .clear-table-filter').bind('click', function(event) {
906
+ event.preventDefault();
907
+ jQuery('#user_list_filter input').val('');
908
+ _this.userRoleFilter = '';
909
+ _this.segmentTables.userList.fnFilter('');
910
+ });
911
+ },
912
+ oLanguage: {
913
+ sSearch: "",
914
+ oPaginate: {
915
+ sFirst: "&Lt;",
916
+ sLast: "&Gt;",
917
+ sNext: "&gt;",
918
+ sPrevious: "&lt;"
919
+ }
920
+ },
921
+ fnRowCallback: function(nRow, aData, iDisplayIndex) { //format data
922
+ //add User attribute
923
+ jQuery(nRow).attr('user', aData[0]);
924
+ jQuery('td:eq(1)', nRow).html(jQuery('<div/>', {
925
+ 'class': 'user-actions'
926
+ }));
927
+
928
+ jQuery('.user-actions', nRow).append(jQuery('<a/>', {
929
+ 'href': '#',
930
+ 'class': 'user-action user-action-manage',
931
+ 'tooltip': aamLocal.labels['Manager']
932
+ }).bind('click', function(event) {
933
+ event.preventDefault();
934
+ _this.setSubject('user', aData[0]);
935
+ _this.retrieveSettings();
936
+ _this.setCurrent('user', nRow, aData[2]);
937
+ }));
938
+
939
+ jQuery('.user-actions', nRow).append(jQuery('<a/>', {
940
+ 'href': aamLocal.editUserURI + '?user_id=' + aData[0],
941
+ 'target': '_blank',
942
+ 'class': 'user-action user-action-edit',
943
+ 'tooltip': aamLocal.labels['Edit']
944
+ }));
945
+
946
+ var status = (aData[4] === '1' ? 'user-action-block-active' : 'user-action-block');
947
+ jQuery('.user-actions', nRow).append(jQuery('<a/>', {
948
+ 'href': '#',
949
+ 'class': 'user-action ' + status,
950
+ 'tooltip': aamLocal.labels['Block']
951
+ }).bind('click', function(event) {
952
+ event.preventDefault();
953
+ _this.blockUser(this, aData);
954
+ }));
955
+
956
+ jQuery('.user-actions', nRow).append(jQuery('<a/>', {
957
+ 'href': '#',
958
+ 'class': 'user-action user-action-delete',
959
+ 'tooltip': aamLocal.labels['Delete']
960
+ }).bind('click', function(event) {
961
+ event.preventDefault();
962
+ _this.launch(jQuery(this), 'user-action-delete');
963
+ _this.deleteUser(this, aData);
964
+ }));
965
+
966
+ //set active
967
+ if (_this.getSubject().type === 'user'
968
+ && _this.getSubject().id === aData[0]) {
969
+ _this.setCurrent('user', nRow, aData[2]);
970
+ }
971
+
972
+ _this.initTooltip(nRow);
973
+ },
974
+ fnInfoCallback: function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
975
+ return (iMax !== iTotal ? _this.clearFilterIndicator() : '');
976
+ }
977
+ });
978
+ }
979
+ };
980
+
981
+ /**
982
+ * Block the selected user
983
+ *
984
+ * @param {Object} button
985
+ * @param {Object} aData
986
+ *
987
+ * @returns {void}
988
+ *
989
+ * @access public
990
+ */
991
+ AAM.prototype.blockUser = function(button, aData) {
992
+ var _this = this;
993
+ var data = this.compileAjaxPackage('block_user');
994
+ data.subject = 'user';
995
+ data.subject_id = aData[0];
996
+ //send the request
997
+ jQuery.ajax(aamLocal.ajaxurl, {
998
+ type: 'POST',
999
+ dataType: 'json',
1000
+ data: data,
1001
+ success: function(response) {
1002
+ _this.highlight('#control_manager .inside', response.status);
1003
+ if (response.user_status === 1) {
1004
+ _this.launch(jQuery(button), 'user-action-block');
1005
+ } else {
1006
+ _this.terminate(jQuery(button), 'user-action-block');
1007
+ }
1008
+ },
1009
+ error: function() {
1010
+ _this.highlight('#control_manager .inside', 'failure');
1011
+ }
1012
+ });
1013
+ };
1014
+
1015
+ /**
1016
+ * Delete selected User
1017
+ *
1018
+ * @param {Object} button
1019
+ * @param {Object} aData
1020
+ *
1021
+ * @returns {void}
1022
+ *
1023
+ * @access public
1024
+ */
1025
+ AAM.prototype.deleteUser = function(button, aData) {
1026
+ var _this = this;
1027
+ //insert content
1028
+ jQuery('#delete_user_dialog .dialog-content').html(
1029
+ aamLocal.labels['Delete User Message'].replace('%s', aData[2])
1030
+ );
1031
+ var buttons = {};
1032
+ buttons[aamLocal.labels['Delete']] = function() {
1033
+ var data = _this.compileAjaxPackage('delete_user');
1034
+ data.subject = 'user';
1035
+ data.subject_id = aData[0];
1036
+ //send request
1037
+ jQuery.ajax(aamLocal.ajaxurl, {
1038
+ type: 'POST',
1039
+ dataType: 'json',
1040
+ data: data,
1041
+ success: function(response) {
1042
+ if (response.status === 'success') {
1043
+ _this.segmentTables.userList.fnDraw();
1044
+ }
1045
+ _this.highlight('#control_manager .inside', response.status);
1046
+
1047
+ },
1048
+ error: function() {
1049
+ _this.highlight('#control_manager .inside', 'failure');
1050
+ },
1051
+ complete: function() {
1052
+ jQuery('#delete_user_dialog').dialog('close');
1053
+ }
1054
+ });
1055
+ };
1056
+
1057
+ buttons[aamLocal.labels['Cancel']] = function() {
1058
+ jQuery('#delete_user_dialog').dialog("close");
1059
+ };
1060
+ //show the dialog
1061
+ jQuery('#delete_user_dialog').dialog({
1062
+ resizable: false,
1063
+ height: 'auto',
1064
+ width: '30%',
1065
+ modal: true,
1066
+ buttons: buttons,
1067
+ close: function() {
1068
+ _this.terminate(jQuery(button), 'user-action-delete');
1069
+ }
1070
+ });
1071
+ };
1072
+
1073
+ /**
1074
+ * Launch the Filter User List by User Role dialog
1075
+ *
1076
+ * @param {Object} button
1077
+ *
1078
+ * @returns {void}
1079
+ *
1080
+ * @access public
1081
+ */
1082
+ AAM.prototype.launchFilterUserDialog = function(button) {
1083
+ var _this = this;
1084
+ if (this.blogTables.filterRoleList === null) {
1085
+ this.blogTables.filterRoleList = jQuery('#filter_role_list').dataTable({
1086
+ sDom: "<'top'f<'clear'>>t<'footer'ip<'clear'>>",
1087
+ bServerSide: true,
1088
+ sPaginationType: "full_numbers",
1089
+ bAutoWidth: false,
1090
+ bSort: false,
1091
+ sAjaxSource: true,
1092
+ fnServerData: function(sSource, aoData, fnCallback, oSettings) {
1093
+ oSettings.jqXHR = jQuery.ajax({
1094
+ "dataType": 'json',
1095
+ "type": "POST",
1096
+ "url": aamLocal.ajaxurl,
1097
+ "data": aoData,
1098
+ "success": fnCallback
1099
+ });
1100
+ },
1101
+ fnServerParams: function(aoData) {
1102
+ aoData.push({
1103
+ name: 'action',
1104
+ value: 'aam'
1105
+ });
1106
+ aoData.push({
1107
+ name: 'sub_action',
1108
+ value: 'role_list'
1109
+ });
1110
+ aoData.push({
1111
+ name: '_ajax_nonce',
1112
+ value: aamLocal.nonce
1113
+ });
1114
+ },
1115
+ fnDrawCallback: function() {
1116
+ jQuery('#filter_role_list_wrapper .clear-table-filter').bind('click', function(event) {
1117
+ event.preventDefault();
1118
+ jQuery('#filter_role_list_filter input').val('');
1119
+ _this.blogTables.filterRoleList.fnFilter('');
1120
+ });
1121
+ _this.initTooltip('#filter_role_list_wrapper');
1122
+ },
1123
+ oLanguage: {
1124
+ sSearch: "",
1125
+ oPaginate: {
1126
+ sFirst: "&Lt;",
1127
+ sLast: "&Gt;",
1128
+ sNext: "&gt;",
1129
+ sPrevious: "&lt;"
1130
+ }
1131
+ },
1132
+ aoColumnDefs: [
1133
+ {
1134
+ bVisible: false,
1135
+ aTargets: [0, 1]
1136
+ }
1137
+ ],
1138
+ fnRowCallback: function(nRow, aData) { //format data
1139
+ jQuery('td:eq(1)', nRow).html(jQuery('<div/>', {
1140
+ 'class': 'user-actions'
1141
+ }));
1142
+
1143
+ jQuery('.user-actions', nRow).empty();
1144
+ jQuery('.user-actions', nRow).append(jQuery('<a/>', {
1145
+ 'href': '#',
1146
+ 'class': 'user-action user-action-select',
1147
+ 'tooltip': 'Select Role'
1148
+ }).bind('click', function(event) {
1149
+ event.preventDefault();
1150
+ _this.userRoleFilter = aData[0];
1151
+ _this.segmentTables.userList.fnDraw();
1152
+ jQuery('#filter_user_dialog').dialog('close');
1153
+ }));
1154
+ },
1155
+ fnInfoCallback: function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
1156
+ return (iMax !== iTotal ? _this.clearFilterIndicator() : '');
1157
+ }
1158
+ });
1159
+ } else {
1160
+ this.blogTables.filterRoleList.fnDraw();
1161
+ }
1162
+ //show the dialog
1163
+ var buttons = {};
1164
+ buttons[aamLocal.labels['Cancel']] = function() {
1165
+ jQuery('#filter_user_dialog').dialog("close");
1166
+ };
1167
+ jQuery('#filter_user_dialog').dialog({
1168
+ resizable: false,
1169
+ height: 'auto',
1170
+ width: '40%',
1171
+ modal: true,
1172
+ buttons: buttons,
1173
+ close: function() {
1174
+ _this.terminate(jQuery(button), 'user-top-action-filter');
1175
+ }
1176
+ });
1177
+ };
1178
+
1179
+ /**
1180
+ * Initialize & Load visitor segment
1181
+ *
1182
+ * @returns {void}
1183
+ *
1184
+ * @access public
1185
+ */
1186
+ AAM.prototype.loadVisitorSegment = function() {
1187
+ jQuery('#visitor_manager_wrap').show();
1188
+ this.setSubject('visitor', 1);
1189
+ this.setCurrent('Visitor', '', '');
1190
+ this.retrieveSettings();
1191
+ };
1192
+
1193
+ /**
1194
+ * Retrieve main metabox settings
1195
+ *
1196
+ * @returns {void}
1197
+ *
1198
+ * @access public
1199
+ */
1200
+ AAM.prototype.retrieveSettings = function() {
1201
+ var _this = this;
1202
+
1203
+ jQuery('.aam-main-loader').show();
1204
+ jQuery('.aam-main-content').empty();
1205
+
1206
+ jQuery.ajax(aamLocal.siteURI, {
1207
+ type: 'POST',
1208
+ dataType: 'html',
1209
+ data: {
1210
+ action: 'features',
1211
+ _ajax_nonce: aamLocal.nonce,
1212
+ subject: _this.getSubject().type,
1213
+ subject_id: _this.getSubject().id
1214
+ },
1215
+ success: function(response) {
1216
+ jQuery('.aam-main-content').html(response);
1217
+ _this.initSettings();
1218
+ _this.checkRoleback();
1219
+ },
1220
+ complete: function() {
1221
+ jQuery('.aam-main-loader').hide();
1222
+ }
1223
+ });
1224
+ };
1225
+
1226
+ /**
1227
+ * Check if current subject has roleback available
1228
+ *
1229
+ * @returns {undefined}
1230
+ */
1231
+ AAM.prototype.checkRoleback = function() {
1232
+ var _this = this;
1233
+
1234
+ jQuery.ajax(aamLocal.ajaxurl, {
1235
+ type: 'POST',
1236
+ dataType: 'json',
1237
+ data: _this.compileAjaxPackage('check_roleback', true),
1238
+ success: function(response) {
1239
+ if (response.status === 1) {
1240
+ jQuery('#aam_roleback').show();
1241
+ } else {
1242
+ jQuery('#aam_roleback').hide();
1243
+ }
1244
+ },
1245
+ complete: function() {
1246
+ jQuery('.aam-main-loader').hide();
1247
+ }
1248
+ });
1249
+ };
1250
+
1251
+ /**
1252
+ * Initialize Main metabox settings
1253
+ *
1254
+ * @returns {void}
1255
+ *
1256
+ * @access public
1257
+ */
1258
+ AAM.prototype.initSettings = function() {
1259
+ //remove all dialogs to make sure that there are no confusions
1260
+ jQuery('.ui-dialog').remove();
1261
+
1262
+ //init Settings Menu
1263
+ jQuery('.feature-list .feature-item').each(function() {
1264
+ jQuery(this).bind('click', function() {
1265
+ jQuery('.feature-list .feature-item').removeClass(
1266
+ 'feature-item-active'
1267
+ );
1268
+ jQuery(this).addClass('feature-item-active');
1269
+ jQuery('.feature-content .feature-content-container').hide();
1270
+ jQuery('#' + jQuery(this).attr('feature') + '_content').show();
1271
+ //hide help content
1272
+ jQuery('.aam-help > span').hide();
1273
+ jQuery('#feature_help_' + jQuery(this).attr('feature')).css(
1274
+ 'display', 'table-cell'
1275
+ );
1276
+ });
1277
+ });
1278
+
1279
+ this.initMenuTab();
1280
+ this.initMetaboxTab();
1281
+ this.initCapabilityTab();
1282
+ this.initPostTab();
1283
+ this.initEventTab();
1284
+ this.initConfigPressTab();
1285
+
1286
+ this.doAction('aam_init_features');
1287
+
1288
+ jQuery('.feature-list .feature-item:eq(0)').trigger('click');
1289
+ };
1290
+
1291
+ /**
1292
+ * Initialize ConfigPress Feature
1293
+ *
1294
+ * @returns {void}
1295
+ *
1296
+ * @access public
1297
+ */
1298
+ AAM.prototype.initConfigPressTab = function() {
1299
+ this.editor = CodeMirror.fromTextArea(document.getElementById("configpress"), {});
1300
+ this.initTooltip('#configpress_content');
1301
+ };
1302
+
1303
+ /**
1304
+ * Initialize Capability Feature
1305
+ *
1306
+ * @returns {void}
1307
+ *
1308
+ * @access public
1309
+ */
1310
+ AAM.prototype.initCapabilityTab = function() {
1311
+ var _this = this;
1312
+
1313
+ //indicator that current user has default capability set. In case he does
1314
+ //not, it will show additional top action - Restore Default Capabilities
1315
+ var userDefault = true;
1316
+
1317
+ this.blogTables.capabilities = jQuery('#capability_list').dataTable({
1318
+ sDom: "<'top'lf<'capability-top-actions'><'clear'>>t<'footer'ip<'clear'>>",
1319
+ sPaginationType: "full_numbers",
1320
+ bAutoWidth: false,
1321
+ bSort: false,
1322
+ bDestroy: true,
1323
+ sAjaxSource: true,
1324
+ fnServerData: function(sSource, aoData, fnCallback) {
1325
+ jQuery.ajax({
1326
+ dataType: 'json',
1327
+ type: "POST",
1328
+ url: aamLocal.ajaxurl,
1329
+ data: aoData,
1330
+ success: function(data) {
1331
+ //set Default Capability set indicator
1332
+ userDefault = parseInt(data.aaDefault);
1333
+ //populate oTable
1334
+ fnCallback(data);
1335
+ },
1336
+ error: function() {
1337
+ _this.parent.failure();
1338
+ }
1339
+ });
1340
+ },
1341
+ fnServerParams: function(aoData) {
1342
+ aoData.push({
1343
+ name: 'action',
1344
+ value: 'aam'
1345
+ });
1346
+ aoData.push({
1347
+ name: 'sub_action',
1348
+ value: 'load_capabilities'
1349
+ });
1350
+ aoData.push({
1351
+ name: '_ajax_nonce',
1352
+ value: aamLocal.nonce
1353
+ });
1354
+ aoData.push({
1355
+ name: 'subject',
1356
+ value: _this.getSubject().type
1357
+ });
1358
+ aoData.push({
1359
+ name: 'subject_id',
1360
+ value: _this.getSubject().id
1361
+ });
1362
+ },
1363
+ fnInitComplete: function() {
1364
+ var a = jQuery('#capability_list_wrapper .capability-top-actions');
1365
+
1366
+ var filter = jQuery('<a/>', {
1367
+ 'href': '#',
1368
+ 'class': 'capability-top-action capability-top-action-filter',
1369
+ 'tooltip': aamLocal.labels['Filter Capabilities by Category']
1370
+ }).bind('click', function(event) {
1371
+ event.preventDefault();
1372
+ _this.launch(jQuery(this), 'capability-top-action-filter');
1373
+ _this.launchCapabilityFilterDialog(this);
1374
+ });
1375
+ jQuery(a).append(filter);
1376
+
1377
+ //do not allow for user to add any new capabilities or copy from
1378
+ //existing role
1379
+ if (_this.getSubject().type !== 'user') {
1380
+ var copy = jQuery('<a/>', {
1381
+ 'href': '#',
1382
+ 'class': 'capability-top-action capability-top-action-copy',
1383
+ 'tooltip': aamLocal.labels['Inherit Capabilities']
1384
+ }).bind('click', function(event) {
1385
+ event.preventDefault();
1386
+ _this.launch(jQuery(this), 'capability-top-action-copy');
1387
+ _this.launchRoleCopyDialog(this);
1388
+ });
1389
+
1390
+ var add = jQuery('<a/>', {
1391
+ 'href': '#',
1392
+ 'class': 'capability-top-action capability-top-action-add',
1393
+ 'tooltip': aamLocal.labels['Add New Capability']
1394
+ }).bind('click', function(event) {
1395
+ event.preventDefault();
1396
+ _this.launch(jQuery(this), 'capability-top-action-add');
1397
+ _this.launchAddCapabilityDialog(this);
1398
+ });
1399
+
1400
+ jQuery(a).append(copy);
1401
+ jQuery(a).append(add);
1402
+ } else if (userDefault === 0) {
1403
+ //add Restore Default Capability button
1404
+ var restore = jQuery('<a/>', {
1405
+ 'href': '#',
1406
+ 'class': 'capability-top-action capability-top-action-restore',
1407
+ 'tooltip': aamLocal.labels['Restore Default Capabilities']
1408
+ }).bind('click', function(event) {
1409
+ event.preventDefault();
1410
+ var data = _this.compileAjaxPackage('restore_capability', true);
1411
+ //show indicator that is running
1412
+ jQuery(this).addClass('capability-top-action-restore-running');
1413
+ jQuery.ajax(aamLocal.ajaxurl, {
1414
+ type: 'POST',
1415
+ dataType: 'json',
1416
+ data: data,
1417
+ success: function(response) {
1418
+ if (response.status === 'success') {
1419
+ _this.retrieveSettings();
1420
+ } else {
1421
+ _this.highlight('#capability_content', 'failure');
1422
+ }
1423
+ },
1424
+ error: function() {
1425
+ _this.highlight('#capability_content', 'failure');
1426
+ }
1427
+ });
1428
+ });
1429
+
1430
+ jQuery(a).append(restore);
1431
+ }
1432
+
1433
+ _this.initTooltip(a);
1434
+ },
1435
+ aoColumnDefs: [
1436
+ {
1437
+ bVisible: false,
1438
+ aTargets: [0, 1]
1439
+ }
1440
+ ],
1441
+ fnRowCallback: function(nRow, aData) {
1442
+ jQuery('td:eq(2)', nRow).empty().append(jQuery('<div/>', {
1443
+ 'class': 'capability-actions'
1444
+ }));
1445
+ var actions = jQuery('.capability-actions', nRow);
1446
+ //add capability checkbox
1447
+ jQuery(actions).append(jQuery('<div/>', {
1448
+ 'class': 'capability-action'
1449
+ }));
1450
+ jQuery('.capability-action', actions).append(jQuery('<input/>', {
1451
+ type: 'checkbox',
1452
+ id: aData[0],
1453
+ checked: (parseInt(aData[1]) === 1 ? true : false),
1454
+ name: 'aam[capability][' + aData[0] + ']'
1455
+ }).bind('change', function() {
1456
+ var status = (jQuery(this).prop('checked') === true ? 1 : 0);
1457
+ _this.blogTables.capabilities.fnUpdate(status, nRow, 1, false);
1458
+ }));
1459
+ jQuery('.capability-action', actions).append(
1460
+ '<label for="' + aData[0] + '"><span></span></label>'
1461
+ );
1462
+ //add capability delete
1463
+ jQuery(actions).append(jQuery('<a/>', {
1464
+ 'href': '#',
1465
+ 'class': 'capability-action capability-action-delete',
1466
+ 'tooltip': aamLocal.labels['Delete']
1467
+ }).bind('click', function(event) {
1468
+ event.preventDefault();
1469
+ _this.launch(jQuery(this), 'capability-action-delete');
1470
+ _this.launchDeleteCapabilityDialog(this, aData, nRow);
1471
+ }));
1472
+ _this.initTooltip(nRow);
1473
+ },
1474
+ fnDrawCallback: function() {
1475
+ jQuery('#capability_list_wrapper .clear-table-filter').bind('click', function(event) {
1476
+ event.preventDefault();
1477
+ jQuery('#capability_list_wrapper input').val('');
1478
+ _this.blogTables.capabilities.fnFilter('');
1479
+ _this.blogTables.capabilities.fnFilter('', 2);
1480
+ });
1481
+ },
1482
+ fnInfoCallback: function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
1483
+ return (iMax !== iTotal ? _this.clearFilterIndicator() : '');
1484
+ },
1485
+ oLanguage: {
1486
+ sSearch: "",
1487
+ oPaginate: {
1488
+ sFirst: "&Lt;",
1489
+ sLast: "&Gt;",
1490
+ sNext: "&gt;",
1491
+ sPrevious: "&lt;"
1492
+ },
1493
+ sLengthMenu: "_MENU_"
1494
+ }
1495
+ });
1496
+ };
1497
+
1498
+ /**
1499
+ * Launch the Delete Capability Dialog
1500
+ *
1501
+ * @param {Object} button
1502
+ * @param {Object} aData
1503
+ *
1504
+ * @returns {void}
1505
+ *
1506
+ * @access public
1507
+ */
1508
+ AAM.prototype.launchDeleteCapabilityDialog = function(button, aData, nRow) {
1509
+ var _this = this;
1510
+ jQuery('#delete_capability .dialog-content').html(
1511
+ aamLocal.labels['Delete Capability Message'].replace('%s', aData[3])
1512
+ );
1513
+ var buttons = {};
1514
+ buttons[aamLocal.labels['Delete Capability']] = function() {
1515
+ var data = _this.compileAjaxPackage('delete_capability');
1516
+ data.capability = aData[0];
1517
+ jQuery.ajax(aamLocal.ajaxurl, {
1518
+ type: 'POST',
1519
+ dataType: 'json',
1520
+ data: data,
1521
+ success: function(response) {
1522
+ if (response.status === 'success') {
1523
+ _this.blogTables.capabilities.fnDeleteRow(nRow);
1524
+ }
1525
+ _this.highlight('#capability_content', response.status);
1526
+ },
1527
+ error: function() {
1528
+ _this.highlight('#capability_content', 'failure');
1529
+ }
1530
+ });
1531
+ jQuery('#delete_capability').dialog("close");
1532
+ };
1533
+ buttons[aamLocal.labels['Cancel']] = function() {
1534
+ jQuery('#delete_capability').dialog("close");
1535
+ };
1536
+
1537
+ jQuery('#delete_capability').dialog({
1538
+ resizable: false,
1539
+ height: 'auto',
1540
+ modal: true,
1541
+ title: aamLocal.labels['Delete Capability'],
1542
+ buttons: buttons,
1543
+ close: function() {
1544
+ _this.terminate(jQuery(button), 'capability-action-delete');
1545
+ }
1546
+ });
1547
+ };
1548
+
1549
+ /**
1550
+ * Launch Capability Filter Dialog
1551
+ *
1552
+ * @param {Object} button
1553
+ *
1554
+ * @returns {void}
1555
+ *
1556
+ * @access public
1557
+ */
1558
+ AAM.prototype.launchCapabilityFilterDialog = function(button) {
1559
+ var _this = this;
1560
+
1561
+ jQuery('#capability_group_list').dataTable({
1562
+ sDom: "t",
1563
+ sPaginationType: "full_numbers",
1564
+ bAutoWidth: false,
1565
+ bSort: false,
1566
+ bDestroy: true,
1567
+ fnRowCallback: function(nRow, aData) {
1568
+ jQuery('.capability-action-select', nRow).bind('click', function(event) {
1569
+ event.preventDefault();
1570
+ _this.blogTables.capabilities.fnFilter(
1571
+ aData[0].replace('&amp;', '&'), 2
1572
+ );
1573
+ jQuery('#filter_capability_dialog').dialog('close');
1574
+ });
1575
+ }
1576
+ });
1577
+ var buttons = {};
1578
+ buttons[aamLocal.labels['Close']] = function() {
1579
+ jQuery('#filter_capability_dialog').dialog("close");
1580
+ };
1581
+ jQuery('#filter_capability_dialog').dialog({
1582
+ resizable: false,
1583
+ height: 'auto',
1584
+ width: '30%',
1585
+ modal: true,
1586
+ buttons: buttons,
1587
+ close: function() {
1588
+ _this.terminate(jQuery(button), 'capability-top-action-filter');
1589
+ }
1590
+ });
1591
+ };
1592
+
1593
+ /**
1594
+ * Launch Capability Role Copy dialog
1595
+ *
1596
+ * @param {Object} button
1597
+ *
1598
+ * @returns {void}
1599
+ *
1600
+ * @access public
1601
+ */
1602
+ AAM.prototype.launchRoleCopyDialog = function(button) {
1603
+ var _this = this;
1604
+
1605
+ this.blogTables.inheritRole = jQuery('#copy_role_list').dataTable({
1606
+ sDom: "<'top'f<'clear'>>t<'footer'ip<'clear'>>",
1607
+ bServerSide: true,
1608
+ sPaginationType: "full_numbers",
1609
+ bAutoWidth: false,
1610
+ bSort: false,
1611
+ bDestroy: true,
1612
+ sAjaxSource: true,
1613
+ fnServerData: function(sSource, aoData, fnCallback, oSettings) {
1614
+ oSettings.jqXHR = jQuery.ajax({
1615
+ "dataType": 'json',
1616
+ "type": "POST",
1617
+ "url": aamLocal.ajaxurl,
1618
+ "data": aoData,
1619
+ "success": fnCallback
1620
+ });
1621
+ },
1622
+ fnServerParams: function(aoData) {
1623
+ aoData.push({
1624
+ name: 'action',
1625
+ value: 'aam'
1626
+ });
1627
+ aoData.push({
1628
+ name: 'sub_action',
1629
+ value: 'role_list'
1630
+ });
1631
+ aoData.push({
1632
+ name: '_ajax_nonce',
1633
+ value: aamLocal.nonce
1634
+ });
1635
+ },
1636
+ fnDrawCallback: function() {
1637
+ jQuery('#copy_role_list_wrapper .clear-table-filter').bind('click', function(event) {
1638
+ event.preventDefault();
1639
+ jQuery('#copy_role_list_filter input').val('');
1640
+ _this.blogTables.inheritRole.fnFilter('');
1641
+ });
1642
+ },
1643
+ oLanguage: {
1644
+ sSearch: "",
1645
+ oPaginate: {
1646
+ sFirst: "&Lt;",
1647
+ sLast: "&Gt;",
1648
+ sNext: "&gt;",
1649
+ sPrevious: "&lt;"
1650
+ }
1651
+ },
1652
+ aoColumnDefs: [
1653
+ {
1654
+ bVisible: false,
1655
+ aTargets: [0, 1]
1656
+ }
1657
+ ],
1658
+ fnRowCallback: function(nRow, aData, iDisplayIndex) { //format data
1659
+ jQuery('td:eq(1)', nRow).html(jQuery('<div/>', {
1660
+ 'class': 'user-actions'
1661
+ })); //
1662
+
1663
+ jQuery('.user-actions', nRow).empty();
1664
+ jQuery('.user-actions', nRow).append(jQuery('<a/>', {
1665
+ 'href': '#',
1666
+ 'class': 'user-action user-action-select',
1667
+ 'title': aamLocal.labels['Select Role']
1668
+ }).bind('click', function(event) {
1669
+ event.preventDefault();
1670
+ _this.showMetaboxLoader('#copy_role_dialog');
1671
+ var data = _this.compileAjaxPackage('role_capabilities');
1672
+ data.subject = 'role';
1673
+ data.subject_id = aData[0];
1674
+ jQuery.ajax(aamLocal.ajaxurl, {
1675
+ type: 'POST',
1676
+ dataType: 'json',
1677
+ data: data,
1678
+ success: function(response) {
1679
+ if (response.status === 'success') {
1680
+ //reset the capability list
1681
+ var oSettings = _this.blogTables.capabilities.fnSettings();
1682
+ for (var i in oSettings.aoData) {
1683
+ var cap = oSettings.aoData[i]._aData[0];
1684
+ var ntr = oSettings.aoData[i].nTr;
1685
+ if (typeof response.capabilities[cap] !== 'undefined') {
1686
+ _this.blogTables.capabilities.fnUpdate(1, ntr, 1, false);
1687
+ jQuery('#' + cap).attr('checked', 'checked');
1688
+ } else {
1689
+ _this.blogTables.capabilities.fnUpdate(0, ntr, 1, false);
1690
+ jQuery('#' + cap).removeAttr('checked');
1691
+ }
1692
+ }
1693
+ }
1694
+ _this.highlight('#capability_content', response.status);
1695
+ },
1696
+ error: function() {
1697
+ _this.highlight('#capability_content', 'failure');
1698
+ },
1699
+ complete: function() {
1700
+ //grab the capability list for selected role
1701
+ _this.hideMetaboxLoader('#copy_role_dialog');
1702
+ jQuery('#copy_role_dialog').dialog('close');
1703
+ }
1704
+ });
1705
+ }));
1706
+ },
1707
+ fnInfoCallback: function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
1708
+ return (iMax !== iTotal ? _this.clearFilterIndicator() : '');
1709
+ }
1710
+ });
1711
+
1712
+ var buttons = {};
1713
+ buttons[aamLocal.labels['Cancel']] = function() {
1714
+ jQuery('#copy_role_dialog').dialog("close");
1715
+ };
1716
+
1717
+ //show the dialog
1718
+ jQuery('#copy_role_dialog').dialog({
1719
+ resizable: false,
1720
+ height: 'auto',
1721
+ width: '40%',
1722
+ modal: true,
1723
+ buttons: buttons,
1724
+ close: function() {
1725
+ _this.terminate(jQuery(button), 'capability-top-action-copy');
1726
+ }
1727
+ });
1728
+ };
1729
+
1730
+ /**
1731
+ * Launch Add Capability Dialog
1732
+ *
1733
+ * @param {Object} button
1734
+ *
1735
+ * @returns {void}
1736
+ *
1737
+ * @access public
1738
+ */
1739
+ AAM.prototype.launchAddCapabilityDialog = function(button) {
1740
+ var _this = this;
1741
+ //reset form
1742
+ jQuery('#capability_name').val('');
1743
+
1744
+ var buttons = {};
1745
+ buttons[aamLocal.labels['Add Capability']] = function() {
1746
+ var capability = jQuery.trim(jQuery('#capability_name').val());
1747
+ if (capability) {
1748
+ _this.showMetaboxLoader('#capability_form_dialog');
1749
+ var data = _this.compileAjaxPackage('add_capability');
1750
+ data.capability = capability;
1751
+ jQuery.ajax(aamLocal.ajaxurl, {
1752
+ type: 'POST',
1753
+ dataType: 'json',
1754
+ data: data,
1755
+ success: function(response) {
1756
+ if (response.status === 'success') {
1757
+ _this.blogTables.capabilities.fnAddData([
1758
+ response.capability,
1759
+ 1,
1760
+ 'Miscelaneous',
1761
+ data.capability,
1762
+ '']);
1763
+ _this.highlight('#capability_content', 'success');
1764
+ jQuery('#capability_form_dialog').dialog("close");
1765
+ } else {
1766
+ _this.highlight('#capability_form_dialog', 'failure');
1767
+ }
1768
+ },
1769
+ error: function() {
1770
+ _this.highlight('#capability_form_dialog', 'failure');
1771
+ },
1772
+ complete: function() {
1773
+ _this.hideMetaboxLoader('#capability_form_dialog');
1774
+ }
1775
+ });
1776
+ } else {
1777
+ jQuery('#capability_name').effect('highlight', 2000);
1778
+ }
1779
+ };
1780
+ buttons[aamLocal.labels['Cancel']] = function() {
1781
+ jQuery('#capability_form_dialog').dialog("close");
1782
+ };
1783
+
1784
+ //show dialog
1785
+ jQuery('#capability_form_dialog').dialog({
1786
+ resizable: false,
1787
+ height: 'auto',
1788
+ width: '30%',
1789
+ modal: true,
1790
+ buttons: buttons,
1791
+ close: function() {
1792
+ _this.terminate(jQuery(button), 'capability-top-action-add');
1793
+ }
1794
+ });
1795
+ };
1796
+
1797
+ /**
1798
+ * Initialize and Load the Menu Feature
1799
+ *
1800
+ * @returns {void}
1801
+ *
1802
+ * @access public
1803
+ */
1804
+ AAM.prototype.initMenuTab = function() {
1805
+ var _this = this;
1806
+ this.initMenuAccordion(false);
1807
+
1808
+ jQuery('.menu-item-action-restrict').each(function() {
1809
+ jQuery(this).bind('click', function(event) {
1810
+ event.preventDefault();
1811
+ _this.launch(jQuery(this), 'menu-item-action-restrict');
1812
+ });
1813
+ });
1814
+
1815
+ jQuery('.whole_menu').each(function() {
1816
+ jQuery(this).bind('change', function() {
1817
+ if (jQuery(this).attr('checked')) {
1818
+ jQuery('input[type="checkbox"]', '#submenu_' + jQuery(this).attr('id')).attr(
1819
+ 'checked', 'checked'
1820
+ );
1821
+ } else {
1822
+ jQuery('input[type="checkbox"]', '#submenu_' + jQuery(this).attr('id')).removeAttr(
1823
+ 'checked'
1824
+ );
1825
+ }
1826
+ });
1827
+ });
1828
+
1829
+ this.initTooltip('#main_menu_list');
1830
+ };
1831
+
1832
+ /**
1833
+ * Init Main Menu Accordion
1834
+ *
1835
+ * @returns {void}
1836
+ *
1837
+ * @access public
1838
+ */
1839
+ AAM.prototype.initMenuAccordion = function() {
1840
+ //destroy if already initialized
1841
+ if (jQuery('#main_menu_list').hasClass('ui-accordion')) {
1842
+ jQuery('#main_menu_list').accordion('destroy');
1843
+ }
1844
+
1845
+ //initialize
1846
+ jQuery('#main_menu_list').accordion({
1847
+ collapsible: true,
1848
+ header: 'h4',
1849
+ heightStyle: 'content',
1850
+ icons: {
1851
+ header: "ui-icon-circle-arrow-e",
1852
+ headerSelected: "ui-icon-circle-arrow-s"
1853
+ },
1854
+ active: false
1855
+ });
1856
+ };
1857
+
1858
+ /**
1859
+ * Initialize and load Metabox Feature
1860
+ *
1861
+ * @returns {void}
1862
+ *
1863
+ * @access public
1864
+ */
1865
+ AAM.prototype.initMetaboxTab = function() {
1866
+ var _this = this;
1867
+
1868
+ jQuery('.metabox-top-action-add').bind('click', function(event) {
1869
+ event.preventDefault();
1870
+ var link = jQuery.trim(jQuery('#metabox_link').val());
1871
+
1872
+ if (link) {
1873
+ //init metaboxes
1874
+ var data = _this.compileAjaxPackage('init_link');
1875
+ data.link = link;
1876
+
1877
+ //send the request
1878
+ jQuery.ajax(aamLocal.ajaxurl, {
1879
+ type: 'POST',
1880
+ dataType: 'json',
1881
+ data: data,
1882
+ success: function(response) {
1883
+ if (response.status === 'success') {
1884
+ jQuery('#metabox_link').val('');
1885
+ _this.loadMetaboxes(0);
1886
+ }
1887
+ _this.highlight('#metabox_content', response.status);
1888
+ },
1889
+ error: function() {
1890
+ _this.highlight('#metabox_content', 'failure');
1891
+ }
1892
+ });
1893
+ } else {
1894
+ jQuery('#metabox_link').effect('highlight', 2000);
1895
+ }
1896
+
1897
+ });
1898
+
1899
+ jQuery('.metabox-top-action-refresh').bind('click', function(event) {
1900
+ event.preventDefault();
1901
+ _this.loadMetaboxes(1);
1902
+ });
1903
+
1904
+ this.initTooltip('.metabox-top-actions');
1905
+
1906
+ this.loadMetaboxes(0);
1907
+ };
1908
+
1909
+ /**
1910
+ * Load Metabox list
1911
+ *
1912
+ * @param {Boolean} refresh
1913
+ *
1914
+ * @returns {void}
1915
+ *
1916
+ * @access public
1917
+ */
1918
+ AAM.prototype.loadMetaboxes = function(refresh) {
1919
+ var _this = this;
1920
+ //init metaboxes
1921
+ var data = this.compileAjaxPackage('load_metaboxes', true);
1922
+ data.refresh = refresh;
1923
+ //show loader and reset the metabox list holder
1924
+ jQuery('#metabox_list_container').empty();
1925
+ this.showMetaboxLoader('#metabox_content');
1926
+ //send the request
1927
+ jQuery.ajax(aamLocal.ajaxurl, {
1928
+ type: 'POST',
1929
+ dataType: 'json',
1930
+ data: data,
1931
+ success: function(response) {
1932
+ jQuery('#metabox_list_container').html(response.content);
1933
+ jQuery('#metabox_list').accordion({
1934
+ collapsible: true,
1935
+ header: 'h4',
1936
+ heightStyle: 'content',
1937
+ icons: {
1938
+ header: "ui-icon-circle-arrow-e",
1939
+ headerSelected: "ui-icon-circle-arrow-s"
1940
+ },
1941
+ active: false
1942
+ });
1943
+ //init Tooltips
1944
+ _this.initTooltip('#metabox_list_container');
1945
+ },
1946
+ error: function() {
1947
+ _this.highlight('#metabox_content', 'failure');
1948
+ },
1949
+ complete: function() {
1950
+ _this.hideMetaboxLoader('#metabox_content');
1951
+ }
1952
+ });
1953
+ };
1954
+
1955
+ /**
1956
+ * Initialize and Load Event Feature
1957
+ *
1958
+ * @returns {void}
1959
+ *
1960
+ * @access public
1961
+ */
1962
+ AAM.prototype.initEventTab = function() {
1963
+ var _this = this;
1964
+
1965
+ jQuery('#event_event').bind('change', function() {
1966
+ if (jQuery(this).val() === 'status_change') {
1967
+ jQuery('#status_changed').show();
1968
+ } else {
1969
+ jQuery('#status_changed').hide();
1970
+ }
1971
+ });
1972
+
1973
+ jQuery('#event_action').bind('change', function() {
1974
+ jQuery('.event-specifier').hide();
1975
+ jQuery('#event_specifier_' + jQuery(this).val() + '_holder').show();
1976
+ });
1977
+
1978
+ this.blogTables.eventList = jQuery('#event_list').dataTable({
1979
+ sDom: "<'event-top-actions'><'clear'>t<'footer'p<'clear'>>",
1980
+ //bProcessing : false,
1981
+ sPaginationType: "full_numbers",
1982
+ bAutoWidth: false,
1983
+ bSort: false,
1984
+ sAjaxSource: true,
1985
+ fnServerData: function(sSource, aoData, fnCallback, oSettings) {
1986
+ oSettings.jqXHR = jQuery.ajax({
1987
+ "dataType": 'json',
1988
+ "type": "POST",
1989
+ "url": aamLocal.ajaxurl,
1990
+ "data": aoData,
1991
+ "success": fnCallback
1992
+ });
1993
+ },
1994
+ fnServerParams: function(aoData) {
1995
+ aoData.push({
1996
+ name: 'action',
1997
+ value: 'aam'
1998
+ });
1999
+ aoData.push({
2000
+ name: 'sub_action',
2001
+ value: 'event_list'
2002
+ });
2003
+ aoData.push({
2004
+ name: '_ajax_nonce',
2005
+ value: aamLocal.nonce
2006
+ });
2007
+ aoData.push({
2008
+ name: 'subject',
2009
+ value: _this.getSubject().type
2010
+ });
2011
+ aoData.push({
2012
+ name: 'subject_id',
2013
+ value: _this.getSubject().id
2014
+ });
2015
+ },
2016
+ aoColumnDefs: [
2017
+ {
2018
+ bVisible: false,
2019
+ aTargets: [1, 4]
2020
+ }
2021
+ ],
2022
+ fnInitComplete: function() {
2023
+ var filter = jQuery('<a/>', {
2024
+ 'href': '#',
2025
+ 'class': 'event-top-action event-top-action-add',
2026
+ 'tooltip': aamLocal.labels['Add Event']
2027
+ }).bind('click', function(event) {
2028
+ event.preventDefault();
2029
+ _this.launch(jQuery(this), 'event-top-action-add');
2030
+ _this.launchManageEventDialog(this, null);
2031
+ });
2032
+ jQuery('#event_list_wrapper .event-top-actions').append(filter);
2033
+ _this.initTooltip(jQuery('#event_list_wrapper .event-top-actions'));
2034
+ },
2035
+ fnDrawCallback: function() {
2036
+ jQuery('#event_list_wrapper .clear-table-filter').bind('click', function(event) {
2037
+ event.preventDefault();
2038
+ jQuery('#event_list_filter input').val('');
2039
+ _this.blogTables.eventList.fnFilter('');
2040
+ });
2041
+ },
2042
+ fnRowCallback: function(nRow, aData) {
2043
+ if (jQuery('.event-actions', nRow).length) {
2044
+ jQuery('.event-actions', nRow).empty();
2045
+ } else {
2046
+ jQuery('td:eq(3)', nRow).html(jQuery('<div/>', {
2047
+ 'class': 'event-actions'
2048
+ }));
2049
+ }
2050
+ jQuery('.event-actions', nRow).append(jQuery('<a/>', {
2051
+ 'href': '#',
2052
+ 'class': 'event-action event-action-edit',
2053
+ 'tooltip': aamLocal.labels['Edit Event']
2054
+ }).bind('click', function(event) {
2055
+ event.preventDefault();
2056
+ _this.launch(jQuery(this), 'event-action-edit');
2057
+ _this.launchManageEventDialog(this, aData, nRow);
2058
+ }));
2059
+ jQuery('.event-actions', nRow).append(jQuery('<a/>', {
2060
+ 'href': '#',
2061
+ 'class': 'event-action event-action-delete',
2062
+ 'tooltip': aamLocal.labels['Delete Event']
2063
+ }).bind('click', function(event) {
2064
+ event.preventDefault();
2065
+ _this.launch(jQuery(this), 'event-action-delete');
2066
+ _this.launchDeleteEventDialog(this, aData, nRow);
2067
+ }));
2068
+
2069
+ _this.initTooltip(nRow);
2070
+
2071
+ //decorate the data in row
2072
+ jQuery('td:eq(0)', nRow).html(
2073
+ jQuery('#event_event option[value="' + aData[0] + '"]').text()
2074
+ );
2075
+ jQuery('td:eq(1)', nRow).html(
2076
+ jQuery('#event_bind option[value="' + aData[2] + '"]').text()
2077
+ );
2078
+ jQuery('td:eq(2)', nRow).html(
2079
+ jQuery('#event_action option[value="' + aData[3] + '"]').text()
2080
+ );
2081
+ },
2082
+ oLanguage: {
2083
+ sSearch: "",
2084
+ oPaginate: {
2085
+ sFirst: "&Lt;",
2086
+ sLast: "&Gt;",
2087
+ sNext: "&gt;",
2088
+ sPrevious: "&lt;"
2089
+ }
2090
+ }
2091
+ });
2092
+ };
2093
+
2094
+ /**
2095
+ * Launch Add/Edit Event Dialog
2096
+ *
2097
+ * @param {Object} button
2098
+ * @param {Object} aData
2099
+ * @param {Object} nRow
2100
+ *
2101
+ * @returns {void}
2102
+ *
2103
+ * @access public
2104
+ */
2105
+ AAM.prototype.launchManageEventDialog = function(button, aData, nRow) {
2106
+ var _this = this;
2107
+
2108
+ //reset form and pre-populate if edit mode
2109
+ jQuery('input, select', '#manage_event_dialog').val('');
2110
+ jQuery('.event-specifier', '#manage_event_dialog').hide();
2111
+ jQuery('#status_changed', '#manage_event_dialog').hide();
2112
+
2113
+ if (aData !== null) {
2114
+ jQuery('#event_event', '#manage_event_dialog').val(aData[0]);
2115
+ jQuery('#event_specifier', '#manage_event_dialog').val(aData[1]);
2116
+ jQuery('#event_bind', '#manage_event_dialog').val(aData[2]);
2117
+ jQuery('#event_action', '#manage_event_dialog').val(aData[3]);
2118
+ jQuery('#event_specifier_' + aData[3], '#manage_event_dialog').val(aData[4]);
2119
+ //TODO - Make this more dynamical
2120
+ jQuery('#event_event', '#manage_event_dialog').trigger('change');
2121
+ jQuery('#event_action', '#manage_event_dialog').trigger('change');
2122
+ }
2123
+
2124
+ var buttons = {};
2125
+ buttons[aamLocal.labels['Save Event']] = function() {
2126
+ //validate first
2127
+ var data = _this.validEvent();
2128
+ if (data !== null) {
2129
+ if (aData !== null) {
2130
+ _this.blogTables.eventList.fnUpdate(data, nRow);
2131
+ } else {
2132
+ _this.blogTables.eventList.fnAddData(data);
2133
+ }
2134
+ jQuery('#manage_event_dialog').dialog("close");
2135
+ } else {
2136
+ jQuery('#manage_event_dialog').effect('highlight', 3000);
2137
+ }
2138
+ };
2139
+ buttons[aamLocal.labels['Close']] = function() {
2140
+ jQuery('#manage_event_dialog').dialog("close");
2141
+ };
2142
+ jQuery('#manage_event_dialog').dialog({
2143
+ resizable: false,
2144
+ height: 'auto',
2145
+ width: '40%',
2146
+ modal: true,
2147
+ buttons: buttons,
2148
+ close: function() {
2149
+ _this.terminate(
2150
+ jQuery(button),
2151
+ (aData ? 'event-action-edit' : 'event-top-action-add')
2152
+ );
2153
+ }
2154
+ });
2155
+ };
2156
+
2157
+ /**
2158
+ * Validate Event Form
2159
+ *
2160
+ * @returns {Boolean}
2161
+ *
2162
+ * @access public
2163
+ */
2164
+ AAM.prototype.validEvent = function() {
2165
+ var data = new Array();
2166
+
2167
+ data.push(jQuery('#event_event').val());
2168
+ data.push(jQuery('#event_specifier').val());
2169
+ data.push(jQuery('#event_bind').val());
2170
+ var action = jQuery('#event_action').val();
2171
+ data.push(action);
2172
+ data.push(jQuery('#event_specifier_' + action).val());
2173
+ data.push('--'); //Event Actions Cell
2174
+
2175
+ return data;
2176
+ };
2177
+
2178
+ /**
2179
+ * Launch Delete Event Dialog
2180
+ *
2181
+ * @param {Object} button
2182
+ * @param {Object} aData
2183
+ * @param {Object} nRow
2184
+ *
2185
+ * @returns {void}
2186
+ *
2187
+ * @access public
2188
+ */
2189
+ AAM.prototype.launchDeleteEventDialog = function(button, aData, nRow) {
2190
+ var _this = this;
2191
+ var buttons = {};
2192
+ buttons[aamLocal.labels['Delete Event']] = function() {
2193
+ _this.blogTables.eventList.fnDeleteRow(nRow);
2194
+ jQuery('#delete_event').dialog("close");
2195
+ };
2196
+ buttons[aamLocal.labels['Cancel']] = function() {
2197
+ jQuery('#delete_event').dialog("close");
2198
+ };
2199
+ jQuery('#delete_event').dialog({
2200
+ resizable: false,
2201
+ height: 'auto',
2202
+ modal: true,
2203
+ title: aamLocal.labels['Delete Event'],
2204
+ buttons: buttons,
2205
+ close: function() {
2206
+ _this.terminate(jQuery(button), 'event-action-delete');
2207
+ }
2208
+ });
2209
+ };
2210
+
2211
+ /**
2212
+ * Initialize and Load Post Feature
2213
+ *
2214
+ * @returns {void}
2215
+ *
2216
+ * @access public
2217
+ */
2218
+ AAM.prototype.initPostTab = function() {
2219
+ var _this = this;
2220
+
2221
+ this.initPostTree();
2222
+
2223
+ jQuery('#sidetreecontrol span').bind('click', function() {
2224
+ jQuery("#tree").replaceWith('<ul id="tree" class="filetree"></ul>');
2225
+ _this.initPostTree();
2226
+ });
2227
+
2228
+ jQuery('.post-access-area').buttonset();
2229
+ jQuery('.post-access-area input', '#access_dialog').each(function() {
2230
+ jQuery(this).bind('click', function() {
2231
+ jQuery('#access_dialog .dataTable').hide();
2232
+ jQuery('#term_access_' + jQuery(this).val()).show();
2233
+ jQuery('#post_access_' + jQuery(this).val()).show();
2234
+ });
2235
+ });
2236
+
2237
+ this.blogTables.postList = jQuery('#post_list').dataTable({
2238
+ sDom: "<'top'lf<'post-top-actions'><'clear'>><'post-breadcrumb'>t<'footer'ip<'clear'>>",
2239
+ sPaginationType: "full_numbers",
2240
+ bAutoWidth: false,
2241
+ bSort: false,
2242
+ bServerSide: true,
2243
+ sAjaxSource: true,
2244
+ fnServerData: function(sSource, aoData, fnCallback, oSettings) {
2245
+ oSettings.jqXHR = jQuery.ajax({
2246
+ "dataType": 'json',
2247
+ "type": "POST",
2248
+ "url": aamLocal.ajaxurl,
2249
+ "data": aoData,
2250
+ "success": fnCallback
2251
+ });
2252
+ },
2253
+ fnServerParams: function(aoData) {
2254
+ aoData.push({
2255
+ name: 'action',
2256
+ value: 'aam'
2257
+ });
2258
+ aoData.push({
2259
+ name: 'sub_action',
2260
+ value: 'post_list'
2261
+ });
2262
+ aoData.push({
2263
+ name: '_ajax_nonce',
2264
+ value: aamLocal.nonce
2265
+ });
2266
+ aoData.push({
2267
+ name: 'term',
2268
+ value: _this.postTerm
2269
+ });
2270
+ },
2271
+ fnInitComplete: function() {
2272
+ var a = jQuery('#post_list_wrapper .post-top-actions');
2273
+
2274
+ var filter = jQuery('<a/>', {
2275
+ 'href': '#',
2276
+ 'class': 'post-top-action post-top-action-filter',
2277
+ 'tooltip': aamLocal.labels['Filter Posts by Post Type']
2278
+ }).bind('click', function(event) {
2279
+ event.preventDefault();
2280
+ _this.launch(jQuery(this), 'post-top-action-filter');
2281
+ _this.launchFilterPostDialog(this);
2282
+ });
2283
+
2284
+ var refresh = jQuery('<a/>', {
2285
+ 'href': '#',
2286
+ 'class': 'post-top-action post-top-action-refresh',
2287
+ 'tooltip': aamLocal.labels['Refresh List']
2288
+ }).bind('click', function(event) {
2289
+ event.preventDefault();
2290
+ _this.blogTables.postList.fnDraw();
2291
+ });
2292
+ jQuery(a).append(filter);
2293
+ jQuery(a).append(refresh);
2294
+ _this.initTooltip(a);
2295
+ },
2296
+ oLanguage: {
2297
+ sSearch: "",
2298
+ oPaginate: {
2299
+ sFirst: "&Lt;",
2300
+ sLast: "&Gt;",
2301
+ sNext: "&gt;",
2302
+ sPrevious: "&lt;"
2303
+ },
2304
+ sLengthMenu: "_MENU_"
2305
+ },
2306
+ aoColumnDefs: [
2307
+ {
2308
+ bVisible: false,
2309
+ aTargets: [0, 1, 2]
2310
+ }
2311
+ ],
2312
+ fnRowCallback: function(nRow, aData, iDisplayIndex) { //format data
2313
+ jQuery('td:eq(0)', nRow).html(jQuery('<a/>', {
2314
+ 'href': "#",
2315
+ 'class': "post-type-post"
2316
+ }).bind('click', function(event) {
2317
+ event.preventDefault();
2318
+ var button = jQuery('.post-action-manage', nRow);
2319
+ _this.launch(button, 'post-action-manage');
2320
+ _this.launchManageAccessDialog(button, nRow, aData, 'post');
2321
+ }).text(aData[3]));
2322
+ jQuery('td:eq(2)', nRow).append(jQuery('<div/>', {
2323
+ 'class': 'post-actions'
2324
+ }));
2325
+
2326
+ jQuery('.post-actions', nRow).append(jQuery('<a/>', {
2327
+ 'href': aData[2].replace('&amp;', '&'),
2328
+ 'class': 'post-action post-action-edit',
2329
+ 'target': '_blank',
2330
+ 'tooltip': aamLocal.labels['Edit']
2331
+ }));
2332
+
2333
+ jQuery('.post-actions', nRow).append(jQuery('<a/>', {
2334
+ 'href': '#',
2335
+ 'class': 'post-action post-action-manage',
2336
+ 'tooltip': aamLocal.labels['Manage Access']
2337
+ }).bind('click', function(event) {
2338
+ event.preventDefault();
2339
+ _this.launch(jQuery(this), 'post-action-manage');
2340
+ _this.launchManageAccessDialog(this, nRow, aData, 'post');
2341
+ }));
2342
+
2343
+ _this.initTooltip(nRow);
2344
+ },
2345
+ fnDrawCallback: function() {
2346
+ jQuery('.post-breadcrumb').addClass('post-breadcrumb-loading');
2347
+ _this.loadBreadcrumb();
2348
+ jQuery('#event_list_wrapper .clear-table-filter').bind('click', function(event) {
2349
+ event.preventDefault();
2350
+ jQuery('#event_list_filter input').val('');
2351
+ _this.blogTables.postList.fnFilter('');
2352
+ });
2353
+ },
2354
+ fnInfoCallback: function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
2355
+ return (iMax !== iTotal ? _this.clearFilterIndicator() : '');
2356
+ }
2357
+ });
2358
+ };
2359
+
2360
+ /**
2361
+ * Launch Filter Post Dialog (Category Tree)
2362
+ *
2363
+ * @param {Object} button
2364
+ *
2365
+ * @returns {void}
2366
+ *
2367
+ * @access public
2368
+ */
2369
+ AAM.prototype.launchFilterPostDialog = function(button) {
2370
+ var _this = this;
2371
+ var buttons = {};
2372
+ buttons[aamLocal.labels['Close']] = function() {
2373
+ jQuery('#filter_post_dialog').dialog("close");
2374
+ };
2375
+ jQuery('#filter_post_dialog').dialog({
2376
+ resizable: false,
2377
+ height: 'auto',
2378
+ width: 'auto',
2379
+ modal: true,
2380
+ buttons: buttons,
2381
+ close: function() {
2382
+ _this.terminate(jQuery(button), 'post-top-action-filter');
2383
+ }
2384
+ });
2385
+ };
2386
+
2387
+ /**
2388
+ * Launch Manage Access Control for selected post
2389
+ *
2390
+ * @param {Object} button
2391
+ * @param {Object} aData
2392
+ * @param {String} type
2393
+ *
2394
+ * @returns {void}
2395
+ *
2396
+ * @access public
2397
+ */
2398
+ AAM.prototype.launchManageAccessDialog = function(button, nRow, aData, type) {
2399
+ var _this = this;
2400
+ //prepare form for view
2401
+ jQuery('.dataTable', '#access_dialog').hide();
2402
+
2403
+ if (type === 'term') {
2404
+ jQuery('#term_access').show();
2405
+ jQuery('#term_access_frontend').show();
2406
+ } else {
2407
+ jQuery('#term_access').hide();
2408
+ }
2409
+
2410
+ //by default show frontend access
2411
+ jQuery('#post_access_frontend').show();
2412
+
2413
+ //reset the Frontend/Backend radio
2414
+ if (jQuery('.post-access-area', '#access_dialog').length) {
2415
+ //in case it is Visitor, this section is not rendered
2416
+ jQuery('.post-access-area input').attr('checked', false);
2417
+ jQuery('.post-access-area #post_area_frontend').attr('checked', true);
2418
+ jQuery('.post-access-area').buttonset('refresh');
2419
+ }
2420
+
2421
+ //reset all checkboxes
2422
+ jQuery('input', '#access_dialog').prop('checked', false);
2423
+
2424
+ //retrieve settings and display the dialog
2425
+ var data = this.compileAjaxPackage('get_access', true);
2426
+ data.id = aData[0];
2427
+ data.type = type;
2428
+
2429
+ jQuery.ajax(aamLocal.ajaxurl, {
2430
+ type: 'POST',
2431
+ dataType: 'json',
2432
+ data: data,
2433
+ success: function(response) {
2434
+ if (type === 'term') {
2435
+ jQuery('.post-access-title').html('All Posts in Term');
2436
+ if (response.counter !== -1) {
2437
+ jQuery('.post-access-block', '#access_dialog').show();
2438
+ }
2439
+ } else {
2440
+ jQuery('.post-access-block', '#access_dialog').hide();
2441
+ jQuery('.post-access-title').html('Post Access');
2442
+ }
2443
+ //populate the form
2444
+ for (var object in response.settings) {
2445
+ for (var area in response.settings[object]) {
2446
+ for (var action in response.settings[object][area]) {
2447
+ var element = '#' + object + '_' + area;
2448
+ element += '_' + action;
2449
+ jQuery(element, '#access_dialog').attr(
2450
+ 'checked',
2451
+ (parseInt(response.settings[object][area][action]) === 1 ? true : false)
2452
+ );
2453
+ }
2454
+ }
2455
+ }
2456
+
2457
+ var buttons = {};
2458
+ buttons[aamLocal.labels['Restore Default']] = function() {
2459
+ //retrieve settings and display the dialog
2460
+ var data = _this.compileAjaxPackage('clear_access', true);
2461
+ data.id = aData[0];
2462
+ data.type = type;
2463
+
2464
+ jQuery.ajax(aamLocal.ajaxurl, {
2465
+ type: 'POST',
2466
+ dataType: 'json',
2467
+ data: data,
2468
+ success: function(response) {
2469
+ _this.highlight(nRow, response.status);
2470
+ },
2471
+ error: function() {
2472
+ _this.highlight(nRow, 'failure');
2473
+ }
2474
+ });
2475
+ jQuery('#access_dialog').dialog("close");
2476
+ };
2477
+
2478
+ if (response.counter <= 5) {
2479
+ buttons[aamLocal.labels['Apply']] = function() {
2480
+ _this.showMetaboxLoader('#access_dialog');
2481
+ var data = _this.compileAjaxPackage('save_access', true);
2482
+ data.id = aData[0];
2483
+ data.type = type;
2484
+
2485
+ jQuery('input', '#access_control_area').each(function() {
2486
+ if (jQuery(this).attr('object')) {
2487
+ var name = 'access[' + jQuery(this).attr('object') + '][';
2488
+ name += jQuery(this).attr('area') + '][';
2489
+ name += jQuery(this).attr('action') + ']';
2490
+ data[name] = (jQuery(this).prop('checked') ? 1 : 0);
2491
+ }
2492
+ });
2493
+
2494
+ jQuery.ajax(aamLocal.ajaxurl, {
2495
+ type: 'POST',
2496
+ dataType: 'json',
2497
+ data: data,
2498
+ success: function(response) {
2499
+ _this.highlight(nRow, response.status);
2500
+ },
2501
+ error: function() {
2502
+ _this.highlight(nRow, 'failure');
2503
+ },
2504
+ complete: function() {
2505
+ _this.hideMetaboxLoader('#access_dialog');
2506
+ }
2507
+ });
2508
+ jQuery('#access_dialog').dialog("close");
2509
+ };
2510
+ jQuery('.aam-lock-message', '#access_dialog').hide();
2511
+ } else {
2512
+ jQuery('.aam-lock-message', '#access_dialog').show();
2513
+ }
2514
+
2515
+ buttons[aamLocal.labels['Close']] = function() {
2516
+ jQuery('#access_dialog').dialog("close");
2517
+ };
2518
+
2519
+ jQuery('#access_dialog').dialog({
2520
+ resizable: false,
2521
+ height: 'auto',
2522
+ width: '25%',
2523
+ modal: true,
2524
+ title: 'Manage Access',
2525
+ buttons: buttons,
2526
+ close: function() {
2527
+ _this.terminate(
2528
+ jQuery(button), 'post-breadcrumb-line-action-manage'
2529
+ );
2530
+ }
2531
+ });
2532
+ },
2533
+ error: function() {
2534
+ _this.highlight(nRow, 'failure');
2535
+ }
2536
+ });
2537
+ };
2538
+
2539
+ /**
2540
+ * Build Post Breadcrumb
2541
+ *
2542
+ * @param {Object} response
2543
+ *
2544
+ * @returns {void}
2545
+ *
2546
+ * @access public
2547
+ */
2548
+ AAM.prototype.buildPostBreadcrumb = function(response) {
2549
+ var _this = this;
2550
+
2551
+ jQuery('.post-breadcrumb').empty();
2552
+ //create a breadcrumb
2553
+ jQuery('.post-breadcrumb').append(jQuery('<div/>', {
2554
+ 'class': 'post-breadcrumb-line'
2555
+ }));
2556
+
2557
+ for (var i in response.breadcrumb) {
2558
+ jQuery('.post-breadcrumb-line').append(jQuery('<a/>', {
2559
+ href: '#'
2560
+ }).bind('click', {
2561
+ term: response.breadcrumb[i][0]
2562
+ }, function(event) {
2563
+ event.preventDefault();
2564
+ _this.postTerm = event.data.term;
2565
+ _this.blogTables.postList.fnDraw();
2566
+ }).html(response.breadcrumb[i][1])).append(jQuery('<span/>', {
2567
+ 'class': 'aam-gt'
2568
+ }).html('&Gt;'));
2569
+ }
2570
+ //deactive last one
2571
+ jQuery('.post-breadcrumb-line a:last').replaceWith(response.breadcrumb[i][1]);
2572
+ jQuery('.post-breadcrumb-line .aam-gt:last').remove();
2573
+
2574
+ jQuery('.post-breadcrumb').append(jQuery('<div/>', {
2575
+ 'class': 'post-breadcrumb-line-actions'
2576
+ }));
2577
+
2578
+ if (/^[\d]+$/.test(this.postTerm)) {
2579
+ jQuery('.post-breadcrumb-line-actions').append(jQuery('<a/>', {
2580
+ 'href': response.link,
2581
+ 'target': '_blank',
2582
+ 'class': 'post-breadcrumb-line-action post-breadcrumb-line-action-edit',
2583
+ 'tooltip': aamLocal.labels['Edit Term']
2584
+ }));
2585
+ jQuery('.post-breadcrumb-line-actions').append(jQuery('<a/>', {
2586
+ 'href': '#',
2587
+ 'class': 'post-breadcrumb-line-action post-breadcrumb-line-action-manage',
2588
+ 'tooltip': aamLocal.labels['Manager Access']
2589
+ }).bind('click', {id: response.breadcrumb[i][0]}, function(event) {
2590
+ event.preventDefault();
2591
+ _this.launch(this, 'post-breadcrumb-line-action-manage');
2592
+ var aData = new Array();
2593
+ aData[0] = event.data.id;
2594
+ _this.launchManageAccessDialog(
2595
+ this, jQuery('.post-breadcrumb'), aData, 'term'
2596
+ );
2597
+ }));
2598
+ } else {
2599
+ jQuery('.post-breadcrumb-line-actions').append(jQuery('<a/>', {
2600
+ 'href': 'http://wpaam.com',
2601
+ 'target': '_blank',
2602
+ 'class': 'post-breadcrumb-line-action post-breadcrumb-line-action-lock',
2603
+ 'tooltip': aamLocal.labels['Unlock Default Accesss Control']
2604
+ }));
2605
+ this.doAction('aam_breadcrumb_action', response);
2606
+ }
2607
+ _this.initTooltip(jQuery('.post-breadcrumb-line-actions'));
2608
+ };
2609
+
2610
+ /**
2611
+ * Load Post Breadcrumb
2612
+ *
2613
+ * @returns {void}
2614
+ *
2615
+ * @access public
2616
+ */
2617
+ AAM.prototype.loadBreadcrumb = function() {
2618
+ var _this = this;
2619
+ var data = this.compileAjaxPackage('post_breadcrumb');
2620
+ data.id = _this.postTerm;
2621
+ //send the request
2622
+ jQuery.ajax(aamLocal.ajaxurl, {
2623
+ type: 'POST',
2624
+ dataType: 'json',
2625
+ data: data,
2626
+ success: function(response) {
2627
+ _this.buildPostBreadcrumb(response);
2628
+ },
2629
+ complete: function() {
2630
+ jQuery('.post-breadcrumb').removeClass('post-breadcrumb-loading');
2631
+ }
2632
+ });
2633
+ };
2634
+
2635
+ /**
2636
+ * Initialize and Load Category Tree
2637
+ *
2638
+ * @returns {void}
2639
+ *
2640
+ * @access public
2641
+ */
2642
+ AAM.prototype.initPostTree = function() {
2643
+ var _this = this;
2644
+
2645
+ var data = this.compileAjaxPackage('post_tree');
2646
+
2647
+ jQuery("#tree").treeview({
2648
+ url: aamLocal.ajaxurl,
2649
+ // add some additional, dynamic data and request with POST
2650
+ ajax: {
2651
+ data: data,
2652
+ type: 'post',
2653
+ complete: function() {
2654
+ jQuery('#tree li').each(function() {
2655
+ var id = jQuery(this).attr('id');
2656
+ if (id && !jQuery(this).attr('active')) {
2657
+ jQuery('.important', this).html(jQuery('<a/>', {
2658
+ href: '#'
2659
+ }).html(jQuery('.important', this).text()).bind('click', {
2660
+ id: id
2661
+ }, function(event) {
2662
+ event.preventDefault();
2663
+ _this.postTerm = event.data.id;
2664
+ _this.blogTables.postList.fnDraw();
2665
+ jQuery('#filter_post_dialog').dialog('close');
2666
+ }));
2667
+ jQuery(this).attr('active', true);
2668
+ }
2669
+ });
2670
+ }
2671
+ },
2672
+ animated: "medium",
2673
+ control: "#sidetreecontrol",
2674
+ persist: "location"
2675
+ });
2676
+ };
2677
+
2678
+ /**
2679
+ * Launch the button
2680
+ *
2681
+ * @param {Object} element
2682
+ * @param {String} inactive
2683
+ *
2684
+ * @returns {void}
2685
+ *
2686
+ * @access public
2687
+ */
2688
+ AAM.prototype.launch = function(element, inactive) {
2689
+ jQuery(element).removeClass(inactive).addClass(inactive + '-active');
2690
+ };
2691
+
2692
+ /**
2693
+ * Terminate the button
2694
+ *
2695
+ * @param {Object} element
2696
+ * @param {String} inactive
2697
+ *
2698
+ * @returns {void}
2699
+ *
2700
+ * @access public
2701
+ */
2702
+ AAM.prototype.terminate = function(element, inactive) {
2703
+ jQuery(element).removeClass(inactive + '-active').addClass(inactive);
2704
+ };
2705
+
2706
+ /**
2707
+ * Highlight the specified DOM area
2708
+ *
2709
+ * @param {String} selector
2710
+ * @param {String} status
2711
+ *
2712
+ * @returns {void}
2713
+ *
2714
+ * @access public
2715
+ */
2716
+ AAM.prototype.highlight = function(selector, status) {
2717
+ if (status === 'success') {
2718
+ jQuery(selector).effect("highlight", {
2719
+ color: '#98CE90'
2720
+ }, 3000);
2721
+ } else {
2722
+ jQuery(selector).effect("highlight", {
2723
+ color: '#FFAAAA'
2724
+ }, 3000);
2725
+ }
2726
+ };
2727
+
2728
+ /**
2729
+ * Grab and build Role Select dropdown
2730
+ *
2731
+ * @param {String} selector
2732
+ * @param {String} selected
2733
+ *
2734
+ * @returns {void}
2735
+ *
2736
+ * @access public
2737
+ */
2738
+ AAM.prototype.renderRoleSelectList = function(selector, selected) {
2739
+ var _this = this;
2740
+ //load Role list
2741
+ jQuery(selector).removeClass('dialog-input').addClass('dialog-input-dynamic').empty();
2742
+ var data = this.compileAjaxPackage('role_list');
2743
+ jQuery.ajax(aamLocal.ajaxurl, {
2744
+ type: 'POST',
2745
+ dataType: 'json',
2746
+ data: data,
2747
+ success: function(response) {
2748
+ jQuery(selector).append(jQuery('<option/>', {
2749
+ 'value': ''
2750
+ }).html('Choose...'));
2751
+ for (var i in response.aaData) {
2752
+ jQuery(selector).append(jQuery('<option/>', {
2753
+ 'value': response.aaData[i][0]
2754
+ }).html(response.aaData[i][2]));
2755
+ }
2756
+
2757
+ if (typeof selected !== 'undefined') {
2758
+ jQuery(selector).val(selected);
2759
+ }
2760
+
2761
+ jQuery(selector).removeClass('dialog-input-dynamic').addClass(
2762
+ 'dialog-input'
2763
+ );
2764
+ },
2765
+ error: function() {
2766
+ _this.highlight(selector, 'failure');
2767
+ }
2768
+ });
2769
+ };
2770
+
2771
+ jQuery(document).ready(function() {
2772
+ aamInterface = new AAM();
2773
+ });
media/js/codemirror.js ADDED
@@ -0,0 +1,5829 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror version 3.16
2
+ //
3
+ // CodeMirror is the only global var we claim
4
+ window.CodeMirror = (function() {
5
+ "use strict";
6
+
7
+ // BROWSER SNIFFING
8
+
9
+ // Crude, but necessary to handle a number of hard-to-feature-detect
10
+ // bugs and behavior differences.
11
+ var gecko = /gecko\/\d/i.test(navigator.userAgent);
12
+ var ie = /MSIE \d/.test(navigator.userAgent);
13
+ var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
14
+ var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
15
+ var webkit = /WebKit\//.test(navigator.userAgent);
16
+ var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
17
+ var chrome = /Chrome\//.test(navigator.userAgent);
18
+ var opera = /Opera\//.test(navigator.userAgent);
19
+ var safari = /Apple Computer/.test(navigator.vendor);
20
+ var khtml = /KHTML\//.test(navigator.userAgent);
21
+ var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
22
+ var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
23
+ var phantom = /PhantomJS/.test(navigator.userAgent);
24
+
25
+ var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
26
+ // This is woefully incomplete. Suggestions for alternative methods welcome.
27
+ var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
28
+ var mac = ios || /Mac/.test(navigator.platform);
29
+ var windows = /win/i.test(navigator.platform);
30
+
31
+ var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
32
+ if (opera_version) opera_version = Number(opera_version[1]);
33
+ if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
34
+ // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
35
+ var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
36
+ var captureMiddleClick = gecko || (ie && !ie_lt9);
37
+
38
+ // Optimize some code when these features are not used
39
+ var sawReadOnlySpans = false, sawCollapsedSpans = false;
40
+
41
+ // CONSTRUCTOR
42
+
43
+ function CodeMirror(place, options) {
44
+ if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
45
+
46
+ this.options = options = options || {};
47
+ // Determine effective options based on given values and defaults.
48
+ for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
49
+ options[opt] = defaults[opt];
50
+ setGuttersForLineNumbers(options);
51
+
52
+ var docStart = typeof options.value == "string" ? 0 : options.value.first;
53
+ var display = this.display = makeDisplay(place, docStart);
54
+ display.wrapper.CodeMirror = this;
55
+ updateGutters(this);
56
+ if (options.autofocus && !mobile) focusInput(this);
57
+
58
+ this.state = {keyMaps: [],
59
+ overlays: [],
60
+ modeGen: 0,
61
+ overwrite: false, focused: false,
62
+ suppressEdits: false, pasteIncoming: false,
63
+ draggingText: false,
64
+ highlight: new Delayed()};
65
+
66
+ themeChanged(this);
67
+ if (options.lineWrapping)
68
+ this.display.wrapper.className += " CodeMirror-wrap";
69
+
70
+ var doc = options.value;
71
+ if (typeof doc == "string") doc = new Doc(options.value, options.mode);
72
+ operation(this, attachDoc)(this, doc);
73
+
74
+ // Override magic textarea content restore that IE sometimes does
75
+ // on our hidden textarea on reload
76
+ if (ie) setTimeout(bind(resetInput, this, true), 20);
77
+
78
+ registerEventHandlers(this);
79
+ // IE throws unspecified error in certain cases, when
80
+ // trying to access activeElement before onload
81
+ var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
82
+ if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
83
+ else onBlur(this);
84
+
85
+ operation(this, function() {
86
+ for (var opt in optionHandlers)
87
+ if (optionHandlers.propertyIsEnumerable(opt))
88
+ optionHandlers[opt](this, options[opt], Init);
89
+ for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
90
+ })();
91
+ }
92
+
93
+ // DISPLAY CONSTRUCTOR
94
+
95
+ function makeDisplay(place, docStart) {
96
+ var d = {};
97
+
98
+ var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");
99
+ if (webkit) input.style.width = "1000px";
100
+ else input.setAttribute("wrap", "off");
101
+ // if border: 0; -- iOS fails to open keyboard (issue #1287)
102
+ if (ios) input.style.border = "1px solid black";
103
+ input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
104
+
105
+ // Wraps and hides input textarea
106
+ d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
107
+ // The actual fake scrollbars.
108
+ d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
109
+ d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
110
+ d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
111
+ d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
112
+ // DIVs containing the selection and the actual code
113
+ d.lineDiv = elt("div", null, "CodeMirror-code");
114
+ d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
115
+ // Blinky cursor, and element used to ensure cursor fits at the end of a line
116
+ d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
117
+ // Secondary cursor, shown when on a 'jump' in bi-directional text
118
+ d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
119
+ // Used to measure text size
120
+ d.measure = elt("div", null, "CodeMirror-measure");
121
+ // Wraps everything that needs to exist inside the vertically-padded coordinate system
122
+ d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
123
+ null, "position: relative; outline: none");
124
+ // Moved around its parent to cover visible view
125
+ d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
126
+ // Set to the height of the text, causes scrolling
127
+ d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
128
+ // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
129
+ d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
130
+ // Will contain the gutters, if any
131
+ d.gutters = elt("div", null, "CodeMirror-gutters");
132
+ d.lineGutter = null;
133
+ // Provides scrolling
134
+ d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
135
+ d.scroller.setAttribute("tabIndex", "-1");
136
+ // The element in which the editor lives.
137
+ d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
138
+ d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
139
+ // Work around IE7 z-index bug
140
+ if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
141
+ if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);
142
+
143
+ // Needed to hide big blue blinking cursor on Mobile Safari
144
+ if (ios) input.style.width = "0px";
145
+ if (!webkit) d.scroller.draggable = true;
146
+ // Needed to handle Tab key in KHTML
147
+ if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
148
+ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
149
+ else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
150
+
151
+ // Current visible range (may be bigger than the view window).
152
+ d.viewOffset = d.lastSizeC = 0;
153
+ d.showingFrom = d.showingTo = docStart;
154
+
155
+ // Used to only resize the line number gutter when necessary (when
156
+ // the amount of lines crosses a boundary that makes its width change)
157
+ d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
158
+ // See readInput and resetInput
159
+ d.prevInput = "";
160
+ // Set to true when a non-horizontal-scrolling widget is added. As
161
+ // an optimization, widget aligning is skipped when d is false.
162
+ d.alignWidgets = false;
163
+ // Flag that indicates whether we currently expect input to appear
164
+ // (after some event like 'keypress' or 'input') and are polling
165
+ // intensively.
166
+ d.pollingFast = false;
167
+ // Self-resetting timeout for the poller
168
+ d.poll = new Delayed();
169
+
170
+ d.cachedCharWidth = d.cachedTextHeight = null;
171
+ d.measureLineCache = [];
172
+ d.measureLineCachePos = 0;
173
+
174
+ // Tracks when resetInput has punted to just putting a short
175
+ // string instead of the (large) selection.
176
+ d.inaccurateSelection = false;
177
+
178
+ // Tracks the maximum line length so that the horizontal scrollbar
179
+ // can be kept static when scrolling.
180
+ d.maxLine = null;
181
+ d.maxLineLength = 0;
182
+ d.maxLineChanged = false;
183
+
184
+ // Used for measuring wheel scrolling granularity
185
+ d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
186
+
187
+ return d;
188
+ }
189
+
190
+ // STATE UPDATES
191
+
192
+ // Used to get the editor into a consistent state again when options change.
193
+
194
+ function loadMode(cm) {
195
+ cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
196
+ cm.doc.iter(function(line) {
197
+ if (line.stateAfter) line.stateAfter = null;
198
+ if (line.styles) line.styles = null;
199
+ });
200
+ cm.doc.frontier = cm.doc.first;
201
+ startWorker(cm, 100);
202
+ cm.state.modeGen++;
203
+ if (cm.curOp) regChange(cm);
204
+ }
205
+
206
+ function wrappingChanged(cm) {
207
+ if (cm.options.lineWrapping) {
208
+ cm.display.wrapper.className += " CodeMirror-wrap";
209
+ cm.display.sizer.style.minWidth = "";
210
+ } else {
211
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
212
+ computeMaxLength(cm);
213
+ }
214
+ estimateLineHeights(cm);
215
+ regChange(cm);
216
+ clearCaches(cm);
217
+ setTimeout(function(){updateScrollbars(cm);}, 100);
218
+ }
219
+
220
+ function estimateHeight(cm) {
221
+ var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
222
+ var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
223
+ return function(line) {
224
+ if (lineIsHidden(cm.doc, line))
225
+ return 0;
226
+ else if (wrapping)
227
+ return (Math.ceil(line.text.length / perLine) || 1) * th;
228
+ else
229
+ return th;
230
+ };
231
+ }
232
+
233
+ function estimateLineHeights(cm) {
234
+ var doc = cm.doc, est = estimateHeight(cm);
235
+ doc.iter(function(line) {
236
+ var estHeight = est(line);
237
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
238
+ });
239
+ }
240
+
241
+ function keyMapChanged(cm) {
242
+ var map = keyMap[cm.options.keyMap], style = map.style;
243
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
244
+ (style ? " cm-keymap-" + style : "");
245
+ cm.state.disableInput = map.disableInput;
246
+ }
247
+
248
+ function themeChanged(cm) {
249
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
250
+ cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
251
+ clearCaches(cm);
252
+ }
253
+
254
+ function guttersChanged(cm) {
255
+ updateGutters(cm);
256
+ regChange(cm);
257
+ setTimeout(function(){alignHorizontally(cm);}, 20);
258
+ }
259
+
260
+ function updateGutters(cm) {
261
+ var gutters = cm.display.gutters, specs = cm.options.gutters;
262
+ removeChildren(gutters);
263
+ for (var i = 0; i < specs.length; ++i) {
264
+ var gutterClass = specs[i];
265
+ var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
266
+ if (gutterClass == "CodeMirror-linenumbers") {
267
+ cm.display.lineGutter = gElt;
268
+ gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
269
+ }
270
+ }
271
+ gutters.style.display = i ? "" : "none";
272
+ }
273
+
274
+ function lineLength(doc, line) {
275
+ if (line.height == 0) return 0;
276
+ var len = line.text.length, merged, cur = line;
277
+ while (merged = collapsedSpanAtStart(cur)) {
278
+ var found = merged.find();
279
+ cur = getLine(doc, found.from.line);
280
+ len += found.from.ch - found.to.ch;
281
+ }
282
+ cur = line;
283
+ while (merged = collapsedSpanAtEnd(cur)) {
284
+ var found = merged.find();
285
+ len -= cur.text.length - found.from.ch;
286
+ cur = getLine(doc, found.to.line);
287
+ len += cur.text.length - found.to.ch;
288
+ }
289
+ return len;
290
+ }
291
+
292
+ function computeMaxLength(cm) {
293
+ var d = cm.display, doc = cm.doc;
294
+ d.maxLine = getLine(doc, doc.first);
295
+ d.maxLineLength = lineLength(doc, d.maxLine);
296
+ d.maxLineChanged = true;
297
+ doc.iter(function(line) {
298
+ var len = lineLength(doc, line);
299
+ if (len > d.maxLineLength) {
300
+ d.maxLineLength = len;
301
+ d.maxLine = line;
302
+ }
303
+ });
304
+ }
305
+
306
+ // Make sure the gutters options contains the element
307
+ // "CodeMirror-linenumbers" when the lineNumbers option is true.
308
+ function setGuttersForLineNumbers(options) {
309
+ var found = false;
310
+ for (var i = 0; i < options.gutters.length; ++i) {
311
+ if (options.gutters[i] == "CodeMirror-linenumbers") {
312
+ if (options.lineNumbers) found = true;
313
+ else options.gutters.splice(i--, 1);
314
+ }
315
+ }
316
+ if (!found && options.lineNumbers)
317
+ options.gutters.push("CodeMirror-linenumbers");
318
+ }
319
+
320
+ // SCROLLBARS
321
+
322
+ // Re-synchronize the fake scrollbars with the actual size of the
323
+ // content. Optionally force a scrollTop.
324
+ function updateScrollbars(cm) {
325
+ var d = cm.display, docHeight = cm.doc.height;
326
+ var totalHeight = docHeight + paddingVert(d);
327
+ d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
328
+ d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
329
+ var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
330
+ var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
331
+ var needsV = scrollHeight > (d.scroller.clientHeight + 1);
332
+ if (needsV) {
333
+ d.scrollbarV.style.display = "block";
334
+ d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
335
+ d.scrollbarV.firstChild.style.height =
336
+ (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
337
+ } else {
338
+ d.scrollbarV.style.display = "";
339
+ d.scrollbarV.firstChild.style.height = "0";
340
+ }
341
+ if (needsH) {
342
+ d.scrollbarH.style.display = "block";
343
+ d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
344
+ d.scrollbarH.firstChild.style.width =
345
+ (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
346
+ } else {
347
+ d.scrollbarH.style.display = "";
348
+ d.scrollbarH.firstChild.style.width = "0";
349
+ }
350
+ if (needsH && needsV) {
351
+ d.scrollbarFiller.style.display = "block";
352
+ d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
353
+ } else d.scrollbarFiller.style.display = "";
354
+ if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
355
+ d.gutterFiller.style.display = "block";
356
+ d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
357
+ d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
358
+ } else d.gutterFiller.style.display = "";
359
+
360
+ if (mac_geLion && scrollbarWidth(d.measure) === 0)
361
+ d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
362
+ }
363
+
364
+ function visibleLines(display, doc, viewPort) {
365
+ var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
366
+ if (typeof viewPort == "number") top = viewPort;
367
+ else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
368
+ top = Math.floor(top - paddingTop(display));
369
+ var bottom = Math.ceil(top + height);
370
+ return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
371
+ }
372
+
373
+ // LINE NUMBERS
374
+
375
+ function alignHorizontally(cm) {
376
+ var display = cm.display;
377
+ if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
378
+ var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
379
+ var gutterW = display.gutters.offsetWidth, l = comp + "px";
380
+ for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
381
+ for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
382
+ }
383
+ if (cm.options.fixedGutter)
384
+ display.gutters.style.left = (comp + gutterW) + "px";
385
+ }
386
+
387
+ function maybeUpdateLineNumberWidth(cm) {
388
+ if (!cm.options.lineNumbers) return false;
389
+ var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
390
+ if (last.length != display.lineNumChars) {
391
+ var test = display.measure.appendChild(elt("div", [elt("div", last)],
392
+ "CodeMirror-linenumber CodeMirror-gutter-elt"));
393
+ var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
394
+ display.lineGutter.style.width = "";
395
+ display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
396
+ display.lineNumWidth = display.lineNumInnerWidth + padding;
397
+ display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
398
+ display.lineGutter.style.width = display.lineNumWidth + "px";
399
+ return true;
400
+ }
401
+ return false;
402
+ }
403
+
404
+ function lineNumberFor(options, i) {
405
+ return String(options.lineNumberFormatter(i + options.firstLineNumber));
406
+ }
407
+ function compensateForHScroll(display) {
408
+ return getRect(display.scroller).left - getRect(display.sizer).left;
409
+ }
410
+
411
+ // DISPLAY DRAWING
412
+
413
+ function updateDisplay(cm, changes, viewPort, forced) {
414
+ var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
415
+ var visible = visibleLines(cm.display, cm.doc, viewPort);
416
+ for (;;) {
417
+ if (!updateDisplayInner(cm, changes, visible, forced)) break;
418
+ forced = false;
419
+ updated = true;
420
+ updateSelection(cm);
421
+ updateScrollbars(cm);
422
+
423
+ // Clip forced viewport to actual scrollable area
424
+ if (viewPort)
425
+ viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
426
+ typeof viewPort == "number" ? viewPort : viewPort.top);
427
+ visible = visibleLines(cm.display, cm.doc, viewPort);
428
+ if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
429
+ break;
430
+ changes = [];
431
+ }
432
+
433
+ if (updated) {
434
+ signalLater(cm, "update", cm);
435
+ if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
436
+ signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
437
+ }
438
+ return updated;
439
+ }
440
+
441
+ // Uses a set of changes plus the current scroll position to
442
+ // determine which DOM updates have to be made, and makes the
443
+ // updates.
444
+ function updateDisplayInner(cm, changes, visible, forced) {
445
+ var display = cm.display, doc = cm.doc;
446
+ if (!display.wrapper.clientWidth) {
447
+ display.showingFrom = display.showingTo = doc.first;
448
+ display.viewOffset = 0;
449
+ return;
450
+ }
451
+
452
+ // Bail out if the visible area is already rendered and nothing changed.
453
+ if (!forced && changes.length == 0 &&
454
+ visible.from > display.showingFrom && visible.to < display.showingTo)
455
+ return;
456
+
457
+ if (maybeUpdateLineNumberWidth(cm))
458
+ changes = [{from: doc.first, to: doc.first + doc.size}];
459
+ var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
460
+ display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
461
+
462
+ // Used to determine which lines need their line numbers updated
463
+ var positionsChangedFrom = Infinity;
464
+ if (cm.options.lineNumbers)
465
+ for (var i = 0; i < changes.length; ++i)
466
+ if (changes[i].diff && changes[i].from < positionsChangedFrom) { positionsChangedFrom = changes[i].from; }
467
+
468
+ var end = doc.first + doc.size;
469
+ var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
470
+ var to = Math.min(end, visible.to + cm.options.viewportMargin);
471
+ if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom);
472
+ if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo);
473
+ if (sawCollapsedSpans) {
474
+ from = lineNo(visualLine(doc, getLine(doc, from)));
475
+ while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to;
476
+ }
477
+
478
+ // Create a range of theoretically intact lines, and punch holes
479
+ // in that using the change info.
480
+ var intact = [{from: Math.max(display.showingFrom, doc.first),
481
+ to: Math.min(display.showingTo, end)}];
482
+ if (intact[0].from >= intact[0].to) intact = [];
483
+ else intact = computeIntact(intact, changes);
484
+ // When merged lines are present, we might have to reduce the
485
+ // intact ranges because changes in continued fragments of the
486
+ // intact lines do require the lines to be redrawn.
487
+ if (sawCollapsedSpans)
488
+ for (var i = 0; i < intact.length; ++i) {
489
+ var range = intact[i], merged;
490
+ while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) {
491
+ var newTo = merged.find().from.line;
492
+ if (newTo > range.from) range.to = newTo;
493
+ else { intact.splice(i--, 1); break; }
494
+ }
495
+ }
496
+
497
+ // Clip off the parts that won't be visible
498
+ var intactLines = 0;
499
+ for (var i = 0; i < intact.length; ++i) {
500
+ var range = intact[i];
501
+ if (range.from < from) range.from = from;
502
+ if (range.to > to) range.to = to;
503
+ if (range.from >= range.to) intact.splice(i--, 1);
504
+ else intactLines += range.to - range.from;
505
+ }
506
+ if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
507
+ updateViewOffset(cm);
508
+ return;
509
+ }
510
+ intact.sort(function(a, b) {return a.from - b.from;});
511
+
512
+ // Avoid crashing on IE's "unspecified error" when in iframes
513
+ try {
514
+ var focused = document.activeElement;
515
+ } catch(e) {}
516
+ if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
517
+ patchDisplay(cm, from, to, intact, positionsChangedFrom);
518
+ display.lineDiv.style.display = "";
519
+ if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus();
520
+
521
+ var different = from != display.showingFrom || to != display.showingTo ||
522
+ display.lastSizeC != display.wrapper.clientHeight;
523
+ // This is just a bogus formula that detects when the editor is
524
+ // resized or the font size changes.
525
+ if (different) {
526
+ display.lastSizeC = display.wrapper.clientHeight;
527
+ startWorker(cm, 400);
528
+ }
529
+ display.showingFrom = from; display.showingTo = to;
530
+
531
+ updateHeightsInViewport(cm);
532
+ updateViewOffset(cm);
533
+
534
+ return true;
535
+ }
536
+
537
+ function updateHeightsInViewport(cm) {
538
+ var display = cm.display;
539
+ var prevBottom = display.lineDiv.offsetTop;
540
+ for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
541
+ if (ie_lt8) {
542
+ var bot = node.offsetTop + node.offsetHeight;
543
+ height = bot - prevBottom;
544
+ prevBottom = bot;
545
+ } else {
546
+ var box = getRect(node);
547
+ height = box.bottom - box.top;
548
+ }
549
+ var diff = node.lineObj.height - height;
550
+ if (height < 2) height = textHeight(display);
551
+ if (diff > .001 || diff < -.001) {
552
+ updateLineHeight(node.lineObj, height);
553
+ var widgets = node.lineObj.widgets;
554
+ if (widgets) for (var i = 0; i < widgets.length; ++i)
555
+ widgets[i].height = widgets[i].node.offsetHeight;
556
+ }
557
+ }
558
+ }
559
+
560
+ function updateViewOffset(cm) {
561
+ var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom));
562
+ // Position the mover div to align with the current virtual scroll position
563
+ cm.display.mover.style.top = off + "px";
564
+ }
565
+
566
+ function computeIntact(intact, changes) {
567
+ for (var i = 0, l = changes.length || 0; i < l; ++i) {
568
+ var change = changes[i], intact2 = [], diff = change.diff || 0;
569
+ for (var j = 0, l2 = intact.length; j < l2; ++j) {
570
+ var range = intact[j];
571
+ if (change.to <= range.from && change.diff) {
572
+ intact2.push({from: range.from + diff, to: range.to + diff});
573
+ } else if (change.to <= range.from || change.from >= range.to) {
574
+ intact2.push(range);
575
+ } else {
576
+ if (change.from > range.from)
577
+ intact2.push({from: range.from, to: change.from});
578
+ if (change.to < range.to)
579
+ intact2.push({from: change.to + diff, to: range.to + diff});
580
+ }
581
+ }
582
+ intact = intact2;
583
+ }
584
+ return intact;
585
+ }
586
+
587
+ function getDimensions(cm) {
588
+ var d = cm.display, left = {}, width = {};
589
+ for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
590
+ left[cm.options.gutters[i]] = n.offsetLeft;
591
+ width[cm.options.gutters[i]] = n.offsetWidth;
592
+ }
593
+ return {fixedPos: compensateForHScroll(d),
594
+ gutterTotalWidth: d.gutters.offsetWidth,
595
+ gutterLeft: left,
596
+ gutterWidth: width,
597
+ wrapperWidth: d.wrapper.clientWidth};
598
+ }
599
+
600
+ function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
601
+ var dims = getDimensions(cm);
602
+ var display = cm.display, lineNumbers = cm.options.lineNumbers;
603
+ if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
604
+ removeChildren(display.lineDiv);
605
+ var container = display.lineDiv, cur = container.firstChild;
606
+
607
+ function rm(node) {
608
+ var next = node.nextSibling;
609
+ if (webkit && mac && cm.display.currentWheelTarget == node) {
610
+ node.style.display = "none";
611
+ node.lineObj = null;
612
+ } else {
613
+ node.parentNode.removeChild(node);
614
+ }
615
+ return next;
616
+ }
617
+
618
+ var nextIntact = intact.shift(), lineN = from;
619
+ cm.doc.iter(from, to, function(line) {
620
+ if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
621
+ if (lineIsHidden(cm.doc, line)) {
622
+ if (line.height != 0) updateLineHeight(line, 0);
623
+ if (line.widgets && cur && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
624
+ var w = line.widgets[i];
625
+ if (w.showIfHidden) {
626
+ var prev = cur.previousSibling;
627
+ if (/pre/i.test(prev.nodeName)) {
628
+ var wrap = elt("div", null, null, "position: relative");
629
+ prev.parentNode.replaceChild(wrap, prev);
630
+ wrap.appendChild(prev);
631
+ prev = wrap;
632
+ }
633
+ var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget"));
634
+ if (!w.handleMouseEvents) wnode.ignoreEvents = true;
635
+ positionLineWidget(w, wnode, prev, dims);
636
+ }
637
+ }
638
+ } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) {
639
+ // This line is intact. Skip to the actual node. Update its
640
+ // line number if needed.
641
+ while (cur.lineObj != line) cur = rm(cur);
642
+ if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber)
643
+ setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN));
644
+ cur = cur.nextSibling;
645
+ } else {
646
+ // For lines with widgets, make an attempt to find and reuse
647
+ // the existing element, so that widgets aren't needlessly
648
+ // removed and re-inserted into the dom
649
+ if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling)
650
+ if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; }
651
+ // This line needs to be generated.
652
+ var lineNode = buildLineElement(cm, line, lineN, dims, reuse);
653
+ if (lineNode != reuse) {
654
+ container.insertBefore(lineNode, cur);
655
+ } else {
656
+ while (cur != reuse) cur = rm(cur);
657
+ cur = cur.nextSibling;
658
+ }
659
+
660
+ lineNode.lineObj = line;
661
+ }
662
+ ++lineN;
663
+ });
664
+ while (cur) cur = rm(cur);
665
+ }
666
+
667
+ function buildLineElement(cm, line, lineNo, dims, reuse) {
668
+ var lineElement = lineContent(cm, line);
669
+ var markers = line.gutterMarkers, display = cm.display, wrap;
670
+
671
+ if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
672
+ return lineElement;
673
+
674
+ // Lines with gutter elements, widgets or a background class need
675
+ // to be wrapped again, and have the extra elements added to the
676
+ // wrapper div
677
+
678
+ if (reuse) {
679
+ reuse.alignable = null;
680
+ var isOk = true, widgetsSeen = 0, insertBefore = null;
681
+ for (var n = reuse.firstChild, next; n; n = next) {
682
+ next = n.nextSibling;
683
+ if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
684
+ reuse.removeChild(n);
685
+ } else {
686
+ for (var i = 0; i < line.widgets.length; ++i) {
687
+ var widget = line.widgets[i];
688
+ if (widget.node == n.firstChild) {
689
+ if (!widget.above && !insertBefore) insertBefore = n;
690
+ positionLineWidget(widget, n, reuse, dims);
691
+ ++widgetsSeen;
692
+ break;
693
+ }
694
+ }
695
+ if (i == line.widgets.length) { isOk = false; break; }
696
+ }
697
+ }
698
+ reuse.insertBefore(lineElement, insertBefore);
699
+ if (isOk && widgetsSeen == line.widgets.length) {
700
+ wrap = reuse;
701
+ reuse.className = line.wrapClass || "";
702
+ }
703
+ }
704
+ if (!wrap) {
705
+ wrap = elt("div", null, line.wrapClass, "position: relative");
706
+ wrap.appendChild(lineElement);
707
+ }
708
+ // Kludge to make sure the styled element lies behind the selection (by z-index)
709
+ if (line.bgClass)
710
+ wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild);
711
+ if (cm.options.lineNumbers || markers) {
712
+ var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
713
+ (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
714
+ wrap.firstChild);
715
+ if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
716
+ if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
717
+ wrap.lineNumber = gutterWrap.appendChild(
718
+ elt("div", lineNumberFor(cm.options, lineNo),
719
+ "CodeMirror-linenumber CodeMirror-gutter-elt",
720
+ "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
721
+ + display.lineNumInnerWidth + "px"));
722
+ if (markers)
723
+ for (var k = 0; k < cm.options.gutters.length; ++k) {
724
+ var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
725
+ if (found)
726
+ gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
727
+ dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
728
+ }
729
+ }
730
+ if (ie_lt8) wrap.style.zIndex = 2;
731
+ if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
732
+ var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
733
+ if (!widget.handleMouseEvents) node.ignoreEvents = true;
734
+ positionLineWidget(widget, node, wrap, dims);
735
+ if (widget.above)
736
+ wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
737
+ else
738
+ wrap.appendChild(node);
739
+ signalLater(widget, "redraw");
740
+ }
741
+ return wrap;
742
+ }
743
+
744
+ function positionLineWidget(widget, node, wrap, dims) {
745
+ if (widget.noHScroll) {
746
+ (wrap.alignable || (wrap.alignable = [])).push(node);
747
+ var width = dims.wrapperWidth;
748
+ node.style.left = dims.fixedPos + "px";
749
+ if (!widget.coverGutter) {
750
+ width -= dims.gutterTotalWidth;
751
+ node.style.paddingLeft = dims.gutterTotalWidth + "px";
752
+ }
753
+ node.style.width = width + "px";
754
+ }
755
+ if (widget.coverGutter) {
756
+ node.style.zIndex = 5;
757
+ node.style.position = "relative";
758
+ if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
759
+ }
760
+ }
761
+
762
+ // SELECTION / CURSOR
763
+
764
+ function updateSelection(cm) {
765
+ var display = cm.display;
766
+ var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to);
767
+ if (collapsed || cm.options.showCursorWhenSelecting)
768
+ updateSelectionCursor(cm);
769
+ else
770
+ display.cursor.style.display = display.otherCursor.style.display = "none";
771
+ if (!collapsed)
772
+ updateSelectionRange(cm);
773
+ else
774
+ display.selectionDiv.style.display = "none";
775
+
776
+ // Move the hidden textarea near the cursor to prevent scrolling artifacts
777
+ if (cm.options.moveInputWithCursor) {
778
+ var headPos = cursorCoords(cm, cm.doc.sel.head, "div");
779
+ var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv);
780
+ display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
781
+ headPos.top + lineOff.top - wrapOff.top)) + "px";
782
+ display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
783
+ headPos.left + lineOff.left - wrapOff.left)) + "px";
784
+ }
785
+ }
786
+
787
+ // No selection, plain cursor
788
+ function updateSelectionCursor(cm) {
789
+ var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div");
790
+ display.cursor.style.left = pos.left + "px";
791
+ display.cursor.style.top = pos.top + "px";
792
+ display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
793
+ display.cursor.style.display = "";
794
+
795
+ if (pos.other) {
796
+ display.otherCursor.style.display = "";
797
+ display.otherCursor.style.left = pos.other.left + "px";
798
+ display.otherCursor.style.top = pos.other.top + "px";
799
+ display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
800
+ } else { display.otherCursor.style.display = "none"; }
801
+ }
802
+
803
+ // Highlight selection
804
+ function updateSelectionRange(cm) {
805
+ var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
806
+ var fragment = document.createDocumentFragment();
807
+ var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);
808
+
809
+ function add(left, top, width, bottom) {
810
+ if (top < 0) top = 0;
811
+ fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
812
+ "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
813
+ "px; height: " + (bottom - top) + "px"));
814
+ }
815
+
816
+ function drawForLine(line, fromArg, toArg) {
817
+ var lineObj = getLine(doc, line);
818
+ var lineLen = lineObj.text.length;
819
+ var start, end;
820
+ function coords(ch, bias) {
821
+ return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
822
+ }
823
+
824
+ iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
825
+ var leftPos = coords(from, "left"), rightPos, left, right;
826
+ if (from == to) {
827
+ rightPos = leftPos;
828
+ left = right = leftPos.left;
829
+ } else {
830
+ rightPos = coords(to - 1, "right");
831
+ if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
832
+ left = leftPos.left;
833
+ right = rightPos.right;
834
+ }
835
+ if (fromArg == null && from == 0) left = pl;
836
+ if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
837
+ add(left, leftPos.top, null, leftPos.bottom);
838
+ left = pl;
839
+ if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
840
+ }
841
+ if (toArg == null && to == lineLen) right = clientWidth;
842
+ if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
843
+ start = leftPos;
844
+ if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
845
+ end = rightPos;
846
+ if (left < pl + 1) left = pl;
847
+ add(left, rightPos.top, right - left, rightPos.bottom);
848
+ });
849
+ return {start: start, end: end};
850
+ }
851
+
852
+ if (sel.from.line == sel.to.line) {
853
+ drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
854
+ } else {
855
+ var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line);
856
+ var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine);
857
+ var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
858
+ var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
859
+ if (singleVLine) {
860
+ if (leftEnd.top < rightStart.top - 2) {
861
+ add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
862
+ add(pl, rightStart.top, rightStart.left, rightStart.bottom);
863
+ } else {
864
+ add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
865
+ }
866
+ }
867
+ if (leftEnd.bottom < rightStart.top)
868
+ add(pl, leftEnd.bottom, null, rightStart.top);
869
+ }
870
+
871
+ removeChildrenAndAdd(display.selectionDiv, fragment);
872
+ display.selectionDiv.style.display = "";
873
+ }
874
+
875
+ // Cursor-blinking
876
+ function restartBlink(cm) {
877
+ if (!cm.state.focused) return;
878
+ var display = cm.display;
879
+ clearInterval(display.blinker);
880
+ var on = true;
881
+ display.cursor.style.visibility = display.otherCursor.style.visibility = "";
882
+ if (cm.options.cursorBlinkRate > 0)
883
+ display.blinker = setInterval(function() {
884
+ display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
885
+ }, cm.options.cursorBlinkRate);
886
+ }
887
+
888
+ // HIGHLIGHT WORKER
889
+
890
+ function startWorker(cm, time) {
891
+ if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo)
892
+ cm.state.highlight.set(time, bind(highlightWorker, cm));
893
+ }
894
+
895
+ function highlightWorker(cm) {
896
+ var doc = cm.doc;
897
+ if (doc.frontier < doc.first) doc.frontier = doc.first;
898
+ if (doc.frontier >= cm.display.showingTo) return;
899
+ var end = +new Date + cm.options.workTime;
900
+ var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
901
+ var changed = [], prevChange;
902
+ doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
903
+ if (doc.frontier >= cm.display.showingFrom) { // Visible
904
+ var oldStyles = line.styles;
905
+ line.styles = highlightLine(cm, line, state);
906
+ var ischange = !oldStyles || oldStyles.length != line.styles.length;
907
+ for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
908
+ if (ischange) {
909
+ if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
910
+ else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
911
+ }
912
+ line.stateAfter = copyState(doc.mode, state);
913
+ } else {
914
+ processLine(cm, line, state);
915
+ line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
916
+ }
917
+ ++doc.frontier;
918
+ if (+new Date > end) {
919
+ startWorker(cm, cm.options.workDelay);
920
+ return true;
921
+ }
922
+ });
923
+ if (changed.length)
924
+ operation(cm, function() {
925
+ for (var i = 0; i < changed.length; ++i)
926
+ regChange(this, changed[i].start, changed[i].end);
927
+ })();
928
+ }
929
+
930
+ // Finds the line to start with when starting a parse. Tries to
931
+ // find a line with a stateAfter, so that it can start with a
932
+ // valid state. If that fails, it returns the line with the
933
+ // smallest indentation, which tends to need the least context to
934
+ // parse correctly.
935
+ function findStartLine(cm, n, precise) {
936
+ var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100;
937
+ for (var search = n, lim = n - maxScan; search > lim; --search) {
938
+ if (search <= doc.first) return doc.first;
939
+ var line = getLine(doc, search - 1);
940
+ if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
941
+ var indented = countColumn(line.text, null, cm.options.tabSize);
942
+ if (minline == null || minindent > indented) {
943
+ minline = search - 1;
944
+ minindent = indented;
945
+ }
946
+ }
947
+ return minline;
948
+ }
949
+
950
+ function getStateBefore(cm, n, precise) {
951
+ var doc = cm.doc, display = cm.display;
952
+ if (!doc.mode.startState) return true;
953
+ var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
954
+ if (!state) state = startState(doc.mode);
955
+ else state = copyState(doc.mode, state);
956
+ doc.iter(pos, n, function(line) {
957
+ processLine(cm, line, state);
958
+ var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
959
+ line.stateAfter = save ? copyState(doc.mode, state) : null;
960
+ ++pos;
961
+ });
962
+ return state;
963
+ }
964
+
965
+ // POSITION MEASUREMENT
966
+
967
+ function paddingTop(display) {return display.lineSpace.offsetTop;}
968
+ function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
969
+ function paddingLeft(display) {
970
+ var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x"));
971
+ return e.offsetLeft;
972
+ }
973
+
974
+ function measureChar(cm, line, ch, data, bias) {
975
+ var dir = -1;
976
+ data = data || measureLine(cm, line);
977
+
978
+ for (var pos = ch;; pos += dir) {
979
+ var r = data[pos];
980
+ if (r) break;
981
+ if (dir < 0 && pos == 0) dir = 1;
982
+ }
983
+ bias = pos > ch ? "left" : pos < ch ? "right" : bias;
984
+ if (bias == "left" && r.leftSide) r = r.leftSide;
985
+ else if (bias == "right" && r.rightSide) r = r.rightSide;
986
+ return {left: pos < ch ? r.right : r.left,
987
+ right: pos > ch ? r.left : r.right,
988
+ top: r.top,
989
+ bottom: r.bottom};
990
+ }
991
+
992
+ function findCachedMeasurement(cm, line) {
993
+ var cache = cm.display.measureLineCache;
994
+ for (var i = 0; i < cache.length; ++i) {
995
+ var memo = cache[i];
996
+ if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
997
+ cm.display.scroller.clientWidth == memo.width &&
998
+ memo.classes == line.textClass + "|" + line.bgClass + "|" + line.wrapClass)
999
+ return memo;
1000
+ }
1001
+ }
1002
+
1003
+ function clearCachedMeasurement(cm, line) {
1004
+ var exists = findCachedMeasurement(cm, line);
1005
+ if (exists) exists.text = exists.measure = exists.markedSpans = null;
1006
+ }
1007
+
1008
+ function measureLine(cm, line) {
1009
+ // First look in the cache
1010
+ var cached = findCachedMeasurement(cm, line);
1011
+ if (cached) return cached.measure;
1012
+
1013
+ // Failing that, recompute and store result in cache
1014
+ var measure = measureLineInner(cm, line);
1015
+ var cache = cm.display.measureLineCache;
1016
+ var memo = {text: line.text, width: cm.display.scroller.clientWidth,
1017
+ markedSpans: line.markedSpans, measure: measure,
1018
+ classes: line.textClass + "|" + line.bgClass + "|" + line.wrapClass};
1019
+ if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
1020
+ else cache.push(memo);
1021
+ return measure;
1022
+ }
1023
+
1024
+ function measureLineInner(cm, line) {
1025
+ var display = cm.display, measure = emptyArray(line.text.length);
1026
+ var pre = lineContent(cm, line, measure, true);
1027
+
1028
+ // IE does not cache element positions of inline elements between
1029
+ // calls to getBoundingClientRect. This makes the loop below,
1030
+ // which gathers the positions of all the characters on the line,
1031
+ // do an amount of layout work quadratic to the number of
1032
+ // characters. When line wrapping is off, we try to improve things
1033
+ // by first subdividing the line into a bunch of inline blocks, so
1034
+ // that IE can reuse most of the layout information from caches
1035
+ // for those blocks. This does interfere with line wrapping, so it
1036
+ // doesn't work when wrapping is on, but in that case the
1037
+ // situation is slightly better, since IE does cache line-wrapping
1038
+ // information and only recomputes per-line.
1039
+ if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
1040
+ var fragment = document.createDocumentFragment();
1041
+ var chunk = 10, n = pre.childNodes.length;
1042
+ for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
1043
+ var wrap = elt("div", null, null, "display: inline-block");
1044
+ for (var j = 0; j < chunk && n; ++j) {
1045
+ wrap.appendChild(pre.firstChild);
1046
+ --n;
1047
+ }
1048
+ fragment.appendChild(wrap);
1049
+ }
1050
+ pre.appendChild(fragment);
1051
+ }
1052
+
1053
+ removeChildrenAndAdd(display.measure, pre);
1054
+
1055
+ var outer = getRect(display.lineDiv);
1056
+ var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight;
1057
+ // Work around an IE7/8 bug where it will sometimes have randomly
1058
+ // replaced our pre with a clone at this point.
1059
+ if (ie_lt9 && display.measure.first != pre)
1060
+ removeChildrenAndAdd(display.measure, pre);
1061
+
1062
+ function measureRect(rect) {
1063
+ var top = rect.top - outer.top, bot = rect.bottom - outer.top;
1064
+ if (bot > maxBot) bot = maxBot;
1065
+ if (top < 0) top = 0;
1066
+ for (var i = vranges.length - 2; i >= 0; i -= 2) {
1067
+ var rtop = vranges[i], rbot = vranges[i+1];
1068
+ if (rtop > bot || rbot < top) continue;
1069
+ if (rtop <= top && rbot >= bot ||
1070
+ top <= rtop && bot >= rbot ||
1071
+ Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
1072
+ vranges[i] = Math.min(top, rtop);
1073
+ vranges[i+1] = Math.max(bot, rbot);
1074
+ break;
1075
+ }
1076
+ }
1077
+ if (i < 0) { i = vranges.length; vranges.push(top, bot); }
1078
+ return {left: rect.left - outer.left,
1079
+ right: rect.right - outer.left,
1080
+ top: i, bottom: null};
1081
+ }
1082
+ function finishRect(rect) {
1083
+ rect.bottom = vranges[rect.top+1];
1084
+ rect.top = vranges[rect.top];
1085
+ }
1086
+
1087
+ for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
1088
+ var node = cur, rect = null;
1089
+ // A widget might wrap, needs special care
1090
+ if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
1091
+ if (cur.firstChild.nodeType == 1) node = cur.firstChild;
1092
+ var rects = node.getClientRects();
1093
+ if (rects.length > 1) {
1094
+ rect = data[i] = measureRect(rects[0]);
1095
+ rect.rightSide = measureRect(rects[rects.length - 1]);
1096
+ }
1097
+ }
1098
+ if (!rect) rect = data[i] = measureRect(getRect(node));
1099
+ if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
1100
+ if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
1101
+ }
1102
+ removeChildren(cm.display.measure);
1103
+ for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
1104
+ finishRect(cur);
1105
+ if (cur.leftSide) finishRect(cur.leftSide);
1106
+ if (cur.rightSide) finishRect(cur.rightSide);
1107
+ }
1108
+ return data;
1109
+ }
1110
+
1111
+ function measureLineWidth(cm, line) {
1112
+ var hasBadSpan = false;
1113
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
1114
+ var sp = line.markedSpans[i];
1115
+ if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
1116
+ }
1117
+ var cached = !hasBadSpan && findCachedMeasurement(cm, line);
1118
+ if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
1119
+
1120
+ var pre = lineContent(cm, line, null, true);
1121
+ var end = pre.appendChild(zeroWidthElement(cm.display.measure));
1122
+ removeChildrenAndAdd(cm.display.measure, pre);
1123
+ return getRect(end).right - getRect(cm.display.lineDiv).left;
1124
+ }
1125
+
1126
+ function clearCaches(cm) {
1127
+ cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
1128
+ cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
1129
+ if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
1130
+ cm.display.lineNumChars = null;
1131
+ }
1132
+
1133
+ function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
1134
+ function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
1135
+
1136
+ // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
1137
+ function intoCoordSystem(cm, lineObj, rect, context) {
1138
+ if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
1139
+ var size = widgetHeight(lineObj.widgets[i]);
1140
+ rect.top += size; rect.bottom += size;
1141
+ }
1142
+ if (context == "line") return rect;
1143
+ if (!context) context = "local";
1144
+ var yOff = heightAtLine(cm, lineObj);
1145
+ if (context == "local") yOff += paddingTop(cm.display);
1146
+ else yOff -= cm.display.viewOffset;
1147
+ if (context == "page" || context == "window") {
1148
+ var lOff = getRect(cm.display.lineSpace);
1149
+ yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
1150
+ var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
1151
+ rect.left += xOff; rect.right += xOff;
1152
+ }
1153
+ rect.top += yOff; rect.bottom += yOff;
1154
+ return rect;
1155
+ }
1156
+
1157
+ // Context may be "window", "page", "div", or "local"/null
1158
+ // Result is in "div" coords
1159
+ function fromCoordSystem(cm, coords, context) {
1160
+ if (context == "div") return coords;
1161
+ var left = coords.left, top = coords.top;
1162
+ // First move into "page" coordinate system
1163
+ if (context == "page") {
1164
+ left -= pageScrollX();
1165
+ top -= pageScrollY();
1166
+ } else if (context == "local" || !context) {
1167
+ var localBox = getRect(cm.display.sizer);
1168
+ left += localBox.left;
1169
+ top += localBox.top;
1170
+ }
1171
+
1172
+ var lineSpaceBox = getRect(cm.display.lineSpace);
1173
+ return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
1174
+ }
1175
+
1176
+ function charCoords(cm, pos, context, lineObj, bias) {
1177
+ if (!lineObj) lineObj = getLine(cm.doc, pos.line);
1178
+ return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context);
1179
+ }
1180
+
1181
+ function cursorCoords(cm, pos, context, lineObj, measurement) {
1182
+ lineObj = lineObj || getLine(cm.doc, pos.line);
1183
+ if (!measurement) measurement = measureLine(cm, lineObj);
1184
+ function get(ch, right) {
1185
+ var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left");
1186
+ if (right) m.left = m.right; else m.right = m.left;
1187
+ return intoCoordSystem(cm, lineObj, m, context);
1188
+ }
1189
+ function getBidi(ch, partPos) {
1190
+ var part = order[partPos], right = part.level % 2;
1191
+ if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
1192
+ part = order[--partPos];
1193
+ ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
1194
+ right = true;
1195
+ } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
1196
+ part = order[++partPos];
1197
+ ch = bidiLeft(part) - part.level % 2;
1198
+ right = false;
1199
+ }
1200
+ if (right && ch == part.to && ch > part.from) return get(ch - 1);
1201
+ return get(ch, right);
1202
+ }
1203
+ var order = getOrder(lineObj), ch = pos.ch;
1204
+ if (!order) return get(ch);
1205
+ var partPos = getBidiPartAt(order, ch);
1206
+ var val = getBidi(ch, partPos);
1207
+ if (bidiOther != null) val.other = getBidi(ch, bidiOther);
1208
+ return val;
1209
+ }
1210
+
1211
+ function PosWithInfo(line, ch, outside, xRel) {
1212
+ var pos = new Pos(line, ch);
1213
+ pos.xRel = xRel;
1214
+ if (outside) pos.outside = true;
1215
+ return pos;
1216
+ }
1217
+
1218
+ // Coords must be lineSpace-local
1219
+ function coordsChar(cm, x, y) {
1220
+ var doc = cm.doc;
1221
+ y += cm.display.viewOffset;
1222
+ if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
1223
+ var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
1224
+ if (lineNo > last)
1225
+ return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
1226
+ if (x < 0) x = 0;
1227
+
1228
+ for (;;) {
1229
+ var lineObj = getLine(doc, lineNo);
1230
+ var found = coordsCharInner(cm, lineObj, lineNo, x, y);
1231
+ var merged = collapsedSpanAtEnd(lineObj);
1232
+ var mergedPos = merged && merged.find();
1233
+ if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
1234
+ lineNo = mergedPos.to.line;
1235
+ else
1236
+ return found;
1237
+ }
1238
+ }
1239
+
1240
+ function coordsCharInner(cm, lineObj, lineNo, x, y) {
1241
+ var innerOff = y - heightAtLine(cm, lineObj);
1242
+ var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
1243
+ var measurement = measureLine(cm, lineObj);
1244
+
1245
+ function getX(ch) {
1246
+ var sp = cursorCoords(cm, Pos(lineNo, ch), "line",
1247
+ lineObj, measurement);
1248
+ wrongLine = true;
1249
+ if (innerOff > sp.bottom) return sp.left - adjust;
1250
+ else if (innerOff < sp.top) return sp.left + adjust;
1251
+ else wrongLine = false;
1252
+ return sp.left;
1253
+ }
1254
+
1255
+ var bidi = getOrder(lineObj), dist = lineObj.text.length;
1256
+ var from = lineLeft(lineObj), to = lineRight(lineObj);
1257
+ var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
1258
+
1259
+ if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
1260
+ // Do a binary search between these bounds.
1261
+ for (;;) {
1262
+ if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
1263
+ var ch = x < fromX || x - fromX <= toX - x ? from : to;
1264
+ var xDiff = x - (ch == from ? fromX : toX);
1265
+ while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
1266
+ var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
1267
+ xDiff < 0 ? -1 : xDiff ? 1 : 0);
1268
+ return pos;
1269
+ }
1270
+ var step = Math.ceil(dist / 2), middle = from + step;
1271
+ if (bidi) {
1272
+ middle = from;
1273
+ for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
1274
+ }
1275
+ var middleX = getX(middle);
1276
+ if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
1277
+ else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
1278
+ }
1279
+ }
1280
+
1281
+ var measureText;
1282
+ function textHeight(display) {
1283
+ if (display.cachedTextHeight != null) return display.cachedTextHeight;
1284
+ if (measureText == null) {
1285
+ measureText = elt("pre");
1286
+ // Measure a bunch of lines, for browsers that compute
1287
+ // fractional heights.
1288
+ for (var i = 0; i < 49; ++i) {
1289
+ measureText.appendChild(document.createTextNode("x"));
1290
+ measureText.appendChild(elt("br"));
1291
+ }
1292
+ measureText.appendChild(document.createTextNode("x"));
1293
+ }
1294
+ removeChildrenAndAdd(display.measure, measureText);
1295
+ var height = measureText.offsetHeight / 50;
1296
+ if (height > 3) display.cachedTextHeight = height;
1297
+ removeChildren(display.measure);
1298
+ return height || 1;
1299
+ }
1300
+
1301
+ function charWidth(display) {
1302
+ if (display.cachedCharWidth != null) return display.cachedCharWidth;
1303
+ var anchor = elt("span", "x");
1304
+ var pre = elt("pre", [anchor]);
1305
+ removeChildrenAndAdd(display.measure, pre);
1306
+ var width = anchor.offsetWidth;
1307
+ if (width > 2) display.cachedCharWidth = width;
1308
+ return width || 10;
1309
+ }
1310
+
1311
+ // OPERATIONS
1312
+
1313
+ // Operations are used to wrap changes in such a way that each
1314
+ // change won't have to update the cursor and display (which would
1315
+ // be awkward, slow, and error-prone), but instead updates are
1316
+ // batched and then all combined and executed at once.
1317
+
1318
+ var nextOpId = 0;
1319
+ function startOperation(cm) {
1320
+ cm.curOp = {
1321
+ // An array of ranges of lines that have to be updated. See
1322
+ // updateDisplay.
1323
+ changes: [],
1324
+ forceUpdate: false,
1325
+ updateInput: null,
1326
+ userSelChange: null,
1327
+ textChanged: null,
1328
+ selectionChanged: false,
1329
+ cursorActivity: false,
1330
+ updateMaxLine: false,
1331
+ updateScrollPos: false,
1332
+ id: ++nextOpId
1333
+ };
1334
+ if (!delayedCallbackDepth++) delayedCallbacks = [];
1335
+ }
1336
+
1337
+ function endOperation(cm) {
1338
+ var op = cm.curOp, doc = cm.doc, display = cm.display;
1339
+ cm.curOp = null;
1340
+
1341
+ if (op.updateMaxLine) computeMaxLength(cm);
1342
+ if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
1343
+ var width = measureLineWidth(cm, display.maxLine);
1344
+ display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px";
1345
+ display.maxLineChanged = false;
1346
+ var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
1347
+ if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
1348
+ setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
1349
+ }
1350
+ var newScrollPos, updated;
1351
+ if (op.updateScrollPos) {
1352
+ newScrollPos = op.updateScrollPos;
1353
+ } else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible
1354
+ var coords = cursorCoords(cm, doc.sel.head);
1355
+ newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
1356
+ }
1357
+ if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
1358
+ updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
1359
+ if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
1360
+ }
1361
+ if (!updated && op.selectionChanged) updateSelection(cm);
1362
+ if (op.updateScrollPos) {
1363
+ display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
1364
+ display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
1365
+ alignHorizontally(cm);
1366
+ if (op.scrollToPos)
1367
+ scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin);
1368
+ } else if (newScrollPos) {
1369
+ scrollCursorIntoView(cm);
1370
+ }
1371
+ if (op.selectionChanged) restartBlink(cm);
1372
+
1373
+ if (cm.state.focused && op.updateInput)
1374
+ resetInput(cm, op.userSelChange);
1375
+
1376
+ var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
1377
+ if (hidden) for (var i = 0; i < hidden.length; ++i)
1378
+ if (!hidden[i].lines.length) signal(hidden[i], "hide");
1379
+ if (unhidden) for (var i = 0; i < unhidden.length; ++i)
1380
+ if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
1381
+
1382
+ var delayed;
1383
+ if (!--delayedCallbackDepth) {
1384
+ delayed = delayedCallbacks;
1385
+ delayedCallbacks = null;
1386
+ }
1387
+ if (op.textChanged)
1388
+ signal(cm, "change", cm, op.textChanged);
1389
+ if (op.cursorActivity) signal(cm, "cursorActivity", cm);
1390
+ if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
1391
+ }
1392
+
1393
+ // Wraps a function in an operation. Returns the wrapped function.
1394
+ function operation(cm1, f) {
1395
+ return function() {
1396
+ var cm = cm1 || this, withOp = !cm.curOp;
1397
+ if (withOp) startOperation(cm);
1398
+ try { var result = f.apply(cm, arguments); }
1399
+ finally { if (withOp) endOperation(cm); }
1400
+ return result;
1401
+ };
1402
+ }
1403
+ function docOperation(f) {
1404
+ return function() {
1405
+ var withOp = this.cm && !this.cm.curOp, result;
1406
+ if (withOp) startOperation(this.cm);
1407
+ try { result = f.apply(this, arguments); }
1408
+ finally { if (withOp) endOperation(this.cm); }
1409
+ return result;
1410
+ };
1411
+ }
1412
+ function runInOp(cm, f) {
1413
+ var withOp = !cm.curOp, result;
1414
+ if (withOp) startOperation(cm);
1415
+ try { result = f(); }
1416
+ finally { if (withOp) endOperation(cm); }
1417
+ return result;
1418
+ }
1419
+
1420
+ function regChange(cm, from, to, lendiff) {
1421
+ if (from == null) from = cm.doc.first;
1422
+ if (to == null) to = cm.doc.first + cm.doc.size;
1423
+ cm.curOp.changes.push({from: from, to: to, diff: lendiff});
1424
+ }
1425
+
1426
+ // INPUT HANDLING
1427
+
1428
+ function slowPoll(cm) {
1429
+ if (cm.display.pollingFast) return;
1430
+ cm.display.poll.set(cm.options.pollInterval, function() {
1431
+ readInput(cm);
1432
+ if (cm.state.focused) slowPoll(cm);
1433
+ });
1434
+ }
1435
+
1436
+ function fastPoll(cm) {
1437
+ var missed = false;
1438
+ cm.display.pollingFast = true;
1439
+ function p() {
1440
+ var changed = readInput(cm);
1441
+ if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
1442
+ else {cm.display.pollingFast = false; slowPoll(cm);}
1443
+ }
1444
+ cm.display.poll.set(20, p);
1445
+ }
1446
+
1447
+ // prevInput is a hack to work with IME. If we reset the textarea
1448
+ // on every change, that breaks IME. So we look for changes
1449
+ // compared to the previous content instead. (Modern browsers have
1450
+ // events that indicate IME taking place, but these are not widely
1451
+ // supported or compatible enough yet to rely on.)
1452
+ function readInput(cm) {
1453
+ var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
1454
+ if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false;
1455
+ if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
1456
+ input.value = input.value.substring(0, input.value.length - 1);
1457
+ cm.state.fakedLastChar = false;
1458
+ }
1459
+ var text = input.value;
1460
+ if (text == prevInput && posEq(sel.from, sel.to)) return false;
1461
+ if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
1462
+ resetInput(cm, true);
1463
+ return false;
1464
+ }
1465
+
1466
+ var withOp = !cm.curOp;
1467
+ if (withOp) startOperation(cm);
1468
+ sel.shift = false;
1469
+ var same = 0, l = Math.min(prevInput.length, text.length);
1470
+ while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
1471
+ var from = sel.from, to = sel.to;
1472
+ if (same < prevInput.length)
1473
+ from = Pos(from.line, from.ch - (prevInput.length - same));
1474
+ else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
1475
+ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same)));
1476
+
1477
+ var updateInput = cm.curOp.updateInput;
1478
+ var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)),
1479
+ origin: cm.state.pasteIncoming ? "paste" : "+input"};
1480
+ makeChange(cm.doc, changeEvent, "end");
1481
+ cm.curOp.updateInput = updateInput;
1482
+ signalLater(cm, "inputRead", cm, changeEvent);
1483
+
1484
+ if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
1485
+ else cm.display.prevInput = text;
1486
+ if (withOp) endOperation(cm);
1487
+ cm.state.pasteIncoming = false;
1488
+ return true;
1489
+ }
1490
+
1491
+ function resetInput(cm, user) {
1492
+ var minimal, selected, doc = cm.doc;
1493
+ if (!posEq(doc.sel.from, doc.sel.to)) {
1494
+ cm.display.prevInput = "";
1495
+ minimal = hasCopyEvent &&
1496
+ (doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
1497
+ var content = minimal ? "-" : selected || cm.getSelection();
1498
+ cm.display.input.value = content;
1499
+ if (cm.state.focused) selectInput(cm.display.input);
1500
+ if (ie && !ie_lt9) cm.display.inputHasSelection = content;
1501
+ } else if (user) {
1502
+ cm.display.prevInput = cm.display.input.value = "";
1503
+ if (ie && !ie_lt9) cm.display.inputHasSelection = null;
1504
+ }
1505
+ cm.display.inaccurateSelection = minimal;
1506
+ }
1507
+
1508
+ function focusInput(cm) {
1509
+ if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
1510
+ cm.display.input.focus();
1511
+ }
1512
+
1513
+ function isReadOnly(cm) {
1514
+ return cm.options.readOnly || cm.doc.cantEdit;
1515
+ }
1516
+
1517
+ // EVENT HANDLERS
1518
+
1519
+ function registerEventHandlers(cm) {
1520
+ var d = cm.display;
1521
+ on(d.scroller, "mousedown", operation(cm, onMouseDown));
1522
+ if (ie)
1523
+ on(d.scroller, "dblclick", operation(cm, function(e) {
1524
+ if (signalDOMEvent(cm, e)) return;
1525
+ var pos = posFromMouse(cm, e);
1526
+ if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
1527
+ e_preventDefault(e);
1528
+ var word = findWordAt(getLine(cm.doc, pos.line).text, pos);
1529
+ extendSelection(cm.doc, word.from, word.to);
1530
+ }));
1531
+ else
1532
+ on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
1533
+ on(d.lineSpace, "selectstart", function(e) {
1534
+ if (!eventInWidget(d, e)) e_preventDefault(e);
1535
+ });
1536
+ // Gecko browsers fire contextmenu *after* opening the menu, at
1537
+ // which point we can't mess with it anymore. Context menu is
1538
+ // handled in onMouseDown for Gecko.
1539
+ if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
1540
+
1541
+ on(d.scroller, "scroll", function() {
1542
+ if (d.scroller.clientHeight) {
1543
+ setScrollTop(cm, d.scroller.scrollTop);
1544
+ setScrollLeft(cm, d.scroller.scrollLeft, true);
1545
+ signal(cm, "scroll", cm);
1546
+ }
1547
+ });
1548
+ on(d.scrollbarV, "scroll", function() {
1549
+ if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
1550
+ });
1551
+ on(d.scrollbarH, "scroll", function() {
1552
+ if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
1553
+ });
1554
+
1555
+ on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
1556
+ on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
1557
+
1558
+ function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
1559
+ on(d.scrollbarH, "mousedown", reFocus);
1560
+ on(d.scrollbarV, "mousedown", reFocus);
1561
+ // Prevent wrapper from ever scrolling
1562
+ on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
1563
+
1564
+ var resizeTimer;
1565
+ function onResize() {
1566
+ if (resizeTimer == null) resizeTimer = setTimeout(function() {
1567
+ resizeTimer = null;
1568
+ // Might be a text scaling operation, clear size caches.
1569
+ d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null;
1570
+ clearCaches(cm);
1571
+ runInOp(cm, bind(regChange, cm));
1572
+ }, 100);
1573
+ }
1574
+ on(window, "resize", onResize);
1575
+ // Above handler holds on to the editor and its data structures.
1576
+ // Here we poll to unregister it when the editor is no longer in
1577
+ // the document, so that it can be garbage-collected.
1578
+ function unregister() {
1579
+ for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
1580
+ if (p) setTimeout(unregister, 5000);
1581
+ else off(window, "resize", onResize);
1582
+ }
1583
+ setTimeout(unregister, 5000);
1584
+
1585
+ on(d.input, "keyup", operation(cm, function(e) {
1586
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
1587
+ if (e.keyCode == 16) cm.doc.sel.shift = false;
1588
+ }));
1589
+ on(d.input, "input", bind(fastPoll, cm));
1590
+ on(d.input, "keydown", operation(cm, onKeyDown));
1591
+ on(d.input, "keypress", operation(cm, onKeyPress));
1592
+ on(d.input, "focus", bind(onFocus, cm));
1593
+ on(d.input, "blur", bind(onBlur, cm));
1594
+
1595
+ function drag_(e) {
1596
+ if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
1597
+ e_stop(e);
1598
+ }
1599
+ if (cm.options.dragDrop) {
1600
+ on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
1601
+ on(d.scroller, "dragenter", drag_);
1602
+ on(d.scroller, "dragover", drag_);
1603
+ on(d.scroller, "drop", operation(cm, onDrop));
1604
+ }
1605
+ on(d.scroller, "paste", function(e) {
1606
+ if (eventInWidget(d, e)) return;
1607
+ focusInput(cm);
1608
+ fastPoll(cm);
1609
+ });
1610
+ on(d.input, "paste", function() {
1611
+ // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
1612
+ // Add a char to the end of textarea before paste occur so that
1613
+ // selection doesn't span to the end of textarea.
1614
+ if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
1615
+ var start = d.input.selectionStart, end = d.input.selectionEnd;
1616
+ d.input.value += "$";
1617
+ d.input.selectionStart = start;
1618
+ d.input.selectionEnd = end;
1619
+ cm.state.fakedLastChar = true;
1620
+ }
1621
+ cm.state.pasteIncoming = true;
1622
+ fastPoll(cm);
1623
+ });
1624
+
1625
+ function prepareCopy() {
1626
+ if (d.inaccurateSelection) {
1627
+ d.prevInput = "";
1628
+ d.inaccurateSelection = false;
1629
+ d.input.value = cm.getSelection();
1630
+ selectInput(d.input);
1631
+ }
1632
+ }
1633
+ on(d.input, "cut", prepareCopy);
1634
+ on(d.input, "copy", prepareCopy);
1635
+
1636
+ // Needed to handle Tab key in KHTML
1637
+ if (khtml) on(d.sizer, "mouseup", function() {
1638
+ if (document.activeElement == d.input) d.input.blur();
1639
+ focusInput(cm);
1640
+ });
1641
+ }
1642
+
1643
+ function eventInWidget(display, e) {
1644
+ for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
1645
+ if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
1646
+ }
1647
+ }
1648
+
1649
+ function posFromMouse(cm, e, liberal) {
1650
+ var display = cm.display;
1651
+ if (!liberal) {
1652
+ var target = e_target(e);
1653
+ if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
1654
+ target == display.scrollbarV || target == display.scrollbarV.firstChild ||
1655
+ target == display.scrollbarFiller || target == display.gutterFiller) return null;
1656
+ }
1657
+ var x, y, space = getRect(display.lineSpace);
1658
+ // Fails unpredictably on IE[67] when mouse is dragged around quickly.
1659
+ try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
1660
+ return coordsChar(cm, x - space.left, y - space.top);
1661
+ }
1662
+
1663
+ var lastClick, lastDoubleClick;
1664
+ function onMouseDown(e) {
1665
+ if (signalDOMEvent(this, e)) return;
1666
+ var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel;
1667
+ sel.shift = e.shiftKey;
1668
+
1669
+ if (eventInWidget(display, e)) {
1670
+ if (!webkit) {
1671
+ display.scroller.draggable = false;
1672
+ setTimeout(function(){display.scroller.draggable = true;}, 100);
1673
+ }
1674
+ return;
1675
+ }
1676
+ if (clickInGutter(cm, e)) return;
1677
+ var start = posFromMouse(cm, e);
1678
+
1679
+ switch (e_button(e)) {
1680
+ case 3:
1681
+ if (captureMiddleClick) onContextMenu.call(cm, cm, e);
1682
+ return;
1683
+ case 2:
1684
+ if (webkit) cm.state.lastMiddleDown = +new Date;
1685
+ if (start) extendSelection(cm.doc, start);
1686
+ setTimeout(bind(focusInput, cm), 20);
1687
+ e_preventDefault(e);
1688
+ return;
1689
+ }
1690
+ // For button 1, if it was clicked inside the editor
1691
+ // (posFromMouse returning non-null), we have to adjust the
1692
+ // selection.
1693
+ if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
1694
+
1695
+ if (!cm.state.focused) onFocus(cm);
1696
+
1697
+ var now = +new Date, type = "single";
1698
+ if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
1699
+ type = "triple";
1700
+ e_preventDefault(e);
1701
+ setTimeout(bind(focusInput, cm), 20);
1702
+ selectLine(cm, start.line);
1703
+ } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
1704
+ type = "double";
1705
+ lastDoubleClick = {time: now, pos: start};
1706
+ e_preventDefault(e);
1707
+ var word = findWordAt(getLine(doc, start.line).text, start);
1708
+ extendSelection(cm.doc, word.from, word.to);
1709
+ } else { lastClick = {time: now, pos: start}; }
1710
+
1711
+ var last = start;
1712
+ if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
1713
+ !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
1714
+ var dragEnd = operation(cm, function(e2) {
1715
+ if (webkit) display.scroller.draggable = false;
1716
+ cm.state.draggingText = false;
1717
+ off(document, "mouseup", dragEnd);
1718
+ off(display.scroller, "drop", dragEnd);
1719
+ if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
1720
+ e_preventDefault(e2);
1721
+ extendSelection(cm.doc, start);
1722
+ focusInput(cm);
1723
+ }
1724
+ });
1725
+ // Let the drag handler handle this.
1726
+ if (webkit) display.scroller.draggable = true;
1727
+ cm.state.draggingText = dragEnd;
1728
+ // IE's approach to draggable
1729
+ if (display.scroller.dragDrop) display.scroller.dragDrop();
1730
+ on(document, "mouseup", dragEnd);
1731
+ on(display.scroller, "drop", dragEnd);
1732
+ return;
1733
+ }
1734
+ e_preventDefault(e);
1735
+ if (type == "single") extendSelection(cm.doc, clipPos(doc, start));
1736
+
1737
+ var startstart = sel.from, startend = sel.to, lastPos = start;
1738
+
1739
+ function doSelect(cur) {
1740
+ if (posEq(lastPos, cur)) return;
1741
+ lastPos = cur;
1742
+
1743
+ if (type == "single") {
1744
+ extendSelection(cm.doc, clipPos(doc, start), cur);
1745
+ return;
1746
+ }
1747
+
1748
+ startstart = clipPos(doc, startstart);
1749
+ startend = clipPos(doc, startend);
1750
+ if (type == "double") {
1751
+ var word = findWordAt(getLine(doc, cur.line).text, cur);
1752
+ if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend);
1753
+ else extendSelection(cm.doc, startstart, word.to);
1754
+ } else if (type == "triple") {
1755
+ if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0)));
1756
+ else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0)));
1757
+ }
1758
+ }
1759
+
1760
+ var editorSize = getRect(display.wrapper);
1761
+ // Used to ensure timeout re-tries don't fire when another extend
1762
+ // happened in the meantime (clearTimeout isn't reliable -- at
1763
+ // least on Chrome, the timeouts still happen even when cleared,
1764
+ // if the clear happens after their scheduled firing time).
1765
+ var counter = 0;
1766
+
1767
+ function extend(e) {
1768
+ var curCount = ++counter;
1769
+ var cur = posFromMouse(cm, e, true);
1770
+ if (!cur) return;
1771
+ if (!posEq(cur, last)) {
1772
+ if (!cm.state.focused) onFocus(cm);
1773
+ last = cur;
1774
+ doSelect(cur);
1775
+ var visible = visibleLines(display, doc);
1776
+ if (cur.line >= visible.to || cur.line < visible.from)
1777
+ setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
1778
+ } else {
1779
+ var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
1780
+ if (outside) setTimeout(operation(cm, function() {
1781
+ if (counter != curCount) return;
1782
+ display.scroller.scrollTop += outside;
1783
+ extend(e);
1784
+ }), 50);
1785
+ }
1786
+ }
1787
+
1788
+ function done(e) {
1789
+ counter = Infinity;
1790
+ e_preventDefault(e);
1791
+ focusInput(cm);
1792
+ off(document, "mousemove", move);
1793
+ off(document, "mouseup", up);
1794
+ }
1795
+
1796
+ var move = operation(cm, function(e) {
1797
+ if (!ie && !e_button(e)) done(e);
1798
+ else extend(e);
1799
+ });
1800
+ var up = operation(cm, done);
1801
+ on(document, "mousemove", move);
1802
+ on(document, "mouseup", up);
1803
+ }
1804
+
1805
+ function clickInGutter(cm, e) {
1806
+ var display = cm.display;
1807
+ try { var mX = e.clientX, mY = e.clientY; }
1808
+ catch(e) { return false; }
1809
+
1810
+ if (mX >= Math.floor(getRect(display.gutters).right)) return false;
1811
+ e_preventDefault(e);
1812
+ if (!hasHandler(cm, "gutterClick")) return true;
1813
+
1814
+ var lineBox = getRect(display.lineDiv);
1815
+ if (mY > lineBox.bottom) return true;
1816
+ mY -= lineBox.top - display.viewOffset;
1817
+
1818
+ for (var i = 0; i < cm.options.gutters.length; ++i) {
1819
+ var g = display.gutters.childNodes[i];
1820
+ if (g && getRect(g).right >= mX) {
1821
+ var line = lineAtHeight(cm.doc, mY);
1822
+ var gutter = cm.options.gutters[i];
1823
+ signalLater(cm, "gutterClick", cm, line, gutter, e);
1824
+ break;
1825
+ }
1826
+ }
1827
+ return true;
1828
+ }
1829
+
1830
+ // Kludge to work around strange IE behavior where it'll sometimes
1831
+ // re-fire a series of drag-related events right after the drop (#1551)
1832
+ var lastDrop = 0;
1833
+
1834
+ function onDrop(e) {
1835
+ var cm = this;
1836
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
1837
+ return;
1838
+ e_preventDefault(e);
1839
+ if (ie) lastDrop = +new Date;
1840
+ var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
1841
+ if (!pos || isReadOnly(cm)) return;
1842
+ if (files && files.length && window.FileReader && window.File) {
1843
+ var n = files.length, text = Array(n), read = 0;
1844
+ var loadFile = function(file, i) {
1845
+ var reader = new FileReader;
1846
+ reader.onload = function() {
1847
+ text[i] = reader.result;
1848
+ if (++read == n) {
1849
+ pos = clipPos(cm.doc, pos);
1850
+ makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around");
1851
+ }
1852
+ };
1853
+ reader.readAsText(file);
1854
+ };
1855
+ for (var i = 0; i < n; ++i) loadFile(files[i], i);
1856
+ } else {
1857
+ // Don't do a replace if the drop happened inside of the selected text.
1858
+ if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) {
1859
+ cm.state.draggingText(e);
1860
+ // Ensure the editor is re-focused
1861
+ setTimeout(bind(focusInput, cm), 20);
1862
+ return;
1863
+ }
1864
+ try {
1865
+ var text = e.dataTransfer.getData("Text");
1866
+ if (text) {
1867
+ var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
1868
+ setSelection(cm.doc, pos, pos);
1869
+ if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
1870
+ cm.replaceSelection(text, null, "paste");
1871
+ focusInput(cm);
1872
+ onFocus(cm);
1873
+ }
1874
+ }
1875
+ catch(e){}
1876
+ }
1877
+ }
1878
+
1879
+ function onDragStart(cm, e) {
1880
+ if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
1881
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
1882
+
1883
+ var txt = cm.getSelection();
1884
+ e.dataTransfer.setData("Text", txt);
1885
+
1886
+ // Use dummy image instead of default browsers image.
1887
+ // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
1888
+ if (e.dataTransfer.setDragImage && !safari) {
1889
+ var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
1890
+ if (opera) {
1891
+ img.width = img.height = 1;
1892
+ cm.display.wrapper.appendChild(img);
1893
+ // Force a relayout, or Opera won't use our image for some obscure reason
1894
+ img._top = img.offsetTop;
1895
+ }
1896
+ e.dataTransfer.setDragImage(img, 0, 0);
1897
+ if (opera) img.parentNode.removeChild(img);
1898
+ }
1899
+ }
1900
+
1901
+ function setScrollTop(cm, val) {
1902
+ if (Math.abs(cm.doc.scrollTop - val) < 2) return;
1903
+ cm.doc.scrollTop = val;
1904
+ if (!gecko) updateDisplay(cm, [], val);
1905
+ if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
1906
+ if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
1907
+ if (gecko) updateDisplay(cm, []);
1908
+ startWorker(cm, 100);
1909
+ }
1910
+ function setScrollLeft(cm, val, isScroller) {
1911
+ if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
1912
+ val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
1913
+ cm.doc.scrollLeft = val;
1914
+ alignHorizontally(cm);
1915
+ if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
1916
+ if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
1917
+ }
1918
+
1919
+ // Since the delta values reported on mouse wheel events are
1920
+ // unstandardized between browsers and even browser versions, and
1921
+ // generally horribly unpredictable, this code starts by measuring
1922
+ // the scroll effect that the first few mouse wheel events have,
1923
+ // and, from that, detects the way it can convert deltas to pixel
1924
+ // offsets afterwards.
1925
+ //
1926
+ // The reason we want to know the amount a wheel event will scroll
1927
+ // is that it gives us a chance to update the display before the
1928
+ // actual scrolling happens, reducing flickering.
1929
+
1930
+ var wheelSamples = 0, wheelPixelsPerUnit = null;
1931
+ // Fill in a browser-detected starting value on browsers where we
1932
+ // know one. These don't have to be accurate -- the result of them
1933
+ // being wrong would just be a slight flicker on the first wheel
1934
+ // scroll (if it is large enough).
1935
+ if (ie) wheelPixelsPerUnit = -.53;
1936
+ else if (gecko) wheelPixelsPerUnit = 15;
1937
+ else if (chrome) wheelPixelsPerUnit = -.7;
1938
+ else if (safari) wheelPixelsPerUnit = -1/3;
1939
+
1940
+ function onScrollWheel(cm, e) {
1941
+ var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
1942
+ if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
1943
+ if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
1944
+ else if (dy == null) dy = e.wheelDelta;
1945
+
1946
+ var display = cm.display, scroll = display.scroller;
1947
+ // Quit if there's nothing to scroll here
1948
+ if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
1949
+ dy && scroll.scrollHeight > scroll.clientHeight)) return;
1950
+
1951
+ // Webkit browsers on OS X abort momentum scrolls when the target
1952
+ // of the scroll event is removed from the scrollable element.
1953
+ // This hack (see related code in patchDisplay) makes sure the
1954
+ // element is kept around.
1955
+ if (dy && mac && webkit) {
1956
+ for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
1957
+ if (cur.lineObj) {
1958
+ cm.display.currentWheelTarget = cur;
1959
+ break;
1960
+ }
1961
+ }
1962
+ }
1963
+
1964
+ // On some browsers, horizontal scrolling will cause redraws to
1965
+ // happen before the gutter has been realigned, causing it to
1966
+ // wriggle around in a most unseemly way. When we have an
1967
+ // estimated pixels/delta value, we just handle horizontal
1968
+ // scrolling entirely here. It'll be slightly off from native, but
1969
+ // better than glitching out.
1970
+ if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
1971
+ if (dy)
1972
+ setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
1973
+ setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
1974
+ e_preventDefault(e);
1975
+ display.wheelStartX = null; // Abort measurement, if in progress
1976
+ return;
1977
+ }
1978
+
1979
+ if (dy && wheelPixelsPerUnit != null) {
1980
+ var pixels = dy * wheelPixelsPerUnit;
1981
+ var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
1982
+ if (pixels < 0) top = Math.max(0, top + pixels - 50);
1983
+ else bot = Math.min(cm.doc.height, bot + pixels + 50);
1984
+ updateDisplay(cm, [], {top: top, bottom: bot});
1985
+ }
1986
+
1987
+ if (wheelSamples < 20) {
1988
+ if (display.wheelStartX == null) {
1989
+ display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
1990
+ display.wheelDX = dx; display.wheelDY = dy;
1991
+ setTimeout(function() {
1992
+ if (display.wheelStartX == null) return;
1993
+ var movedX = scroll.scrollLeft - display.wheelStartX;
1994
+ var movedY = scroll.scrollTop - display.wheelStartY;
1995
+ var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
1996
+ (movedX && display.wheelDX && movedX / display.wheelDX);
1997
+ display.wheelStartX = display.wheelStartY = null;
1998
+ if (!sample) return;
1999
+ wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
2000
+ ++wheelSamples;
2001
+ }, 200);
2002
+ } else {
2003
+ display.wheelDX += dx; display.wheelDY += dy;
2004
+ }
2005
+ }
2006
+ }
2007
+
2008
+ function doHandleBinding(cm, bound, dropShift) {
2009
+ if (typeof bound == "string") {
2010
+ bound = commands[bound];
2011
+ if (!bound) return false;
2012
+ }
2013
+ // Ensure previous input has been read, so that the handler sees a
2014
+ // consistent view of the document
2015
+ if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
2016
+ var doc = cm.doc, prevShift = doc.sel.shift, done = false;
2017
+ try {
2018
+ if (isReadOnly(cm)) cm.state.suppressEdits = true;
2019
+ if (dropShift) doc.sel.shift = false;
2020
+ done = bound(cm) != Pass;
2021
+ } finally {
2022
+ doc.sel.shift = prevShift;
2023
+ cm.state.suppressEdits = false;
2024
+ }
2025
+ return done;
2026
+ }
2027
+
2028
+ function allKeyMaps(cm) {
2029
+ var maps = cm.state.keyMaps.slice(0);
2030
+ if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
2031
+ maps.push(cm.options.keyMap);
2032
+ return maps;
2033
+ }
2034
+
2035
+ var maybeTransition;
2036
+ function handleKeyBinding(cm, e) {
2037
+ // Handle auto keymap transitions
2038
+ var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
2039
+ clearTimeout(maybeTransition);
2040
+ if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
2041
+ if (getKeyMap(cm.options.keyMap) == startMap) {
2042
+ cm.options.keyMap = (next.call ? next.call(null, cm) : next);
2043
+ keyMapChanged(cm);
2044
+ }
2045
+ }, 50);
2046
+
2047
+ var name = keyName(e, true), handled = false;
2048
+ if (!name) return false;
2049
+ var keymaps = allKeyMaps(cm);
2050
+
2051
+ if (e.shiftKey) {
2052
+ // First try to resolve full name (including 'Shift-'). Failing
2053
+ // that, see if there is a cursor-motion command (starting with
2054
+ // 'go') bound to the keyname without 'Shift-'.
2055
+ handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
2056
+ || lookupKey(name, keymaps, function(b) {
2057
+ if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
2058
+ return doHandleBinding(cm, b);
2059
+ });
2060
+ } else {
2061
+ handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
2062
+ }
2063
+
2064
+ if (handled) {
2065
+ e_preventDefault(e);
2066
+ restartBlink(cm);
2067
+ if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
2068
+ signalLater(cm, "keyHandled", cm, name, e);
2069
+ }
2070
+ return handled;
2071
+ }
2072
+
2073
+ function handleCharBinding(cm, e, ch) {
2074
+ var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
2075
+ function(b) { return doHandleBinding(cm, b, true); });
2076
+ if (handled) {
2077
+ e_preventDefault(e);
2078
+ restartBlink(cm);
2079
+ signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
2080
+ }
2081
+ return handled;
2082
+ }
2083
+
2084
+ var lastStoppedKey = null;
2085
+ function onKeyDown(e) {
2086
+ var cm = this;
2087
+ if (!cm.state.focused) onFocus(cm);
2088
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
2089
+ if (ie && e.keyCode == 27) e.returnValue = false;
2090
+ var code = e.keyCode;
2091
+ // IE does strange things with escape.
2092
+ cm.doc.sel.shift = code == 16 || e.shiftKey;
2093
+ // First give onKeyEvent option a chance to handle this.
2094
+ var handled = handleKeyBinding(cm, e);
2095
+ if (opera) {
2096
+ lastStoppedKey = handled ? code : null;
2097
+ // Opera has no cut event... we try to at least catch the key combo
2098
+ if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
2099
+ cm.replaceSelection("");
2100
+ }
2101
+ }
2102
+
2103
+ function onKeyPress(e) {
2104
+ var cm = this;
2105
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
2106
+ var keyCode = e.keyCode, charCode = e.charCode;
2107
+ if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
2108
+ if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
2109
+ var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
2110
+ if (this.options.electricChars && this.doc.mode.electricChars &&
2111
+ this.options.smartIndent && !isReadOnly(this) &&
2112
+ this.doc.mode.electricChars.indexOf(ch) > -1)
2113
+ setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75);
2114
+ if (handleCharBinding(cm, e, ch)) return;
2115
+ if (ie && !ie_lt9) cm.display.inputHasSelection = null;
2116
+ fastPoll(cm);
2117
+ }
2118
+
2119
+ function onFocus(cm) {
2120
+ if (cm.options.readOnly == "nocursor") return;
2121
+ if (!cm.state.focused) {
2122
+ signal(cm, "focus", cm);
2123
+ cm.state.focused = true;
2124
+ if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
2125
+ cm.display.wrapper.className += " CodeMirror-focused";
2126
+ if (!cm.curOp) {
2127
+ resetInput(cm, true);
2128
+ if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
2129
+ }
2130
+ }
2131
+ slowPoll(cm);
2132
+ restartBlink(cm);
2133
+ }
2134
+ function onBlur(cm) {
2135
+ if (cm.state.focused) {
2136
+ signal(cm, "blur", cm);
2137
+ cm.state.focused = false;
2138
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
2139
+ }
2140
+ clearInterval(cm.display.blinker);
2141
+ setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150);
2142
+ }
2143
+
2144
+ var detectingSelectAll;
2145
+ function onContextMenu(cm, e) {
2146
+ if (signalDOMEvent(cm, e, "contextmenu")) return;
2147
+ var display = cm.display, sel = cm.doc.sel;
2148
+ if (eventInWidget(display, e)) return;
2149
+
2150
+ var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
2151
+ if (!pos || opera) return; // Opera is difficult.
2152
+ if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
2153
+ operation(cm, setSelection)(cm.doc, pos, pos);
2154
+
2155
+ var oldCSS = display.input.style.cssText;
2156
+ display.inputDiv.style.position = "absolute";
2157
+ display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
2158
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" +
2159
+ "border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
2160
+ focusInput(cm);
2161
+ resetInput(cm, true);
2162
+ // Adds "Select all" to context menu in FF
2163
+ if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
2164
+
2165
+ function prepareSelectAllHack() {
2166
+ if (display.input.selectionStart != null) {
2167
+ var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value);
2168
+ display.prevInput = " ";
2169
+ display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
2170
+ }
2171
+ }
2172
+ function rehide() {
2173
+ display.inputDiv.style.position = "relative";
2174
+ display.input.style.cssText = oldCSS;
2175
+ if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
2176
+ slowPoll(cm);
2177
+
2178
+ // Try to detect the user choosing select-all
2179
+ if (display.input.selectionStart != null) {
2180
+ if (!ie || ie_lt9) prepareSelectAllHack();
2181
+ clearTimeout(detectingSelectAll);
2182
+ var i = 0, poll = function(){
2183
+ if (display.prevInput == " " && display.input.selectionStart == 0)
2184
+ operation(cm, commands.selectAll)(cm);
2185
+ else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
2186
+ else resetInput(cm);
2187
+ };
2188
+ detectingSelectAll = setTimeout(poll, 200);
2189
+ }
2190
+ }
2191
+
2192
+ if (ie && !ie_lt9) prepareSelectAllHack();
2193
+ if (captureMiddleClick) {
2194
+ e_stop(e);
2195
+ var mouseup = function() {
2196
+ off(window, "mouseup", mouseup);
2197
+ setTimeout(rehide, 20);
2198
+ };
2199
+ on(window, "mouseup", mouseup);
2200
+ } else {
2201
+ setTimeout(rehide, 50);
2202
+ }
2203
+ }
2204
+
2205
+ // UPDATING
2206
+
2207
+ var changeEnd = CodeMirror.changeEnd = function(change) {
2208
+ if (!change.text) return change.to;
2209
+ return Pos(change.from.line + change.text.length - 1,
2210
+ lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
2211
+ };
2212
+
2213
+ // Make sure a position will be valid after the given change.
2214
+ function clipPostChange(doc, change, pos) {
2215
+ if (!posLess(change.from, pos)) return clipPos(doc, pos);
2216
+ var diff = (change.text.length - 1) - (change.to.line - change.from.line);
2217
+ if (pos.line > change.to.line + diff) {
2218
+ var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1;
2219
+ if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length);
2220
+ return clipToLen(pos, getLine(doc, preLine).text.length);
2221
+ }
2222
+ if (pos.line == change.to.line + diff)
2223
+ return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) +
2224
+ getLine(doc, change.to.line).text.length - change.to.ch);
2225
+ var inside = pos.line - change.from.line;
2226
+ return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch));
2227
+ }
2228
+
2229
+ // Hint can be null|"end"|"start"|"around"|{anchor,head}
2230
+ function computeSelAfterChange(doc, change, hint) {
2231
+ if (hint && typeof hint == "object") // Assumed to be {anchor, head} object
2232
+ return {anchor: clipPostChange(doc, change, hint.anchor),
2233
+ head: clipPostChange(doc, change, hint.head)};
2234
+
2235
+ if (hint == "start") return {anchor: change.from, head: change.from};
2236
+
2237
+ var end = changeEnd(change);
2238
+ if (hint == "around") return {anchor: change.from, head: end};
2239
+ if (hint == "end") return {anchor: end, head: end};
2240
+
2241
+ // hint is null, leave the selection alone as much as possible
2242
+ var adjustPos = function(pos) {
2243
+ if (posLess(pos, change.from)) return pos;
2244
+ if (!posLess(change.to, pos)) return end;
2245
+
2246
+ var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
2247
+ if (pos.line == change.to.line) ch += end.ch - change.to.ch;
2248
+ return Pos(line, ch);
2249
+ };
2250
+ return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)};
2251
+ }
2252
+
2253
+ function filterChange(doc, change, update) {
2254
+ var obj = {
2255
+ canceled: false,
2256
+ from: change.from,
2257
+ to: change.to,
2258
+ text: change.text,
2259
+ origin: change.origin,
2260
+ cancel: function() { this.canceled = true; }
2261
+ };
2262
+ if (update) obj.update = function(from, to, text, origin) {
2263
+ if (from) this.from = clipPos(doc, from);
2264
+ if (to) this.to = clipPos(doc, to);
2265
+ if (text) this.text = text;
2266
+ if (origin !== undefined) this.origin = origin;
2267
+ };
2268
+ signal(doc, "beforeChange", doc, obj);
2269
+ if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
2270
+
2271
+ if (obj.canceled) return null;
2272
+ return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
2273
+ }
2274
+
2275
+ // Replace the range from from to to by the strings in replacement.
2276
+ // change is a {from, to, text [, origin]} object
2277
+ function makeChange(doc, change, selUpdate, ignoreReadOnly) {
2278
+ if (doc.cm) {
2279
+ if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly);
2280
+ if (doc.cm.state.suppressEdits) return;
2281
+ }
2282
+
2283
+ if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
2284
+ change = filterChange(doc, change, true);
2285
+ if (!change) return;
2286
+ }
2287
+
2288
+ // Possibly split or suppress the update based on the presence
2289
+ // of read-only spans in its range.
2290
+ var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
2291
+ if (split) {
2292
+ for (var i = split.length - 1; i >= 1; --i)
2293
+ makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]});
2294
+ if (split.length)
2295
+ makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate);
2296
+ } else {
2297
+ makeChangeNoReadonly(doc, change, selUpdate);
2298
+ }
2299
+ }
2300
+
2301
+ function makeChangeNoReadonly(doc, change, selUpdate) {
2302
+ var selAfter = computeSelAfterChange(doc, change, selUpdate);
2303
+ addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
2304
+
2305
+ makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
2306
+ var rebased = [];
2307
+
2308
+ linkedDocs(doc, function(doc, sharedHist) {
2309
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
2310
+ rebaseHist(doc.history, change);
2311
+ rebased.push(doc.history);
2312
+ }
2313
+ makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
2314
+ });
2315
+ }
2316
+
2317
+ function makeChangeFromHistory(doc, type) {
2318
+ if (doc.cm && doc.cm.state.suppressEdits) return;
2319
+
2320
+ var hist = doc.history;
2321
+ var event = (type == "undo" ? hist.done : hist.undone).pop();
2322
+ if (!event) return;
2323
+
2324
+ var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
2325
+ anchorAfter: event.anchorBefore, headAfter: event.headBefore,
2326
+ generation: hist.generation};
2327
+ (type == "undo" ? hist.undone : hist.done).push(anti);
2328
+ hist.generation = event.generation || ++hist.maxGeneration;
2329
+
2330
+ var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
2331
+
2332
+ for (var i = event.changes.length - 1; i >= 0; --i) {
2333
+ var change = event.changes[i];
2334
+ change.origin = type;
2335
+ if (filter && !filterChange(doc, change, false)) {
2336
+ (type == "undo" ? hist.done : hist.undone).length = 0;
2337
+ return;
2338
+ }
2339
+
2340
+ anti.changes.push(historyChangeFromChange(doc, change));
2341
+
2342
+ var after = i ? computeSelAfterChange(doc, change, null)
2343
+ : {anchor: event.anchorBefore, head: event.headBefore};
2344
+ makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
2345
+ var rebased = [];
2346
+
2347
+ linkedDocs(doc, function(doc, sharedHist) {
2348
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
2349
+ rebaseHist(doc.history, change);
2350
+ rebased.push(doc.history);
2351
+ }
2352
+ makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
2353
+ });
2354
+ }
2355
+ }
2356
+
2357
+ function shiftDoc(doc, distance) {
2358
+ function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);}
2359
+ doc.first += distance;
2360
+ if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance);
2361
+ doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor);
2362
+ doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to);
2363
+ }
2364
+
2365
+ function makeChangeSingleDoc(doc, change, selAfter, spans) {
2366
+ if (doc.cm && !doc.cm.curOp)
2367
+ return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
2368
+
2369
+ if (change.to.line < doc.first) {
2370
+ shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
2371
+ return;
2372
+ }
2373
+ if (change.from.line > doc.lastLine()) return;
2374
+
2375
+ // Clip the change to the size of this doc
2376
+ if (change.from.line < doc.first) {
2377
+ var shift = change.text.length - 1 - (doc.first - change.from.line);
2378
+ shiftDoc(doc, shift);
2379
+ change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
2380
+ text: [lst(change.text)], origin: change.origin};
2381
+ }
2382
+ var last = doc.lastLine();
2383
+ if (change.to.line > last) {
2384
+ change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
2385
+ text: [change.text[0]], origin: change.origin};
2386
+ }
2387
+
2388
+ change.removed = getBetween(doc, change.from, change.to);
2389
+
2390
+ if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
2391
+ if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter);
2392
+ else updateDoc(doc, change, spans, selAfter);
2393
+ }
2394
+
2395
+ function makeChangeSingleDocInEditor(cm, change, spans, selAfter) {
2396
+ var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
2397
+
2398
+ var recomputeMaxLength = false, checkWidthStart = from.line;
2399
+ if (!cm.options.lineWrapping) {
2400
+ checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line)));
2401
+ doc.iter(checkWidthStart, to.line + 1, function(line) {
2402
+ if (line == display.maxLine) {
2403
+ recomputeMaxLength = true;
2404
+ return true;
2405
+ }
2406
+ });
2407
+ }
2408
+
2409
+ if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head))
2410
+ cm.curOp.cursorActivity = true;
2411
+
2412
+ updateDoc(doc, change, spans, selAfter, estimateHeight(cm));
2413
+
2414
+ if (!cm.options.lineWrapping) {
2415
+ doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
2416
+ var len = lineLength(doc, line);
2417
+ if (len > display.maxLineLength) {
2418
+ display.maxLine = line;
2419
+ display.maxLineLength = len;
2420
+ display.maxLineChanged = true;
2421
+ recomputeMaxLength = false;
2422
+ }
2423
+ });
2424
+ if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
2425
+ }
2426
+
2427
+ // Adjust frontier, schedule worker
2428
+ doc.frontier = Math.min(doc.frontier, from.line);
2429
+ startWorker(cm, 400);
2430
+
2431
+ var lendiff = change.text.length - (to.line - from.line) - 1;
2432
+ // Remember that these lines changed, for updating the display
2433
+ regChange(cm, from.line, to.line + 1, lendiff);
2434
+
2435
+ if (hasHandler(cm, "change")) {
2436
+ var changeObj = {from: from, to: to,
2437
+ text: change.text,
2438
+ removed: change.removed,
2439
+ origin: change.origin};
2440
+ if (cm.curOp.textChanged) {
2441
+ for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
2442
+ cur.next = changeObj;
2443
+ } else cm.curOp.textChanged = changeObj;
2444
+ }
2445
+ }
2446
+
2447
+ function replaceRange(doc, code, from, to, origin) {
2448
+ if (!to) to = from;
2449
+ if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
2450
+ if (typeof code == "string") code = splitLines(code);
2451
+ makeChange(doc, {from: from, to: to, text: code, origin: origin}, null);
2452
+ }
2453
+
2454
+ // POSITION OBJECT
2455
+
2456
+ function Pos(line, ch) {
2457
+ if (!(this instanceof Pos)) return new Pos(line, ch);
2458
+ this.line = line; this.ch = ch;
2459
+ }
2460
+ CodeMirror.Pos = Pos;
2461
+
2462
+ function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
2463
+ function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
2464
+ function copyPos(x) {return Pos(x.line, x.ch);}
2465
+
2466
+ // SELECTION
2467
+
2468
+ function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
2469
+ function clipPos(doc, pos) {
2470
+ if (pos.line < doc.first) return Pos(doc.first, 0);
2471
+ var last = doc.first + doc.size - 1;
2472
+ if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
2473
+ return clipToLen(pos, getLine(doc, pos.line).text.length);
2474
+ }
2475
+ function clipToLen(pos, linelen) {
2476
+ var ch = pos.ch;
2477
+ if (ch == null || ch > linelen) return Pos(pos.line, linelen);
2478
+ else if (ch < 0) return Pos(pos.line, 0);
2479
+ else return pos;
2480
+ }
2481
+ function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
2482
+
2483
+ // If shift is held, this will move the selection anchor. Otherwise,
2484
+ // it'll set the whole selection.
2485
+ function extendSelection(doc, pos, other, bias) {
2486
+ if (doc.sel.shift || doc.sel.extend) {
2487
+ var anchor = doc.sel.anchor;
2488
+ if (other) {
2489
+ var posBefore = posLess(pos, anchor);
2490
+ if (posBefore != posLess(other, anchor)) {
2491
+ anchor = pos;
2492
+ pos = other;
2493
+ } else if (posBefore != posLess(pos, other)) {
2494
+ pos = other;
2495
+ }
2496
+ }
2497
+ setSelection(doc, anchor, pos, bias);
2498
+ } else {
2499
+ setSelection(doc, pos, other || pos, bias);
2500
+ }
2501
+ if (doc.cm) doc.cm.curOp.userSelChange = true;
2502
+ }
2503
+
2504
+ function filterSelectionChange(doc, anchor, head) {
2505
+ var obj = {anchor: anchor, head: head};
2506
+ signal(doc, "beforeSelectionChange", doc, obj);
2507
+ if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
2508
+ obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head);
2509
+ return obj;
2510
+ }
2511
+
2512
+ // Update the selection. Last two args are only used by
2513
+ // updateDoc, since they have to be expressed in the line
2514
+ // numbers before the update.
2515
+ function setSelection(doc, anchor, head, bias, checkAtomic) {
2516
+ if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) {
2517
+ var filtered = filterSelectionChange(doc, anchor, head);
2518
+ head = filtered.head;
2519
+ anchor = filtered.anchor;
2520
+ }
2521
+
2522
+ var sel = doc.sel;
2523
+ sel.goalColumn = null;
2524
+ // Skip over atomic spans.
2525
+ if (checkAtomic || !posEq(anchor, sel.anchor))
2526
+ anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
2527
+ if (checkAtomic || !posEq(head, sel.head))
2528
+ head = skipAtomic(doc, head, bias, checkAtomic != "push");
2529
+
2530
+ if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;
2531
+
2532
+ sel.anchor = anchor; sel.head = head;
2533
+ var inv = posLess(head, anchor);
2534
+ sel.from = inv ? head : anchor;
2535
+ sel.to = inv ? anchor : head;
2536
+
2537
+ if (doc.cm)
2538
+ doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
2539
+ doc.cm.curOp.cursorActivity = true;
2540
+
2541
+ signalLater(doc, "cursorActivity", doc);
2542
+ }
2543
+
2544
+ function reCheckSelection(cm) {
2545
+ setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push");
2546
+ }
2547
+
2548
+ function skipAtomic(doc, pos, bias, mayClear) {
2549
+ var flipped = false, curPos = pos;
2550
+ var dir = bias || 1;
2551
+ doc.cantEdit = false;
2552
+ search: for (;;) {
2553
+ var line = getLine(doc, curPos.line);
2554
+ if (line.markedSpans) {
2555
+ for (var i = 0; i < line.markedSpans.length; ++i) {
2556
+ var sp = line.markedSpans[i], m = sp.marker;
2557
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
2558
+ (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
2559
+ if (mayClear) {
2560
+ signal(m, "beforeCursorEnter");
2561
+ if (m.explicitlyCleared) {
2562
+ if (!line.markedSpans) break;
2563
+ else {--i; continue;}
2564
+ }
2565
+ }
2566
+ if (!m.atomic) continue;
2567
+ var newPos = m.find()[dir < 0 ? "from" : "to"];
2568
+ if (posEq(newPos, curPos)) {
2569
+ newPos.ch += dir;
2570
+ if (newPos.ch < 0) {
2571
+ if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
2572
+ else newPos = null;
2573
+ } else if (newPos.ch > line.text.length) {
2574
+ if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
2575
+ else newPos = null;
2576
+ }
2577
+ if (!newPos) {
2578
+ if (flipped) {
2579
+ // Driven in a corner -- no valid cursor position found at all
2580
+ // -- try again *with* clearing, if we didn't already
2581
+ if (!mayClear) return skipAtomic(doc, pos, bias, true);
2582
+ // Otherwise, turn off editing until further notice, and return the start of the doc
2583
+ doc.cantEdit = true;
2584
+ return Pos(doc.first, 0);
2585
+ }
2586
+ flipped = true; newPos = pos; dir = -dir;
2587
+ }
2588
+ }
2589
+ curPos = newPos;
2590
+ continue search;
2591
+ }
2592
+ }
2593
+ }
2594
+ return curPos;
2595
+ }
2596
+ }
2597
+
2598
+ // SCROLLING
2599
+
2600
+ function scrollCursorIntoView(cm) {
2601
+ var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);
2602
+ if (!cm.state.focused) return;
2603
+ var display = cm.display, box = getRect(display.sizer), doScroll = null;
2604
+ if (coords.top + box.top < 0) doScroll = true;
2605
+ else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
2606
+ if (doScroll != null && !phantom) {
2607
+ var hidden = display.cursor.style.display == "none";
2608
+ if (hidden) {
2609
+ display.cursor.style.display = "";
2610
+ display.cursor.style.left = coords.left + "px";
2611
+ display.cursor.style.top = (coords.top - display.viewOffset) + "px";
2612
+ }
2613
+ display.cursor.scrollIntoView(doScroll);
2614
+ if (hidden) display.cursor.style.display = "none";
2615
+ }
2616
+ }
2617
+
2618
+ function scrollPosIntoView(cm, pos, margin) {
2619
+ if (margin == null) margin = 0;
2620
+ for (;;) {
2621
+ var changed = false, coords = cursorCoords(cm, pos);
2622
+ var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin);
2623
+ var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
2624
+ if (scrollPos.scrollTop != null) {
2625
+ setScrollTop(cm, scrollPos.scrollTop);
2626
+ if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
2627
+ }
2628
+ if (scrollPos.scrollLeft != null) {
2629
+ setScrollLeft(cm, scrollPos.scrollLeft);
2630
+ if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
2631
+ }
2632
+ if (!changed) return coords;
2633
+ }
2634
+ }
2635
+
2636
+ function scrollIntoView(cm, x1, y1, x2, y2) {
2637
+ var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
2638
+ if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
2639
+ if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
2640
+ }
2641
+
2642
+ function calculateScrollPos(cm, x1, y1, x2, y2) {
2643
+ var display = cm.display, snapMargin = textHeight(cm.display);
2644
+ if (y1 < 0) y1 = 0;
2645
+ var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
2646
+ var docBottom = cm.doc.height + paddingVert(display);
2647
+ var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
2648
+ if (y1 < screentop) {
2649
+ result.scrollTop = atTop ? 0 : y1;
2650
+ } else if (y2 > screentop + screen) {
2651
+ var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
2652
+ if (newTop != screentop) result.scrollTop = newTop;
2653
+ }
2654
+
2655
+ var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
2656
+ x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
2657
+ var gutterw = display.gutters.offsetWidth;
2658
+ var atLeft = x1 < gutterw + 10;
2659
+ if (x1 < screenleft + gutterw || atLeft) {
2660
+ if (atLeft) x1 = 0;
2661
+ result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
2662
+ } else if (x2 > screenw + screenleft - 3) {
2663
+ result.scrollLeft = x2 + 10 - screenw;
2664
+ }
2665
+ return result;
2666
+ }
2667
+
2668
+ function updateScrollPos(cm, left, top) {
2669
+ cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left,
2670
+ scrollTop: top == null ? cm.doc.scrollTop : top};
2671
+ }
2672
+
2673
+ function addToScrollPos(cm, left, top) {
2674
+ var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop});
2675
+ var scroll = cm.display.scroller;
2676
+ pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top));
2677
+ pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left));
2678
+ }
2679
+
2680
+ // API UTILITIES
2681
+
2682
+ function indentLine(cm, n, how, aggressive) {
2683
+ var doc = cm.doc;
2684
+ if (how == null) how = "add";
2685
+ if (how == "smart") {
2686
+ if (!cm.doc.mode.indent) how = "prev";
2687
+ else var state = getStateBefore(cm, n);
2688
+ }
2689
+
2690
+ var tabSize = cm.options.tabSize;
2691
+ var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
2692
+ var curSpaceString = line.text.match(/^\s*/)[0], indentation;
2693
+ if (how == "smart") {
2694
+ indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
2695
+ if (indentation == Pass) {
2696
+ if (!aggressive) return;
2697
+ how = "prev";
2698
+ }
2699
+ }
2700
+ if (how == "prev") {
2701
+ if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
2702
+ else indentation = 0;
2703
+ } else if (how == "add") {
2704
+ indentation = curSpace + cm.options.indentUnit;
2705
+ } else if (how == "subtract") {
2706
+ indentation = curSpace - cm.options.indentUnit;
2707
+ } else if (typeof how == "number") {
2708
+ indentation = curSpace + how;
2709
+ }
2710
+ indentation = Math.max(0, indentation);
2711
+
2712
+ var indentString = "", pos = 0;
2713
+ if (cm.options.indentWithTabs)
2714
+ for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
2715
+ if (pos < indentation) indentString += spaceStr(indentation - pos);
2716
+
2717
+ if (indentString != curSpaceString)
2718
+ replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
2719
+ line.stateAfter = null;
2720
+ }
2721
+
2722
+ function changeLine(cm, handle, op) {
2723
+ var no = handle, line = handle, doc = cm.doc;
2724
+ if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
2725
+ else no = lineNo(handle);
2726
+ if (no == null) return null;
2727
+ if (op(line, no)) regChange(cm, no, no + 1);
2728
+ else return null;
2729
+ return line;
2730
+ }
2731
+
2732
+ function findPosH(doc, pos, dir, unit, visually) {
2733
+ var line = pos.line, ch = pos.ch, origDir = dir;
2734
+ var lineObj = getLine(doc, line);
2735
+ var possible = true;
2736
+ function findNextLine() {
2737
+ var l = line + dir;
2738
+ if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
2739
+ line = l;
2740
+ return lineObj = getLine(doc, l);
2741
+ }
2742
+ function moveOnce(boundToLine) {
2743
+ var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
2744
+ if (next == null) {
2745
+ if (!boundToLine && findNextLine()) {
2746
+ if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
2747
+ else ch = dir < 0 ? lineObj.text.length : 0;
2748
+ } else return (possible = false);
2749
+ } else ch = next;
2750
+ return true;
2751
+ }
2752
+
2753
+ if (unit == "char") moveOnce();
2754
+ else if (unit == "column") moveOnce(true);
2755
+ else if (unit == "word" || unit == "group") {
2756
+ var sawType = null, group = unit == "group";
2757
+ for (var first = true;; first = false) {
2758
+ if (dir < 0 && !moveOnce(!first)) break;
2759
+ var cur = lineObj.text.charAt(ch) || "\n";
2760
+ var type = isWordChar(cur) ? "w"
2761
+ : !group ? null
2762
+ : /\s/.test(cur) ? null
2763
+ : "p";
2764
+ if (sawType && sawType != type) {
2765
+ if (dir < 0) {dir = 1; moveOnce();}
2766
+ break;
2767
+ }
2768
+ if (type) sawType = type;
2769
+ if (dir > 0 && !moveOnce(!first)) break;
2770
+ }
2771
+ }
2772
+ var result = skipAtomic(doc, Pos(line, ch), origDir, true);
2773
+ if (!possible) result.hitSide = true;
2774
+ return result;
2775
+ }
2776
+
2777
+ function findPosV(cm, pos, dir, unit) {
2778
+ var doc = cm.doc, x = pos.left, y;
2779
+ if (unit == "page") {
2780
+ var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
2781
+ y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
2782
+ } else if (unit == "line") {
2783
+ y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
2784
+ }
2785
+ for (;;) {
2786
+ var target = coordsChar(cm, x, y);
2787
+ if (!target.outside) break;
2788
+ if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
2789
+ y += dir * 5;
2790
+ }
2791
+ return target;
2792
+ }
2793
+
2794
+ function findWordAt(line, pos) {
2795
+ var start = pos.ch, end = pos.ch;
2796
+ if (line) {
2797
+ if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
2798
+ var startChar = line.charAt(start);
2799
+ var check = isWordChar(startChar) ? isWordChar
2800
+ : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
2801
+ : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
2802
+ while (start > 0 && check(line.charAt(start - 1))) --start;
2803
+ while (end < line.length && check(line.charAt(end))) ++end;
2804
+ }
2805
+ return {from: Pos(pos.line, start), to: Pos(pos.line, end)};
2806
+ }
2807
+
2808
+ function selectLine(cm, line) {
2809
+ extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0)));
2810
+ }
2811
+
2812
+ // PROTOTYPE
2813
+
2814
+ // The publicly visible API. Note that operation(null, f) means
2815
+ // 'wrap f in an operation, performed on its `this` parameter'
2816
+
2817
+ CodeMirror.prototype = {
2818
+ constructor: CodeMirror,
2819
+ focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
2820
+
2821
+ setOption: function(option, value) {
2822
+ var options = this.options, old = options[option];
2823
+ if (options[option] == value && option != "mode") return;
2824
+ options[option] = value;
2825
+ if (optionHandlers.hasOwnProperty(option))
2826
+ operation(this, optionHandlers[option])(this, value, old);
2827
+ },
2828
+
2829
+ getOption: function(option) {return this.options[option];},
2830
+ getDoc: function() {return this.doc;},
2831
+
2832
+ addKeyMap: function(map, bottom) {
2833
+ this.state.keyMaps[bottom ? "push" : "unshift"](map);
2834
+ },
2835
+ removeKeyMap: function(map) {
2836
+ var maps = this.state.keyMaps;
2837
+ for (var i = 0; i < maps.length; ++i)
2838
+ if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
2839
+ maps.splice(i, 1);
2840
+ return true;
2841
+ }
2842
+ },
2843
+
2844
+ addOverlay: operation(null, function(spec, options) {
2845
+ var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
2846
+ if (mode.startState) throw new Error("Overlays may not be stateful.");
2847
+ this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
2848
+ this.state.modeGen++;
2849
+ regChange(this);
2850
+ }),
2851
+ removeOverlay: operation(null, function(spec) {
2852
+ var overlays = this.state.overlays;
2853
+ for (var i = 0; i < overlays.length; ++i) {
2854
+ var cur = overlays[i].modeSpec;
2855
+ if (cur == spec || typeof spec == "string" && cur.name == spec) {
2856
+ overlays.splice(i, 1);
2857
+ this.state.modeGen++;
2858
+ regChange(this);
2859
+ return;
2860
+ }
2861
+ }
2862
+ }),
2863
+
2864
+ indentLine: operation(null, function(n, dir, aggressive) {
2865
+ if (typeof dir != "string" && typeof dir != "number") {
2866
+ if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
2867
+ else dir = dir ? "add" : "subtract";
2868
+ }
2869
+ if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
2870
+ }),
2871
+ indentSelection: operation(null, function(how) {
2872
+ var sel = this.doc.sel;
2873
+ if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
2874
+ var e = sel.to.line - (sel.to.ch ? 0 : 1);
2875
+ for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
2876
+ }),
2877
+
2878
+ // Fetch the parser token for a given character. Useful for hacks
2879
+ // that want to inspect the mode state (say, for completion).
2880
+ getTokenAt: function(pos, precise) {
2881
+ var doc = this.doc;
2882
+ pos = clipPos(doc, pos);
2883
+ var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
2884
+ var line = getLine(doc, pos.line);
2885
+ var stream = new StringStream(line.text, this.options.tabSize);
2886
+ while (stream.pos < pos.ch && !stream.eol()) {
2887
+ stream.start = stream.pos;
2888
+ var style = mode.token(stream, state);
2889
+ }
2890
+ return {start: stream.start,
2891
+ end: stream.pos,
2892
+ string: stream.current(),
2893
+ className: style || null, // Deprecated, use 'type' instead
2894
+ type: style || null,
2895
+ state: state};
2896
+ },
2897
+
2898
+ getTokenTypeAt: function(pos) {
2899
+ pos = clipPos(this.doc, pos);
2900
+ var styles = getLineStyles(this, getLine(this.doc, pos.line));
2901
+ var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
2902
+ if (ch == 0) return styles[2];
2903
+ for (;;) {
2904
+ var mid = (before + after) >> 1;
2905
+ if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
2906
+ else if (styles[mid * 2 + 1] < ch) before = mid + 1;
2907
+ else return styles[mid * 2 + 2];
2908
+ }
2909
+ },
2910
+
2911
+ getModeAt: function(pos) {
2912
+ var mode = this.doc.mode;
2913
+ if (!mode.innerMode) return mode;
2914
+ return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
2915
+ },
2916
+
2917
+ getHelper: function(pos, type) {
2918
+ if (!helpers.hasOwnProperty(type)) return;
2919
+ var help = helpers[type], mode = this.getModeAt(pos);
2920
+ return mode[type] && help[mode[type]] ||
2921
+ mode.helperType && help[mode.helperType] ||
2922
+ help[mode.name];
2923
+ },
2924
+
2925
+ getStateAfter: function(line, precise) {
2926
+ var doc = this.doc;
2927
+ line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
2928
+ return getStateBefore(this, line + 1, precise);
2929
+ },
2930
+
2931
+ cursorCoords: function(start, mode) {
2932
+ var pos, sel = this.doc.sel;
2933
+ if (start == null) pos = sel.head;
2934
+ else if (typeof start == "object") pos = clipPos(this.doc, start);
2935
+ else pos = start ? sel.from : sel.to;
2936
+ return cursorCoords(this, pos, mode || "page");
2937
+ },
2938
+
2939
+ charCoords: function(pos, mode) {
2940
+ return charCoords(this, clipPos(this.doc, pos), mode || "page");
2941
+ },
2942
+
2943
+ coordsChar: function(coords, mode) {
2944
+ coords = fromCoordSystem(this, coords, mode || "page");
2945
+ return coordsChar(this, coords.left, coords.top);
2946
+ },
2947
+
2948
+ lineAtHeight: function(height, mode) {
2949
+ height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
2950
+ return lineAtHeight(this.doc, height + this.display.viewOffset);
2951
+ },
2952
+ heightAtLine: function(line, mode) {
2953
+ var end = false, last = this.doc.first + this.doc.size - 1;
2954
+ if (line < this.doc.first) line = this.doc.first;
2955
+ else if (line > last) { line = last; end = true; }
2956
+ var lineObj = getLine(this.doc, line);
2957
+ return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
2958
+ (end ? lineObj.height : 0);
2959
+ },
2960
+
2961
+ defaultTextHeight: function() { return textHeight(this.display); },
2962
+ defaultCharWidth: function() { return charWidth(this.display); },
2963
+
2964
+ setGutterMarker: operation(null, function(line, gutterID, value) {
2965
+ return changeLine(this, line, function(line) {
2966
+ var markers = line.gutterMarkers || (line.gutterMarkers = {});
2967
+ markers[gutterID] = value;
2968
+ if (!value && isEmpty(markers)) line.gutterMarkers = null;
2969
+ return true;
2970
+ });
2971
+ }),
2972
+
2973
+ clearGutter: operation(null, function(gutterID) {
2974
+ var cm = this, doc = cm.doc, i = doc.first;
2975
+ doc.iter(function(line) {
2976
+ if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
2977
+ line.gutterMarkers[gutterID] = null;
2978
+ regChange(cm, i, i + 1);
2979
+ if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
2980
+ }
2981
+ ++i;
2982
+ });
2983
+ }),
2984
+
2985
+ addLineClass: operation(null, function(handle, where, cls) {
2986
+ return changeLine(this, handle, function(line) {
2987
+ var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2988
+ if (!line[prop]) line[prop] = cls;
2989
+ else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
2990
+ else line[prop] += " " + cls;
2991
+ return true;
2992
+ });
2993
+ }),
2994
+
2995
+ removeLineClass: operation(null, function(handle, where, cls) {
2996
+ return changeLine(this, handle, function(line) {
2997
+ var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2998
+ var cur = line[prop];
2999
+ if (!cur) return false;
3000
+ else if (cls == null) line[prop] = null;
3001
+ else {
3002
+ var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
3003
+ if (!found) return false;
3004
+ var end = found.index + found[0].length;
3005
+ line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
3006
+ }
3007
+ return true;
3008
+ });
3009
+ }),
3010
+
3011
+ addLineWidget: operation(null, function(handle, node, options) {
3012
+ return addLineWidget(this, handle, node, options);
3013
+ }),
3014
+
3015
+ removeLineWidget: function(widget) { widget.clear(); },
3016
+
3017
+ lineInfo: function(line) {
3018
+ if (typeof line == "number") {
3019
+ if (!isLine(this.doc, line)) return null;
3020
+ var n = line;
3021
+ line = getLine(this.doc, line);
3022
+ if (!line) return null;
3023
+ } else {
3024
+ var n = lineNo(line);
3025
+ if (n == null) return null;
3026
+ }
3027
+ return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
3028
+ textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
3029
+ widgets: line.widgets};
3030
+ },
3031
+
3032
+ getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},
3033
+
3034
+ addWidget: function(pos, node, scroll, vert, horiz) {
3035
+ var display = this.display;
3036
+ pos = cursorCoords(this, clipPos(this.doc, pos));
3037
+ var top = pos.bottom, left = pos.left;
3038
+ node.style.position = "absolute";
3039
+ display.sizer.appendChild(node);
3040
+ if (vert == "over") {
3041
+ top = pos.top;
3042
+ } else if (vert == "above" || vert == "near") {
3043
+ var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
3044
+ hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
3045
+ // Default to positioning above (if specified and possible); otherwise default to positioning below
3046
+ if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
3047
+ top = pos.top - node.offsetHeight;
3048
+ else if (pos.bottom + node.offsetHeight <= vspace)
3049
+ top = pos.bottom;
3050
+ if (left + node.offsetWidth > hspace)
3051
+ left = hspace - node.offsetWidth;
3052
+ }
3053
+ node.style.top = top + "px";
3054
+ node.style.left = node.style.right = "";
3055
+ if (horiz == "right") {
3056
+ left = display.sizer.clientWidth - node.offsetWidth;
3057
+ node.style.right = "0px";
3058
+ } else {
3059
+ if (horiz == "left") left = 0;
3060
+ else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
3061
+ node.style.left = left + "px";
3062
+ }
3063
+ if (scroll)
3064
+ scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
3065
+ },
3066
+
3067
+ triggerOnKeyDown: operation(null, onKeyDown),
3068
+
3069
+ execCommand: function(cmd) {return commands[cmd](this);},
3070
+
3071
+ findPosH: function(from, amount, unit, visually) {
3072
+ var dir = 1;
3073
+ if (amount < 0) { dir = -1; amount = -amount; }
3074
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
3075
+ cur = findPosH(this.doc, cur, dir, unit, visually);
3076
+ if (cur.hitSide) break;
3077
+ }
3078
+ return cur;
3079
+ },
3080
+
3081
+ moveH: operation(null, function(dir, unit) {
3082
+ var sel = this.doc.sel, pos;
3083
+ if (sel.shift || sel.extend || posEq(sel.from, sel.to))
3084
+ pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually);
3085
+ else
3086
+ pos = dir < 0 ? sel.from : sel.to;
3087
+ extendSelection(this.doc, pos, pos, dir);
3088
+ }),
3089
+
3090
+ deleteH: operation(null, function(dir, unit) {
3091
+ var sel = this.doc.sel;
3092
+ if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete");
3093
+ else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete");
3094
+ this.curOp.userSelChange = true;
3095
+ }),
3096
+
3097
+ findPosV: function(from, amount, unit, goalColumn) {
3098
+ var dir = 1, x = goalColumn;
3099
+ if (amount < 0) { dir = -1; amount = -amount; }
3100
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
3101
+ var coords = cursorCoords(this, cur, "div");
3102
+ if (x == null) x = coords.left;
3103
+ else coords.left = x;
3104
+ cur = findPosV(this, coords, dir, unit);
3105
+ if (cur.hitSide) break;
3106
+ }
3107
+ return cur;
3108
+ },
3109
+
3110
+ moveV: operation(null, function(dir, unit) {
3111
+ var sel = this.doc.sel;
3112
+ var pos = cursorCoords(this, sel.head, "div");
3113
+ if (sel.goalColumn != null) pos.left = sel.goalColumn;
3114
+ var target = findPosV(this, pos, dir, unit);
3115
+
3116
+ if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
3117
+ extendSelection(this.doc, target, target, dir);
3118
+ sel.goalColumn = pos.left;
3119
+ }),
3120
+
3121
+ toggleOverwrite: function(value) {
3122
+ if (value != null && value == this.state.overwrite) return;
3123
+ if (this.state.overwrite = !this.state.overwrite)
3124
+ this.display.cursor.className += " CodeMirror-overwrite";
3125
+ else
3126
+ this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
3127
+ },
3128
+ hasFocus: function() { return this.state.focused; },
3129
+
3130
+ scrollTo: operation(null, function(x, y) {
3131
+ updateScrollPos(this, x, y);
3132
+ }),
3133
+ getScrollInfo: function() {
3134
+ var scroller = this.display.scroller, co = scrollerCutOff;
3135
+ return {left: scroller.scrollLeft, top: scroller.scrollTop,
3136
+ height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
3137
+ clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
3138
+ },
3139
+
3140
+ scrollIntoView: operation(null, function(pos, margin) {
3141
+ if (typeof pos == "number") pos = Pos(pos, 0);
3142
+ if (!margin) margin = 0;
3143
+ var coords = pos;
3144
+
3145
+ if (!pos || pos.line != null) {
3146
+ this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
3147
+ this.curOp.scrollToPosMargin = margin;
3148
+ coords = cursorCoords(this, this.curOp.scrollToPos);
3149
+ }
3150
+ var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin);
3151
+ updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
3152
+ }),
3153
+
3154
+ setSize: operation(null, function(width, height) {
3155
+ function interpret(val) {
3156
+ return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
3157
+ }
3158
+ if (width != null) this.display.wrapper.style.width = interpret(width);
3159
+ if (height != null) this.display.wrapper.style.height = interpret(height);
3160
+ if (this.options.lineWrapping)
3161
+ this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
3162
+ this.curOp.forceUpdate = true;
3163
+ }),
3164
+
3165
+ operation: function(f){return runInOp(this, f);},
3166
+
3167
+ refresh: operation(null, function() {
3168
+ clearCaches(this);
3169
+ updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
3170
+ regChange(this);
3171
+ }),
3172
+
3173
+ swapDoc: operation(null, function(doc) {
3174
+ var old = this.doc;
3175
+ old.cm = null;
3176
+ attachDoc(this, doc);
3177
+ clearCaches(this);
3178
+ resetInput(this, true);
3179
+ updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
3180
+ return old;
3181
+ }),
3182
+
3183
+ getInputField: function(){return this.display.input;},
3184
+ getWrapperElement: function(){return this.display.wrapper;},
3185
+ getScrollerElement: function(){return this.display.scroller;},
3186
+ getGutterElement: function(){return this.display.gutters;}
3187
+ };
3188
+ eventMixin(CodeMirror);
3189
+
3190
+ // OPTION DEFAULTS
3191
+
3192
+ var optionHandlers = CodeMirror.optionHandlers = {};
3193
+
3194
+ // The default configuration options.
3195
+ var defaults = CodeMirror.defaults = {};
3196
+
3197
+ function option(name, deflt, handle, notOnInit) {
3198
+ CodeMirror.defaults[name] = deflt;
3199
+ if (handle) optionHandlers[name] =
3200
+ notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
3201
+ }
3202
+
3203
+ var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
3204
+
3205
+ // These two are, on init, called from the constructor because they
3206
+ // have to be initialized before the editor can start at all.
3207
+ option("value", "", function(cm, val) {
3208
+ cm.setValue(val);
3209
+ }, true);
3210
+ option("mode", null, function(cm, val) {
3211
+ cm.doc.modeOption = val;
3212
+ loadMode(cm);
3213
+ }, true);
3214
+
3215
+ option("indentUnit", 2, loadMode, true);
3216
+ option("indentWithTabs", false);
3217
+ option("smartIndent", true);
3218
+ option("tabSize", 4, function(cm) {
3219
+ loadMode(cm);
3220
+ clearCaches(cm);
3221
+ regChange(cm);
3222
+ }, true);
3223
+ option("electricChars", true);
3224
+ option("rtlMoveVisually", !windows);
3225
+
3226
+ option("theme", "default", function(cm) {
3227
+ themeChanged(cm);
3228
+ guttersChanged(cm);
3229
+ }, true);
3230
+ option("keyMap", "default", keyMapChanged);
3231
+ option("extraKeys", null);
3232
+
3233
+ option("onKeyEvent", null);
3234
+ option("onDragEvent", null);
3235
+
3236
+ option("lineWrapping", false, wrappingChanged, true);
3237
+ option("gutters", [], function(cm) {
3238
+ setGuttersForLineNumbers(cm.options);
3239
+ guttersChanged(cm);
3240
+ }, true);
3241
+ option("fixedGutter", true, function(cm, val) {
3242
+ cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
3243
+ cm.refresh();
3244
+ }, true);
3245
+ option("coverGutterNextToScrollbar", false, updateScrollbars, true);
3246
+ option("lineNumbers", false, function(cm) {
3247
+ setGuttersForLineNumbers(cm.options);
3248
+ guttersChanged(cm);
3249
+ }, true);
3250
+ option("firstLineNumber", 1, guttersChanged, true);
3251
+ option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
3252
+ option("showCursorWhenSelecting", false, updateSelection, true);
3253
+
3254
+ option("readOnly", false, function(cm, val) {
3255
+ if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
3256
+ else if (!val) resetInput(cm, true);
3257
+ });
3258
+ option("dragDrop", true);
3259
+
3260
+ option("cursorBlinkRate", 530);
3261
+ option("cursorScrollMargin", 0);
3262
+ option("cursorHeight", 1);
3263
+ option("workTime", 100);
3264
+ option("workDelay", 100);
3265
+ option("flattenSpans", true);
3266
+ option("pollInterval", 100);
3267
+ option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
3268
+ option("historyEventDelay", 500);
3269
+ option("viewportMargin", 10, function(cm){cm.refresh();}, true);
3270
+ option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
3271
+ option("moveInputWithCursor", true, function(cm, val) {
3272
+ if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
3273
+ });
3274
+
3275
+ option("tabindex", null, function(cm, val) {
3276
+ cm.display.input.tabIndex = val || "";
3277
+ });
3278
+ option("autofocus", null);
3279
+
3280
+ // MODE DEFINITION AND QUERYING
3281
+
3282
+ // Known modes, by name and by MIME
3283
+ var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
3284
+
3285
+ CodeMirror.defineMode = function(name, mode) {
3286
+ if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
3287
+ if (arguments.length > 2) {
3288
+ mode.dependencies = [];
3289
+ for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
3290
+ }
3291
+ modes[name] = mode;
3292
+ };
3293
+
3294
+ CodeMirror.defineMIME = function(mime, spec) {
3295
+ mimeModes[mime] = spec;
3296
+ };
3297
+
3298
+ CodeMirror.resolveMode = function(spec) {
3299
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
3300
+ spec = mimeModes[spec];
3301
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
3302
+ var found = mimeModes[spec.name];
3303
+ spec = createObj(found, spec);
3304
+ spec.name = found.name;
3305
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
3306
+ return CodeMirror.resolveMode("application/xml");
3307
+ }
3308
+ if (typeof spec == "string") return {name: spec};
3309
+ else return spec || {name: "null"};
3310
+ };
3311
+
3312
+ CodeMirror.getMode = function(options, spec) {
3313
+ var spec = CodeMirror.resolveMode(spec);
3314
+ var mfactory = modes[spec.name];
3315
+ if (!mfactory) return CodeMirror.getMode(options, "text/plain");
3316
+ var modeObj = mfactory(options, spec);
3317
+ if (modeExtensions.hasOwnProperty(spec.name)) {
3318
+ var exts = modeExtensions[spec.name];
3319
+ for (var prop in exts) {
3320
+ if (!exts.hasOwnProperty(prop)) continue;
3321
+ if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
3322
+ modeObj[prop] = exts[prop];
3323
+ }
3324
+ }
3325
+ modeObj.name = spec.name;
3326
+
3327
+ return modeObj;
3328
+ };
3329
+
3330
+ CodeMirror.defineMode("null", function() {
3331
+ return {token: function(stream) {stream.skipToEnd();}};
3332
+ });
3333
+ CodeMirror.defineMIME("text/plain", "null");
3334
+
3335
+ var modeExtensions = CodeMirror.modeExtensions = {};
3336
+ CodeMirror.extendMode = function(mode, properties) {
3337
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
3338
+ copyObj(properties, exts);
3339
+ };
3340
+
3341
+ // EXTENSIONS
3342
+
3343
+ CodeMirror.defineExtension = function(name, func) {
3344
+ CodeMirror.prototype[name] = func;
3345
+ };
3346
+ CodeMirror.defineDocExtension = function(name, func) {
3347
+ Doc.prototype[name] = func;
3348
+ };
3349
+ CodeMirror.defineOption = option;
3350
+
3351
+ var initHooks = [];
3352
+ CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
3353
+
3354
+ var helpers = CodeMirror.helpers = {};
3355
+ CodeMirror.registerHelper = function(type, name, value) {
3356
+ if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
3357
+ helpers[type][name] = value;
3358
+ };
3359
+
3360
+ // UTILITIES
3361
+
3362
+ CodeMirror.isWordChar = isWordChar;
3363
+
3364
+ // MODE STATE HANDLING
3365
+
3366
+ // Utility functions for working with state. Exported because modes
3367
+ // sometimes need to do this.
3368
+ function copyState(mode, state) {
3369
+ if (state === true) return state;
3370
+ if (mode.copyState) return mode.copyState(state);
3371
+ var nstate = {};
3372
+ for (var n in state) {
3373
+ var val = state[n];
3374
+ if (val instanceof Array) val = val.concat([]);
3375
+ nstate[n] = val;
3376
+ }
3377
+ return nstate;
3378
+ }
3379
+ CodeMirror.copyState = copyState;
3380
+
3381
+ function startState(mode, a1, a2) {
3382
+ return mode.startState ? mode.startState(a1, a2) : true;
3383
+ }
3384
+ CodeMirror.startState = startState;
3385
+
3386
+ CodeMirror.innerMode = function(mode, state) {
3387
+ while (mode.innerMode) {
3388
+ var info = mode.innerMode(state);
3389
+ if (!info || info.mode == mode) break;
3390
+ state = info.state;
3391
+ mode = info.mode;
3392
+ }
3393
+ return info || {mode: mode, state: state};
3394
+ };
3395
+
3396
+ // STANDARD COMMANDS
3397
+
3398
+ var commands = CodeMirror.commands = {
3399
+ selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
3400
+ killLine: function(cm) {
3401
+ var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
3402
+ if (!sel && cm.getLine(from.line).length == from.ch)
3403
+ cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
3404
+ else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
3405
+ },
3406
+ deleteLine: function(cm) {
3407
+ var l = cm.getCursor().line;
3408
+ cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
3409
+ },
3410
+ delLineLeft: function(cm) {
3411
+ var cur = cm.getCursor();
3412
+ cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
3413
+ },
3414
+ undo: function(cm) {cm.undo();},
3415
+ redo: function(cm) {cm.redo();},
3416
+ goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
3417
+ goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
3418
+ goLineStart: function(cm) {
3419
+ cm.extendSelection(lineStart(cm, cm.getCursor().line));
3420
+ },
3421
+ goLineStartSmart: function(cm) {
3422
+ var cur = cm.getCursor(), start = lineStart(cm, cur.line);
3423
+ var line = cm.getLineHandle(start.line);
3424
+ var order = getOrder(line);
3425
+ if (!order || order[0].level == 0) {
3426
+ var firstNonWS = Math.max(0, line.text.search(/\S/));
3427
+ var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
3428
+ cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS));
3429
+ } else cm.extendSelection(start);
3430
+ },
3431
+ goLineEnd: function(cm) {
3432
+ cm.extendSelection(lineEnd(cm, cm.getCursor().line));
3433
+ },
3434
+ goLineRight: function(cm) {
3435
+ var top = cm.charCoords(cm.getCursor(), "div").top + 5;
3436
+ cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"));
3437
+ },
3438
+ goLineLeft: function(cm) {
3439
+ var top = cm.charCoords(cm.getCursor(), "div").top + 5;
3440
+ cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div"));
3441
+ },
3442
+ goLineUp: function(cm) {cm.moveV(-1, "line");},
3443
+ goLineDown: function(cm) {cm.moveV(1, "line");},
3444
+ goPageUp: function(cm) {cm.moveV(-1, "page");},
3445
+ goPageDown: function(cm) {cm.moveV(1, "page");},
3446
+ goCharLeft: function(cm) {cm.moveH(-1, "char");},
3447
+ goCharRight: function(cm) {cm.moveH(1, "char");},
3448
+ goColumnLeft: function(cm) {cm.moveH(-1, "column");},
3449
+ goColumnRight: function(cm) {cm.moveH(1, "column");},
3450
+ goWordLeft: function(cm) {cm.moveH(-1, "word");},
3451
+ goGroupRight: function(cm) {cm.moveH(1, "group");},
3452
+ goGroupLeft: function(cm) {cm.moveH(-1, "group");},
3453
+ goWordRight: function(cm) {cm.moveH(1, "word");},
3454
+ delCharBefore: function(cm) {cm.deleteH(-1, "char");},
3455
+ delCharAfter: function(cm) {cm.deleteH(1, "char");},
3456
+ delWordBefore: function(cm) {cm.deleteH(-1, "word");},
3457
+ delWordAfter: function(cm) {cm.deleteH(1, "word");},
3458
+ delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
3459
+ delGroupAfter: function(cm) {cm.deleteH(1, "group");},
3460
+ indentAuto: function(cm) {cm.indentSelection("smart");},
3461
+ indentMore: function(cm) {cm.indentSelection("add");},
3462
+ indentLess: function(cm) {cm.indentSelection("subtract");},
3463
+ insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");},
3464
+ defaultTab: function(cm) {
3465
+ if (cm.somethingSelected()) cm.indentSelection("add");
3466
+ else cm.replaceSelection("\t", "end", "+input");
3467
+ },
3468
+ transposeChars: function(cm) {
3469
+ var cur = cm.getCursor(), line = cm.getLine(cur.line);
3470
+ if (cur.ch > 0 && cur.ch < line.length - 1)
3471
+ cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
3472
+ Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
3473
+ },
3474
+ newlineAndIndent: function(cm) {
3475
+ operation(cm, function() {
3476
+ cm.replaceSelection("\n", "end", "+input");
3477
+ cm.indentLine(cm.getCursor().line, null, true);
3478
+ })();
3479
+ },
3480
+ toggleOverwrite: function(cm) {cm.toggleOverwrite();}
3481
+ };
3482
+
3483
+ // STANDARD KEYMAPS
3484
+
3485
+ var keyMap = CodeMirror.keyMap = {};
3486
+ keyMap.basic = {
3487
+ "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
3488
+ "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
3489
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
3490
+ "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
3491
+ };
3492
+ // Note that the save and find-related commands aren't defined by
3493
+ // default. Unknown commands are simply ignored.
3494
+ keyMap.pcDefault = {
3495
+ "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
3496
+ "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
3497
+ "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
3498
+ "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
3499
+ "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
3500
+ "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
3501
+ fallthrough: "basic"
3502
+ };
3503
+ keyMap.macDefault = {
3504
+ "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
3505
+ "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
3506
+ "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore",
3507
+ "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
3508
+ "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
3509
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
3510
+ fallthrough: ["basic", "emacsy"]
3511
+ };
3512
+ keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
3513
+ keyMap.emacsy = {
3514
+ "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
3515
+ "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
3516
+ "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
3517
+ "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
3518
+ };
3519
+
3520
+ // KEYMAP DISPATCH
3521
+
3522
+ function getKeyMap(val) {
3523
+ if (typeof val == "string") return keyMap[val];
3524
+ else return val;
3525
+ }
3526
+
3527
+ function lookupKey(name, maps, handle) {
3528
+ function lookup(map) {
3529
+ map = getKeyMap(map);
3530
+ var found = map[name];
3531
+ if (found === false) return "stop";
3532
+ if (found != null && handle(found)) return true;
3533
+ if (map.nofallthrough) return "stop";
3534
+
3535
+ var fallthrough = map.fallthrough;
3536
+ if (fallthrough == null) return false;
3537
+ if (Object.prototype.toString.call(fallthrough) != "[object Array]")
3538
+ return lookup(fallthrough);
3539
+ for (var i = 0, e = fallthrough.length; i < e; ++i) {
3540
+ var done = lookup(fallthrough[i]);
3541
+ if (done) return done;
3542
+ }
3543
+ return false;
3544
+ }
3545
+
3546
+ for (var i = 0; i < maps.length; ++i) {
3547
+ var done = lookup(maps[i]);
3548
+ if (done) return done != "stop";
3549
+ }
3550
+ }
3551
+ function isModifierKey(event) {
3552
+ var name = keyNames[event.keyCode];
3553
+ return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
3554
+ }
3555
+ function keyName(event, noShift) {
3556
+ if (opera && event.keyCode == 34 && event["char"]) return false;
3557
+ var name = keyNames[event.keyCode];
3558
+ if (name == null || event.altGraphKey) return false;
3559
+ if (event.altKey) name = "Alt-" + name;
3560
+ if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
3561
+ if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
3562
+ if (!noShift && event.shiftKey) name = "Shift-" + name;
3563
+ return name;
3564
+ }
3565
+ CodeMirror.lookupKey = lookupKey;
3566
+ CodeMirror.isModifierKey = isModifierKey;
3567
+ CodeMirror.keyName = keyName;
3568
+
3569
+ // FROMTEXTAREA
3570
+
3571
+ CodeMirror.fromTextArea = function(textarea, options) {
3572
+ if (!options) options = {};
3573
+ options.value = textarea.value;
3574
+ if (!options.tabindex && textarea.tabindex)
3575
+ options.tabindex = textarea.tabindex;
3576
+ if (!options.placeholder && textarea.placeholder)
3577
+ options.placeholder = textarea.placeholder;
3578
+ // Set autofocus to true if this textarea is focused, or if it has
3579
+ // autofocus and no other element is focused.
3580
+ if (options.autofocus == null) {
3581
+ var hasFocus = document.body;
3582
+ // doc.activeElement occasionally throws on IE
3583
+ try { hasFocus = document.activeElement; } catch(e) {}
3584
+ options.autofocus = hasFocus == textarea ||
3585
+ textarea.getAttribute("autofocus") != null && hasFocus == document.body;
3586
+ }
3587
+
3588
+ function save() {textarea.value = cm.getValue();}
3589
+ if (textarea.form) {
3590
+ on(textarea.form, "submit", save);
3591
+ // Deplorable hack to make the submit method do the right thing.
3592
+ if (!options.leaveSubmitMethodAlone) {
3593
+ var form = textarea.form, realSubmit = form.submit;
3594
+ try {
3595
+ var wrappedSubmit = form.submit = function() {
3596
+ save();
3597
+ form.submit = realSubmit;
3598
+ form.submit();
3599
+ form.submit = wrappedSubmit;
3600
+ };
3601
+ } catch(e) {}
3602
+ }
3603
+ }
3604
+
3605
+ textarea.style.display = "none";
3606
+ var cm = CodeMirror(function(node) {
3607
+ textarea.parentNode.insertBefore(node, textarea.nextSibling);
3608
+ }, options);
3609
+ cm.save = save;
3610
+ cm.getTextArea = function() { return textarea; };
3611
+ cm.toTextArea = function() {
3612
+ save();
3613
+ textarea.parentNode.removeChild(cm.getWrapperElement());
3614
+ textarea.style.display = "";
3615
+ if (textarea.form) {
3616
+ off(textarea.form, "submit", save);
3617
+ if (typeof textarea.form.submit == "function")
3618
+ textarea.form.submit = realSubmit;
3619
+ }
3620
+ };
3621
+ return cm;
3622
+ };
3623
+
3624
+ // STRING STREAM
3625
+
3626
+ // Fed to the mode parsers, provides helper functions to make
3627
+ // parsers more succinct.
3628
+
3629
+ // The character stream used by a mode's parser.
3630
+ function StringStream(string, tabSize) {
3631
+ this.pos = this.start = 0;
3632
+ this.string = string;
3633
+ this.tabSize = tabSize || 8;
3634
+ this.lastColumnPos = this.lastColumnValue = 0;
3635
+ }
3636
+
3637
+ StringStream.prototype = {
3638
+ eol: function() {return this.pos >= this.string.length;},
3639
+ sol: function() {return this.pos == 0;},
3640
+ peek: function() {return this.string.charAt(this.pos) || undefined;},
3641
+ next: function() {
3642
+ if (this.pos < this.string.length)
3643
+ return this.string.charAt(this.pos++);
3644
+ },
3645
+ eat: function(match) {
3646
+ var ch = this.string.charAt(this.pos);
3647
+ if (typeof match == "string") var ok = ch == match;
3648
+ else var ok = ch && (match.test ? match.test(ch) : match(ch));
3649
+ if (ok) {++this.pos; return ch;}
3650
+ },
3651
+ eatWhile: function(match) {
3652
+ var start = this.pos;
3653
+ while (this.eat(match)){}
3654
+ return this.pos > start;
3655
+ },
3656
+ eatSpace: function() {
3657
+ var start = this.pos;
3658
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
3659
+ return this.pos > start;
3660
+ },
3661
+ skipToEnd: function() {this.pos = this.string.length;},
3662
+ skipTo: function(ch) {
3663
+ var found = this.string.indexOf(ch, this.pos);
3664
+ if (found > -1) {this.pos = found; return true;}
3665
+ },
3666
+ backUp: function(n) {this.pos -= n;},
3667
+ column: function() {
3668
+ if (this.lastColumnPos < this.start) {
3669
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
3670
+ this.lastColumnPos = this.start;
3671
+ }
3672
+ return this.lastColumnValue;
3673
+ },
3674
+ indentation: function() {return countColumn(this.string, null, this.tabSize);},
3675
+ match: function(pattern, consume, caseInsensitive) {
3676
+ if (typeof pattern == "string") {
3677
+ var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
3678
+ var substr = this.string.substr(this.pos, pattern.length);
3679
+ if (cased(substr) == cased(pattern)) {
3680
+ if (consume !== false) this.pos += pattern.length;
3681
+ return true;
3682
+ }
3683
+ } else {
3684
+ var match = this.string.slice(this.pos).match(pattern);
3685
+ if (match && match.index > 0) return null;
3686
+ if (match && consume !== false) this.pos += match[0].length;
3687
+ return match;
3688
+ }
3689
+ },
3690
+ current: function(){return this.string.slice(this.start, this.pos);}
3691
+ };
3692
+ CodeMirror.StringStream = StringStream;
3693
+
3694
+ // TEXTMARKERS
3695
+
3696
+ function TextMarker(doc, type) {
3697
+ this.lines = [];
3698
+ this.type = type;
3699
+ this.doc = doc;
3700
+ }
3701
+ CodeMirror.TextMarker = TextMarker;
3702
+ eventMixin(TextMarker);
3703
+
3704
+ TextMarker.prototype.clear = function() {
3705
+ if (this.explicitlyCleared) return;
3706
+ var cm = this.doc.cm, withOp = cm && !cm.curOp;
3707
+ if (withOp) startOperation(cm);
3708
+ if (hasHandler(this, "clear")) {
3709
+ var found = this.find();
3710
+ if (found) signalLater(this, "clear", found.from, found.to);
3711
+ }
3712
+ var min = null, max = null;
3713
+ for (var i = 0; i < this.lines.length; ++i) {
3714
+ var line = this.lines[i];
3715
+ var span = getMarkedSpanFor(line.markedSpans, this);
3716
+ if (span.to != null) max = lineNo(line);
3717
+ line.markedSpans = removeMarkedSpan(line.markedSpans, span);
3718
+ if (span.from != null)
3719
+ min = lineNo(line);
3720
+ else if (this.collapsed && !lineIsHidden(this.doc, line) && cm)
3721
+ updateLineHeight(line, textHeight(cm.display));
3722
+ }
3723
+ if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
3724
+ var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual);
3725
+ if (len > cm.display.maxLineLength) {
3726
+ cm.display.maxLine = visual;
3727
+ cm.display.maxLineLength = len;
3728
+ cm.display.maxLineChanged = true;
3729
+ }
3730
+ }
3731
+
3732
+ if (min != null && cm) regChange(cm, min, max + 1);
3733
+ this.lines.length = 0;
3734
+ this.explicitlyCleared = true;
3735
+ if (this.atomic && this.doc.cantEdit) {
3736
+ this.doc.cantEdit = false;
3737
+ if (cm) reCheckSelection(cm);
3738
+ }
3739
+ if (withOp) endOperation(cm);
3740
+ };
3741
+
3742
+ TextMarker.prototype.find = function() {
3743
+ var from, to;
3744
+ for (var i = 0; i < this.lines.length; ++i) {
3745
+ var line = this.lines[i];
3746
+ var span = getMarkedSpanFor(line.markedSpans, this);
3747
+ if (span.from != null || span.to != null) {
3748
+ var found = lineNo(line);
3749
+ if (span.from != null) from = Pos(found, span.from);
3750
+ if (span.to != null) to = Pos(found, span.to);
3751
+ }
3752
+ }
3753
+ if (this.type == "bookmark") return from;
3754
+ return from && {from: from, to: to};
3755
+ };
3756
+
3757
+ TextMarker.prototype.changed = function() {
3758
+ var pos = this.find(), cm = this.doc.cm;
3759
+ if (!pos || !cm) return;
3760
+ if (this.type != "bookmark") pos = pos.from;
3761
+ var line = getLine(this.doc, pos.line);
3762
+ clearCachedMeasurement(cm, line);
3763
+ if (pos.line >= cm.display.showingFrom && pos.line < cm.display.showingTo) {
3764
+ for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
3765
+ if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
3766
+ break;
3767
+ }
3768
+ runInOp(cm, function() {
3769
+ cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
3770
+ });
3771
+ }
3772
+ };
3773
+
3774
+ TextMarker.prototype.attachLine = function(line) {
3775
+ if (!this.lines.length && this.doc.cm) {
3776
+ var op = this.doc.cm.curOp;
3777
+ if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
3778
+ (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
3779
+ }
3780
+ this.lines.push(line);
3781
+ };
3782
+ TextMarker.prototype.detachLine = function(line) {
3783
+ this.lines.splice(indexOf(this.lines, line), 1);
3784
+ if (!this.lines.length && this.doc.cm) {
3785
+ var op = this.doc.cm.curOp;
3786
+ (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
3787
+ }
3788
+ };
3789
+
3790
+ function markText(doc, from, to, options, type) {
3791
+ if (options && options.shared) return markTextShared(doc, from, to, options, type);
3792
+ if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
3793
+
3794
+ var marker = new TextMarker(doc, type);
3795
+ if (type == "range" && !posLess(from, to)) return marker;
3796
+ if (options) copyObj(options, marker);
3797
+ if (marker.replacedWith) {
3798
+ marker.collapsed = true;
3799
+ marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
3800
+ if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
3801
+ }
3802
+ if (marker.collapsed) sawCollapsedSpans = true;
3803
+
3804
+ if (marker.addToHistory)
3805
+ addToHistory(doc, {from: from, to: to, origin: "markText"},
3806
+ {head: doc.sel.head, anchor: doc.sel.anchor}, NaN);
3807
+
3808
+ var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine;
3809
+ doc.iter(curLine, to.line + 1, function(line) {
3810
+ if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
3811
+ updateMaxLine = true;
3812
+ var span = {from: null, to: null, marker: marker};
3813
+ size += line.text.length;
3814
+ if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
3815
+ if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
3816
+ if (marker.collapsed) {
3817
+ if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
3818
+ if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
3819
+ else updateLineHeight(line, 0);
3820
+ }
3821
+ addMarkedSpan(line, span);
3822
+ ++curLine;
3823
+ });
3824
+ if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
3825
+ if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
3826
+ });
3827
+
3828
+ if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
3829
+
3830
+ if (marker.readOnly) {
3831
+ sawReadOnlySpans = true;
3832
+ if (doc.history.done.length || doc.history.undone.length)
3833
+ doc.clearHistory();
3834
+ }
3835
+ if (marker.collapsed) {
3836
+ if (collapsedAtStart != collapsedAtEnd)
3837
+ throw new Error("Inserting collapsed marker overlapping an existing one");
3838
+ marker.size = size;
3839
+ marker.atomic = true;
3840
+ }
3841
+ if (cm) {
3842
+ if (updateMaxLine) cm.curOp.updateMaxLine = true;
3843
+ if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
3844
+ regChange(cm, from.line, to.line + 1);
3845
+ if (marker.atomic) reCheckSelection(cm);
3846
+ }
3847
+ return marker;
3848
+ }
3849
+
3850
+ // SHARED TEXTMARKERS
3851
+
3852
+ function SharedTextMarker(markers, primary) {
3853
+ this.markers = markers;
3854
+ this.primary = primary;
3855
+ for (var i = 0, me = this; i < markers.length; ++i) {
3856
+ markers[i].parent = this;
3857
+ on(markers[i], "clear", function(){me.clear();});
3858
+ }
3859
+ }
3860
+ CodeMirror.SharedTextMarker = SharedTextMarker;
3861
+ eventMixin(SharedTextMarker);
3862
+
3863
+ SharedTextMarker.prototype.clear = function() {
3864
+ if (this.explicitlyCleared) return;
3865
+ this.explicitlyCleared = true;
3866
+ for (var i = 0; i < this.markers.length; ++i)
3867
+ this.markers[i].clear();
3868
+ signalLater(this, "clear");
3869
+ };
3870
+ SharedTextMarker.prototype.find = function() {
3871
+ return this.primary.find();
3872
+ };
3873
+
3874
+ function markTextShared(doc, from, to, options, type) {
3875
+ options = copyObj(options);
3876
+ options.shared = false;
3877
+ var markers = [markText(doc, from, to, options, type)], primary = markers[0];
3878
+ var widget = options.replacedWith;
3879
+ linkedDocs(doc, function(doc) {
3880
+ if (widget) options.replacedWith = widget.cloneNode(true);
3881
+ markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
3882
+ for (var i = 0; i < doc.linked.length; ++i)
3883
+ if (doc.linked[i].isParent) return;
3884
+ primary = lst(markers);
3885
+ });
3886
+ return new SharedTextMarker(markers, primary);
3887
+ }
3888
+
3889
+ // TEXTMARKER SPANS
3890
+
3891
+ function getMarkedSpanFor(spans, marker) {
3892
+ if (spans) for (var i = 0; i < spans.length; ++i) {
3893
+ var span = spans[i];
3894
+ if (span.marker == marker) return span;
3895
+ }
3896
+ }
3897
+ function removeMarkedSpan(spans, span) {
3898
+ for (var r, i = 0; i < spans.length; ++i)
3899
+ if (spans[i] != span) (r || (r = [])).push(spans[i]);
3900
+ return r;
3901
+ }
3902
+ function addMarkedSpan(line, span) {
3903
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
3904
+ span.marker.attachLine(line);
3905
+ }
3906
+
3907
+ function markedSpansBefore(old, startCh, isInsert) {
3908
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
3909
+ var span = old[i], marker = span.marker;
3910
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
3911
+ if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
3912
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
3913
+ (nw || (nw = [])).push({from: span.from,
3914
+ to: endsAfter ? null : span.to,
3915
+ marker: marker});
3916
+ }
3917
+ }
3918
+ return nw;
3919
+ }
3920
+
3921
+ function markedSpansAfter(old, endCh, isInsert) {
3922
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
3923
+ var span = old[i], marker = span.marker;
3924
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
3925
+ if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
3926
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
3927
+ (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
3928
+ to: span.to == null ? null : span.to - endCh,
3929
+ marker: marker});
3930
+ }
3931
+ }
3932
+ return nw;
3933
+ }
3934
+
3935
+ function stretchSpansOverChange(doc, change) {
3936
+ var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
3937
+ var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
3938
+ if (!oldFirst && !oldLast) return null;
3939
+
3940
+ var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
3941
+ // Get the spans that 'stick out' on both sides
3942
+ var first = markedSpansBefore(oldFirst, startCh, isInsert);
3943
+ var last = markedSpansAfter(oldLast, endCh, isInsert);
3944
+
3945
+ // Next, merge those two ends
3946
+ var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
3947
+ if (first) {
3948
+ // Fix up .to properties of first
3949
+ for (var i = 0; i < first.length; ++i) {
3950
+ var span = first[i];
3951
+ if (span.to == null) {
3952
+ var found = getMarkedSpanFor(last, span.marker);
3953
+ if (!found) span.to = startCh;
3954
+ else if (sameLine) span.to = found.to == null ? null : found.to + offset;
3955
+ }
3956
+ }
3957
+ }
3958
+ if (last) {
3959
+ // Fix up .from in last (or move them into first in case of sameLine)
3960
+ for (var i = 0; i < last.length; ++i) {
3961
+ var span = last[i];
3962
+ if (span.to != null) span.to += offset;
3963
+ if (span.from == null) {
3964
+ var found = getMarkedSpanFor(first, span.marker);
3965
+ if (!found) {
3966
+ span.from = offset;
3967
+ if (sameLine) (first || (first = [])).push(span);
3968
+ }
3969
+ } else {
3970
+ span.from += offset;
3971
+ if (sameLine) (first || (first = [])).push(span);
3972
+ }
3973
+ }
3974
+ }
3975
+ if (sameLine && first) {
3976
+ // Make sure we didn't create any zero-length spans
3977
+ for (var i = 0; i < first.length; ++i)
3978
+ if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark")
3979
+ first.splice(i--, 1);
3980
+ if (!first.length) first = null;
3981
+ }
3982
+
3983
+ var newMarkers = [first];
3984
+ if (!sameLine) {
3985
+ // Fill gap with whole-line-spans
3986
+ var gap = change.text.length - 2, gapMarkers;
3987
+ if (gap > 0 && first)
3988
+ for (var i = 0; i < first.length; ++i)
3989
+ if (first[i].to == null)
3990
+ (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
3991
+ for (var i = 0; i < gap; ++i)
3992
+ newMarkers.push(gapMarkers);
3993
+ newMarkers.push(last);
3994
+ }
3995
+ return newMarkers;
3996
+ }
3997
+
3998
+ function mergeOldSpans(doc, change) {
3999
+ var old = getOldSpans(doc, change);
4000
+ var stretched = stretchSpansOverChange(doc, change);
4001
+ if (!old) return stretched;
4002
+ if (!stretched) return old;
4003
+
4004
+ for (var i = 0; i < old.length; ++i) {
4005
+ var oldCur = old[i], stretchCur = stretched[i];
4006
+ if (oldCur && stretchCur) {
4007
+ spans: for (var j = 0; j < stretchCur.length; ++j) {
4008
+ var span = stretchCur[j];
4009
+ for (var k = 0; k < oldCur.length; ++k)
4010
+ if (oldCur[k].marker == span.marker) continue spans;
4011
+ oldCur.push(span);
4012
+ }
4013
+ } else if (stretchCur) {
4014
+ old[i] = stretchCur;
4015
+ }
4016
+ }
4017
+ return old;
4018
+ }
4019
+
4020
+ function removeReadOnlyRanges(doc, from, to) {
4021
+ var markers = null;
4022
+ doc.iter(from.line, to.line + 1, function(line) {
4023
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
4024
+ var mark = line.markedSpans[i].marker;
4025
+ if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
4026
+ (markers || (markers = [])).push(mark);
4027
+ }
4028
+ });
4029
+ if (!markers) return null;
4030
+ var parts = [{from: from, to: to}];
4031
+ for (var i = 0; i < markers.length; ++i) {
4032
+ var mk = markers[i], m = mk.find();
4033
+ for (var j = 0; j < parts.length; ++j) {
4034
+ var p = parts[j];
4035
+ if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue;
4036
+ var newParts = [j, 1];
4037
+ if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from))
4038
+ newParts.push({from: p.from, to: m.from});
4039
+ if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to))
4040
+ newParts.push({from: m.to, to: p.to});
4041
+ parts.splice.apply(parts, newParts);
4042
+ j += newParts.length - 1;
4043
+ }
4044
+ }
4045
+ return parts;
4046
+ }
4047
+
4048
+ function collapsedSpanAt(line, ch) {
4049
+ var sps = sawCollapsedSpans && line.markedSpans, found;
4050
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
4051
+ sp = sps[i];
4052
+ if (!sp.marker.collapsed) continue;
4053
+ if ((sp.from == null || sp.from < ch) &&
4054
+ (sp.to == null || sp.to > ch) &&
4055
+ (!found || found.width < sp.marker.width))
4056
+ found = sp.marker;
4057
+ }
4058
+ return found;
4059
+ }
4060
+ function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
4061
+ function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }
4062
+
4063
+ function visualLine(doc, line) {
4064
+ var merged;
4065
+ while (merged = collapsedSpanAtStart(line))
4066
+ line = getLine(doc, merged.find().from.line);
4067
+ return line;
4068
+ }
4069
+
4070
+ function lineIsHidden(doc, line) {
4071
+ var sps = sawCollapsedSpans && line.markedSpans;
4072
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
4073
+ sp = sps[i];
4074
+ if (!sp.marker.collapsed) continue;
4075
+ if (sp.from == null) return true;
4076
+ if (sp.marker.replacedWith) continue;
4077
+ if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
4078
+ return true;
4079
+ }
4080
+ }
4081
+ function lineIsHiddenInner(doc, line, span) {
4082
+ if (span.to == null) {
4083
+ var end = span.marker.find().to, endLine = getLine(doc, end.line);
4084
+ return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
4085
+ }
4086
+ if (span.marker.inclusiveRight && span.to == line.text.length)
4087
+ return true;
4088
+ for (var sp, i = 0; i < line.markedSpans.length; ++i) {
4089
+ sp = line.markedSpans[i];
4090
+ if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
4091
+ (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
4092
+ lineIsHiddenInner(doc, line, sp)) return true;
4093
+ }
4094
+ }
4095
+
4096
+ function detachMarkedSpans(line) {
4097
+ var spans = line.markedSpans;
4098
+ if (!spans) return;
4099
+ for (var i = 0; i < spans.length; ++i)
4100
+ spans[i].marker.detachLine(line);
4101
+ line.markedSpans = null;
4102
+ }
4103
+
4104
+ function attachMarkedSpans(line, spans) {
4105
+ if (!spans) return;
4106
+ for (var i = 0; i < spans.length; ++i)
4107
+ spans[i].marker.attachLine(line);
4108
+ line.markedSpans = spans;
4109
+ }
4110
+
4111
+ // LINE WIDGETS
4112
+
4113
+ var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
4114
+ if (options) for (var opt in options) if (options.hasOwnProperty(opt))
4115
+ this[opt] = options[opt];
4116
+ this.cm = cm;
4117
+ this.node = node;
4118
+ };
4119
+ eventMixin(LineWidget);
4120
+ function widgetOperation(f) {
4121
+ return function() {
4122
+ var withOp = !this.cm.curOp;
4123
+ if (withOp) startOperation(this.cm);
4124
+ try {var result = f.apply(this, arguments);}
4125
+ finally {if (withOp) endOperation(this.cm);}
4126
+ return result;
4127
+ };
4128
+ }
4129
+ LineWidget.prototype.clear = widgetOperation(function() {
4130
+ var ws = this.line.widgets, no = lineNo(this.line);
4131
+ if (no == null || !ws) return;
4132
+ for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
4133
+ if (!ws.length) this.line.widgets = null;
4134
+ var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
4135
+ updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
4136
+ if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
4137
+ regChange(this.cm, no, no + 1);
4138
+ });
4139
+ LineWidget.prototype.changed = widgetOperation(function() {
4140
+ var oldH = this.height;
4141
+ this.height = null;
4142
+ var diff = widgetHeight(this) - oldH;
4143
+ if (!diff) return;
4144
+ updateLineHeight(this.line, this.line.height + diff);
4145
+ var no = lineNo(this.line);
4146
+ regChange(this.cm, no, no + 1);
4147
+ });
4148
+
4149
+ function widgetHeight(widget) {
4150
+ if (widget.height != null) return widget.height;
4151
+ if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
4152
+ removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
4153
+ return widget.height = widget.node.offsetHeight;
4154
+ }
4155
+
4156
+ function addLineWidget(cm, handle, node, options) {
4157
+ var widget = new LineWidget(cm, node, options);
4158
+ if (widget.noHScroll) cm.display.alignWidgets = true;
4159
+ changeLine(cm, handle, function(line) {
4160
+ var widgets = line.widgets || (line.widgets = []);
4161
+ if (widget.insertAt == null) widgets.push(widget);
4162
+ else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
4163
+ widget.line = line;
4164
+ if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
4165
+ var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
4166
+ updateLineHeight(line, line.height + widgetHeight(widget));
4167
+ if (aboveVisible) addToScrollPos(cm, 0, widget.height);
4168
+ }
4169
+ return true;
4170
+ });
4171
+ return widget;
4172
+ }
4173
+
4174
+ // LINE DATA STRUCTURE
4175
+
4176
+ // Line objects. These hold state related to a line, including
4177
+ // highlighting info (the styles array).
4178
+ var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
4179
+ this.text = text;
4180
+ attachMarkedSpans(this, markedSpans);
4181
+ this.height = estimateHeight ? estimateHeight(this) : 1;
4182
+ };
4183
+ eventMixin(Line);
4184
+
4185
+ function updateLine(line, text, markedSpans, estimateHeight) {
4186
+ line.text = text;
4187
+ if (line.stateAfter) line.stateAfter = null;
4188
+ if (line.styles) line.styles = null;
4189
+ if (line.order != null) line.order = null;
4190
+ detachMarkedSpans(line);
4191
+ attachMarkedSpans(line, markedSpans);
4192
+ var estHeight = estimateHeight ? estimateHeight(line) : 1;
4193
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
4194
+ }
4195
+
4196
+ function cleanUpLine(line) {
4197
+ line.parent = null;
4198
+ detachMarkedSpans(line);
4199
+ }
4200
+
4201
+ // Run the given mode's parser over a line, update the styles
4202
+ // array, which contains alternating fragments of text and CSS
4203
+ // classes.
4204
+ function runMode(cm, text, mode, state, f) {
4205
+ var flattenSpans = mode.flattenSpans;
4206
+ if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
4207
+ var curStart = 0, curStyle = null;
4208
+ var stream = new StringStream(text, cm.options.tabSize), style;
4209
+ if (text == "" && mode.blankLine) mode.blankLine(state);
4210
+ while (!stream.eol()) {
4211
+ if (stream.pos > cm.options.maxHighlightLength) {
4212
+ flattenSpans = false;
4213
+ // Webkit seems to refuse to render text nodes longer than 57444 characters
4214
+ stream.pos = Math.min(text.length, stream.start + 50000);
4215
+ style = null;
4216
+ } else {
4217
+ style = mode.token(stream, state);
4218
+ }
4219
+ if (!flattenSpans || curStyle != style) {
4220
+ if (curStart < stream.start) f(stream.start, curStyle);
4221
+ curStart = stream.start; curStyle = style;
4222
+ }
4223
+ stream.start = stream.pos;
4224
+ }
4225
+ if (curStart < stream.pos) f(stream.pos, curStyle);
4226
+ }
4227
+
4228
+ function highlightLine(cm, line, state) {
4229
+ // A styles array always starts with a number identifying the
4230
+ // mode/overlays that it is based on (for easy invalidation).
4231
+ var st = [cm.state.modeGen];
4232
+ // Compute the base array of styles
4233
+ runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});
4234
+
4235
+ // Run overlays, adjust style array.
4236
+ for (var o = 0; o < cm.state.overlays.length; ++o) {
4237
+ var overlay = cm.state.overlays[o], i = 1, at = 0;
4238
+ runMode(cm, line.text, overlay.mode, true, function(end, style) {
4239
+ var start = i;
4240
+ // Ensure there's a token end at the current position, and that i points at it
4241
+ while (at < end) {
4242
+ var i_end = st[i];
4243
+ if (i_end > end)
4244
+ st.splice(i, 1, end, st[i+1], i_end);
4245
+ i += 2;
4246
+ at = Math.min(end, i_end);
4247
+ }
4248
+ if (!style) return;
4249
+ if (overlay.opaque) {
4250
+ st.splice(start, i - start, end, style);
4251
+ i = start + 2;
4252
+ } else {
4253
+ for (; start < i; start += 2) {
4254
+ var cur = st[start+1];
4255
+ st[start+1] = cur ? cur + " " + style : style;
4256
+ }
4257
+ }
4258
+ });
4259
+ }
4260
+
4261
+ return st;
4262
+ }
4263
+
4264
+ function getLineStyles(cm, line) {
4265
+ if (!line.styles || line.styles[0] != cm.state.modeGen)
4266
+ line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
4267
+ return line.styles;
4268
+ }
4269
+
4270
+ // Lightweight form of highlight -- proceed over this line and
4271
+ // update state, but don't save a style array.
4272
+ function processLine(cm, line, state) {
4273
+ var mode = cm.doc.mode;
4274
+ var stream = new StringStream(line.text, cm.options.tabSize);
4275
+ if (line.text == "" && mode.blankLine) mode.blankLine(state);
4276
+ while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
4277
+ mode.token(stream, state);
4278
+ stream.start = stream.pos;
4279
+ }
4280
+ }
4281
+
4282
+ var styleToClassCache = {};
4283
+ function styleToClass(style) {
4284
+ if (!style) return null;
4285
+ return styleToClassCache[style] ||
4286
+ (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
4287
+ }
4288
+
4289
+ function lineContent(cm, realLine, measure, copyWidgets) {
4290
+ var merged, line = realLine, empty = true;
4291
+ while (merged = collapsedSpanAtStart(line))
4292
+ line = getLine(cm.doc, merged.find().from.line);
4293
+
4294
+ var builder = {pre: elt("pre"), col: 0, pos: 0,
4295
+ measure: null, measuredSomething: false, cm: cm,
4296
+ copyWidgets: copyWidgets};
4297
+ if (line.textClass) builder.pre.className = line.textClass;
4298
+
4299
+ do {
4300
+ if (line.text) empty = false;
4301
+ builder.measure = line == realLine && measure;
4302
+ builder.pos = 0;
4303
+ builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
4304
+ if ((ie || webkit) && cm.getOption("lineWrapping"))
4305
+ builder.addToken = buildTokenSplitSpaces(builder.addToken);
4306
+ var next = insertLineContent(line, builder, getLineStyles(cm, line));
4307
+ if (measure && line == realLine && !builder.measuredSomething) {
4308
+ measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
4309
+ builder.measuredSomething = true;
4310
+ }
4311
+ if (next) line = getLine(cm.doc, next.to.line);
4312
+ } while (next);
4313
+
4314
+ if (measure && !builder.measuredSomething && !measure[0])
4315
+ measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
4316
+ if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine))
4317
+ builder.pre.appendChild(document.createTextNode("\u00a0"));
4318
+
4319
+ var order;
4320
+ // Work around problem with the reported dimensions of single-char
4321
+ // direction spans on IE (issue #1129). See also the comment in
4322
+ // cursorCoords.
4323
+ if (measure && ie && (order = getOrder(line))) {
4324
+ var l = order.length - 1;
4325
+ if (order[l].from == order[l].to) --l;
4326
+ var last = order[l], prev = order[l - 1];
4327
+ if (last.from + 1 == last.to && prev && last.level < prev.level) {
4328
+ var span = measure[builder.pos - 1];
4329
+ if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
4330
+ span.nextSibling);
4331
+ }
4332
+ }
4333
+
4334
+ signal(cm, "renderLine", cm, realLine, builder.pre);
4335
+ return builder.pre;
4336
+ }
4337
+
4338
+ var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
4339
+ function buildToken(builder, text, style, startStyle, endStyle, title) {
4340
+ if (!text) return;
4341
+ if (!tokenSpecialChars.test(text)) {
4342
+ builder.col += text.length;
4343
+ var content = document.createTextNode(text);
4344
+ } else {
4345
+ var content = document.createDocumentFragment(), pos = 0;
4346
+ while (true) {
4347
+ tokenSpecialChars.lastIndex = pos;
4348
+ var m = tokenSpecialChars.exec(text);
4349
+ var skipped = m ? m.index - pos : text.length - pos;
4350
+ if (skipped) {
4351
+ content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
4352
+ builder.col += skipped;
4353
+ }
4354
+ if (!m) break;
4355
+ pos += skipped + 1;
4356
+ if (m[0] == "\t") {
4357
+ var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
4358
+ content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
4359
+ builder.col += tabWidth;
4360
+ } else {
4361
+ var token = elt("span", "\u2022", "cm-invalidchar");
4362
+ token.title = "\\u" + m[0].charCodeAt(0).toString(16);
4363
+ content.appendChild(token);
4364
+ builder.col += 1;
4365
+ }
4366
+ }
4367
+ }
4368
+ if (style || startStyle || endStyle || builder.measure) {
4369
+ var fullStyle = style || "";
4370
+ if (startStyle) fullStyle += startStyle;
4371
+ if (endStyle) fullStyle += endStyle;
4372
+ var token = elt("span", [content], fullStyle);
4373
+ if (title) token.title = title;
4374
+ return builder.pre.appendChild(token);
4375
+ }
4376
+ builder.pre.appendChild(content);
4377
+ }
4378
+
4379
+ function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
4380
+ var wrapping = builder.cm.options.lineWrapping;
4381
+ for (var i = 0; i < text.length; ++i) {
4382
+ var ch = text.charAt(i), start = i == 0;
4383
+ if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) {
4384
+ ch = text.slice(i, i + 2);
4385
+ ++i;
4386
+ } else if (i && wrapping && spanAffectsWrapping(text, i)) {
4387
+ builder.pre.appendChild(elt("wbr"));
4388
+ }
4389
+ var old = builder.measure[builder.pos];
4390
+ var span = builder.measure[builder.pos] =
4391
+ buildToken(builder, ch, style,
4392
+ start && startStyle, i == text.length - 1 && endStyle);
4393
+ if (old) span.leftSide = old.leftSide || old;
4394
+ // In IE single-space nodes wrap differently than spaces
4395
+ // embedded in larger text nodes, except when set to
4396
+ // white-space: normal (issue #1268).
4397
+ if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
4398
+ i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
4399
+ span.style.whiteSpace = "normal";
4400
+ builder.pos += ch.length;
4401
+ }
4402
+ if (text.length) builder.measuredSomething = true;
4403
+ }
4404
+
4405
+ function buildTokenSplitSpaces(inner) {
4406
+ function split(old) {
4407
+ var out = " ";
4408
+ for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
4409
+ out += " ";
4410
+ return out;
4411
+ }
4412
+ return function(builder, text, style, startStyle, endStyle, title) {
4413
+ return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
4414
+ };
4415
+ }
4416
+
4417
+ function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
4418
+ var widget = !ignoreWidget && marker.replacedWith;
4419
+ if (widget) {
4420
+ if (builder.copyWidgets) widget = widget.cloneNode(true);
4421
+ builder.pre.appendChild(widget);
4422
+ if (builder.measure) {
4423
+ if (size) {
4424
+ builder.measure[builder.pos] = widget;
4425
+ } else {
4426
+ var elt = zeroWidthElement(builder.cm.display.measure);
4427
+ if (marker.type == "bookmark" && !marker.insertLeft)
4428
+ builder.measure[builder.pos] = builder.pre.appendChild(elt);
4429
+ else if (builder.measure[builder.pos])
4430
+ return;
4431
+ else
4432
+ builder.measure[builder.pos] = builder.pre.insertBefore(elt, widget);
4433
+ }
4434
+ builder.measuredSomething = true;
4435
+ }
4436
+ }
4437
+ builder.pos += size;
4438
+ }
4439
+
4440
+ // Outputs a number of spans to make up a line, taking highlighting
4441
+ // and marked text into account.
4442
+ function insertLineContent(line, builder, styles) {
4443
+ var spans = line.markedSpans, allText = line.text, at = 0;
4444
+ if (!spans) {
4445
+ for (var i = 1; i < styles.length; i+=2)
4446
+ builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
4447
+ return;
4448
+ }
4449
+
4450
+ var len = allText.length, pos = 0, i = 1, text = "", style;
4451
+ var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
4452
+ for (;;) {
4453
+ if (nextChange == pos) { // Update current marker set
4454
+ spanStyle = spanEndStyle = spanStartStyle = title = "";
4455
+ collapsed = null; nextChange = Infinity;
4456
+ var foundBookmarks = [];
4457
+ for (var j = 0; j < spans.length; ++j) {
4458
+ var sp = spans[j], m = sp.marker;
4459
+ if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
4460
+ if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
4461
+ if (m.className) spanStyle += " " + m.className;
4462
+ if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
4463
+ if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
4464
+ if (m.title && !title) title = m.title;
4465
+ if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
4466
+ collapsed = sp;
4467
+ } else if (sp.from > pos && nextChange > sp.from) {
4468
+ nextChange = sp.from;
4469
+ }
4470
+ if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmarks.push(m);
4471
+ }
4472
+ if (collapsed && (collapsed.from || 0) == pos) {
4473
+ buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
4474
+ collapsed.marker, collapsed.from == null);
4475
+ if (collapsed.to == null) return collapsed.marker.find();
4476
+ }
4477
+ if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
4478
+ buildCollapsedSpan(builder, 0, foundBookmarks[j]);
4479
+ }
4480
+ if (pos >= len) break;
4481
+
4482
+ var upto = Math.min(len, nextChange);
4483
+ while (true) {
4484
+ if (text) {
4485
+ var end = pos + text.length;
4486
+ if (!collapsed) {
4487
+ var tokenText = end > upto ? text.slice(0, upto - pos) : text;
4488
+ builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
4489
+ spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
4490
+ }
4491
+ if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
4492
+ pos = end;
4493
+ spanStartStyle = "";
4494
+ }
4495
+ text = allText.slice(at, at = styles[i++]);
4496
+ style = styleToClass(styles[i++]);
4497
+ }
4498
+ }
4499
+ }
4500
+
4501
+ // DOCUMENT DATA STRUCTURE
4502
+
4503
+ function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) {
4504
+ function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
4505
+ function update(line, text, spans) {
4506
+ updateLine(line, text, spans, estimateHeight);
4507
+ signalLater(line, "change", line, change);
4508
+ }
4509
+
4510
+ var from = change.from, to = change.to, text = change.text;
4511
+ var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
4512
+ var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
4513
+
4514
+ // First adjust the line structure
4515
+ if (from.ch == 0 && to.ch == 0 && lastText == "") {
4516
+ // This is a whole-line replace. Treated specially to make
4517
+ // sure line objects move the way they are supposed to.
4518
+ for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
4519
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4520
+ update(lastLine, lastLine.text, lastSpans);
4521
+ if (nlines) doc.remove(from.line, nlines);
4522
+ if (added.length) doc.insert(from.line, added);
4523
+ } else if (firstLine == lastLine) {
4524
+ if (text.length == 1) {
4525
+ update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
4526
+ } else {
4527
+ for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
4528
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4529
+ added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
4530
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4531
+ doc.insert(from.line + 1, added);
4532
+ }
4533
+ } else if (text.length == 1) {
4534
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
4535
+ doc.remove(from.line + 1, nlines);
4536
+ } else {
4537
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4538
+ update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
4539
+ for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
4540
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4541
+ if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
4542
+ doc.insert(from.line + 1, added);
4543
+ }
4544
+
4545
+ signalLater(doc, "change", doc, change);
4546
+ setSelection(doc, selAfter.anchor, selAfter.head, null, true);
4547
+ }
4548
+
4549
+ function LeafChunk(lines) {
4550
+ this.lines = lines;
4551
+ this.parent = null;
4552
+ for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
4553
+ lines[i].parent = this;
4554
+ height += lines[i].height;
4555
+ }
4556
+ this.height = height;
4557
+ }
4558
+
4559
+ LeafChunk.prototype = {
4560
+ chunkSize: function() { return this.lines.length; },
4561
+ removeInner: function(at, n) {
4562
+ for (var i = at, e = at + n; i < e; ++i) {
4563
+ var line = this.lines[i];
4564
+ this.height -= line.height;
4565
+ cleanUpLine(line);
4566
+ signalLater(line, "delete");
4567
+ }
4568
+ this.lines.splice(at, n);
4569
+ },
4570
+ collapse: function(lines) {
4571
+ lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
4572
+ },
4573
+ insertInner: function(at, lines, height) {
4574
+ this.height += height;
4575
+ this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
4576
+ for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
4577
+ },
4578
+ iterN: function(at, n, op) {
4579
+ for (var e = at + n; at < e; ++at)
4580
+ if (op(this.lines[at])) return true;
4581
+ }
4582
+ };
4583
+
4584
+ function BranchChunk(children) {
4585
+ this.children = children;
4586
+ var size = 0, height = 0;
4587
+ for (var i = 0, e = children.length; i < e; ++i) {
4588
+ var ch = children[i];
4589
+ size += ch.chunkSize(); height += ch.height;
4590
+ ch.parent = this;
4591
+ }
4592
+ this.size = size;
4593
+ this.height = height;
4594
+ this.parent = null;
4595
+ }
4596
+
4597
+ BranchChunk.prototype = {
4598
+ chunkSize: function() { return this.size; },
4599
+ removeInner: function(at, n) {
4600
+ this.size -= n;
4601
+ for (var i = 0; i < this.children.length; ++i) {
4602
+ var child = this.children[i], sz = child.chunkSize();
4603
+ if (at < sz) {
4604
+ var rm = Math.min(n, sz - at), oldHeight = child.height;
4605
+ child.removeInner(at, rm);
4606
+ this.height -= oldHeight - child.height;
4607
+ if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
4608
+ if ((n -= rm) == 0) break;
4609
+ at = 0;
4610
+ } else at -= sz;
4611
+ }
4612
+ if (this.size - n < 25) {
4613
+ var lines = [];
4614
+ this.collapse(lines);
4615
+ this.children = [new LeafChunk(lines)];
4616
+ this.children[0].parent = this;
4617
+ }
4618
+ },
4619
+ collapse: function(lines) {
4620
+ for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
4621
+ },
4622
+ insertInner: function(at, lines, height) {
4623
+ this.size += lines.length;
4624
+ this.height += height;
4625
+ for (var i = 0, e = this.children.length; i < e; ++i) {
4626
+ var child = this.children[i], sz = child.chunkSize();
4627
+ if (at <= sz) {
4628
+ child.insertInner(at, lines, height);
4629
+ if (child.lines && child.lines.length > 50) {
4630
+ while (child.lines.length > 50) {
4631
+ var spilled = child.lines.splice(child.lines.length - 25, 25);
4632
+ var newleaf = new LeafChunk(spilled);
4633
+ child.height -= newleaf.height;
4634
+ this.children.splice(i + 1, 0, newleaf);
4635
+ newleaf.parent = this;
4636
+ }
4637
+ this.maybeSpill();
4638
+ }
4639
+ break;
4640
+ }
4641
+ at -= sz;
4642
+ }
4643
+ },
4644
+ maybeSpill: function() {
4645
+ if (this.children.length <= 10) return;
4646
+ var me = this;
4647
+ do {
4648
+ var spilled = me.children.splice(me.children.length - 5, 5);
4649
+ var sibling = new BranchChunk(spilled);
4650
+ if (!me.parent) { // Become the parent node
4651
+ var copy = new BranchChunk(me.children);
4652
+ copy.parent = me;
4653
+ me.children = [copy, sibling];
4654
+ me = copy;
4655
+ } else {
4656
+ me.size -= sibling.size;
4657
+ me.height -= sibling.height;
4658
+ var myIndex = indexOf(me.parent.children, me);
4659
+ me.parent.children.splice(myIndex + 1, 0, sibling);
4660
+ }
4661
+ sibling.parent = me.parent;
4662
+ } while (me.children.length > 10);
4663
+ me.parent.maybeSpill();
4664
+ },
4665
+ iterN: function(at, n, op) {
4666
+ for (var i = 0, e = this.children.length; i < e; ++i) {
4667
+ var child = this.children[i], sz = child.chunkSize();
4668
+ if (at < sz) {
4669
+ var used = Math.min(n, sz - at);
4670
+ if (child.iterN(at, used, op)) return true;
4671
+ if ((n -= used) == 0) break;
4672
+ at = 0;
4673
+ } else at -= sz;
4674
+ }
4675
+ }
4676
+ };
4677
+
4678
+ var nextDocId = 0;
4679
+ var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
4680
+ if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
4681
+ if (firstLine == null) firstLine = 0;
4682
+
4683
+ BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
4684
+ this.first = firstLine;
4685
+ this.scrollTop = this.scrollLeft = 0;
4686
+ this.cantEdit = false;
4687
+ this.history = makeHistory();
4688
+ this.cleanGeneration = 1;
4689
+ this.frontier = firstLine;
4690
+ var start = Pos(firstLine, 0);
4691
+ this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null};
4692
+ this.id = ++nextDocId;
4693
+ this.modeOption = mode;
4694
+
4695
+ if (typeof text == "string") text = splitLines(text);
4696
+ updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start});
4697
+ };
4698
+
4699
+ Doc.prototype = createObj(BranchChunk.prototype, {
4700
+ constructor: Doc,
4701
+ iter: function(from, to, op) {
4702
+ if (op) this.iterN(from - this.first, to - from, op);
4703
+ else this.iterN(this.first, this.first + this.size, from);
4704
+ },
4705
+
4706
+ insert: function(at, lines) {
4707
+ var height = 0;
4708
+ for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
4709
+ this.insertInner(at - this.first, lines, height);
4710
+ },
4711
+ remove: function(at, n) { this.removeInner(at - this.first, n); },
4712
+
4713
+ getValue: function(lineSep) {
4714
+ var lines = getLines(this, this.first, this.first + this.size);
4715
+ if (lineSep === false) return lines;
4716
+ return lines.join(lineSep || "\n");
4717
+ },
4718
+ setValue: function(code) {
4719
+ var top = Pos(this.first, 0), last = this.first + this.size - 1;
4720
+ makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
4721
+ text: splitLines(code), origin: "setValue"},
4722
+ {head: top, anchor: top}, true);
4723
+ },
4724
+ replaceRange: function(code, from, to, origin) {
4725
+ from = clipPos(this, from);
4726
+ to = to ? clipPos(this, to) : from;
4727
+ replaceRange(this, code, from, to, origin);
4728
+ },
4729
+ getRange: function(from, to, lineSep) {
4730
+ var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
4731
+ if (lineSep === false) return lines;
4732
+ return lines.join(lineSep || "\n");
4733
+ },
4734
+
4735
+ getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
4736
+ setLine: function(line, text) {
4737
+ if (isLine(this, line))
4738
+ replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line)));
4739
+ },
4740
+ removeLine: function(line) {
4741
+ if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line)));
4742
+ else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0)));
4743
+ },
4744
+
4745
+ getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
4746
+ getLineNumber: function(line) {return lineNo(line);},
4747
+
4748
+ getLineHandleVisualStart: function(line) {
4749
+ if (typeof line == "number") line = getLine(this, line);
4750
+ return visualLine(this, line);
4751
+ },
4752
+
4753
+ lineCount: function() {return this.size;},
4754
+ firstLine: function() {return this.first;},
4755
+ lastLine: function() {return this.first + this.size - 1;},
4756
+
4757
+ clipPos: function(pos) {return clipPos(this, pos);},
4758
+
4759
+ getCursor: function(start) {
4760
+ var sel = this.sel, pos;
4761
+ if (start == null || start == "head") pos = sel.head;
4762
+ else if (start == "anchor") pos = sel.anchor;
4763
+ else if (start == "end" || start === false) pos = sel.to;
4764
+ else pos = sel.from;
4765
+ return copyPos(pos);
4766
+ },
4767
+ somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);},
4768
+
4769
+ setCursor: docOperation(function(line, ch, extend) {
4770
+ var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line);
4771
+ if (extend) extendSelection(this, pos);
4772
+ else setSelection(this, pos, pos);
4773
+ }),
4774
+ setSelection: docOperation(function(anchor, head, bias) {
4775
+ setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), bias);
4776
+ }),
4777
+ extendSelection: docOperation(function(from, to, bias) {
4778
+ extendSelection(this, clipPos(this, from), to && clipPos(this, to), bias);
4779
+ }),
4780
+
4781
+ getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
4782
+ replaceSelection: function(code, collapse, origin) {
4783
+ makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around");
4784
+ },
4785
+ undo: docOperation(function() {makeChangeFromHistory(this, "undo");}),
4786
+ redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),
4787
+
4788
+ setExtending: function(val) {this.sel.extend = val;},
4789
+
4790
+ historySize: function() {
4791
+ var hist = this.history;
4792
+ return {undo: hist.done.length, redo: hist.undone.length};
4793
+ },
4794
+ clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},
4795
+
4796
+ markClean: function() {
4797
+ this.cleanGeneration = this.changeGeneration();
4798
+ },
4799
+ changeGeneration: function() {
4800
+ this.history.lastOp = this.history.lastOrigin = null;
4801
+ return this.history.generation;
4802
+ },
4803
+ isClean: function (gen) {
4804
+ return this.history.generation == (gen || this.cleanGeneration);
4805
+ },
4806
+
4807
+ getHistory: function() {
4808
+ return {done: copyHistoryArray(this.history.done),
4809
+ undone: copyHistoryArray(this.history.undone)};
4810
+ },
4811
+ setHistory: function(histData) {
4812
+ var hist = this.history = makeHistory(this.history.maxGeneration);
4813
+ hist.done = histData.done.slice(0);
4814
+ hist.undone = histData.undone.slice(0);
4815
+ },
4816
+
4817
+ markText: function(from, to, options) {
4818
+ return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
4819
+ },
4820
+ setBookmark: function(pos, options) {
4821
+ var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
4822
+ insertLeft: options && options.insertLeft};
4823
+ pos = clipPos(this, pos);
4824
+ return markText(this, pos, pos, realOpts, "bookmark");
4825
+ },
4826
+ findMarksAt: function(pos) {
4827
+ pos = clipPos(this, pos);
4828
+ var markers = [], spans = getLine(this, pos.line).markedSpans;
4829
+ if (spans) for (var i = 0; i < spans.length; ++i) {
4830
+ var span = spans[i];
4831
+ if ((span.from == null || span.from <= pos.ch) &&
4832
+ (span.to == null || span.to >= pos.ch))
4833
+ markers.push(span.marker.parent || span.marker);
4834
+ }
4835
+ return markers;
4836
+ },
4837
+ getAllMarks: function() {
4838
+ var markers = [];
4839
+ this.iter(function(line) {
4840
+ var sps = line.markedSpans;
4841
+ if (sps) for (var i = 0; i < sps.length; ++i)
4842
+ if (sps[i].from != null) markers.push(sps[i].marker);
4843
+ });
4844
+ return markers;
4845
+ },
4846
+
4847
+ posFromIndex: function(off) {
4848
+ var ch, lineNo = this.first;
4849
+ this.iter(function(line) {
4850
+ var sz = line.text.length + 1;
4851
+ if (sz > off) { ch = off; return true; }
4852
+ off -= sz;
4853
+ ++lineNo;
4854
+ });
4855
+ return clipPos(this, Pos(lineNo, ch));
4856
+ },
4857
+ indexFromPos: function (coords) {
4858
+ coords = clipPos(this, coords);
4859
+ var index = coords.ch;
4860
+ if (coords.line < this.first || coords.ch < 0) return 0;
4861
+ this.iter(this.first, coords.line, function (line) {
4862
+ index += line.text.length + 1;
4863
+ });
4864
+ return index;
4865
+ },
4866
+
4867
+ copy: function(copyHistory) {
4868
+ var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
4869
+ doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
4870
+ doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor,
4871
+ shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn};
4872
+ if (copyHistory) {
4873
+ doc.history.undoDepth = this.history.undoDepth;
4874
+ doc.setHistory(this.getHistory());
4875
+ }
4876
+ return doc;
4877
+ },
4878
+
4879
+ linkedDoc: function(options) {
4880
+ if (!options) options = {};
4881
+ var from = this.first, to = this.first + this.size;
4882
+ if (options.from != null && options.from > from) from = options.from;
4883
+ if (options.to != null && options.to < to) to = options.to;
4884
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
4885
+ if (options.sharedHist) copy.history = this.history;
4886
+ (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
4887
+ copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
4888
+ return copy;
4889
+ },
4890
+ unlinkDoc: function(other) {
4891
+ if (other instanceof CodeMirror) other = other.doc;
4892
+ if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
4893
+ var link = this.linked[i];
4894
+ if (link.doc != other) continue;
4895
+ this.linked.splice(i, 1);
4896
+ other.unlinkDoc(this);
4897
+ break;
4898
+ }
4899
+ // If the histories were shared, split them again
4900
+ if (other.history == this.history) {
4901
+ var splitIds = [other.id];
4902
+ linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
4903
+ other.history = makeHistory();
4904
+ other.history.done = copyHistoryArray(this.history.done, splitIds);
4905
+ other.history.undone = copyHistoryArray(this.history.undone, splitIds);
4906
+ }
4907
+ },
4908
+ iterLinkedDocs: function(f) {linkedDocs(this, f);},
4909
+
4910
+ getMode: function() {return this.mode;},
4911
+ getEditor: function() {return this.cm;}
4912
+ });
4913
+
4914
+ Doc.prototype.eachLine = Doc.prototype.iter;
4915
+
4916
+ // The Doc methods that should be available on CodeMirror instances
4917
+ var dontDelegate = "iter insert remove copy getEditor".split(" ");
4918
+ for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
4919
+ CodeMirror.prototype[prop] = (function(method) {
4920
+ return function() {return method.apply(this.doc, arguments);};
4921
+ })(Doc.prototype[prop]);
4922
+
4923
+ eventMixin(Doc);
4924
+
4925
+ function linkedDocs(doc, f, sharedHistOnly) {
4926
+ function propagate(doc, skip, sharedHist) {
4927
+ if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
4928
+ var rel = doc.linked[i];
4929
+ if (rel.doc == skip) continue;
4930
+ var shared = sharedHist && rel.sharedHist;
4931
+ if (sharedHistOnly && !shared) continue;
4932
+ f(rel.doc, shared);
4933
+ propagate(rel.doc, doc, shared);
4934
+ }
4935
+ }
4936
+ propagate(doc, null, true);
4937
+ }
4938
+
4939
+ function attachDoc(cm, doc) {
4940
+ if (doc.cm) throw new Error("This document is already in use.");
4941
+ cm.doc = doc;
4942
+ doc.cm = cm;
4943
+ estimateLineHeights(cm);
4944
+ loadMode(cm);
4945
+ if (!cm.options.lineWrapping) computeMaxLength(cm);
4946
+ cm.options.mode = doc.modeOption;
4947
+ regChange(cm);
4948
+ }
4949
+
4950
+ // LINE UTILITIES
4951
+
4952
+ function getLine(chunk, n) {
4953
+ n -= chunk.first;
4954
+ while (!chunk.lines) {
4955
+ for (var i = 0;; ++i) {
4956
+ var child = chunk.children[i], sz = child.chunkSize();
4957
+ if (n < sz) { chunk = child; break; }
4958
+ n -= sz;
4959
+ }
4960
+ }
4961
+ return chunk.lines[n];
4962
+ }
4963
+
4964
+ function getBetween(doc, start, end) {
4965
+ var out = [], n = start.line;
4966
+ doc.iter(start.line, end.line + 1, function(line) {
4967
+ var text = line.text;
4968
+ if (n == end.line) text = text.slice(0, end.ch);
4969
+ if (n == start.line) text = text.slice(start.ch);
4970
+ out.push(text);
4971
+ ++n;
4972
+ });
4973
+ return out;
4974
+ }
4975
+ function getLines(doc, from, to) {
4976
+ var out = [];
4977
+ doc.iter(from, to, function(line) { out.push(line.text); });
4978
+ return out;
4979
+ }
4980
+
4981
+ function updateLineHeight(line, height) {
4982
+ var diff = height - line.height;
4983
+ for (var n = line; n; n = n.parent) n.height += diff;
4984
+ }
4985
+
4986
+ function lineNo(line) {
4987
+ if (line.parent == null) return null;
4988
+ var cur = line.parent, no = indexOf(cur.lines, line);
4989
+ for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
4990
+ for (var i = 0;; ++i) {
4991
+ if (chunk.children[i] == cur) break;
4992
+ no += chunk.children[i].chunkSize();
4993
+ }
4994
+ }
4995
+ return no + cur.first;
4996
+ }
4997
+
4998
+ function lineAtHeight(chunk, h) {
4999
+ var n = chunk.first;
5000
+ outer: do {
5001
+ for (var i = 0, e = chunk.children.length; i < e; ++i) {
5002
+ var child = chunk.children[i], ch = child.height;
5003
+ if (h < ch) { chunk = child; continue outer; }
5004
+ h -= ch;
5005
+ n += child.chunkSize();
5006
+ }
5007
+ return n;
5008
+ } while (!chunk.lines);
5009
+ for (var i = 0, e = chunk.lines.length; i < e; ++i) {
5010
+ var line = chunk.lines[i], lh = line.height;
5011
+ if (h < lh) break;
5012
+ h -= lh;
5013
+ }
5014
+ return n + i;
5015
+ }
5016
+
5017
+ function heightAtLine(cm, lineObj) {
5018
+ lineObj = visualLine(cm.doc, lineObj);
5019
+
5020
+ var h = 0, chunk = lineObj.parent;
5021
+ for (var i = 0; i < chunk.lines.length; ++i) {
5022
+ var line = chunk.lines[i];
5023
+ if (line == lineObj) break;
5024
+ else h += line.height;
5025
+ }
5026
+ for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
5027
+ for (var i = 0; i < p.children.length; ++i) {
5028
+ var cur = p.children[i];
5029
+ if (cur == chunk) break;
5030
+ else h += cur.height;
5031
+ }
5032
+ }
5033
+ return h;
5034
+ }
5035
+
5036
+ function getOrder(line) {
5037
+ var order = line.order;
5038
+ if (order == null) order = line.order = bidiOrdering(line.text);
5039
+ return order;
5040
+ }
5041
+
5042
+ // HISTORY
5043
+
5044
+ function makeHistory(startGen) {
5045
+ return {
5046
+ // Arrays of history events. Doing something adds an event to
5047
+ // done and clears undo. Undoing moves events from done to
5048
+ // undone, redoing moves them in the other direction.
5049
+ done: [], undone: [], undoDepth: Infinity,
5050
+ // Used to track when changes can be merged into a single undo
5051
+ // event
5052
+ lastTime: 0, lastOp: null, lastOrigin: null,
5053
+ // Used by the isClean() method
5054
+ generation: startGen || 1, maxGeneration: startGen || 1
5055
+ };
5056
+ }
5057
+
5058
+ function attachLocalSpans(doc, change, from, to) {
5059
+ var existing = change["spans_" + doc.id], n = 0;
5060
+ doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
5061
+ if (line.markedSpans)
5062
+ (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
5063
+ ++n;
5064
+ });
5065
+ }
5066
+
5067
+ function historyChangeFromChange(doc, change) {
5068
+ var from = { line: change.from.line, ch: change.from.ch };
5069
+ var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
5070
+ attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
5071
+ linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
5072
+ return histChange;
5073
+ }
5074
+
5075
+ function addToHistory(doc, change, selAfter, opId) {
5076
+ var hist = doc.history;
5077
+ hist.undone.length = 0;
5078
+ var time = +new Date, cur = lst(hist.done);
5079
+
5080
+ if (cur &&
5081
+ (hist.lastOp == opId ||
5082
+ hist.lastOrigin == change.origin && change.origin &&
5083
+ ((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) ||
5084
+ change.origin.charAt(0) == "*"))) {
5085
+ // Merge this change into the last event
5086
+ var last = lst(cur.changes);
5087
+ if (posEq(change.from, change.to) && posEq(change.from, last.to)) {
5088
+ // Optimized case for simple insertion -- don't want to add
5089
+ // new changesets for every character typed
5090
+ last.to = changeEnd(change);
5091
+ } else {
5092
+ // Add new sub-event
5093
+ cur.changes.push(historyChangeFromChange(doc, change));
5094
+ }
5095
+ cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head;
5096
+ } else {
5097
+ // Can not be merged, start a new event.
5098
+ cur = {changes: [historyChangeFromChange(doc, change)],
5099
+ generation: hist.generation,
5100
+ anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
5101
+ anchorAfter: selAfter.anchor, headAfter: selAfter.head};
5102
+ hist.done.push(cur);
5103
+ hist.generation = ++hist.maxGeneration;
5104
+ while (hist.done.length > hist.undoDepth)
5105
+ hist.done.shift();
5106
+ }
5107
+ hist.lastTime = time;
5108
+ hist.lastOp = opId;
5109
+ hist.lastOrigin = change.origin;
5110
+ }
5111
+
5112
+ function removeClearedSpans(spans) {
5113
+ if (!spans) return null;
5114
+ for (var i = 0, out; i < spans.length; ++i) {
5115
+ if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
5116
+ else if (out) out.push(spans[i]);
5117
+ }
5118
+ return !out ? spans : out.length ? out : null;
5119
+ }
5120
+
5121
+ function getOldSpans(doc, change) {
5122
+ var found = change["spans_" + doc.id];
5123
+ if (!found) return null;
5124
+ for (var i = 0, nw = []; i < change.text.length; ++i)
5125
+ nw.push(removeClearedSpans(found[i]));
5126
+ return nw;
5127
+ }
5128
+
5129
+ // Used both to provide a JSON-safe object in .getHistory, and, when
5130
+ // detaching a document, to split the history in two
5131
+ function copyHistoryArray(events, newGroup) {
5132
+ for (var i = 0, copy = []; i < events.length; ++i) {
5133
+ var event = events[i], changes = event.changes, newChanges = [];
5134
+ copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore,
5135
+ anchorAfter: event.anchorAfter, headAfter: event.headAfter});
5136
+ for (var j = 0; j < changes.length; ++j) {
5137
+ var change = changes[j], m;
5138
+ newChanges.push({from: change.from, to: change.to, text: change.text});
5139
+ if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
5140
+ if (indexOf(newGroup, Number(m[1])) > -1) {
5141
+ lst(newChanges)[prop] = change[prop];
5142
+ delete change[prop];
5143
+ }
5144
+ }
5145
+ }
5146
+ }
5147
+ return copy;
5148
+ }
5149
+
5150
+ // Rebasing/resetting history to deal with externally-sourced changes
5151
+
5152
+ function rebaseHistSel(pos, from, to, diff) {
5153
+ if (to < pos.line) {
5154
+ pos.line += diff;
5155
+ } else if (from < pos.line) {
5156
+ pos.line = from;
5157
+ pos.ch = 0;
5158
+ }
5159
+ }
5160
+
5161
+ // Tries to rebase an array of history events given a change in the
5162
+ // document. If the change touches the same lines as the event, the
5163
+ // event, and everything 'behind' it, is discarded. If the change is
5164
+ // before the event, the event's positions are updated. Uses a
5165
+ // copy-on-write scheme for the positions, to avoid having to
5166
+ // reallocate them all on every rebase, but also avoid problems with
5167
+ // shared position objects being unsafely updated.
5168
+ function rebaseHistArray(array, from, to, diff) {
5169
+ for (var i = 0; i < array.length; ++i) {
5170
+ var sub = array[i], ok = true;
5171
+ for (var j = 0; j < sub.changes.length; ++j) {
5172
+ var cur = sub.changes[j];
5173
+ if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); }
5174
+ if (to < cur.from.line) {
5175
+ cur.from.line += diff;
5176
+ cur.to.line += diff;
5177
+ } else if (from <= cur.to.line) {
5178
+ ok = false;
5179
+ break;
5180
+ }
5181
+ }
5182
+ if (!sub.copied) {
5183
+ sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore);
5184
+ sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter);
5185
+ sub.copied = true;
5186
+ }
5187
+ if (!ok) {
5188
+ array.splice(0, i + 1);
5189
+ i = 0;
5190
+ } else {
5191
+ rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore);
5192
+ rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter);
5193
+ }
5194
+ }
5195
+ }
5196
+
5197
+ function rebaseHist(hist, change) {
5198
+ var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
5199
+ rebaseHistArray(hist.done, from, to, diff);
5200
+ rebaseHistArray(hist.undone, from, to, diff);
5201
+ }
5202
+
5203
+ // EVENT OPERATORS
5204
+
5205
+ function stopMethod() {e_stop(this);}
5206
+ // Ensure an event has a stop method.
5207
+ function addStop(event) {
5208
+ if (!event.stop) event.stop = stopMethod;
5209
+ return event;
5210
+ }
5211
+
5212
+ function e_preventDefault(e) {
5213
+ if (e.preventDefault) e.preventDefault();
5214
+ else e.returnValue = false;
5215
+ }
5216
+ function e_stopPropagation(e) {
5217
+ if (e.stopPropagation) e.stopPropagation();
5218
+ else e.cancelBubble = true;
5219
+ }
5220
+ function e_defaultPrevented(e) {
5221
+ return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
5222
+ }
5223
+ function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
5224
+ CodeMirror.e_stop = e_stop;
5225
+ CodeMirror.e_preventDefault = e_preventDefault;
5226
+ CodeMirror.e_stopPropagation = e_stopPropagation;
5227
+
5228
+ function e_target(e) {return e.target || e.srcElement;}
5229
+ function e_button(e) {
5230
+ var b = e.which;
5231
+ if (b == null) {
5232
+ if (e.button & 1) b = 1;
5233
+ else if (e.button & 2) b = 3;
5234
+ else if (e.button & 4) b = 2;
5235
+ }
5236
+ if (mac && e.ctrlKey && b == 1) b = 3;
5237
+ return b;
5238
+ }
5239
+
5240
+ // EVENT HANDLING
5241
+
5242
+ function on(emitter, type, f) {
5243
+ if (emitter.addEventListener)
5244
+ emitter.addEventListener(type, f, false);
5245
+ else if (emitter.attachEvent)
5246
+ emitter.attachEvent("on" + type, f);
5247
+ else {
5248
+ var map = emitter._handlers || (emitter._handlers = {});
5249
+ var arr = map[type] || (map[type] = []);
5250
+ arr.push(f);
5251
+ }
5252
+ }
5253
+
5254
+ function off(emitter, type, f) {
5255
+ if (emitter.removeEventListener)
5256
+ emitter.removeEventListener(type, f, false);
5257
+ else if (emitter.detachEvent)
5258
+ emitter.detachEvent("on" + type, f);
5259
+ else {
5260
+ var arr = emitter._handlers && emitter._handlers[type];
5261
+ if (!arr) return;
5262
+ for (var i = 0; i < arr.length; ++i)
5263
+ if (arr[i] == f) { arr.splice(i, 1); break; }
5264
+ }
5265
+ }
5266
+
5267
+ function signal(emitter, type /*, values...*/) {
5268
+ var arr = emitter._handlers && emitter._handlers[type];
5269
+ if (!arr) return;
5270
+ var args = Array.prototype.slice.call(arguments, 2);
5271
+ for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
5272
+ }
5273
+
5274
+ var delayedCallbacks, delayedCallbackDepth = 0;
5275
+ function signalLater(emitter, type /*, values...*/) {
5276
+ var arr = emitter._handlers && emitter._handlers[type];
5277
+ if (!arr) return;
5278
+ var args = Array.prototype.slice.call(arguments, 2);
5279
+ if (!delayedCallbacks) {
5280
+ ++delayedCallbackDepth;
5281
+ delayedCallbacks = [];
5282
+ setTimeout(fireDelayed, 0);
5283
+ }
5284
+ function bnd(f) {return function(){f.apply(null, args);};};
5285
+ for (var i = 0; i < arr.length; ++i)
5286
+ delayedCallbacks.push(bnd(arr[i]));
5287
+ }
5288
+
5289
+ function signalDOMEvent(cm, e, override) {
5290
+ signal(cm, override || e.type, cm, e);
5291
+ return e_defaultPrevented(e) || e.codemirrorIgnore;
5292
+ }
5293
+
5294
+ function fireDelayed() {
5295
+ --delayedCallbackDepth;
5296
+ var delayed = delayedCallbacks;
5297
+ delayedCallbacks = null;
5298
+ for (var i = 0; i < delayed.length; ++i) delayed[i]();
5299
+ }
5300
+
5301
+ function hasHandler(emitter, type) {
5302
+ var arr = emitter._handlers && emitter._handlers[type];
5303
+ return arr && arr.length > 0;
5304
+ }
5305
+
5306
+ CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
5307
+
5308
+ function eventMixin(ctor) {
5309
+ ctor.prototype.on = function(type, f) {on(this, type, f);};
5310
+ ctor.prototype.off = function(type, f) {off(this, type, f);};
5311
+ }
5312
+
5313
+ // MISC UTILITIES
5314
+
5315
+ // Number of pixels added to scroller and sizer to hide scrollbar
5316
+ var scrollerCutOff = 30;
5317
+
5318
+ // Returned or thrown by various protocols to signal 'I'm not
5319
+ // handling this'.
5320
+ var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
5321
+
5322
+ function Delayed() {this.id = null;}
5323
+ Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
5324
+
5325
+ // Counts the column offset in a string, taking tabs into account.
5326
+ // Used mostly to find indentation.
5327
+ function countColumn(string, end, tabSize, startIndex, startValue) {
5328
+ if (end == null) {
5329
+ end = string.search(/[^\s\u00a0]/);
5330
+ if (end == -1) end = string.length;
5331
+ }
5332
+ for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) {
5333
+ if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
5334
+ else ++n;
5335
+ }
5336
+ return n;
5337
+ }
5338
+ CodeMirror.countColumn = countColumn;
5339
+
5340
+ var spaceStrs = [""];
5341
+ function spaceStr(n) {
5342
+ while (spaceStrs.length <= n)
5343
+ spaceStrs.push(lst(spaceStrs) + " ");
5344
+ return spaceStrs[n];
5345
+ }
5346
+
5347
+ function lst(arr) { return arr[arr.length-1]; }
5348
+
5349
+ function selectInput(node) {
5350
+ if (ios) { // Mobile Safari apparently has a bug where select() is broken.
5351
+ node.selectionStart = 0;
5352
+ node.selectionEnd = node.value.length;
5353
+ } else {
5354
+ // Suppress mysterious IE10 errors
5355
+ try { node.select(); }
5356
+ catch(_e) {}
5357
+ }
5358
+ }
5359
+
5360
+ function indexOf(collection, elt) {
5361
+ if (collection.indexOf) return collection.indexOf(elt);
5362
+ for (var i = 0, e = collection.length; i < e; ++i)
5363
+ if (collection[i] == elt) return i;
5364
+ return -1;
5365
+ }
5366
+
5367
+ function createObj(base, props) {
5368
+ function Obj() {}
5369
+ Obj.prototype = base;
5370
+ var inst = new Obj();
5371
+ if (props) copyObj(props, inst);
5372
+ return inst;
5373
+ }
5374
+
5375
+ function copyObj(obj, target) {
5376
+ if (!target) target = {};
5377
+ for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
5378
+ return target;
5379
+ }
5380
+
5381
+ function emptyArray(size) {
5382
+ for (var a = [], i = 0; i < size; ++i) a.push(undefined);
5383
+ return a;
5384
+ }
5385
+
5386
+ function bind(f) {
5387
+ var args = Array.prototype.slice.call(arguments, 1);
5388
+ return function(){return f.apply(null, args);};
5389
+ }
5390
+
5391
+ var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
5392
+ function isWordChar(ch) {
5393
+ return /\w/.test(ch) || ch > "\x80" &&
5394
+ (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
5395
+ }
5396
+
5397
+ function isEmpty(obj) {
5398
+ for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
5399
+ return true;
5400
+ }
5401
+
5402
+ var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;
5403
+
5404
+ // DOM UTILITIES
5405
+
5406
+ function elt(tag, content, className, style) {
5407
+ var e = document.createElement(tag);
5408
+ if (className) e.className = className;
5409
+ if (style) e.style.cssText = style;
5410
+ if (typeof content == "string") setTextContent(e, content);
5411
+ else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
5412
+ return e;
5413
+ }
5414
+
5415
+ function removeChildren(e) {
5416
+ for (var count = e.childNodes.length; count > 0; --count)
5417
+ e.removeChild(e.firstChild);
5418
+ return e;
5419
+ }
5420
+
5421
+ function removeChildrenAndAdd(parent, e) {
5422
+ return removeChildren(parent).appendChild(e);
5423
+ }
5424
+
5425
+ function setTextContent(e, str) {
5426
+ if (ie_lt9) {
5427
+ e.innerHTML = "";
5428
+ e.appendChild(document.createTextNode(str));
5429
+ } else e.textContent = str;
5430
+ }
5431
+
5432
+ function getRect(node) {
5433
+ return node.getBoundingClientRect();
5434
+ }
5435
+ CodeMirror.replaceGetRect = function(f) { getRect = f; };
5436
+
5437
+ // FEATURE DETECTION
5438
+
5439
+ // Detect drag-and-drop
5440
+ var dragAndDrop = function() {
5441
+ // There is *some* kind of drag-and-drop support in IE6-8, but I
5442
+ // couldn't get it to work yet.
5443
+ if (ie_lt9) return false;
5444
+ var div = elt('div');
5445
+ return "draggable" in div || "dragDrop" in div;
5446
+ }();
5447
+
5448
+ // For a reason I have yet to figure out, some browsers disallow
5449
+ // word wrapping between certain characters *only* if a new inline
5450
+ // element is started between them. This makes it hard to reliably
5451
+ // measure the position of things, since that requires inserting an
5452
+ // extra span. This terribly fragile set of tests matches the
5453
+ // character combinations that suffer from this phenomenon on the
5454
+ // various browsers.
5455
+ function spanAffectsWrapping() { return false; }
5456
+ if (gecko) // Only for "$'"
5457
+ spanAffectsWrapping = function(str, i) {
5458
+ return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39;
5459
+ };
5460
+ else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
5461
+ spanAffectsWrapping = function(str, i) {
5462
+ return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
5463
+ };
5464
+ else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
5465
+ spanAffectsWrapping = function(str, i) {
5466
+ if (i > 1 && str.charCodeAt(i - 1) == 45) {
5467
+ if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
5468
+ if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
5469
+ }
5470
+ return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
5471
+ };
5472
+
5473
+ var knownScrollbarWidth;
5474
+ function scrollbarWidth(measure) {
5475
+ if (knownScrollbarWidth != null) return knownScrollbarWidth;
5476
+ var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
5477
+ removeChildrenAndAdd(measure, test);
5478
+ if (test.offsetWidth)
5479
+ knownScrollbarWidth = test.offsetHeight - test.clientHeight;
5480
+ return knownScrollbarWidth || 0;
5481
+ }
5482
+
5483
+ var zwspSupported;
5484
+ function zeroWidthElement(measure) {
5485
+ if (zwspSupported == null) {
5486
+ var test = elt("span", "\u200b");
5487
+ removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
5488
+ if (measure.firstChild.offsetHeight != 0)
5489
+ zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8;
5490
+ }
5491
+ if (zwspSupported) return elt("span", "\u200b");
5492
+ else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
5493
+ }
5494
+
5495
+ // See if "".split is the broken IE version, if so, provide an
5496
+ // alternative way to split lines.
5497
+ var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
5498
+ var pos = 0, result = [], l = string.length;
5499
+ while (pos <= l) {
5500
+ var nl = string.indexOf("\n", pos);
5501
+ if (nl == -1) nl = string.length;
5502
+ var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
5503
+ var rt = line.indexOf("\r");
5504
+ if (rt != -1) {
5505
+ result.push(line.slice(0, rt));
5506
+ pos += rt + 1;
5507
+ } else {
5508
+ result.push(line);
5509
+ pos = nl + 1;
5510
+ }
5511
+ }
5512
+ return result;
5513
+ } : function(string){return string.split(/\r\n?|\n/);};
5514
+ CodeMirror.splitLines = splitLines;
5515
+
5516
+ var hasSelection = window.getSelection ? function(te) {
5517
+ try { return te.selectionStart != te.selectionEnd; }
5518
+ catch(e) { return false; }
5519
+ } : function(te) {
5520
+ try {var range = te.ownerDocument.selection.createRange();}
5521
+ catch(e) {}
5522
+ if (!range || range.parentElement() != te) return false;
5523
+ return range.compareEndPoints("StartToEnd", range) != 0;
5524
+ };
5525
+
5526
+ var hasCopyEvent = (function() {
5527
+ var e = elt("div");
5528
+ if ("oncopy" in e) return true;
5529
+ e.setAttribute("oncopy", "return;");
5530
+ return typeof e.oncopy == 'function';
5531
+ })();
5532
+
5533
+ // KEY NAMING
5534
+
5535
+ var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
5536
+ 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
5537
+ 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
5538
+ 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
5539
+ 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
5540
+ 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
5541
+ 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
5542
+ CodeMirror.keyNames = keyNames;
5543
+ (function() {
5544
+ // Number keys
5545
+ for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
5546
+ // Alphabetic keys
5547
+ for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
5548
+ // Function keys
5549
+ for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
5550
+ })();
5551
+
5552
+ // BIDI HELPERS
5553
+
5554
+ function iterateBidiSections(order, from, to, f) {
5555
+ if (!order) return f(from, to, "ltr");
5556
+ var found = false;
5557
+ for (var i = 0; i < order.length; ++i) {
5558
+ var part = order[i];
5559
+ if (part.from < to && part.to > from || from == to && part.to == from) {
5560
+ f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
5561
+ found = true;
5562
+ }
5563
+ }
5564
+ if (!found) f(from, to, "ltr");
5565
+ }
5566
+
5567
+ function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
5568
+ function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
5569
+
5570
+ function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
5571
+ function lineRight(line) {
5572
+ var order = getOrder(line);
5573
+ if (!order) return line.text.length;
5574
+ return bidiRight(lst(order));
5575
+ }
5576
+
5577
+ function lineStart(cm, lineN) {
5578
+ var line = getLine(cm.doc, lineN);
5579
+ var visual = visualLine(cm.doc, line);
5580
+ if (visual != line) lineN = lineNo(visual);
5581
+ var order = getOrder(visual);
5582
+ var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
5583
+ return Pos(lineN, ch);
5584
+ }
5585
+ function lineEnd(cm, lineN) {
5586
+ var merged, line;
5587
+ while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN)))
5588
+ lineN = merged.find().to.line;
5589
+ var order = getOrder(line);
5590
+ var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
5591
+ return Pos(lineN, ch);
5592
+ }
5593
+
5594
+ function compareBidiLevel(order, a, b) {
5595
+ var linedir = order[0].level;
5596
+ if (a == linedir) return true;
5597
+ if (b == linedir) return false;
5598
+ return a < b;
5599
+ }
5600
+ var bidiOther;
5601
+ function getBidiPartAt(order, pos) {
5602
+ for (var i = 0, found; i < order.length; ++i) {
5603
+ var cur = order[i];
5604
+ if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; }
5605
+ if (cur.from == pos || cur.to == pos) {
5606
+ if (found == null) {
5607
+ found = i;
5608
+ } else if (compareBidiLevel(order, cur.level, order[found].level)) {
5609
+ bidiOther = found;
5610
+ return i;
5611
+ } else {
5612
+ bidiOther = i;
5613
+ return found;
5614
+ }
5615
+ }
5616
+ }
5617
+ bidiOther = null;
5618
+ return found;
5619
+ }
5620
+
5621
+ function moveInLine(line, pos, dir, byUnit) {
5622
+ if (!byUnit) return pos + dir;
5623
+ do pos += dir;
5624
+ while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
5625
+ return pos;
5626
+ }
5627
+
5628
+ // This is somewhat involved. It is needed in order to move
5629
+ // 'visually' through bi-directional text -- i.e., pressing left
5630
+ // should make the cursor go left, even when in RTL text. The
5631
+ // tricky part is the 'jumps', where RTL and LTR text touch each
5632
+ // other. This often requires the cursor offset to move more than
5633
+ // one unit, in order to visually move one unit.
5634
+ function moveVisually(line, start, dir, byUnit) {
5635
+ var bidi = getOrder(line);
5636
+ if (!bidi) return moveLogically(line, start, dir, byUnit);
5637
+ var pos = getBidiPartAt(bidi, start), part = bidi[pos];
5638
+ var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
5639
+
5640
+ for (;;) {
5641
+ if (target > part.from && target < part.to) return target;
5642
+ if (target == part.from || target == part.to) {
5643
+ if (getBidiPartAt(bidi, target) == pos) return target;
5644
+ part = bidi[pos += dir];
5645
+ return (dir > 0) == part.level % 2 ? part.to : part.from;
5646
+ } else {
5647
+ part = bidi[pos += dir];
5648
+ if (!part) return null;
5649
+ if ((dir > 0) == part.level % 2)
5650
+ target = moveInLine(line, part.to, -1, byUnit);
5651
+ else
5652
+ target = moveInLine(line, part.from, 1, byUnit);
5653
+ }
5654
+ }
5655
+ }
5656
+
5657
+ function moveLogically(line, start, dir, byUnit) {
5658
+ var target = start + dir;
5659
+ if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
5660
+ return target < 0 || target > line.text.length ? null : target;
5661
+ }
5662
+
5663
+ // Bidirectional ordering algorithm
5664
+ // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
5665
+ // that this (partially) implements.
5666
+
5667
+ // One-char codes used for character types:
5668
+ // L (L): Left-to-Right
5669
+ // R (R): Right-to-Left
5670
+ // r (AL): Right-to-Left Arabic
5671
+ // 1 (EN): European Number
5672
+ // + (ES): European Number Separator
5673
+ // % (ET): European Number Terminator
5674
+ // n (AN): Arabic Number
5675
+ // , (CS): Common Number Separator
5676
+ // m (NSM): Non-Spacing Mark
5677
+ // b (BN): Boundary Neutral
5678
+ // s (B): Paragraph Separator
5679
+ // t (S): Segment Separator
5680
+ // w (WS): Whitespace
5681
+ // N (ON): Other Neutrals
5682
+
5683
+ // Returns null if characters are ordered as they appear
5684
+ // (left-to-right), or an array of sections ({from, to, level}
5685
+ // objects) in the order in which they occur visually.
5686
+ var bidiOrdering = (function() {
5687
+ // Character types for codepoints 0 to 0xff
5688
+ var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";
5689
+ // Character types for codepoints 0x600 to 0x6ff
5690
+ var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr";
5691
+ function charType(code) {
5692
+ if (code <= 0xff) return lowTypes.charAt(code);
5693
+ else if (0x590 <= code && code <= 0x5f4) return "R";
5694
+ else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
5695
+ else if (0x700 <= code && code <= 0x8ac) return "r";
5696
+ else return "L";
5697
+ }
5698
+
5699
+ var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
5700
+ var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
5701
+ // Browsers seem to always treat the boundaries of block elements as being L.
5702
+ var outerType = "L";
5703
+
5704
+ return function(str) {
5705
+ if (!bidiRE.test(str)) return false;
5706
+ var len = str.length, types = [];
5707
+ for (var i = 0, type; i < len; ++i)
5708
+ types.push(type = charType(str.charCodeAt(i)));
5709
+
5710
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
5711
+ // change the type of the NSM to the type of the previous
5712
+ // character. If the NSM is at the start of the level run, it will
5713
+ // get the type of sor.
5714
+ for (var i = 0, prev = outerType; i < len; ++i) {
5715
+ var type = types[i];
5716
+ if (type == "m") types[i] = prev;
5717
+ else prev = type;
5718
+ }
5719
+
5720
+ // W2. Search backwards from each instance of a European number
5721
+ // until the first strong type (R, L, AL, or sor) is found. If an
5722
+ // AL is found, change the type of the European number to Arabic
5723
+ // number.
5724
+ // W3. Change all ALs to R.
5725
+ for (var i = 0, cur = outerType; i < len; ++i) {
5726
+ var type = types[i];
5727
+ if (type == "1" && cur == "r") types[i] = "n";
5728
+ else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
5729
+ }
5730
+
5731
+ // W4. A single European separator between two European numbers
5732
+ // changes to a European number. A single common separator between
5733
+ // two numbers of the same type changes to that type.
5734
+ for (var i = 1, prev = types[0]; i < len - 1; ++i) {
5735
+ var type = types[i];
5736
+ if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
5737
+ else if (type == "," && prev == types[i+1] &&
5738
+ (prev == "1" || prev == "n")) types[i] = prev;
5739
+ prev = type;
5740
+ }
5741
+
5742
+ // W5. A sequence of European terminators adjacent to European
5743
+ // numbers changes to all European numbers.
5744
+ // W6. Otherwise, separators and terminators change to Other
5745
+ // Neutral.
5746
+ for (var i = 0; i < len; ++i) {
5747
+ var type = types[i];
5748
+ if (type == ",") types[i] = "N";
5749
+ else if (type == "%") {
5750
+ for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
5751
+ var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
5752
+ for (var j = i; j < end; ++j) types[j] = replace;
5753
+ i = end - 1;
5754
+ }
5755
+ }
5756
+
5757
+ // W7. Search backwards from each instance of a European number
5758
+ // until the first strong type (R, L, or sor) is found. If an L is
5759
+ // found, then change the type of the European number to L.
5760
+ for (var i = 0, cur = outerType; i < len; ++i) {
5761
+ var type = types[i];
5762
+ if (cur == "L" && type == "1") types[i] = "L";
5763
+ else if (isStrong.test(type)) cur = type;
5764
+ }
5765
+
5766
+ // N1. A sequence of neutrals takes the direction of the
5767
+ // surrounding strong text if the text on both sides has the same
5768
+ // direction. European and Arabic numbers act as if they were R in
5769
+ // terms of their influence on neutrals. Start-of-level-run (sor)
5770
+ // and end-of-level-run (eor) are used at level run boundaries.
5771
+ // N2. Any remaining neutrals take the embedding direction.
5772
+ for (var i = 0; i < len; ++i) {
5773
+ if (isNeutral.test(types[i])) {
5774
+ for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
5775
+ var before = (i ? types[i-1] : outerType) == "L";
5776
+ var after = (end < len - 1 ? types[end] : outerType) == "L";
5777
+ var replace = before || after ? "L" : "R";
5778
+ for (var j = i; j < end; ++j) types[j] = replace;
5779
+ i = end - 1;
5780
+ }
5781
+ }
5782
+
5783
+ // Here we depart from the documented algorithm, in order to avoid
5784
+ // building up an actual levels array. Since there are only three
5785
+ // levels (0, 1, 2) in an implementation that doesn't take
5786
+ // explicit embedding into account, we can build up the order on
5787
+ // the fly, without following the level-based algorithm.
5788
+ var order = [], m;
5789
+ for (var i = 0; i < len;) {
5790
+ if (countsAsLeft.test(types[i])) {
5791
+ var start = i;
5792
+ for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
5793
+ order.push({from: start, to: i, level: 0});
5794
+ } else {
5795
+ var pos = i, at = order.length;
5796
+ for (++i; i < len && types[i] != "L"; ++i) {}
5797
+ for (var j = pos; j < i;) {
5798
+ if (countsAsNum.test(types[j])) {
5799
+ if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1});
5800
+ var nstart = j;
5801
+ for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
5802
+ order.splice(at, 0, {from: nstart, to: j, level: 2});
5803
+ pos = j;
5804
+ } else ++j;
5805
+ }
5806
+ if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1});
5807
+ }
5808
+ }
5809
+ if (order[0].level == 1 && (m = str.match(/^\s+/))) {
5810
+ order[0].from = m[0].length;
5811
+ order.unshift({from: 0, to: m[0].length, level: 0});
5812
+ }
5813
+ if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
5814
+ lst(order).to -= m[0].length;
5815
+ order.push({from: len - m[0].length, to: len, level: 0});
5816
+ }
5817
+ if (order[0].level != lst(order).level)
5818
+ order.push({from: len, to: len, level: order[0].level});
5819
+
5820
+ return order;
5821
+ };
5822
+ })();
5823
+
5824
+ // THE END
5825
+
5826
+ CodeMirror.version = "3.16.0";
5827
+
5828
+ return CodeMirror;
5829
+ })();
media/js/extension.js ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * ======================================================================
3
+ * LICENSE: This file is subject to the terms and conditions defined in *
4
+ * file 'license.txt', which is part of this source code package. *
5
+ * ======================================================================
6
+ */
7
+
8
+ jQuery(document).ready(function() {
9
+ jQuery('#extension_list').dataTable({
10
+ sDom: "<'top'f<'clear'>>t<'footer'p<'clear'>>",
11
+ //bProcessing : false,
12
+ bStateSave: true,
13
+ sPaginationType: "full_numbers",
14
+ bAutoWidth: false,
15
+ bSort: false,
16
+ oLanguage: {
17
+ "sSearch": "",
18
+ "oPaginate": {
19
+ "sFirst": "&Lt;",
20
+ "sLast": "&Gt;",
21
+ "sNext": "&gt;",
22
+ "sPrevious": "&lt;"
23
+ }
24
+ },
25
+ fnDrawCallback: function() {
26
+ jQuery('.extension-action-purchase').each(function() {
27
+ var link = jQuery(this).attr('link');
28
+ var extension = jQuery(this).attr('extension');
29
+
30
+ jQuery(this).bind('click', function() {
31
+ //show the dialog
32
+ jQuery('#install_extension').dialog({
33
+ resizable: false,
34
+ height: 'auto',
35
+ width: '30%',
36
+ modal: true,
37
+ buttons: [
38
+ {
39
+ text: 'Purchase',
40
+ icons: {primary: "ui-icon-cart"},
41
+ click: function() {
42
+ window.open(link, '_blank');
43
+ }
44
+ },
45
+ {
46
+ text: 'Install',
47
+ icons: {primary: "ui-icon-check"},
48
+ click: function() {
49
+ var license = jQuery.trim(
50
+ jQuery('#license_key').val()
51
+ );
52
+
53
+ if (license) {
54
+ //add loader
55
+ jQuery('#install_extension').append(jQuery('<div/>', {
56
+ 'class' : 'loading-extension'
57
+ }));
58
+
59
+ jQuery.ajax(aamLocal.ajaxurl, {
60
+ type: 'POST',
61
+ dataType: 'json',
62
+ data: {
63
+ action: 'aam',
64
+ sub_action: 'install_extension',
65
+ extension: extension,
66
+ license: license,
67
+ _ajax_nonce: aamLocal.nonce
68
+ },
69
+ success: function(response) {
70
+ if (response.status === 'success') {
71
+ location.reload();
72
+ } else {
73
+ jQuery('#license_key').effect('highlight', 2000);
74
+ }
75
+ },
76
+ error: function() {
77
+ jQuery('#license_key').effect('highlight', 2000);
78
+ },
79
+ complete: function(){
80
+ jQuery('.loading-extension', '#install_extension').remove();
81
+ }
82
+ });
83
+ } else {
84
+ jQuery('#license_key').effect('highlight', 2000);
85
+ }
86
+ }
87
+ },
88
+ {
89
+ text: 'Close',
90
+ icons: {primary: "ui-icon-close"},
91
+ click: function() {
92
+ jQuery(this).dialog('close');
93
+ }
94
+ }
95
+ ]
96
+ });
97
+ });
98
+ });
99
+ jQuery('.extension-action-ok').each(function() {
100
+ jQuery(this).bind('click', function() {
101
+ var license = jQuery(this).attr('license');
102
+ var extension = jQuery(this).attr('extension');
103
+ var dialog = this;
104
+
105
+ jQuery('#installed_license_key').html(license);
106
+ //show the dialog
107
+ jQuery('#update_extension').dialog({
108
+ resizable: false,
109
+ height: 'auto',
110
+ width: '25%',
111
+ modal: true,
112
+ buttons: [
113
+ {
114
+ text: 'Remove',
115
+ icons: {primary: "ui-icon-trash"},
116
+ click: function() {
117
+ jQuery.ajax(aamLocal.ajaxurl, {
118
+ type: 'POST',
119
+ dataType: 'json',
120
+ data: {
121
+ action: 'aam',
122
+ sub_action: 'remove_extension',
123
+ extension: extension,
124
+ license: license,
125
+ _ajax_nonce: aamLocal.nonce
126
+ },
127
+ success: function(response) {
128
+ if (response.status === 'success') {
129
+ location.reload();
130
+ } else {
131
+ jQuery(dialog).dialog('close');
132
+ }
133
+ },
134
+ complete: function() {
135
+ jQuery(dialog).dialog('close');
136
+ }
137
+ });
138
+ }
139
+ },
140
+ {
141
+ text: 'Close',
142
+ icons: {primary: "ui-icon-close"},
143
+ click: function() {
144
+ jQuery(this).dialog('close');
145
+ }
146
+ }
147
+ ]
148
+ });
149
+ });
150
+ });
151
+ }
152
+ });
153
+
154
+ initTooltip('#aam');
155
+
156
+ });
157
+
158
+ /**
159
+ * Initialize tooltip for selected area
160
+ *
161
+ * @param {String} selector
162
+ *
163
+ * @returns {void}
164
+ *
165
+ * @access public
166
+ */
167
+ function initTooltip(selector) {
168
+ jQuery('[tooltip]', selector).hover(function() {
169
+ // Hover over code
170
+ var title = jQuery(this).attr('tooltip');
171
+ jQuery(this).data('tipText', title).removeAttr('tooltip');
172
+ jQuery('<div/>', {
173
+ 'class': 'aam-tooltip'
174
+ }).text(title).appendTo('body').fadeIn('slow');
175
+ }, function() {
176
+ //Hover out code
177
+ jQuery(this).attr('tooltip', jQuery(this).data('tipText'));
178
+ jQuery('.aam-tooltip').remove();
179
+ }).mousemove(function(e) {
180
+ jQuery('.aam-tooltip').css({
181
+ top: e.pageY + 15, //Get Y coordinates
182
+ left: e.pageX + 15 //Get X coordinates
183
+ });
184
+ });
185
+ }
media/js/jquery.dt.js ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * File: jquery.dataTables.min.js
3
+ * Version: 1.9.4
4
+ * Author: Allan Jardine (www.sprymedia.co.uk)
5
+ * Info: www.datatables.net
6
+ *
7
+ * Copyright 2008-2012 Allan Jardine, all rights reserved.
8
+ *
9
+ * This source file is free software, under either the GPL v2 license or a
10
+ * BSD style license, available at:
11
+ * http://datatables.net/license_gpl2
12
+ * http://datatables.net/license_bsd
13
+ *
14
+ * This source file is distributed in the hope that it will be useful, but
15
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
17
+ */
18
+ (function(X,l,n){var L=function(h){var j=function(e){function o(a,b){var c=j.defaults.columns,d=a.aoColumns.length,c=h.extend({},j.models.oColumn,c,{sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,nTh:b?b:l.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.oDefaults:d});a.aoColumns.push(c);if(a.aoPreSearchCols[d]===n||null===a.aoPreSearchCols[d])a.aoPreSearchCols[d]=h.extend({},j.models.oSearch);else if(c=a.aoPreSearchCols[d],
19
+ c.bRegex===n&&(c.bRegex=!0),c.bSmart===n&&(c.bSmart=!0),c.bCaseInsensitive===n)c.bCaseInsensitive=!0;m(a,d,null)}function m(a,b,c){var d=a.aoColumns[b];c!==n&&null!==c&&(c.mDataProp&&!c.mData&&(c.mData=c.mDataProp),c.sType!==n&&(d.sType=c.sType,d._bAutoType=!1),h.extend(d,c),p(d,c,"sWidth","sWidthOrig"),c.iDataSort!==n&&(d.aDataSort=[c.iDataSort]),p(d,c,"aDataSort"));var i=d.mRender?Q(d.mRender):null,f=Q(d.mData);d.fnGetData=function(a,b){var c=f(a,b);return d.mRender&&b&&""!==b?i(c,b,a):c};d.fnSetData=
20
+ L(d.mData);a.oFeatures.bSort||(d.bSortable=!1);!d.bSortable||-1==h.inArray("asc",d.asSorting)&&-1==h.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortableNone,d.sSortingClassJUI=""):-1==h.inArray("asc",d.asSorting)&&-1==h.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortable,d.sSortingClassJUI=a.oClasses.sSortJUI):-1!=h.inArray("asc",d.asSorting)&&-1==h.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortableAsc,d.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed):-1==
21
+ h.inArray("asc",d.asSorting)&&-1!=h.inArray("desc",d.asSorting)&&(d.sSortingClass=a.oClasses.sSortableDesc,d.sSortingClassJUI=a.oClasses.sSortJUIDescAllowed)}function k(a){if(!1===a.oFeatures.bAutoWidth)return!1;da(a);for(var b=0,c=a.aoColumns.length;b<c;b++)a.aoColumns[b].nTh.style.width=a.aoColumns[b].sWidth}function G(a,b){var c=r(a,"bVisible");return"number"===typeof c[b]?c[b]:null}function R(a,b){var c=r(a,"bVisible"),c=h.inArray(b,c);return-1!==c?c:null}function t(a){return r(a,"bVisible").length}
22
+ function r(a,b){var c=[];h.map(a.aoColumns,function(a,i){a[b]&&c.push(i)});return c}function B(a){for(var b=j.ext.aTypes,c=b.length,d=0;d<c;d++){var i=b[d](a);if(null!==i)return i}return"string"}function u(a,b){for(var c=b.split(","),d=[],i=0,f=a.aoColumns.length;i<f;i++)for(var g=0;g<f;g++)if(a.aoColumns[i].sName==c[g]){d.push(g);break}return d}function M(a){for(var b="",c=0,d=a.aoColumns.length;c<d;c++)b+=a.aoColumns[c].sName+",";return b.length==d?"":b.slice(0,-1)}function ta(a,b,c,d){var i,f,
23
+ g,e,w;if(b)for(i=b.length-1;0<=i;i--){var j=b[i].aTargets;h.isArray(j)||D(a,1,"aTargets must be an array of targets, not a "+typeof j);f=0;for(g=j.length;f<g;f++)if("number"===typeof j[f]&&0<=j[f]){for(;a.aoColumns.length<=j[f];)o(a);d(j[f],b[i])}else if("number"===typeof j[f]&&0>j[f])d(a.aoColumns.length+j[f],b[i]);else if("string"===typeof j[f]){e=0;for(w=a.aoColumns.length;e<w;e++)("_all"==j[f]||h(a.aoColumns[e].nTh).hasClass(j[f]))&&d(e,b[i])}}if(c){i=0;for(a=c.length;i<a;i++)d(i,c[i])}}function H(a,
24
+ b){var c;c=h.isArray(b)?b.slice():h.extend(!0,{},b);var d=a.aoData.length,i=h.extend(!0,{},j.models.oRow);i._aData=c;a.aoData.push(i);for(var f,i=0,g=a.aoColumns.length;i<g;i++)c=a.aoColumns[i],"function"===typeof c.fnRender&&c.bUseRendered&&null!==c.mData?F(a,d,i,S(a,d,i)):F(a,d,i,v(a,d,i)),c._bAutoType&&"string"!=c.sType&&(f=v(a,d,i,"type"),null!==f&&""!==f&&(f=B(f),null===c.sType?c.sType=f:c.sType!=f&&"html"!=c.sType&&(c.sType="string")));a.aiDisplayMaster.push(d);a.oFeatures.bDeferRender||ea(a,
25
+ d);return d}function ua(a){var b,c,d,i,f,g,e;if(a.bDeferLoading||null===a.sAjaxSource)for(b=a.nTBody.firstChild;b;){if("TR"==b.nodeName.toUpperCase()){c=a.aoData.length;b._DT_RowIndex=c;a.aoData.push(h.extend(!0,{},j.models.oRow,{nTr:b}));a.aiDisplayMaster.push(c);f=b.firstChild;for(d=0;f;){g=f.nodeName.toUpperCase();if("TD"==g||"TH"==g)F(a,c,d,h.trim(f.innerHTML)),d++;f=f.nextSibling}}b=b.nextSibling}i=T(a);d=[];b=0;for(c=i.length;b<c;b++)for(f=i[b].firstChild;f;)g=f.nodeName.toUpperCase(),("TD"==
26
+ g||"TH"==g)&&d.push(f),f=f.nextSibling;c=0;for(i=a.aoColumns.length;c<i;c++){e=a.aoColumns[c];null===e.sTitle&&(e.sTitle=e.nTh.innerHTML);var w=e._bAutoType,o="function"===typeof e.fnRender,k=null!==e.sClass,n=e.bVisible,m,p;if(w||o||k||!n){g=0;for(b=a.aoData.length;g<b;g++)f=a.aoData[g],m=d[g*i+c],w&&"string"!=e.sType&&(p=v(a,g,c,"type"),""!==p&&(p=B(p),null===e.sType?e.sType=p:e.sType!=p&&"html"!=e.sType&&(e.sType="string"))),e.mRender?m.innerHTML=v(a,g,c,"display"):e.mData!==c&&(m.innerHTML=v(a,
27
+ g,c,"display")),o&&(p=S(a,g,c),m.innerHTML=p,e.bUseRendered&&F(a,g,c,p)),k&&(m.className+=" "+e.sClass),n?f._anHidden[c]=null:(f._anHidden[c]=m,m.parentNode.removeChild(m)),e.fnCreatedCell&&e.fnCreatedCell.call(a.oInstance,m,v(a,g,c,"display"),f._aData,g,c)}}if(0!==a.aoRowCreatedCallback.length){b=0;for(c=a.aoData.length;b<c;b++)f=a.aoData[b],A(a,"aoRowCreatedCallback",null,[f.nTr,f._aData,b])}}function I(a,b){return b._DT_RowIndex!==n?b._DT_RowIndex:null}function fa(a,b,c){for(var b=J(a,b),d=0,a=
28
+ a.aoColumns.length;d<a;d++)if(b[d]===c)return d;return-1}function Y(a,b,c,d){for(var i=[],f=0,g=d.length;f<g;f++)i.push(v(a,b,d[f],c));return i}function v(a,b,c,d){var i=a.aoColumns[c];if((c=i.fnGetData(a.aoData[b]._aData,d))===n)return a.iDrawError!=a.iDraw&&null===i.sDefaultContent&&(D(a,0,"Requested unknown parameter "+("function"==typeof i.mData?"{mData function}":"'"+i.mData+"'")+" from the data source for row "+b),a.iDrawError=a.iDraw),i.sDefaultContent;if(null===c&&null!==i.sDefaultContent)c=
29
+ i.sDefaultContent;else if("function"===typeof c)return c();return"display"==d&&null===c?"":c}function F(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d)}function Q(a){if(null===a)return function(){return null};if("function"===typeof a)return function(b,d,i){return a(b,d,i)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("["))){var b=function(a,d,i){var f=i.split("."),g;if(""!==i){var e=0;for(g=f.length;e<g;e++){if(i=f[e].match(U)){f[e]=f[e].replace(U,"");""!==f[e]&&(a=a[f[e]]);
30
+ g=[];f.splice(0,e+1);for(var f=f.join("."),e=0,h=a.length;e<h;e++)g.push(b(a[e],d,f));a=i[0].substring(1,i[0].length-1);a=""===a?g:g.join(a);break}if(null===a||a[f[e]]===n)return n;a=a[f[e]]}}return a};return function(c,d){return b(c,d,a)}}return function(b){return b[a]}}function L(a){if(null===a)return function(){};if("function"===typeof a)return function(b,d){a(b,"set",d)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("["))){var b=function(a,d,i){var i=i.split("."),f,g,e=0;for(g=
31
+ i.length-1;e<g;e++){if(f=i[e].match(U)){i[e]=i[e].replace(U,"");a[i[e]]=[];f=i.slice();f.splice(0,e+1);g=f.join(".");for(var h=0,j=d.length;h<j;h++)f={},b(f,d[h],g),a[i[e]].push(f);return}if(null===a[i[e]]||a[i[e]]===n)a[i[e]]={};a=a[i[e]]}a[i[i.length-1].replace(U,"")]=d};return function(c,d){return b(c,d,a)}}return function(b,d){b[a]=d}}function Z(a){for(var b=[],c=a.aoData.length,d=0;d<c;d++)b.push(a.aoData[d]._aData);return b}function ga(a){a.aoData.splice(0,a.aoData.length);a.aiDisplayMaster.splice(0,
32
+ a.aiDisplayMaster.length);a.aiDisplay.splice(0,a.aiDisplay.length);y(a)}function ha(a,b){for(var c=-1,d=0,i=a.length;d<i;d++)a[d]==b?c=d:a[d]>b&&a[d]--; -1!=c&&a.splice(c,1)}function S(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,aData:a.aoData[b]._aData,mDataProp:d.mData},v(a,b,c,"display"))}function ea(a,b){var c=a.aoData[b],d;if(null===c.nTr){c.nTr=l.createElement("tr");c.nTr._DT_RowIndex=b;c._aData.DT_RowId&&(c.nTr.id=c._aData.DT_RowId);c._aData.DT_RowClass&&
33
+ (c.nTr.className=c._aData.DT_RowClass);for(var i=0,f=a.aoColumns.length;i<f;i++){var g=a.aoColumns[i];d=l.createElement(g.sCellType);d.innerHTML="function"===typeof g.fnRender&&(!g.bUseRendered||null===g.mData)?S(a,b,i):v(a,b,i,"display");null!==g.sClass&&(d.className=g.sClass);g.bVisible?(c.nTr.appendChild(d),c._anHidden[i]=null):c._anHidden[i]=d;g.fnCreatedCell&&g.fnCreatedCell.call(a.oInstance,d,v(a,b,i,"display"),c._aData,b,i)}A(a,"aoRowCreatedCallback",null,[c.nTr,c._aData,b])}}function va(a){var b,
34
+ c,d;if(0!==h("th, td",a.nTHead).length){b=0;for(d=a.aoColumns.length;b<d;b++)if(c=a.aoColumns[b].nTh,c.setAttribute("role","columnheader"),a.aoColumns[b].bSortable&&(c.setAttribute("tabindex",a.iTabIndex),c.setAttribute("aria-controls",a.sTableId)),null!==a.aoColumns[b].sClass&&h(c).addClass(a.aoColumns[b].sClass),a.aoColumns[b].sTitle!=c.innerHTML)c.innerHTML=a.aoColumns[b].sTitle}else{var i=l.createElement("tr");b=0;for(d=a.aoColumns.length;b<d;b++)c=a.aoColumns[b].nTh,c.innerHTML=a.aoColumns[b].sTitle,
35
+ c.setAttribute("tabindex","0"),null!==a.aoColumns[b].sClass&&h(c).addClass(a.aoColumns[b].sClass),i.appendChild(c);h(a.nTHead).html("")[0].appendChild(i);V(a.aoHeader,a.nTHead)}h(a.nTHead).children("tr").attr("role","row");if(a.bJUI){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;i=l.createElement("div");i.className=a.oClasses.sSortJUIWrapper;h(c).contents().appendTo(i);var f=l.createElement("span");f.className=a.oClasses.sSortIcon;i.appendChild(f);c.appendChild(i)}}if(a.oFeatures.bSort)for(b=
36
+ 0;b<a.aoColumns.length;b++)!1!==a.aoColumns[b].bSortable?ia(a,a.aoColumns[b].nTh,b):h(a.aoColumns[b].nTh).addClass(a.oClasses.sSortableNone);""!==a.oClasses.sFooterTH&&h(a.nTFoot).children("tr").children("th").addClass(a.oClasses.sFooterTH);if(null!==a.nTFoot){c=N(a,null,a.aoFooter);b=0;for(d=a.aoColumns.length;b<d;b++)c[b]&&(a.aoColumns[b].nTf=c[b],a.aoColumns[b].sClass&&h(c[b]).addClass(a.aoColumns[b].sClass))}}function W(a,b,c){var d,i,f,g=[],e=[],h=a.aoColumns.length,j;c===n&&(c=!1);d=0;for(i=
37
+ b.length;d<i;d++){g[d]=b[d].slice();g[d].nTr=b[d].nTr;for(f=h-1;0<=f;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);e.push([])}d=0;for(i=g.length;d<i;d++){if(a=g[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=g[d].length;f<b;f++)if(j=h=1,e[d][f]===n){a.appendChild(g[d][f].cell);for(e[d][f]=1;g[d+h]!==n&&g[d][f].cell==g[d+h][f].cell;)e[d+h][f]=1,h++;for(;g[d][f+j]!==n&&g[d][f].cell==g[d][f+j].cell;){for(c=0;c<h;c++)e[d+c][f+j]=1;j++}g[d][f].cell.rowSpan=h;g[d][f].cell.colSpan=j}}}function x(a){var b=
38
+ A(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==h.inArray(!1,b))E(a,!1);else{var c,d,b=[],i=0,f=a.asStripeClasses.length;c=a.aoOpenRows.length;a.bDrawing=!0;a.iInitDisplayStart!==n&&-1!=a.iInitDisplayStart&&(a._iDisplayStart=a.oFeatures.bServerSide?a.iInitDisplayStart:a.iInitDisplayStart>=a.fnRecordsDisplay()?0:a.iInitDisplayStart,a.iInitDisplayStart=-1,y(a));if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++;else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!wa(a))return}else a.iDraw++;if(0!==a.aiDisplay.length){var g=
39
+ a._iDisplayStart;d=a._iDisplayEnd;a.oFeatures.bServerSide&&(g=0,d=a.aoData.length);for(;g<d;g++){var e=a.aoData[a.aiDisplay[g]];null===e.nTr&&ea(a,a.aiDisplay[g]);var j=e.nTr;if(0!==f){var o=a.asStripeClasses[i%f];e._sRowStripe!=o&&(h(j).removeClass(e._sRowStripe).addClass(o),e._sRowStripe=o)}A(a,"aoRowCallback",null,[j,a.aoData[a.aiDisplay[g]]._aData,i,g]);b.push(j);i++;if(0!==c)for(e=0;e<c;e++)if(j==a.aoOpenRows[e].nParent){b.push(a.aoOpenRows[e].nTr);break}}}else b[0]=l.createElement("tr"),a.asStripeClasses[0]&&
40
+ (b[0].className=a.asStripeClasses[0]),c=a.oLanguage,f=c.sZeroRecords,1==a.iDraw&&null!==a.sAjaxSource&&!a.oFeatures.bServerSide?f=c.sLoadingRecords:c.sEmptyTable&&0===a.fnRecordsTotal()&&(f=c.sEmptyTable),c=l.createElement("td"),c.setAttribute("valign","top"),c.colSpan=t(a),c.className=a.oClasses.sRowEmpty,c.innerHTML=ja(a,f),b[i].appendChild(c);A(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Z(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay]);A(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],
41
+ Z(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay]);i=l.createDocumentFragment();c=l.createDocumentFragment();if(a.nTBody){f=a.nTBody.parentNode;c.appendChild(a.nTBody);if(!a.oScroll.bInfinite||!a._bInitComplete||a.bSorted||a.bFiltered)for(;c=a.nTBody.firstChild;)a.nTBody.removeChild(c);c=0;for(d=b.length;c<d;c++)i.appendChild(b[c]);a.nTBody.appendChild(i);null!==f&&f.appendChild(a.nTBody)}A(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1;a.oFeatures.bServerSide&&(E(a,!1),
42
+ a._bInitComplete||$(a))}}function aa(a){a.oFeatures.bSort?O(a,a.oPreviousSearch):a.oFeatures.bFilter?K(a,a.oPreviousSearch):(y(a),x(a))}function xa(a){var b=h("<div></div>")[0];a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=h('<div id="'+a.sTableId+'_wrapper" class="'+a.oClasses.sWrapper+'" role="grid"></div>')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),i,f,g,e,w,o,k,m=0;m<d.length;m++){f=0;g=d[m];if("<"==g){e=h("<div></div>")[0];w=d[m+
43
+ 1];if("'"==w||'"'==w){o="";for(k=2;d[m+k]!=w;)o+=d[m+k],k++;"H"==o?o=a.oClasses.sJUIHeader:"F"==o&&(o=a.oClasses.sJUIFooter);-1!=o.indexOf(".")?(w=o.split("."),e.id=w[0].substr(1,w[0].length-1),e.className=w[1]):"#"==o.charAt(0)?e.id=o.substr(1,o.length-1):e.className=o;m+=k}c.appendChild(e);c=e}else if(">"==g)c=c.parentNode;else if("l"==g&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange)i=ya(a),f=1;else if("f"==g&&a.oFeatures.bFilter)i=za(a),f=1;else if("r"==g&&a.oFeatures.bProcessing)i=Aa(a),f=
44
+ 1;else if("t"==g)i=Ba(a),f=1;else if("i"==g&&a.oFeatures.bInfo)i=Ca(a),f=1;else if("p"==g&&a.oFeatures.bPaginate)i=Da(a),f=1;else if(0!==j.ext.aoFeatures.length){e=j.ext.aoFeatures;k=0;for(w=e.length;k<w;k++)if(g==e[k].cFeature){(i=e[k].fnInit(a))&&(f=1);break}}1==f&&null!==i&&("object"!==typeof a.aanFeatures[g]&&(a.aanFeatures[g]=[]),a.aanFeatures[g].push(i),c.appendChild(i))}b.parentNode.replaceChild(a.nTableWrapper,b)}function V(a,b){var c=h(b).children("tr"),d,i,f,g,e,j,o,k,m,p;a.splice(0,a.length);
45
+ f=0;for(j=c.length;f<j;f++)a.push([]);f=0;for(j=c.length;f<j;f++){d=c[f];for(i=d.firstChild;i;){if("TD"==i.nodeName.toUpperCase()||"TH"==i.nodeName.toUpperCase()){k=1*i.getAttribute("colspan");m=1*i.getAttribute("rowspan");k=!k||0===k||1===k?1:k;m=!m||0===m||1===m?1:m;g=0;for(e=a[f];e[g];)g++;o=g;p=1===k?!0:!1;for(e=0;e<k;e++)for(g=0;g<m;g++)a[f+g][o+e]={cell:i,unique:p},a[f+g].nTr=d}i=i.nextSibling}}}function N(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],V(c,b)));for(var b=0,i=c.length;b<i;b++)for(var f=
46
+ 0,g=c[b].length;f<g;f++)if(c[b][f].unique&&(!d[f]||!a.bSortCellsTop))d[f]=c[b][f].cell;return d}function wa(a){if(a.bAjaxDataGet){a.iDraw++;E(a,!0);var b=Ea(a);ka(a,b);a.fnServerData.call(a.oInstance,a.sAjaxSource,b,function(b){Fa(a,b)},a);return!1}return!0}function Ea(a){var b=a.aoColumns.length,c=[],d,i,f,g;c.push({name:"sEcho",value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns",value:M(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",
47
+ value:!1!==a.oFeatures.bPaginate?a._iDisplayLength:-1});for(f=0;f<b;f++)d=a.aoColumns[f].mData,c.push({name:"mDataProp_"+f,value:"function"===typeof d?"function":d});if(!1!==a.oFeatures.bFilter){c.push({name:"sSearch",value:a.oPreviousSearch.sSearch});c.push({name:"bRegex",value:a.oPreviousSearch.bRegex});for(f=0;f<b;f++)c.push({name:"sSearch_"+f,value:a.aoPreSearchCols[f].sSearch}),c.push({name:"bRegex_"+f,value:a.aoPreSearchCols[f].bRegex}),c.push({name:"bSearchable_"+f,value:a.aoColumns[f].bSearchable})}if(!1!==
48
+ a.oFeatures.bSort){var e=0;d=null!==a.aaSortingFixed?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(f=0;f<d.length;f++){i=a.aoColumns[d[f][0]].aDataSort;for(g=0;g<i.length;g++)c.push({name:"iSortCol_"+e,value:i[g]}),c.push({name:"sSortDir_"+e,value:d[f][1]}),e++}c.push({name:"iSortingCols",value:e});for(f=0;f<b;f++)c.push({name:"bSortable_"+f,value:a.aoColumns[f].bSortable})}return c}function ka(a,b){A(a,"aoServerParams","serverParams",[b])}function Fa(a,b){if(b.sEcho!==n){if(1*b.sEcho<
49
+ a.iDraw)return;a.iDraw=1*b.sEcho}(!a.oScroll.bInfinite||a.oScroll.bInfinite&&(a.bSorted||a.bFiltered))&&ga(a);a._iRecordsTotal=parseInt(b.iTotalRecords,10);a._iRecordsDisplay=parseInt(b.iTotalDisplayRecords,10);var c=M(a),c=b.sColumns!==n&&""!==c&&b.sColumns!=c,d;c&&(d=u(a,b.sColumns));for(var i=Q(a.sAjaxDataProp)(b),f=0,g=i.length;f<g;f++)if(c){for(var e=[],h=0,j=a.aoColumns.length;h<j;h++)e.push(i[f][d[h]]);H(a,e)}else H(a,i[f]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;x(a);a.bAjaxDataGet=
50
+ !0;E(a,!1)}function za(a){var b=a.oPreviousSearch,c=a.oLanguage.sSearch,c=-1!==c.indexOf("_INPUT_")?c.replace("_INPUT_",'<input type="text" />'):""===c?'<input type="text" />':c+' <input type="text" />',d=l.createElement("div");d.className=a.oClasses.sFilter;d.innerHTML="<label>"+c+"</label>";a.aanFeatures.f||(d.id=a.sTableId+"_filter");c=h('input[type="text"]',d);d._DT_Input=c[0];c.val(b.sSearch.replace('"',"&quot;"));c.bind("keyup.DT",function(){for(var c=a.aanFeatures.f,d=this.value===""?"":this.value,
51
+ g=0,e=c.length;g<e;g++)c[g]!=h(this).parents("div.dataTables_filter")[0]&&h(c[g]._DT_Input).val(d);d!=b.sSearch&&K(a,{sSearch:d,bRegex:b.bRegex,bSmart:b.bSmart,bCaseInsensitive:b.bCaseInsensitive})});c.attr("aria-controls",a.sTableId).bind("keypress.DT",function(a){if(a.keyCode==13)return false});return d}function K(a,b,c){var d=a.oPreviousSearch,i=a.aoPreSearchCols,f=function(a){d.sSearch=a.sSearch;d.bRegex=a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive};if(a.oFeatures.bServerSide)f(b);
52
+ else{Ga(a,b.sSearch,c,b.bRegex,b.bSmart,b.bCaseInsensitive);f(b);for(b=0;b<a.aoPreSearchCols.length;b++)Ha(a,i[b].sSearch,b,i[b].bRegex,i[b].bSmart,i[b].bCaseInsensitive);Ia(a)}a.bFiltered=!0;h(a.oInstance).trigger("filter",a);a._iDisplayStart=0;y(a);x(a);la(a,0)}function Ia(a){for(var b=j.ext.afnFiltering,c=r(a,"bSearchable"),d=0,i=b.length;d<i;d++)for(var f=0,g=0,e=a.aiDisplay.length;g<e;g++){var h=a.aiDisplay[g-f];b[d](a,Y(a,h,"filter",c),h)||(a.aiDisplay.splice(g-f,1),f++)}}function Ha(a,b,c,
53
+ d,i,f){if(""!==b)for(var g=0,b=ma(b,d,i,f),d=a.aiDisplay.length-1;0<=d;d--)i=Ja(v(a,a.aiDisplay[d],c,"filter"),a.aoColumns[c].sType),b.test(i)||(a.aiDisplay.splice(d,1),g++)}function Ga(a,b,c,d,i,f){d=ma(b,d,i,f);i=a.oPreviousSearch;c||(c=0);0!==j.ext.afnFiltering.length&&(c=1);if(0>=b.length)a.aiDisplay.splice(0,a.aiDisplay.length),a.aiDisplay=a.aiDisplayMaster.slice();else if(a.aiDisplay.length==a.aiDisplayMaster.length||i.sSearch.length>b.length||1==c||0!==b.indexOf(i.sSearch)){a.aiDisplay.splice(0,
54
+ a.aiDisplay.length);la(a,1);for(b=0;b<a.aiDisplayMaster.length;b++)d.test(a.asDataSearch[b])&&a.aiDisplay.push(a.aiDisplayMaster[b])}else for(b=c=0;b<a.asDataSearch.length;b++)d.test(a.asDataSearch[b])||(a.aiDisplay.splice(b-c,1),c++)}function la(a,b){if(!a.oFeatures.bServerSide){a.asDataSearch=[];for(var c=r(a,"bSearchable"),d=1===b?a.aiDisplayMaster:a.aiDisplay,i=0,f=d.length;i<f;i++)a.asDataSearch[i]=na(a,Y(a,d[i],"filter",c))}}function na(a,b){var c=b.join(" ");-1!==c.indexOf("&")&&(c=h("<div>").html(c).text());
55
+ return c.replace(/[\n\r]/g," ")}function ma(a,b,c,d){if(c)return a=b?a.split(" "):oa(a).split(" "),a="^(?=.*?"+a.join(")(?=.*?")+").*$",RegExp(a,d?"i":"");a=b?a:oa(a);return RegExp(a,d?"i":"")}function Ja(a,b){return"function"===typeof j.ext.ofnSearch[b]?j.ext.ofnSearch[b](a):null===a?"":"html"==b?a.replace(/[\r\n]/g," ").replace(/<.*?>/g,""):"string"===typeof a?a.replace(/[\r\n]/g," "):a}function oa(a){return a.replace(RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),
56
+ "\\$1")}function Ca(a){var b=l.createElement("div");b.className=a.oClasses.sInfo;a.aanFeatures.i||(a.aoDrawCallback.push({fn:Ka,sName:"information"}),b.id=a.sTableId+"_info");a.nTable.setAttribute("aria-describedby",a.sTableId+"_info");return b}function Ka(a){if(a.oFeatures.bInfo&&0!==a.aanFeatures.i.length){var b=a.oLanguage,c=a._iDisplayStart+1,d=a.fnDisplayEnd(),i=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),g;g=0===f?b.sInfoEmpty:b.sInfo;f!=i&&(g+=" "+b.sInfoFiltered);g+=b.sInfoPostFix;g=ja(a,g);
57
+ null!==b.fnInfoCallback&&(g=b.fnInfoCallback.call(a.oInstance,a,c,d,i,f,g));a=a.aanFeatures.i;b=0;for(c=a.length;b<c;b++)h(a[b]).html(g)}}function ja(a,b){var c=a.fnFormatNumber(a._iDisplayStart+1),d=a.fnDisplayEnd(),d=a.fnFormatNumber(d),i=a.fnRecordsDisplay(),i=a.fnFormatNumber(i),f=a.fnRecordsTotal(),f=a.fnFormatNumber(f);a.oScroll.bInfinite&&(c=a.fnFormatNumber(1));return b.replace(/_START_/g,c).replace(/_END_/g,d).replace(/_TOTAL_/g,i).replace(/_MAX_/g,f)}function ba(a){var b,c,d=a.iInitDisplayStart;
58
+ if(!1===a.bInitialised)setTimeout(function(){ba(a)},200);else{xa(a);va(a);W(a,a.aoHeader);a.nTFoot&&W(a,a.aoFooter);E(a,!0);a.oFeatures.bAutoWidth&&da(a);b=0;for(c=a.aoColumns.length;b<c;b++)null!==a.aoColumns[b].sWidth&&(a.aoColumns[b].nTh.style.width=q(a.aoColumns[b].sWidth));a.oFeatures.bSort?O(a):a.oFeatures.bFilter?K(a,a.oPreviousSearch):(a.aiDisplay=a.aiDisplayMaster.slice(),y(a),x(a));null!==a.sAjaxSource&&!a.oFeatures.bServerSide?(c=[],ka(a,c),a.fnServerData.call(a.oInstance,a.sAjaxSource,
59
+ c,function(c){var f=a.sAjaxDataProp!==""?Q(a.sAjaxDataProp)(c):c;for(b=0;b<f.length;b++)H(a,f[b]);a.iInitDisplayStart=d;if(a.oFeatures.bSort)O(a);else{a.aiDisplay=a.aiDisplayMaster.slice();y(a);x(a)}E(a,false);$(a,c)},a)):a.oFeatures.bServerSide||(E(a,!1),$(a))}}function $(a,b){a._bInitComplete=!0;A(a,"aoInitComplete","init",[a,b])}function pa(a){var b=j.defaults.oLanguage;!a.sEmptyTable&&(a.sZeroRecords&&"No data available in table"===b.sEmptyTable)&&p(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&
60
+ (a.sZeroRecords&&"Loading..."===b.sLoadingRecords)&&p(a,a,"sZeroRecords","sLoadingRecords")}function ya(a){if(a.oScroll.bInfinite)return null;var b='<select size="1" '+('name="'+a.sTableId+'_length"')+">",c,d,i=a.aLengthMenu;if(2==i.length&&"object"===typeof i[0]&&"object"===typeof i[1]){c=0;for(d=i[0].length;c<d;c++)b+='<option value="'+i[0][c]+'">'+i[1][c]+"</option>"}else{c=0;for(d=i.length;c<d;c++)b+='<option value="'+i[c]+'">'+i[c]+"</option>"}b+="</select>";i=l.createElement("div");a.aanFeatures.l||
61
+ (i.id=a.sTableId+"_length");i.className=a.oClasses.sLength;i.innerHTML="<label>"+a.oLanguage.sLengthMenu.replace("_MENU_",b)+"</label>";h('select option[value="'+a._iDisplayLength+'"]',i).attr("selected",!0);h("select",i).bind("change.DT",function(){var b=h(this).val(),i=a.aanFeatures.l;c=0;for(d=i.length;c<d;c++)i[c]!=this.parentNode&&h("select",i[c]).val(b);a._iDisplayLength=parseInt(b,10);y(a);if(a.fnDisplayEnd()==a.fnRecordsDisplay()){a._iDisplayStart=a.fnDisplayEnd()-a._iDisplayLength;if(a._iDisplayStart<
62
+ 0)a._iDisplayStart=0}if(a._iDisplayLength==-1)a._iDisplayStart=0;x(a)});h("select",i).attr("aria-controls",a.sTableId);return i}function y(a){a._iDisplayEnd=!1===a.oFeatures.bPaginate?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||-1==a._iDisplayLength?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Da(a){if(a.oScroll.bInfinite)return null;var b=l.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;j.ext.oPagination[a.sPaginationType].fnInit(a,
63
+ b,function(a){y(a);x(a)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(a){j.ext.oPagination[a.sPaginationType].fnUpdate(a,function(a){y(a);x(a)})},sName:"pagination"});return b}function qa(a,b){var c=a._iDisplayStart;if("number"===typeof b)a._iDisplayStart=b*a._iDisplayLength,a._iDisplayStart>a.fnRecordsDisplay()&&(a._iDisplayStart=0);else if("first"==b)a._iDisplayStart=0;else if("previous"==b)a._iDisplayStart=0<=a._iDisplayLength?a._iDisplayStart-a._iDisplayLength:0,0>a._iDisplayStart&&(a._iDisplayStart=
64
+ 0);else if("next"==b)0<=a._iDisplayLength?a._iDisplayStart+a._iDisplayLength<a.fnRecordsDisplay()&&(a._iDisplayStart+=a._iDisplayLength):a._iDisplayStart=0;else if("last"==b)if(0<=a._iDisplayLength){var d=parseInt((a.fnRecordsDisplay()-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(d-1)*a._iDisplayLength}else a._iDisplayStart=0;else D(a,0,"Unknown paging action: "+b);h(a.oInstance).trigger("page",a);return c!=a._iDisplayStart}function Aa(a){var b=l.createElement("div");a.aanFeatures.r||(b.id=a.sTableId+
65
+ "_processing");b.innerHTML=a.oLanguage.sProcessing;b.className=a.oClasses.sProcessing;a.nTable.parentNode.insertBefore(b,a.nTable);return b}function E(a,b){if(a.oFeatures.bProcessing)for(var c=a.aanFeatures.r,d=0,i=c.length;d<i;d++)c[d].style.visibility=b?"visible":"hidden";h(a.oInstance).trigger("processing",[a,b])}function Ba(a){if(""===a.oScroll.sX&&""===a.oScroll.sY)return a.nTable;var b=l.createElement("div"),c=l.createElement("div"),d=l.createElement("div"),i=l.createElement("div"),f=l.createElement("div"),
66
+ g=l.createElement("div"),e=a.nTable.cloneNode(!1),j=a.nTable.cloneNode(!1),o=a.nTable.getElementsByTagName("thead")[0],k=0===a.nTable.getElementsByTagName("tfoot").length?null:a.nTable.getElementsByTagName("tfoot")[0],m=a.oClasses;c.appendChild(d);f.appendChild(g);i.appendChild(a.nTable);b.appendChild(c);b.appendChild(i);d.appendChild(e);e.appendChild(o);null!==k&&(b.appendChild(f),g.appendChild(j),j.appendChild(k));b.className=m.sScrollWrapper;c.className=m.sScrollHead;d.className=m.sScrollHeadInner;
67
+ i.className=m.sScrollBody;f.className=m.sScrollFoot;g.className=m.sScrollFootInner;a.oScroll.bAutoCss&&(c.style.overflow="hidden",c.style.position="relative",f.style.overflow="hidden",i.style.overflow="auto");c.style.border="0";c.style.width="100%";f.style.border="0";d.style.width=""!==a.oScroll.sXInner?a.oScroll.sXInner:"100%";e.removeAttribute("id");e.style.marginLeft="0";a.nTable.style.marginLeft="0";null!==k&&(j.removeAttribute("id"),j.style.marginLeft="0");d=h(a.nTable).children("caption");0<
68
+ d.length&&(d=d[0],"top"===d._captionSide?e.appendChild(d):"bottom"===d._captionSide&&k&&j.appendChild(d));""!==a.oScroll.sX&&(c.style.width=q(a.oScroll.sX),i.style.width=q(a.oScroll.sX),null!==k&&(f.style.width=q(a.oScroll.sX)),h(i).scroll(function(){c.scrollLeft=this.scrollLeft;if(k!==null)f.scrollLeft=this.scrollLeft}));""!==a.oScroll.sY&&(i.style.height=q(a.oScroll.sY));a.aoDrawCallback.push({fn:La,sName:"scrolling"});a.oScroll.bInfinite&&h(i).scroll(function(){if(!a.bDrawing&&h(this).scrollTop()!==
69
+ 0&&h(this).scrollTop()+h(this).height()>h(a.nTable).height()-a.oScroll.iLoadGap&&a.fnDisplayEnd()<a.fnRecordsDisplay()){qa(a,"next");y(a);x(a)}});a.nScrollHead=c;a.nScrollFoot=f;return b}function La(a){var b=a.nScrollHead.getElementsByTagName("div")[0],c=b.getElementsByTagName("table")[0],d=a.nTable.parentNode,i,f,g,e,j,o,k,m,p=[],n=[],l=null!==a.nTFoot?a.nScrollFoot.getElementsByTagName("div")[0]:null,R=null!==a.nTFoot?l.getElementsByTagName("table")[0]:null,r=a.oBrowser.bScrollOversize,s=function(a){k=
70
+ a.style;k.paddingTop="0";k.paddingBottom="0";k.borderTopWidth="0";k.borderBottomWidth="0";k.height=0};h(a.nTable).children("thead, tfoot").remove();i=h(a.nTHead).clone()[0];a.nTable.insertBefore(i,a.nTable.childNodes[0]);g=a.nTHead.getElementsByTagName("tr");e=i.getElementsByTagName("tr");null!==a.nTFoot&&(j=h(a.nTFoot).clone()[0],a.nTable.insertBefore(j,a.nTable.childNodes[1]),o=a.nTFoot.getElementsByTagName("tr"),j=j.getElementsByTagName("tr"));""===a.oScroll.sX&&(d.style.width="100%",b.parentNode.style.width=
71
+ "100%");var t=N(a,i);i=0;for(f=t.length;i<f;i++)m=G(a,i),t[i].style.width=a.aoColumns[m].sWidth;null!==a.nTFoot&&C(function(a){a.style.width=""},j);a.oScroll.bCollapse&&""!==a.oScroll.sY&&(d.style.height=d.offsetHeight+a.nTHead.offsetHeight+"px");i=h(a.nTable).outerWidth();if(""===a.oScroll.sX){if(a.nTable.style.width="100%",r&&(h("tbody",d).height()>d.offsetHeight||"scroll"==h(d).css("overflow-y")))a.nTable.style.width=q(h(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else""!==a.oScroll.sXInner?a.nTable.style.width=
72
+ q(a.oScroll.sXInner):i==h(d).width()&&h(d).height()<h(a.nTable).height()?(a.nTable.style.width=q(i-a.oScroll.iBarWidth),h(a.nTable).outerWidth()>i-a.oScroll.iBarWidth&&(a.nTable.style.width=q(i))):a.nTable.style.width=q(i);i=h(a.nTable).outerWidth();C(s,e);C(function(a){p.push(q(h(a).width()))},e);C(function(a,b){a.style.width=p[b]},g);h(e).height(0);null!==a.nTFoot&&(C(s,j),C(function(a){n.push(q(h(a).width()))},j),C(function(a,b){a.style.width=n[b]},o),h(j).height(0));C(function(a,b){a.innerHTML=
73
+ "";a.style.width=p[b]},e);null!==a.nTFoot&&C(function(a,b){a.innerHTML="";a.style.width=n[b]},j);if(h(a.nTable).outerWidth()<i){g=d.scrollHeight>d.offsetHeight||"scroll"==h(d).css("overflow-y")?i+a.oScroll.iBarWidth:i;if(r&&(d.scrollHeight>d.offsetHeight||"scroll"==h(d).css("overflow-y")))a.nTable.style.width=q(g-a.oScroll.iBarWidth);d.style.width=q(g);a.nScrollHead.style.width=q(g);null!==a.nTFoot&&(a.nScrollFoot.style.width=q(g));""===a.oScroll.sX?D(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width."):
74
+ ""!==a.oScroll.sXInner&&D(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else d.style.width=q("100%"),a.nScrollHead.style.width=q("100%"),null!==a.nTFoot&&(a.nScrollFoot.style.width=q("100%"));""===a.oScroll.sY&&r&&(d.style.height=q(a.nTable.offsetHeight+a.oScroll.iBarWidth));""!==a.oScroll.sY&&a.oScroll.bCollapse&&(d.style.height=q(a.oScroll.sY),r=""!==a.oScroll.sX&&a.nTable.offsetWidth>
75
+ d.offsetWidth?a.oScroll.iBarWidth:0,a.nTable.offsetHeight<d.offsetHeight&&(d.style.height=q(a.nTable.offsetHeight+r)));r=h(a.nTable).outerWidth();c.style.width=q(r);b.style.width=q(r);c=h(a.nTable).height()>d.clientHeight||"scroll"==h(d).css("overflow-y");b.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px";null!==a.nTFoot&&(R.style.width=q(r),l.style.width=q(r),l.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px");h(d).scroll();if(a.bSorted||a.bFiltered)d.scrollTop=0}function C(a,b,c){for(var d=
76
+ 0,i=0,f=b.length,g,e;i<f;){g=b[i].firstChild;for(e=c?c[i].firstChild:null;g;)1===g.nodeType&&(c?a(g,e,d):a(g,d),d++),g=g.nextSibling,e=c?e.nextSibling:null;i++}}function Ma(a,b){if(!a||null===a||""===a)return 0;b||(b=l.body);var c,d=l.createElement("div");d.style.width=q(a);b.appendChild(d);c=d.offsetWidth;b.removeChild(d);return c}function da(a){var b=0,c,d=0,i=a.aoColumns.length,f,e,j=h("th",a.nTHead),o=a.nTable.getAttribute("width");e=a.nTable.parentNode;for(f=0;f<i;f++)a.aoColumns[f].bVisible&&
77
+ (d++,null!==a.aoColumns[f].sWidth&&(c=Ma(a.aoColumns[f].sWidthOrig,e),null!==c&&(a.aoColumns[f].sWidth=q(c)),b++));if(i==j.length&&0===b&&d==i&&""===a.oScroll.sX&&""===a.oScroll.sY)for(f=0;f<a.aoColumns.length;f++)c=h(j[f]).width(),null!==c&&(a.aoColumns[f].sWidth=q(c));else{b=a.nTable.cloneNode(!1);f=a.nTHead.cloneNode(!0);d=l.createElement("tbody");c=l.createElement("tr");b.removeAttribute("id");b.appendChild(f);null!==a.nTFoot&&(b.appendChild(a.nTFoot.cloneNode(!0)),C(function(a){a.style.width=
78
+ ""},b.getElementsByTagName("tr")));b.appendChild(d);d.appendChild(c);d=h("thead th",b);0===d.length&&(d=h("tbody tr:eq(0)>td",b));j=N(a,f);for(f=d=0;f<i;f++){var k=a.aoColumns[f];k.bVisible&&null!==k.sWidthOrig&&""!==k.sWidthOrig?j[f-d].style.width=q(k.sWidthOrig):k.bVisible?j[f-d].style.width="":d++}for(f=0;f<i;f++)a.aoColumns[f].bVisible&&(d=Na(a,f),null!==d&&(d=d.cloneNode(!0),""!==a.aoColumns[f].sContentPadding&&(d.innerHTML+=a.aoColumns[f].sContentPadding),c.appendChild(d)));e.appendChild(b);
79
+ ""!==a.oScroll.sX&&""!==a.oScroll.sXInner?b.style.width=q(a.oScroll.sXInner):""!==a.oScroll.sX?(b.style.width="",h(b).width()<e.offsetWidth&&(b.style.width=q(e.offsetWidth))):""!==a.oScroll.sY?b.style.width=q(e.offsetWidth):o&&(b.style.width=q(o));b.style.visibility="hidden";Oa(a,b);i=h("tbody tr:eq(0)",b).children();0===i.length&&(i=N(a,h("thead",b)[0]));if(""!==a.oScroll.sX){for(f=d=e=0;f<a.aoColumns.length;f++)a.aoColumns[f].bVisible&&(e=null===a.aoColumns[f].sWidthOrig?e+h(i[d]).outerWidth():
80
+ e+(parseInt(a.aoColumns[f].sWidth.replace("px",""),10)+(h(i[d]).outerWidth()-h(i[d]).width())),d++);b.style.width=q(e);a.nTable.style.width=q(e)}for(f=d=0;f<a.aoColumns.length;f++)a.aoColumns[f].bVisible&&(e=h(i[d]).width(),null!==e&&0<e&&(a.aoColumns[f].sWidth=q(e)),d++);i=h(b).css("width");a.nTable.style.width=-1!==i.indexOf("%")?i:q(h(b).outerWidth());b.parentNode.removeChild(b)}o&&(a.nTable.style.width=q(o))}function Oa(a,b){""===a.oScroll.sX&&""!==a.oScroll.sY?(h(b).width(),b.style.width=q(h(b).outerWidth()-
81
+ a.oScroll.iBarWidth)):""!==a.oScroll.sX&&(b.style.width=q(h(b).outerWidth()))}function Na(a,b){var c=Pa(a,b);if(0>c)return null;if(null===a.aoData[c].nTr){var d=l.createElement("td");d.innerHTML=v(a,c,b,"");return d}return J(a,c)[b]}function Pa(a,b){for(var c=-1,d=-1,i=0;i<a.aoData.length;i++){var e=v(a,i,b,"display")+"",e=e.replace(/<.*?>/g,"");e.length>c&&(c=e.length,d=i)}return d}function q(a){if(null===a)return"0px";if("number"==typeof a)return 0>a?"0px":a+"px";var b=a.charCodeAt(a.length-1);
82
+ return 48>b||57<b?a:a+"px"}function Qa(){var a=l.createElement("p"),b=a.style;b.width="100%";b.height="200px";b.padding="0px";var c=l.createElement("div"),b=c.style;b.position="absolute";b.top="0px";b.left="0px";b.visibility="hidden";b.width="200px";b.height="150px";b.padding="0px";b.overflow="hidden";c.appendChild(a);l.body.appendChild(c);b=a.offsetWidth;c.style.overflow="scroll";a=a.offsetWidth;b==a&&(a=c.clientWidth);l.body.removeChild(c);return b-a}function O(a,b){var c,d,i,e,g,k,o=[],m=[],p=
83
+ j.ext.oSort,l=a.aoData,q=a.aoColumns,G=a.oLanguage.oAria;if(!a.oFeatures.bServerSide&&(0!==a.aaSorting.length||null!==a.aaSortingFixed)){o=null!==a.aaSortingFixed?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(c=0;c<o.length;c++)if(d=o[c][0],i=R(a,d),e=a.aoColumns[d].sSortDataType,j.ext.afnSortData[e])if(g=j.ext.afnSortData[e].call(a.oInstance,a,d,i),g.length===l.length){i=0;for(e=l.length;i<e;i++)F(a,i,d,g[i])}else D(a,0,"Returned data sort array (col "+d+") is the wrong length");c=
84
+ 0;for(d=a.aiDisplayMaster.length;c<d;c++)m[a.aiDisplayMaster[c]]=c;var r=o.length,s;c=0;for(d=l.length;c<d;c++)for(i=0;i<r;i++){s=q[o[i][0]].aDataSort;g=0;for(k=s.length;g<k;g++)e=q[s[g]].sType,e=p[(e?e:"string")+"-pre"],l[c]._aSortData[s[g]]=e?e(v(a,c,s[g],"sort")):v(a,c,s[g],"sort")}a.aiDisplayMaster.sort(function(a,b){var c,d,e,i,f;for(c=0;c<r;c++){f=q[o[c][0]].aDataSort;d=0;for(e=f.length;d<e;d++)if(i=q[f[d]].sType,i=p[(i?i:"string")+"-"+o[c][1]](l[a]._aSortData[f[d]],l[b]._aSortData[f[d]]),0!==
85
+ i)return i}return p["numeric-asc"](m[a],m[b])})}(b===n||b)&&!a.oFeatures.bDeferRender&&P(a);c=0;for(d=a.aoColumns.length;c<d;c++)e=q[c].sTitle.replace(/<.*?>/g,""),i=q[c].nTh,i.removeAttribute("aria-sort"),i.removeAttribute("aria-label"),q[c].bSortable?0<o.length&&o[0][0]==c?(i.setAttribute("aria-sort","asc"==o[0][1]?"ascending":"descending"),i.setAttribute("aria-label",e+("asc"==(q[c].asSorting[o[0][2]+1]?q[c].asSorting[o[0][2]+1]:q[c].asSorting[0])?G.sSortAscending:G.sSortDescending))):i.setAttribute("aria-label",
86
+ e+("asc"==q[c].asSorting[0]?G.sSortAscending:G.sSortDescending)):i.setAttribute("aria-label",e);a.bSorted=!0;h(a.oInstance).trigger("sort",a);a.oFeatures.bFilter?K(a,a.oPreviousSearch,1):(a.aiDisplay=a.aiDisplayMaster.slice(),a._iDisplayStart=0,y(a),x(a))}function ia(a,b,c,d){Ra(b,{},function(b){if(!1!==a.aoColumns[c].bSortable){var e=function(){var d,e;if(b.shiftKey){for(var f=!1,h=0;h<a.aaSorting.length;h++)if(a.aaSorting[h][0]==c){f=!0;d=a.aaSorting[h][0];e=a.aaSorting[h][2]+1;a.aoColumns[d].asSorting[e]?
87
+ (a.aaSorting[h][1]=a.aoColumns[d].asSorting[e],a.aaSorting[h][2]=e):a.aaSorting.splice(h,1);break}!1===f&&a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0])}else 1==a.aaSorting.length&&a.aaSorting[0][0]==c?(d=a.aaSorting[0][0],e=a.aaSorting[0][2]+1,a.aoColumns[d].asSorting[e]||(e=0),a.aaSorting[0][1]=a.aoColumns[d].asSorting[e],a.aaSorting[0][2]=e):(a.aaSorting.splice(0,a.aaSorting.length),a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0]));O(a)};a.oFeatures.bProcessing?(E(a,!0),setTimeout(function(){e();
88
+ a.oFeatures.bServerSide||E(a,!1)},0)):e();"function"==typeof d&&d(a)}})}function P(a){var b,c,d,e,f,g=a.aoColumns.length,j=a.oClasses;for(b=0;b<g;b++)a.aoColumns[b].bSortable&&h(a.aoColumns[b].nTh).removeClass(j.sSortAsc+" "+j.sSortDesc+" "+a.aoColumns[b].sSortingClass);c=null!==a.aaSortingFixed?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(b=0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable){f=a.aoColumns[b].sSortingClass;e=-1;for(d=0;d<c.length;d++)if(c[d][0]==b){f="asc"==c[d][1]?
89
+ j.sSortAsc:j.sSortDesc;e=d;break}h(a.aoColumns[b].nTh).addClass(f);a.bJUI&&(f=h("span."+j.sSortIcon,a.aoColumns[b].nTh),f.removeClass(j.sSortJUIAsc+" "+j.sSortJUIDesc+" "+j.sSortJUI+" "+j.sSortJUIAscAllowed+" "+j.sSortJUIDescAllowed),f.addClass(-1==e?a.aoColumns[b].sSortingClassJUI:"asc"==c[e][1]?j.sSortJUIAsc:j.sSortJUIDesc))}else h(a.aoColumns[b].nTh).addClass(a.aoColumns[b].sSortingClass);f=j.sSortColumn;if(a.oFeatures.bSort&&a.oFeatures.bSortClasses){a=J(a);e=[];for(b=0;b<g;b++)e.push("");b=0;
90
+ for(d=1;b<c.length;b++)j=parseInt(c[b][0],10),e[j]=f+d,3>d&&d++;f=RegExp(f+"[123]");var o;b=0;for(c=a.length;b<c;b++)j=b%g,d=a[b].className,o=e[j],j=d.replace(f,o),j!=d?a[b].className=h.trim(j):0<o.length&&-1==d.indexOf(o)&&(a[b].className=d+" "+o)}}function ra(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b,c;b=a.oScroll.bInfinite;var d={iCreate:(new Date).getTime(),iStart:b?0:a._iDisplayStart,iEnd:b?a._iDisplayLength:a._iDisplayEnd,iLength:a._iDisplayLength,aaSorting:h.extend(!0,[],a.aaSorting),
91
+ oSearch:h.extend(!0,{},a.oPreviousSearch),aoSearchCols:h.extend(!0,[],a.aoPreSearchCols),abVisCols:[]};b=0;for(c=a.aoColumns.length;b<c;b++)d.abVisCols.push(a.aoColumns[b].bVisible);A(a,"aoStateSaveParams","stateSaveParams",[a,d]);a.fnStateSave.call(a.oInstance,a,d)}}function Sa(a,b){if(a.oFeatures.bStateSave){var c=a.fnStateLoad.call(a.oInstance,a);if(c){var d=A(a,"aoStateLoadParams","stateLoadParams",[a,c]);if(-1===h.inArray(!1,d)){a.oLoadedState=h.extend(!0,{},c);a._iDisplayStart=c.iStart;a.iInitDisplayStart=
92
+ c.iStart;a._iDisplayEnd=c.iEnd;a._iDisplayLength=c.iLength;a.aaSorting=c.aaSorting.slice();a.saved_aaSorting=c.aaSorting.slice();h.extend(a.oPreviousSearch,c.oSearch);h.extend(!0,a.aoPreSearchCols,c.aoSearchCols);b.saved_aoColumns=[];for(d=0;d<c.abVisCols.length;d++)b.saved_aoColumns[d]={},b.saved_aoColumns[d].bVisible=c.abVisCols[d];A(a,"aoStateLoaded","stateLoaded",[a,c])}}}}function s(a){for(var b=0;b<j.settings.length;b++)if(j.settings[b].nTable===a)return j.settings[b];return null}function T(a){for(var b=
93
+ [],a=a.aoData,c=0,d=a.length;c<d;c++)null!==a[c].nTr&&b.push(a[c].nTr);return b}function J(a,b){var c=[],d,e,f,g,h,j;e=0;var o=a.aoData.length;b!==n&&(e=b,o=b+1);for(f=e;f<o;f++)if(j=a.aoData[f],null!==j.nTr){e=[];for(d=j.nTr.firstChild;d;)g=d.nodeName.toLowerCase(),("td"==g||"th"==g)&&e.push(d),d=d.nextSibling;g=d=0;for(h=a.aoColumns.length;g<h;g++)a.aoColumns[g].bVisible?c.push(e[g-d]):(c.push(j._anHidden[g]),d++)}return c}function D(a,b,c){a=null===a?"DataTables warning: "+c:"DataTables warning (table id = '"+
94
+ a.sTableId+"'): "+c;if(0===b)if("alert"==j.ext.sErrMode)alert(a);else throw Error(a);else X.console&&console.log&&console.log(a)}function p(a,b,c,d){d===n&&(d=c);b[c]!==n&&(a[d]=b[c])}function Ta(a,b){var c,d;for(d in b)b.hasOwnProperty(d)&&(c=b[d],"object"===typeof e[d]&&null!==c&&!1===h.isArray(c)?h.extend(!0,a[d],c):a[d]=c);return a}function Ra(a,b,c){h(a).bind("click.DT",b,function(b){a.blur();c(b)}).bind("keypress.DT",b,function(a){13===a.which&&c(a)}).bind("selectstart.DT",function(){return!1})}
95
+ function z(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function A(a,b,c,d){for(var b=a[b],e=[],f=b.length-1;0<=f;f--)e.push(b[f].fn.apply(a.oInstance,d));null!==c&&h(a.oInstance).trigger(c,d);return e}function Ua(a){var b=h('<div style="position:absolute; top:0; left:0; height:1px; width:1px; overflow:hidden"><div style="position:absolute; top:1px; left:1px; width:100px; overflow:scroll;"><div id="DT_BrowserTest" style="width:100%; height:10px;"></div></div></div>')[0];l.body.appendChild(b);a.oBrowser.bScrollOversize=
96
+ 100===h("#DT_BrowserTest",b)[0].offsetWidth?!0:!1;l.body.removeChild(b)}function Va(a){return function(){var b=[s(this[j.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return j.ext.oApi[a].apply(this,b)}}var U=/\[.*?\]$/,Wa=X.JSON?JSON.stringify:function(a){var b=typeof a;if("object"!==b||null===a)return"string"===b&&(a='"'+a+'"'),a+"";var c,d,e=[],f=h.isArray(a);for(c in a)d=a[c],b=typeof d,"string"===b?d='"'+d+'"':"object"===b&&null!==d&&(d=Wa(d)),e.push((f?"":'"'+c+'":')+d);return(f?
97
+ "[":"{")+e+(f?"]":"}")};this.$=function(a,b){var c,d,e=[],f;d=s(this[j.ext.iApiIndex]);var g=d.aoData,o=d.aiDisplay,k=d.aiDisplayMaster;b||(b={});b=h.extend({},{filter:"none",order:"current",page:"all"},b);if("current"==b.page){c=d._iDisplayStart;for(d=d.fnDisplayEnd();c<d;c++)(f=g[o[c]].nTr)&&e.push(f)}else if("current"==b.order&&"none"==b.filter){c=0;for(d=k.length;c<d;c++)(f=g[k[c]].nTr)&&e.push(f)}else if("current"==b.order&&"applied"==b.filter){c=0;for(d=o.length;c<d;c++)(f=g[o[c]].nTr)&&e.push(f)}else if("original"==
98
+ b.order&&"none"==b.filter){c=0;for(d=g.length;c<d;c++)(f=g[c].nTr)&&e.push(f)}else if("original"==b.order&&"applied"==b.filter){c=0;for(d=g.length;c<d;c++)f=g[c].nTr,-1!==h.inArray(c,o)&&f&&e.push(f)}else D(d,1,"Unknown selection options");e=h(e);c=e.filter(a);e=e.find(a);return h([].concat(h.makeArray(c),h.makeArray(e)))};this._=function(a,b){var c=[],d,e,f=this.$(a,b);d=0;for(e=f.length;d<e;d++)c.push(this.fnGetData(f[d]));return c};this.fnAddData=function(a,b){if(0===a.length)return[];var c=[],
99
+ d,e=s(this[j.ext.iApiIndex]);if("object"===typeof a[0]&&null!==a[0])for(var f=0;f<a.length;f++){d=H(e,a[f]);if(-1==d)return c;c.push(d)}else{d=H(e,a);if(-1==d)return c;c.push(d)}e.aiDisplay=e.aiDisplayMaster.slice();(b===n||b)&&aa(e);return c};this.fnAdjustColumnSizing=function(a){var b=s(this[j.ext.iApiIndex]);k(b);a===n||a?this.fnDraw(!1):(""!==b.oScroll.sX||""!==b.oScroll.sY)&&this.oApi._fnScrollDraw(b)};this.fnClearTable=function(a){var b=s(this[j.ext.iApiIndex]);ga(b);(a===n||a)&&x(b)};this.fnClose=
100
+ function(a){for(var b=s(this[j.ext.iApiIndex]),c=0;c<b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a)return(a=b.aoOpenRows[c].nTr.parentNode)&&a.removeChild(b.aoOpenRows[c].nTr),b.aoOpenRows.splice(c,1),0;return 1};this.fnDeleteRow=function(a,b,c){var d=s(this[j.ext.iApiIndex]),e,f,a="object"===typeof a?I(d,a):a,g=d.aoData.splice(a,1);e=0;for(f=d.aoData.length;e<f;e++)null!==d.aoData[e].nTr&&(d.aoData[e].nTr._DT_RowIndex=e);e=h.inArray(a,d.aiDisplay);d.asDataSearch.splice(e,1);ha(d.aiDisplayMaster,
101
+ a);ha(d.aiDisplay,a);"function"===typeof b&&b.call(this,d,g);d._iDisplayStart>=d.fnRecordsDisplay()&&(d._iDisplayStart-=d._iDisplayLength,0>d._iDisplayStart&&(d._iDisplayStart=0));if(c===n||c)y(d),x(d);return g};this.fnDestroy=function(a){var b=s(this[j.ext.iApiIndex]),c=b.nTableWrapper.parentNode,d=b.nTBody,i,f,a=a===n?!1:a;b.bDestroying=!0;A(b,"aoDestroyCallback","destroy",[b]);if(!a){i=0;for(f=b.aoColumns.length;i<f;i++)!1===b.aoColumns[i].bVisible&&this.fnSetColumnVis(i,!0)}h(b.nTableWrapper).find("*").andSelf().unbind(".DT");
102
+ h("tbody>tr>td."+b.oClasses.sRowEmpty,b.nTable).parent().remove();b.nTable!=b.nTHead.parentNode&&(h(b.nTable).children("thead").remove(),b.nTable.appendChild(b.nTHead));b.nTFoot&&b.nTable!=b.nTFoot.parentNode&&(h(b.nTable).children("tfoot").remove(),b.nTable.appendChild(b.nTFoot));b.nTable.parentNode.removeChild(b.nTable);h(b.nTableWrapper).remove();b.aaSorting=[];b.aaSortingFixed=[];P(b);h(T(b)).removeClass(b.asStripeClasses.join(" "));h("th, td",b.nTHead).removeClass([b.oClasses.sSortable,b.oClasses.sSortableAsc,
103
+ b.oClasses.sSortableDesc,b.oClasses.sSortableNone].join(" "));b.bJUI&&(h("th span."+b.oClasses.sSortIcon+", td span."+b.oClasses.sSortIcon,b.nTHead).remove(),h("th, td",b.nTHead).each(function(){var a=h("div."+b.oClasses.sSortJUIWrapper,this),c=a.contents();h(this).append(c);a.remove()}));!a&&b.nTableReinsertBefore?c.insertBefore(b.nTable,b.nTableReinsertBefore):a||c.appendChild(b.nTable);i=0;for(f=b.aoData.length;i<f;i++)null!==b.aoData[i].nTr&&d.appendChild(b.aoData[i].nTr);!0===b.oFeatures.bAutoWidth&&
104
+ (b.nTable.style.width=q(b.sDestroyWidth));if(f=b.asDestroyStripes.length){a=h(d).children("tr");for(i=0;i<f;i++)a.filter(":nth-child("+f+"n + "+i+")").addClass(b.asDestroyStripes[i])}i=0;for(f=j.settings.length;i<f;i++)j.settings[i]==b&&j.settings.splice(i,1);e=b=null};this.fnDraw=function(a){var b=s(this[j.ext.iApiIndex]);!1===a?(y(b),x(b)):aa(b)};this.fnFilter=function(a,b,c,d,e,f){var g=s(this[j.ext.iApiIndex]);if(g.oFeatures.bFilter){if(c===n||null===c)c=!1;if(d===n||null===d)d=!0;if(e===n||null===
105
+ e)e=!0;if(f===n||null===f)f=!0;if(b===n||null===b){if(K(g,{sSearch:a+"",bRegex:c,bSmart:d,bCaseInsensitive:f},1),e&&g.aanFeatures.f){b=g.aanFeatures.f;c=0;for(d=b.length;c<d;c++)try{b[c]._DT_Input!=l.activeElement&&h(b[c]._DT_Input).val(a)}catch(o){h(b[c]._DT_Input).val(a)}}}else h.extend(g.aoPreSearchCols[b],{sSearch:a+"",bRegex:c,bSmart:d,bCaseInsensitive:f}),K(g,g.oPreviousSearch,1)}};this.fnGetData=function(a,b){var c=s(this[j.ext.iApiIndex]);if(a!==n){var d=a;if("object"===typeof a){var e=a.nodeName.toLowerCase();
106
+ "tr"===e?d=I(c,a):"td"===e&&(d=I(c,a.parentNode),b=fa(c,d,a))}return b!==n?v(c,d,b,""):c.aoData[d]!==n?c.aoData[d]._aData:null}return Z(c)};this.fnGetNodes=function(a){var b=s(this[j.ext.iApiIndex]);return a!==n?b.aoData[a]!==n?b.aoData[a].nTr:null:T(b)};this.fnGetPosition=function(a){var b=s(this[j.ext.iApiIndex]),c=a.nodeName.toUpperCase();return"TR"==c?I(b,a):"TD"==c||"TH"==c?(c=I(b,a.parentNode),a=fa(b,c,a),[c,R(b,a),a]):null};this.fnIsOpen=function(a){for(var b=s(this[j.ext.iApiIndex]),c=0;c<
107
+ b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a)return!0;return!1};this.fnOpen=function(a,b,c){var d=s(this[j.ext.iApiIndex]),e=T(d);if(-1!==h.inArray(a,e)){this.fnClose(a);var e=l.createElement("tr"),f=l.createElement("td");e.appendChild(f);f.className=c;f.colSpan=t(d);"string"===typeof b?f.innerHTML=b:h(f).html(b);b=h("tr",d.nTBody);-1!=h.inArray(a,b)&&h(e).insertAfter(a);d.aoOpenRows.push({nTr:e,nParent:a});return e}};this.fnPageChange=function(a,b){var c=s(this[j.ext.iApiIndex]);qa(c,a);
108
+ y(c);(b===n||b)&&x(c)};this.fnSetColumnVis=function(a,b,c){var d=s(this[j.ext.iApiIndex]),e,f,g=d.aoColumns,h=d.aoData,o,m;if(g[a].bVisible!=b){if(b){for(e=f=0;e<a;e++)g[e].bVisible&&f++;m=f>=t(d);if(!m)for(e=a;e<g.length;e++)if(g[e].bVisible){o=e;break}e=0;for(f=h.length;e<f;e++)null!==h[e].nTr&&(m?h[e].nTr.appendChild(h[e]._anHidden[a]):h[e].nTr.insertBefore(h[e]._anHidden[a],J(d,e)[o]))}else{e=0;for(f=h.length;e<f;e++)null!==h[e].nTr&&(o=J(d,e)[a],h[e]._anHidden[a]=o,o.parentNode.removeChild(o))}g[a].bVisible=
109
+ b;W(d,d.aoHeader);d.nTFoot&&W(d,d.aoFooter);e=0;for(f=d.aoOpenRows.length;e<f;e++)d.aoOpenRows[e].nTr.colSpan=t(d);if(c===n||c)k(d),x(d);ra(d)}};this.fnSettings=function(){return s(this[j.ext.iApiIndex])};this.fnSort=function(a){var b=s(this[j.ext.iApiIndex]);b.aaSorting=a;O(b)};this.fnSortListener=function(a,b,c){ia(s(this[j.ext.iApiIndex]),a,b,c)};this.fnUpdate=function(a,b,c,d,e){var f=s(this[j.ext.iApiIndex]),b="object"===typeof b?I(f,b):b;if(h.isArray(a)&&c===n){f.aoData[b]._aData=a.slice();
110
+ for(c=0;c<f.aoColumns.length;c++)this.fnUpdate(v(f,b,c),b,c,!1,!1)}else if(h.isPlainObject(a)&&c===n){f.aoData[b]._aData=h.extend(!0,{},a);for(c=0;c<f.aoColumns.length;c++)this.fnUpdate(v(f,b,c),b,c,!1,!1)}else{F(f,b,c,a);var a=v(f,b,c,"display"),g=f.aoColumns[c];null!==g.fnRender&&(a=S(f,b,c),g.bUseRendered&&F(f,b,c,a));null!==f.aoData[b].nTr&&(J(f,b)[c].innerHTML=a)}c=h.inArray(b,f.aiDisplay);f.asDataSearch[c]=na(f,Y(f,b,"filter",r(f,"bSearchable")));(e===n||e)&&k(f);(d===n||d)&&aa(f);return 0};
111
+ this.fnVersionCheck=j.ext.fnVersionCheck;this.oApi={_fnExternApiFunc:Va,_fnInitialise:ba,_fnInitComplete:$,_fnLanguageCompat:pa,_fnAddColumn:o,_fnColumnOptions:m,_fnAddData:H,_fnCreateTr:ea,_fnGatherData:ua,_fnBuildHead:va,_fnDrawHead:W,_fnDraw:x,_fnReDraw:aa,_fnAjaxUpdate:wa,_fnAjaxParameters:Ea,_fnAjaxUpdateDraw:Fa,_fnServerParams:ka,_fnAddOptionsHtml:xa,_fnFeatureHtmlTable:Ba,_fnScrollDraw:La,_fnAdjustColumnSizing:k,_fnFeatureHtmlFilter:za,_fnFilterComplete:K,_fnFilterCustom:Ia,_fnFilterColumn:Ha,
112
+ _fnFilter:Ga,_fnBuildSearchArray:la,_fnBuildSearchRow:na,_fnFilterCreateSearch:ma,_fnDataToSearch:Ja,_fnSort:O,_fnSortAttachListener:ia,_fnSortingClasses:P,_fnFeatureHtmlPaginate:Da,_fnPageChange:qa,_fnFeatureHtmlInfo:Ca,_fnUpdateInfo:Ka,_fnFeatureHtmlLength:ya,_fnFeatureHtmlProcessing:Aa,_fnProcessingDisplay:E,_fnVisibleToColumnIndex:G,_fnColumnIndexToVisible:R,_fnNodeToDataIndex:I,_fnVisbleColumns:t,_fnCalculateEnd:y,_fnConvertToWidth:Ma,_fnCalculateColumnWidths:da,_fnScrollingWidthAdjust:Oa,_fnGetWidestNode:Na,
113
+ _fnGetMaxLenString:Pa,_fnStringToCss:q,_fnDetectType:B,_fnSettingsFromNode:s,_fnGetDataMaster:Z,_fnGetTrNodes:T,_fnGetTdNodes:J,_fnEscapeRegex:oa,_fnDeleteIndex:ha,_fnReOrderIndex:u,_fnColumnOrdering:M,_fnLog:D,_fnClearTable:ga,_fnSaveState:ra,_fnLoadState:Sa,_fnCreateCookie:function(a,b,c,d,e){var f=new Date;f.setTime(f.getTime()+1E3*c);var c=X.location.pathname.split("/"),a=a+"_"+c.pop().replace(/[\/:]/g,"").toLowerCase(),g;null!==e?(g="function"===typeof h.parseJSON?h.parseJSON(b):eval("("+b+")"),
114
+ b=e(a,g,f.toGMTString(),c.join("/")+"/")):b=a+"="+encodeURIComponent(b)+"; expires="+f.toGMTString()+"; path="+c.join("/")+"/";a=l.cookie.split(";");e=b.split(";")[0].length;f=[];if(4096<e+l.cookie.length+10){for(var j=0,o=a.length;j<o;j++)if(-1!=a[j].indexOf(d)){var k=a[j].split("=");try{(g=eval("("+decodeURIComponent(k[1])+")"))&&g.iCreate&&f.push({name:k[0],time:g.iCreate})}catch(m){}}for(f.sort(function(a,b){return b.time-a.time});4096<e+l.cookie.length+10;){if(0===f.length)return;d=f.pop();l.cookie=
115
+ d.name+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+c.join("/")+"/"}}l.cookie=b},_fnReadCookie:function(a){for(var b=X.location.pathname.split("/"),a=a+"_"+b[b.length-1].replace(/[\/:]/g,"").toLowerCase()+"=",b=l.cookie.split(";"),c=0;c<b.length;c++){for(var d=b[c];" "==d.charAt(0);)d=d.substring(1,d.length);if(0===d.indexOf(a))return decodeURIComponent(d.substring(a.length,d.length))}return null},_fnDetectHeader:V,_fnGetUniqueThs:N,_fnScrollBarWidth:Qa,_fnApplyToChildren:C,_fnMap:p,_fnGetRowData:Y,
116
+ _fnGetCellData:v,_fnSetCellData:F,_fnGetObjectDataFn:Q,_fnSetObjectDataFn:L,_fnApplyColumnDefs:ta,_fnBindAction:Ra,_fnExtend:Ta,_fnCallbackReg:z,_fnCallbackFire:A,_fnJsonString:Wa,_fnRender:S,_fnNodeToColumnIndex:fa,_fnInfoMacros:ja,_fnBrowserDetect:Ua,_fnGetColumns:r};h.extend(j.ext.oApi,this.oApi);for(var sa in j.ext.oApi)sa&&(this[sa]=Va(sa));var ca=this;this.each(function(){var a=0,b,c,d;c=this.getAttribute("id");var i=!1,f=!1;if("table"!=this.nodeName.toLowerCase())D(null,0,"Attempted to initialise DataTables on a node which is not a table: "+
117
+ this.nodeName);else{a=0;for(b=j.settings.length;a<b;a++){if(j.settings[a].nTable==this){if(e===n||e.bRetrieve)return j.settings[a].oInstance;if(e.bDestroy){j.settings[a].oInstance.fnDestroy();break}else{D(j.settings[a],0,"Cannot reinitialise DataTable.\n\nTo retrieve the DataTables object for this table, pass no arguments or see the docs for bRetrieve and bDestroy");return}}if(j.settings[a].sTableId==this.id){j.settings.splice(a,1);break}}if(null===c||""===c)this.id=c="DataTables_Table_"+j.ext._oExternConfig.iNextUnique++;
118
+ var g=h.extend(!0,{},j.models.oSettings,{nTable:this,oApi:ca.oApi,oInit:e,sDestroyWidth:h(this).width(),sInstance:c,sTableId:c});j.settings.push(g);g.oInstance=1===ca.length?ca:h(this).dataTable();e||(e={});e.oLanguage&&pa(e.oLanguage);e=Ta(h.extend(!0,{},j.defaults),e);p(g.oFeatures,e,"bPaginate");p(g.oFeatures,e,"bLengthChange");p(g.oFeatures,e,"bFilter");p(g.oFeatures,e,"bSort");p(g.oFeatures,e,"bInfo");p(g.oFeatures,e,"bProcessing");p(g.oFeatures,e,"bAutoWidth");p(g.oFeatures,e,"bSortClasses");
119
+ p(g.oFeatures,e,"bServerSide");p(g.oFeatures,e,"bDeferRender");p(g.oScroll,e,"sScrollX","sX");p(g.oScroll,e,"sScrollXInner","sXInner");p(g.oScroll,e,"sScrollY","sY");p(g.oScroll,e,"bScrollCollapse","bCollapse");p(g.oScroll,e,"bScrollInfinite","bInfinite");p(g.oScroll,e,"iScrollLoadGap","iLoadGap");p(g.oScroll,e,"bScrollAutoCss","bAutoCss");p(g,e,"asStripeClasses");p(g,e,"asStripClasses","asStripeClasses");p(g,e,"fnServerData");p(g,e,"fnFormatNumber");p(g,e,"sServerMethod");p(g,e,"aaSorting");p(g,
120
+ e,"aaSortingFixed");p(g,e,"aLengthMenu");p(g,e,"sPaginationType");p(g,e,"sAjaxSource");p(g,e,"sAjaxDataProp");p(g,e,"iCookieDuration");p(g,e,"sCookiePrefix");p(g,e,"sDom");p(g,e,"bSortCellsTop");p(g,e,"iTabIndex");p(g,e,"oSearch","oPreviousSearch");p(g,e,"aoSearchCols","aoPreSearchCols");p(g,e,"iDisplayLength","_iDisplayLength");p(g,e,"bJQueryUI","bJUI");p(g,e,"fnCookieCallback");p(g,e,"fnStateLoad");p(g,e,"fnStateSave");p(g.oLanguage,e,"fnInfoCallback");z(g,"aoDrawCallback",e.fnDrawCallback,"user");
121
+ z(g,"aoServerParams",e.fnServerParams,"user");z(g,"aoStateSaveParams",e.fnStateSaveParams,"user");z(g,"aoStateLoadParams",e.fnStateLoadParams,"user");z(g,"aoStateLoaded",e.fnStateLoaded,"user");z(g,"aoRowCallback",e.fnRowCallback,"user");z(g,"aoRowCreatedCallback",e.fnCreatedRow,"user");z(g,"aoHeaderCallback",e.fnHeaderCallback,"user");z(g,"aoFooterCallback",e.fnFooterCallback,"user");z(g,"aoInitComplete",e.fnInitComplete,"user");z(g,"aoPreDrawCallback",e.fnPreDrawCallback,"user");g.oFeatures.bServerSide&&
122
+ g.oFeatures.bSort&&g.oFeatures.bSortClasses?z(g,"aoDrawCallback",P,"server_side_sort_classes"):g.oFeatures.bDeferRender&&z(g,"aoDrawCallback",P,"defer_sort_classes");e.bJQueryUI?(h.extend(g.oClasses,j.ext.oJUIClasses),e.sDom===j.defaults.sDom&&"lfrtip"===j.defaults.sDom&&(g.sDom='<"H"lfr>t<"F"ip>')):h.extend(g.oClasses,j.ext.oStdClasses);h(this).addClass(g.oClasses.sTable);if(""!==g.oScroll.sX||""!==g.oScroll.sY)g.oScroll.iBarWidth=Qa();g.iInitDisplayStart===n&&(g.iInitDisplayStart=e.iDisplayStart,
123
+ g._iDisplayStart=e.iDisplayStart);e.bStateSave&&(g.oFeatures.bStateSave=!0,Sa(g,e),z(g,"aoDrawCallback",ra,"state_save"));null!==e.iDeferLoading&&(g.bDeferLoading=!0,a=h.isArray(e.iDeferLoading),g._iRecordsDisplay=a?e.iDeferLoading[0]:e.iDeferLoading,g._iRecordsTotal=a?e.iDeferLoading[1]:e.iDeferLoading);null!==e.aaData&&(f=!0);""!==e.oLanguage.sUrl?(g.oLanguage.sUrl=e.oLanguage.sUrl,h.getJSON(g.oLanguage.sUrl,null,function(a){pa(a);h.extend(true,g.oLanguage,e.oLanguage,a);ba(g)}),i=!0):h.extend(!0,
124
+ g.oLanguage,e.oLanguage);null===e.asStripeClasses&&(g.asStripeClasses=[g.oClasses.sStripeOdd,g.oClasses.sStripeEven]);b=g.asStripeClasses.length;g.asDestroyStripes=[];if(b){c=!1;d=h(this).children("tbody").children("tr:lt("+b+")");for(a=0;a<b;a++)d.hasClass(g.asStripeClasses[a])&&(c=!0,g.asDestroyStripes.push(g.asStripeClasses[a]));c&&d.removeClass(g.asStripeClasses.join(" "))}c=[];a=this.getElementsByTagName("thead");0!==a.length&&(V(g.aoHeader,a[0]),c=N(g));if(null===e.aoColumns){d=[];a=0;for(b=
125
+ c.length;a<b;a++)d.push(null)}else d=e.aoColumns;a=0;for(b=d.length;a<b;a++)e.saved_aoColumns!==n&&e.saved_aoColumns.length==b&&(null===d[a]&&(d[a]={}),d[a].bVisible=e.saved_aoColumns[a].bVisible),o(g,c?c[a]:null);ta(g,e.aoColumnDefs,d,function(a,b){m(g,a,b)});a=0;for(b=g.aaSorting.length;a<b;a++){g.aaSorting[a][0]>=g.aoColumns.length&&(g.aaSorting[a][0]=0);var k=g.aoColumns[g.aaSorting[a][0]];g.aaSorting[a][2]===n&&(g.aaSorting[a][2]=0);e.aaSorting===n&&g.saved_aaSorting===n&&(g.aaSorting[a][1]=
126
+ k.asSorting[0]);c=0;for(d=k.asSorting.length;c<d;c++)if(g.aaSorting[a][1]==k.asSorting[c]){g.aaSorting[a][2]=c;break}}P(g);Ua(g);a=h(this).children("caption").each(function(){this._captionSide=h(this).css("caption-side")});b=h(this).children("thead");0===b.length&&(b=[l.createElement("thead")],this.appendChild(b[0]));g.nTHead=b[0];b=h(this).children("tbody");0===b.length&&(b=[l.createElement("tbody")],this.appendChild(b[0]));g.nTBody=b[0];g.nTBody.setAttribute("role","alert");g.nTBody.setAttribute("aria-live",
127
+ "polite");g.nTBody.setAttribute("aria-relevant","all");b=h(this).children("tfoot");if(0===b.length&&0<a.length&&(""!==g.oScroll.sX||""!==g.oScroll.sY))b=[l.createElement("tfoot")],this.appendChild(b[0]);0<b.length&&(g.nTFoot=b[0],V(g.aoFooter,g.nTFoot));if(f)for(a=0;a<e.aaData.length;a++)H(g,e.aaData[a]);else ua(g);g.aiDisplay=g.aiDisplayMaster.slice();g.bInitialised=!0;!1===i&&ba(g)}});ca=null;return this};j.fnVersionCheck=function(e){for(var h=function(e,h){for(;e.length<h;)e+="0";return e},m=j.ext.sVersion.split("."),
128
+ e=e.split("."),k="",n="",l=0,t=e.length;l<t;l++)k+=h(m[l],3),n+=h(e[l],3);return parseInt(k,10)>=parseInt(n,10)};j.fnIsDataTable=function(e){for(var h=j.settings,m=0;m<h.length;m++)if(h[m].nTable===e||h[m].nScrollHead===e||h[m].nScrollFoot===e)return!0;return!1};j.fnTables=function(e){var o=[];jQuery.each(j.settings,function(j,k){(!e||!0===e&&h(k.nTable).is(":visible"))&&o.push(k.nTable)});return o};j.version="1.9.4";j.settings=[];j.models={};j.models.ext={afnFiltering:[],afnSortData:[],aoFeatures:[],
129
+ aTypes:[],fnVersionCheck:j.fnVersionCheck,iApiIndex:0,ofnSearch:{},oApi:{},oStdClasses:{},oJUIClasses:{},oPagination:{},oSort:{},sVersion:j.version,sErrMode:"alert",_oExternConfig:{iNextUnique:0}};j.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};j.models.oRow={nTr:null,_aData:[],_aSortData:[],_anHidden:[],_sRowStripe:""};j.models.oColumn={aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bUseRendered:null,bVisible:null,_bAutoType:!0,fnCreatedCell:null,fnGetData:null,
130
+ fnRender:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};j.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,
131
+ bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollAutoCss:!0,bScrollCollapse:!1,bScrollInfinite:!1,bServerSide:!1,bSort:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCookieCallback:null,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(e){if(1E3>e)return e;for(var h=e+"",e=h.split(""),j="",h=h.length,k=0;k<h;k++)0===k%3&&0!==k&&(j=this.oLanguage.sInfoThousands+j),j=e[h-k-1]+j;return j},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,
132
+ fnRowCallback:null,fnServerData:function(e,j,m,k){k.jqXHR=h.ajax({url:e,data:j,success:function(e){e.sError&&k.oApi._fnLog(k,0,e.sError);h(k.oInstance).trigger("xhr",[k,e]);m(e)},dataType:"json",cache:!1,type:k.sServerMethod,error:function(e,h){"parsererror"==h&&k.oApi._fnLog(k,0,"DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})},fnServerParams:null,fnStateLoad:function(e){var e=this.oApi._fnReadCookie(e.sCookiePrefix+e.sInstance),j;try{j=
133
+ "function"===typeof h.parseJSON?h.parseJSON(e):eval("("+e+")")}catch(m){j=null}return j},fnStateLoadParams:null,fnStateLoaded:null,fnStateSave:function(e,h){this.oApi._fnCreateCookie(e.sCookiePrefix+e.sInstance,this.oApi._fnJsonString(h),e.iCookieDuration,e.sCookiePrefix,e.fnCookieCallback)},fnStateSaveParams:null,iCookieDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iScrollLoadGap:100,iTabIndex:0,oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},
134
+ oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sInfoThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sUrl:"",sZeroRecords:"No matching records found"},oSearch:h.extend({},j.models.oSearch),sAjaxDataProp:"aaData",
135
+ sAjaxSource:null,sCookiePrefix:"SpryMedia_DataTables_",sDom:"lfrtip",sPaginationType:"two_button",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET"};j.defaults.columns={aDataSort:null,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bUseRendered:!0,bVisible:!0,fnCreatedCell:null,fnRender:null,iDataSort:-1,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null};j.models.oSettings={oFeatures:{bAutoWidth:null,
136
+ bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortClasses:null,bStateSave:null},oScroll:{bAutoCss:null,bCollapse:null,bInfinite:null,iBarWidth:0,iLoadGap:null,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1},aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aoColumns:[],aoHeader:[],aoFooter:[],asDataSearch:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:null,
137
+ asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,sPaginationType:"two_button",iCookieDuration:0,sCookiePrefix:"",fnCookieCallback:null,aoStateSave:[],aoStateLoad:[],
138
+ oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iDisplayEnd:10,_iRecordsTotal:0,_iRecordsDisplay:0,bJUI:null,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length},
139
+ fnRecordsDisplay:function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length},fnDisplayEnd:function(){return this.oFeatures.bServerSide?!1===this.oFeatures.bPaginate||-1==this._iDisplayLength?this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null};j.ext=h.extend(!0,{},j.models.ext);h.extend(j.ext.oStdClasses,
140
+ {sTable:"dataTable",sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active",sPageButtonStaticDisabled:"paginate_button paginate_button_disabled",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",
141
+ sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",
142
+ sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:"",sJUIHeader:"",sJUIFooter:""});h.extend(j.ext.oJUIClasses,j.ext.oStdClasses,{sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left",sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",
143
+ sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled",sPageFirst:"first ui-corner-tl ui-corner-bl",sPageLast:"last ui-corner-tr ui-corner-br",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",
144
+ sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",sSortableAsc:"ui-state-default",sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",
145
+ sScrollHead:"dataTables_scrollHead ui-state-default",sScrollFoot:"dataTables_scrollFoot ui-state-default",sFooterTH:"ui-state-default",sJUIHeader:"fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix",sJUIFooter:"fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix"});h.extend(j.ext.oPagination,{two_button:{fnInit:function(e,j,m){var k=e.oLanguage.oPaginate,n=function(h){e.oApi._fnPageChange(e,h.data.action)&&m(e)},k=!e.bJUI?'<a class="'+
146
+ e.oClasses.sPagePrevDisabled+'" tabindex="'+e.iTabIndex+'" role="button">'+k.sPrevious+'</a><a class="'+e.oClasses.sPageNextDisabled+'" tabindex="'+e.iTabIndex+'" role="button">'+k.sNext+"</a>":'<a class="'+e.oClasses.sPagePrevDisabled+'" tabindex="'+e.iTabIndex+'" role="button"><span class="'+e.oClasses.sPageJUIPrev+'"></span></a><a class="'+e.oClasses.sPageNextDisabled+'" tabindex="'+e.iTabIndex+'" role="button"><span class="'+e.oClasses.sPageJUINext+'"></span></a>';h(j).append(k);var l=h("a",j),
147
+ k=l[0],l=l[1];e.oApi._fnBindAction(k,{action:"previous"},n);e.oApi._fnBindAction(l,{action:"next"},n);e.aanFeatures.p||(j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_previous",l.id=e.sTableId+"_next",k.setAttribute("aria-controls",e.sTableId),l.setAttribute("aria-controls",e.sTableId))},fnUpdate:function(e){if(e.aanFeatures.p)for(var h=e.oClasses,j=e.aanFeatures.p,k,l=0,n=j.length;l<n;l++)if(k=j[l].firstChild)k.className=0===e._iDisplayStart?h.sPagePrevDisabled:h.sPagePrevEnabled,k=k.nextSibling,
148
+ k.className=e.fnDisplayEnd()==e.fnRecordsDisplay()?h.sPageNextDisabled:h.sPageNextEnabled}},iFullNumbersShowPages:5,full_numbers:{fnInit:function(e,j,m){var k=e.oLanguage.oPaginate,l=e.oClasses,n=function(h){e.oApi._fnPageChange(e,h.data.action)&&m(e)};h(j).append('<a tabindex="'+e.iTabIndex+'" class="'+l.sPageButton+" "+l.sPageFirst+'">'+k.sFirst+'</a><a tabindex="'+e.iTabIndex+'" class="'+l.sPageButton+" "+l.sPagePrevious+'">'+k.sPrevious+'</a><span></span><a tabindex="'+e.iTabIndex+'" class="'+
149
+ l.sPageButton+" "+l.sPageNext+'">'+k.sNext+'</a><a tabindex="'+e.iTabIndex+'" class="'+l.sPageButton+" "+l.sPageLast+'">'+k.sLast+"</a>");var t=h("a",j),k=t[0],l=t[1],r=t[2],t=t[3];e.oApi._fnBindAction(k,{action:"first"},n);e.oApi._fnBindAction(l,{action:"previous"},n);e.oApi._fnBindAction(r,{action:"next"},n);e.oApi._fnBindAction(t,{action:"last"},n);e.aanFeatures.p||(j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_first",l.id=e.sTableId+"_previous",r.id=e.sTableId+"_next",t.id=e.sTableId+"_last")},
150
+ fnUpdate:function(e,o){if(e.aanFeatures.p){var m=j.ext.oPagination.iFullNumbersShowPages,k=Math.floor(m/2),l=Math.ceil(e.fnRecordsDisplay()/e._iDisplayLength),n=Math.ceil(e._iDisplayStart/e._iDisplayLength)+1,t="",r,B=e.oClasses,u,M=e.aanFeatures.p,L=function(h){e.oApi._fnBindAction(this,{page:h+r-1},function(h){e.oApi._fnPageChange(e,h.data.page);o(e);h.preventDefault()})};-1===e._iDisplayLength?n=k=r=1:l<m?(r=1,k=l):n<=k?(r=1,k=m):n>=l-k?(r=l-m+1,k=l):(r=n-Math.ceil(m/2)+1,k=r+m-1);for(m=r;m<=k;m++)t+=
151
+ n!==m?'<a tabindex="'+e.iTabIndex+'" class="'+B.sPageButton+'">'+e.fnFormatNumber(m)+"</a>":'<a tabindex="'+e.iTabIndex+'" class="'+B.sPageButtonActive+'">'+e.fnFormatNumber(m)+"</a>";m=0;for(k=M.length;m<k;m++)u=M[m],u.hasChildNodes()&&(h("span:eq(0)",u).html(t).children("a").each(L),u=u.getElementsByTagName("a"),u=[u[0],u[1],u[u.length-2],u[u.length-1]],h(u).removeClass(B.sPageButton+" "+B.sPageButtonActive+" "+B.sPageButtonStaticDisabled),h([u[0],u[1]]).addClass(1==n?B.sPageButtonStaticDisabled:
152
+ B.sPageButton),h([u[2],u[3]]).addClass(0===l||n===l||-1===e._iDisplayLength?B.sPageButtonStaticDisabled:B.sPageButton))}}}});h.extend(j.ext.oSort,{"string-pre":function(e){"string"!=typeof e&&(e=null!==e&&e.toString?e.toString():"");return e.toLowerCase()},"string-asc":function(e,h){return e<h?-1:e>h?1:0},"string-desc":function(e,h){return e<h?1:e>h?-1:0},"html-pre":function(e){return e.replace(/<.*?>/g,"").toLowerCase()},"html-asc":function(e,h){return e<h?-1:e>h?1:0},"html-desc":function(e,h){return e<
153
+ h?1:e>h?-1:0},"date-pre":function(e){e=Date.parse(e);if(isNaN(e)||""===e)e=Date.parse("01/01/1970 00:00:00");return e},"date-asc":function(e,h){return e-h},"date-desc":function(e,h){return h-e},"numeric-pre":function(e){return"-"==e||""===e?0:1*e},"numeric-asc":function(e,h){return e-h},"numeric-desc":function(e,h){return h-e}});h.extend(j.ext.aTypes,[function(e){if("number"===typeof e)return"numeric";if("string"!==typeof e)return null;var h,j=!1;h=e.charAt(0);if(-1=="0123456789-".indexOf(h))return null;
154
+ for(var k=1;k<e.length;k++){h=e.charAt(k);if(-1=="0123456789.".indexOf(h))return null;if("."==h){if(j)return null;j=!0}}return"numeric"},function(e){var h=Date.parse(e);return null!==h&&!isNaN(h)||"string"===typeof e&&0===e.length?"date":null},function(e){return"string"===typeof e&&-1!=e.indexOf("<")&&-1!=e.indexOf(">")?"html":null}]);h.fn.DataTable=j;h.fn.dataTable=j;h.fn.dataTableSettings=j.settings;h.fn.dataTableExt=j.ext};"function"===typeof define&&define.amd?define(["jquery"],L):jQuery&&!jQuery.fn.dataTable&&
155
+ L(jQuery)})(window,document);
media/js/jquery.treeview.js ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Treeview 1.5pre - jQuery plugin to hide and show branches of a tree
3
+ *
4
+ * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/
5
+ * http://docs.jquery.com/Plugins/Treeview
6
+ *
7
+ * Copyright (c) 2007 Jörn Zaefferer
8
+ *
9
+ * Dual licensed under the MIT and GPL licenses:
10
+ * http://www.opensource.org/licenses/mit-license.php
11
+ * http://www.gnu.org/licenses/gpl.html
12
+ *
13
+ * Revision: $Id: jquery.treeview.js 5759 2008-07-01 07:50:28Z joern.zaefferer $
14
+ *
15
+ */
16
+
17
+ (function(b){b.extend(b.fn,{swapClass:function(c,a){var b=this.filter("."+c);this.filter("."+a).removeClass(a).addClass(c);b.removeClass(c).addClass(a);return this},replaceClass:function(a,b){return this.filter("."+a).removeClass(a).addClass(b).end()},hoverClass:function(a){a=a||"hover";return this.hover(function(){b(this).addClass(a)},function(){b(this).removeClass(a)})},heightToggle:function(a,b){a?this.animate({height:"toggle"},a,b):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")? "show":"hide"]();b&&b.apply(this,arguments)})},heightHide:function(a,b){a?this.animate({height:"hide"},a,b):(this.hide(),b&&this.each(b))},prepareBranches:function(b){b.prerendered||(this.filter(":last-child:not(ul)").addClass(a.last),this.filter((b.collapsed?"":"."+a.closed)+":not(."+a.open+")").find(">ul").hide());return this.filter(":has(>ul)")},applyClasses:function(c,g){this.filter(":has(>ul):not(:has(>a))").find(">span").unbind("click.treeview").bind("click.treeview",function(a){this==a.target&& g.apply(b(this).next())}).add(b("a",this)).hoverClass();if(!c.prerendered){this.filter(":has(>ul:hidden)").addClass(a.expandable).replaceClass(a.last,a.lastExpandable);this.not(":has(>ul:hidden)").addClass(a.collapsable).replaceClass(a.last,a.lastCollapsable);var d=this.find("div."+a.hitarea);d.length||(d=this.prepend('<div class="'+a.hitarea+'"/>').find("div."+a.hitarea));d.removeClass().addClass(a.hitarea).each(function(){var a="";b.each(b(this).parent().attr("class").split(" "),function(){a+=this+ "-hitarea "});b(this).addClass(a)})}this.find("div."+a.hitarea).click(g)},treeview:function(c){function g(c,e){function h(e){return function(){d.apply(b("div."+a.hitarea,c).filter(function(){return e?b(this).parent("."+e).length:!0}));return!1}}b("a:eq(0)",e).click(h(a.collapsable));b("a:eq(1)",e).click(h(a.expandable));b("a:eq(2)",e).click(h())}function d(){b(this).parent().find(">.hitarea").swapClass(a.collapsableHitarea,a.expandableHitarea).swapClass(a.lastCollapsableHitarea,a.lastExpandableHitarea).end().swapClass(a.collapsable, a.expandable).swapClass(a.lastCollapsable,a.lastExpandable).find(">ul").heightToggle(c.animated,c.toggle);c.unique&&b(this).parent().siblings().find(">.hitarea").replaceClass(a.collapsableHitarea,a.expandableHitarea).replaceClass(a.lastCollapsableHitarea,a.lastExpandableHitarea).end().replaceClass(a.collapsable,a.expandable).replaceClass(a.lastCollapsable,a.lastExpandable).find(">ul").heightHide(c.animated,c.toggle)}function k(){var a=[];i.each(function(c,d){a[c]=b(d).is(":has(>ul:visible)")?1:0}); b.cookie(c.cookieId,a.join(""),c.cookieOptions)}function l(){var a=b.cookie(c.cookieId);if(a){var d=a.split("");i.each(function(a,c){b(c).find(">ul")[parseInt(d[a])?"show":"hide"]()})}}c=b.extend({cookieId:"treeview"},c);if(c.toggle){var m=c.toggle;c.toggle=function(){return m.apply(b(this).parent()[0],arguments)}}this.data("toggler",d);this.addClass("treeview");var i=this.find("li").prepareBranches(c);switch(c.persist){case "cookie":var j=c.toggle;c.toggle=function(){k();j&&j.apply(this,arguments)}; l();break;case "location":var f=this.find("a").filter(function(){return this.href.toLowerCase()==location.href.toLowerCase()});f.length&&(f=f.addClass("selected").parents("ul, li").add(f.next()).show(),c.prerendered&&f.filter("li").swapClass(a.collapsable,a.expandable).swapClass(a.lastCollapsable,a.lastExpandable).find(">.hitarea").swapClass(a.collapsableHitarea,a.expandableHitarea).swapClass(a.lastCollapsableHitarea,a.lastExpandableHitarea))}i.applyClasses(c,d);c.control&&(g(this,c.control),b(c.control).show()); return this}});b.treeview={};var a=b.treeview.classes={open:"open",closed:"closed",expandable:"expandable",expandableHitarea:"expandable-hitarea",lastExpandableHitarea:"lastExpandable-hitarea",collapsable:"collapsable",collapsableHitarea:"collapsable-hitarea",lastCollapsableHitarea:"lastCollapsable-hitarea",lastCollapsable:"lastCollapsable",lastExpandable:"lastExpandable",last:"last",hitarea:"hitarea"}})(jQuery);
18
+
19
+ (function($) {
20
+ var CLASSES = $.treeview.classes;
21
+ var proxied = $.fn.treeview;
22
+ $.fn.treeview = function(settings) {
23
+ settings = $.extend({}, settings);
24
+ if (settings.add) {
25
+ return this.trigger("add", [settings.add]);
26
+ }
27
+ if (settings.remove) {
28
+ return this.trigger("remove", [settings.remove]);
29
+ }
30
+ return proxied.apply(this, arguments).bind("add", function(event, branches) {
31
+ $(branches).prev()
32
+ .removeClass(CLASSES.last)
33
+ .removeClass(CLASSES.lastCollapsable)
34
+ .removeClass(CLASSES.lastExpandable)
35
+ .find(">.hitarea")
36
+ .removeClass(CLASSES.lastCollapsableHitarea)
37
+ .removeClass(CLASSES.lastExpandableHitarea);
38
+ $(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings, $(this).data("toggler"));
39
+ }).bind("remove", function(event, branches) {
40
+ var prev = $(branches).prev();
41
+ var parent = $(branches).parent();
42
+ $(branches).remove();
43
+ prev.filter(":last-child").addClass(CLASSES.last)
44
+ .filter("." + CLASSES.expandable).replaceClass(CLASSES.last, CLASSES.lastExpandable).end()
45
+ .find(">.hitarea").replaceClass(CLASSES.expandableHitarea, CLASSES.lastExpandableHitarea).end()
46
+ .filter("." + CLASSES.collapsable).replaceClass(CLASSES.last, CLASSES.lastCollapsable).end()
47
+ .find(">.hitarea").replaceClass(CLASSES.collapsableHitarea, CLASSES.lastCollapsableHitarea);
48
+ if (parent.is(":not(:has(>))") && parent[0] != this) {
49
+ parent.parent().removeClass(CLASSES.collapsable).removeClass(CLASSES.expandable)
50
+ parent.siblings(".hitarea").andSelf().remove();
51
+ }
52
+ });
53
+ };
54
+
55
+ })(jQuery);
56
+
57
+ (function($) {
58
+
59
+ function load(settings, root, child, container) {
60
+ function createNode(parent) {
61
+ var current = $("<li/>").attr("id", this.id || "").html("<span>" + this.text + "</span>").appendTo(parent);
62
+ if (this.classes) {
63
+ current.children("span").addClass(this.classes);
64
+ }
65
+ if (this.expanded) {
66
+ current.addClass("open");
67
+ }
68
+ if (this.hasChildren || this.children && this.children.length) {
69
+ var branch = $("<ul/>").appendTo(current);
70
+ if (this.hasChildren) {
71
+ current.addClass("hasChildren");
72
+ createNode.call({
73
+ classes: "placeholder",
74
+ text: "&nbsp;",
75
+ children:[]
76
+ }, branch);
77
+ }
78
+ if (this.children && this.children.length) {
79
+ $.each(this.children, createNode, [branch])
80
+ }
81
+ }
82
+ }
83
+ $.ajax($.extend(true, {
84
+ url: settings.url,
85
+ dataType: "json",
86
+ data: {
87
+ root: root
88
+ },
89
+ success: function(response) {
90
+ child.empty();
91
+ $.each(response, createNode, [child]);
92
+ $(container).treeview({
93
+ add: child
94
+ });
95
+ }
96
+ }, settings.ajax));
97
+ }
98
+
99
+ var proxied = $.fn.treeview;
100
+ $.fn.treeview = function(settings) {
101
+ if (!settings.url) {
102
+ return proxied.apply(this, arguments);
103
+ }
104
+ var container = this;
105
+ if (!container.children().size())
106
+ load(settings, "source", this, container);
107
+ var userToggle = settings.toggle;
108
+ return proxied.call(this, $.extend({}, settings, {
109
+ collapsed: true,
110
+ toggle: function() {
111
+ var $this = $(this);
112
+ if ($this.hasClass("hasChildren")) {
113
+ var childList = $this.removeClass("hasChildren").find("ul");
114
+ load(settings, this.id, childList, container);
115
+ }
116
+ if (userToggle) {
117
+ userToggle.apply(this, arguments);
118
+ }
119
+ }
120
+ }));
121
+ };
122
+
123
+ })(jQuery);
media/js/migrate.js ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * ======================================================================
3
+ * LICENSE: This file is subject to the terms and conditions defined in *
4
+ * file 'license.txt', which is part of this source code package. *
5
+ * ======================================================================
6
+ */
7
+
8
+ function aamMigration() {
9
+ this.steps = {
10
+ 1: {
11
+ id: 'aam_collect_data',
12
+ action: 'collect'
13
+ },
14
+ 2: {
15
+ id: 'aam_migrating',
16
+ action: 'migrate'
17
+ },
18
+ 3: {
19
+ id: 'aam_cleanup',
20
+ action: 'cleanup'
21
+ },
22
+ 4: {
23
+ id: 'aam_migration_complete',
24
+ action: 'complete'
25
+ }
26
+ };
27
+ }
28
+
29
+ aamMigration.prototype.run = function() {
30
+ this.activateStep(1);
31
+ };
32
+
33
+ aamMigration.prototype.activateStep = function(index) {
34
+ if (typeof this.steps[index] !== 'undefined') {
35
+ jQuery('#' + this.steps[index].id).css('opacity', '1');
36
+ jQuery('#' + this.steps[index].id).removeClass('migration-step-pending').addClass('migration-step-running');
37
+ this.sendRequest(index);
38
+ }
39
+ };
40
+
41
+ aamMigration.prototype.completeStep = function(index) {
42
+ jQuery('#' + this.steps[index].id).removeClass('migration-step-running').addClass('migration-step-completed');
43
+ };
44
+
45
+ aamMigration.prototype.failedStep = function(index) {
46
+ jQuery('#' + this.steps[index].id).removeClass('migration-step-running').addClass('migration-step-failed');
47
+ };
48
+
49
+ aamMigration.prototype.sendRequest = function(index) {
50
+ var _this = this;
51
+ jQuery.ajax(aamMigrateLocal.ajaxurl, {
52
+ type: 'POST',
53
+ dataType: 'json',
54
+ data: {
55
+ action: 'aam',
56
+ sub_action: 'migrate',
57
+ step: this.steps[index].action,
58
+ _ajax_nonce: aamMigrateLocal.nonce
59
+ },
60
+ success: function(response) {
61
+ if (response.status === 'success') {
62
+ if (parseInt(response.stop) === 1) {
63
+ _this.completeStep(index);
64
+ _this.activateStep(index + 1);
65
+ } else {
66
+ _this.sendRequest(index);
67
+ }
68
+ } else {
69
+ _this.failedStep(index);
70
+ }
71
+ },
72
+ error: function() {
73
+ _this.failedStep(index);
74
+ }
75
+ });
76
+ };
77
+
78
+
79
+ jQuery(document).ready(function() {
80
+ jQuery('#aam_migrate').bind('click', function() {
81
+ var holder = jQuery('<div/>', {'class': 'migration-dialog'});
82
+ //add header
83
+ jQuery(holder).append(jQuery('<div/>', {
84
+ 'class': 'migration-header'
85
+ }).html('Migration Process Status'));
86
+ //add notice
87
+ jQuery(holder).append(jQuery('<div/>', {
88
+ 'class': 'migration-notice'
89
+ }).html('Warning! Please take a minute to read about migration process. <a href="http://wpaam.com/forum/viewtopic.php?f=2&t=20" target="_blank">Read more</a>'));
90
+ jQuery(holder).append(jQuery('<div/>', {
91
+ 'class': 'migration-notice'
92
+ }).html('Please do not reload the page until process is complete! <a href="#" id="start_migration">Start the Migration</a> or <a href="#" id="dont_bother">No Thank you</a>'));
93
+
94
+ //add migration steps
95
+ var step_holder = jQuery('<div/>', {'class': 'migration-steps'});
96
+ jQuery(step_holder).append(jQuery('<div/>', {
97
+ 'class': 'migration-step migration-step-pending',
98
+ 'id': 'aam_collect_data'
99
+ }).html('Collecting AAM Data'));
100
+ jQuery(step_holder).append(jQuery('<div/>', {
101
+ 'class': 'migration-step migration-step-pending',
102
+ 'id': 'aam_migrating'
103
+ }).html('Migrating Settings'));
104
+ jQuery(step_holder).append(jQuery('<div/>', {
105
+ 'class': 'migration-step migration-step-pending',
106
+ 'id': 'aam_cleanup'
107
+ }).html('Migration Clean-up'));
108
+ jQuery(step_holder).append(jQuery('<div/>', {
109
+ 'class': 'migration-step migration-step-pending',
110
+ 'id': 'aam_migration_complete'
111
+ }).html('Migration Completed (You can Reload the Page)'));
112
+
113
+ jQuery(holder).append(step_holder);
114
+
115
+ jQuery('body').append(holder);
116
+
117
+ jQuery('#start_migration').bind('click', function(event) {
118
+ event.preventDefault();
119
+ migration.run();
120
+ });
121
+
122
+ jQuery('#dont_bother').bind('click', function(event) {
123
+ event.preventDefault();
124
+ jQuery.ajax(aamMigrateLocal.ajaxurl, {
125
+ type: 'POST',
126
+ dataType: 'json',
127
+ data: {
128
+ action: 'aam',
129
+ sub_action: 'migrate',
130
+ step: 'complete',
131
+ _ajax_nonce: aamMigrateLocal.nonce
132
+ },
133
+ success: function(response) {
134
+ if (response.status === 'success') {
135
+ location.reload();
136
+ }
137
+ },
138
+ error: function() {
139
+ alert('Failed to Update Database');
140
+ }
141
+ });
142
+ });
143
+
144
+ //run the migration process
145
+ var migration = new aamMigration();
146
+ });
147
+ });
media/js/properties.js ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CodeMirror.defineMode("properties", function() {
2
+ return {
3
+ token: function(stream, state) {
4
+ var sol = stream.sol() || state.afterSection;
5
+ var eol = stream.eol();
6
+
7
+ state.afterSection = false;
8
+
9
+ if (sol) {
10
+ if (state.nextMultiline) {
11
+ state.inMultiline = true;
12
+ state.nextMultiline = false;
13
+ } else {
14
+ state.position = "def";
15
+ }
16
+ }
17
+
18
+ if (eol && !state.nextMultiline) {
19
+ state.inMultiline = false;
20
+ state.position = "def";
21
+ }
22
+
23
+ if (sol) {
24
+ while (stream.eatSpace())
25
+ ;
26
+ }
27
+
28
+ var ch = stream.next();
29
+
30
+ if (sol && (ch === "#" || ch === "!" || ch === ";")) {
31
+ state.position = "comment";
32
+ stream.skipToEnd();
33
+ return "comment";
34
+ } else if (sol && ch === "[") {
35
+ state.afterSection = true;
36
+ stream.skipTo("]");
37
+ stream.eat("]");
38
+ return "header";
39
+ } else if (ch === "=" || ch === ":") {
40
+ state.position = "quote";
41
+ return null;
42
+ } else if (ch === "\\" && state.position === "quote") {
43
+ if (stream.next() !== "u") { // u = Unicode sequence \u1234
44
+ // Multiline value
45
+ state.nextMultiline = true;
46
+ }
47
+ }
48
+
49
+ return state.position;
50
+ },
51
+ startState: function() {
52
+ return {
53
+ position: "def", // Current position, "def", "quote" or "comment"
54
+ nextMultiline: false, // Is the next line multiline value
55
+ inMultiline: false, // Is the current line a multiline value
56
+ afterSection: false // Did we just open a section
57
+ };
58
+ }
59
+
60
+ };
61
+ });
62
+
63
+ CodeMirror.defineMIME("text/x-properties", "properties");
64
+ CodeMirror.defineMIME("text/x-ini", "properties");
module/class-module_filtermenu.php DELETED
@@ -1,174 +0,0 @@
1
- <?php
2
-
3
- /*
4
- Copyright (C) <2011> Vasyl Martyniuk <martyniuk.vasyl@gmail.com>
5
-
6
- This program is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- This program is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU General Public License for more details.
15
-
16
- You should have received a copy of the GNU General Public License
17
- along with this program. If not, see <http://www.gnu.org/licenses/>.
18
-
19
- */
20
-
21
- class module_filterMenu extends module_User {
22
-
23
- private $cParams;
24
-
25
- function __construct() {
26
-
27
- parent::__construct();
28
-
29
- $this->cParams = get_option(WPACCESS_PREFIX . 'options');
30
- }
31
-
32
- function manage() {
33
- global $menu, $submenu;
34
-
35
- $userRoles = $this->getCurrentUserRole();
36
- if (is_array($userRoles)) {
37
- foreach ($userRoles as $role) {
38
- if (is_array($this->cParams[$role]['menu'])) {
39
- foreach ($this->cParams[$role]['menu'] as $main => $data) {
40
- if ($data['whole'] == 1) {
41
- $this->unsetMainMenuItem($main);
42
- } elseif (is_array($data['sub'])) {
43
- foreach ($data['sub'] as $sub => $dummy) {
44
- $this->unsetSubMenuItem($main, $sub);
45
- }
46
- }
47
- }
48
- }
49
- }
50
- } else {
51
- wp_die('You are not authorized to view this page');
52
- }
53
- }
54
-
55
- function checkAccess($requestedMenu) {
56
-
57
- $userRoles = $this->getCurrentUserRole();
58
-
59
- if (is_array($userRoles)) {
60
- foreach ($userRoles as $role) {
61
- if ($role == 'administrator') {
62
- return TRUE;
63
- }
64
-
65
- if (is_array($this->cParams[$role]['menu'])) {
66
- foreach ($this->cParams[$role]['menu'] as $menu => $sub) {
67
- if (($sub['whole']) == 1 && ($this->compareMenus($requestedMenu, $menu))) {
68
- return FALSE;
69
- }
70
-
71
- if (is_array($sub['sub'])) {
72
- foreach ($sub['sub'] as $subMenu => $dummy) {
73
- if ($this->compareMenus($requestedMenu, $subMenu)) {
74
- return FALSE;
75
- }
76
- }
77
- }
78
- }
79
- }
80
- }
81
- }
82
-
83
- return TRUE;
84
- }
85
-
86
- function compareMenus($requestedMenu, $menu) {
87
- $result = FALSE;
88
-
89
- $parts = preg_split('/\?/', $menu);
90
- if (count($parts) == 2) {
91
- $params = preg_split('/&/', $parts[1]);
92
- if (is_array($params) && (strpos($requestedMenu, $parts[0]) !== FALSE)) {
93
- foreach ($params as $param) {
94
- if (strpos($requestedMenu, $param) !== FALSE) {
95
- $result = TRUE;
96
- break;
97
- }
98
- }
99
- }
100
- } else {
101
- if (strpos($requestedMenu, $parts[0]) !== FALSE) {
102
- $result = TRUE;
103
- }
104
- //TODO - Emergency solution
105
- if (isset($_REQUEST['post_type']) && ($_REQUEST['post_type'] != 'post')
106
- && in_array($menu, array('edit.php', 'post-new.php'))) {
107
- $result = FALSE;
108
- }
109
- }
110
-
111
- return $result;
112
- }
113
-
114
- /*
115
- function _compareMenus($requestedMenu, $menu) {
116
- $result = FALSE;
117
-
118
- $parts = preg_split('/\?/', $menu);
119
- if (count($parts) == 2) {
120
- $params = preg_split('/&/', $parts[1]);
121
-