diff --git a/.prettierignore b/.prettierignore index d96cfe97..6c9ab6ff 100644 --- a/.prettierignore +++ b/.prettierignore @@ -9,5 +9,4 @@ log/ missions/ node_modules/ super-ui/ -var/www/public/chiselchat/ var/www/public/starmap/js/ diff --git a/CLAUDE.md b/CLAUDE.md index cdf24bfb..59a0be16 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -97,15 +97,15 @@ To add a new building, follow the checklist in `info/add_a_building.txt` (DB::Re `Lacuna::RPC` extends `JSON::RPC::Dispatcher::App`. It resolves sessions (`get_session`, via `Lacuna::Session`), checks body/building/sitter permissions, and rate-limits via `Lacuna->cache`. -`lib/Lacuna/RPC/*.pm` = top-level game endpoints (`Empire`, `Body`, `Map`, `Alliance`, `Chat`, `Stats`, ...). +`lib/Lacuna/RPC/*.pm` = top-level game endpoints (`Empire`, `Body`, `Map`, `Alliance`, `Stats`, ...). `lib/Lacuna/RPC/Building/*.pm` (156 files) = one thin controller per building type, declaring `app_url`/`model_class` and inheriting generic behavior from `lib/Lacuna/RPC/Building.pm`. RPC methods take `($self, $session_id, ...)`, whitelist themselves via `register_rpc_method_names`, and return a hashref including `status => $self->format_status($session)`. Separate from the JSON-RPC API, `lib/Lacuna/Web.pm` (extends `Plack::Component`) does simple path-based dispatch -(`/foo/bar` → `www_foo_bar`) for HTML-facing endpoints under `lib/Lacuna/Web/*.pm` (`Admin`, `Pay`, `Chat`, `Facebook`, -`Announcement`, ...). +(`/foo/bar` → `www_foo_bar`) for HTML-facing endpoints under `lib/Lacuna/Web/*.pm` (`Admin`, `Pay`, `Announcement`, +...). `bin/lacuna.psgi` is where RPC/Web modules get mounted into the Plack app. diff --git a/bin/chat_alliance_room.pl b/bin/chat_alliance_room.pl deleted file mode 100644 index d4f8f629..00000000 --- a/bin/chat_alliance_room.pl +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/env perl - -use strict; -use Firebase; -use Config::JSON; -use Getopt::Long; -use feature 'say'; -use Data::Dumper; - -GetOptions( - 'config=s' => \my $config_file, - 'alliance-id=s'=> \my $alliance_id, - 'alliance-name=s'=> \my $alliance_name, - 'empire-id=s' => \my $empire_id, -); - - -unless ($config_file && $alliance_id && $alliance_name && $empire_id) { - say "Usage: $0 --config=/path/to/config.json --alliance-id=xxx --alliance-name='Big Cool Guys' --empire-id=yyy"; - exit; -} - -say "Reading config."; -my $config = Config::JSON->new($config_file)->get('firebase'); - -say "Connecting to Firebase."; -my $firebase = Firebase->new(%{$config}); - -say "Fetching room."; -my $room = $firebase->get('room-metadata/'.$alliance_id); -if (defined $room) { - say "Authorizing empire."; - $firebase->patch('room-metadata/'.$alliance_id.'/authorizedUsers', { - $empire_id => \1 - }); -} -else { - say "Creating room."; - $firebase->put('room-metadata/'.$alliance_id, { - id => $alliance_id, - name => $alliance_name, - type => 'private', - createdByUserId => $empire_id, - '.priority' => {'.sv' => 'timestamp'}, - authorizedUsers => {$empire_id => \1}, - }); -} - -say "Adding room to user's list of rooms."; -$firebase->put('users/'.$empire_id.'/rooms/'.$alliance_id, { - id => $alliance_id, - active => \1, - name => $alliance_name, -}); - diff --git a/bin/chat_clean_old_rooms.pl b/bin/chat_clean_old_rooms.pl deleted file mode 100644 index 66f8fda7..00000000 --- a/bin/chat_clean_old_rooms.pl +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/env perl - -use strict; -use Firebase; -use Config::JSON; -use Getopt::Long; -use feature 'say'; -use Data::Dumper; - -GetOptions( - 'config=s' =>, \my $config_file, -); - - -unless ($config_file) { - say "Usage: $0 --config=/path/to/config.json"; - exit; -} - -say "Reading config."; -my $config = Config::JSON->new($config_file)->get('firebase'); - -say "Connecting to Firebase."; -my $firebase = Firebase->new(%{$config}); - -say "Fetching rooms."; -my $rooms = $firebase->get('room-metadata'); - -say "Fetching users attached to rooms."; -my $room_users = $firebase->get('room-users'); - -say "Deleting abandoned rooms."; -my %room_clear; -my %room_keep; -foreach my $room (keys %{$rooms}) { - if ($rooms->{$room}{type} eq 'official') { - say "Skipping ".$rooms->{$room}{name}.", because it's an official room."; - } - elsif (exists $room_users->{$room}) { - if ($room_keep{"$rooms->{$room}{name}"}) { - $room_keep{"$rooms->{$room}{name}"} += 1; - } - else { - $room_keep{"$rooms->{$room}{name}"} = 1; - } - } - else { - if ($room_clear{"$rooms->{$room}{name}"}) { - $room_clear{"$rooms->{$room}{name}"} += 1; - } - else { - $room_clear{"$rooms->{$room}{name}"} = 1; - } - $firebase->delete('room-messages/'.$room); - $firebase->delete('room-metadata/'.$room); - } -} -foreach my $key (sort keys %room_clear) { - say "Deleted ".$key." ".$room_clear{"$key"}."."; -} -foreach my $key (sort keys %room_keep) { - say "Skipping ".$key." ".$room_keep{"$key"}."."; -} diff --git a/bin/chat_clr_suspension.pl b/bin/chat_clr_suspension.pl deleted file mode 100644 index 09277f38..00000000 --- a/bin/chat_clr_suspension.pl +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/env perl - -use strict; -use Firebase; -use Config::JSON; -use Getopt::Long; -use feature 'say'; -use Data::Dumper; - -GetOptions( - 'config=s' =>, \my $config_file, -); - - -unless ($config_file) { - say "Usage: $0 --config=/path/to/config.json"; - exit; -} - -say "Reading config."; -my $config = Config::JSON->new($config_file)->get('firebase'); - -say "Connecting to Firebase."; -my $firebase = Firebase->new(%{$config}); - -say "Fetching rooms."; -my $susp = $firebase->get('suspensions'); - -say "Clearing Suspensions."; -foreach my $user (keys %{$susp}) { - say "Clearing ".$user; - $firebase->delete('suspensions/'.$user); -} - - diff --git a/bin/lacuna.psgi b/bin/lacuna.psgi index 16024233..b10f4d7c 100644 --- a/bin/lacuna.psgi +++ b/bin/lacuna.psgi @@ -87,11 +87,8 @@ my $app = builder { mount "/inbox" => Lacuna::RPC::Inbox->new->to_app; mount "/stats" => Lacuna::RPC::Stats->new->to_app; mount "/pay" => Lacuna::Web::Pay->new->to_app; - mount "/chat" => Lacuna::Web::Chat->new->to_app; - mount "/chat/rpc" => Lacuna::RPC::Chat->new->to_app; mount "/entertainment/vote" => Lacuna::Web::EntertainmentVote->new->to_app; mount "/announcement" => Lacuna::Web::Announcement->new->to_app; - mount "/facebook" => Lacuna::Web::Facebook->new->to_app; mount "/apikey" => Lacuna::Web::ApiKey->new->to_app; mount "/essentia-code" => Lacuna::RPC::EssentiaCode->new->to_app; mount "/captcha" => Lacuna::RPC::Captcha->new->to_app; diff --git a/bin/setup/install-pm.sh b/bin/setup/install-pm.sh index 8d71c0ed..3ebf6257 100755 --- a/bin/setup/install-pm.sh +++ b/bin/setup/install-pm.sh @@ -1,11 +1,11 @@ -cpanm AnyEvent Email::Valid Chat::Envolve Text::CSV_XS Log::Log4perl UUID::Tiny DateTime::Format::MySQL DBIx::Class::TimeStamp +cpanm AnyEvent Email::Valid Text::CSV_XS Log::Log4perl UUID::Tiny DateTime::Format::MySQL DBIx::Class::TimeStamp cpanm JSON::XS JSON Config::JSON Starman JSON::RPC::Dispatcher Log::Any::Adapter Log::Any::Adapter::Log4perl String::Random cpanm List::Util::WeightedChoice List::Util List::MoreUtils DateTime Regexp::Common Pod::Simple::HTML File::Copy cpanm DateTime::Format::Duration XML::FeedPP SOAP::Amazon::S3 DBD::mysql DBIx::Class JSON::Any DBIx::Class::InflateColumn::Serializer cpanm DBIx::Class::DynamicSubclass Memcached::libmemcached Server::Starter IO::Socket::SSL Net::Server::SS::PreFork -cpanm Email::Stuff Facebook::Graph File::Path namespace::autoclean Clone Plack::Middleware::CrossOrigin Net::Amazon::S3 -cpanm Path::Class Git::Wrapper Guard Digest::MD5 Digest::HMAC_SHA1 XML::Hash::LX Tie::IxHash LWP::UserAgent XML::Parser -cpanm SOAP::Lite Business::PayPal::API URI::Encode XML::Hash::LX +cpanm Email::Stuff File::Path namespace::autoclean Clone Plack::Middleware::CrossOrigin Net::Amazon::S3 +cpanm Path::Class Git::Wrapper Guard Digest::MD5 Digest::HMAC_SHA1 XML::Hash::LX Tie::IxHash LWP::UserAgent XML::Parser +cpanm SOAP::Lite URI::Encode XML::Hash::LX cpanm List::Util::WeightedChoice cpanm Module::Find @@ -29,15 +29,12 @@ cpanm Beanstalk::Client cpanm Memcached::libmemcached cpanm JSON::RPC::Dispatcher::App cpanm String::Random -cpanm Chat::Envolve cpanm Text::CSV_XS cpanm JSON::WebToken cpanm Guard cpanm URI::Encode -cpanm Facebook::Graph cpanm XML::Hash::LX cpanm Tie::IxHash -cpanm Business::PayPal::API cpanm DBD::mysql cpanm Log::Log4perl cpanm Log::Any::Adapter diff --git a/cpanfile b/cpanfile index 5ad80770..6e539d6e 100644 --- a/cpanfile +++ b/cpanfile @@ -112,11 +112,7 @@ requires 'LWP::Protocol::https'; requires 'IO::Socket::IP'; requires 'IO::Socket::SSL'; requires 'Net::Amazon::S3'; -requires 'Facebook::Graph'; -requires 'Firebase::Auth'; -requires 'Business::PayPal::API'; requires 'SOAP::Lite'; -requires 'Gravatar::URL'; # --- Runtime: email --------------------------------------------------------- diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 3ced9061..84ae2a94 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -335,33 +335,6 @@ DISTRIBUTIONS IO::Socket::INET 0 Socket 0 YAML::Syck 0 - Business-PayPal-API-0.77 - pathname: O/OA/OALDERS/Business-PayPal-API-0.77.tar.gz - provides: - Business::PayPal::API 0.77 - Business::PayPal::API::AuthorizationRequest 0.77 - Business::PayPal::API::CaptureRequest 0.77 - Business::PayPal::API::DirectPayments 0.77 - Business::PayPal::API::ExpressCheckout 0.77 - Business::PayPal::API::GetBalance 0.77 - Business::PayPal::API::GetTransactionDetails 0.77 - Business::PayPal::API::MassPay 0.77 - Business::PayPal::API::ReauthorizationRequest 0.77 - Business::PayPal::API::RecurringPayments 0.77 - Business::PayPal::API::RefundTransaction 0.77 - Business::PayPal::API::TransactionSearch 0.77 - Business::PayPal::API::VoidRequest 0.77 - Example::Role::Auth undef - Example::TransactionFetcher undef - Example::TransactionSearcher undef - requirements: - Carp 0 - Data::Printer 0 - ExtUtils::MakeMaker 0 - SOAP::Lite 0.67 - perl 5.008001 - strict 0 - warnings 0 CGI-4.72 pathname: L/LE/LEEJO/CGI-4.72.tar.gz provides: @@ -3125,45 +3098,6 @@ DISTRIBUTIONS File::Which 0 List::Util 1.33 perl 5.006 - Facebook-Graph-1.1205 - pathname: R/RI/RIZEN/Facebook-Graph-1.1205.tar.gz - provides: - Facebook::Graph 1.1205 - Facebook::Graph::AccessToken 1.1205 - Facebook::Graph::AccessToken::Response 1.1205 - Facebook::Graph::Authorize 1.1205 - Facebook::Graph::BatchRequests 1.1205 - Facebook::Graph::Page::Feed 1.1205 - Facebook::Graph::Picture 1.1205 - Facebook::Graph::Publish 1.1205 - Facebook::Graph::Publish::Checkin 1.1205 - Facebook::Graph::Publish::Comment 1.1205 - Facebook::Graph::Publish::PageTab 1.1205 - Facebook::Graph::Publish::Photo 1.1205 - Facebook::Graph::Publish::Post 1.1205 - Facebook::Graph::Publish::RSVPAttending 1.1205 - Facebook::Graph::Publish::RSVPDeclined 1.1205 - Facebook::Graph::Publish::RSVPMaybe 1.1205 - Facebook::Graph::Query 1.1205 - Facebook::Graph::Request 1.1205 - Facebook::Graph::Response 1.1205 - Facebook::Graph::Role::Uri 1.1205 - Facebook::Graph::Session 1.1205 - requirements: - DateTime 0.61 - DateTime::Format::Strptime 1.4000 - ExtUtils::MakeMaker 0 - HTTP::Response 0 - JSON 2.16 - LWP::Protocol::https 6.06 - LWP::UserAgent 6.13 - MIME::Base64::URLSafe 0.01 - Moo 0 - Ouch 0.0400 - Test::More 0 - Test::Pod 0 - URI 1.54 - perl 5.006 Fatal-Exception-0.05 pathname: D/DE/DEXTER/Fatal-Exception-0.05.tar.gz provides: @@ -3273,24 +3207,6 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 perl 5.008001 - Firebase-1.0002 - pathname: R/RI/RIZEN/Firebase-1.0002.tar.gz - provides: - Firebase 1.0002 - Firebase::Auth 1.0002 - requirements: - Digest::SHA 0 - ExtUtils::MakeMaker 6.30 - HTTP::Request::Common 0 - HTTP::Thin 0 - JSON 0 - JSON::XS 0 - MIME::Base64 0 - Moo 0 - Ouch 0 - Test::Deep 0 - Test::More 0 - URI 0 GD-2.91 pathname: R/RU/RURBAN/GD-2.91.tar.gz provides: @@ -3337,23 +3253,6 @@ DISTRIBUTIONS perl 5.012 strict 0 warnings 0 - Gravatar-URL-1.07 - pathname: M/MS/MSCHWERN/Gravatar-URL-1.07.tar.gz - provides: - Gravatar::URL 1.07 - Libravatar::URL 1.07 - Unicornify::URL 1.07 - requirements: - Carp 0 - Digest::MD5 0 - Digest::SHA 0 - Net::DNS 1.01 - Test::MockRandom 1.01 - Test::More 0.4 - Test::Warn 0.11 - URI::Escape 0 - parent 0 - perl v5.6.0 Guard-1.023 pathname: M/ML/MLEHMANN/Guard-1.023.tar.gz provides: diff --git a/docker/server/etc-dev/lacuna.conf b/docker/server/etc-dev/lacuna.conf index 4ca34865..cbb1dce2 100644 --- a/docker/server/etc-dev/lacuna.conf +++ b/docker/server/etc-dev/lacuna.conf @@ -39,16 +39,7 @@ "password" : "lacuna", "username" : "root" }, - "envolve" : { - "Sn" : 0, - "api_key" : "XXXX" - }, "essentia_code_server_url" : "", - "facebook" : { - "api_key" : "XXXX", - "app_id" : "XXXX", - "secret" : "XXXX" - }, "feeds" : { "bucket" : "XXXX", "surl" : "https://xxxx/", @@ -106,12 +97,6 @@ ] }, "offline" : 0, - "paypal" : { - "APIPassword" : "XXXX", - "APIUsername" : "XXXX", - "Sandbox" : "0", - "Signature" : "XXXX" - }, "rpc_limit" : 10000, "rpc_throttle" : 200, "self_destruct_after_inactive_days" : 9999999, diff --git a/docker/server/etc-homelab/lacuna.conf b/docker/server/etc-homelab/lacuna.conf index 4ca34865..cbb1dce2 100644 --- a/docker/server/etc-homelab/lacuna.conf +++ b/docker/server/etc-homelab/lacuna.conf @@ -39,16 +39,7 @@ "password" : "lacuna", "username" : "root" }, - "envolve" : { - "Sn" : 0, - "api_key" : "XXXX" - }, "essentia_code_server_url" : "", - "facebook" : { - "api_key" : "XXXX", - "app_id" : "XXXX", - "secret" : "XXXX" - }, "feeds" : { "bucket" : "XXXX", "surl" : "https://xxxx/", @@ -106,12 +97,6 @@ ] }, "offline" : 0, - "paypal" : { - "APIPassword" : "XXXX", - "APIUsername" : "XXXX", - "Sandbox" : "0", - "Signature" : "XXXX" - }, "rpc_limit" : 10000, "rpc_throttle" : 200, "self_destruct_after_inactive_days" : 9999999, diff --git a/docker/server/etc-test/lacuna.conf b/docker/server/etc-test/lacuna.conf index 4ca34865..cbb1dce2 100644 --- a/docker/server/etc-test/lacuna.conf +++ b/docker/server/etc-test/lacuna.conf @@ -39,16 +39,7 @@ "password" : "lacuna", "username" : "root" }, - "envolve" : { - "Sn" : 0, - "api_key" : "XXXX" - }, "essentia_code_server_url" : "", - "facebook" : { - "api_key" : "XXXX", - "app_id" : "XXXX", - "secret" : "XXXX" - }, "feeds" : { "bucket" : "XXXX", "surl" : "https://xxxx/", @@ -106,12 +97,6 @@ ] }, "offline" : 0, - "paypal" : { - "APIPassword" : "XXXX", - "APIUsername" : "XXXX", - "Sandbox" : "0", - "Signature" : "XXXX" - }, "rpc_limit" : 10000, "rpc_throttle" : 200, "self_destruct_after_inactive_days" : 9999999, diff --git a/docs/Chat.pod b/docs/Chat.pod deleted file mode 100644 index b05aeddb..00000000 --- a/docs/Chat.pod +++ /dev/null @@ -1,15 +0,0 @@ -=head1 Chat - -The chat system is overlayed onto the web client in a way that makes it impossible for other apps to use it. However, through this API you can pop open a web browser from your app that will allow the users to participate in the conversation. - -B This API is B JSON-RPC based. - -To open a chat, open a browser window / panel / pane and point it to: - - http://servername.lacunaexpanse.com/chat?session_id=xxxxxxxxxxxxxxxx - -The chat system will handle the rest. - -B The parameters in the above URL can be passed via GET or POST, it doesn't matter which. - -=cut diff --git a/docs/Empire.pod b/docs/Empire.pod index 988db8c4..5fcd675e 100644 --- a/docs/Empire.pod +++ b/docs/Empire.pod @@ -91,7 +91,7 @@ The name of the empire to create. Required. =head4 password -The password to log in to the empire. Must be between 6 and 30 characters. Required unless you have a valid C and C. Still recommended even if you are authenticating using Facebook. +The password to log in to the empire. Must be between 6 and 30 characters. Required. =head4 password1 @@ -109,14 +109,6 @@ This is the text typed in by the user as the solution of the captcha. Required. The user's email address. It is not required, but is used for system vital functions like password recovery. -=head4 facebook_uid - -A Facebook user id passed in through Lacuna's Facebook integration system. Optional, but required with the use of C. - -=head4 facebook_token - -A Facebook access token passed in through Lacuna's Facebook integration system. Optional, but required with the use of C. - =head4 invite_code A 36 character code that was sent to the user by a friend. It is usable only once, and will ensure that their friend gets a home planet that is in relatively close proximity to their home planet. @@ -314,7 +306,6 @@ Provides a list of the editable properties of the current empire's profile. See "skip_resource_warnings" : 0, "skip_pollution_warnings" : 0, "skip_medal_messages" : 0, - "skip_facebook_wall_posts" : 0, "skip_found_nothing "skip_excavator_resources" : 0, "skip_excavator_glyph" : 0, @@ -412,10 +403,6 @@ B: These messages are there for your own protection. Turn off at your o Defaults to 0. Set to 1 if the user no longer wants to receive messages about the medals they've earned. -=head4 skip_facebook_wall_posts - -Defaults to 0. Set to 1 if the user no longer wants messages to be posted to their Facebook wall. - =head4 skip_found_nothing Defaults to 0. Set to 1 if the user no longer wants to receive messages when excavators find nothing. @@ -609,7 +596,7 @@ The name your searching for. It's case insensitive, and partial names work fine. =head2 set_status_message ( session_id, message ) -Sets the empire status message. Similar to what you might put on your Facebook wall, or in a tweet, but about your empire. +Sets the empire status message. Similar to what you might put in a tweet, but about your empire. =head3 session_id diff --git a/docs/Intro.pod b/docs/Intro.pod index 2781fe89..040dfa3d 100644 --- a/docs/Intro.pod +++ b/docs/Intro.pod @@ -194,10 +194,6 @@ Methods for interacting with the buildings on a body. How to allow users to purchase Essentia from your app. -=item L - -Integrate the in-game chat system with your app. - =item L Display a serverwide announcement. diff --git a/info/setup.md b/info/setup.md index 0c5c024d..a8329161 100644 --- a/info/setup.md +++ b/info/setup.md @@ -410,7 +410,6 @@ directory that has the following: alias /captcha "/data/captcha" alias /assets "/data/Lacuna-Assets" - alias /chiselchat "/home/lacuna/server/var/www/public/chiselchat" ProxyPassMatch ^/([a-z][^.]*)$ http://localhost:5000/$1 ProxyPreserveHost On diff --git a/lacuna/app/controllers/empire_controller.rb b/lacuna/app/controllers/empire_controller.rb index 2b85c3c6..cc33a6e8 100644 --- a/lacuna/app/controllers/empire_controller.rb +++ b/lacuna/app/controllers/empire_controller.rb @@ -33,7 +33,6 @@ class EmpireController < ApplicationController skip_pollution_warnings: current_empire.skip_pollution_warnings, skip_resource_warnings: current_empire.skip_resource_warnings, skip_happiness_warnings: current_empire.skip_happiness_warnings, - skip_facebook_wall_posts: current_empire.skip_facebook_wall_posts, medals: medals, skip_found_nothing: current_empire.skip_found_nothing, skip_excavator_resources: current_empire.skip_excavator_resources, diff --git a/lacuna/app/models/login_log.rb b/lacuna/app/models/login_log.rb index 60c20ddc..43a5a6fe 100644 --- a/lacuna/app/models/login_log.rb +++ b/lacuna/app/models/login_log.rb @@ -5,7 +5,6 @@ # # id :integer not null, primary key # api_key :string(36) -# browser_fingerprint :string(32) # date_stamp :datetime not null # empire_name :string(30) not null # extended :integer default(0), not null @@ -20,7 +19,6 @@ # idx_api_key (api_key) # idx_empire_id (empire_id) # idx_empire_name (empire_name) -# idx_fingerprint (browser_fingerprint) # idx_session_id (session_id) # diff --git a/lacuna/db/schema.rb b/lacuna/db/schema.rb index b6808a87..26b58fec 100644 --- a/lacuna/db/schema.rb +++ b/lacuna/db/schema.rb @@ -376,7 +376,6 @@ ActiveRecord::Schema[8.1].define(version: 0) do create_table "empire", id: :integer, charset: "latin1", force: :cascade do |t| t.integer "alliance_id" t.datetime "building_boost", precision: nil, null: false - t.integer "chat_admin", default: 0, null: false t.string "city", limit: 100 t.string "country", limit: 100 t.datetime "date_created", precision: nil, null: false @@ -389,8 +388,6 @@ ActiveRecord::Schema[8.1].define(version: 0) do t.float "essentia_free", default: 0.0, null: false t.float "essentia_game", default: 0.0, null: false t.float "essentia_paid", default: 0.0, null: false - t.string "facebook_token", limit: 100 - t.bigint "facebook_uid" t.integer "farming_affinity", limit: 1, default: 4, null: false t.datetime "food_boost", precision: nil, null: false t.integer "growth_affinity", limit: 1, default: 4, null: false @@ -428,7 +425,6 @@ ActiveRecord::Schema[8.1].define(version: 0) do t.integer "skip_excavator_plan", limit: 1, default: 0, null: false t.integer "skip_excavator_replace_msg", limit: 1, default: 0, null: false t.integer "skip_excavator_resources", limit: 1, default: 0, null: false - t.integer "skip_facebook_wall_posts", limit: 1, default: 0, null: false t.integer "skip_found_nothing", limit: 1, default: 0, null: false t.integer "skip_happiness_warnings", limit: 1, default: 0, null: false t.integer "skip_incoming_ships", limit: 1, default: 0, null: false @@ -630,7 +626,6 @@ ActiveRecord::Schema[8.1].define(version: 0) do create_table "login_log", id: :integer, charset: "latin1", force: :cascade do |t| t.string "api_key", limit: 36 - t.string "browser_fingerprint", limit: 32 t.datetime "date_stamp", precision: nil, null: false t.integer "empire_id", null: false t.string "empire_name", limit: 30, null: false @@ -640,7 +635,6 @@ ActiveRecord::Schema[8.1].define(version: 0) do t.datetime "log_out_date", precision: nil t.string "session_id", limit: 36, null: false t.index ["api_key"], name: "idx_api_key" - t.index ["browser_fingerprint"], name: "idx_fingerprint" t.index ["empire_id"], name: "idx_empire_id" t.index ["empire_name"], name: "idx_empire_name" t.index ["session_id"], name: "idx_session_id" diff --git a/lacuna/test/fixtures/empire.yml b/lacuna/test/fixtures/empire.yml index cf142aaa..fcb2caee 100644 --- a/lacuna/test/fixtures/empire.yml +++ b/lacuna/test/fixtures/empire.yml @@ -47,7 +47,6 @@ rails_parity_owner: skip_pollution_warnings: 0 skip_resource_warnings: 0 skip_happiness_warnings: 0 - skip_facebook_wall_posts: 0 is_admin: 0 is_mission_curator: 0 skip_found_nothing: 0 @@ -63,7 +62,6 @@ rails_parity_owner: dont_replace_excavator: 0 latest_message_id: 205 skip_incoming_ships: 0 - chat_admin: 0 in_stasis: 0 timeout: 0 outlaw: 0 diff --git a/lib/Lacuna/DB/Result/Empire.pm b/lib/Lacuna/DB/Result/Empire.pm index d0c4e1ea..6b9ab3ea 100644 --- a/lib/Lacuna/DB/Result/Empire.pm +++ b/lib/Lacuna/DB/Result/Empire.pm @@ -51,8 +51,6 @@ __PACKAGE__->add_columns( happiness_boost => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, building_boost => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, spy_training_boost => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, - facebook_uid => { data_type => 'bigint', is_nullable => 1 }, - facebook_token => { data_type => 'varchar', size => 100, is_nullable => 1 }, alliance_id => { data_type => 'int', is_nullable => 1 }, species_name => { data_type => 'varchar', size => 30, default_value => 'Human', is_nullable => 0 }, species_description => { data_type => 'text', is_nullable => 1 }, @@ -73,7 +71,6 @@ __PACKAGE__->add_columns( skip_pollution_warnings => { data_type => 'tinyint', default_value => 0 }, skip_resource_warnings => { data_type => 'tinyint', default_value => 0 }, skip_happiness_warnings => { data_type => 'tinyint', default_value => 0 }, - skip_facebook_wall_posts => { data_type => 'tinyint', default_value => 0 }, is_admin => { data_type => 'tinyint', default_value => 0 }, is_mission_curator => { data_type => 'tinyint', default_value => 0 }, skip_found_nothing => { data_type => 'tinyint', default_value => 0 }, @@ -89,7 +86,6 @@ __PACKAGE__->add_columns( dont_replace_excavator => { data_type => 'tinyint', default_value => 0 }, latest_message_id => { data_type => 'int', is_nullable => 1 }, skip_incoming_ships => { data_type => 'tinyint', default_value => 0 }, - chat_admin => { data_type => 'int', default_value => 0 }, in_stasis => { data_type => 'tinyint', default_value => 0 }, timeout => { data_type => 'tinyint', default_value => 0 }, outlaw => { data_type => 'tinyint', default_value => 0 }, diff --git a/lib/Lacuna/DB/Result/Log/Login.pm b/lib/Lacuna/DB/Result/Log/Login.pm index 9554f9c0..35ef0a08 100644 --- a/lib/Lacuna/DB/Result/Log/Login.pm +++ b/lib/Lacuna/DB/Result/Log/Login.pm @@ -14,14 +14,12 @@ __PACKAGE__->add_columns( log_out_date => { data_type => 'datetime', is_nullable => 1 }, extended => { data_type => 'int', size => 11, default_value => 0 }, is_sitter => { data_type => 'int', size => 1, is_nullable => 0, default_value => 0 }, - browser_fingerprint => { data_type => 'varchar', size => 32, is_nullable => 1 }, ); after 'sqlt_deploy_hook' => sub { my ($self, $sqlt_table) = @_; $sqlt_table->add_index(name => 'idx_api_key', fields => ['api_key']); $sqlt_table->add_index(name => 'idx_session_id', fields => ['session_id']); - $sqlt_table->add_index(name => 'idx_fingerprint', fields => ['browser_fingerprint']); }; diff --git a/lib/Lacuna/DB/Result/Promotion.pm b/lib/Lacuna/DB/Result/Promotion.pm index 3bde6f3d..bb440a3b 100644 --- a/lib/Lacuna/DB/Result/Promotion.pm +++ b/lib/Lacuna/DB/Result/Promotion.pm @@ -84,7 +84,7 @@ sub purchase_applies # empire (object) # cost (in USD) # transaction_id -# type (iTransact, Paypal, etc.) +# type (iTransact, etc.) sub essentia_purchased { diff --git a/lib/Lacuna/RPC/Chat.pm b/lib/Lacuna/RPC/Chat.pm deleted file mode 100644 index c92c8154..00000000 --- a/lib/Lacuna/RPC/Chat.pm +++ /dev/null @@ -1,127 +0,0 @@ -package Lacuna::RPC::Chat; - -use Moose; -use utf8; -no warnings qw(uninitialized); -extends 'Lacuna::RPC'; -use Firebase::Auth; -use Firebase; -use Gravatar::URL; -use Ouch; - -sub init_chat { - my ($self, $session_id) = @_; - - my $session = $self->get_session({session_id => $session_id }); - my $empire = $session->current_empire; - - my $config = Lacuna->config; - my $firebase_config = $config->get('firebase'); - return undef unless $firebase_config; - return undef if $empire->current_session->is_sitter && $empire->id > 1; - my $chat_auth = Firebase::Auth->new( - secret => $firebase_config->{auth}{secret}, -# debug => \1, - data => { - uid => $empire->id, - isModerator => $empire->chat_admin ? \1 : \0, - isStaff => $empire->is_admin ? \1 : \0, - } - # data => $data, - ); - my $firebase = Firebase->new( - firebase => $firebase_config->{firebase}, - authobj => $chat_auth, - ); - my $chat_name = $empire->name; - my $aname; - $chat_name =~ s/[^0-9a-zA-Z_ ]/_/g; - $chat_name =~ s/__*/_/g; - if ($empire->alliance_id) { - $aname = $empire->alliance->name; - $aname =~ s/[^0-9a-zA-Z_ ]/_/g; - $aname =~ s/__*/_/g; - $chat_name .= " (".$aname.")"; - } - if (0) { -# if ($empire->alliance_id) { - my $room = eval { $firebase->get('room-metadata/'.$empire->alliance_id) }; - if ($@) { - warn bleep; - } - elsif (defined $room) { - eval { - $firebase->patch('room-metadata/'.$empire->alliance_id.'/authorizedUsers', { - $empire->id => \1 - }); - }; - if ($@) { - warn bleep; - } - } - else { - eval { - $firebase->put('room-metadata/'.$empire->alliance_id, { - id => $empire->alliance_id, - name => $aname, - type => 'private', - createdByUserId => $empire->id, - '.priority' => {'.sv' => 'timestamp'}, - authorizedUsers => {$empire->id => \1}, - }); - }; - if ($@) { - warn bleep; - } - } - $firebase->put('users/'.$empire->id.'/rooms/'.$empire->alliance_id, { - id => $empire->alliance_id, - active => \1, - name => $aname, - }); - } -# if ($empire->is_admin) { -# $chat_name .= " "; -# } -# elsif ($empire->chat_admin) { -# $chat_name .= " "; -# } - my $email = $empire->email // do { - # give it a predictable but unique name. - my $e = ($empire->name . '@lacunaexpanse.com'); - $e =~ s/[^\w\d@.]/_/g; - $e; - }; - my $gravatar_url = gravatar_url( - email => $email, - default => 'monsterid', - size => 300, - https => 1, - rating => 'g', - ); - my $ret = { - status => $self->format_status($session), - gravatar_url => $gravatar_url, - chat_name => $chat_name, - chat_auth => $chat_auth->create_token, - isStaff => $empire->is_admin ? \1 : \0, - isModerator => $empire->chat_admin ? \1 : \0, - }; - if (0) { -# if ($empire->alliance_id) { - $ret->{private_room} = { - id => $empire->alliance_id, - name => $aname, - }; - } - return $ret; -} - -__PACKAGE__->register_rpc_method_names( - qw(init_chat), -); - - -no Moose; -__PACKAGE__->meta->make_immutable; - diff --git a/lib/Lacuna/RPC/Empire.pm b/lib/Lacuna/RPC/Empire.pm index e1b52f35..9c8a038d 100644 --- a/lib/Lacuna/RPC/Empire.pm +++ b/lib/Lacuna/RPC/Empire.pm @@ -10,8 +10,6 @@ use String::Random qw(random_string); use UUID::Tiny ':std'; use Time::HiRes; use Text::CSV_XS; -use Firebase::Auth; -use Gravatar::URL; use List::Util qw(none); use PerlX::Maybe qw(provided); use Log::Any qw($log); @@ -77,7 +75,7 @@ sub logout { } sub login { - my ($self, $plack_request, $name, $password, $api_key, $browser) = @_; + my ($self, $plack_request, $name, $password, $api_key) = @_; unless ($api_key) { confess [1002, 'You need an API Key.']; } @@ -97,7 +95,6 @@ sub login { my %session_params = ( api_key => $api_key, request => $plack_request, - browser => $browser, ); if ($empire->is_password_valid($password)) { @@ -136,18 +133,6 @@ sub login { if ($empire->rpc_count > $max) { confess [1010, $empire->name.' has already made the maximum number of requests ('.$max.') you can make for one day.']; } - my $firebase_config = $config->get('firebase'); - if ($firebase_config) - { - my $auth_code = Firebase::Auth->new( - secret => $firebase_config->{auth}{secret}, - data => { - uid => $empire->id, - isModerator => $empire->chat_admin ? \1 : \0, - isStaff => $empire->is_admin ? \1 : \0, - } - )->create_token; - } my $session = $empire->start_session(\%session_params); @@ -333,26 +318,15 @@ sub create { sitter_password => random_string('CC.c!ccn'), ); - # check facebook - my $has_facebook = (exists $account{facebook_uid} && $account{facebook_uid} =~ m/^\d+$/ && exists $account{facebook_token} && length($account{facebook_token}) > 60); - if ($has_facebook) { - $params{facebook_uid} = $account{facebook_uid}; - $params{facebook_token} = $account{facebook_token}; - } - # verify captcha - unless ($has_facebook) { - $self->validate_captcha($plack_request, $account{captcha_guid}, $account{captcha_solution}); - } + $self->validate_captcha($plack_request, $account{captcha_guid}, $account{captcha_solution}); # verify password - if (exists $account{password} || !$has_facebook) { - Lacuna::Verify->new(content=>\$account{password}, throws=>[1001,'Invalid password. It must be at least 6 characters and both passwords must match.', 'password']) - ->length_gt(5) - ->eq($account{password1}); - $params{password} = Lacuna::DB::Result::Empire->encrypt_password($account{password}); - } - + Lacuna::Verify->new(content=>\$account{password}, throws=>[1001,'Invalid password. It must be at least 6 characters and both passwords must match.', 'password']) + ->length_gt(5) + ->eq($account{password1}); + $params{password} = Lacuna::DB::Result::Empire->encrypt_password($account{password}); + # verify username eval { $self->is_name_unique($account{name}) }; if ($@) { # maybe they're trying to finish an incomplete empire @@ -479,7 +453,6 @@ sub view_profile { skip_pollution_warnings => $empire->skip_pollution_warnings, skip_resource_warnings => $empire->skip_resource_warnings, skip_happiness_warnings => $empire->skip_happiness_warnings, - skip_facebook_wall_posts=> $empire->skip_facebook_wall_posts, medals => \%my_medals, skip_found_nothing => $empire->skip_found_nothing, skip_excavator_resources => $empire->skip_excavator_resources, @@ -571,12 +544,6 @@ sub edit_profile { } $empire->skip_happiness_warnings($profile->{skip_happiness_warnings}); } - if (exists $profile->{skip_facebook_wall_posts}) { - if ($profile->{skip_facebook_wall_posts} < 0 || $profile->{skip_facebook_wall_posts} > 1) { - confess [1009, 'Skip Facebook Wall Posts must be a 1 or a 0.', 'skip_facebook_wall_posts'] - } - $empire->skip_facebook_wall_posts($profile->{skip_facebook_wall_posts}); - } if (exists $profile->{skip_resource_warnings}) { if ($profile->{skip_resource_warnings} < 0 || $profile->{skip_resource_warnings} > 1) { confess [1009, 'Skip Resource Warnings must be a 1 or a 0.', 'skip_resource_warnings'] diff --git a/lib/Lacuna/RPC/Firebase.pm b/lib/Lacuna/RPC/Firebase.pm deleted file mode 100644 index e3bb5549..00000000 --- a/lib/Lacuna/RPC/Firebase.pm +++ /dev/null @@ -1,40 +0,0 @@ -package Lacuna::RPC::Firebase; - -use Moose; -use utf8; -no warnings qw(uninitialized); -extends 'Lacuna::RPC'; -use WWW::Firebase::TokenGenerator; - -sub get_token { - my ($self, $session_id) = @_; - - my $session = $self->get_session({session_id => $session_id }); - my $empire = $session->current_empire; - my $firebase_secret = Lacuna->config->get('firebase/secret'); - unless ($firebase_secret) { - return { token => '', status => $self->format_status($session)}; - } - my $token_generator = WWW::Firebase::TokenGenerator->new({ - secret => $firebase_secret, - admin => $empire->is_admin, - debug => Lacuna->config->get('firebase/debug'), - }); - - my $token = $token_generator->create_token({ - empire_id => $empire->id, - empire_name => $empire->name, - alliance_id => $empire->alliance_id, - alliance_name => $empire->alliance_id ? $empire->alliance->name : '', - }); - - return { token => $token, status => $self->format_status($session)}; -} - -__PACKAGE__->register_rpc_method_names( - qw(get_token), -); - -no Moose; -__PACKAGE__->meta->make_immutable; - diff --git a/lib/Lacuna/Session.pm b/lib/Lacuna/Session.pm index eca5c0d2..0cd65b2d 100644 --- a/lib/Lacuna/Session.pm +++ b/lib/Lacuna/Session.pm @@ -177,7 +177,6 @@ sub start { ip_address => $ip, session_id => $self->id, is_sitter => $options->{is_sitter} ? 1 : 0, - browser_fingerprint => $options->{browser}, # is_from_admin => $options->{is_from_admin} <-- probably not needed })->insert; return $self->extend; diff --git a/lib/Lacuna/Web/Admin.pm b/lib/Lacuna/Web/Admin.pm index 71b5a167..7c2d04a1 100644 --- a/lib/Lacuna/Web/Admin.pm +++ b/lib/Lacuna/Web/Admin.pm @@ -143,7 +143,7 @@ sub www_view_essentia_log { sub www_view_login_log { my ($self, $request) = @_; my ( $search_field, $search_value ); - for my $field (qw( empire_id ip_address api_key browser_fingerprint )) { + for my $field (qw( empire_id ip_address api_key )) { if ( my $value = $request->param($field) ) { $search_field = $field; $search_value = $value; @@ -161,7 +161,7 @@ sub www_view_login_log { if ( $search_field eq 'empire_id' ) { $out .= sprintf('Back To Empire', $search_value); } - $out .= ''; + $out .= '
IDEmpire NameLog-in DateLog-out DateExtendedIP AddressSitterAPI KeyBrowser ID
'; while (my $login = $logins->next) { my $sitter = $login->is_sitter ? 'Sitter' : ''; $out .= sprintf('', @@ -173,8 +173,6 @@ sub www_view_login_log { $out .= sprintf('', $sitter); $out .= sprintf('', $login->api_key, $login->api_key ); - $out .= sprintf('', - $login->browser_fingerprint); $out .= ''; } $out .= '
IDEmpire NameLog-in DateLog-out DateExtendedIP AddressSitterAPI Key
%d%s%s%1$s
'; diff --git a/lib/Lacuna/Web/Chat.pm b/lib/Lacuna/Web/Chat.pm deleted file mode 100644 index 4b57fbc8..00000000 --- a/lib/Lacuna/Web/Chat.pm +++ /dev/null @@ -1,49 +0,0 @@ -package Lacuna::Web::Chat; - -use Moose; -use utf8; -no warnings qw(uninitialized); -extends qw(Lacuna::Web); - -sub www_default { - my ($self, $request) = @_; - my $session = $self->get_session($request->param('session_id')); - unless (defined $session) { - confess [ 401, 'You must be logged in to use chat.']; - } - my $empire = $session->empire; - unless (defined $empire) { - confess [401, 'Empire not found.']; - } - my $content; - my $envolve = Lacuna->config->get('envolve'); - if ($envolve->{api_key}) { - my $chat = Chat::Envolve->new( - api_key => $envolve->{api_key}, - client_ip => 'none', - ); - my %params; - if ($empire->alliance_id) { - my $alliance = $empire->alliance; - if (defined $alliance) { - $params{last_name} = '('.$alliance->name.')'; - } - } - $content = $chat->get_tags($empire->name, %params); - } - else { - $content = q{ - - - }; - } - return $self->wrapper($content, { - title => 'Lacuna Expanse Chat', - head_tags => '', - logo => 1 - }); -} - -no Moose; -__PACKAGE__->meta->make_immutable(inline_constructor => 0); - diff --git a/lib/Lacuna/Web/Facebook.pm b/lib/Lacuna/Web/Facebook.pm deleted file mode 100644 index 415d5082..00000000 --- a/lib/Lacuna/Web/Facebook.pm +++ /dev/null @@ -1,135 +0,0 @@ -package Lacuna::Web::Facebook; - -use Moose; -use utf8; -no warnings qw(uninitialized); -extends qw(Lacuna::Web); -use Facebook::Graph; -use LWP::UserAgent; - -has facebook => ( - is => 'rw', - lazy => 1, - default => sub { - my $self = shift; - my $config = Lacuna->config; - return Facebook::Graph->new( - postback => $config->get('server_url').'facebook/postback', - app_id => $config->get('facebook/app_id'), - secret => $config->get('facebook/secret'), - ); - }, -); - -sub www_postback { - my ($self, $request) = @_; - my $fb = $self->facebook; - $fb->request_access_token($request->param('code')); - my $user = $fb->query->find('me')->request->as_hashref; - - unless (exists $user->{id}) { - return $self->format_error('Could not authenticate your Facebook account. Please close this window and try again.'); - } - - my $empire = Lacuna->db->resultset('Lacuna::DB::Result::Empire')->search({facebook_uid => $user->{id} })->first; - my $uri = Lacuna->config->get('server_url'); - if (defined $empire && $empire->stage eq 'founded') { - $empire->facebook_token($fb->access_token); - $empire->update; - $uri .= '#session_id=%s'; - $uri = sprintf $uri, $empire->start_session({ request => $request, api_key => 'facebook' })->id; - } - elsif (defined $empire && $empire->stage ne 'founded') { - $empire->facebook_token($fb->access_token); - $empire->update; - $uri .= '#empire_id=%s'; - $uri = sprintf $uri, $empire->id; - } - else { - $uri .= '#facebook_uid=%s&facebook_token=%s&facebook_name=%s'; - $uri = sprintf $uri, $user->{id}, $fb->access_token, $user->{name}; - } - return [$uri, { status => 302 } ]; -} - -sub www_authorize { - my ($self, $request) = @_; - return [$self->facebook->authorize->extend_permissions(qw(email))->uri_as_string, { status => 302 }]; -} - -sub www_server_list { - my ($self, $request) = @_; - my $cache = Lacuna->cache; - my $servers = $cache->get_and_deserialize('www.lacunaexpanse.com', 'servers.json'); - unless (defined $servers && ref $servers eq 'ARRAY') { - my $servers_json = LWP::UserAgent->new->get('http://www.lacunaexpanse.com/servers.json')->content; - $servers = JSON->new->decode($servers_json); - $cache->set('www.lacunaexpanse.com', 'servers.json', $servers, 60 * 60 * 24); - } - my $template = ' -
Server
-
%s
-
Location
-
%s
-
Status
-
%s
-
Play Now!
-
-'; - my $out = ' -
Choose A Server
'; - foreach my $server (@{$servers}) { - $out .= sprintf $template, $server->{uri}.'facebook/authorize', $server->{name}, $server->{location}, $server->{status}; - } - return $self->wrapper($out, { title => 'Available Servers' }); -} - -sub www_default { - my ($self, $request) = @_; - my $config = Lacuna->config; - my $fb = Facebook::Graph->new( - postback => $config->get('server_url').'facebook/my/empire', - app_id => $config->get('facebook/app_id'), - secret => $config->get('facebook/secret'), - ); - return [$fb->authorize->extend_permissions(qw(publish_stream offline_access))->uri_as_string, { status => 302 }]; -} - -sub www_my_empire { - my ($self, $request) = @_; - my $config = Lacuna->config; - my $server_url = $config->get('server_url'); - my $fb = Facebook::Graph->new( - postback => $config->get('server_url').'facebook/my/empire', - app_id => $config->get('facebook/app_id'), - secret => $config->get('facebook/secret'), - ); - $fb->request_access_token($request->param('code')); - my $user = $fb->query->find('me')->request->as_hashref; - unless (exists $user->{id}) { - return $self->format_error(q{The bad thing that should never happen just happened. Facebook doesn't remember who you are!}); - } - - my $empire = Lacuna->db->resultset('Lacuna::DB::Result::Empire')->search({facebook_uid => $user->{id} })->first; - my $out; - unless (defined $empire) { - $out = q{

Join thousands of other players online now in this strategic browser game. No downloads required. Play for free.

-

The Expanse is a region of space with millions of habitable worlds. You can play with or compete against thousands of - other players as you build your empire, fight off spies in a battle for cold war supremacy, form alliances, search the - expanse for lost ancient artifacts, and more.

}; - return $self->wrapper($out, { title => 'Play for Free in The Lacuna Expanse' }); - } - $out .= '
'; - $out .= '

