plezi 0.12.22 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/LICENSE.txt +17 -18
  4. data/README.md +54 -698
  5. data/Rakefile +7 -4
  6. data/bin/config.ru +22 -0
  7. data/{test → bin}/console +4 -6
  8. data/bin/hello_world +52 -0
  9. data/bin/setup +8 -0
  10. data/exe/plezi +145 -0
  11. data/lib/plezi.rb +24 -137
  12. data/lib/plezi/activation.rb +28 -0
  13. data/lib/plezi/api.rb +62 -0
  14. data/lib/plezi/controller/controller.rb +259 -0
  15. data/lib/plezi/controller/controller_class.rb +176 -0
  16. data/lib/plezi/controller/cookies.rb +40 -0
  17. data/lib/plezi/helpers.rb +60 -0
  18. data/lib/plezi/rake.rb +2 -24
  19. data/lib/plezi/render/erb.rb +34 -0
  20. data/lib/plezi/render/has_cache.rb +36 -0
  21. data/lib/plezi/render/markdown.rb +63 -0
  22. data/lib/plezi/render/render.rb +49 -0
  23. data/lib/plezi/render/sass.rb +55 -0
  24. data/lib/plezi/render/slim.rb +33 -0
  25. data/lib/plezi/router/adclient.rb +23 -0
  26. data/lib/plezi/router/assets.rb +67 -0
  27. data/lib/plezi/router/errors.rb +29 -0
  28. data/lib/plezi/router/route.rb +112 -0
  29. data/lib/plezi/router/router.rb +120 -0
  30. data/lib/plezi/version.rb +1 -1
  31. data/lib/plezi/websockets/message_dispatch.rb +91 -0
  32. data/lib/plezi/websockets/redis.rb +55 -0
  33. data/plezi.gemspec +25 -16
  34. data/resources/404.erb +5 -4
  35. data/resources/500.erb +5 -4
  36. data/resources/{500.html → 503.html} +8 -9
  37. data/resources/client.js +253 -0
  38. data/resources/config.ru +5 -36
  39. data/resources/ctrlr.rb +34 -0
  40. data/resources/gemfile +4 -0
  41. data/resources/mini_app.rb +28 -82
  42. data/resources/mini_exec +7 -0
  43. data/resources/mini_welcome_page.html +0 -0
  44. data/resources/procfile +3 -0
  45. data/resources/rakefile +4 -8
  46. data/resources/routes.rb +9 -26
  47. data/resources/{websockets.js → simple-client.js} +3 -3
  48. metadata +60 -85
  49. data/bin/plezi +0 -104
  50. data/docs/async_helpers.md +0 -245
  51. data/docs/controllers.md +0 -27
  52. data/docs/logging.md +0 -49
  53. data/docs/routes.md +0 -209
  54. data/docs/websockets.md +0 -213
  55. data/lib/plezi/builders/ac_model.rb +0 -59
  56. data/lib/plezi/builders/app_builder.rb +0 -137
  57. data/lib/plezi/builders/builder.rb +0 -43
  58. data/lib/plezi/builders/form_builder.rb +0 -27
  59. data/lib/plezi/common/api.rb +0 -92
  60. data/lib/plezi/common/cache.rb +0 -122
  61. data/lib/plezi/common/defer.rb +0 -21
  62. data/lib/plezi/common/dsl.rb +0 -94
  63. data/lib/plezi/common/redis.rb +0 -65
  64. data/lib/plezi/common/renderer.rb +0 -141
  65. data/lib/plezi/common/settings.rb +0 -52
  66. data/lib/plezi/handlers/controller_core.rb +0 -106
  67. data/lib/plezi/handlers/controller_magic.rb +0 -284
  68. data/lib/plezi/handlers/http_router.rb +0 -205
  69. data/lib/plezi/handlers/placebo.rb +0 -112
  70. data/lib/plezi/handlers/route.rb +0 -216
  71. data/lib/plezi/handlers/session.rb +0 -109
  72. data/lib/plezi/handlers/stubs.rb +0 -156
  73. data/lib/plezi/handlers/ws_identity.rb +0 -253
  74. data/lib/plezi/handlers/ws_object.rb +0 -308
  75. data/lib/plezi/helpers/http_sender.rb +0 -84
  76. data/lib/plezi/helpers/magic_helpers.rb +0 -104
  77. data/lib/plezi/helpers/mime_types.rb +0 -1995
  78. data/lib/plezi/oauth.rb +0 -5
  79. data/lib/plezi/oauth/auth_controller.rb +0 -229
  80. data/logo/dark.png +0 -0
  81. data/logo/light.png +0 -0
  82. data/logo/sign.png +0 -0
  83. data/resources/404.haml +0 -121
  84. data/resources/404.html +0 -124
  85. data/resources/404.slim +0 -120
  86. data/resources/500.haml +0 -120
  87. data/resources/500.slim +0 -120
  88. data/resources/Gemfile +0 -86
  89. data/resources/code.rb +0 -8
  90. data/resources/controller.rb +0 -142
  91. data/resources/database.yml +0 -33
  92. data/resources/db_ac_config.rb +0 -59
  93. data/resources/db_dm_config.rb +0 -51
  94. data/resources/db_sequel_config.rb +0 -33
  95. data/resources/en.yml +0 -204
  96. data/resources/haml_config.rb +0 -6
  97. data/resources/i18n_config.rb +0 -14
  98. data/resources/initialize.rb +0 -49
  99. data/resources/mini_exec.rb +0 -7
  100. data/resources/oauth_config.rb +0 -24
  101. data/resources/plezi_client.js +0 -198
  102. data/resources/plezi_websockets.html +0 -47
  103. data/resources/redis_config.rb +0 -42
  104. data/resources/slim_config.rb +0 -11
  105. data/resources/welcome_page.html +0 -272
  106. data/test/dispatch +0 -58
  107. data/test/hello_world +0 -13
  108. data/test/plezi_tests.rb +0 -581
