bike 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. data/LICENSE +19 -0
  2. data/README.rdoc +124 -0
  3. data/bin/bike +35 -0
  4. data/lib/_error.rb +14 -0
  5. data/lib/_field.rb +260 -0
  6. data/lib/_i18n.rb +144 -0
  7. data/lib/_parser.rb +256 -0
  8. data/lib/_path.rb +86 -0
  9. data/lib/_storage/_storage.rb +215 -0
  10. data/lib/_storage/file.rb +201 -0
  11. data/lib/_storage/sequel.rb +174 -0
  12. data/lib/_storage/temp.rb +73 -0
  13. data/lib/_widget/action_create.rb +23 -0
  14. data/lib/_widget/action_login.rb +22 -0
  15. data/lib/_widget/action_signup.rb +16 -0
  16. data/lib/_widget/action_update.rb +16 -0
  17. data/lib/_widget/crumb.rb +24 -0
  18. data/lib/_widget/done.rb +16 -0
  19. data/lib/_widget/login.rb +25 -0
  20. data/lib/_widget/me.rb +31 -0
  21. data/lib/_widget/message.rb +51 -0
  22. data/lib/_widget/navi.rb +88 -0
  23. data/lib/_widget/submit.rb +49 -0
  24. data/lib/_widget/view_ym.rb +77 -0
  25. data/lib/_workflow/_workflow.rb +89 -0
  26. data/lib/_workflow/attachment.rb +50 -0
  27. data/lib/_workflow/blog.rb +28 -0
  28. data/lib/_workflow/contact.rb +23 -0
  29. data/lib/_workflow/forum.rb +26 -0
  30. data/lib/_workflow/register.rb +39 -0
  31. data/lib/bike.rb +396 -0
  32. data/lib/meta/_meta.rb +20 -0
  33. data/lib/meta/group.rb +19 -0
  34. data/lib/meta/id.rb +59 -0
  35. data/lib/meta/owner.rb +21 -0
  36. data/lib/meta/timestamp.rb +118 -0
  37. data/lib/scalar/checkbox.rb +68 -0
  38. data/lib/scalar/file.rb +144 -0
  39. data/lib/scalar/img.rb +112 -0
  40. data/lib/scalar/password.rb +58 -0
  41. data/lib/scalar/radio.rb +47 -0
  42. data/lib/scalar/select.rb +47 -0
  43. data/lib/scalar/text.rb +38 -0
  44. data/lib/scalar/textarea.rb +35 -0
  45. data/lib/scalar/textarea_pre.rb +14 -0
  46. data/lib/scalar/textarea_wiki.rb +173 -0
  47. data/lib/set/_set.rb +196 -0
  48. data/lib/set/dynamic.rb +177 -0
  49. data/lib/set/static.rb +102 -0
  50. data/lib/set/static_folder.rb +96 -0
  51. data/locale/en/index.po +242 -0
  52. data/locale/index.pot +243 -0
  53. data/locale/ja/index.po +242 -0
  54. data/locale/lazy_parser.rb +54 -0
  55. data/skel/config.ru +27 -0
  56. data/skel/skin/_users/00000000_frank-avatar.jpg +0 -0
  57. data/skel/skin/_users/00000000_frank-avatar_small.jpg +0 -0
  58. data/skel/skin/_users/00000000_frank.yaml +12 -0
  59. data/skel/skin/_users/00000000_root-avatar.jpg +0 -0
  60. data/skel/skin/_users/00000000_root-avatar_small.jpg +0 -0
  61. data/skel/skin/_users/00000000_root.yaml +11 -0
  62. data/skel/skin/_users/css/users.css +21 -0
  63. data/skel/skin/_users/css/users.less +25 -0
  64. data/skel/skin/_users/done.html +42 -0
  65. data/skel/skin/_users/index.html +46 -0
  66. data/skel/skin/_users/index.yaml +3 -0
  67. data/skel/skin/_users/summary.html +40 -0
  68. data/skel/skin/css/base.css +93 -0
  69. data/skel/skin/css/base.less +139 -0
  70. data/skel/skin/css/coax.css +199 -0
  71. data/skel/skin/css/coax.less +244 -0
  72. data/skel/skin/examples/blog/20091214_0001.yaml +8 -0
  73. data/skel/skin/examples/blog/20100630_0001.yaml +8 -0
  74. data/skel/skin/examples/blog/20100630_0002.yaml +14 -0
  75. data/skel/skin/examples/blog/20100701_0001.yaml +8 -0
  76. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f.jpg +0 -0
  77. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f_small.jpg +0 -0
  78. data/skel/skin/examples/blog/20100701_0002.yaml +19 -0
  79. data/skel/skin/examples/blog/frank/20100701_0001.yaml +10 -0
  80. data/skel/skin/examples/blog/frank/index.yaml +4 -0
  81. data/skel/skin/examples/blog/index.html +51 -0
  82. data/skel/skin/examples/blog/rss.xml +18 -0
  83. data/skel/skin/examples/contact/20100701_0001-file.txt +1 -0
  84. data/skel/skin/examples/contact/20100701_0001.yaml +15 -0
  85. data/skel/skin/examples/contact/20100701_0002.yaml +8 -0
  86. data/skel/skin/examples/contact/20100701_0003.yaml +9 -0
  87. data/skel/skin/examples/contact/index.html +47 -0
  88. data/skel/skin/examples/contact/js/contact.js +13 -0
  89. data/skel/skin/examples/contact/summary.html +54 -0
  90. data/skel/skin/examples/forum/20100701_0001.yaml +41 -0
  91. data/skel/skin/examples/forum/20100701_0002.yaml +25 -0
  92. data/skel/skin/examples/forum/index.html +68 -0
  93. data/skel/skin/examples/forum/summary.html +47 -0
  94. data/skel/skin/examples/index.html +73 -0
  95. data/skel/skin/index.html +39 -0
  96. data/skel/skin/js/base.js +50 -0
  97. data/t/locale/de/index.po +19 -0
  98. data/t/locale/en-GB/index.po +25 -0
  99. data/t/locale/ja/index.po +30 -0
  100. data/t/skin/_users/00000000_test.yaml +3 -0
  101. data/t/skin/_users/index.html +13 -0
  102. data/t/skin/foo/20091120_0001.yaml +7 -0
  103. data/t/skin/foo/bar/20091120_0001.yaml +5 -0
  104. data/t/skin/foo/bar/index.yaml +5 -0
  105. data/t/skin/foo/baz/css/baz.css +1 -0
  106. data/t/skin/foo/css/foo.css +1 -0
  107. data/t/skin/foo/index.html +14 -0
  108. data/t/skin/foo/index.yaml +7 -0
  109. data/t/skin/foo/not_css/foo.css +1 -0
  110. data/t/skin/foo/qux/index.html +8 -0
  111. data/t/skin/foo/qux/moo/index.html +6 -0
  112. data/t/skin/foo/sub-20100306_0001.yaml +3 -0
  113. data/t/skin/index.yaml +3 -0
  114. data/t/skin/t_attachment/index.html +13 -0
  115. data/t/skin/t_contact/done.html +6 -0
  116. data/t/skin/t_contact/index.html +9 -0
  117. data/t/skin/t_file/index.html +16 -0
  118. data/t/skin/t_img/index.html +14 -0
  119. data/t/skin/t_img/test.jpg +0 -0
  120. data/t/skin/t_select/index.html +9 -0
  121. data/t/skin/t_store/index.html +9 -0
  122. data/t/skin/t_summary/20100326_0001.yaml +3 -0
  123. data/t/skin/t_summary/create.html +9 -0
  124. data/t/skin/t_summary/index.html +9 -0
  125. data/t/skin/t_summary/summary.html +9 -0
  126. data/t/t.rb +27 -0
  127. data/t/test_bike.rb +768 -0
  128. data/t/test_call.rb +1281 -0
  129. data/t/test_checkbox.rb +273 -0
  130. data/t/test_field.rb +330 -0
  131. data/t/test_file.rb +900 -0
  132. data/t/test_i18n.rb +325 -0
  133. data/t/test_id.rb +215 -0
  134. data/t/test_img.rb +328 -0
  135. data/t/test_meta.rb +57 -0
  136. data/t/test_parser.rb +1516 -0
  137. data/t/test_password.rb +188 -0
  138. data/t/test_radio.rb +226 -0
  139. data/t/test_role.rb +249 -0
  140. data/t/test_select.rb +182 -0
  141. data/t/test_set_complex.rb +527 -0
  142. data/t/test_set_dynamic.rb +1504 -0
  143. data/t/test_set_folder.rb +515 -0
  144. data/t/test_set_permit.rb +246 -0
  145. data/t/test_set_static.rb +468 -0
  146. data/t/test_storage.rb +915 -0
  147. data/t/test_text.rb +125 -0
  148. data/t/test_textarea.rb +138 -0
  149. data/t/test_timestamp.rb +473 -0
  150. data/t/test_workflow.rb +367 -0
  151. metadata +347 -0