'.$empire->name.'

'; - my $planets = $empire->planets; - while (my $planet = $planets->next) { - $out .= '
planet -
'.$planet->name.'
'; - } - $out .= '
'; - return $self->wrapper($out, { title => 'My Empire in The Lacuna Expanse', logo => 1 }); -} - -no Moose; -__PACKAGE__->meta->make_immutable(inline_constructor => 0); - diff --git a/lib/Lacuna/Web/Pay.pm b/lib/Lacuna/Web/Pay.pm index bb636930..1750d954 100644 --- a/lib/Lacuna/Web/Pay.pm +++ b/lib/Lacuna/Web/Pay.pm @@ -9,7 +9,6 @@ use Digest::HMAC_SHA1; use XML::Hash::LX; use Tie::IxHash; use LWP::UserAgent; -use Business::PayPal::API qw( ExpressCheckout ); @@ -27,7 +26,6 @@ sub www_default { unless (defined $empire) { confess [401, 'Empire not found.']; } - Lacuna->cache->set( 'paypal_order', $empire->id, { session => $session_id, }, 60 * 30 ); return [ $self->buy_currency_url($empire->id), { status => 302 } ]; #return $self->wrap('
'); } @@ -52,25 +50,10 @@ sub www_buy_currency { var text = el.options[el.selectedIndex].text; var value = text.split(" "); var newvalue = value[0]; - var formid = document.getElementById('form_to_update').value; - var form = document.getElementById(formid); + var form = document.getElementById('cc_form'); var currency = form.premium_currency_amount; currency.value = newvalue; } - function update_form(el) { - var chosen = el.value; - var form = chosen+'_form'; - document.getElementById('form_to_update').value = form; - var form1 = document.getElementById(form); - if (chosen == 'cc') { - chosen = 'paypal'; - } else { - chosen = 'cc'; - } - var form2 = document.getElementById(chosen+'_form'); - form2.style.display = 'none'; - form1.style.display = 'block'; - } function close_current() { try { window.setTimeout( function () { window.close() }, 10000); @@ -109,39 +92,11 @@ sub www_buy_currency { margin-right: auto; } - form#paypal_form { - display: none; - } form#cc_form { display: block; }

