cardboard_cms 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (360) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +42 -0
  5. data/Gemfile.lock +324 -0
  6. data/Guardfile +23 -0
  7. data/LICENSE.txt +677 -0
  8. data/README.md +370 -0
  9. data/Rakefile +23 -0
  10. data/app/assets/images/cardboard/.gitkeep +0 -0
  11. data/app/assets/images/cardboard/bg.png +0 -0
  12. data/app/assets/images/cardboard/calendar.png +0 -0
  13. data/app/assets/images/cardboard/lorem-ipsum-coffe-mug.jpg +0 -0
  14. data/app/assets/javascripts/cardboard.js +1 -0
  15. data/app/assets/javascripts/cardboard/admin.js +62 -0
  16. data/app/assets/javascripts/cardboard/content_sidebar.js +27 -0
  17. data/app/assets/javascripts/cardboard/datepicker.js +19 -0
  18. data/app/assets/javascripts/cardboard/main_sidebar.js +32 -0
  19. data/app/assets/javascripts/cardboard/rich_text.js +81 -0
  20. data/app/assets/javascripts/cardboard/search_filter.js +28 -0
  21. data/app/assets/stylesheets/cardboard.css.scss +2 -0
  22. data/app/assets/stylesheets/cardboard/_bootstrap-select.css.scss +183 -0
  23. data/app/assets/stylesheets/cardboard/_content.css.scss +35 -0
  24. data/app/assets/stylesheets/cardboard/_content_sidebar.css.scss +96 -0
  25. data/app/assets/stylesheets/cardboard/_framework.css.scss +129 -0
  26. data/app/assets/stylesheets/cardboard/_main_sidebar.css.scss +38 -0
  27. data/app/assets/stylesheets/cardboard/_main_topbar.css.scss +62 -0
  28. data/app/assets/stylesheets/cardboard/_resources.css.scss +28 -0
  29. data/app/assets/stylesheets/cardboard/_rich_text.css.scss +6 -0
  30. data/app/assets/stylesheets/cardboard/_variables.scss +326 -0
  31. data/app/assets/stylesheets/cardboard/admin.css.scss +63 -0
  32. data/app/controllers/cardboard/application_controller.rb +45 -0
  33. data/app/controllers/cardboard/dashboard_controller.rb +9 -0
  34. data/app/controllers/cardboard/my_account_controller.rb +27 -0
  35. data/app/controllers/cardboard/pages_controller.rb +34 -0
  36. data/app/controllers/cardboard/resource_controller.rb +61 -0
  37. data/app/controllers/cardboard/settings_controller.rb +28 -0
  38. data/app/controllers/cardboard/super_user_controller.rb +8 -0
  39. data/app/controllers/pages_controller.rb +29 -0
  40. data/app/decorators/controllers/application_controller_decorator.rb +9 -0
  41. data/app/decorators/lib/cardboard/user_class_decorator.rb +32 -0
  42. data/app/helpers/cardboard/application_helper.rb +4 -0
  43. data/app/helpers/cardboard/public_helper.rb +53 -0
  44. data/app/helpers/cardboard/resource_helper.rb +80 -0
  45. data/app/inputs/date_picker_input.rb +10 -0
  46. data/app/inputs/date_time_input.rb +7 -0
  47. data/app/inputs/image_input.rb +3 -0
  48. data/app/inputs/rich_text_input.rb +6 -0
  49. data/app/models/cardboard/field.rb +67 -0
  50. data/app/models/cardboard/field/boolean.rb +29 -0
  51. data/app/models/cardboard/field/date.rb +24 -0
  52. data/app/models/cardboard/field/decimal.rb +25 -0
  53. data/app/models/cardboard/field/external_link.rb +4 -0
  54. data/app/models/cardboard/field/file.rb +19 -0
  55. data/app/models/cardboard/field/image.rb +33 -0
  56. data/app/models/cardboard/field/integer.rb +26 -0
  57. data/app/models/cardboard/field/resource_link.rb +4 -0
  58. data/app/models/cardboard/field/rich_text.rb +21 -0
  59. data/app/models/cardboard/field/string.rb +16 -0
  60. data/app/models/cardboard/field/text.rb +15 -0
  61. data/app/models/cardboard/page.rb +253 -0
  62. data/app/models/cardboard/page_part.rb +79 -0
  63. data/app/models/cardboard/setting.rb +46 -0
  64. data/app/views/cardboard/dashboard/index.html.slim +1 -0
  65. data/app/views/cardboard/fields/_base_input.html.slim +1 -0
  66. data/app/views/cardboard/fields/_boolean.html.slim +4 -0
  67. data/app/views/cardboard/fields/_date.html.slim +1 -0
  68. data/app/views/cardboard/fields/_external_link.html.slim +2 -0
  69. data/app/views/cardboard/fields/_file.html.slim +12 -0
  70. data/app/views/cardboard/fields/_image.html.slim +11 -0
  71. data/app/views/cardboard/fields/_resource_link.html.slim +2 -0
  72. data/app/views/cardboard/fields/_rich_text.html.slim +3 -0
  73. data/app/views/cardboard/fields/_string.html.slim +1 -0
  74. data/app/views/cardboard/my_account/edit.html.slim +29 -0
  75. data/app/views/cardboard/pages/_error.html.slim +7 -0
  76. data/app/views/cardboard/pages/_seo.html.slim +6 -0
  77. data/app/views/cardboard/pages/_sidebar.html.slim +17 -0
  78. data/app/views/cardboard/pages/_subpart_fields.html.slim +20 -0
  79. data/app/views/cardboard/pages/_url_field.html.slim +20 -0
  80. data/app/views/cardboard/pages/edit.html.slim +43 -0
  81. data/app/views/cardboard/pages/index.html.slim +2 -0
  82. data/app/views/cardboard/pages/show.html.slim +9 -0
  83. data/app/views/cardboard/resources/_advanced_search.html.slim +40 -0
  84. data/app/views/cardboard/resources/_search_button.html.slim +2 -0
  85. data/app/views/cardboard/resources/_search_helper.html.slim +17 -0
  86. data/app/views/cardboard/resources/_simple_search.html.slim +6 -0
  87. data/app/views/cardboard/rich_editor/_links_modal.html.slim +39 -0
  88. data/app/views/cardboard/settings/index.html.slim +8 -0
  89. data/app/views/cardboard/super_user/index.html.slim +10 -0
  90. data/app/views/layouts/cardboard/_flash_message.html.slim +6 -0
  91. data/app/views/layouts/cardboard/_head.html.slim +16 -0
  92. data/app/views/layouts/cardboard/_main_sidebar.html.slim +12 -0
  93. data/app/views/layouts/cardboard/_main_topbar.html.slim +32 -0
  94. data/app/views/layouts/cardboard/application.html.slim +28 -0
  95. data/cardboard.gemspec +57 -0
  96. data/config/initializers/dragonfly.rb +27 -0
  97. data/config/initializers/ranker_mapper_finder_bugfix.rb +43 -0
  98. data/config/initializers/simple_form.rb +142 -0
  99. data/config/initializers/simple_form_bootstrap.rb +45 -0
  100. data/config/locales/simple_form.en.yml +26 -0
  101. data/config/routes.rb +53 -0
  102. data/doc/apple-touch-icon.png +0 -0
  103. data/doc/classes/Cardboard.html +190 -0
  104. data/doc/classes/Cardboard/AdminController.html +134 -0
  105. data/doc/classes/Cardboard/AdminHelper.html +307 -0
  106. data/doc/classes/Cardboard/ApplicationController.html +76 -0
  107. data/doc/classes/Cardboard/ApplicationHelper.html +70 -0
  108. data/doc/classes/Cardboard/DashboardController.html +131 -0
  109. data/doc/classes/Cardboard/Field.html +283 -0
  110. data/doc/classes/Cardboard/Field/Boolean.html +218 -0
  111. data/doc/classes/Cardboard/Field/Date.html +218 -0
  112. data/doc/classes/Cardboard/Field/Decimal.html +218 -0
  113. data/doc/classes/Cardboard/Field/ExternalLink.html +76 -0
  114. data/doc/classes/Cardboard/Field/File.html +131 -0
  115. data/doc/classes/Cardboard/Field/Image.html +181 -0
  116. data/doc/classes/Cardboard/Field/Integer.html +218 -0
  117. data/doc/classes/Cardboard/Field/ResourceLink.html +76 -0
  118. data/doc/classes/Cardboard/Field/RichText.html +131 -0
  119. data/doc/classes/Cardboard/Field/String.html +131 -0
  120. data/doc/classes/Cardboard/Page.html +1184 -0
  121. data/doc/classes/Cardboard/PagePart.html +304 -0
  122. data/doc/classes/Cardboard/PagesController.html +186 -0
  123. data/doc/classes/Cardboard/PublicHelper.html +252 -0
  124. data/doc/classes/Cardboard/Setting.html +240 -0
  125. data/doc/classes/Cardboard/SettingsController.html +184 -0
  126. data/doc/classes/Cardboard/SuperUserController.html +130 -0
  127. data/doc/classes/Cardboard/UsersController.html +191 -0
  128. data/doc/classes/DatePickerInput.html +132 -0
  129. data/doc/classes/ImageInput.html +76 -0
  130. data/doc/classes/Object.html +211 -0
  131. data/doc/classes/PagesController.html +145 -0
  132. data/doc/classes/RichTextInput.html +132 -0
  133. data/doc/created.rid +31 -0
  134. data/doc/css/github.css +129 -0
  135. data/doc/css/main.css +333 -0
  136. data/doc/css/panel.css +384 -0
  137. data/doc/css/reset.css +48 -0
  138. data/doc/favicon.ico +0 -0
  139. data/doc/files/app/controllers/cardboard/admin_controller_rb.html +79 -0
  140. data/doc/files/app/controllers/cardboard/application_controller_rb.html +84 -0
  141. data/doc/files/app/controllers/cardboard/dashboard_controller_rb.html +84 -0
  142. data/doc/files/app/controllers/cardboard/pages_controller_rb.html +84 -0
  143. data/doc/files/app/controllers/cardboard/settings_controller_rb.html +84 -0
  144. data/doc/files/app/controllers/cardboard/super_user_controller_rb.html +84 -0
  145. data/doc/files/app/controllers/cardboard/users_controller_rb.html +84 -0
  146. data/doc/files/app/controllers/pages_controller_rb.html +79 -0
  147. data/doc/files/app/decorators/controllers/application_controller_decorator_rb.html +68 -0
  148. data/doc/files/app/decorators/lib/cardboard/user_class_decorator_rb.html +68 -0
  149. data/doc/files/app/helpers/cardboard/admin_helper_rb.html +84 -0
  150. data/doc/files/app/helpers/cardboard/application_helper_rb.html +84 -0
  151. data/doc/files/app/helpers/cardboard/public_helper_rb.html +84 -0
  152. data/doc/files/app/inputs/date_picker_input_rb.html +79 -0
  153. data/doc/files/app/inputs/image_input_rb.html +79 -0
  154. data/doc/files/app/inputs/rich_text_input_rb.html +79 -0
  155. data/doc/files/app/models/cardboard/field/boolean_rb.html +84 -0
  156. data/doc/files/app/models/cardboard/field/date_rb.html +84 -0
  157. data/doc/files/app/models/cardboard/field/decimal_rb.html +84 -0
  158. data/doc/files/app/models/cardboard/field/external_link_rb.html +84 -0
  159. data/doc/files/app/models/cardboard/field/file_rb.html +84 -0
  160. data/doc/files/app/models/cardboard/field/image_rb.html +84 -0
  161. data/doc/files/app/models/cardboard/field/integer_rb.html +84 -0
  162. data/doc/files/app/models/cardboard/field/resource_link_rb.html +84 -0
  163. data/doc/files/app/models/cardboard/field/rich_text_rb.html +84 -0
  164. data/doc/files/app/models/cardboard/field/string_rb.html +84 -0
  165. data/doc/files/app/models/cardboard/field_rb.html +84 -0
  166. data/doc/files/app/models/cardboard/page_part_rb.html +84 -0
  167. data/doc/files/app/models/cardboard/page_rb.html +84 -0
  168. data/doc/files/app/models/cardboard/setting_rb.html +84 -0
  169. data/doc/i/arrows.png +0 -0
  170. data/doc/i/results_bg.png +0 -0
  171. data/doc/i/tree_bg.png +0 -0
  172. data/doc/index.html +13 -0
  173. data/doc/js/highlight.pack.js +1 -0
  174. data/doc/js/jquery-1.3.2.min.js +19 -0
  175. data/doc/js/jquery-effect.js +593 -0
  176. data/doc/js/main.js +24 -0
  177. data/doc/js/navigation.js +142 -0
  178. data/doc/js/search_index.js +1 -0
  179. data/doc/js/searchdoc.js +449 -0
  180. data/doc/js/searcher.js +228 -0
  181. data/doc/panel/index.html +73 -0
  182. data/doc/panel/links.html +66 -0
  183. data/doc/panel/tree.js +1 -0
  184. data/lib/cardboard/application.rb +67 -0
  185. data/lib/cardboard/engine.rb +83 -0
  186. data/lib/cardboard/helpers/seed.rb +80 -0
  187. data/lib/cardboard/helpers/settings.rb +58 -0
  188. data/lib/cardboard/version.rb +3 -0
  189. data/lib/cardboard_cms.rb +34 -0
  190. data/lib/generators/cardboard/assets/assets_generator.rb +18 -0
  191. data/lib/generators/cardboard/install/install_generator.rb +96 -0
  192. data/lib/generators/cardboard/install/templates/cardboard.rb.erb +53 -0
  193. data/lib/generators/cardboard/install/templates/cardboard.yml +29 -0
  194. data/lib/generators/cardboard/install/templates/index.html.erb +0 -0
  195. data/lib/generators/cardboard/install/templates/migrations/1_create_cardboard_fields.rb +21 -0
  196. data/lib/generators/cardboard/install/templates/migrations/2_create_cardboard_page_parts.rb +17 -0
  197. data/lib/generators/cardboard/install/templates/migrations/3_create_cardboard_pages.rb +18 -0
  198. data/lib/generators/cardboard/install/templates/migrations/4_create_cardboard_settings.rb +14 -0
  199. data/lib/generators/cardboard/resource/resource_generator.rb +52 -0
  200. data/lib/generators/cardboard/resource/templates/admin_controller.rb +9 -0
  201. data/lib/generators/cardboard/resource/templates/slim/_fields.html.slim +5 -0
  202. data/lib/generators/cardboard/resource/templates/slim/edit.html.slim +4 -0
  203. data/lib/generators/cardboard/resource/templates/slim/index.html.slim +18 -0
  204. data/lib/generators/cardboard/resource/templates/slim/new.html.slim +4 -0
  205. data/lib/tasks/cardboard_tasks.rake +22 -0
  206. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  207. data/script/rails +8 -0
  208. data/test/dummy/README.rdoc +261 -0
  209. data/test/dummy/Rakefile +7 -0
  210. data/test/dummy/app/assets/images/defaults/CrashTest.jpg +0 -0
  211. data/test/dummy/app/assets/javascripts/admins.js +2 -0
  212. data/test/dummy/app/assets/javascripts/application.js +5 -0
  213. data/test/dummy/app/assets/javascripts/beans.js +2 -0
  214. data/test/dummy/app/assets/javascripts/cardboard.js +1 -0
  215. data/test/dummy/app/assets/javascripts/icescreams.js +2 -0
  216. data/test/dummy/app/assets/javascripts/main.js +2 -0
  217. data/test/dummy/app/assets/javascripts/news_posts.js +2 -0
  218. data/test/dummy/app/assets/javascripts/pianos.js +2 -0
  219. data/test/dummy/app/assets/stylesheets/admins.css.scss +3 -0
  220. data/test/dummy/app/assets/stylesheets/application.css.scss +9 -0
  221. data/test/dummy/app/assets/stylesheets/beans.css.scss +3 -0
  222. data/test/dummy/app/assets/stylesheets/cardboard.css.scss +5 -0
  223. data/test/dummy/app/assets/stylesheets/icescreams.css.scss +3 -0
  224. data/test/dummy/app/assets/stylesheets/main.css +4 -0
  225. data/test/dummy/app/assets/stylesheets/news_posts.css.scss +3 -0
  226. data/test/dummy/app/assets/stylesheets/pianos.css.scss +3 -0
  227. data/test/dummy/app/assets/stylesheets/scaffolds.css.scss +69 -0
  228. data/test/dummy/app/controllers/application_controller.rb +3 -0
  229. data/test/dummy/app/controllers/cardboard/pianos_controller.rb +6 -0
  230. data/test/dummy/app/controllers/pianos_controller.rb +83 -0
  231. data/test/dummy/app/helpers/application_helper.rb +9 -0
  232. data/test/dummy/app/helpers/cardboard/pianos_helper.rb +7 -0
  233. data/test/dummy/app/mailers/.gitkeep +0 -0
  234. data/test/dummy/app/models/.gitkeep +0 -0
  235. data/test/dummy/app/models/admin_user.rb +28 -0
  236. data/test/dummy/app/models/piano.rb +3 -0
  237. data/test/dummy/app/views/cardboard/pianos/_fields.html.slim +5 -0
  238. data/test/dummy/app/views/cardboard/pianos/edit.html.slim +6 -0
  239. data/test/dummy/app/views/cardboard/pianos/index.html.slim +18 -0
  240. data/test/dummy/app/views/cardboard/pianos/new.html.slim +6 -0
  241. data/test/dummy/app/views/cardboard/pianos/show.html.slim +11 -0
  242. data/test/dummy/app/views/layouts/application.html.slim +24 -0
  243. data/test/dummy/app/views/main/index.html.slim +1 -0
  244. data/test/dummy/app/views/pages/about-us.html.slim +1 -0
  245. data/test/dummy/app/views/pages/home.html.slim +3 -0
  246. data/test/dummy/app/views/pianos/_form.html.erb +25 -0
  247. data/test/dummy/app/views/pianos/edit.html.erb +6 -0
  248. data/test/dummy/app/views/pianos/index.html.erb +25 -0
  249. data/test/dummy/app/views/pianos/new.html.erb +5 -0
  250. data/test/dummy/app/views/pianos/show.html.erb +15 -0
  251. data/test/dummy/config.ru +4 -0
  252. data/test/dummy/config/application.rb +50 -0
  253. data/test/dummy/config/boot.rb +10 -0
  254. data/test/dummy/config/cardboard.yml +126 -0
  255. data/test/dummy/config/database.yml +17 -0
  256. data/test/dummy/config/environment.rb +5 -0
  257. data/test/dummy/config/environments/development.rb +24 -0
  258. data/test/dummy/config/environments/production.rb +70 -0
  259. data/test/dummy/config/environments/test.rb +33 -0
  260. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  261. data/test/dummy/config/initializers/cardboard.rb +53 -0
  262. data/test/dummy/config/initializers/devise.rb +240 -0
  263. data/test/dummy/config/initializers/inflections.rb +15 -0
  264. data/test/dummy/config/initializers/mime_types.rb +5 -0
  265. data/test/dummy/config/initializers/secret_token.rb +8 -0
  266. data/test/dummy/config/initializers/session_store.rb +8 -0
  267. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  268. data/test/dummy/config/locales/devise.en.yml +59 -0
  269. data/test/dummy/config/locales/en.yml +5 -0
  270. data/test/dummy/config/routes.rb +16 -0
  271. data/test/dummy/db/migrate/20130403142235_create_pianos.rb +10 -0
  272. data/test/dummy/db/migrate/20130417134832_add_devise_to_admin_users.rb +53 -0
  273. data/test/dummy/db/migrate/20130426021522_create_news_posts.rb +10 -0
  274. data/test/dummy/db/migrate/20130501195423_create_icescreams.rb +10 -0
  275. data/test/dummy/db/migrate/20130502165540_create_beans.rb +12 -0
  276. data/test/dummy/db/migrate/20130522151358_create_cardboard_fields.rb +21 -0
  277. data/test/dummy/db/migrate/20130522151359_create_cardboard_page_parts.rb +17 -0
  278. data/test/dummy/db/migrate/20130522151400_create_cardboard_pages.rb +18 -0
  279. data/test/dummy/db/migrate/20130522151401_create_cardboard_settings.rb +14 -0
  280. data/test/dummy/db/migrate/20130607132558_create_admins.rb +9 -0
  281. data/test/dummy/db/schema.rb +129 -0
  282. data/test/dummy/db/seeds.rb +2 -0
  283. data/test/dummy/lib/assets/.gitkeep +0 -0
  284. data/test/dummy/log/.gitkeep +0 -0
  285. data/test/dummy/public/404.html +26 -0
  286. data/test/dummy/public/422.html +26 -0
  287. data/test/dummy/public/500.html +25 -0
  288. data/test/dummy/public/favicon.ico +0 -0
  289. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_10_816_404_no_file.png +0 -0
  290. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_10_816_404_no_file.png.meta +2 -0
  291. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_17_87_404_no_file.png +0 -0
  292. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_17_87_404_no_file.png.meta +2 -0
  293. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_34_680_404_no_file.png +0 -0
  294. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_34_680_404_no_file.png.meta +2 -0
  295. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_44_00_698_404_no_file.png +0 -0
  296. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_44_00_698_404_no_file.png.meta +2 -0
  297. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_46_49_55_6152message_in_a_bottle.jpeg +0 -0
  298. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_46_49_55_6152message_in_a_bottle.jpeg.meta +2 -0
  299. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_10_30_773_404_no_file.png +0 -0
  300. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_10_30_773_404_no_file.png.meta +2 -0
  301. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_10_38_856_airport_shuttles_20130207_1647.csv +8 -0
  302. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_10_38_856_airport_shuttles_20130207_1647.csv.meta +2 -0
  303. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_12_12_144_1361696555_GMail_Android_R.png +0 -0
  304. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_12_12_144_1361696555_GMail_Android_R.png.meta +2 -0
  305. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_16_40_989_404_no_file.png +0 -0
  306. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_16_40_989_404_no_file.png.meta +2 -0
  307. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_19_19_40_6152message_in_a_bottle.jpeg +0 -0
  308. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_19_19_40_6152message_in_a_bottle.jpeg.meta +2 -0
  309. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_21_21_825_6152message_in_a_bottle.jpeg +0 -0
  310. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_21_21_825_6152message_in_a_bottle.jpeg.meta +2 -0
  311. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_46_33_341_bio.jpg +0 -0
  312. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_46_33_341_bio.jpg.meta +2 -0
  313. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_52_55_892_404_no_file.png +0 -0
  314. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_52_55_892_404_no_file.png.meta +2 -0
  315. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_52_56_30_404_no_file.png +0 -0
  316. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_52_56_30_404_no_file.png.meta +2 -0
  317. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_24_04_585_Sky_3920445.jpg +0 -0
  318. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_24_04_585_Sky_3920445.jpg.meta +2 -0
  319. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_25_41_111_Sky_3920445.jpg +0 -0
  320. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_25_41_111_Sky_3920445.jpg.meta +2 -0
  321. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_27_16_937_Sky_3920445.jpg +0 -0
  322. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_27_16_937_Sky_3920445.jpg.meta +2 -0
  323. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_27_57_585_Sky_3920445.jpg +0 -0
  324. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_27_57_585_Sky_3920445.jpg.meta +2 -0
  325. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_28_24_991_Sky_3920445.jpg +0 -0
  326. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_28_24_991_Sky_3920445.jpg.meta +2 -0
  327. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_33_30_610_Sky_3920445.jpg +0 -0
  328. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_33_30_610_Sky_3920445.jpg.meta +2 -0
  329. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_35_18_437_Sky_3920445.jpg +0 -0
  330. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_35_18_437_Sky_3920445.jpg.meta +2 -0
  331. data/test/dummy/public/system/dragonfly/development/2013/04/17/16_45_07_162_Vehicle_Types.jpg +0 -0
  332. data/test/dummy/public/system/dragonfly/development/2013/04/17/16_45_07_162_Vehicle_Types.jpg.meta +2 -0
  333. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_27_35_733_hall.jpg +0 -0
  334. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_27_35_733_hall.jpg.meta +2 -0
  335. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_29_15_808_fluidicon.png +0 -0
  336. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_29_15_808_fluidicon.png.meta +2 -0
  337. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_29_15_989_fluidicon.png +0 -0
  338. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_29_15_989_fluidicon.png.meta +2 -0
  339. data/test/dummy/public/system/dragonfly/development/2013/04/19/09_54_44_881_hall3.jpg +0 -0
  340. data/test/dummy/public/system/dragonfly/development/2013/04/19/09_54_44_881_hall3.jpg.meta +2 -0
  341. data/test/dummy/public/system/dragonfly/development/2013/04/19/09_54_45_450_hall3.jpg +0 -0
  342. data/test/dummy/public/system/dragonfly/development/2013/04/19/09_54_45_450_hall3.jpg.meta +2 -0
  343. data/test/dummy/script/rails +6 -0
  344. data/test/dummy/test/fixtures/admins.yml +7 -0
  345. data/test/dummy/test/functional/admins_controller_test.rb +49 -0
  346. data/test/dummy/test/unit/admin_test.rb +7 -0
  347. data/test/dummy/test/unit/helpers/admins_helper_test.rb +4 -0
  348. data/test/factories.rb +47 -0
  349. data/test/integration/page_editing_test.rb +77 -0
  350. data/test/integration/seeding_test.rb +96 -0
  351. data/test/models/field_test.rb +102 -0
  352. data/test/models/page_test.rb +105 -0
  353. data/test/test_helper.rb +40 -0
  354. data/vendor/assets/javascripts/cardboard/bootstrap-select.js +590 -0
  355. data/vendor/assets/javascripts/cardboard/jquery.livesearch.js +48 -0
  356. data/vendor/assets/javascripts/cardboard/jquery.pjax.js +822 -0
  357. data/vendor/assets/javascripts/cardboard/jquery.wysihtml5_size_matters.js.coffee +44 -0
  358. data/vendor/assets/javascripts/cardboard/jquery.wysihtml5imgresizer.js +320 -0
  359. data/vendor/assets/javascripts/cardboard/wysihtml5-0.4.0pre.js +9579 -0
  360. metadata +1011 -0