@@ -0,0 +1,242 @@
1
+ # Copyright (C) 2009-2010 Akira FUNAI
2
+ # This file is distributed under the same license as the Bike package.
3
+ # Akira FUNAI <akira@funai.com>, 2010.
4
+ #
5
+ msgid ""
6
+ msgstr ""
7
+ "Project-Id-Version: Bike 0.1\n"
8
+ "POT-Creation-Date: 2010-05-09 17:07+0900\n"
9
+ "PO-Revision-Date: 2010-05-09 18:58+0900\n"
10
+ "Last-Translator: Akira FUNAI <akira@funai.com>\n"
11
+ "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
12
+ "MIME-Version: 1.0\n"
13
+ "Content-Type: text/plain; charset=UTF-8\n"
14
+ "Content-Transfer-Encoding: 8bit\n"
15
+ "Plural-Forms: nplurals=2; plural=n!=1;\n"
16
+
17
+ #: lib/_widget/action_signup.rb:12
18
+ msgid "signup"
19
+ msgstr "ユーザ登録"
20
+
21
+ #: lib/_workflow/_workflow.rb:11
22
+ msgid "item"
23
+ msgid_plural "items"
24
+ msgstr[0] "アイテム"
25
+ msgstr[1] "アイテム"
26
+
27
+ #: lib/_workflow/_workflow.rb:41
28
+ msgid "admin"
29
+ msgstr "管理者"
30
+
31
+ #: lib/_workflow/_workflow.rb:41
32
+ msgid "group"
33
+ msgstr "グループ"
34
+
35
+ #: lib/_workflow/_workflow.rb:41
36
+ msgid "owner"
37
+ msgstr "所有者"
38
+
39
+ #: lib/_workflow/_workflow.rb:41
40
+ msgid "user"
41
+ msgid_plural "users"
42
+ msgstr[0] "ユーザ"
43
+ msgstr[1] "ユーザ"
44
+
45
+ #: lib/_workflow/_workflow.rb:41
46
+ msgid "none"
47
+ msgstr "なし"
48
+
49
+ #: lib/_workflow/_workflow.rb:94 lib/_workflow/attachment.rb:32
50
+ msgid "create"
51
+ msgstr "作成"
52
+
53
+ #: lib/_workflow/_workflow.rb:94 lib/_workflow/attachment.rb:32
54
+ msgid "update"
55
+ msgstr "更新"
56
+
57
+ #: lib/_workflow/_workflow.rb:94 lib/_workflow/attachment.rb:32
58
+ msgid "delete"
59
+ msgstr "削除"
60
+
61
+ #: lib/_workflow/_workflow.rb:99
62
+ msgid "preview"
63
+ msgstr "確認"
64
+
65
+ #: lib/_workflow/_workflow.rb:112
66
+ msgid "delete..."
67
+ msgstr "削除..."
68
+
69
+ #: lib/_workflow/attachment.rb:10
70
+ msgid "attachment"
71
+ msgid_plural "attachments"
72
+ msgstr[0] "添付アイテム"
73
+ msgstr[1] "添付アイテム"
74
+
75
+ #: lib/_workflow/blog.rb:11
76
+ msgid "entry"
77
+ msgid_plural "entries"
78
+ msgstr[0] "記事"
79
+ msgstr[1] "記事"
80
+
81
+ #: lib/_workflow/contact.rb:11
82
+ msgid "answer"
83
+ msgid_plural "answers"
84
+ msgstr[0] "回答"
85
+ msgstr[1] "回答"
86
+
87
+ #: lib/meta/id.rb:23
88
+ msgid "malformatted id"
89
+ msgstr "使用可能な文字は、a-z および 0-9 です"
90
+
91
+ #: lib/meta/id.rb:30
92
+ msgid "duplicate id: %{id}"
93
+ msgstr "「%{id}」は既に使われています"
94
+
95
+ #: lib/meta/timestamp.rb:44
96
+ msgid "%Y-%m-%dT%H:%M:%S"
97
+ msgstr "%Y/%m/%d %H:%M:%S"
98
+
99
+ #: lib/meta/timestamp.rb:63
100
+ msgid "update the timestamp"
101
+ msgstr "タイムスタンプを更新する"
102
+
103
+ #: lib/scalar/checkbox.rb:22 lib/scalar/file.rb:55 lib/scalar/radio.rb:15
104
+ #: lib/scalar/select.rb:15 lib/scalar/text.rb:17 lib/scalar/textarea.rb:12
105
+ msgid "mandatory"
106
+ msgstr "入力してください"
107
+
108
+ #: lib/scalar/checkbox.rb:24 lib/scalar/radio.rb:17 lib/scalar/select.rb:19
109
+ msgid "no such option"
110
+ msgstr "選択肢が存在しません"
111
+
112
+ #: lib/scalar/file.rb:53
113
+ msgid "wrong file type: should be %{types}"
114
+ msgstr "ファイル形式は %{types} のみです"
115
+
116
+ #: lib/scalar/file.rb:53
117
+ msgid "too large: %{max} bytes maximum"
118
+ msgstr "ファイルサイズは最大%{max} bytesです"
119
+
120
+ #: lib/scalar/file.rb:57
121
+ msgid "too small: %{min} bytes minimum"
122
+ msgstr "ファイルサイズは最小%{min} bytesです"
123
+
124
+ #: lib/scalar/select.rb:31
125
+ msgid "please select"
126
+ msgstr "選択してください"
127
+
128
+ #: lib/scalar/text.rb:15 lib/scalar/textarea.rb:10
129
+ msgid "too long: %{max} characters maximum"
130
+ msgstr "%{max}文字以内で入力してください"
131
+
132
+ #: lib/scalar/text.rb:19 lib/scalar/textarea.rb:14
133
+ msgid "too short: %{min} characters minimum"
134
+ msgstr "%{min}文字以上で入力してください"
135
+
136
+ #: lib/set/dynamic.rb:112
137
+ msgid "login"
138
+ msgstr "ログイン"
139
+
140
+ #: lib/set/dynamic.rb:118
141
+ msgid "done."
142
+ msgstr "送信しました"
143
+
144
+ #: lib/set/dynamic.rb:125
145
+ msgid "please login."
146
+ msgstr "ログインしてください。"
147
+
148
+ #: lib/set/dynamic.rb:127
149
+ msgid "please confirm."
150
+ msgstr "内容を確認してください。"
151
+
152
+ #: lib/set/dynamic.rb:129
153
+ msgid "malformed input."
154
+ msgstr "入力に問題があります。"
155
+
156
+ #: lib/set/dynamic.rb:134
157
+ msgid "%{result} %{n} %{item}."
158
+ msgstr "%{n}件の%{item}を%{result}。"
159
+
160
+ #: lib/set/dynamic.rb:136
161
+ msgid "created"
162
+ msgstr "追加しました"
163
+
164
+ #: lib/set/dynamic.rb:137
165
+ msgid "updated"
166
+ msgstr "更新しました"
167
+
168
+ #: lib/set/dynamic.rb:138
169
+ msgid "deleted"
170
+ msgstr "削除しました"
171
+
172
+ #: lib/set/dynamic.rb:161
173
+ msgid "create new %{item}..."
174
+ msgstr "新規%{item}..."
175
+
176
+ #: lib/set/dynamic.rb:181
177
+ msgid "prev"
178
+ msgstr "前へ"
179
+
180
+ #: lib/set/dynamic.rb:186
181
+ msgid "next"
182
+ msgstr "次へ"
183
+
184
+ #: lib/set/dynamic.rb:294
185
+ msgid "%{year}/%{month}"
186
+ msgstr ""
187
+
188
+ #: lib/set/dynamic.rb:301
189
+ msgid "Jan"
190
+ msgstr "01"
191
+
192
+ #: lib/set/dynamic.rb:301
193
+ msgid "Feb"
194
+ msgstr "02"
195
+
196
+ #: lib/set/dynamic.rb:301
197
+ msgid "Mar"
198
+ msgstr "03"
199
+
200
+ #: lib/set/dynamic.rb:301
201
+ msgid "Apr"
202
+ msgstr "04"
203
+
204
+ #: lib/set/dynamic.rb:301
205
+ msgid "May"
206
+ msgstr "05"
207
+
208
+ #: lib/set/dynamic.rb:301
209
+ msgid "Jun"
210
+ msgstr "06"
211
+
212
+ #: lib/set/dynamic.rb:301
213
+ msgid "Jul"
214
+ msgstr "07"
215
+
216
+ #: lib/set/dynamic.rb:301
217
+ msgid "Aug"
218
+ msgstr "08"
219
+
220
+ #: lib/set/dynamic.rb:301
221
+ msgid "Sep"
222
+ msgstr "09"
223
+
224
+ #: lib/set/dynamic.rb:301
225
+ msgid "Oct"
226
+ msgstr "10"
227
+
228
+ #: lib/set/dynamic.rb:301
229
+ msgid "Nov"
230
+ msgstr "11"
231
+
232
+ #: lib/set/dynamic.rb:301
233
+ msgid "Dec"
234
+ msgstr "12"
235
+
236
+ #: lib/set/static.rb:40
237
+ msgid "update..."
238
+ msgstr "更新..."
239
+
240
+ #: lib/set/static_folder.rb:56
241
+ msgid "logout"
242
+ msgstr "ログアウト"
@@ -0,0 +1,54 @@
1
+ # encoding: UTF-8
2
+
3
+ # Author:: Akira FUNAI
4
+ # Copyright:: Copyright (c) 2010 Akira FUNAI
5
+
6
+ require 'gettext'
7
+
8
+ module GetText::LazyParser
9
+
10
+ GetText::RGetText.add_parser GetText::LazyParser
11
+
12
+ module_function
13
+
14
+ def target?(file)
15
+ File.extname(file) == '.rb' || File.extname(file) == '.html'
16
+ end
17
+
18
+ def parse(file)
19
+ ary = []
20
+
21
+ code = ::File.open(file) {|f| f.read }
22
+ s = StringScanner.new code
23
+ until s.eos?
24
+ if (
25
+ s.scan(/_\('([^']+)'\)/) ||
26
+ s.scan(/_\(([\w \.\,\!\:]+)\)/) ||
27
+ s.scan(/_ '([^']+)'/) ||
28
+ s.scan(/_ ([\w\.]+)/)
29
+ )
30
+ po = GetText::PoMessage.new :normal
31
+ po.msgid = s[1]
32
+ po.sources = ["#{file}:#{_line(s.pos, code)}"]
33
+ ary << po
34
+ elsif (
35
+ s.scan(/n_\(\s*'([^']+)'\s*,\s*'([^']+)'/m)
36
+ )
37
+ po = GetText::PoMessage.new :plural
38
+ po.msgid = s[1]
39
+ po.msgid_plural = s[2]
40
+ po.sources = ["#{file}:#{_line(s.pos, code)}"]
41
+ ary << po
42
+ else
43
+ s.scan /.+?(?=_|n|\z)/m
44
+ end
45
+ end
46
+
47
+ ary
48
+ end
49
+
50
+ def _line(pos, code)
51
+ code[0...pos].count("\n") + 1
52
+ end
53
+
54
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # Author:: Akira FUNAI
5
+ # Copyright:: Copyright (c) 2009-2010 Akira FUNAI
6
+
7
+ require 'rubygems'
8
+
9
+ $LOAD_PATH.unshift(::File.expand_path('../lib',::File.dirname(__FILE__)))
10
+ require 'bike'
11
+
12
+ use Rack::ShowExceptions
13
+ use Rack::Session::Pool #Cookie
14
+ use Rack::Lock
15
+
16
+ ::Dir.chdir ::File.dirname(__FILE__)
17
+
18
+ Bike.config(
19
+ 'skin_dir' => './skin',
20
+ 'storage' => {
21
+ 'default' => 'File',
22
+ 'File' => {'data_dir' => './data'},
23
+ 'Sequel' => {'uri' => 'sqlite:/'},
24
+ }
25
+ )
26
+
27
+ run Bike.new
@@ -0,0 +1,12 @@
1
+ ---
2
+ _id: frank
3
+ _owner: frank
4
+ _timestamp:
5
+ updated: 2010-06-30 19:36:10.685090 +09:00
6
+ avatar:
7
+ basename: 090104.jpg
8
+ size: 4257
9
+ type: image/jpeg
10
+ email: frank@example.com
11
+ name: Frank
12
+ password: ygELi9fCAIJNA
@@ -0,0 +1,11 @@
1
+ ---
2
+ _id: root
3
+ _timestamp:
4
+ updated: 2010-05-29 03:06:57.156802 +09:00
5
+ avatar:
6
+ basename: 091210.jpg
7
+ size: 5790
8
+ type: image/jpeg
9
+ email: test@example.com
10
+ name: "Root User"
11
+ password: yln/Xsr4Tcv/s
@@ -0,0 +1,21 @@
1
+ #center table.panel {
2
+ display: -moz-inline-box;
3
+ display: inline-block;
4
+ margin: 0 10px 10px 10px;
5
+ padding: 5px 15px 20px 15px;
6
+ width: auto;
7
+ height: 120px;
8
+ }
9
+ #center table.panel th {
10
+ width: auto;
11
+ text-align: center;
12
+ vertical-align: top;
13
+ padding: 0;
14
+ background: white;
15
+ color: black;
16
+ }
17
+ #center table.panel td {
18
+ width: auto;
19
+ vertical-align: top;
20
+ padding: 0;
21
+ }
@@ -0,0 +1,25 @@
1
+ #center {
2
+ table.panel {
3
+ display: -moz-inline-box;
4
+ display: inline-block;
5
+ margin: 0 10px 10px 10px;
6
+ padding: 5px 15px 20px 15px;
7
+ width: auto;
8
+ height: 120px;
9
+
10
+ th {
11
+ width: auto;
12
+ text-align: center;
13
+ vertical-align: top;
14
+ padding: 0;
15
+ background: white;
16
+ color: black;
17
+ }
18
+
19
+ td {
20
+ width: auto;
21
+ vertical-align: top;
22
+ padding: 0;
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,42 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="_(en)" lang="_(en)">
6
+
7
+ <head>
8
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9
+ <title>_(Account Created)</title>
10
+ <link rel="stylesheet" href="/css/base.css" type="text/css" media="screen" />
11
+ <link rel="stylesheet" href="/css/coax.css" type="text/css" media="screen" />
12
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
13
+ <script type="text/javascript" src="/js/base.js"></script>
14
+ </head>
15
+
16
+ <body>
17
+ <div id="container">
18
+ <div id="header">
19
+ <h1>_(Account Created)</h1>
20
+ $(.crumb)
21
+ </div>
22
+
23
+ <div id="center" class="column">
24
+ <h2>_(Thanks!)</h2>
25
+ <p>_(You can login with your new account now.)</p>
26
+ <form id="form_login" method="post" action="@(base_href)../login.html">
27
+ <div class="login">
28
+ <label for="login_id">_(ID)</label><input type="text" id="login_id" name="id" size="10" value="" />
29
+ <label for="login_pw">_(Password)</label><input type="password" id="login_pw" name="pw" size="10" value="" />
30
+ <input type="submit" value="_(login)" />
31
+ </div>
32
+ </form>
33
+ </div>
34
+
35
+ <div id="right" class="column">
36
+ </div>
37
+
38
+ <div id="footer"></div>
39
+ </div>
40
+ </body>
41
+
42
+ </html>