Get More Essentia

-
-
- Payment Type - Credit card - Paypal - -
-
-
- - -
- Get More Essentia - - - -
-
-
@@ -588,170 +543,6 @@ sub www_buy_currency_cc { } } -sub paypal_ec_return { - my $self = shift; - my $config = Lacuna->config->get(); - return $config->{server_url}.'pay/paypal/ec/return'; -} - -sub paypal_ec_cancel { - my ($self, $user_id) = @_; - my $config = Lacuna->config->get(); - Lacuna->cache->delete( 'paypal_order', $user_id ); - return $config->{server_url}.'pay/paypal/ec/cancel?user_id='.$user_id; -} - -# step one -sub www_buy_currency_paypal { - my ($self, $request) = @_; - my $user_id = $request->param('user_id'); - my $total = $request->param('total'); - my $currency = $request->param('premium_currency_amount'); - my $config = Lacuna->config->get('paypal'); -warn Dumper( $config ); - $Business::PayPal::API::Debug = 1; - - my $pp = Business::PayPal::API->new( - Username => $config->{APIUsername}, - Password => $config->{APIPassword}, - Signature => $config->{Signature}, - sandbox => $config->{Sandbox}, - ); - my %resp = $pp->SetExpressCheckout( - OrderTotal => $total, - ReturnURL => $self->paypal_ec_return, - CancelURL => $self->paypal_ec_cancel, - NoShipping => 1, - Custom => $user_id, -# InvoiceID => $InvoiceID, - ); - if ($resp{Ack} ne 'Success') { - my $content = Dumper(\%resp); use Data::Dumper; - return $self->wrap(qq{

Error acquiring token