data/lib/plezi/oauth.rb DELETED
@@ -1,5 +0,0 @@
1
- # requires the open-uri library.
2
- # require 'open-uri'
3
- require 'net/http'
4
- # require the OAuth2 controller
5
- require 'plezi/oauth/auth_controller.rb'
@@ -1,229 +0,0 @@
1
-
2
-
3
-
4
-
5
- module Plezi
6
-
7
- #########################################
8
- # This is a social Authentication Controller for OAuth2 services.
9
- # This controller allows you to easily deploy Facebook Login, Google Login and any other OAuth2 complient login service.
10
- #
11
- # To include this controller in your application, you need to require it using:
12
- #
13
- # require 'plezi/oauth'
14
- #
15
- # It is possible to manualy register any OAuth 2.0 authentication service using the `register_service` method:
16
- #
17
- # register_service(:foo,
18
- # app_id: 'registered app id / client id',
19
- # app_secret: 'registered app secret / client secret',
20
- # auth_url: "https://foo.bar.com/o/oauth2/auth",
21
- # token_url: "https://foo.bar.com/oauth2/v3/token",
22
- # profile_url: "https://foo.bar/oauth2/v1/userinfo",
23
- # scope: "profile email")
24
- #
25
- # The `.register_service` method will be automatically called for the following login services:
26
- #
27
- # - Facebook authentication using the Graph API, v. 2.3 - [see Facebook documentation](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.3).
28
- # - Google authentication using the OAuth 2.0 API - [see Google documentation](https://developers.google.com/identity/protocols/OAuth2WebServer).
29
- #
30
- # To enjoy autorgistration for Facebook or Google, make sure the following environment variables are set:
31
- # ENV['FB_APP_ID'] = {facebook_app_id}
32
- # ENV['FB_APP_SECRET'] = {facebook_app_secret}
33
- # ENV['GOOGLE_APP_ID'] = {google_app_id}
34
- # ENV['GOOGLE_APP_SECRET'] = {google_app_secret}
35
- #
36
- # To add the OAuth routes to the routes, use the following short-cut method (add it to the `routes.rb`) file:
37
- #
38
- # create_auth_shared_route do |service, remote_user_id, email, full_remote_response|
39
- # # perform any specific app authentication logic such as saving the info.
40
- # # return the current user or false if the callback is called with an authentication failure.
41
- # end
42
- #
43
- # \* Notice that, as always, route placement order effects behavior, so that routes are checked according to order of creation.
44
- #
45
- # The `create_auth_shared_route` method is a shortcut taht calls the `#shared_route` method with the relevant arguments and sets the OAuth2Ctrl callback.
46
- #
47
- # Use the following links for social authentication:
48
- #
49
- # - Facebook: "/auth/facebook"
50
- # - Google: "/auth/google"
51
- # - foo_service: "/auth/foo_service"
52
- #
53
- # You can control the page to which the user will return once authentication is complete
54
- # (even when authentication fails) by setting the "redirect_after" parameter into the GET request in the url. for example:
55
- #
56
- # - Google: "/auth/google?redirect_after=/foo/bar"
57
- class OAuth2Ctrl
58
-
59
- # Sets (or gets) the global callback to be called after authentication is attempeted.
60
- #
61
- # Accepts a block that will be called with the following parameters:
62
- # service_name:: the name of the service. i.e. :facebook, :google, etc'.
63
- # service_token:: the authentication token returned by the service. This token should be stored for future access
64
- # remote_user_id:: service's user id.
65
- # remote_user_email:: user's primamry email, as (and if) registed with the service.
66
- # remote_response:: a Hash with the complete user data response (including email and id).
67
- #
68
- # If the authentication fails for the service, the block will be called with the following values `auth_callback.call(nil, ni, {server: :responce, might_be: :empty})`
69
- #
70
- # The block will be run in the context of the controller and all the controller's methods will be available to it.
71
- #
72
- # i.e.:
73
- # OAuth2Ctrl.auth_callback |service, service_token, id, email, full_res| PL.info "OAuth got: #{full_res.to_s}"; cookies["#{service}_pl_auth_token".to_sym], cookies["#{service}_user_id".to_sym], cookies["#{service}_user_email".to_sym] = service_token, id, email }
74
- #
75
- # defaults to the example above, which isn't a very sercure behavior, but allows for easy testing.
76
- def self.auth_callback &block
77
- block_given? ? (@@auth_callback = block) : ( @@auth_callback ||= (Proc.new {|service, service_token, id, email, res| Plezi.info "deafult callback called for #{service}, with response: #{res.to_s}"; session["#{service}_pl_auth_token"], session["#{service}_user_id"], session["#{service}_user_email"] = service_token, id, email}) )
78
- end
79
-
80
-
81
- # Stores the registered services library
82
- SERVICES = {}
83
-
84
- # This method registers a social login service that conforms to the OAuth2 model.
85
- #
86
- # Accepts the following required parameters:
87
- # service_name:: a Symbol naming the service. i.e. :facebook or :google .
88
- # options:: a Hash of options, some of which are required.
89
- #
90
- # The options are:
91
- # app_id:: Required. The aplication's unique ID (sometimes called `client_id`) registered with the service. i.e. ENV [FB_APP_ID] (storing these in environment variables is safer then hardcoding them)
92
- # app_secret:: Required. The aplication's unique secret registered with the service (sometimes called `client_secret`).
93
- # auth_url:: Required. The authentication URL. This is the url to which the user is redirected. i.e.: "https://www.facebook.com/dialog/oauth"
94
- # token_url:: Required. The token request URL. This is the url used to switch the single-use code into a persistant authentication token. i.e.: "https://www.googleapis.com/oauth2/v3/token"
95
- # profile_url:: Required. The URL used to ask the service for the user's profile (the service's API url). i.e.: "https://graph.facebook.com/v2.3/me"
96
- # scope:: a String representing the scope requested. i.e. 'email profile'.
97
- #
98
- # There will be an attempt to automatically register Facebook and Google login services under these conditions:
99
- #
100
- # * For Facebook: Both ENV ['FB_APP_ID'] && ENV ['FB_APP_SECRET'] have been defined.
101
- # * For Google: Both ENV ['GOOGLE_APP_ID'] && ENV ['GOOGLE_APP_SECRET'] have been defined.
102
- #
103
- #
104
- # The auto registration uses the following urls (updated to June 5, 2015):
105
- #
106
- # * facebook auth_url: "https://www.facebook.com/dialog/oauth"
107
- # * facebook token_url: "https://graph.facebook.com/v2.3/oauth/access_token"
108
- # * facebook profile_url: "https://graph.facebook.com/v2.3/me"
109
- # * google auth_url: "https://accounts.google.com/o/oauth2/auth"
110
- # * google token_url: "https://www.googleapis.com/oauth2/v3/token"
111
- # * google profile_url: "https://www.googleapis.com/plus/v1/people/me"
112
- #
113
- # to change the default scope or url's for Facebook or Google, simpley re-register the service using this method.
114
- #
115
- def self.register_service service_name, options
116
- raise "Cannot register service, missing required information." unless service_name && options[:auth_url] && options[:token_url] && options[:profile_url] && options[:app_id] && options[:app_secret]
117
- # for google, scope is space delimited. for facebook it's comma delimited
118
- options[:scope] ||= 'profile, email'
119
- SERVICES[service_name] = options
120
- end
121
-
122
- # Called to manually run through the authentication logic for the requested service,
123
- # without performing any redirections.
124
- #
125
- # Use this method to attempt and re-login a user using an existing login token:
126
- #
127
- # token = 'google_token_could_be_recieved_also_from_javascript_sdk'
128
- # OAuth2Ctrl.auth :google, token, self
129
- #
130
- # The method will return false if re-login fails and it will otherwise return the callback's return value.
131
- #
132
- # Call this method from within a controller, passing the controller (self) to the method, like so:
133
- #
134
- # OAuth2Ctrl.auth :facebook, token, self
135
- #
136
- # This is especially effective if `auth_callback` returns the user object, as it would allow to chain
137
- # different login methods, i.e.:
138
- #
139
- # @user ||= app_login || OAuth2Ctrl.auth(:facebook, fb_token, self) || OAuth2Ctrl.auth(:google, google_token, self) || ....
140
- def self.auth service_name, service_token, controller
141
- service = SERVICES[service_name]
142
- return false unless service
143
- # auth_res = controller.cookies[c_name] ? (JSON.parse URI.parse("#{service[:profile_url]}?access_token=#{controller.cookies[c_name]}").read rescue ({}) ) : {}
144
- # controller.cookies[c_name] = nil unless auth_res['id']
145
- # auth_res['id'] ? controller.instance_exec( service_name, auth_res['id'], auth_res['email'], auth_res, &auth_callback) : ( controller.instance_exec( service_name, nil, nil, auth_res, &auth_callback) && false)
146
- auth_res = {}
147
- uri = URI.parse("#{service[:profile_url]}?access_token=#{service_token}")
148
- Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == "https"), verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
149
- req = Net::HTTP::Get.new(uri)
150
- res = http.request(req).body
151
- auth_res = (JSON.parse res) rescue ({})
152
- end if service_token
153
- auth_res['id'] ? controller.instance_exec( service_name, service_token, auth_res['id'], auth_res['email'], auth_res, &auth_callback) : ( controller.instance_exec( service_name, nil, nil, nil, auth_res, &auth_callback) && false)
154
- end
155
-
156
- def update
157
- service_name = params[:id].to_s.to_sym
158
- service = SERVICES[service_name]
159
- return false unless service
160
- if params[:error]
161
- instance_exec( service_name, nil, nil, nil, {}, &self.class.auth_callback)
162
- return redirect_to(flash[:redirect_after])
163
- end
164
- unless params[:code]
165
- flash[:redirect_after] = params[:redirect_after] || '/'
166
- return redirect_to _auth_url_for(service_name)
167
- end
168
- uri = URI.parse service[:token_url]
169
- service_token = nil
170
- Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == "https"), verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
171
- req = Net::HTTP::Post.new(uri)
172
- req.form_data = {"client_id" => service[:app_id],
173
- "client_secret" => service[:app_secret], "code" => params[:code] ,
174
- "grant_type" => "authorization_code","redirect_uri" => "#{request.base_url}/auth/#{service_name.to_s}"}
175
- res = http.request(req).body
176
- service_token = ((JSON.parse res)['access_token'] rescue nil)
177
- end
178
-
179
- self.class.auth service_name, service_token, self
180
- redirect_to(flash[:redirect_after])
181
- end
182
- alias :show :update
183
-
184
- protected
185
-
186
- # returns a url for the requested service's social login.
187
- #
188
- # this is used internally. Normal behavior would be to set a link to '/auth/{service_name}', where correct redirection will be automatic.
189
- #
190
- def _auth_url_for service_name
191
- service = SERVICES[service_name]
192
- return nil unless service
193
- redirect_uri = Plezi::Base::Helpers.encode_url "#{request.base_url}/auth/#{service_name.to_s}" #response_type
194
- return "#{service[:auth_url]}?client_id=#{service[:app_id]}&redirect_uri=#{redirect_uri}&scope=#{service[:scope]}&response_type=code"
195
- end
196
-
197
- register_service(:facebook, app_id: ENV['FB_APP_ID'],
198
- app_secret: ENV['FB_APP_SECRET'],
199
- auth_url: "https://www.facebook.com/dialog/oauth",
200
- token_url: "https://graph.facebook.com/v2.3/oauth/access_token",
201
- profile_url: "https://graph.facebook.com/v2.3/me",
202
- scope: "public_profile,email") if ENV['FB_APP_ID'] && ENV['FB_APP_SECRET']
203
- register_service(:google, app_id: ENV['GOOGLE_APP_ID'],
204
- app_secret: ENV['GOOGLE_APP_SECRET'],
205
- auth_url: "https://accounts.google.com/o/oauth2/auth",
206
- token_url: "https://www.googleapis.com/oauth2/v3/token",
207
- profile_url: "https://www.googleapis.com/oauth2/v1/userinfo",
208
- scope: "profile email") if ENV['GOOGLE_APP_ID'] && ENV['GOOGLE_APP_SECRET']
209
-
210
- end
211
- end
212
-
213
- # This method creates the OAuth2Ctrl route.
214
- # This is actually a short-cut for:
215
- #
216
- # shared_route "auth/(:id)/(:code)" , Plezi::OAuth2Ctrl
217
- # Plezi::OAuth2Ctrl.auth_callback = Proc.new {|service, user_id, user_email, service_response| ... }
218
- #
219
- # the `:id` parameter is used to identify the service (facebook, google. etc').
220
- #
221
- # The method accepts a block that will be used to set the authentication callback. See the Plezi::OAuth2Ctrl documentation for details.
222
- #
223
- # The method can be called only once and will self-destruct.
224
- def create_auth_shared_route options = {}, &block
225
- shared_route "auth/(:id)" , Plezi::OAuth2Ctrl
226
- undef create_auth_shared_route
227
- Plezi::OAuth2Ctrl.auth_callback &block if block
228
- Plezi::OAuth2Ctrl
229
- end
data/logo/dark.png DELETED
Binary file
data/logo/light.png DELETED
Binary file
data/logo/sign.png DELETED
Binary file
data/resources/404.haml DELETED
@@ -1,121 +0,0 @@
1
- !!!5
2
- %head
3
- :css
4
- /*
5
- med-blue: #44518E
6
- dark-gray: #424A70
7
- blue: #1B2864
8
- light-blue: #818ECE
9
- light-gray: #99A3CE
10
- */
11
- body, html
12
- {
13
- background-color: #99A3CE;
14
- padding: 0; margin: 0;
15
- width: 100%;
16
- font-size: 1em;
17
- }
18
-
19
- h1
20
- {
21
- font-family: 'Shadows Into Light', cursive;
22
- background-color: #1B2864;
23
- color: #99A3CE;
24
- text-align: center;
25
- border-bottom: 4px solid #424A70;
26
- margin: 0 0 1em 0;
27
- padding: 0.4em 0;
28
- width: 100%;
29
- }
30
- h2
31
- {
32
- background-color: #44518E;
33
- color: #C6CCE7;
34
- text-align: left;
35
- margin: 0 0 1em 0;
36
- padding: 0.5em 5%;
37
- border-radius: 20px 20px 0 0;
38
- font-family: 'Architects Daughter', cursive;
39
- border-bottom: 3px solid #424A70;
40
- font-size: 1.2em;
41
- }
42
- h3
43
- {
44
- font-family: 'Architects Daughter', cursive;
45
- background-color: #44518E;
46
- color: #C6CCE7;
47
- text-align: left;
48
- margin: 0 0 1em 0;
49
- padding: 0.5em 5%;
50
- border-radius: 1em 1em 0 0;
51
- border-bottom: 2px solid #424A70;
52
- font-size: 1.1em;
53
- }
54
- h2:before {
55
- content: "|||";
56
- color: #99A3CE;
57
- padding-right: 0.3em;
58
- margin-left: -0.5em;
59
- }
60
- h3:before {
61
- content: "|||||";
62
- color: #99A3CE;
63
- padding-right: 0.3em;
64
- margin-left: -1em;
65
- }
66
- h1 a, h2 a, h3 a
67
- {
68
- color: #EBCD86;
69
- }
70
- h1 a:hover, h2 a:hover, h3 a:hover
71
- {
72
- color: #EBD7A6;
73
- }
74
- p
75
- {
76
- font-size: 1em;
77
- padding: 0 1em;
78
- margin: 0.5em 0;
79
- }
80
- a
81
- {
82
- color: #D0AC54;
83
- text-decoration: none;
84
- }
85
- a:hover
86
- {
87
- color: #927121;
88
- text-decoration: underline;
89
- }
90
- #wrapper
91
- {
92
- background-color: #fff;
93
- margin: 1em 5%;
94
- padding: 0 0 2%;
95
- border-radius: 20px;
96
- min-height: 50%;
97
- color: #007;
98
- }
99
-
100
- #wrapper p{ padding: 0 2%;}
101
- .bold { font-weight: bold; }
102
- #wrapper ol li{ padding: 0 2%;}
103
- pre
104
- {
105
- border-radius: 20px;
106
- padding: 0.5em 0;
107
- background-color: #444;
108
- color: #ddd;
109
- }
110
- @media screen and (max-width: 680px)
111
- {
112
- }
113
- %body
114
- %h1< Plezi 404 error code (missing, not broken)...
115
- #wrapper
116
- %h2#missing
117
- couldn't find
118
- = defined?(request) ? request.path : "what you're looking for..."
119
- %p Sorry, we couldn't find what you're looking for...
120
- %p ... but we can always bring you something nice from another location, right?
121
- / want to use your layout? use the :haml_concat method to wrap the 404 error code message. see http://haml.info/docs/yardoc/Haml/Helpers.html#haml_concat-instance_method .
data/resources/404.html DELETED
@@ -1,124 +0,0 @@
1
- <!DOCTYPE html>
2
- <head>
3
- <style>
4
- /*
5
- med-blue: #44518E
6
- dark-gray: #424A70
7
- blue: #1B2864
8
- light-blue: #818ECE
9
- light-gray: #99A3CE
10
- */
11
- body, html
12
- {
13
- background-color: #99A3CE;
14
- padding: 0; margin: 0;
15
- width: 100%;
16
- font-size: 1em;
17
- }
18
-
19
- h1
20
- {
21
- font-family: 'Shadows Into Light', cursive;
22
- background-color: #1B2864;
23
- color: #99A3CE;
24
- text-align: center;
25
- border-bottom: 4px solid #424A70;
26
- margin: 0 0 1em 0;
27
- padding: 0.4em 0;
28
- width: 100%;
29
- }
30
- h2
31
- {
32
- background-color: #44518E;
33
- color: #C6CCE7;
34
- text-align: left;
35
- margin: 0 0 1em 0;
36
- padding: 0.5em 5%;
37
- border-radius: 20px 20px 0 0;
38
- font-family: 'Architects Daughter', cursive;
39
- border-bottom: 3px solid #424A70;
40
- font-size: 1.2em;
41
- }
42
- h3
43
- {
44
- font-family: 'Architects Daughter', cursive;
45
- background-color: #44518E;
46
- color: #C6CCE7;
47
- text-align: left;
48
- margin: 0 0 1em 0;
49
- padding: 0.5em 5%;
50
- border-radius: 1em 1em 0 0;
51
- border-bottom: 2px solid #424A70;
52
- font-size: 1.1em;
53
- }
54
- h2:before {
55
- content: "|||";
56
- color: #99A3CE;
57
- padding-right: 0.3em;
58
- margin-left: -0.5em;
59
- }
60
- h3:before {
61
- content: "|||||";
62
- color: #99A3CE;
63
- padding-right: 0.3em;
64
- margin-left: -1em;
65
- }
66
- h1 a, h2 a, h3 a
67
- {
68
- color: #EBCD86;
69
- }
70
- h1 a:hover, h2 a:hover, h3 a:hover
71
- {
72
- color: #EBD7A6;
73
- }
74
- p
75
- {
76
- font-size: 1em;
77
- padding: 0 1em;
78
- margin: 0.5em 0;
79
- }
80
- a
81
- {
82
- color: #D0AC54;
83
- text-decoration: none;
84
- }
85
- a:hover
86
- {
87
- color: #927121;
88
- text-decoration: underline;
89
- }
90
- #wrapper
91
- {
92
- background-color: #fff;
93
- margin: 1em 5%;
94
- padding: 0 0 2%;
95
- border-radius: 20px;
96
- min-height: 50%;
97
- color: #007;
98
- }
99
-
100
- #wrapper p{ padding: 0 2%;}
101
- .bold { font-weight: bold; }
102
- #wrapper ol li{ padding: 0 2%;}
103
- pre
104
- {
105
- border-radius: 20px;
106
- padding: 0.5em 0;
107
- background-color: #444;
108
- color: #ddd;
109
- }
110
- @media screen and (max-width: 680px)
111
- {
112
- }
113
- </style>
114
- </head>
115
- <body>
116
- <h1>Plezi 404 error code (missing, not broken)...</h1>
117
- <div id='wrapper'>
118
- <h2 id='missing'>
119
- couldn't find your request...
120
- </h2>
121
- <p>Sorry, we couldn't find what you're looking for...</p>
122
- <p>... but we can always bring you something nice from another location, right?</p>
123
- </div>
124
- </body>