+
- " data-order="none"><%= t("recording.table.name") %>
+ ">
+ <%= t("recording.table.name") %>
+ <% if @order_column == "name" && @order_direction == "desc" %>
+ ↓
+ <% elsif @order_column == "name" && @order_direction == "asc" %>
+ ↑
+ <% end %>
+
<% if recording_thumbnails? %>
- <%= t("recording.table.thumbnails") %>
+
+ <%= t("recording.table.thumbnails") %>
+
<% end %>
- " data-order="none">
+ ">
<%= t("recording.table.length") %>
+ <% if @order_column == "length" && @order_direction == "desc" %>
+ ↓
+ <% elsif @order_column == "length" && @order_direction == "asc" %>
+ ↑
+ <% end %>
- " data-order="none">
+ ">
<%= t("recording.table.users") %>
+ <% if @order_column == "users" && @order_direction == "desc" %>
+ ↓
+ <% elsif @order_column == "users" && @order_direction == "asc" %>
+ ↑
+ <% end %>
+
+ ">
+ <%= t("recording.table.visibility") %>
+ <% if @order_column == "visibility" && @order_direction == "desc" %>
+ ↓
+ <% elsif @order_column == "visibility" && @order_direction == "asc" %>
+ ↑
+ <% end %>
+
+ ">
+ <%= t("recording.table.formats") %>
+ <% if @order_column == "formats" && @order_direction == "desc" %>
+ ↓
+ <% elsif @order_column == "formats" && @order_direction == "asc" %>
+ ↑
+ <% end %>
- <%= t("recording.table.visibility") %>
- <%= t("recording.table.formats") %>
<% unless only_public %>
<% end %>
@@ -68,6 +101,11 @@
<% end %>
+ <% if !recordings.empty?%>
+
+ <%== pagy_bootstrap_nav(pagy) %>
+
+ <% end %>
diff --git a/app/views/shared/admin_settings/_site_settings.html.erb b/app/views/shared/admin_settings/_site_settings.html.erb
index c191bcb2..793083db 100644
--- a/app/views/shared/admin_settings/_site_settings.html.erb
+++ b/app/views/shared/admin_settings/_site_settings.html.erb
@@ -22,7 +22,7 @@
- <%= t("administrator.site_settings.branding.change") %>
+ <%= t("administrator.site_settings.branding.change") %>
@@ -33,12 +33,12 @@
diff --git a/app/views/shared/components/_recording_row.html.erb b/app/views/shared/components/_recording_row.html.erb
index 734d6ff9..1d298e19 100644
--- a/app/views/shared/components/_recording_row.html.erb
+++ b/app/views/shared/components/_recording_row.html.erb
@@ -39,7 +39,7 @@
<% end %>
<% end %>
-
+
<%= recording_length(recording[:playbacks]) %>
@@ -63,7 +63,7 @@
- <% sorted_formats = recording[:playbacks].sort_by! {|p| p[:type]} %>
+ <% sorted_formats = recording[:playbacks].sort_by! { |p| p[:type] } %>
<% sorted_formats.each do |p| %>
<%= link_to t("recording.format.#{p[:type]}"), p[:url], class: "btn btn-sm btn-primary", target: "_blank" %>
<% end %>
diff --git a/app/views/shared/components/_subtitle.html.erb b/app/views/shared/components/_subtitle.html.erb
index b072e380..29870f89 100644
--- a/app/views/shared/components/_subtitle.html.erb
+++ b/app/views/shared/components/_subtitle.html.erb
@@ -18,14 +18,24 @@
<%= subtitle %>
<% if search %>
-
-
-
+
+
\ No newline at end of file
diff --git a/app/views/shared/settings/_setting_view.html.erb b/app/views/shared/settings/_setting_view.html.erb
index 681d4fc3..a2c65c60 100644
--- a/app/views/shared/settings/_setting_view.html.erb
+++ b/app/views/shared/settings/_setting_view.html.erb
@@ -17,38 +17,9 @@
-
<% unless (defined?(admin_view)).nil? %>
<%= render "shared/admin_settings/#{setting_id}" %>
diff --git a/app/views/users/recordings.html.erb b/app/views/users/recordings.html.erb
index 392f0002..1c050723 100644
--- a/app/views/users/recordings.html.erb
+++ b/app/views/users/recordings.html.erb
@@ -18,4 +18,4 @@
# without losing all css
%>
-<%= render "shared/sessions", recordings: @recordings, only_public: false, user_recordings: true, title: t("recording.all_recordings") %>
+<%= render "shared/sessions", recordings: @recordings, pagy: @pagy, only_public: false, user_recordings: true, title: t("recording.all_recordings") %>
diff --git a/config/application.rb b/config/application.rb
index ac71d331..2a5dc010 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -48,7 +48,7 @@ module Greenlight
config.gl_callback_url = ENV["GL_CALLBACK_URL"]
# Default credentials (test-install.blindsidenetworks.com/bigbluebutton).
- config.bigbluebutton_endpoint_default = "http://test-install.blindsidenetworks.com/bigbluebutton/"
+ config.bigbluebutton_endpoint_default = "http://test-install.blindsidenetworks.com/bigbluebutton/api/"
config.bigbluebutton_secret_default = "8cd8ef52e8e101574e400365b55e11a6"
# Use standalone BigBlueButton server.
@@ -66,7 +66,6 @@ module Greenlight
config.loadbalancer_endpoint = ENV["LOADBALANCER_ENDPOINT"]
config.loadbalancer_secret = ENV["LOADBALANCER_SECRET"]
config.launcher_secret = ENV["LAUNCHER_SECRET"]
- config.launcher_allow_user_signup = ENV["LAUNCHER_ALLOW_GREENLIGHT_ACCOUNTS"]
# Fix endpoint format if required.
config.loadbalancer_endpoint += "/" unless config.bigbluebutton_endpoint.ends_with?("/")
@@ -111,5 +110,8 @@ module Greenlight
# Whether the user has defined the variables required for recaptcha
config.recaptcha_enabled = ENV['RECAPTCHA_SITE_KEY'].present? && ENV['RECAPTCHA_SECRET_KEY'].present?
+
+ # Show/hide "Add to Google Calendar" button in the room page
+ config.enable_google_calendar_button = (ENV['ENABLE_GOOGLE_CALENDAR_BUTTON'] == "true")
end
end
diff --git a/config/initializers/pagy.rb b/config/initializers/pagy.rb
index 243664a6..96e41565 100644
--- a/config/initializers/pagy.rb
+++ b/config/initializers/pagy.rb
@@ -13,7 +13,7 @@
# Array extra: Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
# See https://ddnexus.github.io/pagy/extras/array
-# require 'pagy/extras/array'
+require 'pagy/extras/array'
# Countless extra: Paginate without any count, saving one query per rendering
# See https://ddnexus.github.io/pagy/extras/countless
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 1c54de20..885afdc0 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -62,12 +62,14 @@ en:
uid: User ID
username: Username
title: Manage Users
+ add_to_google_calendar: "Add to Google Calendar"
bigbluebutton: BigBlueButton
bigbluebutton_exception: Oops, there was an error when starting the meeting!
cancel: Cancel
cookies:
cookie_info: Cookies help us deliver our services. By using our services, you agree to our use of cookies.
cookie_button: I Agree
+ copied: Copied
copy: Copy
default_admin: You are still using the default password for this account. Please click
here to change it
delete: Delete
diff --git a/lib/bbb_api.rb b/lib/bbb_api.rb
index d6b12fd2..46f9bdfd 100644
--- a/lib/bbb_api.rb
+++ b/lib/bbb_api.rb
@@ -73,10 +73,4 @@ module BbbApi
def remove_slash(s)
s.nil? ? nil : s.chomp("/")
end
-
- def launcher_allow_user_signup_whitelisted?(provider)
- return false unless Rails.configuration.launcher_allow_user_signup
- whitelist = Rails.configuration.launcher_allow_user_signup.split(',')
- whitelist.include?(provider)
- end
end
diff --git a/lib/tasks/configuration.rake b/lib/tasks/configuration.rake
index 0e9573ee..602f245c 100644
--- a/lib/tasks/configuration.rake
+++ b/lib/tasks/configuration.rake
@@ -24,7 +24,7 @@ namespace :conf do
# Tests the checksum on the getMeetings api call
print "Checking Secret"
checksum = Digest::SHA1.hexdigest("getMeetings#{ENV['BIGBLUEBUTTON_SECRET']}")
- test_request("#{ENV['BIGBLUEBUTTON_ENDPOINT']}api/getMeetings?checksum=#{checksum}")
+ test_request("#{ENV['BIGBLUEBUTTON_ENDPOINT']}getMeetings?checksum=#{checksum}")
passed
if ENV['ALLOW_MAIL_NOTIFICATIONS'] == 'true'
diff --git a/sample.env b/sample.env
index 59c80baf..b26beea9 100644
--- a/sample.env
+++ b/sample.env
@@ -139,6 +139,10 @@ PAGINATION_NUMBER=25
# Default is set to 10 rows
NUMBER_OF_ROWS=10
+# Specify if you want to display the Google Calendar button
+# ENABLE_GOOGLE_CALENDAR_BUTTON=true|false
+ENABLE_GOOGLE_CALENDAR_BUTTON=
+
# Comment this out to send logs to STDOUT in production instead of log/production.log .
#
# RAILS_LOG_TO_STDOUT=true
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 49e9fbd1..24c8cd0d 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -65,20 +65,9 @@ describe ApplicationHelper do
expect(helper.allow_greenlight_accounts?).to eql(false)
end
- it "allows if user_domain is white listed" do
- allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
- allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
- allow(helper).to receive(:launcher_allow_user_signup_whitelisted?).and_return(true)
-
- @user_domain = "provider1"
-
- expect(helper.allow_greenlight_accounts?).to eql(true)
- end
-
it "allows if user provider is set to greenlight" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
- allow(helper).to receive(:launcher_allow_user_signup_whitelisted?).and_return(false)
allow(helper).to receive(:retrieve_provider_info).and_return("provider" => "greenlight")
@user_domain = "provider1"
@@ -89,7 +78,6 @@ describe ApplicationHelper do
it "doesnt allow if user provider is not set to greenlight" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
- allow(helper).to receive(:launcher_allow_user_signup_whitelisted?).and_return(false)
allow(helper).to receive(:retrieve_provider_info).and_return("provider" => "google")
@user_domain = "provider1"
diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb
index d418b043..a95a9684 100644
--- a/spec/models/room_spec.rb
+++ b/spec/models/room_spec.rb
@@ -139,18 +139,414 @@ describe Room, type: :model do
{
name: "Example",
playback: {
- format: "presentation",
- },
- },
- ],
+ format:
+ {
+ type: "presentation"
+ }
+ }
+ }
+ ]
)
expect(@room.recordings).to contain_exactly(
name: "Example",
- playbacks: %w(presentation),
+ playbacks:
+ [
+ {
+ type: "presentation"
+ }
+ ]
)
end
+ context '#filtering' do
+ before do
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
+ recordings: [
+ {
+ name: "Example",
+ participants: "3",
+ playback: {
+ format:
+ {
+ type: "presentation"
+ }
+ },
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "aExamaaa",
+ participants: "5",
+ playback: {
+ format:
+ {
+ type: "other"
+ }
+ },
+ metadata: {
+ "gl-listed": "false",
+ }
+ },
+ {
+ name: "test",
+ participants: "1",
+ playback: {
+ format:
+ {
+ type: "presentation"
+ }
+ },
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "Exam",
+ participants: "1",
+ playback: {
+ format:
+ {
+ type: "other"
+ }
+ },
+ metadata: {
+ "gl-listed": "false",
+ name: "z",
+ }
+ }
+ ]
+ )
+ end
+
+ it "should filter recordings on name" do
+ expect(@room.recordings(search: "Exam")).to contain_exactly(
+ {
+ name: "aExamaaa",
+ participants: "5",
+ playbacks:
+ [
+ {
+ type: "other"
+ }
+ ],
+ metadata: {
+ "gl-listed": "false",
+ }
+ },
+ name: "Example",
+ participants: "3",
+ playbacks:
+ [
+ {
+ type: "presentation"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ )
+ end
+
+ it "should filter recordings on participants" do
+ expect(@room.recordings(search: "5")).to contain_exactly(
+ name: "aExamaaa",
+ participants: "5",
+ playbacks:
+ [
+ {
+ type: "other"
+ }
+ ],
+ metadata: {
+ "gl-listed": "false",
+ }
+ )
+ end
+
+ it "should filter recordings on format" do
+ expect(@room.recordings(search: "presentation")).to contain_exactly(
+ {
+ name: "test",
+ participants: "1",
+ playbacks:
+ [
+ {
+ type: "presentation"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ name: "Example",
+ participants: "3",
+ playbacks:
+ [
+ {
+ type: "presentation"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ )
+ end
+
+ it "should filter recordings on visibility" do
+ expect(@room.recordings(search: "public")).to contain_exactly(
+ {
+ name: "test",
+ participants: "1",
+ playbacks:
+ [
+ {
+ type: "presentation"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ },
+ },
+ name: "Example",
+ participants: "3",
+ playbacks:
+ [
+ {
+ type: "presentation"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ )
+ end
+
+ it "should filter recordings on metadata name by default" do
+ expect(@room.recordings(search: "z")).to contain_exactly(
+ name: "Exam",
+ participants: "1",
+ playbacks:
+ [
+ {
+ type: "other"
+ }
+ ],
+ metadata: {
+ "gl-listed": "false",
+ name: "z",
+ }
+ )
+ end
+ end
+
+ context '#sorting' do
+ before do
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
+ recordings: [
+ {
+ name: "Example",
+ participants: "3",
+ playback: {
+ format: {
+ type: "presentation",
+ length: "4"
+ }
+ },
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "aExamaaa",
+ participants: "1",
+ playback: {
+ format: {
+ type: "other",
+ length: "3"
+ }
+ },
+ metadata: {
+ name: "Z",
+ "gl-listed": "false"
+ }
+ }
+ ]
+ )
+ end
+
+ it "should sort recordings on name" do
+ expect(@room.recordings(column: "name", direction: "asc")).to eq(
+ [
+ {
+ name: "Example",
+ participants: "3",
+ playbacks: [
+ {
+ type: "presentation",
+ length: "4"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "aExamaaa",
+ participants: "1",
+ playbacks: [
+ {
+ type: "other",
+ length: "3"
+ }
+ ],
+ metadata: {
+ name: "Z",
+ "gl-listed": "false"
+ }
+ }
+ ]
+ )
+ end
+
+ it "should sort recordings on participants" do
+ expect(@room.recordings(column: "users", direction: "desc")).to eq(
+ [
+ {
+ name: "Example",
+ participants: "3",
+ playbacks: [
+ {
+ type: "presentation",
+ length: "4"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "aExamaaa",
+ participants: "1",
+ playbacks: [
+ {
+ type: "other",
+ length: "3"
+ }
+ ],
+ metadata: {
+ name: "Z",
+ "gl-listed": "false"
+ }
+ }
+ ]
+ )
+ end
+
+ it "should sort recordings on visibility" do
+ expect(@room.recordings(column: "visibility", direction: "desc")).to eq(
+ [
+ {
+ name: "Example",
+ participants: "3",
+ playbacks: [
+ {
+ type: "presentation",
+ length: "4"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "aExamaaa",
+ participants: "1",
+ playbacks: [
+ {
+ type: "other",
+ length: "3"
+ }
+ ],
+ metadata: {
+ name: "Z",
+ "gl-listed": "false"
+ }
+ }
+ ]
+ )
+ end
+
+ it "should sort recordings on length" do
+ expect(@room.recordings(column: "length", direction: "asc")).to eq(
+ [
+ {
+ name: "aExamaaa",
+ participants: "1",
+ playbacks: [
+ {
+ type: "other",
+ length: "3"
+ }
+ ],
+ metadata: {
+ name: "Z",
+ "gl-listed": "false"
+ }
+ },
+ {
+ name: "Example",
+ participants: "3",
+ playbacks: [
+ {
+ type: "presentation",
+ length: "4"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ }
+ ]
+ )
+ end
+
+ it "should sort recordings on format" do
+ expect(@room.recordings(column: "formats", direction: "desc")).to eq(
+ [
+ {
+ name: "Example",
+ participants: "3",
+ playbacks: [
+ {
+ type: "presentation",
+ length: "4"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "aExamaaa",
+ participants: "1",
+ playbacks: [
+ {
+ type: "other",
+ length: "3"
+ }
+ ],
+ metadata: {
+ name: "Z",
+ "gl-listed": "false"
+ }
+ }
+ ]
+ )
+ end
+ end
+
it "deletes the recording" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
returncode: true, deleted: true
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index fefb0b20..dc38dc11 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -173,4 +173,97 @@ describe User, type: :model do
.to raise_exception(ActiveRecord::RecordInvalid, "Validation failed: Email can't be blank")
end
end
+
+ context '#recordings' do
+ it "gets all filtered and sorted recordings for the user" do
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
+ recordings: [
+ {
+ name: "Example",
+ participants: "3",
+ playback: {
+ format:
+ {
+ type: "presentation"
+ }
+ },
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "aExamaaa",
+ participants: "5",
+ playback: {
+ format:
+ {
+ type: "other"
+ }
+ },
+ metadata: {
+ "gl-listed": "false",
+ }
+ },
+ {
+ name: "test",
+ participants: "1",
+ playback: {
+ format:
+ {
+ type: "presentation"
+ }
+ },
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "Exam",
+ participants: "1",
+ playback: {
+ format:
+ {
+ type: "other"
+ }
+ },
+ metadata: {
+ "gl-listed": "false",
+ name: "z",
+ }
+ }
+ ]
+ )
+
+ expect(@user.all_recordings(search: "Exam", column: "name", direction: "desc")).to eq(
+ [
+ {
+ name: "Example",
+ participants: "3",
+ playbacks:
+ [
+ {
+ type: "presentation"
+ }
+ ],
+ metadata: {
+ "gl-listed": "true",
+ }
+ },
+ {
+ name: "aExamaaa",
+ participants: "5",
+ playbacks:
+ [
+ {
+ type: "other"
+ }
+ ],
+ metadata: {
+ "gl-listed": "false",
+ }
+ }
+ ]
+ )
+ end
+ end
end
diff --git a/vendor/assets/images/colourPicker/blank.gif b/vendor/assets/images/colourPicker/blank.gif
new file mode 100644
index 00000000..75b945d2
Binary files /dev/null and b/vendor/assets/images/colourPicker/blank.gif differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_background.png b/vendor/assets/images/colourPicker/colorpicker_background.png
new file mode 100644
index 00000000..8401572f
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_background.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_hex.png b/vendor/assets/images/colourPicker/colorpicker_hex.png
new file mode 100644
index 00000000..4e532d7c
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_hex.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_hsb_b.png b/vendor/assets/images/colourPicker/colorpicker_hsb_b.png
new file mode 100644
index 00000000..dfac595d
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_hsb_b.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_hsb_h.png b/vendor/assets/images/colourPicker/colorpicker_hsb_h.png
new file mode 100644
index 00000000..3977ed9f
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_hsb_h.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_hsb_s.png b/vendor/assets/images/colourPicker/colorpicker_hsb_s.png
new file mode 100644
index 00000000..a2a69973
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_hsb_s.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_indic.gif b/vendor/assets/images/colourPicker/colorpicker_indic.gif
new file mode 100644
index 00000000..f9fa95e2
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_indic.gif differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_overlay.png b/vendor/assets/images/colourPicker/colorpicker_overlay.png
new file mode 100644
index 00000000..561cdd9c
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_overlay.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_rgb_b.png b/vendor/assets/images/colourPicker/colorpicker_rgb_b.png
new file mode 100644
index 00000000..dfac595d
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_rgb_b.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_rgb_g.png b/vendor/assets/images/colourPicker/colorpicker_rgb_g.png
new file mode 100644
index 00000000..72b32760
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_rgb_g.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_rgb_r.png b/vendor/assets/images/colourPicker/colorpicker_rgb_r.png
new file mode 100644
index 00000000..4855fe03
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_rgb_r.png differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_select.gif b/vendor/assets/images/colourPicker/colorpicker_select.gif
new file mode 100644
index 00000000..599f7f13
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_select.gif differ
diff --git a/vendor/assets/images/colourPicker/colorpicker_submit.png b/vendor/assets/images/colourPicker/colorpicker_submit.png
new file mode 100644
index 00000000..7f4c0825
Binary files /dev/null and b/vendor/assets/images/colourPicker/colorpicker_submit.png differ
diff --git a/vendor/assets/images/colourPicker/custom_background.png b/vendor/assets/images/colourPicker/custom_background.png
new file mode 100644
index 00000000..cf55ffdd
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_background.png differ
diff --git a/vendor/assets/images/colourPicker/custom_hex.png b/vendor/assets/images/colourPicker/custom_hex.png
new file mode 100644
index 00000000..888f4444
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_hex.png differ
diff --git a/vendor/assets/images/colourPicker/custom_hsb_b.png b/vendor/assets/images/colourPicker/custom_hsb_b.png
new file mode 100644
index 00000000..2f99dae8
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_hsb_b.png differ
diff --git a/vendor/assets/images/colourPicker/custom_hsb_h.png b/vendor/assets/images/colourPicker/custom_hsb_h.png
new file mode 100644
index 00000000..a217e921
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_hsb_h.png differ
diff --git a/vendor/assets/images/colourPicker/custom_hsb_s.png b/vendor/assets/images/colourPicker/custom_hsb_s.png
new file mode 100644
index 00000000..7826b415
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_hsb_s.png differ
diff --git a/vendor/assets/images/colourPicker/custom_indic.gif b/vendor/assets/images/colourPicker/custom_indic.gif
new file mode 100644
index 00000000..222fb94c
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_indic.gif differ
diff --git a/vendor/assets/images/colourPicker/custom_rgb_b.png b/vendor/assets/images/colourPicker/custom_rgb_b.png
new file mode 100644
index 00000000..80764e5d
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_rgb_b.png differ
diff --git a/vendor/assets/images/colourPicker/custom_rgb_g.png b/vendor/assets/images/colourPicker/custom_rgb_g.png
new file mode 100644
index 00000000..fc9778be
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_rgb_g.png differ
diff --git a/vendor/assets/images/colourPicker/custom_rgb_r.png b/vendor/assets/images/colourPicker/custom_rgb_r.png
new file mode 100644
index 00000000..91b0cd4c
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_rgb_r.png differ
diff --git a/vendor/assets/images/colourPicker/custom_submit.png b/vendor/assets/images/colourPicker/custom_submit.png
new file mode 100644
index 00000000..cd202cd9
Binary files /dev/null and b/vendor/assets/images/colourPicker/custom_submit.png differ
diff --git a/vendor/assets/images/colourPicker/select.png b/vendor/assets/images/colourPicker/select.png
new file mode 100644
index 00000000..21213bfd
Binary files /dev/null and b/vendor/assets/images/colourPicker/select.png differ
diff --git a/vendor/assets/images/colourPicker/select2.png b/vendor/assets/images/colourPicker/select2.png
new file mode 100644
index 00000000..2cd2cabe
Binary files /dev/null and b/vendor/assets/images/colourPicker/select2.png differ
diff --git a/vendor/assets/images/colourPicker/slider.png b/vendor/assets/images/colourPicker/slider.png
new file mode 100644
index 00000000..8b03da96
Binary files /dev/null and b/vendor/assets/images/colourPicker/slider.png differ
diff --git a/vendor/assets/javascripts/colorpicker.js b/vendor/assets/javascripts/colorpicker.js
new file mode 100644
index 00000000..45f56ced
--- /dev/null
+++ b/vendor/assets/javascripts/colorpicker.js
@@ -0,0 +1,484 @@
+/**
+ *
+ * Color picker
+ * Author: Stefan Petre www.eyecon.ro
+ *
+ * Dual licensed under the MIT and GPL licenses
+ *
+ */
+(function ($) {
+ var ColorPicker = function () {
+ var
+ ids = {},
+ inAction,
+ charMin = 65,
+ visible,
+ tpl = '
',
+ defaults = {
+ eventName: 'click',
+ onShow: function () {},
+ onBeforeShow: function(){},
+ onHide: function () {},
+ onChange: function () {},
+ onSubmit: function () {},
+ color: 'ff0000',
+ livePreview: true,
+ flat: false
+ },
+ fillRGBFields = function (hsb, cal) {
+ var rgb = HSBToRGB(hsb);
+ $(cal).data('colorpicker').fields
+ .eq(1).val(rgb.r).end()
+ .eq(2).val(rgb.g).end()
+ .eq(3).val(rgb.b).end();
+ },
+ fillHSBFields = function (hsb, cal) {
+ $(cal).data('colorpicker').fields
+ .eq(4).val(hsb.h).end()
+ .eq(5).val(hsb.s).end()
+ .eq(6).val(hsb.b).end();
+ },
+ fillHexFields = function (hsb, cal) {
+ $(cal).data('colorpicker').fields
+ .eq(0).val(HSBToHex(hsb)).end();
+ },
+ setSelector = function (hsb, cal) {
+ $(cal).data('colorpicker').selector.css('backgroundColor', '#' + HSBToHex({h: hsb.h, s: 100, b: 100}));
+ $(cal).data('colorpicker').selectorIndic.css({
+ left: parseInt(150 * hsb.s/100, 10),
+ top: parseInt(150 * (100-hsb.b)/100, 10)
+ });
+ },
+ setHue = function (hsb, cal) {
+ $(cal).data('colorpicker').hue.css('top', parseInt(150 - 150 * hsb.h/360, 10));
+ },
+ setCurrentColor = function (hsb, cal) {
+ $(cal).data('colorpicker').currentColor.css('backgroundColor', '#' + HSBToHex(hsb));
+ },
+ setNewColor = function (hsb, cal) {
+ $(cal).data('colorpicker').newColor.css('backgroundColor', '#' + HSBToHex(hsb));
+ },
+ keyDown = function (ev) {
+ var pressedKey = ev.charCode || ev.keyCode || -1;
+ if ((pressedKey > charMin && pressedKey <= 90) || pressedKey == 32) {
+ return false;
+ }
+ var cal = $(this).parent().parent();
+ if (cal.data('colorpicker').livePreview === true) {
+ change.apply(this);
+ }
+ },
+ change = function (ev) {
+ var cal = $(this).parent().parent(), col;
+ if (this.parentNode.className.indexOf('_hex') > 0) {
+ cal.data('colorpicker').color = col = HexToHSB(fixHex(this.value));
+ } else if (this.parentNode.className.indexOf('_hsb') > 0) {
+ cal.data('colorpicker').color = col = fixHSB({
+ h: parseInt(cal.data('colorpicker').fields.eq(4).val(), 10),
+ s: parseInt(cal.data('colorpicker').fields.eq(5).val(), 10),
+ b: parseInt(cal.data('colorpicker').fields.eq(6).val(), 10)
+ });
+ } else {
+ cal.data('colorpicker').color = col = RGBToHSB(fixRGB({
+ r: parseInt(cal.data('colorpicker').fields.eq(1).val(), 10),
+ g: parseInt(cal.data('colorpicker').fields.eq(2).val(), 10),
+ b: parseInt(cal.data('colorpicker').fields.eq(3).val(), 10)
+ }));
+ }
+ if (ev) {
+ fillRGBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ }
+ setSelector(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ cal.data('colorpicker').onChange.apply(cal, [col, HSBToHex(col), HSBToRGB(col)]);
+ },
+ blur = function (ev) {
+ var cal = $(this).parent().parent();
+ cal.data('colorpicker').fields.parent().removeClass('colorpicker_focus');
+ },
+ focus = function () {
+ charMin = this.parentNode.className.indexOf('_hex') > 0 ? 70 : 65;
+ $(this).parent().parent().data('colorpicker').fields.parent().removeClass('colorpicker_focus');
+ $(this).parent().addClass('colorpicker_focus');
+ },
+ downIncrement = function (ev) {
+ var field = $(this).parent().find('input').focus();
+ var current = {
+ el: $(this).parent().addClass('colorpicker_slider'),
+ max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255),
+ y: ev.pageY,
+ field: field,
+ val: parseInt(field.val(), 10),
+ preview: $(this).parent().parent().data('colorpicker').livePreview
+ };
+ $(document).bind('mouseup', current, upIncrement);
+ $(document).bind('mousemove', current, moveIncrement);
+ },
+ moveIncrement = function (ev) {
+ ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val + ev.pageY - ev.data.y, 10))));
+ if (ev.data.preview) {
+ change.apply(ev.data.field.get(0), [true]);
+ }
+ return false;
+ },
+ upIncrement = function (ev) {
+ change.apply(ev.data.field.get(0), [true]);
+ ev.data.el.removeClass('colorpicker_slider').find('input').focus();
+ $(document).unbind('mouseup', upIncrement);
+ $(document).unbind('mousemove', moveIncrement);
+ return false;
+ },
+ downHue = function (ev) {
+ var current = {
+ cal: $(this).parent(),
+ y: $(this).offset().top
+ };
+ current.preview = current.cal.data('colorpicker').livePreview;
+ $(document).bind('mouseup', current, upHue);
+ $(document).bind('mousemove', current, moveHue);
+ },
+ moveHue = function (ev) {
+ change.apply(
+ ev.data.cal.data('colorpicker')
+ .fields
+ .eq(4)
+ .val(parseInt(360*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.y))))/150, 10))
+ .get(0),
+ [ev.data.preview]
+ );
+ return false;
+ },
+ upHue = function (ev) {
+ fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ $(document).unbind('mouseup', upHue);
+ $(document).unbind('mousemove', moveHue);
+ return false;
+ },
+ downSelector = function (ev) {
+ var current = {
+ cal: $(this).parent(),
+ pos: $(this).offset()
+ };
+ current.preview = current.cal.data('colorpicker').livePreview;
+ $(document).bind('mouseup', current, upSelector);
+ $(document).bind('mousemove', current, moveSelector);
+ },
+ moveSelector = function (ev) {
+ change.apply(
+ ev.data.cal.data('colorpicker')
+ .fields
+ .eq(6)
+ .val(parseInt(100*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.pos.top))))/150, 10))
+ .end()
+ .eq(5)
+ .val(parseInt(100*(Math.max(0,Math.min(150,(ev.pageX - ev.data.pos.left))))/150, 10))
+ .get(0),
+ [ev.data.preview]
+ );
+ return false;
+ },
+ upSelector = function (ev) {
+ fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ $(document).unbind('mouseup', upSelector);
+ $(document).unbind('mousemove', moveSelector);
+ return false;
+ },
+ enterSubmit = function (ev) {
+ $(this).addClass('colorpicker_focus');
+ },
+ leaveSubmit = function (ev) {
+ $(this).removeClass('colorpicker_focus');
+ },
+ clickSubmit = function (ev) {
+ var cal = $(this).parent();
+ var col = cal.data('colorpicker').color;
+ cal.data('colorpicker').origColor = col;
+ setCurrentColor(col, cal.get(0));
+ cal.data('colorpicker').onSubmit(col, HSBToHex(col), HSBToRGB(col), cal.data('colorpicker').el);
+ },
+ show = function (ev) {
+ var cal = $('#' + $(this).data('colorpickerId'));
+ cal.data('colorpicker').onBeforeShow.apply(this, [cal.get(0)]);
+ var pos = $(this).offset();
+ var viewPort = getViewport();
+ var top = pos.top + this.offsetHeight;
+ var left = pos.left;
+ if (top + 176 > viewPort.t + viewPort.h) {
+ top -= this.offsetHeight + 176;
+ }
+ if (left + 356 > viewPort.l + viewPort.w) {
+ left -= 356;
+ }
+ cal.css({left: left + 'px', top: top + 'px'});
+ if (cal.data('colorpicker').onShow.apply(this, [cal.get(0)]) != false) {
+ cal.show();
+ }
+ $(document).bind('mousedown', {cal: cal}, hide);
+ return false;
+ },
+ hide = function (ev) {
+ if (!isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {
+ if (ev.data.cal.data('colorpicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) {
+ ev.data.cal.hide();
+ }
+ $(document).unbind('mousedown', hide);
+ }
+ },
+ isChildOf = function(parentEl, el, container) {
+ if (parentEl == el) {
+ return true;
+ }
+ if (parentEl.contains) {
+ return parentEl.contains(el);
+ }
+ if ( parentEl.compareDocumentPosition ) {
+ return !!(parentEl.compareDocumentPosition(el) & 16);
+ }
+ var prEl = el.parentNode;
+ while(prEl && prEl != container) {
+ if (prEl == parentEl)
+ return true;
+ prEl = prEl.parentNode;
+ }
+ return false;
+ },
+ getViewport = function () {
+ var m = document.compatMode == 'CSS1Compat';
+ return {
+ l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
+ t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),
+ w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),
+ h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)
+ };
+ },
+ fixHSB = function (hsb) {
+ return {
+ h: Math.min(360, Math.max(0, hsb.h)),
+ s: Math.min(100, Math.max(0, hsb.s)),
+ b: Math.min(100, Math.max(0, hsb.b))
+ };
+ },
+ fixRGB = function (rgb) {
+ return {
+ r: Math.min(255, Math.max(0, rgb.r)),
+ g: Math.min(255, Math.max(0, rgb.g)),
+ b: Math.min(255, Math.max(0, rgb.b))
+ };
+ },
+ fixHex = function (hex) {
+ var len = 6 - hex.length;
+ if (len > 0) {
+ var o = [];
+ for (var i=0; i
-1) ? hex.substring(1) : hex), 16);
+ return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)};
+ },
+ HexToHSB = function (hex) {
+ return RGBToHSB(HexToRGB(hex));
+ },
+ RGBToHSB = function (rgb) {
+ var hsb = {
+ h: 0,
+ s: 0,
+ b: 0
+ };
+ var min = Math.min(rgb.r, rgb.g, rgb.b);
+ var max = Math.max(rgb.r, rgb.g, rgb.b);
+ var delta = max - min;
+ hsb.b = max;
+ if (max != 0) {
+
+ }
+ hsb.s = max != 0 ? 255 * delta / max : 0;
+ if (hsb.s != 0) {
+ if (rgb.r == max) {
+ hsb.h = (rgb.g - rgb.b) / delta;
+ } else if (rgb.g == max) {
+ hsb.h = 2 + (rgb.b - rgb.r) / delta;
+ } else {
+ hsb.h = 4 + (rgb.r - rgb.g) / delta;
+ }
+ } else {
+ hsb.h = -1;
+ }
+ hsb.h *= 60;
+ if (hsb.h < 0) {
+ hsb.h += 360;
+ }
+ hsb.s *= 100/255;
+ hsb.b *= 100/255;
+ return hsb;
+ },
+ HSBToRGB = function (hsb) {
+ var rgb = {};
+ var h = Math.round(hsb.h);
+ var s = Math.round(hsb.s*255/100);
+ var v = Math.round(hsb.b*255/100);
+ if(s == 0) {
+ rgb.r = rgb.g = rgb.b = v;
+ } else {
+ var t1 = v;
+ var t2 = (255-s)*v/255;
+ var t3 = (t1-t2)*(h%60)/60;
+ if(h==360) h = 0;
+ if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3}
+ else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3}
+ else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3}
+ else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3}
+ else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3}
+ else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3}
+ else {rgb.r=0; rgb.g=0; rgb.b=0}
+ }
+ return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)};
+ },
+ RGBToHex = function (rgb) {
+ var hex = [
+ rgb.r.toString(16),
+ rgb.g.toString(16),
+ rgb.b.toString(16)
+ ];
+ $.each(hex, function (nr, val) {
+ if (val.length == 1) {
+ hex[nr] = '0' + val;
+ }
+ });
+ return hex.join('');
+ },
+ HSBToHex = function (hsb) {
+ return RGBToHex(HSBToRGB(hsb));
+ },
+ restoreOriginal = function () {
+ var cal = $(this).parent();
+ var col = cal.data('colorpicker').origColor;
+ cal.data('colorpicker').color = col;
+ fillRGBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ setSelector(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ };
+ return {
+ init: function (opt) {
+ opt = $.extend({}, defaults, opt||{});
+ if (typeof opt.color == 'string') {
+ opt.color = HexToHSB(opt.color);
+ } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) {
+ opt.color = RGBToHSB(opt.color);
+ } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) {
+ opt.color = fixHSB(opt.color);
+ } else {
+ return this;
+ }
+ return this.each(function () {
+ if (!$(this).data('colorpickerId')) {
+ var options = $.extend({}, opt);
+ options.origColor = opt.color;
+ var id = 'collorpicker_' + parseInt(Math.random() * 1000);
+ $(this).data('colorpickerId', id);
+ var cal = $(tpl).attr('id', id);
+ if (options.flat) {
+ cal.appendTo(this).show();
+ } else {
+ cal.appendTo(document.body);
+ }
+ options.fields = cal
+ .find('input')
+ .bind('keyup', keyDown)
+ .bind('change', change)
+ .bind('blur', blur)
+ .bind('focus', focus);
+ cal
+ .find('span').bind('mousedown', downIncrement).end()
+ .find('>div.colorpicker_current_color').bind('click', restoreOriginal);
+ options.selector = cal.find('div.colorpicker_color').bind('mousedown', downSelector);
+ options.selectorIndic = options.selector.find('div div');
+ options.el = this;
+ options.hue = cal.find('div.colorpicker_hue div');
+ cal.find('div.colorpicker_hue').bind('mousedown', downHue);
+ options.newColor = cal.find('div.colorpicker_new_color');
+ options.currentColor = cal.find('div.colorpicker_current_color');
+ cal.data('colorpicker', options);
+ cal.find('div.colorpicker_submit')
+ .bind('mouseenter', enterSubmit)
+ .bind('mouseleave', leaveSubmit)
+ .bind('click', clickSubmit);
+ fillRGBFields(options.color, cal.get(0));
+ fillHSBFields(options.color, cal.get(0));
+ fillHexFields(options.color, cal.get(0));
+ setHue(options.color, cal.get(0));
+ setSelector(options.color, cal.get(0));
+ setCurrentColor(options.color, cal.get(0));
+ setNewColor(options.color, cal.get(0));
+ if (options.flat) {
+ cal.css({
+ position: 'relative',
+ display: 'block'
+ });
+ } else {
+ $(this).bind(options.eventName, show);
+ }
+ }
+ });
+ },
+ showPicker: function() {
+ return this.each( function () {
+ if ($(this).data('colorpickerId')) {
+ show.apply(this);
+ }
+ });
+ },
+ hidePicker: function() {
+ return this.each( function () {
+ if ($(this).data('colorpickerId')) {
+ $('#' + $(this).data('colorpickerId')).hide();
+ }
+ });
+ },
+ setColor: function(col) {
+ if (typeof col == 'string') {
+ col = HexToHSB(col);
+ } else if (col.r != undefined && col.g != undefined && col.b != undefined) {
+ col = RGBToHSB(col);
+ } else if (col.h != undefined && col.s != undefined && col.b != undefined) {
+ col = fixHSB(col);
+ } else {
+ return this;
+ }
+ return this.each(function(){
+ if ($(this).data('colorpickerId')) {
+ var cal = $('#' + $(this).data('colorpickerId'));
+ cal.data('colorpicker').color = col;
+ cal.data('colorpicker').origColor = col;
+ fillRGBFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setSelector(col, cal.get(0));
+ setCurrentColor(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ }
+ });
+ }
+ };
+ }();
+ $.fn.extend({
+ ColorPicker: ColorPicker.init,
+ ColorPickerHide: ColorPicker.hidePicker,
+ ColorPickerShow: ColorPicker.showPicker,
+ ColorPickerSetColor: ColorPicker.setColor
+ });
+})(jQuery)
\ No newline at end of file
diff --git a/vendor/assets/stylesheets/colorpicker.scss b/vendor/assets/stylesheets/colorpicker.scss
new file mode 100644
index 00000000..57022942
--- /dev/null
+++ b/vendor/assets/stylesheets/colorpicker.scss
@@ -0,0 +1,161 @@
+.colorpicker {
+ width: 356px;
+ height: 176px;
+ overflow: hidden;
+ position: absolute;
+ background: image-url("colourPicker/colorpicker_background.png");
+ font-family: Arial, Helvetica, sans-serif;
+ display: none;
+}
+.colorpicker_color {
+ width: 150px;
+ height: 150px;
+ left: 14px;
+ top: 13px;
+ position: absolute;
+ background: #f00;
+ overflow: hidden;
+ cursor: crosshair;
+}
+.colorpicker_color div {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 150px;
+ height: 150px;
+ background: image-url("colourPicker/colorpicker_overlay.png");
+}
+.colorpicker_color div div {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 11px;
+ height: 11px;
+ overflow: hidden;
+ background: image-url("colourPicker/colorpicker_select.gif");
+ margin: -5px 0 0 -5px;
+}
+.colorpicker_hue {
+ position: absolute;
+ top: 13px;
+ left: 171px;
+ width: 35px;
+ height: 150px;
+ cursor: n-resize;
+}
+.colorpicker_hue div {
+ position: absolute;
+ width: 35px;
+ height: 9px;
+ overflow: hidden;
+ background: image-url("colourPicker/colorpicker_indic.gif") left top;
+ margin: -4px 0 0 0;
+ left: 0px;
+}
+.colorpicker_new_color {
+ position: absolute;
+ width: 60px;
+ height: 30px;
+ left: 213px;
+ top: 13px;
+ background: #f00;
+}
+.colorpicker_current_color {
+ position: absolute;
+ width: 60px;
+ height: 30px;
+ left: 283px;
+ top: 13px;
+ background: #f00;
+}
+.colorpicker input {
+ background-color: transparent;
+ border: 1px solid transparent;
+ position: absolute;
+ font-size: 10px;
+ font-family: Arial, Helvetica, sans-serif;
+ color: #898989;
+ top: 4px;
+ right: 11px;
+ text-align: right;
+ margin: 0;
+ padding: 0;
+ height: 11px;
+}
+.colorpicker_hex {
+ position: absolute;
+ width: 72px;
+ height: 22px;
+ background: image-url("colourPicker/colorpicker_hex.png") top;
+ left: 212px;
+ top: 142px;
+}
+.colorpicker_hex input {
+ right: 6px;
+}
+.colorpicker_field {
+ height: 22px;
+ width: 62px;
+ background-position: top;
+ position: absolute;
+}
+.colorpicker_field span {
+ position: absolute;
+ width: 12px;
+ height: 22px;
+ overflow: hidden;
+ top: 0;
+ right: 0;
+ cursor: n-resize;
+}
+.colorpicker_rgb_r {
+ background-image: image-url("colourPicker/colorpicker_rgb_r.png");
+ top: 52px;
+ left: 212px;
+}
+.colorpicker_rgb_g {
+ background-image: image-url("colourPicker/colorpicker_rgb_g.png");
+ top: 82px;
+ left: 212px;
+}
+.colorpicker_rgb_b {
+ background-image: image-url("colourPicker/colorpicker_rgb_b.png");
+ top: 112px;
+ left: 212px;
+}
+.colorpicker_hsb_h {
+ background-image: image-url("colourPicker/colorpicker_hsb_h.png");
+ top: 52px;
+ left: 282px;
+}
+.colorpicker_hsb_s {
+ background-image: image-url("colourPicker/colorpicker_hsb_s.png");
+ top: 82px;
+ left: 282px;
+}
+.colorpicker_hsb_b {
+ background-image: image-url("colourPicker/colorpicker_hsb_b.png");
+ top: 112px;
+ left: 282px;
+}
+.colorpicker_submit {
+ position: absolute;
+ width: 22px;
+ height: 22px;
+ background: image-url("colourPicker/colorpicker_submit.png") top;
+ left: 322px;
+ top: 142px;
+ overflow: hidden;
+}
+.colorpicker_focus {
+ background-position: center;
+}
+.colorpicker_hex.colorpicker_focus {
+ background-position: bottom;
+}
+.colorpicker_submit.colorpicker_focus {
+ background-position: bottom;
+}
+.colorpicker_slider {
+ background-position: bottom;
+}