@@ -0,0 +1,10 @@
1
+ class DatePickerInput < SimpleForm::Inputs::StringInput
2
+ def input
3
+ input_html_options[:class] |= ["datepicker"]
4
+ input_html_options[:type] = "text"
5
+ super
6
+ end
7
+
8
+ end
9
+
10
+
@@ -0,0 +1,7 @@
1
+ class DateTimeInput < SimpleForm::Inputs::DateTimeInput
2
+ def input
3
+ # added for http://silviomoreto.github.io/bootstrap-select/
4
+ input_html_options["data-width"] = "auto"
5
+ super
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ class ImageInput < SimpleForm::Inputs::FileInput
2
+ #image is a file input, just makes code cleaner
3
+ end
@@ -0,0 +1,6 @@
1
+ class RichTextInput < SimpleForm::Inputs::TextInput
2
+ def input
3
+ input_html_options[:class] += [:wysihtml5]
4
+ @builder.text_area(attribute_name, input_html_options)
5
+ end
6
+ end
@@ -0,0 +1,67 @@
1
+ module Cardboard
2
+ class Field < ActiveRecord::Base
3
+ attr_accessor :seeding, :default
4
+ alias_attribute :value, :value_uid
5
+
6
+ belongs_to :object_with_field, :polymorphic => true, :inverse_of => :fields
7
+
8
+ #gem
9
+ include RankedModel
10
+ ranks :position, :with_same => [:object_with_field_id, :object_with_field_type], :class_name => 'Cardboard::Field'
11
+
12
+ #validations
13
+ validates :identifier, :type, presence:true
14
+ validates :identifier, uniqueness: {:case_sensitive => false, :scope => [:object_with_field_id, :object_with_field_type]},
15
+ :format => { :with => /\A[a-z\_0-9]+\z/,
16
+ :message => "Only downcase letters, numbers and underscores are allowed" }
17
+
18
+ default_scope {rank(:position)}
19
+
20
+ class << self
21
+ # Allow "type" to be passed in nested forms
22
+ def new_with_cast(*attributes, &block)
23
+ if (h = attributes.first).is_a?(Hash) && !h.nil? && (type = h.delete(:type) || h.delete('type')) && type.present? && (klass = type.constantize) != self
24
+ raise "Field type #{type} does not inherit from Cardboard::Field" unless klass <= self
25
+ return klass.new(*attributes, &block)
26
+ end
27
+ new_without_cast(*attributes, &block)
28
+ end
29
+ alias_method_chain :new, :cast
30
+ end
31
+
32
+ # overwritten setter
33
+ def type=(val)
34
+ return super if val =~ /^Cardboard::Field::/ || val.nil?
35
+ @_type = val.to_s.downcase
36
+ self[:type] = "Cardboard::Field::#{@_type.camelize}"
37
+ end
38
+ def type
39
+ @_type ||= self[:type].demodulize.underscore
40
+ end
41
+
42
+ def default
43
+ #overwritten for each subclass
44
+ end
45
+ def default=(val)
46
+ return unless self.value_uid.nil? && val.present?
47
+ if type == "image" || type == "file"
48
+ path = "app/assets/#{type.pluralize}/defaults/#{val}"
49
+ raise "File not found #{path}. Make sure to add your #{type} before seeding." unless ::File.exist?(Rails.root.join(path))
50
+ self.value_uid = path
51
+ else
52
+ self.value_uid = val
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def is_required
59
+ errors.add(:value, "is required") if required_field? && value_uid.blank?
60
+ end
61
+
62
+ def required_field?
63
+ self.required? && !self.seeding
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ module Cardboard
2
+ class Field::Boolean < Field
3
+ before_validation :convert_to_boolean
4
+
5
+ validate :is_boolean
6
+
7
+
8
+ def default
9
+ [true, false].sample
10
+ end
11
+
12
+ private
13
+
14
+ def is_boolean
15
+ errors.add(:value, "is not a valid boolean") if self.value.nil?
16
+ end
17
+
18
+ def convert_to_boolean
19
+ self.value = to_boolean(self.value_uid)
20
+ true # don't return a validation error on false
21
+ end
22
+
23
+ def to_boolean(val)
24
+ return true if val == true || !!(val =~ /(true|t|yes|y|1)$/i)
25
+ return false if val == false || val.blank? || !!(val =~ /(false|f|no|n|0)$/i)
26
+ return nil
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ module Cardboard
2
+ class Field::Date < Field
3
+ validate :is_required
4
+ validate :is_date
5
+
6
+ def value
7
+ Chronic.parse(value_uid)
8
+ end
9
+
10
+ def value=(val)
11
+ self.value_uid = val
12
+ end
13
+
14
+ def default
15
+ Time.now
16
+ end
17
+
18
+ private
19
+
20
+ def is_date
21
+ errors.add(:value, "not a recognized date format") if value_uid.present? && value.blank?
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ module Cardboard
2
+ class Field::Decimal < Field
3
+ validate :is_decimal
4
+ validate :is_required
5
+
6
+ def value=(val)
7
+ self.value_uid = val == "" ? nil : val #bug in rails? should work with allow_blank
8
+ end
9
+
10
+ def value
11
+ value_uid.to_f
12
+ end
13
+
14
+ def default
15
+ 234.23
16
+ end
17
+
18
+ private
19
+
20
+ def is_decimal
21
+ errors.add(:value, "is not a number") if value_uid.present? && value_uid.to_s =~ /([^\d\.]|\.{2,})/
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,4 @@
1
+ module Cardboard
2
+ class Field::ExternalLink < Field
3
+ end
4
+ end
@@ -0,0 +1,19 @@
1
+ module Cardboard
2
+ class Field::File < Field
3
+
4
+ dragonfly_accessor :value
5
+
6
+ validates_size_of :value, :maximum => 20.megabytes #20000.kilobytes #TODO: move size to gem settings
7
+ validate :is_required #for some reason this is different from image
8
+
9
+ def value
10
+ return nil unless value_uid
11
+ if value_uid =~ /^app\/assets\/files/
12
+ Dragonfly.app.fetch_file(value_uid)
13
+ else
14
+ Dragonfly.app.fetch(value_uid)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ module Cardboard
2
+ class Field::Image < Field
3
+
4
+ dragonfly_accessor :value do
5
+ after_assign :resize_image
6
+ end
7
+
8
+ validates_property :format, :of => :value, :in => ['jpeg', 'jpg', 'png', 'gif'], if: :value_uid?
9
+ validates_property :image?, :of => :value, :as => true, if: :value_uid?
10
+ validates :value, presence:true, :if => :required_field?
11
+
12
+ def value
13
+ return nil unless value_uid
14
+ if value_uid =~ /^app\/assets\/images/
15
+ Dragonfly.app.fetch_file(value_uid)
16
+ else
17
+ Dragonfly.app.fetch(value_uid)
18
+ end
19
+ end
20
+
21
+ def default
22
+ # Dragonfly.app.generate(:plasma, [400, 800].sample, 600)
23
+ Dragonfly.app.generate(:plain, [400, 800].sample, 600, :color => '#CCCCCC')
24
+ end
25
+
26
+ private
27
+
28
+ def resize_image
29
+ self.value.process!(:resize, '1920x1080>') if value_uid? #max image size
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module Cardboard
2
+ class Field::Integer < Field
3
+ validate :is_integer
4
+ validate :is_required
5
+
6
+
7
+ def value=(val)
8
+ self.value_uid = val == "" ? nil : val #bug in rails? should work with allow_blank
9
+ end
10
+
11
+ def value
12
+ self.value_uid.to_i
13
+ end
14
+
15
+ def default
16
+ 12321454
17
+ end
18
+
19
+ private
20
+
21
+ def is_integer
22
+ errors.add(:value, "is not a number") if value_uid.present? && value_uid.to_s =~ /[^\d]/
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ module Cardboard
2
+ class Field::ResourceLink < Field
3
+ end
4
+ end
@@ -0,0 +1,21 @@
1
+ module Cardboard
2
+ class Field::RichText < Field
3
+ validate :is_required
4
+ before_save :sanitize_value
5
+
6
+ def value
7
+ self.value_uid.try(:html_safe)
8
+ end
9
+
10
+ def default
11
+ "<div><p><strong>Lorem Ipsum</strong> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p></div>".html_safe
12
+ end
13
+
14
+ private
15
+
16
+ def sanitize_value
17
+ return nil unless value_changed?
18
+ self.value = ActionController::Base.helpers.sanitize(self.value, :tags => %w(strong b i u em br p div span ul ol li a pre code blockquote h1 h2 h3), :attributes => %w(class style href src width height alt))
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ module Cardboard
2
+ class Field::String < Field
3
+ validate :is_required
4
+ before_validation :truncate_long_string # validates :value, :length => { :maximum => 255 }
5
+
6
+ def default
7
+ "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur"
8
+ end
9
+
10
+ private
11
+
12
+ def truncate_long_string
13
+ self.value = self.value[0..254] if value
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Cardboard
2
+ class Field::Text < Field
3
+ validate :is_required
4
+
5
+ def value
6
+ return nil unless self.value_uid
7
+ self.value_uid.split(/\n/).map { |i| ERB::Util.html_escape(i) }.join("<br />").html_safe
8
+ end
9
+
10
+ def default
11
+ "What is Lorem Ipsum? Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,253 @@
1
+ module Cardboard
2
+ class Page < ActiveRecord::Base
3
+ has_many :parts, class_name: "Cardboard::PagePart", :dependent => :destroy, :validate => true
4
+
5
+ attr_accessor :parent_url, :is_root
6
+
7
+ accepts_nested_attributes_for :parts, allow_destroy: true, :reject_if => :all_blank
8
+ serialize :meta_seo, Hash
9
+ serialize :slugs_backup, Array
10
+
11
+ before_validation :default_values
12
+ before_save :update_slugs_backup
13
+
14
+ #gems
15
+ acts_as_url :title, :url_attribute => :slug, :scope => :path, only_when_blank: true
16
+
17
+ include RankedModel
18
+ ranks :position, :with_same => :path
19
+
20
+ #validations
21
+ validates :title, :path, presence:true
22
+ validates :slug, uniqueness: { :case_sensitive => false, :scope => :path }, presence: true
23
+ validates :identifier, uniqueness: {:case_sensitive => false}, :format => { :with => /\A[a-z\_0-9]+\z/,
24
+ :message => "Only downcase letters, numbers and underscores are allowed" }
25
+ #validate all seo keys are valid meta keys + title
26
+
27
+ # validates_associated :parts, on: :update #breaks seed, should work
28
+
29
+ #scopes
30
+ scope :preordered, -> {order("path ASC, position ASC, slug ASC")} #order("CASE slug WHEN '/' THEN 'slug, position' ELSE 'path, position, slug' END")
31
+
32
+ #class variables
33
+ after_commit do
34
+ Page.clear_arranged_pages
35
+ end
36
+
37
+ #overwritten setters/getters
38
+ def slug=(value)
39
+ # the user can overwrite the auto generated slug
40
+ self[:slug] = value.present? ? value.to_url : nil
41
+ end
42
+
43
+ def is_root=(val)
44
+ self.position_position = :first if val
45
+ end
46
+
47
+ def using_slug_backup?
48
+ @using_slug_backup || false
49
+ end
50
+
51
+ def using_slug_backup=(value)
52
+ @using_slug_backup = value
53
+ end
54
+
55
+ #class methods
56
+ def self.find_by_url(full_url)
57
+ return nil unless full_url
58
+ path, slug = self.path_and_slug(full_url)
59
+ page = self.where(path: path, slug: slug).first
60
+
61
+ if slug && page.nil?
62
+ #use arel instead of LIKE/ILIKE
63
+ page = self.where(path: path).where(self.arel_table[:slugs_backup].matches("% #{slug}\n%")).first
64
+ page.using_slug_backup = true if page
65
+ end
66
+
67
+ page
68
+ end
69
+
70
+ def self.root
71
+ # Homepage is the highest position in the root path
72
+ where(path: "/").rank(:position).first
73
+ end
74
+ def self.homepage; self.root; end
75
+
76
+ def root?
77
+ @root_id ||= Page.root.id
78
+ @root_id == self.id
79
+ end
80
+
81
+ #instance methods
82
+
83
+ # @page.get("slideshow.image1")
84
+ # @page.get("slideshow").first.image1
85
+ # @page.get("slideshow").each...
86
+
87
+ # slideshow = @page.get("slideshow")
88
+ # slideshow.field("image1")
89
+ # slideshow.each{|p| p.field("image")}
90
+ # slideshow.get("slide1")
91
+ def get(field)
92
+ f = field.split(".")
93
+ parent_part = self.parts.where(identifier: f.first).first
94
+ return nil unless parent_part
95
+
96
+ part = parent_part.try(:subparts)
97
+ if parent_part.repeatable?
98
+ raise "Part is repeatable, expected each loop" unless f.size == 1
99
+ part || []
100
+ else
101
+ return nil unless part
102
+ f.size == 1 ? part.first : part.first.attr(f.last)
103
+ end
104
+ end
105
+
106
+ # def page_hash
107
+ # return {} if self.parts.blank?
108
+ # self.parts.rank(:part_position).inject(ActiveSupport::OrderedHash.new) do |part_hash, part|
109
+ # part_hash[part.identifier] = if part.repeatable?
110
+ # part.subparts.rank(:subpart_position).inject([]) do |sub_array, subpart|
111
+ # sub_array << subpart.fields.rank(:position).inject(ActiveSupport::OrderedHash.new) do |fields_hash, field|
112
+ # fields_hash[field.identifier] = subpart.attr(field.identifier)
113
+ # fields_hash
114
+ # end
115
+ # end
116
+ # else
117
+ # get(part.identifier).fields.rank(:position).inject(ActiveSupport::OrderedHash.new) do |fields_hash, field|
118
+ # fields_hash[field.identifier] = part.attr(field.identifier)
119
+ # fields_hash
120
+ # end
121
+ # end
122
+ # part_hash
123
+ # end
124
+ # end
125
+
126
+ # SEO
127
+ # children inherit their parent's SEO settings (these can be overwritten)
128
+ def seo
129
+ @_seo ||= begin
130
+ seo = self.meta_seo
131
+ seo = self.parent.seo.merge(seo) if parent
132
+ seo = Page.root.seo.merge(seo) unless root?
133
+ seo
134
+ end
135
+ end
136
+
137
+ def seo=(hash)
138
+ # to hash is important here for strong parameters
139
+ self.meta_seo = hash.to_hash
140
+ @_seo = nil
141
+ end
142
+
143
+ def url
144
+ return "/" if slug.blank? #|| self.root?
145
+ "#{path}#{slug}/"
146
+ end
147
+
148
+ def split_path
149
+ # path.sub(/^\//,'').split("/") # "/path/" => ["path"]
150
+ path[1..-1].split("/")
151
+ end
152
+
153
+ def parent
154
+ @parent ||= Cardboard::Page.find_by_url(path)
155
+ end
156
+
157
+ # Get all other pages
158
+ def parent_url_options
159
+ # @parent_url_options ||= begin
160
+ Cardboard::Page.all.inject(["/"]) do |result, elm|
161
+ result << elm.url unless elm.id == self.id
162
+ result
163
+ end.sort
164
+ # end
165
+ end
166
+
167
+ def parent_url
168
+ return "/" if parent.nil?
169
+ parent.url
170
+ end
171
+
172
+ def parent=(new_parent)
173
+ return nil if new_parent && !new_parent.is_a?(Cardboard::Page)
174
+ self.path = new_parent ? new_parent.url : "/"
175
+ end
176
+
177
+ def parent_id=(new_parent_id)
178
+ self.parent = Cardboard::Page.where(identifier: new_parent_id).first
179
+ end
180
+
181
+ def parent_url=(new_parent_url)
182
+ self.parent = Cardboard::Page.find_by_url(new_parent_url)
183
+ end
184
+
185
+ def children
186
+ Cardboard::Page.where(path: url)
187
+ end
188
+
189
+ def siblings
190
+ Cardboard::Page.where("path = ? AND id != ?", path, id)
191
+ end
192
+
193
+ def depth
194
+ # root is depth 0
195
+ split_path.size
196
+ end
197
+
198
+ # Arrange array of nodes into a nested hash of the form
199
+ # {node => children}, where children = {} if the node has no children
200
+ #
201
+ # Example:
202
+ # {#<Cardboard::Page => {
203
+ # #<Cardboard::Page => {}
204
+ # #<Cardboard::Page => {}
205
+ # #<Cardboard::Page => {#<Cardboard::Page => {}}
206
+ # }}
207
+ def self.arrange(root_page = nil)
208
+ root_page ||= self.root
209
+ return unless root_page
210
+ # TODO: use root_page...
211
+
212
+ Rails.cache.fetch("arranged_pages") do
213
+ pages = self.preordered
214
+
215
+ pages.inject(ActiveSupport::OrderedHash.new) do |ordered_hash, page|
216
+ (["/"] + page.split_path).inject(ordered_hash) do |insertion_hash, subpath|
217
+
218
+ insertion_hash.each do |parent, children|
219
+ insertion_hash = children if subpath == parent.slug
220
+ end
221
+ insertion_hash
222
+ end[page] = ActiveSupport::OrderedHash.new
223
+ ordered_hash
224
+ end
225
+ end
226
+ end
227
+ def self.clear_arranged_pages
228
+ # clear cache when a page changes
229
+ Rails.cache.delete("arranged_pages")
230
+ end
231
+
232
+ # def to_param
233
+ # "#{id}-#{slug}"
234
+ # end
235
+
236
+ private
237
+ def self.path_and_slug(full_url)
238
+ *path, slug = full_url.sub(/^\//, '').split('/')
239
+ [path.blank? ? '/' : "/#{path.join('/')}/", slug]
240
+ end
241
+
242
+
243
+ def update_slugs_backup
244
+ return nil if !self.slug_changed? || self.slug_was.nil?
245
+ self.slugs_backup |= [self.slug_was] #Yes, that's a single pipe...
246
+ end
247
+
248
+ def default_values
249
+ self.path ||= '/'
250
+ self.title ||= self.identifier.parameterize("_")
251
+ end
252
+ end
253
+ end