$content
}); - } - my $token = $resp{Token}; - my $uri = $config->{Sandbox} - ? qq{https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=$token} - : qq{https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=$token}; - my $order = Lacuna->cache->get_and_deserialize( 'paypal_order', $user_id ); - Lacuna->cache->set( 'paypal_order', $user_id, { session => $order->{session}, token => $token, total => $total, currency => $currency }, 60 * 30 ); - return [ $uri, { status => 302 } ]; -} - -sub www_paypal_ec_return { - my ($self, $request) = @_; - my $token = $request->param('token'); - my $payerId = $request->param('PayerID'); - my $config = Lacuna->config->get(); - my $paypal = $config->{paypal}; - $Business::PayPal::API::Debug = 1; - - my $pp = Business::PayPal::API->new( - Username => $paypal->{APIUsername}, - Password => $paypal->{APIPassword}, - Signature => $paypal->{Signature}, - sandbox => $paypal->{Sandbox}, - ); - my %details = $pp->GetExpressCheckoutDetails( $token ); - if ($details{Ack} ne 'Success') { - my $content = Dumper(\%details); use Data::Dumper; - return $self->wrap(qq{

Error acquiring checkout details

$content
}); - } - my $PayerID = ''; - $PayerID = $details{PayerID} if $details{PayerID}; - my $uri = $config->{server_url}.'pay/paypal/ec/checkout?token='.$token.'&PayerID='.$PayerID.'&user_id='.$details{Custom}; - return [ $uri, { status => 302 } ]; -} - -sub www_paypal_ec_cancel { - my ($self, $request) = @_; - my $user_id = $request->param('user_id'); - Lacuna->cache->delete( 'paypal_order', $user_id ); - return $self->wrap('

Transaction cancelled

'); -} - -sub www_paypal_ec_checkout { - my ($self, $request) = @_; - my $token = $request->param('token'); - my $PayerID = $request->param('PayerID'); - my $user_id = $request->param('user_id'); - - # get user account - unless ($user_id) { - return ['Not a valid user_id.', { status => 401 }]; - } - - my $empire = Lacuna->db->resultset('Lacuna::DB::Result::Empire')->find($user_id); - unless (defined $empire) { - return ['Empire not found.', { status => 404 }]; - } - - my $order = Lacuna->cache->get_and_deserialize( 'paypal_order', $user_id ); - my $config = Lacuna->config->get(); - my $paypal = $config->{paypal}; - - $Business::PayPal::API::Debug = 1; - - my $pp = Business::PayPal::API->new( - Username => $paypal->{APIUsername}, - Password => $paypal->{APIPassword}, - Signature => $paypal->{Signature}, - sandbox => $paypal->{Sandbox}, - ); - my %payinfo = $pp->DoExpressCheckoutPayment( - Token => $token, - PayerID => $PayerID, - OrderTotal => $order->{total}, - ); - if ($payinfo{Ack} ne 'Success') { - my $content = Dumper(\%payinfo); use Data::Dumper; - return $self->wrap(qq{

Error acquiring with checkout

$content
}); - } - - # make sure we haven't already processed this transaction - my $transaction_id = $payinfo{TransactionID}; - unless ($transaction_id) { - return ['Not a valid PayPal TransactionID.', { status => 402 }]; - } - my $transaction = Lacuna->db->resultset('Lacuna::DB::Result::Log::Essentia')->search( - { transaction_id => $transaction_id } - )->first; - if (defined $transaction) { - return ['Already processed this transaction.', { status => 200 }]; - } - - # add essentia and alert user - my $amount = $order->{currency}; - $empire->add_essentia({ - amount => $amount, - reason => 'Purchased via PayPal', - type => 'paid', - transaction_id => $transaction_id, - }); - $empire->update; - $empire->send_predefined_message( - tags => ['Alert'], - filename => 'purchase_essentia.txt', - params => [$amount, $transaction_id], - ); - $self->_run_promotions({ - amount => $amount, - empire => $empire, - cost => $order->{total}, - type => 'PayPal', - transaction_id => $transaction_id - }); - - Lacuna->cache->delete( 'paypal_order', $user_id ); - my $script = " - try { - window.opener.YAHOO.lacuna.Essentia.paymentFinished(); - window.setTimeout( function () { window.close() }, 5000); - } catch (e) {} - "; - return $self->wrap('Thank you! The essentia will be added to your account momentarily.'); -} - sub _run_promotions { my ($self, $opts) = @_; diff --git a/lib/WWW/Firebase/API.pm b/lib/WWW/Firebase/API.pm deleted file mode 100644 index e9026b6b..00000000 --- a/lib/WWW/Firebase/API.pm +++ /dev/null @@ -1,34 +0,0 @@ -package WWW::Firebase::API; - -use Moose; -use JSON; -use JSON::WebToken; -use DateTime; -use Data::Dumper; - -has 'secret' => ( - is => 'rw', - isa => 'Str', - required => 1, -); - -sub GET { -} - -sub PUT { -} - -sub POST { -} - -sub PATCH { -} - -sub DELETE { -} - - - -1; - - diff --git a/lib/WWW/Firebase/API/Connection.pm b/lib/WWW/Firebase/API/Connection.pm deleted file mode 100644 index c4fc24c5..00000000 --- a/lib/WWW/Firebase/API/Connection.pm +++ /dev/null @@ -1,106 +0,0 @@ -package WWW::Firebase::API::Connection; - -use MooseX::Singleton; - -use Log::Log4perl; -use Data::Dumper; -use LWP::UserAgent; -use JSON; -use Carp; - -has 'base_uri' => (is => 'ro', required => 1); -has 'auth' => (is => 'rw', required => 1); -has 'user_agent' => (is => 'ro', lazy_build => 1); -has 'log' => (is => 'ro', lazy_build => 1); - -sub _build_log { - my ($self) = @_; - - return Log::Log4perl->get_logger('WWW::Firebase::API::Connection'); -} - -sub _build_user_agent { - my ($self) = @_; - - return LWP::UserAgent->new(env_proxy => 1); -} - - -sub GET { - my ($self, $url, $params) = @_; - - return $self->call({ - url => $url, - method => 'GET', - params => $params, - }); - -} - -sub POST { - my ($self, $url, $data, $params) = @_; - - return $self->call({ - url => $url, - method => 'POST', - params => $params, - data => $data, - }); -} - -sub PUT { - my ($self, $url, $data, $params) = @_; - - return $self->call({ - url => $url, - method => 'PUT', - params => $params, - data => $data, - }); -} - -sub DELETE { - my ($self, $url, $params) = @_; - - return $self->call({ - url => $url, - method => 'DELETE', - params => $params, - }); - -} - -sub call { - my ($self, $args) = @_; - - my $url = $args->{url}; - my $method = $args->{method}; - my $data = $args->{data}; - my $params = $args->{params}; - - if (defined $params) { - $params .= "&auth=".$self->auth; - } - else { - $params = "?auth=".$self->auth; - } - - - $self->log->debug("API-CALL: PATH $url : METHOD $method [$params]"); - - $url = $self->base_uri.$url.'.json'; - $url .= "?$params" if $params; - - my $request = HTTP::Request->new($method => $url); - $request->content(encode_json($data)) if $data; - my $response = $self->user_agent->request($request); - - if (not $response->is_success) { - Carp::croak("HTTP Error (".$response->status_line.")"); - } - print STDERR "[".$response->content."]\n"; - return decode_json($response->content); -} - -1; - diff --git a/lib/WWW/Firebase/TokenGenerator.pm b/lib/WWW/Firebase/TokenGenerator.pm deleted file mode 100644 index c48227b1..00000000 --- a/lib/WWW/Firebase/TokenGenerator.pm +++ /dev/null @@ -1,69 +0,0 @@ -package WWW::Firebase::TokenGenerator; - -use Moose; -use JSON; -use JSON::WebToken; -use DateTime; -use Data::Dumper; - -has 'secret' => ( - is => 'rw', - isa => 'Str', - required => 1, -); - -has 'version' => ( - is => 'ro', - isa => 'Int', - default => 0, -); - -has 'expires' => ( - is => 'rw', - isa => 'Maybe[DateTime]', -); - -has 'not_before' => ( - is => 'rw', - isa => 'Maybe[DateTime]', -); - -has 'debug' => ( - is => 'rw', - isa => 'Maybe[Int]', -); - -has 'admin' => ( - is => 'rw', - isa => 'Maybe[Int]', -); - -has 'algorithm' => ( - is => 'rw', - isa => 'Str', - default => 'HS256', -); - -sub create_token { - my ($self, $data) = @_; - - # ensure that data is JSONifiable - my $json = encode_json($data); - - my $claims = { - d => $data, - v => $self->version, - iat => time, - }; - $claims->{admin} = $self->admin if $self->admin; - $claims->{debug} = $self->debug if $self->debug; - $claims->{nbf} = $self->not_before->epoch if defined $self->not_before; - $claims->{exp} = $self->expires->epoch if defined $self->expires; - - my $jwt = encode_jwt($claims, $self->secret, $self->algorithm); -} - - -1; - - diff --git a/t/550_firebase.t b/t/550_firebase.t deleted file mode 100644 index d82059f8..00000000 --- a/t/550_firebase.t +++ /dev/null @@ -1,107 +0,0 @@ -use lib '../lib'; -use Test::More tests => 1; -use Test::Deep; -use Data::Dumper; -use 5.010; -use DateTime; -use WWW::Firebase::TokenGenerator; -use WWW::Firebase::API::Connection; -use DateTime; - -use TestHelper; - -my $tester = TestHelper->new({empire_name => 'icydee'}); - -$tester->use_existing_test_empire; -my $session_id = $tester->session->id; -my $empire = $tester->empire; - -my $token_generator = WWW::Firebase::TokenGenerator->new({ - secret => 'EiFR06EdQcht5WCiwSSPNGOcUK16dpUXc1OHp1cS', - admin => $empire->is_admin, -}); - -isa_ok($token_generator,'WWW::Firebase::TokenGenerator'); - -my $token = $token_generator->create_token({ - empire_name => $empire->name, - empire_id => $empire->id, - alliance_name => defined $empire->alliance_id ? $empire->alliance->name : '', - alliance_id => $empire->alliance_id || 0, -}); - -diag($token); - -my $connection = WWW::Firebase::API::Connection->new({ - base_uri => 'https://lacuna-chat.firebaseio.com/', - auth => $token, -}); - -my $response; - -# This inserts a new record, or replaces an existing record -$response = $connection->PUT('person/945', { - empire => 'icydee', - on_line => 0, -}); - -# Insert or update -$response = $connection->PUT('person/46', { - empire => 'Norway', - on_line => 1, -}); - - -$response = $connection->PUT('chatroom/Secret', { - is_public => 0, -}); - -$response = $connection->POST('chatroom/Secret/auth_people', { - person => { - id => 945, - name => 'icydee', - }, -}); - - -my $now = DateTime->now; -# put a new chat posting. -$response = $connection->POST('chatroom/General/chat', { - person => { - id => 945, - name => 'icydee', - }, - datetime => $now->ymd('-').' '.$now->hms(':'), - text => 'Hello world', -}); - - - - - - -exit; - - - -my $response = $connection->GET('chat'); - -$response = $connection->POST('chat/room/general/chat',{ empire => {name => 'Freda', id => 3}, text => 'Hello world 2'}); - -diag(Dumper($response)); - -my $name = $response->{name}; - -$response= $connection->GET("chat/room/general/chat/$name"); -diag(Dumper($response)); - -# now delete it again -$response = $connection->DELETE("chat/room/general/chat/$name"); -diag("DELETE response:".Dumper($response)); - - -diag(Dumper($name)); - - -ok(1); - diff --git a/var/upgrades/4.0003.sql b/var/upgrades/4.0003.sql new file mode 100644 index 00000000..d1cc421a --- /dev/null +++ b/var/upgrades/4.0003.sql @@ -0,0 +1,12 @@ +-- Remove dead third-party integration columns from `empire`. +-- +-- `facebook_uid` / `facebook_token` / `skip_facebook_wall_posts` supported the +-- Facebook::Graph login + wall-post integration (lib/Lacuna/Web/Facebook.pm), +-- now removed. `chat_admin` was read only by the Firebase/ChiselChat external +-- chat (lib/Lacuna/RPC/Chat.pm, lib/Lacuna/Web/Chat.pm), also removed. Nothing +-- in the codebase references any of these columns any more. + +ALTER TABLE empire DROP COLUMN facebook_uid; +ALTER TABLE empire DROP COLUMN facebook_token; +ALTER TABLE empire DROP COLUMN skip_facebook_wall_posts; +ALTER TABLE empire DROP COLUMN chat_admin; diff --git a/var/upgrades/4.0004.sql b/var/upgrades/4.0004.sql new file mode 100644 index 00000000..a8a56cf5 --- /dev/null +++ b/var/upgrades/4.0004.sql @@ -0,0 +1,9 @@ +-- Remove browser fingerprinting from login tracking. +-- +-- `login_log.browser_fingerprint` stored a client-supplied browser fingerprint +-- captured on every login (login RPC's 5th param -> Lacuna::Session::start -> +-- login_log). It was only ever used by the admin login-log search to correlate +-- accounts by device. Nothing in the codebase references it any more. + +ALTER TABLE login_log DROP INDEX idx_fingerprint; +ALTER TABLE login_log DROP COLUMN browser_fingerprint; diff --git a/var/www/public/chiselchat/chiselchat.min.css b/var/www/public/chiselchat/chiselchat.min.css deleted file mode 100644 index e9e878df..00000000 --- a/var/www/public/chiselchat/chiselchat.min.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8";#chiselchat{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;font-size:12px;z-index:2000000000;position:relative}#chiselchat-tab-list{position:fixed;bottom:0;right:0;width:100%;height:20px;border:0;list-style-type:none;margin:0;padding:0;z-index:2000000001}#chiselchat-tab-list li{display:inline;width:120px;background-color:#0099f2;margin-right:5px;padding:3px;float:right;border:1px solid #0099f2;height:20px;position:relative;overflow:hidden;white-space:nowrap;-webkit-border-top-right-radius:2px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:2px;-moz-border-radius-topright:2px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:2px;border-top-right-radius:2px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:2px;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}#chiselchat-tab-list li a{text-decoration:none;color:#111;width:100%;display:block}#chiselchat-tab-list li:hover{background-color:#fc0}#chiselchat-tab-list li a:hover{color:#000}#chiselchat-tab-list li#chiselchat-presence-tab{width:55px}#chiselchat-tab-list li#chiselchat-room-tab{margin:0;width:55px}#chiselchat-tab-list li .chiselchat-new-count{background-color:#fc0;color:#000;font-size:80%;font-weight:bold;display:inline-block;padding:1px 3px 1px 3px;position:absolute;right:3px;top:3px}#chiselchat-tab-list li .chiselchat-new-count.chiselchat-new-count-alert{background-color:#f00;color:#fff}#chiselchat-tab-list li.active{background-color:#fff;font-weight:bold;border:1px solid #fff}#chiselchat-tab-list li.active a{color:#000}#chiselchat-tab-list li.active .chiselchat-new-count{display:none}#chiselchat-tab-content{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;z-index:2000000001}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-title{color:#111;background-color:#0099f2;margin:0;display:block;padding:5px;height:13px;font-weight:bold;z-index:1000001;overflow:hidden;-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:3px;border-top-right-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:3px;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-pane-controls{position:absolute;top:2px;right:5px}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-pane-controls a{color:#000;text-decoration:none;font-size:110%;display:inline-block;vertical-align:top;padding-left:5px}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-toggle-sound{padding-top:2px}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-toggle-pane-size{font-size:130%;padding-top:5px}#chiselchat-tab-content .chiselchat-tab-pane{position:fixed;bottom:25px;right:5px;background-color:#fff;width:50%;height:50%;display:none;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#chiselchat-tab-content .chiselchat-tab-pane.active{display:block}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-tab-pane-menu{width:35%;overflow-y:auto;overflow-x:hidden;float:right;color:#000;height:80%}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-tab-pane-menu a{color:#000}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history{z-index:1000000;width:65%;overflow-y:scroll;overflow-x:hidden;float:left;height:80%}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message{margin:5px;margin-top:13px;padding:0;color:#000}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-avatar{margin-right:5px;width:30px;height:30px;float:left;text-align:center}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-avatar img{width:100%;height:100%;margin-bottom:2px}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-user a{font-size:90%;text-decoration:none;color:#014986}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-timestamp{color:#000;font-size:60%;display:inline}#chiselchat-tab-content .chiselchat-tab-pane span.chiselchat-controls{display:inline}#chiselchat-user-search span.chiselchat-controls a,#chiselchat-tab-content .chiselchat-tab-pane span.chiselchat-controls a,#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message .chiselchat-message-content span.chiselchat-controls a{font-size:80%;padding:1px;color:#aaa;margin-left:10px;text-decoration:none}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message-content{margin-top:3px;margin-left:30px;padding-right:10px;font-size:110%}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-user .chiselchat-guest{color:#000}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-user .chiselchat-moderator{font-weight:bold;color:#ff9b00}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-user .chiselchat-staff{font-weight:bold;color:#f00}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-say{z-index:100000001;width:100%;height:50px;position:absolute;bottom:0;left:0}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-say textarea{margin:0;font-family:inherit;overflow:auto;vertical-align:top;color:#000;border:5px solid #fff;background-color:#eee;width:100%;padding:1px;height:100%;font-size:110%;max-width:100%;font-family:sans-serif;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;box-sizing:border-box}#chiselchat #chiselchat-presence-pane,#chiselchat #chiselchat-room-pane{position:fixed;bottom:25px;right:5px;background-color:#fff;color:#000;width:140px;height:50%;display:none;overflow:hidden}#chiselchat .chiselchat-tab-pane .chiselchat-scrollable-list{overflow-y:auto;overflow-x:hidden;height:80%}#chiselchat #chiselchat-room-pane #chiselchat-room-list,#chiselchat #chiselchat-presence-pane #chiselchat-user-search{padding-left:5px}#chiselchat #chiselchat-room-pane #chiselchat-room-list li,#chiselchat #chiselchat-presence-pane #chiselchat-user-search li{padding-bottom:5px}#chiselchat #chiselchat-presence-pane .chiselchat-user-list-item,#chiselchat #chiselchat-room-pane .chiselchat-room-list-item{color:#000;text-decoration:none}#chiselchat #chiselchat-presence-pane.active,#chiselchat #chiselchat-room-pane.active{display:block}#chiselchat-tab-content .chiselchat-tab-pane.active.fullscreen,#chiselchat-tab-content #chiselchat-presence-pane.active.fullscreen,#chiselchat-tab-content #chiselchat-room-pane.active.fullscreen{width:99%;height:96%}#chiselchat-tab-content .chiselchat-tab-pane.fullscreen .chiselchat-tab-pane-menu{width:25%}#chiselchat-tab-content .chiselchat-tab-pane.fullscreen .chiselchat-history{width:75%}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message .chiselchat-message-content a{color:#014986}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message-activity{text-align:center;font-style:italic;color:#000}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message-activity .chiselchat-avatar,#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message-activity .chiselchat-timestamp,#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message-activity .chiselchat-user .chiselchat-controls{display:none}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message-activity .chiselchat-user,#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history .chiselchat-message-activity .chiselchat-message-content{display:inline;padding:0;margin:0}div.chiselchat-alert,.chiselchat-alert .alert{z-index:2000000002;color:#000;background-color:#fff;font-family:sans-serif}.chiselchat-alert hr{border-top-color:#000}.chiselchat-alert .alert-link{color:#014986}@media(max-width:960px){div.chiselchat-alert,.chiselchat-alert .alert{width:50%}#chiselchat-tab-content .chiselchat-tab-pane.active,#chiselchat-tab-content #chiselchat-presence-pane.active,#chiselchat-tab-content #chiselchat-room-pane.active{bottom:35px;width:98%;height:94%}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-toggle-pane-size{display:none}#chiselchat-tab-list{height:30px}#chiselchat-tab-list li{height:30px;width:110px;font-size:150%}#chiselchat-tab-list li#chiselchat-presence-tab,#chiselchat-tab-list li#chiselchat-room-tab{width:18px}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-tab-pane-menu{display:none}#chiselchat-tab-content .chiselchat-tab-pane .chiselchat-history{width:100%;float:none;height:100%}}@font-face{font-family:'Glyphicons Halflings';src:url('//netdna.bootstrapcdn.com/bootstrap/3.0.3/fonts/glyphicons-halflings-regular.eot');src:url('//netdna.bootstrapcdn.com/bootstrap/3.0.3/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('//netdna.bootstrapcdn.com/bootstrap/3.0.3/fonts/glyphicons-halflings-regular.woff') format('woff'),url('//netdna.bootstrapcdn.com/bootstrap/3.0.3/fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('//netdna.bootstrapcdn.com/bootstrap/3.0.3/fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.chiselchat-glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1;-moz-osx-font-smoothing:grayscale}.chiselchat-glyphicon:empty{width:1em}.chiselchat-glyphicon-asterisk:before{content:"\2a"}.chiselchat-glyphicon-plus:before{content:"\2b"}.chiselchat-glyphicon-euro:before{content:"\20ac"}.chiselchat-glyphicon-minus:before{content:"\2212"}.chiselchat-glyphicon-cloud:before{content:"\2601"}.chiselchat-glyphicon-envelope:before{content:"\2709"}.chiselchat-glyphicon-pencil:before{content:"\270f"}.chiselchat-glyphicon-glass:before{content:"\e001"}.chiselchat-glyphicon-music:before{content:"\e002"}.chiselchat-glyphicon-search:before{content:"\e003"}.chiselchat-glyphicon-heart:before{content:"\e005"}.chiselchat-glyphicon-star:before{content:"\e006"}.chiselchat-glyphicon-star-empty:before{content:"\e007"}.chiselchat-glyphicon-user:before{content:"\e008"}.chiselchat-glyphicon-film:before{content:"\e009"}.chiselchat-glyphicon-th-large:before{content:"\e010"}.chiselchat-glyphicon-th:before{content:"\e011"}.chiselchat-glyphicon-th-list:before{content:"\e012"}.chiselchat-glyphicon-ok:before{content:"\e013"}.chiselchat-glyphicon-remove:before{content:"\e014"}.chiselchat-glyphicon-zoom-in:before{content:"\e015"}.chiselchat-glyphicon-zoom-out:before{content:"\e016"}.chiselchat-glyphicon-off:before{content:"\e017"}.chiselchat-glyphicon-signal:before{content:"\e018"}.chiselchat-glyphicon-cog:before{content:"\e019"}.chiselchat-glyphicon-trash:before{content:"\e020"}.chiselchat-glyphicon-home:before{content:"\e021"}.chiselchat-glyphicon-file:before{content:"\e022"}.chiselchat-glyphicon-time:before{content:"\e023"}.chiselchat-glyphicon-road:before{content:"\e024"}.chiselchat-glyphicon-download-alt:before{content:"\e025"}.chiselchat-glyphicon-download:before{content:"\e026"}.chiselchat-glyphicon-upload:before{content:"\e027"}.chiselchat-glyphicon-inbox:before{content:"\e028"}.chiselchat-glyphicon-play-circle:before{content:"\e029"}.chiselchat-glyphicon-repeat:before{content:"\e030"}.chiselchat-glyphicon-refresh:before{content:"\e031"}.chiselchat-glyphicon-list-alt:before{content:"\e032"}.chiselchat-glyphicon-lock:before{content:"\e033"}.chiselchat-glyphicon-flag:before{content:"\e034"}.chiselchat-glyphicon-headphones:before{content:"\e035"}.chiselchat-glyphicon-volume-off:before{content:"\e036"}.chiselchat-glyphicon-volume-down:before{content:"\e037"}.chiselchat-glyphicon-volume-up:before{content:"\e038"}.chiselchat-glyphicon-qrcode:before{content:"\e039"}.chiselchat-glyphicon-barcode:before{content:"\e040"}.chiselchat-glyphicon-tag:before{content:"\e041"}.chiselchat-glyphicon-tags:before{content:"\e042"}.chiselchat-glyphicon-book:before{content:"\e043"}.chiselchat-glyphicon-bookmark:before{content:"\e044"}.chiselchat-glyphicon-print:before{content:"\e045"}.chiselchat-glyphicon-camera:before{content:"\e046"}.chiselchat-glyphicon-font:before{content:"\e047"}.chiselchat-glyphicon-bold:before{content:"\e048"}.chiselchat-glyphicon-italic:before{content:"\e049"}.chiselchat-glyphicon-text-height:before{content:"\e050"}.chiselchat-glyphicon-text-width:before{content:"\e051"}.chiselchat-glyphicon-align-left:before{content:"\e052"}.chiselchat-glyphicon-align-center:before{content:"\e053"}.chiselchat-glyphicon-align-right:before{content:"\e054"}.chiselchat-glyphicon-align-justify:before{content:"\e055"}.chiselchat-glyphicon-list:before{content:"\e056"}.chiselchat-glyphicon-indent-left:before{content:"\e057"}.chiselchat-glyphicon-indent-right:before{content:"\e058"}.chiselchat-glyphicon-facetime-video:before{content:"\e059"}.chiselchat-glyphicon-picture:before{content:"\e060"}.chiselchat-glyphicon-map-marker:before{content:"\e062"}.chiselchat-glyphicon-adjust:before{content:"\e063"}.chiselchat-glyphicon-tint:before{content:"\e064"}.chiselchat-glyphicon-edit:before{content:"\e065"}.chiselchat-glyphicon-share:before{content:"\e066"}.chiselchat-glyphicon-check:before{content:"\e067"}.chiselchat-glyphicon-move:before{content:"\e068"}.chiselchat-glyphicon-step-backward:before{content:"\e069"}.chiselchat-glyphicon-fast-backward:before{content:"\e070"}.chiselchat-glyphicon-backward:before{content:"\e071"}.chiselchat-glyphicon-play:before{content:"\e072"}.chiselchat-glyphicon-pause:before{content:"\e073"}.chiselchat-glyphicon-stop:before{content:"\e074"}.chiselchat-glyphicon-forward:before{content:"\e075"}.chiselchat-glyphicon-fast-forward:before{content:"\e076"}.chiselchat-glyphicon-step-forward:before{content:"\e077"}.chiselchat-glyphicon-eject:before{content:"\e078"}.chiselchat-glyphicon-chevron-left:before{content:"\e079"}.chiselchat-glyphicon-chevron-right:before{content:"\e080"}.chiselchat-glyphicon-plus-sign:before{content:"\e081"}.chiselchat-glyphicon-minus-sign:before{content:"\e082"}.chiselchat-glyphicon-remove-sign:before{content:"\e083"}.chiselchat-glyphicon-ok-sign:before{content:"\e084"}.chiselchat-glyphicon-question-sign:before{content:"\e085"}.chiselchat-glyphicon-info-sign:before{content:"\e086"}.chiselchat-glyphicon-screenshot:before{content:"\e087"}.chiselchat-glyphicon-remove-circle:before{content:"\e088"}.chiselchat-glyphicon-ok-circle:before{content:"\e089"}.chiselchat-glyphicon-ban-circle:before{content:"\e090"}.chiselchat-glyphicon-arrow-left:before{content:"\e091"}.chiselchat-glyphicon-arrow-right:before{content:"\e092"}.chiselchat-glyphicon-arrow-up:before{content:"\e093"}.chiselchat-glyphicon-arrow-down:before{content:"\e094"}.chiselchat-glyphicon-share-alt:before{content:"\e095"}.chiselchat-glyphicon-resize-full:before{content:"\e096"}.chiselchat-glyphicon-resize-small:before{content:"\e097"}.chiselchat-glyphicon-exclamation-sign:before{content:"\e101"}.chiselchat-glyphicon-gift:before{content:"\e102"}.chiselchat-glyphicon-leaf:before{content:"\e103"}.chiselchat-glyphicon-fire:before{content:"\e104"}.chiselchat-glyphicon-eye-open:before{content:"\e105"}.chiselchat-glyphicon-eye-close:before{content:"\e106"}.chiselchat-glyphicon-warning-sign:before{content:"\e107"}.chiselchat-glyphicon-plane:before{content:"\e108"}.chiselchat-glyphicon-calendar:before{content:"\e109"}.chiselchat-glyphicon-random:before{content:"\e110"}.chiselchat-glyphicon-comment:before{content:"\e111"}.chiselchat-glyphicon-magnet:before{content:"\e112"}.chiselchat-glyphicon-chevron-up:before{content:"\e113"}.chiselchat-glyphicon-chevron-down:before{content:"\e114"}.chiselchat-glyphicon-retweet:before{content:"\e115"}.chiselchat-glyphicon-shopping-cart:before{content:"\e116"}.chiselchat-glyphicon-folder-close:before{content:"\e117"}.chiselchat-glyphicon-folder-open:before{content:"\e118"}.chiselchat-glyphicon-resize-vertical:before{content:"\e119"}.chiselchat-glyphicon-resize-horizontal:before{content:"\e120"}.chiselchat-glyphicon-hdd:before{content:"\e121"}.chiselchat-glyphicon-bullhorn:before{content:"\e122"}.chiselchat-glyphicon-bell:before{content:"\e123"}.chiselchat-glyphicon-certificate:before{content:"\e124"}.chiselchat-glyphicon-thumbs-up:before{content:"\e125"}.chiselchat-glyphicon-thumbs-down:before{content:"\e126"}.chiselchat-glyphicon-hand-right:before{content:"\e127"}.chiselchat-glyphicon-hand-left:before{content:"\e128"}.chiselchat-glyphicon-hand-up:before{content:"\e129"}.chiselchat-glyphicon-hand-down:before{content:"\e130"}.chiselchat-glyphicon-circle-arrow-right:before{content:"\e131"}.chiselchat-glyphicon-circle-arrow-left:before{content:"\e132"}.chiselchat-glyphicon-circle-arrow-up:before{content:"\e133"}.chiselchat-glyphicon-circle-arrow-down:before{content:"\e134"}.chiselchat-glyphicon-globe:before{content:"\e135"}.chiselchat-glyphicon-wrench:before{content:"\e136"}.chiselchat-glyphicon-tasks:before{content:"\e137"}.chiselchat-glyphicon-filter:before{content:"\e138"}.chiselchat-glyphicon-briefcase:before{content:"\e139"}.chiselchat-glyphicon-fullscreen:before{content:"\e140"}.chiselchat-glyphicon-dashboard:before{content:"\e141"}.chiselchat-glyphicon-paperclip:before{content:"\e142"}.chiselchat-glyphicon-heart-empty:before{content:"\e143"}.chiselchat-glyphicon-link:before{content:"\e144"}.chiselchat-glyphicon-phone:before{content:"\e145"}.chiselchat-glyphicon-pushpin:before{content:"\e146"}.chiselchat-glyphicon-usd:before{content:"\e148"}.chiselchat-glyphicon-gbp:before{content:"\e149"}.chiselchat-glyphicon-sort:before{content:"\e150"}.chiselchat-glyphicon-sort-by-alphabet:before{content:"\e151"}.chiselchat-glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.chiselchat-glyphicon-sort-by-order:before{content:"\e153"}.chiselchat-glyphicon-sort-by-order-alt:before{content:"\e154"}.chiselchat-glyphicon-sort-by-attributes:before{content:"\e155"}.chiselchat-glyphicon-sort-by-attributes-alt:before{content:"\e156"}.chiselchat-glyphicon-unchecked:before{content:"\e157"}.chiselchat-glyphicon-expand:before{content:"\e158"}.chiselchat-glyphicon-collapse-down:before{content:"\e159"}.chiselchat-glyphicon-collapse-up:before{content:"\e160"}.chiselchat-glyphicon-log-in:before{content:"\e161"}.chiselchat-glyphicon-flash:before{content:"\e162"}.chiselchat-glyphicon-log-out:before{content:"\e163"}.chiselchat-glyphicon-new-window:before{content:"\e164"}.chiselchat-glyphicon-record:before{content:"\e165"}.chiselchat-glyphicon-save:before{content:"\e166"}.chiselchat-glyphicon-open:before{content:"\e167"}.chiselchat-glyphicon-saved:before{content:"\e168"}.chiselchat-glyphicon-import:before{content:"\e169"}.chiselchat-glyphicon-export:before{content:"\e170"}.chiselchat-glyphicon-send:before{content:"\e171"}.chiselchat-glyphicon-floppy-disk:before{content:"\e172"}.chiselchat-glyphicon-floppy-saved:before{content:"\e173"}.chiselchat-glyphicon-floppy-remove:before{content:"\e174"}.chiselchat-glyphicon-floppy-save:before{content:"\e175"}.chiselchat-glyphicon-floppy-open:before{content:"\e176"}.chiselchat-glyphicon-credit-card:before{content:"\e177"}.chiselchat-glyphicon-transfer:before{content:"\e178"}.chiselchat-glyphicon-cutlery:before{content:"\e179"}.chiselchat-glyphicon-header:before{content:"\e180"}.chiselchat-glyphicon-compressed:before{content:"\e181"}.chiselchat-glyphicon-earphone:before{content:"\e182"}.chiselchat-glyphicon-phone-alt:before{content:"\e183"}.chiselchat-glyphicon-tower:before{content:"\e184"}.chiselchat-glyphicon-stats:before{content:"\e185"}.chiselchat-glyphicon-sd-video:before{content:"\e186"}.chiselchat-glyphicon-hd-video:before{content:"\e187"}.chiselchat-glyphicon-subtitles:before{content:"\e188"}.chiselchat-glyphicon-sound-stereo:before{content:"\e189"}.chiselchat-glyphicon-sound-dolby:before{content:"\e190"}.chiselchat-glyphicon-sound-5-1:before{content:"\e191"}.chiselchat-glyphicon-sound-6-1:before{content:"\e192"}.chiselchat-glyphicon-sound-7-1:before{content:"\e193"}.chiselchat-glyphicon-copyright-mark:before{content:"\e194"}.chiselchat-glyphicon-registration-mark:before{content:"\e195"}.chiselchat-glyphicon-cloud-download:before{content:"\e197"}.chiselchat-glyphicon-cloud-upload:before{content:"\e198"}.chiselchat-glyphicon-tree-conifer:before{content:"\e199"}.chiselchat-glyphicon-tree-deciduous:before{content:"\e200"} diff --git a/var/www/public/chiselchat/chiselchat.min.js b/var/www/public/chiselchat/chiselchat.min.js deleted file mode 100644 index 158a5da7..00000000 --- a/var/www/public/chiselchat/chiselchat.min.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){var e=this,t=e._,a={},n=Array.prototype,i=Object.prototype,s=Function.prototype,r=n.push,o=n.slice,c=n.concat,l=i.toString,u=i.hasOwnProperty,h=n.forEach,d=n.map,f=n.reduce,m=n.reduceRight,p=n.filter,v=n.every,_=n.some,g=n.indexOf,y=n.lastIndexOf,b=Array.isArray,R=Object.keys,C=s.bind,I=function(e){return e instanceof I?e:this instanceof I?(this._wrapped=e,void 0):new I(e)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=I),exports._=I):e._=I,I.VERSION="1.4.4";var M=I.each=I.forEach=function(e,t,n){if(null!=e)if(h&&e.forEach===h)e.forEach(t,n);else if(e.length===+e.length){for(var i=0,s=e.length;s>i;i++)if(t.call(n,e[i],i,e)===a)return}else for(var r in e)if(I.has(e,r)&&t.call(n,e[r],r,e)===a)return};I.map=I.collect=function(e,t,a){var n=[];return null==e?n:d&&e.map===d?e.map(t,a):(M(e,function(e,i,s){n[n.length]=t.call(a,e,i,s)}),n)};var w="Reduce of empty array with no initial value";I.reduce=I.foldl=I.inject=function(e,t,a,n){var i=arguments.length>2;if(null==e&&(e=[]),f&&e.reduce===f)return n&&(t=I.bind(t,n)),i?e.reduce(t,a):e.reduce(t);if(M(e,function(e,s,r){i?a=t.call(n,a,e,s,r):(a=e,i=!0)}),!i)throw new TypeError(w);return a},I.reduceRight=I.foldr=function(e,t,a,n){var i=arguments.length>2;if(null==e&&(e=[]),m&&e.reduceRight===m)return n&&(t=I.bind(t,n)),i?e.reduceRight(t,a):e.reduceRight(t);var s=e.length;if(s!==+s){var r=I.keys(e);s=r.length}if(M(e,function(o,c,l){c=r?r[--s]:--s,i?a=t.call(n,a,e[c],c,l):(a=e[c],i=!0)}),!i)throw new TypeError(w);return a},I.find=I.detect=function(e,t,a){var n;return U(e,function(e,i,s){return t.call(a,e,i,s)?(n=e,!0):void 0}),n},I.filter=I.select=function(e,t,a){var n=[];return null==e?n:p&&e.filter===p?e.filter(t,a):(M(e,function(e,i,s){t.call(a,e,i,s)&&(n[n.length]=e)}),n)},I.reject=function(e,t,a){return I.filter(e,function(e,n,i){return!t.call(a,e,n,i)},a)},I.every=I.all=function(e,t,n){t||(t=I.identity);var i=!0;return null==e?i:v&&e.every===v?e.every(t,n):(M(e,function(e,s,r){return(i=i&&t.call(n,e,s,r))?void 0:a}),!!i)};var U=I.some=I.any=function(e,t,n){t||(t=I.identity);var i=!1;return null==e?i:_&&e.some===_?e.some(t,n):(M(e,function(e,s,r){return i||(i=t.call(n,e,s,r))?a:void 0}),!!i)};I.contains=I.include=function(e,t){return null==e?!1:g&&e.indexOf===g?-1!=e.indexOf(t):U(e,function(e){return e===t})},I.invoke=function(e,t){var a=o.call(arguments,2),n=I.isFunction(t);return I.map(e,function(e){return(n?t:e[t]).apply(e,a)})},I.pluck=function(e,t){return I.map(e,function(e){return e[t]})},I.where=function(e,t,a){return I.isEmpty(t)?a?null:[]:I[a?"find":"filter"](e,function(e){for(var a in t)if(t[a]!==e[a])return!1;return!0})},I.findWhere=function(e,t){return I.where(e,t,!0)},I.max=function(e,t,a){if(!t&&I.isArray(e)&&e[0]===+e[0]&&65535>e.length)return Math.max.apply(Math,e);if(!t&&I.isEmpty(e))return-1/0;var n={computed:-1/0,value:-1/0};return M(e,function(e,i,s){var r=t?t.call(a,e,i,s):e;r>=n.computed&&(n={value:e,computed:r})}),n.value},I.min=function(e,t,a){if(!t&&I.isArray(e)&&e[0]===+e[0]&&65535>e.length)return Math.min.apply(Math,e);if(!t&&I.isEmpty(e))return 1/0;var n={computed:1/0,value:1/0};return M(e,function(e,i,s){var r=t?t.call(a,e,i,s):e;n.computed>r&&(n={value:e,computed:r})}),n.value},I.shuffle=function(e){var t,a=0,n=[];return M(e,function(e){t=I.random(a++),n[a-1]=n[t],n[t]=e}),n};var x=function(e){return I.isFunction(e)?e:function(t){return t[e]}};I.sortBy=function(e,t,a){var n=x(t);return I.pluck(I.map(e,function(e,t,i){return{value:e,index:t,criteria:n.call(a,e,t,i)}}).sort(function(e,t){var a=e.criteria,n=t.criteria;if(a!==n){if(a>n||void 0===a)return 1;if(n>a||void 0===n)return-1}return e.indexs;){var o=s+r>>>1;i>a.call(n,e[o])?s=o+1:r=o}return s},I.toArray=function(e){return e?I.isArray(e)?o.call(e):e.length===+e.length?I.map(e,I.identity):I.values(e):[]},I.size=function(e){return null==e?0:e.length===+e.length?e.length:I.keys(e).length},I.first=I.head=I.take=function(e,t,a){return null==e?void 0:null==t||a?e[0]:o.call(e,0,t)},I.initial=function(e,t,a){return o.call(e,0,e.length-(null==t||a?1:t))},I.last=function(e,t,a){return null==e?void 0:null==t||a?e[e.length-1]:o.call(e,Math.max(e.length-t,0))},I.rest=I.tail=I.drop=function(e,t,a){return o.call(e,null==t||a?1:t)},I.compact=function(e){return I.filter(e,I.identity)};var j=function(e,t,a){return M(e,function(e){I.isArray(e)?t?r.apply(a,e):j(e,t,a):a.push(e)}),a};I.flatten=function(e,t){return j(e,t,[])},I.without=function(e){return I.difference(e,o.call(arguments,1))},I.uniq=I.unique=function(e,t,a,n){I.isFunction(t)&&(n=a,a=t,t=!1);var i=a?I.map(e,a,n):e,s=[],r=[];return M(i,function(a,n){(t?n&&r[r.length-1]===a:I.contains(r,a))||(r.push(a),s.push(e[n]))}),s},I.union=function(){return I.uniq(c.apply(n,arguments))},I.intersection=function(e){var t=o.call(arguments,1);return I.filter(I.uniq(e),function(e){return I.every(t,function(t){return I.indexOf(t,e)>=0})})},I.difference=function(e){var t=c.apply(n,o.call(arguments,1));return I.filter(e,function(e){return!I.contains(t,e)})},I.zip=function(){for(var e=o.call(arguments),t=I.max(I.pluck(e,"length")),a=Array(t),n=0;t>n;n++)a[n]=I.pluck(e,""+n);return a},I.object=function(e,t){if(null==e)return{};for(var a={},n=0,i=e.length;i>n;n++)t?a[e[n]]=t[n]:a[e[n][0]]=e[n][1];return a},I.indexOf=function(e,t,a){if(null==e)return-1;var n=0,i=e.length;if(a){if("number"!=typeof a)return n=I.sortedIndex(e,t),e[n]===t?n:-1;n=0>a?Math.max(0,i+a):a}if(g&&e.indexOf===g)return e.indexOf(t,a);for(;i>n;n++)if(e[n]===t)return n;return-1},I.lastIndexOf=function(e,t,a){if(null==e)return-1;var n=null!=a;if(y&&e.lastIndexOf===y)return n?e.lastIndexOf(t,a):e.lastIndexOf(t);for(var i=n?a:e.length;i--;)if(e[i]===t)return i;return-1},I.range=function(e,t,a){1>=arguments.length&&(t=e||0,e=0),a=arguments[2]||1;for(var n=Math.max(Math.ceil((t-e)/a),0),i=0,s=Array(n);n>i;)s[i++]=e,e+=a;return s},I.bind=function(e,t){if(e.bind===C&&C)return C.apply(e,o.call(arguments,1));var a=o.call(arguments,2);return function(){return e.apply(t,a.concat(o.call(arguments)))}},I.partial=function(e){var t=o.call(arguments,1);return function(){return e.apply(this,t.concat(o.call(arguments)))}},I.bindAll=function(e){var t=o.call(arguments,1);return 0===t.length&&(t=I.functions(e)),M(t,function(t){e[t]=I.bind(e[t],e)}),e},I.memoize=function(e,t){var a={};return t||(t=I.identity),function(){var n=t.apply(this,arguments);return I.has(a,n)?a[n]:a[n]=e.apply(this,arguments)}},I.delay=function(e,t){var a=o.call(arguments,2);return setTimeout(function(){return e.apply(null,a)},t)},I.defer=function(e){return I.delay.apply(I,[e,1].concat(o.call(arguments,1)))},I.throttle=function(e,t){var a,n,i,s,r=0,o=function(){r=new Date,i=null,s=e.apply(a,n)};return function(){var c=new Date,l=t-(c-r);return a=this,n=arguments,0>=l?(clearTimeout(i),i=null,r=c,s=e.apply(a,n)):i||(i=setTimeout(o,l)),s}},I.debounce=function(e,t,a){var n,i;return function(){var s=this,r=arguments,o=function(){n=null,a||(i=e.apply(s,r))},c=a&&!n;return clearTimeout(n),n=setTimeout(o,t),c&&(i=e.apply(s,r)),i}},I.once=function(e){var t,a=!1;return function(){return a?t:(a=!0,t=e.apply(this,arguments),e=null,t)}},I.wrap=function(e,t){return function(){var a=[e];return r.apply(a,arguments),t.apply(this,a)}},I.compose=function(){var e=arguments;return function(){for(var t=arguments,a=e.length-1;a>=0;a--)t=[e[a].apply(this,t)];return t[0]}},I.after=function(e,t){return 0>=e?t():function(){return 1>--e?t.apply(this,arguments):void 0}},I.keys=R||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var a in e)I.has(e,a)&&(t[t.length]=a);return t},I.values=function(e){var t=[];for(var a in e)I.has(e,a)&&t.push(e[a]);return t},I.pairs=function(e){var t=[];for(var a in e)I.has(e,a)&&t.push([a,e[a]]);return t},I.invert=function(e){var t={};for(var a in e)I.has(e,a)&&(t[e[a]]=a);return t},I.functions=I.methods=function(e){var t=[];for(var a in e)I.isFunction(e[a])&&t.push(a);return t.sort()},I.extend=function(e){return M(o.call(arguments,1),function(t){if(t)for(var a in t)e[a]=t[a]}),e},I.pick=function(e){var t={},a=c.apply(n,o.call(arguments,1));return M(a,function(a){a in e&&(t[a]=e[a])}),t},I.omit=function(e){var t={},a=c.apply(n,o.call(arguments,1));for(var i in e)I.contains(a,i)||(t[i]=e[i]);return t},I.defaults=function(e){return M(o.call(arguments,1),function(t){if(t)for(var a in t)null==e[a]&&(e[a]=t[a])}),e},I.clone=function(e){return I.isObject(e)?I.isArray(e)?e.slice():I.extend({},e):e},I.tap=function(e,t){return t(e),e};var k=function(e,t,a,n){if(e===t)return 0!==e||1/e==1/t;if(null==e||null==t)return e===t;e instanceof I&&(e=e._wrapped),t instanceof I&&(t=t._wrapped);var i=l.call(e);if(i!=l.call(t))return!1;switch(i){case"[object String]":return e==t+"";case"[object Number]":return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if("object"!=typeof e||"object"!=typeof t)return!1;for(var s=a.length;s--;)if(a[s]==e)return n[s]==t;a.push(e),n.push(t);var r=0,o=!0;if("[object Array]"==i){if(r=e.length,o=r==t.length)for(;r--&&(o=k(e[r],t[r],a,n)););}else{var c=e.constructor,u=t.constructor;if(c!==u&&!(I.isFunction(c)&&c instanceof c&&I.isFunction(u)&&u instanceof u))return!1;for(var h in e)if(I.has(e,h)&&(r++,!(o=I.has(t,h)&&k(e[h],t[h],a,n))))break;if(o){for(h in t)if(I.has(t,h)&&!r--)break;o=!r}}return a.pop(),n.pop(),o};I.isEqual=function(e,t){return k(e,t,[],[])},I.isEmpty=function(e){if(null==e)return!0;if(I.isArray(e)||I.isString(e))return 0===e.length;for(var t in e)if(I.has(e,t))return!1;return!0},I.isElement=function(e){return!(!e||1!==e.nodeType)},I.isArray=b||function(e){return"[object Array]"==l.call(e)},I.isObject=function(e){return e===Object(e)},M(["Arguments","Function","String","Number","Date","RegExp"],function(e){I["is"+e]=function(t){return l.call(t)=="[object "+e+"]"}}),I.isArguments(arguments)||(I.isArguments=function(e){return!(!e||!I.has(e,"callee"))}),true&&(I.isFunction=function(e){return"function"==typeof e}),I.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},I.isNaN=function(e){return I.isNumber(e)&&e!=+e},I.isBoolean=function(e){return e===!0||e===!1||"[object Boolean]"==l.call(e)},I.isNull=function(e){return null===e},I.isUndefined=function(e){return void 0===e},I.has=function(e,t){return u.call(e,t)},I.noConflict=function(){return e._=t,this},I.identity=function(e){return e},I.times=function(e,t,a){for(var n=Array(e),i=0;e>i;i++)n[i]=t.call(a,i);return n},I.random=function(e,t){return null==t&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var S={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};S.unescape=I.invert(S.escape);var N={escape:RegExp("["+I.keys(S.escape).join("")+"]","g"),unescape:RegExp("("+I.keys(S.unescape).join("|")+")","g")};I.each(["escape","unescape"],function(e){I[e]=function(t){return null==t?"":(""+t).replace(N[e],function(t){return S[e][t]})}}),I.result=function(e,t){if(null==e)return null;var a=e[t];return I.isFunction(a)?a.call(e):a},I.mixin=function(e){M(I.functions(e),function(t){var a=I[t]=e[t];I.prototype[t]=function(){var e=[this._wrapped];return r.apply(e,arguments),F.call(this,a.apply(I,e))}})};var E=0;I.uniqueId=function(e){var t=++E+"";return e?e+t:t},I.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var A=/(.)^/,D={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},L=/\\|'|\r|\n|\t|\u2028|\u2029/g;I.template=function(e,t,a){var n;a=I.defaults({},a,I.templateSettings);var i=RegExp([(a.escape||A).source,(a.interpolate||A).source,(a.evaluate||A).source].join("|")+"|$","g"),s=0,r="__p+='";e.replace(i,function(t,a,n,i,o){return r+=e.slice(s,o).replace(L,function(e){return"\\"+D[e]}),a&&(r+="'+\n((__t=("+a+"))==null?'':_.escape(__t))+\n'"),n&&(r+="'+\n((__t=("+n+"))==null?'':__t)+\n'"),i&&(r+="';\n"+i+"\n__p+='"),s=o+t.length,t}),r+="';\n",a.variable||(r="with(obj||{}){\n"+r+"}\n"),r="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+r+"return __p;\n";try{n=Function(a.variable||"obj","_",r)}catch(o){throw o.source=r,o}if(t)return n(t,I);var c=function(e){return n.call(this,e,I)};return c.source="function("+(a.variable||"obj")+"){\n"+r+"}",c},I.chain=function(e){return I(e).chain()};var F=function(e){return this._chain?I(e).chain():e};I.mixin(I),M(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=n[e];I.prototype[e]=function(){var a=this._wrapped;return t.apply(a,arguments),"shift"!=e&&"splice"!=e||0!==a.length||delete a[0],F.call(this,a)}}),M(["concat","join","slice"],function(e){var t=n[e];I.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),I.extend(I.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),this.ChiselchatDefaultTemplates=this.ChiselchatDefaultTemplates||{},this.ChiselchatDefaultTemplates["templates/layout-full.html"]=function(obj){obj||(obj={});var __p="",__e=_.escape;with(obj)__p+="
\n\n\n
\n
\n
\nPeople\n\n_\n▀\n\n
\n
\n\n\n
\n
\n
\n
\nRooms\n\n_\n▀\n\n
\n
\n\n
\n
    \n
    \n
    \n
    \n
    ";return __p},this.ChiselchatDefaultTemplates["templates/layout-popout.html"]=function(obj){obj||(obj={});var __p="";with(_.escape,obj)__p+="
    \n
    \n\n
    \n
    \n
    ";return __p},this.ChiselchatDefaultTemplates["templates/message.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(Array.prototype.join,obj)__p+="
    \n
    \n\n
    "+__e(localtime)+"
    \n
    \n
    "+__e(name)+"\n \n\n",disableActions||(__p+="\nPM\nMute\n",userIsModerator&&(__p+="\nWarn\nBan (hour)\nBan (day)\n"),__p+="\n"),__p+="\n\n
    \n
    \n"+(null==(__t=message)?"":__t)+"\n",userIsModerator&&(__p+="\n ×\n"),__p+="\n
    \n
    ";return __p},this.ChiselchatDefaultTemplates["templates/room-list-item.html"]=function(obj){obj||(obj={});var __p="",__e=_.escape;with(Array.prototype.join,obj)__p+="
  • \n"+__e(name)+"\n","official"!=type&&(__p+="\n",userIsModerator&&(__p+="\n×\n"),__p+="\n"),__p+="\n
  • ";return __p},this.ChiselchatDefaultTemplates["templates/room-user-list-item.html"]=function(obj){obj||(obj={});var __p="",__e=_.escape;with(Array.prototype.join,obj)__p+="
  • \n\n"+__e(name)+"\n\n",disableActions||(__p+="\n\n",__p+=isMuted?"Unmute":"Mute",__p+="\nPM\n\n"),__p+="\n
  • ";return __p},this.ChiselchatDefaultTemplates["templates/room-user-search-list-item.html"]=function(obj){obj||(obj={});var __p="",__e=_.escape;with(Array.prototype.join,obj)__p+="
  • \n\n",__p+=disableActions?"\n"+__e(name)+"\n":"\n"+__e(name)+"\n+\n",__p+="\n\n
  • ";return __p},this.ChiselchatDefaultTemplates["templates/tab-content.html"]=function(obj){obj||(obj={});var __p="",__e=_.escape;with(obj)__p+="
    \n
    \n'+__e(name)+"\n\n\n_\n▀\n×\n\n
    \n
    \n
    \n\n
      \nInvite\n\n
      \n
        \n
        \n
        \n
        \n
        \n\n
        \n
        ";return __p},this.ChiselchatDefaultTemplates["templates/tab-menu-item.html"]=function(obj){obj||(obj={});var __p="",__e=_.escape;with(obj)__p+="
      • \n"+__e(name)+" 0\n
      • ";return __p},this.ChiselchatDefaultTemplates["templates/user-search-list-item.html"]=function(obj){obj||(obj={});var __p="",__e=_.escape;with(Array.prototype.join,obj)__p+="
      • \n",__p+=disableActions?"\n"+__e(name)+"\n":"\n"+__e(name)+"\nPM\n",__p+="\n\n
      • ";return __p},function(){Function.prototype.bind||(Function.prototype.bind=function(e){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var t=Array.prototype.slice.call(arguments,1),a=this,n=function(){},i=function(){return a.apply(this instanceof n&&e?this:e,t.concat(Array.prototype.slice.call(arguments)))};return n.prototype=this.prototype,i.prototype=new n,i}),Object.keys=Object.keys||function(e){var t=[];for(var a in e)e.hasOwnProperty(a)&&t.push(a);return t}}(),function(e){function t(e,t){this._firebase=e,this._user=null,this._userId=null,this._userName=null,this._avatarUri="",this._profileUri="",this._isModerator=!1,this._isStaff=!1,this._isGuest=!1,this._sessionId=null,this._events={},this._rooms={},this._presenceBits={},this._userRef=null,this._messageRef=this._firebase.child("room-messages"),this._roomRef=this._firebase.child("room-metadata"),this._privateRoomRef=this._firebase.child("room-private-metadata"),this._moderatorsRef=this._firebase.child("moderators"),this._suspensionsRef=this._firebase.child("suspensions"),this._usersOnlineRef=this._firebase.child("user-names-online"),this._guestNameList=["Arnold","Burton","Cal","Caroline","Peabody","Pubert","Gomez","Morticia","Wednesday","Uncle Fester","Pugsly","Greggory","Greg","Bruce","Jean Claude","Herobrine","Cake","Lilith","Penelope","Rhiannon","Medusa","Sally","Barry","Elmer","Gretel","Chris","David","Donald","Dude","Dudette","Ernest","Esther","Fern","Gertrude","Gus","Hazel","Isobel","Kevin","Malcolm","Neville","Oscar","Paul","Quentin","Rupert","Simon","Thom","Vern","Wally","Trudy","Bertha","Abernathy","Adolf","Attila","Kurt","Helen","Marv","Magda","Hansel","Mort","Gunther","Dreshawn","Percy","Shaneekwa","Ronald","Tyquasia","Tallulah","Margot","Ennis","Roscoe","Heloise","Eunice","Cecil","Bueford","Eustace","Baxter","Tiara","Garland","Judy","Cooter","Daisy","Cletus","Crystal","Martha","Jesse","Bo","Luke","Martha","Jefferson","Martha","Albert","Beauregard","Al","Peggy","Bud","Kelly","Igor","Boris","Natasha","Moose","Squirrel","Fannie","Chuck","Dennis","Hamish","Angus","Tate","Mildred","Waldo","Stewart","Horace","Jean Luc","William","Beverly","Data","Geordi","Worf","Deanna","James","Spock","Leonard","Pavel","Hickaru","Nyota","Wesley","Laren","Miles","Keiko","Montgomery","Christine","Janice"],this._options=t||{},this._chatter_cache={},this._options.numMaxMessages=this._options.numMaxMessages||50}var a=this,n=a.Chiselchat;t.noConflict=function(){return a.Chiselchat=n,t},a.Chiselchat=t,t.prototype={_loadUserMetadata:function(e){var t=this;this._userRef.transaction(function(e){var a={id:t._userId,name:t._userName,avatarUri:t._avatarUri,profileUri:t._profileUri,isModerator:t._isModerator,isStaff:t._isStaff,isGuest:t._isGuest};return e&&(e.rooms&&(a.rooms=e.rooms),e.sessions&&(a.sessions=e.sessions),e.muted&&(a.muted=e.muted)),a.isGuest&&(e&&""!==e.name&&void 0!==e.name?(t._userName=e.name,a.name=e.name,console.log("using existing guest name "+a.name)):(a.name="Guest "+t._guestNameList[Math.floor(Math.random()*t._guestNameList.length)],t._userName=a.name,console.log("setting guest name to "+a.name))),a},function(n,i,s){n?console.warn(n):(t._user=s.val(),t._chatter_cache[t._user.id]=t._user,t._moderatorsRef.child(t._userId).once("value",function(n){t._isModerator=!!n.val(),a.setTimeout(e,0)}))},!1)},_setupDataEvents:function(){this._firebase.root().child(".info/connected").on("value",function(e){if(e.val()===!0)for(var t=0;this._presenceBits>t;t++){var a=this._presenceBits[t],n=this._firebase.root().child(a.ref);n.onDisconnect().set(a.offlineValue),n.set(a.onlineValue)}},this);var e=this._userRef.child("sessions").push();this._sessionId=e.name(),this._queuePresenceOperation(e,!0,null);var t=this._usersOnlineRef.child(this._userName.toLowerCase()),a=t.child(this._sessionId);this._queuePresenceOperation(a,{id:this._userId,name:this._userName},null),this._userRef.on("value",this._onUpdateUser,this),this._userRef.child("invites").on("child_added",this._onChiselchatInvite,this),this._userRef.child("notifications").on("child_added",this._onNotification,this);var n=this;this._roomRef.on("child_removed",function(e){n.leaveRoom(e.name())}),this._roomRef.startAt(Date.now()).on("child_added",function(e){this._onCreateRoom(e)},this),n._roomRef.on("child_changed",function(e){n._invokeEventCallbacks("room-changed",e.val())})},_addEventCallback:function(e,t){this._events[e]=this._events[e]||[],this._events[e].push(t)},_getEventCallbacks:function(e){return this._events.hasOwnProperty(e)?this._events[e]:[]},_invokeEventCallbacks:function(e){var t=[],a=this._getEventCallbacks(e);Array.prototype.push.apply(t,arguments),t=t.slice(1);for(var n=0;a.length>n;n+=1)a[n].apply(null,t)},_queuePresenceOperation:function(e,t,a){e.onDisconnect().set(a),e.set(t),this._presenceBits[""+e]={ref:e,onlineValue:t,offlineValue:a}},_removePresenceOperation:function(t,a){var n=new e(t);n.onDisconnect().cancel(),n.set(a),delete this._presenceBits[t]},_onUpdateUser:function(e){this._user=e.val(),this._invokeEventCallbacks("user-update",this._user)},_onCreateRoom:function(e){var t=e.val();this._invokeEventCallbacks("room-create",t)},_onAuthRequired:function(){this._invokeEventCallbacks("auth-required")},_onEnterRoom:function(e){this._invokeEventCallbacks("room-enter",e)},_onNewMessage:function(e,t){var a=t.val();a.id=t.name(),this._invokeEventCallbacks("message-add",e,a)},_onRemoveMessage:function(e,t){var a=t.name();this._invokeEventCallbacks("message-remove",e,a)},_onLeaveRoom:function(e){this._invokeEventCallbacks("room-exit",e)},_onNotification:function(e){var t=e.val();t.read?e.ref().remove():(e.ref().child("read").set(!0),this._invokeEventCallbacks("notification",t))},_onChiselchatInvite:function(e){var t=this,a=e.val();a.status||(a.id=a.id||e.name(),t.getRoom(a.roomId,function(e){a.toRoomName=e.name,t._invokeEventCallbacks("room-invite",a)}))},_onChiselchatInviteResponse:function(e){var t=e.val();t.id=t.id||e.name(),this._invokeEventCallbacks("room-invite-response",t)}},t.prototype.setUser=function(e,t){var n=this;n._firebase.root().child(".info/authenticated").on("value",function(i){i.val()===!0&&(n._firebase.root().child(".info/authenticated").off(),n._userId=e.userId,n._userName=e.userName,n._isModerator=e.isModerator,n._avatarUri=e.avatarUri,n._profileUri=e.profileUri,n._isGuest=e.isGuest,n._isStaff=e.isStaff,n._isModerator===!0&&(n._moderatorsRef.child(n._userId).set(!0),n._moderatorsRef.child(n._userId).onDisconnect().remove()),n._userRef=n._firebase.child("users").child(n._userId),n._loadUserMetadata(function(){a.setTimeout(function(){n._setupDataEvents(),t(n._user)},0)}))})},t.prototype.unsetUser=function(){var e=this;e._userRef.child("rooms").once("value",function(t){var a=t.val();for(var n in a)e.leaveRoom(a[n].id);e._firebase.root().child(".info/connected").off(),e._userRef.child("invites").off(),e._userRef.child("notifications").off(),e._userRef.off(),e._firebase.root().child(".info/authenticated").off(),e._user=null,e._userId=null,e._userName=null,e._isModerator=!1,e._isGuest=!0,e._avatarUri=null,e._profileUri=null,e._sessionId=null,e._userRef=null})},t.prototype.lookupUser=function(e,t){var a=this;e in a._chatter_cache?t(this._chatter_cache[e]):a._firebase.child("users").child(e).once("value",function(n){var i=n.val();a._chatter_cache[e]=i,t(i)})},t.prototype.resumeSession=function(){this._userRef.child("rooms").once("value",function(e){var t=e.val();for(var a in t)this.enterRoom(t[a].id)},function(){},this),this._roomRef.once("value",function(e){var t=e.val();for(var a in t)"official"==t[a].type&&this.enterRoom(a)},function(){},this)},t.prototype.on=function(e,t){this._addEventCallback(e,t)},t.prototype.createRoom=function(t,a,n){var i=this,s=this._roomRef.push(),r={id:s.name(),name:t,type:a||"public",createdByUserId:this._userId,".priority":e.ServerValue.TIMESTAMP};"private"===a&&(r.authorizedUsers={},r.authorizedUsers[this._userId]=!0),s.set(r,function(e){e||i.enterRoom(s.name()),n&&n(s.name())})},t.prototype.enterRoom=function(e){var t=this;t.getRoom(e,function(a){var n=a.name;if(e&&n&&!t._rooms[e]){if(t._rooms[e]=!0,t._user){t._userRef.child("rooms").child(e).set({id:e,name:n,active:!0});var i=t._firebase.child("room-users").child(e).child(t._userId).child(t._sessionId);t._queuePresenceOperation(i,{id:t._userId,name:t._userName},null)}t._onEnterRoom({id:e,name:n}),t._roomRef.child(e).once("value",function(){t._messageRef.child(e).limit(t._options.numMaxMessages).on("child_added",function(a){t._onNewMessage(e,a)},function(){t.leaveRoom(e)},t),t._messageRef.child(e).limit(t._options.numMaxMessages).on("child_removed",function(a){t._onRemoveMessage(e,a)},function(){},t)},function(){},t)}})},t.prototype.leaveRoom=function(e){var t=this,a=t._firebase.child("room-users").child(e);if(t._messageRef.child(e).off(),t._user){var n=a.child(t._userId).child(t._sessionId);t._removePresenceOperation(""+n,null),t._userRef.child("rooms").child(e).remove()}delete t._rooms[e],t._onLeaveRoom(e)},t.prototype.removeRoom=function(e){var t=this;t.leaveRoom(e),t._firebase.child("users").once("value",function(a){var n=a.val();for(var i in n)t._firebase.child("users").child(i).child(e).remove()}),t._messageRef.child(e).remove(),t._firebase.child("room-users").child(e).remove(),t._roomRef.child(e).remove()},t.prototype.sendMessage=function(t,a,n,i){var s,r=this,o={userId:r._userId,name:r._userName,timestamp:e.ServerValue.TIMESTAMP,message:a,type:n||"default"}; -return r._user?(s=r._messageRef.child(t).push(),s.setWithPriority(o,e.ServerValue.TIMESTAMP,i),void 0):(r._onAuthRequired(),i&&i(Error("Not authenticated or user not set!")),void 0)},t.prototype.deleteMessage=function(e,t,a){var n=this;n._messageRef.child(e).child(t).remove(a)},t.prototype.toggleUserMute=function(e,t){var a=this;return a._user?(a._firebase.child("users").child(e).once("value",function(n){n.val().isModerator?t(Error("Cannot mute a moderator.")):a._userRef.child("muted").child(e).transaction(function(e){return e?null:!0},t)}),void 0):(a._onAuthRequired(),t&&t(Error("Not authenticated or user not set!")),void 0)},t.prototype.sendSuperuserNotification=function(t,a,n,i){var s=this,r=s._firebase.child("users").child(t).child("notifications");r.push({fromUserId:s._userId,timestamp:e.ServerValue.TIMESTAMP,notificationType:a,data:n||{}},i)},t.prototype.warnUser=function(e){var t=this;t.sendSuperuserNotification(e,"warning")},t.prototype.suspendUser=function(e,t,a){var n=this,i=(new Date).getTime()+1e3*t;n._suspensionsRef.child(e).set(i,function(t){return t&&a?a(t):(n.sendSuperuserNotification(e,"suspension",{suspendedUntil:i}),a(null))})},t.prototype.inviteUser=function(e,t){var a=this,n=function(){var n=a._firebase.child("users").child(e).child("invites").push();n.set({id:n.name(),fromUserId:a._userId,fromUserName:a._userName,roomId:t}),n.on("value",a._onChiselchatInviteResponse,function(){},a)};return a._user?(a.getRoom(t,function(i){if("private"===i.type){var s=a._roomRef.child(t).child("authorizedUsers");s.child(e).set(!0,function(e){e||n()})}else n()}),void 0):(a._onAuthRequired(),void 0)},t.prototype.acceptInvite=function(e,t){var a=this;a._userRef.child("invites").child(e).once("value",function(n){var i=n.val();return null===i&&t?t(Error("acceptInvite("+e+"): invalid invite id")):(a.enterRoom(i.roomId),a._userRef.child("invites").child(e).update({status:"accepted",toUserName:a._userName},t(i)),void 0)},a)},t.prototype.declineInvite=function(e,t){var a=this,n={status:"declined",toUserName:a._userName};a._userRef.child("invites").child(e).update(n,t)},t.prototype.getRoomList=function(e){var t=this;t._roomRef.once("value",function(t){e(t.val())})},t.prototype.getUserNameById=function(e,t){var a=this;a._firebase.child("users").child(e+"/name").once("value",t)},t.prototype.getUsersByRoom=function(){var e=this,t=arguments[0],n=e._firebase.child("room-users").child(t),i=arguments[arguments.length-1],s=null;arguments.length>2&&(s=arguments[1]),n=s?n.limit(s):n,n.once("value",function(e){var t=e.val()||{},n={};for(var s in t)for(var r in t[s]){n[s]=t[s][r];break}a.setTimeout(function(){i(n)},0)})},t.prototype.getUsersByPrefix=function(e,t,n,i,s){var r=this._usersOnlineRef,o=e.toLowerCase();r=t?r.startAt(null,t):n?r.endAt(null,n):o?r.startAt(null,o):r.startAt(),r=i?r.limit(i):r,r.once("value",function(t){var n=t.val()||{},i={};for(var r in n){var c,l,u=n[r];for(var h in u){c=u[h].name,l=u[h].id;break}e.length>0&&0!==c.toLowerCase().indexOf(o)||(i[c]={name:c,id:l})}a.setTimeout(function(){s(i)},0)})},t.prototype.getRoom=function(e,t){this._roomRef.child(e).once("value",function(e){t(e.val())})},t.prototype.userIsModerator=function(){return this._isModerator},t.prototype.userIsStaff=function(){return this._isStaff}}(Firebase),function(e,t){function a(e){var t=document.cookie.indexOf(e+"="),a=t+e.length+1;if(!t&&e!=document.cookie.substring(0,e.length))return null;if(-1==t)return null;var n=document.cookie.indexOf(";",a);return-1==n&&(n=document.cookie.length),unescape(document.cookie.substring(a,n))}function n(e,t,a,n,i,s){var r=new Date;r.setTime(r.getTime()),a&&(a=24*60*60*1e3*a);var o=new Date(r.getTime()+a);document.cookie=e+"="+escape(t)+(a?";expires="+o.toGMTString():"")+(n?";path="+n:"")+(i?";domain="+i:"")+(s?";secure":"")}function i(t,n,i){if(!t)throw Error("ChiselchatUI: Missing required argument `firebaseRef`");if(!n)throw Error("ChiselchatUI: Missing required argument `el`");i=i||{},this._options=i,this._el=n,this._user=null,this._chat=new Chiselchat(t,i),this._roomQueue=[],this.autoFocusTab=!1,this.fullScreenTab=!1,this.playSounds="true"===a("chiselchat-playSounds")?!0:!1,this.displayNewMessageCount=!1,this.commands=[],this.maxLengthUsername=15,this.maxLengthUsernameDisplay=15,this.maxLengthRoomName=16,this.maxLengthMessage=1e3,this.maxUserSearchResults=100,this.messageHistoryScrollHeight=80,this.urlPattern=/\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim,this.pseudoUrlPattern=/(^|[^\/])(www\.[\S]+(\b|$))/gim,this._renderLayout(),this.$wrapper=e("#chiselchat"),this.$roomList=e("#chiselchat-room-list"),this.$tabList=e("#chiselchat-tab-list"),this.$tabContent=e("#chiselchat-tab-content"),this.$messages={},this.$rateLimit={limitCount:10,limitInterval:1e4,limitWaitTime:3e4,history:{}},this._bindUIEvents(),this._bindDataEvents(),this._initCommands()}var s,r=document.title;t.flashTitle=function(e){function a(){document.title=document.title==r?e:r,6e4>n&&(n+=100,s=setTimeout(a,n))}t.cancelFlashTitle();var n=100;document.hasFocus()||a()};var o=function(){clearTimeout(s),document.title=r};if(t.cancelFlashTitle=o,e(t).focus(o),!e||170>parseInt(e().jquery.replace(/\./g,""),10))throw Error("jQuery 1.7 or later required!");var c=this,l=c.ChiselchatUI;if(c.ChiselchatUI=i,!self.ChiselchatDefaultTemplates)throw Error("Unable to find chat templates!");i.noConflict=function(){return c.ChiselchatUI=l,i},i.prototype={_initCommands:function(){self=this,self.addCommand({match:/^\/help$/,func:function(e,t){var a="";for(var n in t.commands)(!t.commands[n].moderatorOnly||t._chat.userIsModerator())&&(a+="

        "+t.commands[n].name+" - "+t.commands[n].help+"

        ");t.info(a,"Chat Help"),e.type="command"},name:"/help",help:"Display this message."}),self.addCommand({match:/^\/me\s/,func:function(e){e.content=e.content.replace(/^\/me/,""),e.type="activity"},name:"/me ",help:"Your name will appear followed by any text you write."}),self.addCommand({match:/^\/whoami$/,func:function(e,t){var a='You are "'+t._user.name+'", ';a+=t._user.isStaff?"a staffer.":t._user.isModerator?"a moderator.":t._user.isGuest?"an anonymous guest user.":"a normal user.",t.info(a,"Who Am I?"),e.type="command"},name:"/whoami",help:"Display your name."}),self.addCommand({match:/^\/leave$/,func:function(e,t){t._chat.leaveRoom(e.roomId),e.type="command"},name:"/leave",help:"Leave the current room."}),self.addCommand({match:/^\/topic\s/,func:function(e,t){var a=e.content.replace(/^\/topic\s+/,"");if(e.content.match(/\w+/)){var n=t._chat._roomRef.child(e.roomId);n.transaction(function(i){"official"==i.type?t.error("Cannot modify the topic of an official room."):(n.child("name").set(a),t._chat.sendMessage(e.roomId,'changed the topic to "'+a+'".',"activity"))})}e.type="command"},name:"/topic ",help:"Change the name of the room.",moderatorOnly:!0})},_bindUIEvents:function(){this._bindForRoomList(),this._bindForUserRoomList(),this._bindForUserSearch(),this._bindForUserMuting(),this._bindForChatInvites(),this._bindForRoomListing(),this._bindForRoomNotification(),this._setupTabs(),this._bindTextInputFieldLimits()},_bindDataEvents:function(){this._chat.on("user-update",this._onUpdateUser.bind(this)),this._chat.on("room-enter",this._onEnterRoom.bind(this)),this._chat.on("room-create",this._onCreateRoom.bind(this)),this._chat.on("room-changed",this._onRoomChanged.bind(this)),this._chat.on("room-exit",this._onLeaveRoom.bind(this)),this._chat.on("message-add",this._onNewMessage.bind(this)),this._chat.on("message-remove",this._onRemoveMessage.bind(this)),this._chat.on("room-invite",this._onChatInvite.bind(this)),this._chat.on("room-invite-response",this._onChatInviteResponse.bind(this)),this._chat.on("notification",this._onNotification.bind(this))},_renderLayout:function(){var t=ChiselchatDefaultTemplates["templates/layout-full.html"];e(this._el).html(t({maxLengthUsername:this.maxLengthUsername,maxLengthRoomName:this.maxLengthRoomName,isModerator:this._chat.userIsModerator(),isStaff:this._chat.userIsStaff()}))},_onUpdateUser:function(t){this._user=t;var a=this._user.muted||{};e('[data-event="chiselchat-user-mute-toggle"]').each(function(){var t=e(this).closest("[data-user-id]").data("user-id");e(this).toggleClass("chiselchat-muted",!!a[t])});for(var n in a)e('.message[data-user-id="'+n+'"]').fadeOut()},_onEnterRoom:function(e){this.attachTab(e.id,e.name)},_onRoomChanged:function(t){e('#chiselchat-tab-list li[data-room-id="'+t.id+'"] a .chiselchat-tab-text').html(t.name),e('[data-room-id="'+t.id+'"] .chiselchat-title-text').html(t.name)},_onCreateRoom:function(e){self=this,"public"==e.type&&self.info('A new public chatroom called "'+e.name+'" has been created.',"New Public Room")},_onLeaveRoom:function(e){this.removeTab(e),this._roomQueue.length>0&&this._chat.enterRoom(this._roomQueue.shift(e))},_onNewMessage:function(t,a){var n=a.userId,i=this;this._user&&this._user.muted&&this._user.muted[n]||(i.showMessage(t,a),this._chat.lookupUser(n,function(t){var n=e('div[data-message-id="'+a.id+'"]');t.profileUri&&(n.find(".chiselchat-avatar > a").attr("href",t.profileUri),n.find(".chiselchat-user > a").attr("href",t.profileUri)),t.avatarUri&&n.find(".chiselchat-avatar img").attr("src",t.avatarUri),t.isGuest&&n.find(".chiselchat-user > a").addClass("chiselchat-guest"),t.isModerator&&n.find(".chiselchat-user > a").addClass("chiselchat-moderator"),t.isStaff&&n.find(".chiselchat-user > a").addClass("chiselchat-staff")}))},_onRemoveMessage:function(e,t){this.removeMessage(e,t)},_onChatInvite:function(e){var t=this;t.confirm(e.fromUserName+" invited you to join "+e.toRoomName,"Invitation",function(){return t._chat.acceptInvite(e.id,function(e){e instanceof Error||t.focusTab(e.roomId)}),!1},function(){return t._chat.declineInvite(e.id),!1})},_onChatInviteResponse:function(t){if(t.status){var a=this;t.status&&"accepted"===t.status?(a.success(t.toUserName+" accepted your invite.","Invitation Accepted"),this._chat.getRoom(t.roomId,function(n){var i=e('#chiselchat-tab-list li[data-room-id="'+t.roomId+'"]');i.length||(a.autoFocusTab=!0,a.attachTab(t.roomId,n.name))})):a.error(t.toUserName+" declined your invite.","Invitation Declined")}},_onNotification:function(e){if("warning"===e.notificationType)this.warn("You are being warned for inappropriate messaging. Further violation may result in temporary or permanent ban of service.");else if("suspension"===e.notificationType){var t=e.data.suspendedUntil,a=Math.round((t-(new Date).getTime())/1e3),n="";if(a>0){if(a>7200){var i=Math.floor(a/3600);n=i+" hours, ",a-=3600*i}n+=Math.floor(a/60)+" minutes",this.error("A moderator has suspended you for violating site rules. You cannot send messages for another "+n+".","Suspended")}}}},i.prototype.setUser=function(e){var a=this;e.userName===void 0&&(e.userName=""),e.isModerator===void 0&&(e.isModerator=!1),e.isStaff===void 0&&(e.isStaff=!1),e.isGuest===void 0&&(e.isGuest=!0),e.avatarUri===void 0&&(e.avatarUri=""),e.profileUri===void 0&&(e.profileUri=""),a._chat.setUser(e,function(e){a._user=e,a._chat.userIsModerator()&&a._bindSuperuserUIEvents(),t.setTimeout(function(){a.displayNewMessageCount=!0},1e3),a._chat.resumeSession()})},i.prototype.unsetUser=function(){var e=this;e._chat.unsetUser(),e._user=null,e._roomQueue=[],e.displayNewMessageCount=!1},i.prototype.on=function(e,t){this._chat.on(e,t)},i.prototype._bindSuperuserUIEvents=function(){var t=this,a=function(){var t=e(this),a=t.closest("[data-message-id]").data("message-id"),n=e('[data-message-id="'+a+'"]').closest("[data-user-id]").data("user-id"),i=e('[data-message-id="'+a+'"]').closest("[data-room-id]").data("room-id");return{messageId:a,userId:n,roomId:i}};e(document).delegate('[data-event="chiselchat-user-warn"]',"click",function(e){var n=a.call(this,e);t._chat.warnUser(n.userId),t._chat.getUserNameById(n.userId,function(e){t._chat.sendMessage(n.roomId,"warned "+e.val()+".","activity")})}),e(document).delegate('[data-event="chiselchat-user-suspend-hour"]',"click",function(e){var n=a.call(this,e);t._chat.suspendUser(n.userId,3600),t._chat.getUserNameById(n.userId,function(e){t._chat.sendMessage(n.roomId,"suspended "+e.val()+" for 1 hour.","activity")})}),e(document).delegate('[data-event="chiselchat-user-suspend-day"]',"click",function(e){var n=a.call(this,e);t._chat.suspendUser(n.userId,86400),t._chat.getUserNameById(n.userId,function(e){t._chat.sendMessage(n.roomId,"suspended "+e.val()+" for 1 day.","activity")})}),e(document).delegate('[data-event="chiselchat-message-delete"]',"click",function(e){var n=a.call(this,e);t._chat.deleteMessage(n.roomId,n.messageId)})},i.prototype._bindForRoomList=function(){var t=this;e("#chiselchat-room-tab").bind("click",function(){var a=(e(this),ChiselchatDefaultTemplates["templates/room-list-item.html"]),n=function(){var a=e(this).parent(),n=a.data("room-id"),i=a.data("room-name");return t.$messages[n]?t.focusTab(n):(t.autoFocusTab=!0,t._chat.enterRoom(n,i)),!1};deleteRoom=function(){var a=e(this).closest("li"),n=a.data("room-id");t._chat.removeRoom(n),a.remove()},t._chat.getRoomList(function(i){t.$roomList.empty();for(var s in i){var r=i[s];if("private"!=r.type){r.isRoomOpen=!!t.$messages[r.id],r.userIsModerator=t._chat.userIsModerator();var o=e(a(r));o.children(".chiselchat-room-list-item").bind("click",n),o.children(".chiselchat-delete-room").bind("click",deleteRoom),t.$roomList.append(o.toggle(!0))}}})})},i.prototype._bindForUserRoomList=function(){var t=this;e(document).delegate('[data-event="chiselchat-user-room-list-btn"]',"click",function(a){a.stopPropagation();var n=e(this),i=n.closest("[data-room-id]").data("room-id"),s=ChiselchatDefaultTemplates["templates/room-user-list-item.html"],r=n.data("target"),o=e("#"+r);o.empty(),t._chat.getUsersByRoom(i,function(a){for(var n in a)user=a[n],user.disableActions=!t._user||user.id===t._user.id,user.nameTrimmed=t.trimWithEllipsis(user.name,t.maxLengthUsernameDisplay),user.isMuted=t._user&&t._user.muted&&t._user.muted[user.id],o.append(e(s(user)));t.sortListLexicographically("#"+r)})})},i.prototype._bindForUserSearch=function(){var t=this,a=function(t){var a=e(this),i=a.data("target"),s=a.data("controls"),r=a.data("template"),o=a.val()||a.data("prefix")||"",c=a.data("startAt")||null,l=a.data("endAt")||null;t.preventDefault(),n(i,r,s,o,c,l)},n=function(a,n,i,s,r,o){var c=e("#"+a),l=ChiselchatDefaultTemplates[n];t._chat.getUsersByPrefix(s,r,o,t.maxUserSearchResults,function(e){var a,n,i,s=0;c.empty();for(a in e){var r=e[a];if(r.disableActions=!t._user||r.id===t._user.id,s+=1,c.append(l(r)),1===s)n=r.name.toLowerCase();else if(s>=t.maxUserSearchResults){i=r.name.toLowerCase();break}}})};e(document).delegate('[data-event="chiselchat-user-search"]',"keyup",a),e(document).delegate('[data-event="chiselchat-user-search"]',"click",a),e(document).delegate("#chiselchat-user-search-form","submit",a),e(document).delegate("#chiselchat-presence-tab","click",function(t){t.stopPropagation();var a=e("#chiselchat-user-search-form").find("input");a.focus(),a.trigger(jQuery.Event("keyup"))})},i.prototype._bindForUserMuting=function(){var t=this;e(document).delegate('[data-event="chiselchat-user-mute-toggle"]',"click",function(a){var n=e(this),i=n.closest("[data-user-id]").data("user-id"),s=n.closest("[data-user-name]").data("user-name"),r=n.hasClass("chiselchat-muted");a.preventDefault(),t._chat.toggleUserMute(i,function(e){e?t.error(e.message):r?(t.success(s+" has been unmuted.","User Unmuted"),n.html("Mute")):(t.error(s+" has been muted.","User Muted"),n.html("Unmute"))})})},i.prototype._bindForChatInvites=function(){var t=this,a=function(){var a=e(this),n=a.closest("[data-user-id]").data("user-id"),i=a.closest("[data-room-id]").data("room-id"),s=a.closest("[data-user-name]").data("user-name");return t._chat.getRoom(i,function(e){t._chat.inviteUser(n,i,e.name),t.info(s+" invited.")}),!1},n=function(){var a=e(this),n=a.closest("[data-user-id]").data("user-id"),i=a.closest("[data-user-name]").data("user-name");if(n&&i){var s="Private Chat";t.autoFocusTab=!0,t._chat.createRoom(s,"private",function(e){t._chat.inviteUser(n,e,s),t.info(i+" invited.")})}return!1};e(document).delegate('[data-event="chiselchat-user-chat"]',"click",n),e(document).delegate('[data-event="chiselchat-user-invite"]',"click",a)},i.prototype._bindForRoomNotification=function(){var t=this,a=function(){var a=e(this),n=a.data("room-id"),i=a.data("room-name");return t.autoFocusTab=!0,t._chat.enterRoom(n,i),!1};e(document).delegate('[data-event="chiselchat-room-notification"]',"click",a)},i.prototype._bindForRoomListing=function(){var t=this;e("#chiselchat-create-room").bind("submit",function(){var a=e("#chiselchat-input-room-name").val();return e("#chiselchat-input-room-name").val(""),a.length?(t.autoFocusTab=!0,t._chat.createRoom(a)):t.error("Room name must be specified."),!1})},i.prototype._setupTabs=function(){var a=this,i=function(t){t.parent("li").removeClass("active"),e("#chiselchat-tab-content .chiselchat-tab-pane").removeClass("active"),a.resetNewMessageCount(t.parent("li").attr("data-room-id"))},s=function(t){var n,i,s=t,o=s.closest("ul"),c=s.attr("data-target"),l=o.find(".active:last a")[0];c||(c=s.attr("href"),c=c&&c.replace(/.*(?=#[^\s]*$)/,"")),a.resetNewMessageCount(e(l).parent("li").attr("data-room-id")),s.parent("li").hasClass("active")||(i=e.Event("show",{relatedTarget:l}),s.trigger(i),i.isDefaultPrevented()||(n=e(c),r(s.parent("li"),o),r(n,n.parent(),function(){s.trigger({type:"shown",relatedTarget:l})}),n.find(".chiselchat-history").css("height",n.height()-a.messageHistoryScrollHeight+"px")))},r=function(e,t,n){var i=t.find("> .active");i.removeClass("active").removeClass("fullscreen"),e.addClass("active"),a.fullScreenTab&&e.addClass("fullscreen"),n&&n()};e(document).delegate('[chisel-toggle="tab"]',"click",function(t){t.preventDefault();var a=e(this);a.parent("li").hasClass("active")?i(a):s(a)}),e(document).delegate('[data-event="chiselchat-minimize-pane"]',"click",function(){var t=e(this).closest("[data-room-id]").data("room-id");return i(e('#chiselchat-tab-list li[data-room-id="'+t+'"] a, #chiselchat-room-tab a, #chiselchat-presence-tab a')),!1}),e(document).delegate('[data-event="chiselchat-close-tab"]',"click",function(){var t=e(this).closest("[data-room-id]").data("room-id");return a._chat.leaveRoom(t),!1}),e(document).delegate('[data-event="chiselchat-toggle-pane-size"]',"click",function(){return a.fullScreenTab?(a.fullScreenTab=!1,e(this).closest(".chiselchat-tab-pane").removeClass("fullscreen")):(e(this).closest(".chiselchat-tab-pane").addClass("fullscreen"),a.fullScreenTab=!0),e(t).trigger("resize"),!1}),e(document).delegate('[data-event="chiselchat-toggle-sound"]',"click",function(){var t=e(".chiselchat-sound-control");return a.playSounds?(a.playSounds=!1,n("chiselchat-playSounds",!1,30),t.removeClass("chiselchat-glyphicon-volume-up"),t.addClass("chiselchat-glyphicon-volume-off")):(a.playSounds=!0,n("chiselchat-playSounds",!0,30),t.addClass("chiselchat-glyphicon-volume-up"),t.removeClass("chiselchat-glyphicon-volume-off")),!1})},i.prototype._bindTextInputFieldLimits=function(){e("body").delegate('input[data-provide="limit"], textarea[data-provide="limit"]',"keyup",function(){var t=e(this),a=e(t.data("counter")),n=t.attr("maxlength"),i=t.val().length;a.html(Math.max(0,n-i))})},i.prototype.confirm=function(e,t,a,n){new PNotify({title:t||"Confirmation Needed",text:e,addclass:"chiselchat-alert",type:"info",icon:"chiselchat-glyphicon chiselchat-glyphicon-question-sign",hide:!1,confirm:{confirm:!0},buttons:{closer:!1,sticker:!1},history:{history:!1}}).get().on("pnotify.confirm",function(){a()}).on("pnotify.cancel",function(){n()})},i.prototype.warn=function(e,t){new PNotify({addclass:"chiselchat-alert",title:t||"Warning",text:e,icon:"chiselchat-glyphicon chiselchat-glyphicon-exclamation-sign",opacity:.95,history:!1,sticker:!1})},i.prototype.info=function(e,t){new PNotify({addclass:"chiselchat-alert",type:"info",title:t||"Info",text:e,icon:"chiselchat-glyphicon chiselchat-glyphicon-info-sign",opacity:.95,history:!1,sticker:!1})},i.prototype.error=function(e,t){new PNotify({addclass:"chiselchat-alert",type:"error",title:t||"Error",text:e,icon:"chiselchat-glyphicon chiselchat-glyphicon-warning-sign",opacity:.95,history:!1,sticker:!1})},i.prototype.success=function(e,t){new PNotify({addclass:"chiselchat-alert",type:"success",title:t||"Success",text:e,icon:"chiselchat-glyphicon chiselchat-glyphicon-ok-sign",opacity:.95,history:!1,sticker:!1})},i.prototype.addCommand=function(e){self=this,self.commands.push(e)},i.prototype.executeCommands=function(e){var t=this;for(var a in t.commands){var n=t.commands[a];if(e.content.match(n.match)){if(n.moderatorOnly&&!t._chat.userIsModerator())continue;n.func(e,t)}}},i.prototype.resetNewMessageCount=function(e){t.cancelFlashTitle();var a=this.$tabList.find("[data-room-id="+e+"]").find("a");if(a.length){var n=a.first().children(".chiselchat-new-count");n.html("0"),n.removeClass("chiselchat-new-count-alert")}},i.prototype.toggleInputs=function(t){e("#chiselchat-tab-content textarea").each(function(){var a=e(this);t?e(this).val(""):e(this).val("You have exceeded the message limit, please wait before sending."),a.prop("disabled",!t)}),e("#chiselchat-input-name").prop("disabled",!t)},i.prototype.attachTab=function(a,n){var i=this;if(this.$messages[a])return this.focusTab(a),void 0;var s={id:a,name:n},r=ChiselchatDefaultTemplates["templates/tab-content.html"],o=e(r(s));this.$tabContent.prepend(o);var c=e("#chiselchat-messages"+a);this.$messages[a]=c;var l=o.find("textarea").first();l.bind("keydown",function(e){var t={content:i.trimWithEllipsis(l.val(),i.maxLengthMessage),type:"default",roomId:a};if(13===e.which&&""!==t.content){if(e.shiftKey){var n=this.value;if("number"==typeof this.selectionStart&&"number"==typeof this.selectionEnd){var s=this.selectionStart;this.value=n.slice(0,s)+"\n"+n.slice(this.selectionEnd),this.selectionStart=this.selectionEnd=s+1}else if(document.selection&&document.selection.createRange){this.focus();var r=document.selection.createRange();r.text="\r\n",r.collapse(!1),r.select()}}else l.val(""),i.executeCommands(t),("activity"==t.type||"default"==t.type)&&i._chat.sendMessage(t.roomId,t.content,t.type,function(e){e&&i.error("You are not allowed to post messages right now.")});return!1}});var u=ChiselchatDefaultTemplates["templates/tab-menu-item.html"],h=e(u(s));this.$tabList.append(h),c.css("height",o.height()-i.messageHistoryScrollHeight+"px"),e(t).resize(function(){c.css("height",o.height()-i.messageHistoryScrollHeight+"px"),c.scrollTop(c[0].scrollHeight)}),h.bind("shown",function(){c.scrollTop(c[0].scrollHeight)}),e("#chiselchat-btn-room-user-list-"+a).bind("click",function(){return i.sortListLexicographically("#chiselchat-room-user-list-"+a),!1}),i.autoFocusTab?(this.focusTab(a),i.autoFocusTab=!1):i.resetNewMessageCount(a),this.playSounds?e(".chiselchat-sound-control").addClass("chiselchat-glyphicon-volume-up"):e(".chiselchat-sound-control").addClass("chiselchat-glyphicon-volume-off")},i.prototype.focusTab=function(e){var t=this;if(t.$messages[e]){var a=t.$tabList.find("[data-room-id="+e+"]").find("a");a.length&&(a.first().trigger("click"),t.resetNewMessageCount(e))}},i.prototype.removeTab=function(e){delete this.$messages[e],this.$tabContent.find("[data-room-id="+e+"]").remove();var t=this.$tabList.find("[data-room-id="+e+"]"),a=t.hasClass("active");t.remove(),a&&this.$tabList.find("[chisel-toggle=tab]").first().trigger("click")},i.prototype.showMessage=function(a,n){var i=this,s={id:n.id,localtime:i.formatTime(n.timestamp),message:n.message||"",userId:n.userId,name:n.name,type:n.type||"default",isSelfMessage:i._user&&n.userId==i._user.id,disableActions:!i._user||n.userId==i._user.id,userIsModerator:i._chat.userIsModerator(),avatarUri:"",profileUri:""};s.message=_.map(s.message.split(" "),function(e){return i.urlPattern.test(e)||i.pseudoUrlPattern.test(e)?i.linkify(encodeURI(e)):_.escape(e)}).join(" "),s.message=i.trimWithEllipsis(s.message,i.maxLengthMessage),s.message=s.message.replace(/\n/g,"
        ");var r=ChiselchatDefaultTemplates["templates/message.html"],o=e(r(s)),c=i.$messages[a];if(c){var l=!1;c.scrollTop()/(c[0].scrollHeight-c[0].offsetHeight)>=.95?l=!0:c[0].scrollHeight<=c.height()&&(l=!0),c.append(o);var u=this.$tabList.find("[data-room-id="+a+"]").find("a");if(u.length&&i.displayNewMessageCount){var h=u.first().children(".chiselchat-new-count");h.html(parseInt(h.html(),10)+1),this.pulse(h,"chiselchat-new-count-alert",{pulses:5,duration:300}),t.flashTitle("New Chat Message!"),this.playNewMessageSound()}l&&c.scrollTop(c[0].scrollHeight)}},i.prototype.removeMessage=function(t,a){e('.chiselchat-message[data-message-id="'+a+'"]').remove()},i.prototype.sortListLexicographically=function(t){e(t).children("li").sort(function(t,a){var n=e(t).text().toUpperCase(),i=e(a).text().toUpperCase();return i>n?-1:n>i?1:0}).appendTo(t)},i.prototype.trimWithEllipsis=function(e,t){return e=e.replace(/^\s\s*/,"").replace(/\s\s*$/,""),t&&t>=e.length?e:e.substring(0,t)+"..."},i.prototype.formatTime=function(e){var t=e?new Date(e):new Date,a=t.getHours()||12,n=""+t.getMinutes(),i=t.getHours()>=12?"pm":"am";return a=a>12?a-12:a,n=2>n.length?"0"+n:n,""+a+":"+n+i},i.prototype.linkify=function(e){var t=this;return e.replace(t.urlPattern,'$&').replace(t.pseudoUrlPattern,'$1$2')},i.prototype.playNewMessageSound=function(){this.playSounds&&document.getElementById("chiselchat-new-message-sound").play()},i.prototype.pulse=function(a,n,i,s){var r={pulses:1,interval:0,returnDelay:0,duration:500},o="destroy"===n;return"function"==typeof i&&(s=i,i={}),i=e.extend({},r,i),0>i.interval&&(i.interval=0),0>i.returnDelay&&(i.returnDelay=0),0>i.duration&&(i.duration=500),-1>i.pulses&&(i.pulses=1),"function"!=typeof s&&(s=function(){}),a.each(function(){function a(){if(void 0!==r.data("pulse")&&!r.data("pulse").stop){if(i.pulses>-1&&++l>i.pulses)return s.apply(r);r.removeClass(n),t.setTimeout(h.complete,h.duration)}}var r=e(this),c=r.data("pulse")||{};c.stop=o,r.data("pulse",c);var l=0,u=e.extend({},i);u.duration=i.duration/2,u.complete=function(){t.setTimeout(a,i.interval)};var h=e.extend({},i);h.duration=i.duration/2,h.complete=function(){t.setTimeout(function(){r.addClass(n),t.setTimeout(u.complete,u.duration)},i.returnDelay)},a()})}}(jQuery,window,document); diff --git a/var/www/public/chiselchat/guest_logo.png b/var/www/public/chiselchat/guest_logo.png deleted file mode 100644 index 59169c17e5e25c7446be88f570f5771d0ea8f323..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2701 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 fHl diff --git a/var/www/public/chiselchat/whoosh.wav b/var/www/public/chiselchat/whoosh.wav deleted file mode 100644 index ecf9dfb68f486c254f73a30763d68bd99eaf06b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23656 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 Q0;Qlo{}~xTz67NT01(#`TL1t6